Title: [197917] trunk
Revision
197917
Author
[email protected]
Date
2016-03-09 18:33:12 -0800 (Wed, 09 Mar 2016)

Log Message

defineElement should upgrade existing unresolved custom elements
https://bugs.webkit.org/show_bug.cgi?id=155107

Reviewed by Darin Adler.

Source/WebCore:

Added the support for upgrading existing unresolved custom elements when defineElement is called.

The current implementation upgrades elements in the order they were created and has the issue that
it keeps accumulating all elements with a hyphen in its name until defineElement is called as
documented in https://github.com/w3c/webcomponents/issues/419

This patch re-purposes IsEditingTextFlag to indicate that the node is an unresolved custom element.
Since isEditingText() is only called in textRendererIsNeeded only on Text nodes, it's mutually
exclusive with isUnresolvedCustomElement().

The list of unresolved custom elements is kept in m_upgradeCandidatesMap, a hash map of element names
to the list of unresolved elements with that name.

In addition, added the logic to use HTMLElement as the interface for unresolved custom element instead
of HTMLUnknownElement.

Test: fast/custom-elements/upgrading/upgrading-parser-created-element.html

* bindings/js/JSCustomElementInterface.cpp:
(WebCore::JSCustomElementInterface::upgradeElement): Clear the flag.
* bindings/js/JSDocumentCustom.cpp:
(WebCore::JSDocument::defineElement): Set the unique private name to keep the interface alive before
calling addElementDefinition as the call can now invoke author scripts.
* dom/CustomElementDefinitions.cpp:
(WebCore::CustomElementDefinitions::addElementDefinition): Upgrade existing unresolved elements kept
in m_upgradeCandidatesMap.
(WebCore::CustomElementDefinitions::addUpgradeCandidate): Added.
* dom/CustomElementDefinitions.h:
* dom/Document.cpp:
(WebCore::createHTMLElementWithNameValidation): Added the code to add the unresolved custom elements
to the upgrade candidates map. Also instantiate it as HTMLElement instead of HTMLUnknownElement.
(WebCore::createFallbackHTMLElement): Ditto.
* dom/Node.h:
(WebCore::Node::setIsCustomElement):
(WebCore::Node::isUnresolvedCustomElement): Added.
(WebCore::Node::setIsUnresolvedCustomElement): Added.
(WebCore::Node::setCustomElementIsResolved): Added. Clears IsEditingTextOrUnresolvedCustomElementFlag
and sets IsCustomElement.
(WebCore::Node::isEditingText): Check both IsEditingTextOrUnresolvedCustomElementFlag and IsTextFlag
for safety even though it's currently only used in textRendererIsNeeded which takes Text&.
* dom/make_names.pl:
(defaultParametersHash): Added customElementInterfaceName as a parameter.
(printWrapperFactoryCppFile): Generate the code to use customElementInterfaceName when the element
for which the wrapper is created has isUnresolvedCustomElement flag set.
* html/HTMLTagNames.in: Use HTMLElement for unresolved custom elements.
* html/parser/HTMLConstructionSite.cpp:
(WebCore::HTMLConstructionSite::createHTMLElementOrFindCustomElementInterface): Added the code to add
the unresolved custom elements to the upgrade candidates map. Also instantiate it as HTMLElement instead
of HTMLUnknownElement. 

LayoutTests:

Added W3C style testharness.js tests for asynchronously defining custom elements.

* fast/custom-elements/upgrading/Node-cloneNode.html:
* fast/custom-elements/upgrading/upgrading-parser-created-element-expected.txt: Added.
* fast/custom-elements/upgrading/upgrading-parser-created-element.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (197916 => 197917)


--- trunk/LayoutTests/ChangeLog	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/LayoutTests/ChangeLog	2016-03-10 02:33:12 UTC (rev 197917)
@@ -1,3 +1,16 @@
+2016-03-09  Ryosuke Niwa  <[email protected]>
+
+        defineElement should upgrade existing unresolved custom elements
+        https://bugs.webkit.org/show_bug.cgi?id=155107
+
+        Reviewed by Darin Adler.
+
+        Added W3C style testharness.js tests for asynchronously defining custom elements.
+
+        * fast/custom-elements/upgrading/Node-cloneNode.html:
+        * fast/custom-elements/upgrading/upgrading-parser-created-element-expected.txt: Added.
+        * fast/custom-elements/upgrading/upgrading-parser-created-element.html: Added.
+
 2016-03-09  Saam Barati  <[email protected]>
 
         ES6: Implement lexical scoping for function definitions in strict mode

