Changeset 195538 in webkit
- Timestamp:
- Jan 25, 2016 9:23:42 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r195530 r195538 1 2016-01-22 Ryosuke Niwa <rniwa@webkit.org> 2 3 document.createElement should be able to create a custom element 4 https://bugs.webkit.org/show_bug.cgi?id=153173 5 6 Reviewed by Darin Adler. 7 8 Add a test for creating a custom elemnet via document.createElement. 9 The behavior is to be documented later. 10 11 * fast/custom-elements/Document-createElement-expected.txt: Added. 12 * fast/custom-elements/Document-createElement.html: Added. 13 1 14 2016-01-25 Youenn Fablet <youenn.fablet@crf.canon.fr> 2 15 -
trunk/Source/WebCore/ChangeLog
r195537 r195538 1 2016-01-22 Ryosuke Niwa <rniwa@webkit.org> 2 3 document.createElement should be able to create a custom element 4 https://bugs.webkit.org/show_bug.cgi?id=153173 5 6 Reviewed by Darin Adler. 7 8 Added the support for constructing a custom element via document.createElement. 9 10 Extracted HTMLElementFactory::createKnownElement, which returns nullptr when the specified name doesn't match 11 any builtin element instead of out of HTMLUnknownElement, out of HTMLElementFactory::createElement. 12 13 Test: fast/custom-elements/Document-createElement.html 14 15 * bindings/js/JSCustomElementInterface.cpp: 16 (WebCore::JSCustomElementInterface::constructHTMLElement): Added. Constructs a custom element by invoking its 17 constructor. We allow exceptions to be thrown by the constructor so the caller is responsible for checking 18 any exceptions in the ExecState before preceeding if the returned value is null. 19 20 * bindings/js/JSCustomElementInterface.h: 21 (WebCore::JSCustomElementInterface::constructSVGElement): Added. 22 * bindings/js/JSElementCustom.cpp: 23 (WebCore::toJSNewlyCreated): Exit early if the element is a custom element as the wrapper had already been 24 created by super() call inside the custom element'c constructor. 25 26 * bindings/js/JSMainThreadExecState.h: 27 (WebCore::JSMainThreadExecState): 28 * bindings/js/JSMainThreadExecStateInstrumentation.h: 29 (WebCore::JSMainThreadExecState::instrumentFunctionInternal): Generalized from instrumentFunctionCall so that 30 we can use it for both call and construct. 31 (WebCore::JSMainThreadExecState::instrumentFunctionCall): Specialized the above function for call. 32 (WebCore::JSMainThreadExecState::instrumentFunctionConstruct): Ditto for construct. 33 34 * dom/CustomElementDefinitions.cpp: 35 (WebCore::CustomElementDefinitions::findInterface): Added. 36 * dom/CustomElementDefinitions.h: 37 38 * dom/Document.cpp: 39 (WebCore::createHTMLElementWithNameValidation): Extracted from createElement. 40 (WebCore::Document::createElementForBindings): Renamed from createElement. Specifies 41 ShouldCreateCustomElement::Create to create a custom element before using fallback elements. 42 * dom/Document.h: 43 * dom/Document.idl: 44 45 * dom/Node.h: 46 (WebCore::Node::isCustomElement): Added. This flag is used to identify a custom element. 47 (WebCore::Node::setIsCustomElement): Added. 48 49 * dom/make_names.pl: Extracted createKnownElement from createElement for createHTMLElementWithNameValidation. 50 51 * inspector/InspectorCSSAgent.cpp: 52 (WebCore::InspectorCSSAgent::createInspectorStyleSheetForDocument): Use qualified name object to instantiate 53 a style element and set type content attribute. 54 * inspector/InspectorDOMAgent.cpp: 55 (WebCore::InspectorDOMAgent::setNodeName): Use createElementForBindings here since we might be creating an 56 arbitrary element here. Also use RefPtr instead of raw pointers while mutating DOM for safety. 57 1 58 2016-01-25 Carlos Garcia Campos <cgarcia@igalia.com> 2 59 -
trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp
r195087 r195538 32 32 33 33 #include "DOMWrapperWorld.h" 34 #include "Element.h"35 34 #include "JSDOMGlobalObject.h" 36 35 #include "JSElement.h" 36 #include "JSHTMLElement.h" 37 37 #include "JSMainThreadExecState.h" 38 38 #include "JSMainThreadExecStateInstrumentation.h" … … 56 56 } 57 57 58 RefPtr<Element> JSCustomElementInterface::constructElement(const AtomicString& tagName) 59 { 60 if (!canInvokeCallback()) 61 return nullptr; 62 63 Ref<JSCustomElementInterface> protect(*this); 64 65 JSLockHolder lock(m_isolatedWorld->vm()); 66 67 if (!m_constructor) 68 return nullptr; 69 70 ScriptExecutionContext* context = scriptExecutionContext(); 71 if (!context) 72 return nullptr; 73 ASSERT(context->isDocument()); 74 JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, *m_isolatedWorld); 75 ExecState* state = globalObject->globalExec(); 76 77 ConstructData constructData; 78 ConstructType constructType = m_constructor->methodTable()->getConstructData(m_constructor.get(), constructData); 79 if (constructType == ConstructTypeNone) { 80 ASSERT_NOT_REACHED(); 81 return nullptr; 82 } 83 84 MarkedArgumentBuffer args; 85 args.append(jsStringWithCache(state, tagName)); 86 87 InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionConstruct(context, constructType, constructData); 88 JSValue newElement = construct(state, m_constructor.get(), constructType, constructData, args); 89 InspectorInstrumentation::didCallFunction(cookie, context); 90 91 if (newElement.isEmpty()) 92 return nullptr; 93 94 Element* wrappedElement = JSElement::toWrapped(newElement); 95 if (!wrappedElement) 96 return nullptr; 97 wrappedElement->setIsCustomElement(); 98 return wrappedElement; 99 } 100 58 101 } // namespace WebCore 59 102 -
trunk/Source/WebCore/bindings/js/JSCustomElementInterface.h
r195087 r195538 50 50 class Element; 51 51 class JSDOMGlobalObject; 52 class MathMLElement; 53 class SVGElement; 52 54 53 55 class JSCustomElementInterface : public RefCounted<JSCustomElementInterface>, public ActiveDOMCallback { … … 57 59 return adoptRef(*new JSCustomElementInterface(callback, globalObject)); 58 60 } 61 62 RefPtr<Element> constructElement(const AtomicString&); 59 63 60 64 ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); } -
trunk/Source/WebCore/bindings/js/JSElementCustom.cpp
r191887 r195538 55 55 return jsNull(); 56 56 57 #if ENABLE(CUSTOM_ELEMENTS) 58 if (element->isCustomElement()) 59 return getCachedWrapper(globalObject->world(), element); 60 #endif 57 61 ASSERT(!getCachedWrapper(globalObject->world(), element)); 58 62 -
trunk/Source/WebCore/bindings/js/JSMainThreadExecState.h
r194871 r195538 94 94 95 95 static InspectorInstrumentationCookie instrumentFunctionCall(ScriptExecutionContext*, JSC::CallType, const JSC::CallData&); 96 static InspectorInstrumentationCookie instrumentFunctionConstruct(ScriptExecutionContext*, JSC::ConstructType, const JSC::ConstructData&); 96 97 97 98 private: … … 116 117 didLeaveScriptContext(); 117 118 } 119 120 template<typename Type, Type jsType, typename DataType> static InspectorInstrumentationCookie instrumentFunctionInternal(ScriptExecutionContext*, Type, const DataType&); 118 121 119 122 static JSC::ExecState* s_mainThreadState; -
trunk/Source/WebCore/bindings/js/JSMainThreadExecStateInstrumentation.h
r182038 r195538 34 34 namespace WebCore { 35 35 36 inline InspectorInstrumentationCookie JSMainThreadExecState::instrumentFunctionCall(ScriptExecutionContext* context, JSC::CallType callType, const JSC::CallData& callData) 36 template<typename Type, Type jsType, class DataType> 37 inline InspectorInstrumentationCookie JSMainThreadExecState::instrumentFunctionInternal(ScriptExecutionContext* context, Type callType, const DataType& callData) 37 38 { 38 39 if (!InspectorInstrumentation::timelineAgentEnabled(context)) … … 40 41 String resourceName; 41 42 int lineNumber = 1; 42 if (callType == JSC::CallTypeJS) {43 if (callType == jsType) { 43 44 resourceName = callData.js.functionExecutable->sourceURL(); 44 45 lineNumber = callData.js.functionExecutable->firstLine(); … … 48 49 } 49 50 51 inline InspectorInstrumentationCookie JSMainThreadExecState::instrumentFunctionCall(ScriptExecutionContext* context, JSC::CallType type, const JSC::CallData& data) 52 { 53 return instrumentFunctionInternal<JSC::CallType, JSC::CallTypeJS, JSC::CallData>(context, type, data); 54 } 55 56 inline InspectorInstrumentationCookie JSMainThreadExecState::instrumentFunctionConstruct(ScriptExecutionContext* context, JSC::ConstructType type, const JSC::ConstructData& data) 57 { 58 return instrumentFunctionInternal<JSC::ConstructType, JSC::ConstructTypeJS, JSC::ConstructData>(context, type, data); 59 } 60 50 61 } // namespace WebCore 51 62 -
trunk/Source/WebCore/dom/CustomElementDefinitions.cpp
r195087 r195538 83 83 } 84 84 85 JSCustomElementInterface* CustomElementDefinitions::findInterface(const QualifiedName& name) const 86 { 87 auto it = m_nameMap.find(name.localName()); 88 return it == m_nameMap.end() || it->value.fullName != name ? nullptr : it->value.interface.get(); 89 } 90 85 91 JSCustomElementInterface* CustomElementDefinitions::findInterface(const AtomicString& name) const 86 92 { -
trunk/Source/WebCore/dom/CustomElementDefinitions.h
r195087 r195538 51 51 bool defineElement(const QualifiedName&, Ref<JSCustomElementInterface>&&); 52 52 53 JSCustomElementInterface* findInterface(const QualifiedName&) const; 53 54 JSCustomElementInterface* findInterface(const AtomicString&) const; 54 55 const QualifiedName& findName(const JSC::JSObject*) const; -
trunk/Source/WebCore/dom/Document.cpp
r195524 r195538 91 91 #include "HTMLStyleElement.h" 92 92 #include "HTMLTitleElement.h" 93 #include "HTMLUnknownElement.h" 93 94 #include "HTTPHeaderNames.h" 94 95 #include "HTTPParsers.h" … … 883 884 } 884 885 885 RefPtr<Element> Document::createElement(const AtomicString& name, ExceptionCode& ec) 886 { 886 static RefPtr<Element> createHTMLElementWithNameValidation(Document& document, const QualifiedName qualifiedName, ExceptionCode& ec) 887 { 888 RefPtr<HTMLElement> element = HTMLElementFactory::createKnownElement(qualifiedName, document); 889 if (LIKELY(element)) 890 return element; 891 892 #if ENABLE(CUSTOM_ELEMENTS) 893 auto* definitions = document.customElementDefinitions(); 894 if (UNLIKELY(definitions)) { 895 if (auto* interface = definitions->findInterface(qualifiedName)) 896 return interface->constructElement(qualifiedName.localName()); 897 } 898 #endif 899 900 if (UNLIKELY(!Document::isValidName(qualifiedName.localName()))) { 901 ec = INVALID_CHARACTER_ERR; 902 return nullptr; 903 } 904 905 return HTMLUnknownElement::create(qualifiedName, document); 906 } 907 908 RefPtr<Element> Document::createElementForBindings(const AtomicString& name, ExceptionCode& ec) 909 { 910 if (isHTMLDocument()) 911 return createHTMLElementWithNameValidation(*this, QualifiedName(nullAtom, name.convertToASCIILowercase(), xhtmlNamespaceURI), ec); 912 913 if (isXHTMLDocument()) 914 return createHTMLElementWithNameValidation(*this, QualifiedName(nullAtom, name, xhtmlNamespaceURI), ec); 915 887 916 if (!isValidName(name)) { 888 917 ec = INVALID_CHARACTER_ERR; 889 918 return nullptr; 890 919 } 891 892 if (isHTMLDocument())893 return HTMLElementFactory::createElement(QualifiedName(nullAtom, name.convertToASCIILowercase(), xhtmlNamespaceURI), *this);894 895 if (isXHTMLDocument())896 return HTMLElementFactory::createElement(QualifiedName(nullAtom, name, xhtmlNamespaceURI), *this);897 920 898 921 return createElement(QualifiedName(nullAtom, name, nullAtom), false); -
trunk/Source/WebCore/dom/Document.h
r195524 r195538 384 384 bool hasManifest() const; 385 385 386 WEBCORE_EXPORT RefPtr<Element> createElement (const AtomicString& tagName, ExceptionCode&);386 WEBCORE_EXPORT RefPtr<Element> createElementForBindings(const AtomicString& tagName, ExceptionCode&); 387 387 WEBCORE_EXPORT Ref<DocumentFragment> createDocumentFragment(); 388 388 WEBCORE_EXPORT Ref<Text> createTextNode(const String& data); -
trunk/Source/WebCore/dom/Document.idl
r195497 r195538 32 32 readonly attribute Element documentElement; 33 33 34 [NewObject, RaisesException ] Element createElement(DOMString tagName);34 [NewObject, RaisesException, ImplementedAs=createElementForBindings] Element createElement(DOMString tagName); 35 35 [NewObject] DocumentFragment createDocumentFragment(); 36 36 [NewObject] Text createTextNode([Default=Undefined] optional DOMString data); -
trunk/Source/WebCore/dom/Node.h
r195355 r195538 287 287 #endif 288 288 289 #if ENABLE(CUSTOM_ELEMENTS) 290 bool isCustomElement() const { return getFlag(IsCustomElement); } 291 void setIsCustomElement() { return setFlag(IsCustomElement); } 292 #endif 293 289 294 // Returns null, a child of ShadowRoot, or a legacy shadow root. 290 295 Node* nonBoundaryShadowTreeRootNode(); … … 618 623 HasCustomStyleResolveCallbacksFlag = 1 << 20, 619 624 HasEventTargetDataFlag = 1 << 21, 620 // HeyItIsAFreeBit = 1 << 22,625 IsCustomElement = 1 << 22, 621 626 IsInShadowTreeFlag = 1 << 23, 622 627 IsMathMLFlag = 1 << 24, -
trunk/Source/WebCore/dom/make_names.pl
r191060 r195538 979 979 980 980 my %tagConstructorMap = buildConstructorMap(); 981 my $argumentList; 982 983 if ($parameters{namespace} eq "HTML") { 984 $argumentList = "name, document, formElement, createdByParser"; 985 } else { 986 $argumentList = "name, document, createdByParser"; 987 } 981 988 982 989 printConstructors($F, \%tagConstructorMap); … … 1003 1010 } 1004 1011 1005 Ref <$parameters{namespace}Element> $parameters{namespace}ElementFactory::createElement(const QualifiedName& name, Document& document$formElementArgumentForDefinition, bool createdByParser)1012 RefPtr<$parameters{namespace}Element> $parameters{namespace}ElementFactory::createKnownElement(const QualifiedName& name, Document& document$formElementArgumentForDefinition, bool createdByParser) 1006 1013 { 1007 1014 static NeverDestroyed<HashMap<AtomicStringImpl*, $parameters{namespace}ConstructorFunction>> functions; 1008 1015 if (functions.get().isEmpty()) 1009 1016 populate$parameters{namespace}FactoryMap(functions); 1010 if ($parameters{namespace}ConstructorFunction function = functions.get().get(name.localName().impl()))1011 END 1012 ;1013 1014 if ($parameters{namespace} eq "HTML") { 1015 print F " return function(name, document, formElement, createdByParser);\n"; 1016 } else { 1017 print F " return function(name, document, createdByParser);\n"; 1018 }1019 1020 print F <<END1017 $parameters{namespace}ConstructorFunction function = functions.get().get(name.localName().impl()); 1018 if (LIKELY(function)) 1019 return function($argumentList); 1020 return nullptr; 1021 } 1022 1023 Ref<$parameters{namespace}Element> $parameters{namespace}ElementFactory::createElement(const QualifiedName& name, Document& document$formElementArgumentForDefinition, bool createdByParser) 1024 { 1025 RefPtr<$parameters{namespace}Element> element = $parameters{namespace}ElementFactory::createKnownElement($argumentList); 1026 if (LIKELY(element)) 1027 return element.releaseNonNull(); 1021 1028 return $parameters{fallbackInterfaceName}::create(name, document); 1022 1029 } … … 1059 1066 ; 1060 1067 1068 print F " static RefPtr<$parameters{namespace}Element> createKnownElement(const QualifiedName&, Document&"; 1069 print F ", HTMLFormElement* = nullptr" if $parameters{namespace} eq "HTML"; 1070 print F ", bool createdByParser = false);\n\n"; 1061 1071 print F " static Ref<$parameters{namespace}Element> createElement(const QualifiedName&, Document&"; 1062 1072 print F ", HTMLFormElement* = nullptr" if $parameters{namespace} eq "HTML"; -
trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp
r195386 r195538 777 777 return nullptr; 778 778 779 ExceptionCode ec = 0; 780 RefPtr<Element> styleElement = document.createElement("style", ec); 781 if (ec) 782 return nullptr; 783 784 styleElement->setAttribute("type", "text/css", ec); 785 if (ec) 786 return nullptr; 779 Ref<Element> styleElement = document.createElement(HTMLNames::styleTag, false); 780 styleElement->setAttribute(HTMLNames::typeAttr, "text/css"); 787 781 788 782 ContainerNode* targetNode; … … 800 794 m_creatingViaInspectorStyleSheet = true; 801 795 InlineStyleOverrideScope overrideScope(document); 802 targetNode->appendChild(styleElement.releaseNonNull(), ec); 796 ExceptionCode ec = 0; 797 targetNode->appendChild(WTFMove(styleElement), ec); 803 798 m_creatingViaInspectorStyleSheet = false; 804 799 if (ec) -
trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp
r195520 r195538 715 715 *newId = 0; 716 716 717 Node*oldNode = nodeForId(nodeId);718 if (!is<Element>(oldNode ))717 RefPtr<Node> oldNode = nodeForId(nodeId); 718 if (!is<Element>(oldNode.get())) 719 719 return; 720 720 721 721 ExceptionCode ec = 0; 722 RefPtr<Element> newElem = oldNode->document().createElement(tagName, ec);722 RefPtr<Element> newElement = oldNode->document().createElementForBindings(tagName, ec); 723 723 if (ec) 724 724 return; 725 725 726 726 // Copy over the original node's attributes. 727 newElem ->cloneAttributesFromElement(*downcast<Element>(oldNode));727 newElement->cloneAttributesFromElement(downcast<Element>(*oldNode)); 728 728 729 729 // Copy over the original node's children. 730 Node*child;730 RefPtr<Node> child; 731 731 while ((child = oldNode->firstChild())) { 732 if (!m_domEditor->insertBefore(newElem .get(), child, 0, errorString))732 if (!m_domEditor->insertBefore(newElement.get(), child.get(), 0, errorString)) 733 733 return; 734 734 } 735 735 736 736 // Replace the old node with the new node 737 ContainerNode*parent = oldNode->parentNode();738 if (!m_domEditor->insertBefore(parent , newElem.get(), oldNode->nextSibling(), errorString))739 return; 740 if (!m_domEditor->removeChild(parent , oldNode, errorString))741 return; 742 743 *newId = pushNodePathToFrontend(newElem .get());737 RefPtr<ContainerNode> parent = oldNode->parentNode(); 738 if (!m_domEditor->insertBefore(parent.get(), newElement.get(), oldNode->nextSibling(), errorString)) 739 return; 740 if (!m_domEditor->removeChild(parent.get(), oldNode.get(), errorString)) 741 return; 742 743 *newId = pushNodePathToFrontend(newElement.get()); 744 744 if (m_childrenRequested.contains(nodeId)) 745 745 pushChildNodesToFrontend(*newId); -
trunk/Source/WebKit/win/ChangeLog
r195524 r195538 1 2016-01-22 Ryosuke Niwa <rniwa@webkit.org> 2 3 document.createElement should be able to create a custom element 4 https://bugs.webkit.org/show_bug.cgi?id=153173 5 6 Reviewed by Darin Adler. 7 8 Use createElementForBindings here since this is a C++ binding for Windows. 9 10 * DOMCoreClasses.cpp: 11 (DOMDocument::createElement): 12 1 13 2016-01-24 Gyuyoung Kim <gyuyoung.kim@webkit.org> 2 14 -
trunk/Source/WebKit/win/DOMCoreClasses.cpp
r189830 r195538 636 636 String tagNameString(tagName); 637 637 ExceptionCode ec; 638 *result = DOMElement::createInstance(m_document->createElement (tagNameString, ec).get());638 *result = DOMElement::createInstance(m_document->createElementForBindings(tagNameString, ec).get()); 639 639 return *result ? S_OK : E_FAIL; 640 640 } -
trunk/Source/WebKit2/ChangeLog
r195526 r195538 1 2016-01-22 Ryosuke Niwa <rniwa@webkit.org> 2 3 document.createElement should be able to create a custom element 4 https://bugs.webkit.org/show_bug.cgi?id=153173 5 6 Reviewed by Darin Adler. 7 8 Use createElementForBindings here since this is for SPI. 9 10 * WebProcess/InjectedBundle/API/mac/WKDOMDocument.mm: 11 (-[WKDOMDocument createElement:]): 12 (-[WKDOMDocument createTextNode:]): 13 1 14 2016-01-24 Alex Christensen <achristensen@webkit.org> 2 15 -
trunk/Source/WebKit2/WebProcess/InjectedBundle/API/mac/WKDOMDocument.mm
r179157 r195538 40 40 // FIXME: Do something about the exception. 41 41 WebCore::ExceptionCode ec = 0; 42 return WebKit::toWKDOMElement(downcast<WebCore::Document>(*_impl).createElement (tagName, ec).get());42 return WebKit::toWKDOMElement(downcast<WebCore::Document>(*_impl).createElementForBindings(tagName, ec).get()); 43 43 } 44 44
Note: See TracChangeset
for help on using the changeset viewer.