Changeset 208716 in webkit
- Timestamp:
- Nov 14, 2016 4:27:01 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r208700 r208716 1 2016-11-14 Ryosuke Niwa <rniwa@webkit.org> 2 3 document.createElementNS doesn't construct a custom element 4 https://bugs.webkit.org/show_bug.cgi?id=164700 5 6 Reviewed by Darin Adler. 7 8 Added W3C style testharness.js tests for createElementNS and DOMImplementation's createDocument. 9 10 * fast/custom-elements/DOMImplementation-createDocument-expected.txt: Added. 11 * fast/custom-elements/DOMImplementation-createDocument.html: Added. 12 * fast/custom-elements/document-createElementNS-expected.txt: Added. 13 * fast/custom-elements/document-createElementNS.html: Added. 14 1 15 2016-11-14 Dean Jackson <dino@apple.com> 2 16 -
trunk/Source/WebCore/ChangeLog
r208711 r208716 1 2016-11-14 Ryosuke Niwa <rniwa@webkit.org> 2 3 document.createElementNS doesn't construct a custom element 4 https://bugs.webkit.org/show_bug.cgi?id=164700 5 6 Reviewed by Darin Adler. 7 8 Fixed the bug that document.createElementNS doesn't create a custom element or enqueue it to upgrade. 9 10 Also made constructCustomElementSynchronously not call the custom element constructors with the element's 11 local name as the first argument, which was a non-standard behavior added during prototyping. 12 13 Test: fast/custom-elements/DOMImplementation-createDocument.html 14 fast/custom-elements/document-createElementNS.html 15 16 * bindings/js/JSCustomElementInterface.cpp: 17 (WebCore::JSCustomElementInterface::constructElementWithFallback): Added a variant that takes QualifiedName 18 instead of AtomicString. 19 (WebCore::constructCustomElementSynchronously): Don't add the local name as an argument. 20 * bindings/js/JSCustomElementInterface.h: 21 22 * dom/CustomElementRegistry.cpp: 23 (WebCore::CustomElementRegistry::findInterface): Just find the interface based on the local name after 24 checking the namespace URI to be that of the XHTML. We need to ignore the prefix for the purpose of looking 25 up the custom element definition as specified in the latest HTML specification: 26 https://html.spec.whatwg.org/multipage/scripting.html#look-up-a-custom-element-definition 27 28 * dom/DOMImplementation.cpp: 29 (WebCore::DOMImplementation::createDocument): Added an assertion to make sure we don't invoke scripts while 30 constructing the document element. 31 32 * dom/Document.cpp: 33 (WebCore::createUpgradeCandidateElement): Made this function create a HTMLUnknownElement instead of returning 34 nullptr to share more code. Also added a variant which takes QualifiedName. 35 (WebCore::isValidHTMLElementName): Added; helpers for createHTMLElementWithNameValidation to call isValidName 36 on Document with the right argument. 37 (WebCore::createHTMLElementWithNameValidation): Templatized the function to be called with either AtomicString 38 or QualifiedName for the name. 39 (WebCore::createFallbackHTMLElement): 40 (WebCore::Document::createElementNS): Call createHTMLElementWithNameValidation to create a custom element if 41 possible. This function ends up re-validating the element name before creating a HTMLUnknownElement but that 42 shouldn't be a common scenario to matter. In fact, createElementNS is a rarely used API. 43 1 44 2016-11-14 Chris Dumez <cdumez@apple.com> 2 45 -
trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp
r208256 r208716 68 68 element->setIsFailedCustomElement(*this); 69 69 70 return element.get(); 70 return WTFMove(element); 71 } 72 73 Ref<Element> JSCustomElementInterface::constructElementWithFallback(Document& document, const QualifiedName& name) 74 { 75 if (auto element = tryToConstructCustomElement(document, name.localName())) { 76 if (name.prefix() != nullAtom) 77 element->setPrefix(name.prefix()); 78 return element.releaseNonNull(); 79 } 80 81 auto element = HTMLUnknownElement::create(name, document); 82 element->setIsCustomElementUpgradeCandidate(); 83 element->setIsFailedCustomElement(*this); 84 85 return WTFMove(element); 71 86 } 72 87 … … 111 126 } 112 127 128 InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionConstruct(&document, constructType, constructData); 113 129 MarkedArgumentBuffer args; 114 args.append(jsStringWithCache(&state, localName));115 116 InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionConstruct(&document, constructType, constructData);117 130 JSValue newElement = construct(&state, constructor, constructType, constructData, args); 118 131 InspectorInstrumentation::didCallFunction(cookie, &document); -
trunk/Source/WebCore/bindings/js/JSCustomElementInterface.h
r208256 r208716 60 60 61 61 Ref<Element> constructElementWithFallback(Document&, const AtomicString&); 62 Ref<Element> constructElementWithFallback(Document&, const QualifiedName&); 62 63 63 64 void upgradeElement(Element&); -
trunk/Source/WebCore/dom/CustomElementRegistry.cpp
r208256 r208716 88 88 JSCustomElementInterface* CustomElementRegistry::findInterface(const QualifiedName& name) const 89 89 { 90 ASSERT(!name.hasPrefix());91 90 if (name.namespaceURI() != HTMLNames::xhtmlNamespaceURI) 92 91 return nullptr; 93 auto it = m_nameMap.find(name.localName()); 94 return it == m_nameMap.end() || it->value->name() != name ? nullptr : const_cast<JSCustomElementInterface*>(it->value.ptr()); 92 return m_nameMap.get(name.localName()); 95 93 } 96 94 -
trunk/Source/WebCore/dom/DOMImplementation.cpp
r208688 r208716 115 115 RefPtr<Element> documentElement; 116 116 if (!qualifiedName.isEmpty()) { 117 ASSERT(!document->domWindow()); // If domWindow is not null, createElementNS could find CustomElementRegistry and arbitrary scripts. 117 118 auto result = document->createElementNS(namespaceURI, qualifiedName); 118 119 if (result.hasException()) -
trunk/Source/WebCore/dom/Document.cpp
r208660 r208716 862 862 } 863 863 864 static ALWAYS_INLINE RefPtr<HTMLElement> createUpgradeCandidateElement(Document& document, const QualifiedName& name) 865 { 866 if (!RuntimeEnabledFeatures::sharedFeatures().customElementsEnabled()) 867 return nullptr; 868 869 if (Document::validateCustomElementName(name.localName()) != CustomElementNameValidationStatus::Valid) 870 return nullptr; 864 static ALWAYS_INLINE Ref<HTMLElement> createUpgradeCandidateElement(Document& document, const QualifiedName& name) 865 { 866 if (!RuntimeEnabledFeatures::sharedFeatures().customElementsEnabled() 867 || Document::validateCustomElementName(name.localName()) != CustomElementNameValidationStatus::Valid) 868 return HTMLUnknownElement::create(name, document); 871 869 872 870 auto element = HTMLElement::create(name, document); 873 871 element->setIsCustomElementUpgradeCandidate(); 874 return WTFMove(element); 875 } 876 877 static ExceptionOr<Ref<Element>> createHTMLElementWithNameValidation(Document& document, const AtomicString& localName) 878 { 879 auto element = HTMLElementFactory::createKnownElement(localName, document); 872 return element; 873 } 874 875 static ALWAYS_INLINE Ref<HTMLElement> createUpgradeCandidateElement(Document& document, const AtomicString& localName) 876 { 877 return createUpgradeCandidateElement(document, QualifiedName { nullAtom, localName, xhtmlNamespaceURI }); 878 } 879 880 static inline bool isValidHTMLElementName(const AtomicString& localName) 881 { 882 return Document::isValidName(localName); 883 } 884 885 static inline bool isValidHTMLElementName(const QualifiedName& name) 886 { 887 return Document::isValidName(name.localName()); 888 } 889 890 template<typename NameType> 891 static ExceptionOr<Ref<Element>> createHTMLElementWithNameValidation(Document& document, const NameType& name) 892 { 893 auto element = HTMLElementFactory::createKnownElement(name, document); 880 894 if (LIKELY(element)) 881 895 return Ref<Element> { element.releaseNonNull() }; … … 884 898 auto* registry = window->customElementRegistry(); 885 899 if (UNLIKELY(registry)) { 886 if (auto* elementInterface = registry->findInterface( localName))887 return elementInterface->constructElementWithFallback(document, localName);900 if (auto* elementInterface = registry->findInterface(name)) 901 return elementInterface->constructElementWithFallback(document, name); 888 902 } 889 903 } 890 904 891 if (UNLIKELY(! Document::isValidName(localName)))905 if (UNLIKELY(!isValidHTMLElementName(name))) 892 906 return Exception { INVALID_CHARACTER_ERR }; 893 907 894 QualifiedName qualifiedName { nullAtom, localName, xhtmlNamespaceURI }; 895 896 if (auto element = createUpgradeCandidateElement(document, qualifiedName)) 897 return Ref<Element> { element.releaseNonNull() }; 898 899 return Ref<Element> { HTMLUnknownElement::create(qualifiedName, document) }; 908 return Ref<Element> { createUpgradeCandidateElement(document, name) }; 900 909 } 901 910 … … 1056 1065 } 1057 1066 // FIXME: Should we also check the equality of prefix between the custom element and name? 1058 if (auto element = createUpgradeCandidateElement(document, name)) 1059 return element.releaseNonNull(); 1060 return HTMLUnknownElement::create(name, document); 1067 return createUpgradeCandidateElement(document, name); 1061 1068 } 1062 1069 … … 1160 1167 if (!hasValidNamespaceForElements(parsedName)) 1161 1168 return Exception { NAMESPACE_ERR }; 1169 1170 if (parsedName.namespaceURI() == xhtmlNamespaceURI) 1171 return createHTMLElementWithNameValidation(*this, parsedName); 1172 1162 1173 return createElement(parsedName, false); 1163 1174 }
Note: See TracChangeset
for help on using the changeset viewer.