Modified: trunk/LayoutTests/fast/custom-elements/upgrading/Node-cloneNode.html (197916 => 197917)


--- trunk/LayoutTests/fast/custom-elements/upgrading/Node-cloneNode.html	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/LayoutTests/fast/custom-elements/upgrading/Node-cloneNode.html	2016-03-10 02:33:12 UTC (rev 197917)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
-<title>Custom Elements: Extensions to Document interface</title>
+<title>Custom Elements: Upgrading</title>
 <meta name="author" title="Ryosuke Niwa" href=""
 <meta name="assert" content="Node.prototype.cloneNode should upgrade a custom element">
 <link rel="help" href=""

Added: trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element-expected.txt (0 => 197917)


--- trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element-expected.txt	2016-03-10 02:33:12 UTC (rev 197917)
@@ -0,0 +1,6 @@
+
+PASS Element.prototype.createElement must add an unresolved custom element to the upgrade candidates map 
+PASS HTMLElement constructor must throw an InvalidStateError when the top of the construction stack is marked AlreadyConstructed due to a custom element constructor constructing itself after super() call 
+PASS HTMLElement constructor must throw an InvalidStateError when the top of the construction stack is marked AlreadyConstructed due to a custom element constructor constructing itself before super() call 
+PASS Upgrading a custom element must throw an InvalidStateError when the returned element is not SameValue as the upgraded element 
+

Added: trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element.html (0 => 197917)


--- trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element.html	                        (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element.html	2016-03-10 02:33:12 UTC (rev 197917)
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Custom Elements: Upgrading unresolved elements</title>
+<meta name="author" title="Ryosuke Niwa" href=""
+<meta name="assert" content="HTML parser must add an unresolved custom element to the upgrade candidates map">
+<link rel="help" href=""
+<script src=""
+<script src=""
+<link rel='stylesheet' href=''>
+</head>
+<body>
+<div id="log"></div>
+<my-custom-element></my-custom-element>
+<instantiates-itself-after-super></instantiates-itself-after-super>
+<instantiates-itself-before-super></instantiates-itself-before-super>
+<my-other-element id="instance"></my-other-element>
+<my-other-element id="otherInstance"></my-other-element>
+<script>
+
+test(function () {
+    class MyCustomElement extends HTMLElement { }
+
+    var instance = document.querySelector('my-custom-element');
+    assert_true(instance instanceof HTMLElement);
+    assert_false(instance instanceof HTMLUnknownElement,
+        'an unresolved custom element should not be an instance of HTMLUnknownElement');
+    assert_false(instance instanceof MyCustomElement);
+
+    document.defineElement('my-custom-element', MyCustomElement);
+
+    assert_true(instance instanceof HTMLElement);
+    assert_true(instance instanceof MyCustomElement,
+        'Calling defineElement must upgrade existing custom elements');
+
+}, 'Element.prototype.createElement must add an unresolved custom element to the upgrade candidates map');
+
+
+test(function () {
+    class InstantiatesItselfAfterSuper extends HTMLElement {
+        constructor(doNotCreateItself) {
+            super();
+            if (!doNotCreateItself)
+                new InstantiatesItselfAfterSuper(true);
+        }
+    }
+
+    assert_throws({'name': 'InvalidStateError'}, function () {
+        document.defineElement('instantiates-itself-after-super', InstantiatesItselfAfterSuper);
+    });
+}, 'HTMLElement constructor must throw an InvalidStateError when the top of the construction stack is marked AlreadyConstructed'
+    + ' due to a custom element constructor constructing itself after super() call');
+
+test(function () {
+    class InstantiatesItselfBeforeSuper extends HTMLElement {
+        constructor(doNotCreateItself) {
+            if (!doNotCreateItself)
+                new InstantiatesItselfBeforeSuper(true);
+            super();
+        }
+    }
+
+    assert_throws({'name': 'InvalidStateError'}, function () {
+        document.defineElement('instantiates-itself-before-super', InstantiatesItselfBeforeSuper);
+    });
+}, 'HTMLElement constructor must throw an InvalidStateError when the top of the construction stack is marked AlreadyConstructed'
+    + ' due to a custom element constructor constructing itself before super() call');
+
+test(function () {
+    class MyOtherElement extends HTMLElement {
+        constructor() {
+            super();
+            if (this == instance)
+                return otherInstance;
+        }
+    }
+    var instance = document.getElementById('instance');
+    var otherInstance = document.getElementById('otherInstance');
+
+    assert_false(instance instanceof MyOtherElement);
+    assert_false(otherInstance instanceof MyOtherElement);
+
+    assert_throws({'name': 'InvalidStateError'}, function () {
+        document.defineElement('my-other-element', MyOtherElement);
+    });
+
+    assert_true(document.createElement('my-other-element') instanceof MyOtherElement,
+        'Upgrading of custom elements must happen after the definition was added to the registry.');
+}, 'Upgrading a custom element must throw an InvalidStateError when the returned element is not SameValue as the upgraded element');
+
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (197916 => 197917)


--- trunk/Source/WebCore/ChangeLog	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/ChangeLog	2016-03-10 02:33:12 UTC (rev 197917)
@@ -1,3 +1,60 @@
+2016-03-09  Ryosuke Niwa  <[email protected]>
+
+        defineElement should upgrade existing unresolved custom elements
+        https://bugs.webkit.org/show_bug.cgi?id=155107
+
+        Reviewed by Darin Adler.
+
+        Added the support for upgrading existing unresolved custom elements when defineElement is called.
+
+        The current implementation upgrades elements in the order they were created and has the issue that
+        it keeps accumulating all elements with a hyphen in its name until defineElement is called as
+        documented in https://github.com/w3c/webcomponents/issues/419
+
+        This patch re-purposes IsEditingTextFlag to indicate that the node is an unresolved custom element.
+        Since isEditingText() is only called in textRendererIsNeeded only on Text nodes, it's mutually
+        exclusive with isUnresolvedCustomElement().
+
+        The list of unresolved custom elements is kept in m_upgradeCandidatesMap, a hash map of element names
+        to the list of unresolved elements with that name.
+
+        In addition, added the logic to use HTMLElement as the interface for unresolved custom element instead
+        of HTMLUnknownElement.
+
+        Test: fast/custom-elements/upgrading/upgrading-parser-created-element.html
+
+        * bindings/js/JSCustomElementInterface.cpp:
+        (WebCore::JSCustomElementInterface::upgradeElement): Clear the flag.
+        * bindings/js/JSDocumentCustom.cpp:
+        (WebCore::JSDocument::defineElement): Set the unique private name to keep the interface alive before
+        calling addElementDefinition as the call can now invoke author scripts.
+        * dom/CustomElementDefinitions.cpp:
+        (WebCore::CustomElementDefinitions::addElementDefinition): Upgrade existing unresolved elements kept
+        in m_upgradeCandidatesMap.
+        (WebCore::CustomElementDefinitions::addUpgradeCandidate): Added.
+        * dom/CustomElementDefinitions.h:
+        * dom/Document.cpp:
+        (WebCore::createHTMLElementWithNameValidation): Added the code to add the unresolved custom elements
+        to the upgrade candidates map. Also instantiate it as HTMLElement instead of HTMLUnknownElement.
+        (WebCore::createFallbackHTMLElement): Ditto.
+        * dom/Node.h:
+        (WebCore::Node::setIsCustomElement):
+        (WebCore::Node::isUnresolvedCustomElement): Added.
+        (WebCore::Node::setIsUnresolvedCustomElement): Added.
+        (WebCore::Node::setCustomElementIsResolved): Added. Clears IsEditingTextOrUnresolvedCustomElementFlag
+        and sets IsCustomElement.
+        (WebCore::Node::isEditingText): Check both IsEditingTextOrUnresolvedCustomElementFlag and IsTextFlag
+        for safety even though it's currently only used in textRendererIsNeeded which takes Text&.
+        * dom/make_names.pl:
+        (defaultParametersHash): Added customElementInterfaceName as a parameter.
+        (printWrapperFactoryCppFile): Generate the code to use customElementInterfaceName when the element
+        for which the wrapper is created has isUnresolvedCustomElement flag set.
+        * html/HTMLTagNames.in: Use HTMLElement for unresolved custom elements.
+        * html/parser/HTMLConstructionSite.cpp:
+        (WebCore::HTMLConstructionSite::createHTMLElementOrFindCustomElementInterface): Added the code to add
+        the unresolved custom elements to the upgrade candidates map. Also instantiate it as HTMLElement instead
+        of HTMLUnknownElement. 
+
 2016-03-09  Enrica Casucci  <[email protected]>
 
         Retrieve additional context for some data detector link for preview and action menu.

Modified: trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp (197916 => 197917)


--- trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp	2016-03-10 02:33:12 UTC (rev 197917)
@@ -104,7 +104,7 @@
 
 void JSCustomElementInterface::upgradeElement(Element& element)
 {
-    ASSERT(element.isCustomElement());
+    ASSERT(element.isUnresolvedCustomElement());
     if (!canInvokeCallback())
         return;
 
@@ -147,6 +147,7 @@
         throwInvalidStateError(*state, "Custom element constructor failed to upgrade an element");
         return;
     }
+    wrappedElement->setCustomElementIsResolved();
     ASSERT(wrappedElement->isCustomElement());
 }
 

