WebKit Bugzilla
Attachment 346735 Details for
Bug 187319
: document.open and document.write must throw while the HTML parser is synchronously constructing a custom element
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for landing
bug-187319-20180807144725.patch (text/plain), 32.03 KB, created by
Ryosuke Niwa
on 2018-08-07 14:47:26 PDT
(
hide
)
Description:
Patch for landing
Filename:
MIME Type:
Creator:
Ryosuke Niwa
Created:
2018-08-07 14:47:26 PDT
Size:
32.03 KB
patch
obsolete
>Index: Source/WebCore/ChangeLog >=================================================================== >--- Source/WebCore/ChangeLog (revision 234673) >+++ Source/WebCore/ChangeLog (working copy) >@@ -1,3 +1,33 @@ >+2018-08-07 Ryosuke Niwa <rniwa@webkit.org> >+ >+ document.open and document.write must throw while the HTML parser is synchronously constructing a custom element >+ https://bugs.webkit.org/show_bug.cgi?id=187319 >+ <rdar://problem/42843012> >+ >+ Reviewed by Frédéric Wang. >+ >+ Make document.open, document.write, document.writeln, and document.close throw InvalidStateError during >+ a synchronous custom element construction as specified: >+ https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token >+ https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#throw-on-dynamic-markup-insertion-counter >+ >+ Tests: fast/custom-elements/throw-on-dynamic-markup-insertion-counter-construct.html >+ fast/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions.html >+ >+ * WebCore.xcodeproj/project.pbxproj: >+ * dom/Document.cpp: >+ (WebCore::Document::openForBindings): Throw InvalidStateError when m_throwOnDynamicMarkupInsertionCount is non-zero. >+ (WebCore::Document::closeForBindings): Ditto. >+ (WebCore::Document::write): Ditto. >+ (WebCore::Document::writeln): Ditto. >+ * dom/Document.h: Re-ordered the related instance variables in the order they appear in the spec, and updated spec URLs. >+ * dom/ThrowOnDynamicMarkupInsertionCountIncrementer.h: Added. >+ (WebCore::ThrowOnDynamicMarkupInsertionCountIncrementer): Added. >+ (WebCore::ThrowOnDynamicMarkupInsertionCountIncrementer::ThrowOnDynamicMarkupInsertionCountIncrementer): >+ (WebCore::ThrowOnDynamicMarkupInsertionCountIncrementer::~ThrowOnDynamicMarkupInsertionCountIncrementer): >+ * html/parser/HTMLDocumentParser.cpp: >+ (WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder): Instantiate ThrowOnDynamicMarkupInsertionCountIncrementer. >+ > 2018-08-06 Ryosuke Niwa <rniwa@webkit.org> > > document.open and document.write must throw while the HTML parser is synchronously constructing a custom element >Index: Source/WebCore/WebCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/WebCore/WebCore.xcodeproj/project.pbxproj (revision 234673) >+++ Source/WebCore/WebCore.xcodeproj/project.pbxproj (working copy) >@@ -10859,6 +10859,7 @@ > 9B32CDA813DF7FA900F34D13 /* RenderedPosition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderedPosition.cpp; sourceTree = "<group>"; }; > 9B417062125662B3006B28FC /* ApplyBlockElementCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplyBlockElementCommand.h; sourceTree = "<group>"; }; > 9B417063125662B3006B28FC /* ApplyBlockElementCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ApplyBlockElementCommand.cpp; sourceTree = "<group>"; }; >+ 9B4376EF2117E872009D03A0 /* ThrowOnDynamicMarkupInsertionCountIncrementer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ThrowOnDynamicMarkupInsertionCountIncrementer.h; sourceTree = "<group>"; }; > 9B50B1DC17CD4C0F0087F63C /* FormNamedItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormNamedItem.h; sourceTree = "<group>"; }; > 9B532EA11BA928570038A827 /* SlotAssignment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlotAssignment.cpp; sourceTree = "<group>"; }; > 9B532EA21BA928570038A827 /* SlotAssignment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlotAssignment.h; sourceTree = "<group>"; }; >@@ -26575,6 +26576,7 @@ > A77B419F12E675A90054343D /* TextEventInputType.h */, > E4D988B517BFEB210084FB88 /* TextNodeTraversal.cpp */, > E4D988B317BFD1F60084FB88 /* TextNodeTraversal.h */, >+ 9B4376EF2117E872009D03A0 /* ThrowOnDynamicMarkupInsertionCountIncrementer.h */, > 0F54DD051881D5F5003EEDBB /* Touch.h */, > 0F54DD061881D5F5003EEDBB /* TouchEvent.h */, > 0F54DD071881D5F5003EEDBB /* TouchList.h */, >Index: Source/WebCore/dom/Document.cpp >=================================================================== >--- Source/WebCore/dom/Document.cpp (revision 234673) >+++ Source/WebCore/dom/Document.cpp (working copy) >@@ -2609,12 +2609,9 @@ ExceptionOr<RefPtr<WindowProxy>> Documen > // FIXME: Add support for the 'type' and 'replace' parameters. > ExceptionOr<Document&> Document::openForBindings(Document* responsibleDocument, const String&, const String&) > { >- if (!isHTMLDocument()) >+ if (!isHTMLDocument() || m_throwOnDynamicMarkupInsertionCount) > return Exception { InvalidStateError }; > >- // FIXME: This should also throw if "document's throw-on-dynamic-markup-insertion counter is greater than 0". >- // https://bugs.webkit.org/show_bug.cgi?id=187319 >- > open(responsibleDocument); > return *this; > } >@@ -2753,12 +2750,9 @@ ExceptionOr<void> Document::closeForBind > // FIXME: We should follow the specification more closely: > // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-close > >- if (!isHTMLDocument()) >+ if (!isHTMLDocument() || m_throwOnDynamicMarkupInsertionCount) > return Exception { InvalidStateError }; > >- // FIXME: This should also throw if "document's throw-on-dynamic-markup-insertion counter is greater than 0". >- // https://bugs.webkit.org/show_bug.cgi?id=187319 >- > close(); > return { }; > } >@@ -2984,12 +2978,9 @@ void Document::write(Document* responsib > > ExceptionOr<void> Document::write(Document* responsibleDocument, Vector<String>&& strings) > { >- if (!isHTMLDocument()) >+ if (!isHTMLDocument() || m_throwOnDynamicMarkupInsertionCount) > return Exception { InvalidStateError }; > >- // FIXME: This should also throw if "document's throw-on-dynamic-markup-insertion counter is greater than 0". >- // https://bugs.webkit.org/show_bug.cgi?id=187319 >- > SegmentedString text; > for (auto& string : strings) > text.append(WTFMove(string)); >@@ -3001,12 +2992,9 @@ ExceptionOr<void> Document::write(Docume > > ExceptionOr<void> Document::writeln(Document* responsibleDocument, Vector<String>&& strings) > { >- if (!isHTMLDocument()) >+ if (!isHTMLDocument() || m_throwOnDynamicMarkupInsertionCount) > return Exception { InvalidStateError }; > >- // FIXME: This should also throw if "document's throw-on-dynamic-markup-insertion counter is greater than 0". >- // https://bugs.webkit.org/show_bug.cgi?id=187319 >- > SegmentedString text; > for (auto& string : strings) > text.append(WTFMove(string)); >Index: Source/WebCore/dom/Document.h >=================================================================== >--- Source/WebCore/dom/Document.h (revision 234673) >+++ Source/WebCore/dom/Document.h (working copy) >@@ -1480,8 +1480,9 @@ protected: > private: > friend class DocumentParserYieldToken; > friend class Node; >- friend class IgnoreDestructiveWriteCountIncrementer; >+ friend class ThrowOnDynamicMarkupInsertionCountIncrementer; > friend class IgnoreOpensDuringUnloadCountIncrementer; >+ friend class IgnoreDestructiveWriteCountIncrementer; > > bool shouldInheritContentSecurityPolicyFromOwner() const; > >@@ -1854,12 +1855,15 @@ private: > int m_loadEventDelayCount { 0 }; > unsigned m_lastStyleUpdateSizeForTesting { 0 }; > >- // https://html.spec.whatwg.org/multipage/webappapis.html#ignore-destructive-writes-counter >- unsigned m_ignoreDestructiveWriteCount { 0 }; >+ // https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#throw-on-dynamic-markup-insertion-counter >+ unsigned m_throwOnDynamicMarkupInsertionCount { 0 }; > >- // https://html.spec.whatwg.org/multipage/webappapis.html#ignore-opens-during-unload-counter >+ // https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#ignore-opens-during-unload-counter > unsigned m_ignoreOpensDuringUnloadCount { 0 }; > >+ // https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#ignore-destructive-writes-counter >+ unsigned m_ignoreDestructiveWriteCount { 0 }; >+ > unsigned m_activeParserCount { 0 }; > unsigned m_styleRecalcCount { 0 }; > >Index: Source/WebCore/dom/ThrowOnDynamicMarkupInsertionCountIncrementer.h >=================================================================== >--- Source/WebCore/dom/ThrowOnDynamicMarkupInsertionCountIncrementer.h (nonexistent) >+++ Source/WebCore/dom/ThrowOnDynamicMarkupInsertionCountIncrementer.h (working copy) >@@ -0,0 +1,51 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "Document.h" >+ >+namespace WebCore { >+ >+class ThrowOnDynamicMarkupInsertionCountIncrementer { >+ WTF_MAKE_NONCOPYABLE(ThrowOnDynamicMarkupInsertionCountIncrementer); >+public: >+ explicit ThrowOnDynamicMarkupInsertionCountIncrementer(Document& document) >+ : m_document(document) >+ { >+ ++document.m_throwOnDynamicMarkupInsertionCount; >+ } >+ >+ ~ThrowOnDynamicMarkupInsertionCountIncrementer() >+ { >+ ASSERT(m_document->m_throwOnDynamicMarkupInsertionCount); >+ --m_document->m_throwOnDynamicMarkupInsertionCount; >+ } >+ >+private: >+ Ref<Document> m_document; >+}; >+ >+} // namespace WebCore >Index: Source/WebCore/html/parser/HTMLDocumentParser.cpp >=================================================================== >--- Source/WebCore/html/parser/HTMLDocumentParser.cpp (revision 234673) >+++ Source/WebCore/html/parser/HTMLDocumentParser.cpp (working copy) >@@ -41,6 +41,7 @@ > #include "LinkLoader.h" > #include "NavigationScheduler.h" > #include "ScriptElement.h" >+#include "ThrowOnDynamicMarkupInsertionCountIncrementer.h" > > namespace WebCore { > >@@ -210,6 +211,8 @@ void HTMLDocumentParser::runScriptsForPa > > // https://html.spec.whatwg.org/#create-an-element-for-the-token > { >+ // Prevent document.open/write during reactions by allocating the incrementer before the reactions stack. >+ ThrowOnDynamicMarkupInsertionCountIncrementer incrementer(*document()); > CustomElementReactionStack reactionStack(document()->execState()); > auto& elementInterface = constructionData->elementInterface.get(); > auto newElement = elementInterface.constructElementWithFallback(*document(), constructionData->name); >Index: LayoutTests/ChangeLog >=================================================================== >--- LayoutTests/ChangeLog (revision 234673) >+++ LayoutTests/ChangeLog (working copy) >@@ -1,3 +1,20 @@ >+2018-08-07 Ryosuke Niwa <rniwa@webkit.org> >+ >+ document.open and document.write must throw while the HTML parser is synchronously constructing a custom element >+ https://bugs.webkit.org/show_bug.cgi?id=187319 >+ <rdar://problem/42843012> >+ >+ Reviewed by Frédéric Wang. >+ >+ Added W3C style testharness.js tests. The WPT test added by https://github.com/web-platform-tests/wpt/pull/12037 >+ doesn't test nearly as many edge cases. >+ >+ * fast/custom-elements/resources/navigation-destination.html: Added. >+ * fast/custom-elements/throw-on-dynamic-markup-insertion-counter-construct-expected.txt: Added. >+ * fast/custom-elements/throw-on-dynamic-markup-insertion-counter-construct.html: Added. >+ * fast/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions-expected.txt: Added. >+ * fast/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions.html: Added. >+ > 2018-08-07 Commit Queue <commit-queue@webkit.org> > > Unreviewed, rolling out r234669. >Index: LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-construct-expected.txt >=================================================================== >--- LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-construct-expected.txt (nonexistent) >+++ LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-construct-expected.txt (working copy) >@@ -0,0 +1,13 @@ >+ >+PASS document.open() must throw an InvalidStateError when synchronously constructing a custom element >+PASS document.open("text/html") must throw an InvalidStateError when synchronously constructing a custom element >+PASS document.open(URL) must NOT throw an InvalidStateError when synchronously constructing a custom element >+PASS document.close() must throw an InvalidStateError when synchronously constructing a custom element >+PASS document.write must throw an InvalidStateError when synchronously constructing a custom element >+PASS document.writeln must throw an InvalidStateError when synchronously constructing a custom element >+PASS document.open() of another document must not throw an InvalidStateError when synchronously constructing a custom element >+PASS document.open("text/html") of another document must not throw an InvalidStateError when synchronously constructing a custom element >+PASS document.close() of another document must not throw an InvalidStateError when synchronously constructing a custom element >+PASS document.write of another document must not throw an InvalidStateError when synchronously constructing a custom element >+PASS document.writeln of another document must not throw an InvalidStateError when synchronously constructing a custom element >+ >Index: LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-construct.html >=================================================================== >--- LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-construct.html (nonexistent) >+++ LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-construct.html (working copy) >@@ -0,0 +1,117 @@ >+<!DOCTYPE html> >+<html> >+<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="../../imported/w3c/web-platform-tests/custom-elements/resources/custom-elements-helpers.js"></script> >+</head> >+<body> >+<div id="log"></div> >+<script> >+ >+async function construct_custom_element_in_parser(test, call_function) >+{ >+ const window = await create_window_in_test(test); >+ const document = window.document; >+ >+ document.open(); >+ >+ let executed = false; >+ let exception = null; >+ class CustomElement extends window.HTMLElement { >+ constructor() { >+ super(); >+ try { >+ call_function(document, window); >+ } catch (error) { >+ exception = error; >+ } >+ executed = true; >+ } >+ } >+ window.customElements.define('some-element', CustomElement); >+ >+ document.write('<!DOCTYPE html><html><body><some-element></some-element></body></html>'); >+ document.close(); >+ >+ assert_true(executed, 'Must synchronously instantiate a custom element'); >+ return {window, document, exception}; >+} >+ >+promise_test(async function () { >+ const result = await construct_custom_element_in_parser(this, (document) => document.open()); >+ assert_throws({name: 'InvalidStateError'}, () => { throw result.exception; }, 'Must throw an InvalidStateError'); >+}, 'document.open() must throw an InvalidStateError when synchronously constructing a custom element'); >+ >+promise_test(async function () { >+ const result = await construct_custom_element_in_parser(this, (document) => document.open('text/html')); >+ assert_throws({name: 'InvalidStateError'}, () => { throw result.exception; }, 'Must throw an InvalidStateError'); >+}, 'document.open("text/html") must throw an InvalidStateError when synchronously constructing a 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 result = await construct_custom_element_in_parser(this, (document, window) => document.open('resources/navigation-destination.html', '_self', '')); >+ assert_equals(result.exception, null); >+ assert_equals(await load_promise, 'didNavigate'); >+}, 'document.open(URL) must NOT throw an InvalidStateError when synchronously constructing a custom element'); >+ >+promise_test(async function () { >+ const result = await construct_custom_element_in_parser(this, (document) => document.close()); >+ assert_throws({name: 'InvalidStateError'}, () => { throw result.exception; }, 'Must throw an InvalidStateError'); >+}, 'document.close() must throw an InvalidStateError when synchronously constructing a custom element'); >+ >+promise_test(async function () { >+ const result = await construct_custom_element_in_parser(this, (document) => document.write('<b>some text</b>')); >+ assert_throws({name: 'InvalidStateError'}, () => { throw result.exception; }, 'Must throw an InvalidStateError'); >+ assert_equals(result.document.querySelector('b'), null, 'Must not insert new content'); >+ assert_false(result.document.documentElement.innerHTML.includes('some text'), 'Must not insert new content'); >+}, 'document.write must throw an InvalidStateError when synchronously constructing a custom element'); >+ >+promise_test(async function () { >+ const result = await construct_custom_element_in_parser(this, (document) => document.writeln('<b>some text</b>')); >+ assert_throws({name: 'InvalidStateError'}, () => { throw result.exception; }, 'Must throw an InvalidStateError'); >+ assert_equals(result.document.querySelector('b'), null, 'Must not insert new content'); >+ assert_false(result.document.documentElement.innerHTML.includes('some text'), 'Must not insert new content'); >+}, 'document.writeln must throw an InvalidStateError when synchronously constructing a custom element'); >+ >+promise_test(async function () { >+ const another_window = await create_window_in_test(this); >+ const result = await construct_custom_element_in_parser(this, (document) => another_window.document.open()); >+ assert_equals(result.exception, null); >+}, 'document.open() of another document must not throw an InvalidStateError when synchronously constructing a custom element'); >+ >+promise_test(async function () { >+ const another_window = await create_window_in_test(this); >+ const result = await construct_custom_element_in_parser(this, (document) => another_window.document.open('text/html')); >+ assert_equals(result.exception, null); >+}, 'document.open("text/html") of another document must not throw an InvalidStateError when synchronously constructing a custom element'); >+ >+promise_test(async function () { >+ const another_window = await create_window_in_test(this); >+ const result = await construct_custom_element_in_parser(this, (document) => another_window.document.close()); >+ assert_equals(result.exception, null); >+}, 'document.close() of another document must not throw an InvalidStateError when synchronously constructing a custom element'); >+ >+promise_test(async function () { >+ const another_window = await create_window_in_test(this); >+ const result = await construct_custom_element_in_parser(this, (document) => 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 synchronously constructing a custom element'); >+ >+promise_test(async function () { >+ const another_window = await create_window_in_test(this); >+ const result = await construct_custom_element_in_parser(this, (document) => 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 synchronously constructing a custom element'); >+ >+</script> >+</body> >+</html> >Index: LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions-expected.txt >=================================================================== >--- LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions-expected.txt (nonexistent) >+++ LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions-expected.txt (working copy) >@@ -0,0 +1,13 @@ >+ >+PASS document.open() must throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+PASS document.open("text/html") must throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+PASS document.open(URL) must NOT throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+PASS document.close() must throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+PASS document.write must throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+PASS document.writeln must throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+PASS document.open() of another document must not throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+PASS document.open("text/html") of another document must not throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+PASS document.close() of another document must not throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+PASS document.write of another document must not throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+PASS document.writeln of another document must not throw an InvalidStateError when processing custom element reactions for a synchronous constructed custom element >+ >Index: LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions.html >=================================================================== >--- LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions.html (nonexistent) >+++ LayoutTests/fast/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions.html (working copy) >@@ -0,0 +1,117 @@ >+<!DOCTYPE html> >+<html> >+<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="../../imported/w3c/web-platform-tests/custom-elements/resources/custom-elements-helpers.js"></script> >+</head> >+<body> >+<div id="log"></div> >+<script> >+ >+async function custom_element_reactions_in_parser(test, call_function) >+{ >+ const window = await create_window_in_test(test); >+ const document = window.document; >+ >+ document.open(); >+ >+ let executed = false; >+ let exception = null; >+ class CustomElement extends window.HTMLElement { >+ attributeChangedCallback(name, oldValue, newValue) { >+ try { >+ call_function(document, window); >+ } catch (error) { >+ exception = error; >+ } >+ executed = true; >+ } >+ } >+ CustomElement.observedAttributes = ['title']; >+ window.customElements.define('some-element', CustomElement); >+ >+ document.write('<!DOCTYPE html><html><body><some-element title="some title"></some-element></body></html>'); >+ document.close(); >+ >+ assert_true(executed, 'Must immediately process custom element reactions for setting attributes'); >+ return {frameElement, window, document, exception}; >+} >+ >+promise_test(async function () { >+ const result = await custom_element_reactions_in_parser(this, (document) => document.open()); >+ assert_throws({name: 'InvalidStateError'}, () => { 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) => document.open('text/html')); >+ assert_throws({name: 'InvalidStateError'}, () => { 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 result = await custom_element_reactions_in_parser(this, (document, window) => document.open('resources/navigation-destination.html', '_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) => document.close()); >+ assert_throws({name: 'InvalidStateError'}, () => { 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) => document.write('<b>some text</b>')); >+ assert_throws({name: 'InvalidStateError'}, () => { throw result.exception; }, 'Must throw an InvalidStateError'); >+ assert_equals(result.document.querySelector('b'), null, 'Must not insert new content'); >+ assert_false(result.document.documentElement.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) => document.writeln('<b>some text</b>')); >+ assert_throws({name: 'InvalidStateError'}, () => { throw result.exception; }, 'Must throw an InvalidStateError'); >+ assert_equals(result.document.querySelector('b'), null, 'Must not insert new content'); >+ assert_false(result.document.documentElement.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 () { >+ const another_window = await create_window_in_test(this); >+ const result = await custom_element_reactions_in_parser(this, (document) => 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 () { >+ const another_window = await create_window_in_test(this); >+ const result = await custom_element_reactions_in_parser(this, (document) => 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 () { >+ const another_window = await create_window_in_test(this); >+ const result = await custom_element_reactions_in_parser(this, (document) => 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 () { >+ const another_window = await create_window_in_test(this); >+ const result = await custom_element_reactions_in_parser(this, (document) => 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 () { >+ const another_window = await create_window_in_test(this); >+ const result = await custom_element_reactions_in_parser(this, (document) => 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> >Index: LayoutTests/fast/custom-elements/resources/navigation-destination.html >=================================================================== >--- LayoutTests/fast/custom-elements/resources/navigation-destination.html (nonexistent) >+++ LayoutTests/fast/custom-elements/resources/navigation-destination.html (working copy) >@@ -0,0 +1,9 @@ >+<!DOCTYPE html> >+<html> >+<body> >+<p>Navigated!</p> >+<script> >+parent.postMessage('didNavigate', '*'); >+</script> >+</body> >+</html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
rniwa
:
commit-queue+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 187319
:
346686
|
346687
|
346729
| 346735