Changeset 197917 in webkit
- Timestamp:
- Mar 9, 2016 6:33:12 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r197915 r197917 1 2016-03-09 Ryosuke Niwa <rniwa@webkit.org> 2 3 defineElement should upgrade existing unresolved custom elements 4 https://bugs.webkit.org/show_bug.cgi?id=155107 5 6 Reviewed by Darin Adler. 7 8 Added W3C style testharness.js tests for asynchronously defining custom elements. 9 10 * fast/custom-elements/upgrading/Node-cloneNode.html: 11 * fast/custom-elements/upgrading/upgrading-parser-created-element-expected.txt: Added. 12 * fast/custom-elements/upgrading/upgrading-parser-created-element.html: Added. 13 1 14 2016-03-09 Saam Barati <sbarati@apple.com> 2 15 -
trunk/LayoutTests/fast/custom-elements/upgrading/Node-cloneNode.html
r197634 r197917 2 2 <html> 3 3 <head> 4 <title>Custom Elements: Extensions to Document interface</title>4 <title>Custom Elements: Upgrading</title> 5 5 <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> 6 6 <meta name="assert" content="Node.prototype.cloneNode should upgrade a custom element"> -
trunk/Source/WebCore/ChangeLog
r197916 r197917 1 2016-03-09 Ryosuke Niwa <rniwa@webkit.org> 2 3 defineElement should upgrade existing unresolved custom elements 4 https://bugs.webkit.org/show_bug.cgi?id=155107 5 6 Reviewed by Darin Adler. 7 8 Added the support for upgrading existing unresolved custom elements when defineElement is called. 9 10 The current implementation upgrades elements in the order they were created and has the issue that 11 it keeps accumulating all elements with a hyphen in its name until defineElement is called as 12 documented in https://github.com/w3c/webcomponents/issues/419 13 14 This patch re-purposes IsEditingTextFlag to indicate that the node is an unresolved custom element. 15 Since isEditingText() is only called in textRendererIsNeeded only on Text nodes, it's mutually 16 exclusive with isUnresolvedCustomElement(). 17 18 The list of unresolved custom elements is kept in m_upgradeCandidatesMap, a hash map of element names 19 to the list of unresolved elements with that name. 20 21 In addition, added the logic to use HTMLElement as the interface for unresolved custom element instead 22 of HTMLUnknownElement. 23 24 Test: fast/custom-elements/upgrading/upgrading-parser-created-element.html 25 26 * bindings/js/JSCustomElementInterface.cpp: 27 (WebCore::JSCustomElementInterface::upgradeElement): Clear the flag. 28 * bindings/js/JSDocumentCustom.cpp: 29 (WebCore::JSDocument::defineElement): Set the unique private name to keep the interface alive before 30 calling addElementDefinition as the call can now invoke author scripts. 31 * dom/CustomElementDefinitions.cpp: 32 (WebCore::CustomElementDefinitions::addElementDefinition): Upgrade existing unresolved elements kept 33 in m_upgradeCandidatesMap. 34 (WebCore::CustomElementDefinitions::addUpgradeCandidate): Added. 35 * dom/CustomElementDefinitions.h: 36 * dom/Document.cpp: 37 (WebCore::createHTMLElementWithNameValidation): Added the code to add the unresolved custom elements 38 to the upgrade candidates map. Also instantiate it as HTMLElement instead of HTMLUnknownElement. 39 (WebCore::createFallbackHTMLElement): Ditto. 40 * dom/Node.h: 41 (WebCore::Node::setIsCustomElement): 42 (WebCore::Node::isUnresolvedCustomElement): Added. 43 (WebCore::Node::setIsUnresolvedCustomElement): Added. 44 (WebCore::Node::setCustomElementIsResolved): Added. Clears IsEditingTextOrUnresolvedCustomElementFlag 45 and sets IsCustomElement. 46 (WebCore::Node::isEditingText): Check both IsEditingTextOrUnresolvedCustomElementFlag and IsTextFlag 47 for safety even though it's currently only used in textRendererIsNeeded which takes Text&. 48 * dom/make_names.pl: 49 (defaultParametersHash): Added customElementInterfaceName as a parameter. 50 (printWrapperFactoryCppFile): Generate the code to use customElementInterfaceName when the element 51 for which the wrapper is created has isUnresolvedCustomElement flag set. 52 * html/HTMLTagNames.in: Use HTMLElement for unresolved custom elements. 53 * html/parser/HTMLConstructionSite.cpp: 54 (WebCore::HTMLConstructionSite::createHTMLElementOrFindCustomElementInterface): Added the code to add 55 the unresolved custom elements to the upgrade candidates map. Also instantiate it as HTMLElement instead 56 of HTMLUnknownElement. 57 1 58 2016-03-09 Enrica Casucci <enrica@apple.com> 2 59 -
trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp
r197634 r197917 105 105 void JSCustomElementInterface::upgradeElement(Element& element) 106 106 { 107 ASSERT(element.is CustomElement());107 ASSERT(element.isUnresolvedCustomElement()); 108 108 if (!canInvokeCallback()) 109 109 return; … … 148 148 return; 149 149 } 150 wrappedElement->setCustomElementIsResolved(); 150 151 ASSERT(wrappedElement->isCustomElement()); 151 152 } -
trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp
r197614 r197917 181 181 // FIXME: 14. Let attributeChangedCallback be Get(prototype, "attributeChangedCallback"). Rethrow any exceptions. 182 182 183 PrivateName uniquePrivateName; 184 globalObject()->putDirect(globalObject()->vm(), uniquePrivateName, object); 185 183 186 QualifiedName name(nullAtom, tagName, HTMLNames::xhtmlNamespaceURI); 184 187 definitions.addElementDefinition(JSCustomElementInterface::create(name, object, globalObject())); 185 PrivateName uniquePrivateName;186 globalObject()->putDirect(globalObject()->vm(), uniquePrivateName, object);187 188 188 189 // FIXME: 17. Let map be registry's upgrade candidates map. -
trunk/Source/WebCore/dom/CustomElementDefinitions.cpp
r197630 r197917 75 75 ASSERT(!m_nameMap.contains(localName)); 76 76 m_constructorMap.add(interface->constructor(), interface.ptr()); 77 m_nameMap.add(localName, WTFMove(interface)); 77 m_nameMap.add(localName, interface.copyRef()); 78 79 auto candidateList = m_upgradeCandidatesMap.find(localName); 80 if (candidateList == m_upgradeCandidatesMap.end()) 81 return; 82 83 Vector<RefPtr<Element>> list(WTFMove(candidateList->value)); 84 85 m_upgradeCandidatesMap.remove(localName); 86 87 for (auto& candidate : list) { 88 ASSERT(candidate); 89 interface->upgradeElement(*candidate); 90 } 91 92 // We should not be adding more upgrade candidate for this local name. 93 ASSERT(!m_upgradeCandidatesMap.contains(localName)); 94 } 95 96 void CustomElementDefinitions::addUpgradeCandidate(Element& candidate) 97 { 98 auto result = m_upgradeCandidatesMap.ensure(candidate.localName(), [] { 99 return Vector<RefPtr<Element>>(); 100 }); 101 auto& nodeVector = result.iterator->value; 102 ASSERT(!nodeVector.contains(&candidate)); 103 nodeVector.append(&candidate); 78 104 } 79 105 -
trunk/Source/WebCore/dom/CustomElementDefinitions.h
r197612 r197917 50 50 public: 51 51 void addElementDefinition(Ref<JSCustomElementInterface>&&); 52 void addUpgradeCandidate(Element&); 52 53 53 54 JSCustomElementInterface* findInterface(const QualifiedName&) const; … … 60 61 61 62 private: 63 HashMap<AtomicString, Vector<RefPtr<Element>>> m_upgradeCandidatesMap; 62 64 HashMap<AtomicString, RefPtr<JSCustomElementInterface>> m_nameMap; 63 65 HashMap<const JSC::JSObject*, JSCustomElementInterface*> m_constructorMap; -
trunk/Source/WebCore/dom/Document.cpp
r197804 r197917 900 900 } 901 901 902 return HTMLUnknownElement::create(QualifiedName(nullAtom, localName, xhtmlNamespaceURI), document); 902 QualifiedName qualifiedName(nullAtom, localName, xhtmlNamespaceURI); 903 904 #if ENABLE(CUSTOM_ELEMENTS) 905 if (CustomElementDefinitions::checkName(localName) == CustomElementDefinitions::NameStatus::Valid) { 906 Ref<HTMLElement> element = HTMLElement::create(qualifiedName, document); 907 element->setIsUnresolvedCustomElement(); 908 document.ensureCustomElementDefinitions().addUpgradeCandidate(element.get()); 909 return WTFMove(element); 910 } 911 #endif 912 913 return HTMLUnknownElement::create(qualifiedName, document); 903 914 } 904 915 … … 1081 1092 if (auto* interface = definitions->findInterface(name)) { 1082 1093 Ref<HTMLElement> element = HTMLElement::create(name, document); 1083 element->setIs CustomElement(); // Pre-upgrade element is still considered a custom element.1094 element->setIsUnresolvedCustomElement(); 1084 1095 LifecycleCallbackQueue::enqueueElementUpgrade(element.get(), *interface); 1085 1096 return element; 1086 1097 } 1098 } 1099 // FIXME: Should we also check the equality of prefix between the custom element and name? 1100 if (CustomElementDefinitions::checkName(name.localName()) == CustomElementDefinitions::NameStatus::Valid) { 1101 Ref<HTMLElement> element = HTMLElement::create(name, document); 1102 element->setIsUnresolvedCustomElement(); 1103 document.ensureCustomElementDefinitions().addUpgradeCandidate(element.get()); 1104 return element; 1087 1105 } 1088 1106 #endif -
trunk/Source/WebCore/dom/Node.h
r197887 r197917 267 267 #if ENABLE(CUSTOM_ELEMENTS) 268 268 bool isCustomElement() const { return getFlag(IsCustomElement); } 269 void setIsCustomElement() { return setFlag(IsCustomElement); } 269 void setIsCustomElement() { setFlag(IsCustomElement); } 270 271 bool isUnresolvedCustomElement() const { return isElementNode() && getFlag(IsEditingTextOrUnresolvedCustomElementFlag); } 272 void setIsUnresolvedCustomElement() { setFlag(IsEditingTextOrUnresolvedCustomElementFlag); } 273 void setCustomElementIsResolved(); 270 274 #endif 271 275 … … 321 325 bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); } 322 326 bool styleIsAffectedByPreviousSibling() const { return getFlag(StyleIsAffectedByPreviousSibling); } 323 bool isEditingText() const { return getFlag(Is EditingTextFlag); }327 bool isEditingText() const { return getFlag(IsTextFlag) && getFlag(IsEditingTextOrUnresolvedCustomElementFlag); } 324 328 325 329 void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); } … … 596 600 597 601 StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1) | 1 << (nodeStyleChangeShift + 2), 598 IsEditingText Flag = 1 << 17,602 IsEditingTextOrUnresolvedCustomElementFlag = 1 << 17, 599 603 IsNamedFlowContentNodeFlag = 1 << 18, 600 604 HasSyntheticAttrChildNodesFlag = 1 << 19, … … 635 639 CreateSVGElement = CreateStyledElement | IsSVGFlag | HasCustomStyleResolveCallbacksFlag, 636 640 CreateDocument = CreateContainer | InDocumentFlag, 637 CreateEditingText = CreateText | IsEditingText Flag,641 CreateEditingText = CreateText | IsEditingTextOrUnresolvedCustomElementFlag, 638 642 CreateMathMLElement = CreateStyledElement | IsMathMLFlag 639 643 }; … … 770 774 } 771 775 776 #if ENABLE(CUSTOM_ELEMENTS) 777 778 inline void Node::setCustomElementIsResolved() 779 { 780 clearFlag(IsEditingTextOrUnresolvedCustomElementFlag); 781 setFlag(IsCustomElement); 782 } 783 784 #endif 785 772 786 } // namespace WebCore 773 787 -
trunk/Source/WebCore/dom/make_names.pl
r197634 r197917 217 217 'fallbackInterfaceName' => '', 218 218 'fallbackJSInterfaceName' => '', 219 'customElementInterfaceName' => '', 219 220 ); 220 221 } … … 1319 1320 if (auto function = functions.get().get(element->localName().impl())) 1320 1321 return function(globalObject, element); 1322 END 1323 ; 1324 1325 if ($parameters{customElementInterfaceName}) { 1326 print F <<END 1327 #if ENABLE(CUSTOM_ELEMENTS) 1328 if (element->isUnresolvedCustomElement()) 1329 return CREATE_DOM_WRAPPER(globalObject, $parameters{customElementInterfaceName}, element.get()); 1330 #endif 1331 END 1332 ; 1333 } 1334 1335 print F <<END 1321 1336 return CREATE_DOM_WRAPPER(globalObject, $parameters{fallbackJSInterfaceName}, element.get()); 1322 1337 } -
trunk/Source/WebCore/html/HTMLTagNames.in
r195627 r197917 3 3 namespaceURI="http://www.w3.org/1999/xhtml" 4 4 fallbackInterfaceName="HTMLUnknownElement" 5 customElementInterfaceName="HTMLElement" 5 6 6 7 a interfaceName=HTMLAnchorElement -
trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp
r197463 r197917 673 673 RefPtr<Element> element = HTMLElementFactory::createKnownElement(localName, ownerDocument, insideTemplateElement ? nullptr : form(), true); 674 674 if (UNLIKELY(!element)) { 675 676 675 #if ENABLE(CUSTOM_ELEMENTS) 677 auto* definitions = ownerDocumentForCurrentNode().customElementDefinitions(); 678 if (customElementInterface && UNLIKELY(definitions)) { 679 if (auto* interface = definitions->findInterface(localName)) { 680 *customElementInterface = interface; 681 return nullptr; 676 if (customElementInterface) { 677 auto* definitions = ownerDocument.customElementDefinitions(); 678 if (UNLIKELY(definitions)) { 679 if (auto* interface = definitions->findInterface(localName)) { 680 *customElementInterface = interface; 681 return nullptr; 682 } 682 683 } 683 684 } … … 686 687 #endif 687 688 688 element = HTMLUnknownElement::create(QualifiedName(nullAtom, localName, xhtmlNamespaceURI), ownerDocumentForCurrentNode()); 689 QualifiedName qualifiedName(nullAtom, localName, xhtmlNamespaceURI); 690 #if ENABLE(CUSTOM_ELEMENTS) 691 if (CustomElementDefinitions::checkName(localName) == CustomElementDefinitions::NameStatus::Valid) { 692 element = HTMLElement::create(qualifiedName, ownerDocument); 693 element->setIsUnresolvedCustomElement(); 694 ownerDocument.ensureCustomElementDefinitions().addUpgradeCandidate(*element); 695 } else 696 #endif 697 element = HTMLUnknownElement::create(qualifiedName, ownerDocument); 689 698 } 690 699 ASSERT(element);
Note: See TracChangeset
for help on using the changeset viewer.