Modified: trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp (197916 => 197917)


--- trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp	2016-03-10 02:33:12 UTC (rev 197917)
@@ -180,11 +180,12 @@
     // FIXME: 13. Let detachedCallback be Get(prototype, "detachedCallback"). Rethrow any exceptions.
     // FIXME: 14. Let attributeChangedCallback be Get(prototype, "attributeChangedCallback"). Rethrow any exceptions.
 
-    QualifiedName name(nullAtom, tagName, HTMLNames::xhtmlNamespaceURI);
-    definitions.addElementDefinition(JSCustomElementInterface::create(name, object, globalObject()));
     PrivateName uniquePrivateName;
     globalObject()->putDirect(globalObject()->vm(), uniquePrivateName, object);
 
+    QualifiedName name(nullAtom, tagName, HTMLNames::xhtmlNamespaceURI);
+    definitions.addElementDefinition(JSCustomElementInterface::create(name, object, globalObject()));
+
     // FIXME: 17. Let map be registry's upgrade candidates map.
     // FIXME: 18. Upgrade a newly-defined element given map and definition.
 

Modified: trunk/Source/WebCore/dom/CustomElementDefinitions.cpp (197916 => 197917)


--- trunk/Source/WebCore/dom/CustomElementDefinitions.cpp	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/dom/CustomElementDefinitions.cpp	2016-03-10 02:33:12 UTC (rev 197917)
@@ -74,9 +74,35 @@
     AtomicString localName = interface->name().localName();
     ASSERT(!m_nameMap.contains(localName));
     m_constructorMap.add(interface->constructor(), interface.ptr());
-    m_nameMap.add(localName, WTFMove(interface));
+    m_nameMap.add(localName, interface.copyRef());
+
+    auto candidateList = m_upgradeCandidatesMap.find(localName);
+    if (candidateList == m_upgradeCandidatesMap.end())
+        return;
+
+    Vector<RefPtr<Element>> list(WTFMove(candidateList->value));
+
+    m_upgradeCandidatesMap.remove(localName);
+
+    for (auto& candidate : list) {
+        ASSERT(candidate);
+        interface->upgradeElement(*candidate);
+    }
+
+    // We should not be adding more upgrade candidate for this local name.
+    ASSERT(!m_upgradeCandidatesMap.contains(localName));
 }
 
+void CustomElementDefinitions::addUpgradeCandidate(Element& candidate)
+{
+    auto result = m_upgradeCandidatesMap.ensure(candidate.localName(), [] {
+        return Vector<RefPtr<Element>>();
+    });
+    auto& nodeVector = result.iterator->value;
+    ASSERT(!nodeVector.contains(&candidate));
+    nodeVector.append(&candidate);
+}
+
 JSCustomElementInterface* CustomElementDefinitions::findInterface(const QualifiedName& name) const
 {
     auto it = m_nameMap.find(name.localName());

Modified: trunk/Source/WebCore/dom/CustomElementDefinitions.h (197916 => 197917)


--- trunk/Source/WebCore/dom/CustomElementDefinitions.h	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/dom/CustomElementDefinitions.h	2016-03-10 02:33:12 UTC (rev 197917)
@@ -49,6 +49,7 @@
     WTF_MAKE_FAST_ALLOCATED;
 public:
     void addElementDefinition(Ref<JSCustomElementInterface>&&);
+    void addUpgradeCandidate(Element&);
 
     JSCustomElementInterface* findInterface(const QualifiedName&) const;
     JSCustomElementInterface* findInterface(const AtomicString&) const;
@@ -59,6 +60,7 @@
     static NameStatus checkName(const AtomicString& tagName);
 
 private:
+    HashMap<AtomicString, Vector<RefPtr<Element>>> m_upgradeCandidatesMap;
     HashMap<AtomicString, RefPtr<JSCustomElementInterface>> m_nameMap;
     HashMap<const JSC::JSObject*, JSCustomElementInterface*> m_constructorMap;
 };

