throw-on-dynamic-markup-insertion-counter-construct-xml-parser.xhtml (7406B)
1 <?xml version="1.0" encoding="utf-8"?> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title>Custom Elements: create an element for a token must increment and decrement document's throw-on-dynamic-markup-insertion counter</title> 5 <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org" /> 6 <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" /> 7 <meta name="help" content="https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token" /> 8 <meta name="help" content="https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#throw-on-dynamic-markup-insertion-counter" /> 9 <script src="/resources/testharness.js"></script> 10 <script src="/resources/testharnessreport.js"></script> 11 <script src="resources/custom-elements-helpers.js"></script> 12 </head> 13 <body> 14 <div id="log"></div> 15 <script> 16 <![CDATA[ 17 18 async function construct_custom_element_in_parser(test, code) 19 { 20 window.executed = false; 21 window.exception = null; 22 const content_window = await create_window_in_test_async(test, 'application/xml', `<?xml version="1.0" encoding="utf-8"?> 23 <html xmlns="http://www.w3.org/1999/xhtml"> 24 <head> 25 <script> 26 <![CDATA[ 27 class CustomElement extends window.HTMLElement { 28 constructor() { 29 super(); 30 let exception = null; 31 try { 32 ${code} 33 } catch (error) { 34 exception = error; 35 } 36 top.executed = true; 37 top.exception = exception; 38 } 39 } 40 customElements.define('some-element', CustomElement); 41 ]]` + `> 42 </` + `script> 43 </head> 44 <body> 45 <some-element></some-element> 46 </body> 47 </html>`); 48 let content_document; 49 try { 50 content_document = content_window.document; 51 } catch (error) { } 52 assert_true(executed, 'Must synchronously instantiate a custom element'); 53 return {window: content_window, document: content_document, exception}; 54 } 55 56 promise_test(async function () { 57 const result = await construct_custom_element_in_parser(this, `document.open()`); 58 assert_throws_dom('InvalidStateError', result.window.DOMException, () => { throw result.exception; }, 'Must throw an InvalidStateError'); 59 }, 'document.open() must throw an InvalidStateError when synchronously constructing a custom element'); 60 61 promise_test(async function () { 62 const result = await construct_custom_element_in_parser(this, `document.open('text/html')`); 63 assert_throws_dom('InvalidStateError', result.window.DOMException, () => { throw result.exception; }, 'Must throw an InvalidStateError'); 64 }, 'document.open("text/html") must throw an InvalidStateError when synchronously constructing a custom element'); 65 66 // https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-document-open-window 67 promise_test(async function () { 68 let load_promise = new Promise((resolve) => window.onmessage = (event) => resolve(event.data)); 69 const url = top.location.href.substring(0, top.location.href.lastIndexOf('/')) + '/resources/navigation-destination.html'; 70 const result = await construct_custom_element_in_parser(this, `document.open('${url}', '_self', '')`); 71 assert_equals(result.exception, null); 72 assert_equals(await load_promise, 'didNavigate'); 73 }, 'document.open(URL) must NOT throw an InvalidStateError when synchronously constructing a custom element'); 74 75 promise_test(async function () { 76 const result = await construct_custom_element_in_parser(this, `document.close()`); 77 assert_not_equals(result.exception, null); 78 assert_throws_dom('InvalidStateError', result.window.DOMException, () => { throw result.exception; }, 'Must throw an InvalidStateError'); 79 }, 'document.close() must throw an InvalidStateError when synchronously constructing a custom element'); 80 81 promise_test(async function () { 82 const result = await construct_custom_element_in_parser(this, `document.write('<b>some text</b>')`); 83 assert_throws_dom('InvalidStateError', result.window.DOMException, () => { throw result.exception; }, 'Must throw an InvalidStateError'); 84 assert_equals(result.document.querySelector('b'), null, 'Must not insert new content'); 85 assert_false(result.document.body.innerHTML.includes('some text'), 'Must not insert new content'); 86 }, 'document.write must throw an InvalidStateError when synchronously constructing a custom element'); 87 88 promise_test(async function () { 89 const result = await construct_custom_element_in_parser(this, `document.writeln('<b>some text</b>')`); 90 assert_throws_dom('InvalidStateError', result.window.DOMException, () => { throw result.exception; }, 'Must throw an InvalidStateError'); 91 assert_equals(result.document.querySelector('b'), null, 'Must not insert new content'); 92 assert_false(result.document.body.innerHTML.includes('some text'), 'Must not insert new content'); 93 }, 'document.writeln must throw an InvalidStateError when synchronously constructing a custom element'); 94 95 promise_test(async function () { 96 window.another_window = await create_window_in_test_async(this, 'text/html', '<!DOCTYPE html><html><body>'); 97 const result = await construct_custom_element_in_parser(this, `top.another_window.document.open()`); 98 assert_equals(result.exception, null); 99 }, 'document.open() of another document must not throw an InvalidStateError when synchronously constructing a custom element'); 100 101 promise_test(async function () { 102 window.another_window = await create_window_in_test_async(this, 'text/html', '<!DOCTYPE html><html><body>'); 103 const result = await construct_custom_element_in_parser(this, `top.another_window.document.open('text/html')`); 104 assert_equals(result.exception, null); 105 }, 'document.open("text/html") of another document must not throw an InvalidStateError when synchronously constructing a custom element'); 106 107 promise_test(async function () { 108 window.another_window = await create_window_in_test_async(this, 'text/html', '<!DOCTYPE html><html><body>'); 109 const result = await construct_custom_element_in_parser(this, `top.another_window.document.close()`); 110 assert_equals(result.exception, null); 111 }, 'document.close() of another document must not throw an InvalidStateError when synchronously constructing a custom element'); 112 113 promise_test(async function () { 114 window.another_window = await create_window_in_test_async(this, 'text/html', '<!DOCTYPE html><html><body>'); 115 const result = await construct_custom_element_in_parser(this, `top.another_window.document.write('<b>some text</b>')`); 116 assert_equals(result.exception, null); 117 assert_equals(another_window.document.querySelector('b').outerHTML, '<b>some text</b>'); 118 }, 'document.write of another document must not throw an InvalidStateError when synchronously constructing a custom element'); 119 120 promise_test(async function () { 121 window.another_window = await create_window_in_test_async(this, 'text/html', '<!DOCTYPE html><html><body>'); 122 const result = await construct_custom_element_in_parser(this, `top.another_window.document.writeln('<b>some text</b>')`); 123 assert_equals(result.exception, null); 124 assert_equals(another_window.document.querySelector('b').outerHTML, '<b>some text</b>'); 125 }, 'document.writeln of another document must not throw an InvalidStateError when synchronously constructing a custom element'); 126 127 ]]> 128 </script> 129 </body> 130 </html>