forked from mirrors/gecko-dev
Automatic update from web-platform-tests Fix two custom elements tests to avoid depending on undefined ordering. Each test file has a single test that is currently failing identically in both Chromium and Gecko, while passing in WebKit. The tests that fail invoke: document.open(URL, "_self", ""); in a custom element constructor, and then rely on a script element *following* the custom element to be executed. This change fixes the test to avoid depending on that following script, but instead run the necessary code in the custom element constructor. (Only the test that does the document.open(URL, "_self", "") call needs this change, but the change affects all the tests in these files.) I believe the current test is depending on undefined behavior because (although I fully admit I'm skimming relatively long lists of complex steps in the HTML specification quite quickly) the document.open call is specified at https://html.spec.whatwg.org/multipage/C#dom-document-open-window which invokes https://html.spec.whatwg.org/multipage/C#window-open-steps where either step 12.6 or 13.1.3 are the same and invoke https://html.spec.whatwg.org/multipage/C#navigate . Step 19 of that algorithm is run "in parallel"), and step 19.3 invokes https://html.spec.whatwg.org/multipage/C#abort-a-document which in turn invokes https://html.spec.whatwg.org/multipage/C#abort-a-parser which I believe will stop later scripts from executing. The definition of "in parallel" is explicitly undefined at https://html.spec.whatwg.org/multipage/C#in-parallel so it's not clear when the parser is aborted relative to other things. I think this means that either the Gecko/Chromium behavior of aborting the parser before executing the following script, or the WebKit behavior of aborting at some later time, are both permitted. Fixed: 1365368 Fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=1819922 Fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=1819925 Change-Id: Ied396b36e5b7466de7ef98b9ab4559c9556be995 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4661389 Commit-Queue: Joey Arhar <jarhar@chromium.org> Auto-Submit: David Baron <dbaron@chromium.org> Reviewed-by: Joey Arhar <jarhar@chromium.org> Cr-Commit-Position: refs/heads/main@{#1164733} -- wpt-commits: 63e0e7019a119d75308e436bcec179c6cc40edae wpt-pr: 40831
130 lines
7.4 KiB
HTML
130 lines
7.4 KiB
HTML
<?xml version="1.0" encoding="utf-8"?>
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<title>Custom Elements: create an element for a token must increment and decrement document's throw-on-dynamic-markup-insertion counter</title>
|
|
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org" />
|
|
<meta name="assert" content="Invoking document.open, document.write, document.writeln, and document.write must throw an exception when the HTML parser is creating a custom element for a token" />
|
|
<meta name="help" content="https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token" />
|
|
<meta name="help" content="https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#throw-on-dynamic-markup-insertion-counter" />
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="resources/custom-elements-helpers.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="log"></div>
|
|
<script>
|
|
<![CDATA[
|
|
|
|
async function custom_element_reactions_in_parser(test, code)
|
|
{
|
|
window.executed = false;
|
|
window.exception = null;
|
|
const content_window = await create_window_in_test_async(test, 'application/xml', `<?xml version="1.0" encoding="utf-8"?>
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<script>
|
|
<![CDATA[
|
|
class CustomElement extends window.HTMLElement {
|
|
constructor() {
|
|
super();
|
|
let exception = null;
|
|
try {
|
|
${code}
|
|
} catch (error) {
|
|
exception = error;
|
|
}
|
|
top.executed = true;
|
|
top.exception = exception;
|
|
}
|
|
}
|
|
CustomElement.observedAttributes = ['title'];
|
|
customElements.define('some-element', CustomElement);
|
|
]]` + `>
|
|
</` + `script>
|
|
</head>
|
|
<body>
|
|
<some-element title="some title"></some-element>
|
|
</body>
|
|
</html>`);
|
|
let content_document;
|
|
try {
|
|
content_document = content_window.document;
|
|
} catch (error) { }
|
|
assert_true(executed, 'Must immediately process custom element reactions for setting attributes');
|
|
return {window: content_window, document: content_document, exception};
|
|
}
|
|
|
|
promise_test(async function () {
|
|
const result = await custom_element_reactions_in_parser(this, `document.open()`);
|
|
assert_throws_dom('InvalidStateError', result.window.DOMException, () => { throw result.exception; }, 'Must throw an InvalidStateError');
|
|
}, 'document.open() must throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
promise_test(async function () {
|
|
const result = await custom_element_reactions_in_parser(this, `document.open('text/html')`);
|
|
assert_throws_dom('InvalidStateError', result.window.DOMException, () => { throw result.exception; }, 'Must throw an InvalidStateError');
|
|
}, 'document.open("text/html") must throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
// https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-document-open-window
|
|
promise_test(async function () {
|
|
let load_promise = new Promise((resolve) => window.onmessage = (event) => resolve(event.data));
|
|
const url = top.location.href.substring(0, top.location.href.lastIndexOf('/')) + '/resources/navigation-destination.html';
|
|
const result = await custom_element_reactions_in_parser(this, `document.open('${url}', '_self', '')`);
|
|
assert_equals(result.exception, null);
|
|
assert_equals(await load_promise, 'didNavigate');
|
|
}, 'document.open(URL) must NOT throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
promise_test(async function () {
|
|
const result = await custom_element_reactions_in_parser(this, `document.close()`);
|
|
assert_throws_dom('InvalidStateError', result.window.DOMException, () => { throw result.exception; }, 'Must throw an InvalidStateError');
|
|
}, 'document.close() must throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
promise_test(async function () {
|
|
const result = await custom_element_reactions_in_parser(this, `document.write('<b>some text</b>')`);
|
|
assert_throws_dom('InvalidStateError', result.window.DOMException, () => { throw result.exception; }, 'Must throw an InvalidStateError');
|
|
assert_equals(result.document.querySelector('b'), null, 'Must not insert new content');
|
|
assert_false(result.document.body.innerHTML.includes('some text'), 'Must not insert new content');
|
|
}, 'document.write must throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
promise_test(async function () {
|
|
const result = await custom_element_reactions_in_parser(this, `document.writeln('<b>some text</b>')`);
|
|
assert_throws_dom('InvalidStateError', result.window.DOMException, () => { throw result.exception; }, 'Must throw an InvalidStateError');
|
|
assert_equals(result.document.querySelector('b'), null, 'Must not insert new content');
|
|
assert_false(result.document.body.innerHTML.includes('some text'), 'Must not insert new content');
|
|
}, 'document.writeln must throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
promise_test(async function () {
|
|
window.another_window = await create_window_in_test(this);
|
|
const result = await custom_element_reactions_in_parser(this, `top.another_window.document.open()`);
|
|
assert_equals(result.exception, null);
|
|
}, 'document.open() of another document must not throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
promise_test(async function () {
|
|
window.another_window = await create_window_in_test(this);
|
|
const result = await custom_element_reactions_in_parser(this, `top.another_window.document.open('text/html')`);
|
|
assert_equals(result.exception, null);
|
|
}, 'document.open("text/html") of another document must not throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
promise_test(async function () {
|
|
window.another_window = await create_window_in_test(this);
|
|
const result = await custom_element_reactions_in_parser(this, `top.another_window.document.close()`);
|
|
assert_equals(result.exception, null);
|
|
}, 'document.close() of another document must not throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
promise_test(async function () {
|
|
window.another_window = await create_window_in_test(this);
|
|
const result = await custom_element_reactions_in_parser(this, `top.another_window.document.write('<b>some text</b>')`);
|
|
assert_equals(result.exception, null);
|
|
assert_equals(another_window.document.querySelector('b').outerHTML, '<b>some text</b>');
|
|
}, 'document.write of another document must not throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
promise_test(async function () {
|
|
window.another_window = await create_window_in_test(this);
|
|
const result = await custom_element_reactions_in_parser(this, `top.another_window.document.writeln('<b>some text</b>')`);
|
|
assert_equals(result.exception, null);
|
|
assert_equals(another_window.document.querySelector('b').outerHTML, '<b>some text</b>');
|
|
}, 'document.writeln of another document must not throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element');
|
|
|
|
]]>
|
|
</script>
|
|
</body>
|
|
</html>
|