Make HTML parser construct custom elements
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Mar 2016 21:56:47 +0000 (21:56 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Mar 2016 21:56:47 +0000 (21:56 +0000)
commit0e065d6c60cdf15803893061b68da7b30936faab
treeab77d113a3651bb2b76fd166e06fb80682707612
parentc717b093b1386f0b9b4b7742f8223657c7e4f04b
Make HTML parser construct custom elements
https://bugs.webkit.org/show_bug.cgi?id=154908
Source/WebCore:

<rdar://problem/24923735>

Reviewed by Antti Koivisto.

Added the support for instantiating custom elements inside the parser. Based on Jan F2F discussion,
the HTML parser is going to synchronously construct custom elements. When a custom element constructor
throws, the HTML parser creates a HTMLUnknownElement instead.

In our implementation, we pause the parser completely and construct custom elements using the same
mechanism used to run author scripts. It's possible that we may want to apply some optimizations to
to make custom element construction but it's probably a good idea to get semantics right first.

Tests: fast/custom-elements/parser/parser-constructs-custom-elements.html
       fast/custom-elements/parser/parser-fallsback-to-unknown-element.html
       fast/custom-elements/parser/parser-sets-attributes-and-children.html
       fast/custom-elements/parser/parser-uses-constructed-element.html

* bindings/js/JSCustomElementInterface.cpp:
(WebCore::JSCustomElementInterface::constructElement): Added ShouldClearException as an argument
to be used by the HTML parser since the parser can't re-throw to anywhere or fail parsing.

* bindings/js/JSCustomElementInterface.h:
(WebCore::JSCustomElementInterface::ShouldClearException): Added.

* dom/Document.cpp:
(WebCore::createHTMLElementWithNameValidation): Do not clear the exception here since createElement
must re-throw the exception thrown by a custom element constructor.
(WebCore::Document::createElementForBindings):

* dom/make_names.pl:
(printFactoryCppFile): Added ConstructorFunctionMapEntry which contains the constructor function
as well as the qualified name.
(printFactoryHeaderFile): Added a variant of createKnownElement and createElement that takes
AtomicString instead of QualifiedName.

* html/parser/HTMLConstructionSite.cpp:
(WebCore::setAttributes): Added a variant that takes Vector<Attribute>.
(WebCore::HTMLConstructionSite::insertHTMLElementOrFindCustomElementInterface): Added. Returns a
custom element interface when the element doesn't match any builtin element and there is a custom
element definition that matches the specified name.
(WebCore::HTMLConstructionSite::insertCustomElement): Added. Like insertElement but also sets the
attributes on the newly created custom element.
(WebCore::HTMLConstructionSite::createHTMLElementOrFindCustomElementInterface): Extracted from
createHTMLElement. When customElementInterface is not nullptr, we optionally find the custom
element interface and return nullptr.
(WebCore::HTMLConstructionSite::createHTMLElement):
* html/parser/HTMLConstructionSite.h:

* html/parser/HTMLDocumentParser.cpp:
(WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder): Create a custom element when there
is a pending custom element to create (i.e. m_customElementToConstruct is not empty).
(WebCore::HTMLDocumentParser::isWaitingForScripts):

* html/parser/HTMLStackItem.h:
(WebCore::HTMLStackItem::create): Added a variant used for custom elements.
(WebCore::HTMLStackItem::HTMLStackItem): Ditto.

* html/parser/HTMLTreeBuilder.cpp:
(WebCore::CustomElementConstructionData::CustomElementConstructionData): Added. It needs to be in
the cpp file to avoid introducing more header dependencies in HTMLTreeBuilder.h.
(WebCore::CustomElementConstructionData::~CustomElementConstructionData): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInBody): Use insertGenericHTMLElement when creating
a generic element that could be custom elements.
(WebCore::HTMLTreeBuilder::insertGenericHTMLElement): Added. Create and insert a new element
or set m_customElementToConstruct so that the HTMLDocumentParser will create a custom element later.
(WebCore::HTMLTreeBuilder::didCreateCustomOrCallbackElement): Added. Called by HTMLDocumentParser
when it finishes creating a new custom element.

* html/parser/HTMLTreeBuilder.h:
(WebCore::HTMLTreeBuilder::takeCustomElementConstructionData): Added.
(WebCore::HTMLTreeBuilder::hasParserBlockingScriptWork): Renamed from hasParserBlockingScript.
Checks the existence of m_customElementToConstruct as well as m_scriptToProcess.

LayoutTests:

Reviewed by Antti Koivisto.

Added W3C testharness.js based tests for instantiating custom elements inside the HTML parser.

* fast/custom-elements/parser: Added.
* fast/custom-elements/parser/parser-constructs-custom-elements-expected.txt: Added.
* fast/custom-elements/parser/parser-constructs-custom-elements.html: Added.
* fast/custom-elements/parser/parser-fallsback-to-unknown-element-expected.txt: Added.
* fast/custom-elements/parser/parser-fallsback-to-unknown-element.html: Added.
* fast/custom-elements/parser/parser-sets-attributes-and-children-expected.txt: Added.
* fast/custom-elements/parser/parser-sets-attributes-and-children.html: Added.
* fast/custom-elements/parser/parser-uses-constructed-element-expected.txt: Added.
* fast/custom-elements/parser/parser-uses-constructed-element.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@197463 268f45cc-cd09-0410-ab3c-d52691b4dbfc
20 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/custom-elements/parser/parser-constructs-custom-elements-expected.txt [new file with mode: 0644]
LayoutTests/fast/custom-elements/parser/parser-constructs-custom-elements.html [new file with mode: 0644]
LayoutTests/fast/custom-elements/parser/parser-fallsback-to-unknown-element-expected.txt [new file with mode: 0644]
LayoutTests/fast/custom-elements/parser/parser-fallsback-to-unknown-element.html [new file with mode: 0644]
LayoutTests/fast/custom-elements/parser/parser-sets-attributes-and-children-expected.txt [new file with mode: 0644]
LayoutTests/fast/custom-elements/parser/parser-sets-attributes-and-children.html [new file with mode: 0644]
LayoutTests/fast/custom-elements/parser/parser-uses-constructed-element-expected.txt [new file with mode: 0644]
LayoutTests/fast/custom-elements/parser/parser-uses-constructed-element.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSCustomElementInterface.cpp
Source/WebCore/bindings/js/JSCustomElementInterface.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/make_names.pl
Source/WebCore/html/parser/HTMLConstructionSite.cpp
Source/WebCore/html/parser/HTMLConstructionSite.h
Source/WebCore/html/parser/HTMLDocumentParser.cpp
Source/WebCore/html/parser/HTMLStackItem.h
Source/WebCore/html/parser/HTMLTreeBuilder.cpp
Source/WebCore/html/parser/HTMLTreeBuilder.h