Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: third_party/WebKit/Source/core/dom/Document.cpp

Issue 2477713003: Custom Elements: Check Definition in createElement, Create Customized Built-in Elements Sync (Closed)
Patch Set: V1 definition check in document::createElement Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All
7 * rights reserved. 7 * rights reserved.
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
9 * (http://www.torchmobile.com/) 9 * (http://www.torchmobile.com/)
10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. 10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
(...skipping 26 matching lines...) Expand all
37 #include "bindings/core/v8/Microtask.h" 37 #include "bindings/core/v8/Microtask.h"
38 #include "bindings/core/v8/ScriptController.h" 38 #include "bindings/core/v8/ScriptController.h"
39 #include "bindings/core/v8/SourceLocation.h" 39 #include "bindings/core/v8/SourceLocation.h"
40 #include "bindings/core/v8/StringOrDictionary.h" 40 #include "bindings/core/v8/StringOrDictionary.h"
41 #include "bindings/core/v8/V0CustomElementConstructorBuilder.h" 41 #include "bindings/core/v8/V0CustomElementConstructorBuilder.h"
42 #include "bindings/core/v8/V8DOMWrapper.h" 42 #include "bindings/core/v8/V8DOMWrapper.h"
43 #include "bindings/core/v8/V8ElementCreationOptions.h" 43 #include "bindings/core/v8/V8ElementCreationOptions.h"
44 #include "bindings/core/v8/V8PerIsolateData.h" 44 #include "bindings/core/v8/V8PerIsolateData.h"
45 #include "bindings/core/v8/WindowProxy.h" 45 #include "bindings/core/v8/WindowProxy.h"
46 #include "core/HTMLElementFactory.h" 46 #include "core/HTMLElementFactory.h"
47 #include "core/HTMLElementTypeHelpers.h"
47 #include "core/HTMLNames.h" 48 #include "core/HTMLNames.h"
48 #include "core/SVGElementFactory.h" 49 #include "core/SVGElementFactory.h"
49 #include "core/SVGNames.h" 50 #include "core/SVGNames.h"
50 #include "core/XMLNSNames.h" 51 #include "core/XMLNSNames.h"
51 #include "core/XMLNames.h" 52 #include "core/XMLNames.h"
52 #include "core/animation/CompositorPendingAnimations.h" 53 #include "core/animation/CompositorPendingAnimations.h"
53 #include "core/animation/DocumentAnimations.h" 54 #include "core/animation/DocumentAnimations.h"
54 #include "core/animation/DocumentTimeline.h" 55 #include "core/animation/DocumentTimeline.h"
55 #include "core/css/CSSFontSelector.h" 56 #include "core/css/CSSFontSelector.h"
56 #include "core/css/CSSStyleDeclaration.h" 57 #include "core/css/CSSStyleDeclaration.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 #include "core/dom/StaticNodeList.h" 106 #include "core/dom/StaticNodeList.h"
106 #include "core/dom/StyleChangeReason.h" 107 #include "core/dom/StyleChangeReason.h"
107 #include "core/dom/StyleEngine.h" 108 #include "core/dom/StyleEngine.h"
108 #include "core/dom/TaskRunnerHelper.h" 109 #include "core/dom/TaskRunnerHelper.h"
109 #include "core/dom/TouchList.h" 110 #include "core/dom/TouchList.h"
110 #include "core/dom/TransformSource.h" 111 #include "core/dom/TransformSource.h"
111 #include "core/dom/TreeWalker.h" 112 #include "core/dom/TreeWalker.h"
112 #include "core/dom/VisitedLinkState.h" 113 #include "core/dom/VisitedLinkState.h"
113 #include "core/dom/XMLDocument.h" 114 #include "core/dom/XMLDocument.h"
114 #include "core/dom/custom/CustomElement.h" 115 #include "core/dom/custom/CustomElement.h"
116 #include "core/dom/custom/CustomElementDefinition.h"
117 #include "core/dom/custom/CustomElementDescriptor.h"
115 #include "core/dom/custom/CustomElementRegistry.h" 118 #include "core/dom/custom/CustomElementRegistry.h"
116 #include "core/dom/custom/V0CustomElementMicrotaskRunQueue.h" 119 #include "core/dom/custom/V0CustomElementMicrotaskRunQueue.h"
117 #include "core/dom/custom/V0CustomElementRegistrationContext.h" 120 #include "core/dom/custom/V0CustomElementRegistrationContext.h"
118 #include "core/dom/shadow/ElementShadow.h" 121 #include "core/dom/shadow/ElementShadow.h"
119 #include "core/dom/shadow/FlatTreeTraversal.h" 122 #include "core/dom/shadow/FlatTreeTraversal.h"
120 #include "core/dom/shadow/ShadowRoot.h" 123 #include "core/dom/shadow/ShadowRoot.h"
121 #include "core/editing/DragCaretController.h" 124 #include "core/editing/DragCaretController.h"
122 #include "core/editing/EditingUtilities.h" 125 #include "core/editing/EditingUtilities.h"
123 #include "core/editing/Editor.h" 126 #include "core/editing/Editor.h"
124 #include "core/editing/FrameSelection.h" 127 #include "core/editing/FrameSelection.h"
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 exceptionState); 706 exceptionState);
704 if (impl.hasIs()) 707 if (impl.hasIs())
705 return impl.is(); 708 return impl.is();
706 709
707 return toCoreString(dict.v8Value()->ToString()); 710 return toCoreString(dict.v8Value()->ToString());
708 } 711 }
709 712
710 return emptyString(); 713 return emptyString();
711 } 714 }
712 715
716 // https://dom.spec.whatwg.org/#dom-document-createelement
713 Element* Document::createElement(const AtomicString& localName, 717 Element* Document::createElement(const AtomicString& localName,
714 const StringOrDictionary& stringOrOptions, 718 const StringOrDictionary& stringOrOptions,
715 ExceptionState& exceptionState) { 719 ExceptionState& exceptionState) {
720 bool isV1 = stringOrOptions.isDictionary() || !registrationContext();
dominicc (has gone to gerrit) 2016/11/15 07:39:53 This v0, v1 split thing is very tricky. The way y
721 // 1. If localName does not match Name production, throw InvalidCharacterError
716 if (!isValidName(localName)) { 722 if (!isValidName(localName)) {
717 exceptionState.throwDOMException( 723 exceptionState.throwDOMException(
718 InvalidCharacterError, 724 InvalidCharacterError,
719 "The tag name provided ('" + localName + "') is not a valid name."); 725 "The tag name provided ('" + localName + "') is not a valid name.");
720 return nullptr; 726 return nullptr;
721 } 727 }
722 728
729 // 2. localName converted to ASCII lowercase
730 const AtomicString& convertedLocalName = convertLocalName(localName);
731
732 // 3.
733 const AtomicString& is = convertLocalName(
734 AtomicString(getTypeExtension(this, stringOrOptions, exceptionState)));
735 const AtomicString& name = is.isNull() ? convertedLocalName : is;
736
737 // 4. Let definition be result of lookup up custom element definition
738 CustomElementDefinition* definition = nullptr;
739 if (isV1) {
740 // Is the runtime flag enabled for customized builtin elements?
741 const CustomElementDescriptor desc =
742 RuntimeEnabledFeatures::customElementsBuiltinEnabled()
743 ? CustomElementDescriptor(name, convertedLocalName)
744 : CustomElementDescriptor(convertedLocalName, convertedLocalName);
745 definition = CustomElement::registry(*this)->definitionFor(desc);
746 // 5. If 'is' is non-null and definition is null, throw NotFoundError
747 if (!definition && !is.isNull() && stringOrOptions.isDictionary()) {
748 exceptionState.throwDOMException(NotFoundError,
749 "Custom element definition not found.");
750 return nullptr;
751 }
752 }
753
754 // 7. Let element be the result of creating an element
723 Element* element; 755 Element* element;
724 756
725 if (CustomElement::shouldCreateCustomElement(convertLocalName(localName))) { 757 if (definition) {
726 element = CustomElement::createCustomElementSync( 758 element =
727 *this, convertLocalName(localName)); 759 CustomElement::createCustomElementSync(*this, convertedLocalName, name);
728 } else if (V0CustomElement::isValidName(localName) && registrationContext()) { 760 } else if (V0CustomElement::isValidName(localName) && registrationContext()) {
729 element = registrationContext()->createCustomTagElement( 761 element = registrationContext()->createCustomTagElement(
730 *this, QualifiedName(nullAtom, convertLocalName(localName), 762 *this, QualifiedName(nullAtom, convertedLocalName, xhtmlNamespaceURI));
731 xhtmlNamespaceURI));
732 } else { 763 } else {
733 element = createElement(localName, exceptionState); 764 element = createElement(localName, exceptionState);
734 if (exceptionState.hadException()) 765 if (exceptionState.hadException())
735 return nullptr; 766 return nullptr;
736 } 767 }
737 768
738 String typeExtention = 769 // 8. If 'is' is non-null, set 'is' attribute
739 getTypeExtension(this, stringOrOptions, exceptionState); 770 if (!is.isEmpty()) {
740 if (!typeExtention.isEmpty()) { 771 if (stringOrOptions.isString()) {
741 V0CustomElementRegistrationContext::setIsAttributeAndTypeExtension( 772 V0CustomElementRegistrationContext::setIsAttributeAndTypeExtension(
742 element, AtomicString(typeExtention)); 773 element, is);
774 } else if (stringOrOptions.isDictionary()) {
775 element->setAttribute(HTMLNames::isAttr, is);
776 }
743 } 777 }
744 778
745 return element; 779 return element;
746 } 780 }
747 781
748 static inline QualifiedName createQualifiedName( 782 static inline QualifiedName createQualifiedName(
749 const AtomicString& namespaceURI, 783 const AtomicString& namespaceURI,
750 const AtomicString& qualifiedName, 784 const AtomicString& qualifiedName,
751 ExceptionState& exceptionState) { 785 ExceptionState& exceptionState) {
752 AtomicString prefix, localName; 786 AtomicString prefix, localName;
(...skipping 20 matching lines...) Expand all
773 QualifiedName qName( 807 QualifiedName qName(
774 createQualifiedName(namespaceURI, qualifiedName, exceptionState)); 808 createQualifiedName(namespaceURI, qualifiedName, exceptionState));
775 if (qName == QualifiedName::null()) 809 if (qName == QualifiedName::null())
776 return nullptr; 810 return nullptr;
777 811
778 if (CustomElement::shouldCreateCustomElement(qName)) 812 if (CustomElement::shouldCreateCustomElement(qName))
779 return CustomElement::createCustomElementSync(*this, qName); 813 return CustomElement::createCustomElementSync(*this, qName);
780 return createElement(qName, CreatedByCreateElement); 814 return createElement(qName, CreatedByCreateElement);
781 } 815 }
782 816
817 // https://dom.spec.whatwg.org/#internal-createelementns-steps
783 Element* Document::createElementNS(const AtomicString& namespaceURI, 818 Element* Document::createElementNS(const AtomicString& namespaceURI,
784 const AtomicString& qualifiedName, 819 const AtomicString& qualifiedName,
785 const StringOrDictionary& stringOrOptions, 820 const StringOrDictionary& stringOrOptions,
786 ExceptionState& exceptionState) { 821 ExceptionState& exceptionState) {
822 bool isV1 = stringOrOptions.isDictionary() || !registrationContext();
823 // 1. Validate and extract
dominicc (has gone to gerrit) 2016/11/15 07:39:54 These comments seem incomplete?
824
825 // 2.
826 const AtomicString& is =
827 AtomicString(getTypeExtension(this, stringOrOptions, exceptionState));
828 const AtomicString& name = is.isNull() ? qualifiedName : is;
829
830 if (!isValidName(qualifiedName)) {
831 exceptionState.throwDOMException(
832 InvalidCharacterError,
833 "The tag name provided ('" + qualifiedName + "') is not a valid name.");
834 return nullptr;
835 }
836
787 QualifiedName qName( 837 QualifiedName qName(
788 createQualifiedName(namespaceURI, qualifiedName, exceptionState)); 838 createQualifiedName(namespaceURI, qualifiedName, exceptionState));
789 if (qName == QualifiedName::null()) 839 if (qName == QualifiedName::null())
790 return nullptr; 840 return nullptr;
791 841
842 // 3. Let definition be result of lookup up custom element definition
dominicc (has gone to gerrit) 2016/11/15 07:39:54 Transcribe these carefully.
843 CustomElementDefinition* definition = nullptr;
844 if (isV1) {
845 const CustomElementDescriptor desc =
846 RuntimeEnabledFeatures::customElementsBuiltinEnabled()
847 ? CustomElementDescriptor(name, qualifiedName)
848 : CustomElementDescriptor(qualifiedName, qualifiedName);
849 definition = CustomElement::registry(*this)->definitionFor(desc);
850
851 // 4. If 'is' is non-null and definition is null, throw NotFoundError
852 if (!definition && !is.isNull()) {
853 exceptionState.throwDOMException(NotFoundError,
854 "Custom element definition not found.");
855 return nullptr;
856 }
857 }
858
859 // 5. Let element be the result of creating an element
792 Element* element; 860 Element* element;
793 if (CustomElement::shouldCreateCustomElement(qName)) 861
794 element = CustomElement::createCustomElementSync(*this, qName); 862 bool shouldCreateBuiltin =
795 else if (V0CustomElement::isValidName(qName.localName()) && 863 isV1 && RuntimeEnabledFeatures::customElementsBuiltinEnabled();
796 registrationContext()) 864
865 if (CustomElement::shouldCreateCustomElement(qName) || shouldCreateBuiltin) {
866 element = CustomElement::createCustomElementSync(*this, qName, is);
867 } else if (V0CustomElement::isValidName(qName.localName()) &&
868 registrationContext()) {
797 element = registrationContext()->createCustomTagElement(*this, qName); 869 element = registrationContext()->createCustomTagElement(*this, qName);
798 else 870 } else {
799 element = createElement(qName, CreatedByCreateElement); 871 element = createElement(qName, CreatedByCreateElement);
872 }
800 873
801 String typeExtention = 874 // 6. If 'is' is non-null, set 'is' attribute
802 getTypeExtension(this, stringOrOptions, exceptionState); 875 if (!is.isEmpty()) {
803 if (!typeExtention.isEmpty()) { 876 if (element->getCustomElementState() != CustomElementState::Custom) {
804 V0CustomElementRegistrationContext::setIsAttributeAndTypeExtension( 877 V0CustomElementRegistrationContext::setIsAttributeAndTypeExtension(
805 element, AtomicString(typeExtention)); 878 element, is);
879 } else if (stringOrOptions.isDictionary()) {
880 element->setAttribute(HTMLNames::isAttr, is);
881 }
806 } 882 }
807 883
808 return element; 884 return element;
809 } 885 }
810 886
811 ScriptValue Document::registerElement(ScriptState* scriptState, 887 ScriptValue Document::registerElement(ScriptState* scriptState,
812 const AtomicString& name, 888 const AtomicString& name,
813 const ElementRegistrationOptions& options, 889 const ElementRegistrationOptions& options,
814 ExceptionState& exceptionState, 890 ExceptionState& exceptionState,
815 V0CustomElement::NameSet validNames) { 891 V0CustomElement::NameSet validNames) {
(...skipping 5622 matching lines...) Expand 10 before | Expand all | Expand 10 after
6438 } 6514 }
6439 6515
6440 void showLiveDocumentInstances() { 6516 void showLiveDocumentInstances() {
6441 WeakDocumentSet& set = liveDocumentSet(); 6517 WeakDocumentSet& set = liveDocumentSet();
6442 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); 6518 fprintf(stderr, "There are %u documents currently alive:\n", set.size());
6443 for (Document* document : set) 6519 for (Document* document : set)
6444 fprintf(stderr, "- Document %p URL: %s\n", document, 6520 fprintf(stderr, "- Document %p URL: %s\n", document,
6445 document->url().getString().utf8().data()); 6521 document->url().getString().utf8().data());
6446 } 6522 }
6447 #endif 6523 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698