Modified: trunk/Source/WebCore/dom/Document.cpp (197916 => 197917)


--- trunk/Source/WebCore/dom/Document.cpp	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/dom/Document.cpp	2016-03-10 02:33:12 UTC (rev 197917)
@@ -899,7 +899,18 @@
         return nullptr;
     }
 
-    return HTMLUnknownElement::create(QualifiedName(nullAtom, localName, xhtmlNamespaceURI), document);
+    QualifiedName qualifiedName(nullAtom, localName, xhtmlNamespaceURI);
+
+#if ENABLE(CUSTOM_ELEMENTS)
+    if (CustomElementDefinitions::checkName(localName) == CustomElementDefinitions::NameStatus::Valid) {
+        Ref<HTMLElement> element = HTMLElement::create(qualifiedName, document);
+        element->setIsUnresolvedCustomElement();
+        document.ensureCustomElementDefinitions().addUpgradeCandidate(element.get());
+        return WTFMove(element);
+    }
+#endif
+
+    return HTMLUnknownElement::create(qualifiedName, document);
 }
 
 RefPtr<Element> Document::createElementForBindings(const AtomicString& name, ExceptionCode& ec)
@@ -1080,11 +1091,18 @@
     if (UNLIKELY(definitions)) {
         if (auto* interface = definitions->findInterface(name)) {
             Ref<HTMLElement> element = HTMLElement::create(name, document);
-            element->setIsCustomElement(); // Pre-upgrade element is still considered a custom element.
+            element->setIsUnresolvedCustomElement();
             LifecycleCallbackQueue::enqueueElementUpgrade(element.get(), *interface);
             return element;
         }
     }
+    // FIXME: Should we also check the equality of prefix between the custom element and name?
+    if (CustomElementDefinitions::checkName(name.localName()) == CustomElementDefinitions::NameStatus::Valid) {
+        Ref<HTMLElement> element = HTMLElement::create(name, document);
+        element->setIsUnresolvedCustomElement();
+        document.ensureCustomElementDefinitions().addUpgradeCandidate(element.get());
+        return element;
+    }
 #endif
     return HTMLUnknownElement::create(name, document);
 }

Modified: trunk/Source/WebCore/dom/Node.h (197916 => 197917)


--- trunk/Source/WebCore/dom/Node.h	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/dom/Node.h	2016-03-10 02:33:12 UTC (rev 197917)
@@ -266,7 +266,11 @@
 
 #if ENABLE(CUSTOM_ELEMENTS)
     bool isCustomElement() const { return getFlag(IsCustomElement); }
-    void setIsCustomElement() { return setFlag(IsCustomElement); }
+    void setIsCustomElement() { setFlag(IsCustomElement); }
+
+    bool isUnresolvedCustomElement() const { return isElementNode() && getFlag(IsEditingTextOrUnresolvedCustomElementFlag); }
+    void setIsUnresolvedCustomElement() { setFlag(IsEditingTextOrUnresolvedCustomElementFlag); }
+    void setCustomElementIsResolved();
 #endif
 
     // Returns null, a child of ShadowRoot, or a legacy shadow root.
@@ -320,7 +324,7 @@
     StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); }
     bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); }
     bool styleIsAffectedByPreviousSibling() const { return getFlag(StyleIsAffectedByPreviousSibling); }
-    bool isEditingText() const { return getFlag(IsEditingTextFlag); }
+    bool isEditingText() const { return getFlag(IsTextFlag) && getFlag(IsEditingTextOrUnresolvedCustomElementFlag); }
 
     void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
     void clearChildNeedsStyleRecalc() { m_nodeFlags &= ~(ChildNeedsStyleRecalcFlag | DirectChildNeedsStyleRecalcFlag); }
@@ -595,7 +599,7 @@
         IsParsingChildrenFinishedFlag = 1 << 13, // Element
 
         StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1) | 1 << (nodeStyleChangeShift + 2),
-        IsEditingTextFlag = 1 << 17,
+        IsEditingTextOrUnresolvedCustomElementFlag = 1 << 17,
         IsNamedFlowContentNodeFlag = 1 << 18,
         HasSyntheticAttrChildNodesFlag = 1 << 19,
         HasCustomStyleResolveCallbacksFlag = 1 << 20,
@@ -634,7 +638,7 @@
         CreateHTMLElement = CreateStyledElement | IsHTMLFlag,
         CreateSVGElement = CreateStyledElement | IsSVGFlag | HasCustomStyleResolveCallbacksFlag,
         CreateDocument = CreateContainer | InDocumentFlag,
