WebKit Bugzilla
Attachment 346152 Details for
Bug 188190
: XML Parser should invoke reactions when creating/inserting new custom elements
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP Patch
188190.patch (text/plain), 13.46 KB, created by
Frédéric Wang (:fredw)
on 2018-07-31 04:21:17 PDT
(
hide
)
Description:
WIP Patch
Filename:
MIME Type:
Creator:
Frédéric Wang (:fredw)
Created:
2018-07-31 04:21:17 PDT
Size:
13.46 KB
patch
obsolete
>diff --git a/LayoutTests/imported/w3c/web-platform-tests/custom-elements/parser/parser-sets-attributes-and-children-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/custom-elements/parser/parser-sets-attributes-and-children-expected.txt >index e2317aa63f7..036dba33e10 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/custom-elements/parser/parser-sets-attributes-and-children-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/custom-elements/parser/parser-sets-attributes-and-children-expected.txt >@@ -2,6 +2,6 @@ > PASS HTML parser must set the attributes > PASS HTML parser must append child nodes > PASS HTML parser must set the attributes or append children before calling constructor >-FAIL HTML parser should call connectedCallback before appending child nodes. assert_equals: expected 0 but got 2 >-FAIL HTML parser must enqueue attributeChanged reactions assert_equals: attributeChangedCallback should be called before appending a child expected 0 but got 2 >+PASS HTML parser should call connectedCallback before appending child nodes. >+PASS HTML parser must enqueue attributeChanged reactions > hello world >diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.cpp b/Source/WebCore/html/parser/HTMLConstructionSite.cpp >index 023c8fd7f35..c2ff10038b8 100644 >--- a/Source/WebCore/html/parser/HTMLConstructionSite.cpp >+++ b/Source/WebCore/html/parser/HTMLConstructionSite.cpp >@@ -28,6 +28,7 @@ > #include "HTMLTreeBuilder.h" > > #include "Comment.h" >+#include "CustomElementReactionQueue.h" > #include "CustomElementRegistry.h" > #include "DOMWindow.h" > #include "DocumentFragment.h" >@@ -118,7 +119,13 @@ static inline void executeInsertTask(HTMLConstructionSiteTask& task) > { > ASSERT(task.operation == HTMLConstructionSiteTask::Insert); > >+ // Custom element reactions are executed after inserting a custom element. >+ // See https://html.spec.whatwg.org/#insert-a-foreign-element >+ std::optional<CustomElementReactionStack> customElementReactionStack; >+ if (UNLIKELY(task.mayRunConnectedCallback)) >+ customElementReactionStack.emplace(); > insert(task); >+ customElementReactionStack.reset(); > > task.child->beginParsingChildren(); > >@@ -188,7 +195,7 @@ static inline void executeTask(HTMLConstructionSiteTask& task) > ASSERT_NOT_REACHED(); > } > >-void HTMLConstructionSite::attachLater(ContainerNode& parent, Ref<Node>&& child, bool selfClosing) >+void HTMLConstructionSite::attachLater(ContainerNode& parent, Ref<Node>&& child, bool selfClosing, bool mayRunConnectedCallback) > { > ASSERT(scriptingContentIsAllowed(m_parserContentPolicy) || !is<Element>(child) || !isScriptElement(downcast<Element>(child.get()))); > ASSERT(pluginContentIsAllowed(m_parserContentPolicy) || !child->isPluginElement()); >@@ -202,6 +209,7 @@ void HTMLConstructionSite::attachLater(ContainerNode& parent, Ref<Node>&& child, > task.parent = &parent; > task.child = WTFMove(child); > task.selfClosing = selfClosing; >+ task.mayRunConnectedCallback = mayRunConnectedCallback; > > // Add as a sibling of the parent if we have reached the maximum depth allowed. > if (m_openElements.stackDepth() > m_maximumDOMTreeDepth && task.parent->parentNode()) >@@ -509,10 +517,14 @@ std::unique_ptr<CustomElementConstructionData> HTMLConstructionSite::insertHTMLE > return nullptr; > } > >-void HTMLConstructionSite::insertCustomElement(Ref<Element>&& element, const AtomicString& localName, Vector<Attribute>&& attributes) >+void HTMLConstructionSite::setAttributeOnCustomElement(Ref<Element>&& element, Vector<Attribute>&& attributes) > { > setAttributes(element, attributes, m_parserContentPolicy); >- attachLater(currentNode(), element.copyRef()); >+} >+ >+void HTMLConstructionSite::insertCustomElement(Ref<Element>&& element, const AtomicString& localName, Vector<Attribute>&& attributes, bool mayRunConnectedCallback) >+{ >+ attachLater(currentNode(), element.copyRef(), false, mayRunConnectedCallback); > m_openElements.push(HTMLStackItem::create(WTFMove(element), localName, WTFMove(attributes))); > } > >@@ -602,7 +614,8 @@ void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMo > ASSERT(currentPosition <= characters.length()); > task.child = WTFMove(textNode); > >- executeTask(task); >+ // FIXME: Execute the task immediately if task.parent is a not custom element? >+ m_taskQueue.append(WTFMove(task)); > } > } > >diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.h b/Source/WebCore/html/parser/HTMLConstructionSite.h >index 96e64cfc7a9..dea07bb9df8 100644 >--- a/Source/WebCore/html/parser/HTMLConstructionSite.h >+++ b/Source/WebCore/html/parser/HTMLConstructionSite.h >@@ -63,6 +63,7 @@ struct HTMLConstructionSiteTask { > RefPtr<Node> nextChild; > RefPtr<Node> child; > bool selfClosing; >+ bool mayRunConnectedCallback { false }; > }; > > } // namespace WebCore >@@ -104,7 +105,8 @@ public: > void insertCommentOnHTMLHtmlElement(AtomicHTMLToken&&); > void insertHTMLElement(AtomicHTMLToken&&); > std::unique_ptr<CustomElementConstructionData> insertHTMLElementOrFindCustomElementInterface(AtomicHTMLToken&&); >- void insertCustomElement(Ref<Element>&&, const AtomicString& localName, Vector<Attribute>&&); >+ void setAttributeOnCustomElement(Ref<Element>&&, Vector<Attribute>&&); >+ void insertCustomElement(Ref<Element>&&, const AtomicString& localName, Vector<Attribute>&&, bool mayRunConnectedCallback); > void insertSelfClosingHTMLElement(AtomicHTMLToken&&); > void insertFormattingElement(AtomicHTMLToken&&); > void insertHTMLHeadElement(AtomicHTMLToken&&); >@@ -182,7 +184,7 @@ private: > void setCompatibilityMode(DocumentCompatibilityMode); > void setCompatibilityModeFromDoctype(const String& name, const String& publicId, const String& systemId); > >- void attachLater(ContainerNode& parent, Ref<Node>&& child, bool selfClosing = false); >+ void attachLater(ContainerNode& parent, Ref<Node>&& child, bool selfClosing = false, bool mayRunConnectedCallback = false); > > void findFosterSite(HTMLConstructionSiteTask&); > >diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.cpp b/Source/WebCore/html/parser/HTMLDocumentParser.cpp >index c9cc3ac91e0..b9791818f50 100644 >--- a/Source/WebCore/html/parser/HTMLDocumentParser.cpp >+++ b/Source/WebCore/html/parser/HTMLDocumentParser.cpp >@@ -27,6 +27,9 @@ > #include "config.h" > #include "HTMLDocumentParser.h" > >+#include "CustomElementReactionQueue.h" >+#include "CustomElementRegistry.h" >+#include "DOMWindow.h" > #include "DocumentFragment.h" > #include "DocumentLoader.h" > #include "Frame.h" >@@ -207,10 +210,41 @@ void HTMLDocumentParser::runScriptsForPausedTreeBuilder() > if (std::unique_ptr<CustomElementConstructionData> constructionData = m_treeBuilder->takeCustomElementConstructionData()) { > ASSERT(!m_treeBuilder->hasParserBlockingScriptWork()); > >+ // Code below follows steps to create an element for a token. > // https://html.spec.whatwg.org/#create-an-element-for-the-token >+ // Step 5. >+ bool willExecuteScript = false; >+ if (!isParsingFragment()) { >+ if (auto* window = document()->domWindow()) { >+ auto* registry = window->customElementRegistry(); >+ if (UNLIKELY(registry)) >+ willExecuteScript = registry->findInterface(constructionData->name); >+ } >+ } >+ >+ std::optional<CustomElementReactionStack> customElementReactionStack; >+ if (willExecuteScript) { >+ // Step 6. >+ // FIXME(https://webkit.org/b/187319): throw-on-dynamic-markup-insertion should be incremented. >+ // FIXME(https://webkit.org/b/188189): A microstask checkpoint should be performed. >+ customElementReactionStack.emplace(); >+ } >+ >+ // Step 7. >+ // FIXME(https://webkit.org/b/183586): The "synchronous custom element" flag should be set to true when willExecuteScript is true. > auto& elementInterface = constructionData->elementInterface.get(); > auto newElement = elementInterface.constructElementWithFallback(*document(), constructionData->name); >- m_treeBuilder->didCreateCustomOrFallbackElement(WTFMove(newElement), *constructionData); >+ >+ // Step 8. >+ m_treeBuilder->setAttributeOnCustomOrFallbackElement(WTFMove(newElement), *constructionData); >+ >+ // Step 9. >+ if (willExecuteScript) { >+ // FIXME(https://webkit.org/b/187319): throw-on-dynamic-markup-insertion should be decremented. >+ customElementReactionStack.reset(); >+ } >+ >+ m_treeBuilder->insertCustomOrFallbackElement(WTFMove(newElement), *constructionData, willExecuteScript); > return; > } > >diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp >index e40f9a886f1..90895b6cfca 100644 >--- a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp >+++ b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp >@@ -873,9 +873,14 @@ inline void HTMLTreeBuilder::insertGenericHTMLElement(AtomicHTMLToken&& token) > m_customElementToConstruct = m_tree.insertHTMLElementOrFindCustomElementInterface(WTFMove(token)); > } > >-void HTMLTreeBuilder::didCreateCustomOrFallbackElement(Ref<Element>&& element, CustomElementConstructionData& data) >+void HTMLTreeBuilder::setAttributeOnCustomOrFallbackElement(Ref<Element>&& element, CustomElementConstructionData& data) > { >- m_tree.insertCustomElement(WTFMove(element), data.name, WTFMove(data.attributes)); >+ m_tree.setAttributeOnCustomElement(WTFMove(element), WTFMove(data.attributes)); >+} >+ >+void HTMLTreeBuilder::insertCustomOrFallbackElement(Ref<Element>&& element, CustomElementConstructionData& data, bool mayRunConnectedCallback) >+{ >+ m_tree.insertCustomElement(WTFMove(element), data.name, WTFMove(data.attributes), mayRunConnectedCallback); > } > > void HTMLTreeBuilder::processTemplateStartTag(AtomicHTMLToken&& token) >diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.h b/Source/WebCore/html/parser/HTMLTreeBuilder.h >index c563abafa0c..5be47c90ddf 100644 >--- a/Source/WebCore/html/parser/HTMLTreeBuilder.h >+++ b/Source/WebCore/html/parser/HTMLTreeBuilder.h >@@ -66,7 +66,8 @@ public: > RefPtr<ScriptElement> takeScriptToProcess(TextPosition& scriptStartPosition); > > std::unique_ptr<CustomElementConstructionData> takeCustomElementConstructionData() { return WTFMove(m_customElementToConstruct); } >- void didCreateCustomOrFallbackElement(Ref<Element>&&, CustomElementConstructionData&); >+ void setAttributeOnCustomOrFallbackElement(Ref<Element>&&, CustomElementConstructionData&); >+ void insertCustomOrFallbackElement(Ref<Element>&&, CustomElementConstructionData&, bool mayRunConnectedCallback); > > // Done, close any open tags, etc. > void finished(); >diff --git a/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp b/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp >index 80973e98550..c4814e02c94 100644 >--- a/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp >+++ b/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp >@@ -31,6 +31,9 @@ > #include "CDATASection.h" > #include "Comment.h" > #include "CachedResourceLoader.h" >+#include "CustomElementReactionQueue.h" >+#include "CustomElementRegistry.h" >+#include "DOMWindow.h" > #include "Document.h" > #include "DocumentFragment.h" > #include "DocumentType.h" >@@ -781,6 +784,28 @@ void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlCha > m_sawFirstElement = true; > > QualifiedName qName(prefix, localName, uri); >+ // Code below follows steps to create an element for a token. >+ // See https://html.spec.whatwg.org/#parsing-xhtml-documents:create-an-element-for-the-token >+ // Step 5. >+ bool willExecuteScript = false; >+ if (!m_parsingFragment) { >+ if (auto* window = m_currentNode->document().domWindow()) { >+ auto* registry = window->customElementRegistry(); >+ if (UNLIKELY(registry)) >+ willExecuteScript = registry->findInterface(qName); >+ } >+ } >+ >+ std::optional<CustomElementReactionStack> customElementReactionStack; >+ if (willExecuteScript) { >+ // Step 6. >+ // FIXME(https://webkit.org/b/187319): throw-on-dynamic-markup-insertion should be incremented. >+ // FIXME(https://webkit.org/b/188189): A microstask checkpoint should be performed. >+ customElementReactionStack.emplace(); >+ } >+ >+ // Step 7 and 8. >+ // FIXME(https://webkit.org/b/183586): The "synchronous custom element" flag should be set to true when willExecuteScript is true. > auto newElement = m_currentNode->document().createElement(qName, true); > > Vector<Attribute> prefixedAttributes; >@@ -797,12 +822,24 @@ void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlCha > return; > } > >+ // Step 9. >+ if (willExecuteScript) { >+ // FIXME(https://webkit.org/b/187319): throw-on-dynamic-markup-insertion should be decremented. >+ customElementReactionStack.reset(); >+ } >+ > newElement->beginParsingChildren(); > > if (isScriptElement(newElement.get())) > m_scriptStartPosition = textPosition(); > >+ // If this is a custom element that might become connected, ensure custom element reactions are >+ // called for consistency with the HTML parsing algorithm. >+ // See https://html.spec.whatwg.org/multipage/parsing.html#insert-a-foreign-element >+ if (willExecuteScript) >+ customElementReactionStack.emplace(); > m_currentNode->parserAppendChild(newElement); >+ customElementReactionStack.reset(); > if (!m_currentNode) // Synchronous DOM events may have removed the current node. > return; >
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:
ews-watchlist
:
commit-queue-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188190
:
346146
|
346152
|
346155
|
346156
|
346161
|
346163
|
346166
|
346189
|
461337