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

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: patch fix 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 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 exceptionState); 705 exceptionState);
703 if (impl.hasIs()) 706 if (impl.hasIs())
704 return impl.is(); 707 return impl.is();
705 708
706 return toCoreString(dict.v8Value()->ToString()); 709 return toCoreString(dict.v8Value()->ToString());
707 } 710 }
708 711
709 return emptyString(); 712 return emptyString();
710 } 713 }
711 714
715 // https://dom.spec.whatwg.org/#dom-document-createelement
712 Element* Document::createElement(const AtomicString& localName, 716 Element* Document::createElement(const AtomicString& localName,
713 const StringOrDictionary& stringOrOptions, 717 const StringOrDictionary& stringOrOptions,
714 ExceptionState& exceptionState) { 718 ExceptionState& exceptionState) {
719 // 1. If localName does not match Name production, throw InvalidCharacterError
715 if (!isValidName(localName)) { 720 if (!isValidName(localName)) {
716 exceptionState.throwDOMException( 721 exceptionState.throwDOMException(
717 InvalidCharacterError, 722 InvalidCharacterError,
718 "The tag name provided ('" + localName + "') is not a valid name."); 723 "The tag name provided ('" + localName + "') is not a valid name.");
719 return nullptr; 724 return nullptr;
720 } 725 }
721 726
727 // 2. localName converted to ASCII lowercase
728 const AtomicString& convertedLocalName = convertLocalName(localName);
729
730 bool isV1 = stringOrOptions.isDictionary() || !registrationContext();
731 bool createV1Builtin = stringOrOptions.isDictionary() &&
732 RuntimeEnabledFeatures::customElementsBuiltinEnabled();
733 bool shouldCreateBuiltin = createV1Builtin || stringOrOptions.isString();
734
735 // 3.
736 const AtomicString& is =
737 AtomicString(getTypeExtension(this, stringOrOptions, exceptionState));
738 const AtomicString& name = shouldCreateBuiltin ? is : convertedLocalName;
739
740 // 4. Let definition be result of lookup up custom element definition
741 CustomElementDefinition* definition = nullptr;
742 if (isV1) {
743 // Is the runtime flag enabled for customized builtin elements?
744 const CustomElementDescriptor desc =
745 RuntimeEnabledFeatures::customElementsBuiltinEnabled()
746 ? CustomElementDescriptor(name, convertedLocalName)
747 : CustomElementDescriptor(convertedLocalName, convertedLocalName);
748 if (CustomElementRegistry* registry = CustomElement::registry(*this))
749 definition = registry->definitionFor(desc);
750
751 // 5. If 'is' is non-null and definition is null, throw NotFoundError
752 // TODO(yurak): update when https://github.com/w3c/webcomponents/issues/608
753 // is resolved
754 if (!definition && createV1Builtin) {
755 exceptionState.throwDOMException(NotFoundError,
756 "Custom element definition not found.");
757 return nullptr;
758 }
759 }
760
761 // 7. Let element be the result of creating an element
722 Element* element; 762 Element* element;
723 763
724 if (CustomElement::shouldCreateCustomElement(convertLocalName(localName))) { 764 if (definition) {
725 element = CustomElement::createCustomElementSync( 765 element =
726 *this, convertLocalName(localName)); 766 CustomElement::createCustomElementSync(*this, convertedLocalName, name);
727 } else if (V0CustomElement::isValidName(localName) && registrationContext()) { 767 } else if (V0CustomElement::isValidName(localName) && registrationContext()) {
728 element = registrationContext()->createCustomTagElement( 768 element = registrationContext()->createCustomTagElement(
729 *this, QualifiedName(nullAtom, convertLocalName(localName), 769 *this, QualifiedName(nullAtom, convertedLocalName, xhtmlNamespaceURI));
730 xhtmlNamespaceURI));
731 } else { 770 } else {
732 element = createElement(localName, exceptionState); 771 element = createElement(localName, exceptionState);
733 if (exceptionState.hadException()) 772 if (exceptionState.hadException())
734 return nullptr; 773 return nullptr;
735 } 774 }
736 775
737 String typeExtention = 776 // 8. If 'is' is non-null, set 'is' attribute
738 getTypeExtension(this, stringOrOptions, exceptionState); 777 if (!is.isEmpty()) {
739 if (!typeExtention.isEmpty()) { 778 if (stringOrOptions.isString()) {
740 V0CustomElementRegistrationContext::setIsAttributeAndTypeExtension( 779 V0CustomElementRegistrationContext::setIsAttributeAndTypeExtension(
741 element, AtomicString(typeExtention)); 780 element, is);
781 } else if (stringOrOptions.isDictionary()) {
782 element->setAttribute(HTMLNames::isAttr, is);
783 }
742 } 784 }
743 785
744 return element; 786 return element;
745 } 787 }
746 788
747 static inline QualifiedName createQualifiedName( 789 static inline QualifiedName createQualifiedName(
748 const AtomicString& namespaceURI, 790 const AtomicString& namespaceURI,
749 const AtomicString& qualifiedName, 791 const AtomicString& qualifiedName,
750 ExceptionState& exceptionState) { 792 ExceptionState& exceptionState) {
751 AtomicString prefix, localName; 793 AtomicString prefix, localName;
(...skipping 20 matching lines...) Expand all
772 QualifiedName qName( 814 QualifiedName qName(
773 createQualifiedName(namespaceURI, qualifiedName, exceptionState)); 815 createQualifiedName(namespaceURI, qualifiedName, exceptionState));
774 if (qName == QualifiedName::null()) 816 if (qName == QualifiedName::null())
775 return nullptr; 817 return nullptr;
776 818
777 if (CustomElement::shouldCreateCustomElement(qName)) 819 if (CustomElement::shouldCreateCustomElement(qName))
778 return CustomElement::createCustomElementSync(*this, qName); 820 return CustomElement::createCustomElementSync(*this, qName);
779 return createElement(qName, CreatedByCreateElement); 821 return createElement(qName, CreatedByCreateElement);
780 } 822 }
781 823
824 // https://dom.spec.whatwg.org/#internal-createelementns-steps
782 Element* Document::createElementNS(const AtomicString& namespaceURI, 825 Element* Document::createElementNS(const AtomicString& namespaceURI,
783 const AtomicString& qualifiedName, 826 const AtomicString& qualifiedName,
784 const StringOrDictionary& stringOrOptions, 827 const StringOrDictionary& stringOrOptions,
785 ExceptionState& exceptionState) { 828 ExceptionState& exceptionState) {
829 // 1. Validate and extract
786 QualifiedName qName( 830 QualifiedName qName(
787 createQualifiedName(namespaceURI, qualifiedName, exceptionState)); 831 createQualifiedName(namespaceURI, qualifiedName, exceptionState));
788 if (qName == QualifiedName::null()) 832 if (qName == QualifiedName::null())
789 return nullptr; 833 return nullptr;
790 834
835 bool isV1 = stringOrOptions.isDictionary() || !registrationContext();
836 bool createV1Builtin = stringOrOptions.isDictionary() &&
837 RuntimeEnabledFeatures::customElementsBuiltinEnabled();
838 bool shouldCreateBuiltin = createV1Builtin || stringOrOptions.isString();
839
840 // 2.
841 const AtomicString& is =
842 AtomicString(getTypeExtension(this, stringOrOptions, exceptionState));
843 const AtomicString& name = shouldCreateBuiltin ? is : qualifiedName;
844
845 if (!isValidName(qualifiedName)) {
846 exceptionState.throwDOMException(
847 InvalidCharacterError,
848 "The tag name provided ('" + qualifiedName + "') is not a valid name.");
849 return nullptr;
850 }
851
852 // 3. Let definition be result of lookup up custom element definition
853 CustomElementDefinition* definition = nullptr;
854 if (isV1) {
855 const CustomElementDescriptor desc =
856 RuntimeEnabledFeatures::customElementsBuiltinEnabled()
857 ? CustomElementDescriptor(name, qualifiedName)
858 : CustomElementDescriptor(qualifiedName, qualifiedName);
859 if (CustomElementRegistry* registry = CustomElement::registry(*this))
860 definition = registry->definitionFor(desc);
861
862 // 4. If 'is' is non-null and definition is null, throw NotFoundError
863 if (!definition && createV1Builtin) {
864 exceptionState.throwDOMException(NotFoundError,
865 "Custom element definition not found.");
866 return nullptr;
867 }
868 }
869
870 // 5. Let element be the result of creating an element
791 Element* element; 871 Element* element;
792 if (CustomElement::shouldCreateCustomElement(qName)) 872
793 element = CustomElement::createCustomElementSync(*this, qName); 873 if (CustomElement::shouldCreateCustomElement(qName) || createV1Builtin) {
794 else if (V0CustomElement::isValidName(qName.localName()) && 874 element = CustomElement::createCustomElementSync(*this, qName, is);
795 registrationContext()) 875 } else if (V0CustomElement::isValidName(qName.localName()) &&
876 registrationContext()) {
796 element = registrationContext()->createCustomTagElement(*this, qName); 877 element = registrationContext()->createCustomTagElement(*this, qName);
797 else 878 } else {
798 element = createElement(qName, CreatedByCreateElement); 879 element = createElement(qName, CreatedByCreateElement);
880 }
799 881
800 String typeExtention = 882 // 6. If 'is' is non-null, set 'is' attribute
801 getTypeExtension(this, stringOrOptions, exceptionState); 883 if (!is.isEmpty()) {
802 if (!typeExtention.isEmpty()) { 884 if (element->getCustomElementState() != CustomElementState::Custom) {
803 V0CustomElementRegistrationContext::setIsAttributeAndTypeExtension( 885 V0CustomElementRegistrationContext::setIsAttributeAndTypeExtension(
804 element, AtomicString(typeExtention)); 886 element, is);
887 } else if (stringOrOptions.isDictionary()) {
888 element->setAttribute(HTMLNames::isAttr, is);
889 }
805 } 890 }
806 891
807 return element; 892 return element;
808 } 893 }
809 894
810 ScriptValue Document::registerElement(ScriptState* scriptState, 895 ScriptValue Document::registerElement(ScriptState* scriptState,
811 const AtomicString& name, 896 const AtomicString& name,
812 const ElementRegistrationOptions& options, 897 const ElementRegistrationOptions& options,
813 ExceptionState& exceptionState, 898 ExceptionState& exceptionState,
814 V0CustomElement::NameSet validNames) { 899 V0CustomElement::NameSet validNames) {
(...skipping 5627 matching lines...) Expand 10 before | Expand all | Expand 10 after
6442 } 6527 }
6443 6528
6444 void showLiveDocumentInstances() { 6529 void showLiveDocumentInstances() {
6445 WeakDocumentSet& set = liveDocumentSet(); 6530 WeakDocumentSet& set = liveDocumentSet();
6446 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); 6531 fprintf(stderr, "There are %u documents currently alive:\n", set.size());
6447 for (Document* document : set) 6532 for (Document* document : set)
6448 fprintf(stderr, "- Document %p URL: %s\n", document, 6533 fprintf(stderr, "- Document %p URL: %s\n", document,
6449 document->url().getString().utf8().data()); 6534 document->url().getString().utf8().data());
6450 } 6535 }
6451 #endif 6536 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698