-        CreateEditingText = CreateText | IsEditingTextFlag,
+        CreateEditingText = CreateText | IsEditingTextOrUnresolvedCustomElementFlag,
         CreateMathMLElement = CreateStyledElement | IsMathMLFlag
     };
     Node(Document&, ConstructionType);
@@ -769,6 +773,16 @@
     return parentNode();
 }
 
+#if ENABLE(CUSTOM_ELEMENTS)
+
+inline void Node::setCustomElementIsResolved()
+{
+    clearFlag(IsEditingTextOrUnresolvedCustomElementFlag);
+    setFlag(IsCustomElement);
+}
+
+#endif
+
 } // namespace WebCore
 
 #if ENABLE(TREE_DEBUGGING)

Modified: trunk/Source/WebCore/dom/make_names.pl (197916 => 197917)


--- trunk/Source/WebCore/dom/make_names.pl	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/dom/make_names.pl	2016-03-10 02:33:12 UTC (rev 197917)
@@ -216,6 +216,7 @@
         'attrsNullNamespace' => 0,
         'fallbackInterfaceName' => '',
         'fallbackJSInterfaceName' => '',
+        'customElementInterfaceName' => '',
     );
 }
 
@@ -1318,6 +1319,20 @@
         populate$parameters{namespace}WrapperMap(functions);
     if (auto function = functions.get().get(element->localName().impl()))
         return function(globalObject, element);
+END
+;
+
+    if ($parameters{customElementInterfaceName}) {
+        print F <<END
+#if ENABLE(CUSTOM_ELEMENTS)
+    if (element->isUnresolvedCustomElement())
+        return CREATE_DOM_WRAPPER(globalObject, $parameters{customElementInterfaceName}, element.get());
+#endif
+END
+;
+    }
+
+    print F <<END
     return CREATE_DOM_WRAPPER(globalObject, $parameters{fallbackJSInterfaceName}, element.get());
 }
 

Modified: trunk/Source/WebCore/html/HTMLTagNames.in (197916 => 197917)


--- trunk/Source/WebCore/html/HTMLTagNames.in	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/html/HTMLTagNames.in	2016-03-10 02:33:12 UTC (rev 197917)
@@ -2,6 +2,7 @@
 namespacePrefix="xhtml"
 namespaceURI="http://www.w3.org/1999/xhtml"
 fallbackInterfaceName="HTMLUnknownElement"
+customElementInterfaceName="HTMLElement"
 
 a interfaceName=HTMLAnchorElement
 abbr interfaceName=HTMLElement

Modified: trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp (197916 => 197917)


--- trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp	2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp	2016-03-10 02:33:12 UTC (rev 197917)
@@ -672,20 +672,29 @@
     bool insideTemplateElement = !ownerDocument.frame();
     RefPtr<Element> element = HTMLElementFactory::createKnownElement(localName, ownerDocument, insideTemplateElement ? nullptr : form(), true);
     if (UNLIKELY(!element)) {
-
 #if ENABLE(CUSTOM_ELEMENTS)
-        auto* definitions = ownerDocumentForCurrentNode().customElementDefinitions();
-        if (customElementInterface && UNLIKELY(definitions)) {
-            if (auto* interface = definitions->findInterface(localName)) {
-                *customElementInterface = interface;
-                return nullptr;
+        if (customElementInterface) {
+            auto* definitions = ownerDocument.customElementDefinitions();
+            if (UNLIKELY(definitions)) {
+                if (auto* interface = definitions->findInterface(localName)) {
+                    *customElementInterface = interface;
+                    return nullptr;
+                }
             }
         }
 #else
         UNUSED_PARAM(customElementInterface);
 #endif
 
-        element = HTMLUnknownElement::create(QualifiedName(nullAtom, localName, xhtmlNamespaceURI), ownerDocumentForCurrentNode());
+        QualifiedName qualifiedName(nullAtom, localName, xhtmlNamespaceURI);
+#if ENABLE(CUSTOM_ELEMENTS)
+        if (CustomElementDefinitions::checkName(localName) == CustomElementDefinitions::NameStatus::Valid) {
+            element = HTMLElement::create(qualifiedName, ownerDocument);
+            element->setIsUnresolvedCustomElement();
+            ownerDocument.ensureCustomElementDefinitions().addUpgradeCandidate(*element);
+        } else
+#endif
+            element = HTMLUnknownElement::create(qualifiedName, ownerDocument);
     }
     ASSERT(element);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to