| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/dom/custom/CustomElement.h" | 5 #include "core/dom/custom/CustomElement.h" |
| 6 | 6 |
| 7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
| 8 #include "core/dom/QualifiedName.h" | 8 #include "core/dom/QualifiedName.h" |
| 9 #include "core/dom/custom/CEReactionsScope.h" | 9 #include "core/dom/custom/CEReactionsScope.h" |
| 10 #include "core/dom/custom/CustomElementDefinition.h" | 10 #include "core/dom/custom/CustomElementDefinition.h" |
| 11 #include "core/dom/custom/CustomElementReactionStack.h" | 11 #include "core/dom/custom/CustomElementReactionStack.h" |
| 12 #include "core/dom/custom/CustomElementRegistry.h" | 12 #include "core/dom/custom/CustomElementRegistry.h" |
| 13 #include "core/dom/custom/V0CustomElement.h" | 13 #include "core/dom/custom/V0CustomElement.h" |
| 14 #include "core/dom/custom/V0CustomElementRegistrationContext.h" | 14 #include "core/dom/custom/V0CustomElementRegistrationContext.h" |
| 15 #include "core/frame/LocalDOMWindow.h" | 15 #include "core/frame/LocalDOMWindow.h" |
| 16 #include "core/html/HTMLElement.h" | 16 #include "core/html/HTMLElement.h" |
| 17 #include "core/html/HTMLUnknownElement.h" | 17 #include "core/html/HTMLUnknownElement.h" |
| 18 #include "platform/text/Character.h" | |
| 19 #include "wtf/text/AtomicStringHash.h" | 18 #include "wtf/text/AtomicStringHash.h" |
| 20 | 19 |
| 21 namespace blink { | 20 namespace blink { |
| 22 | 21 |
| 23 CustomElementRegistry* CustomElement::registry(const Element& element) | 22 CustomElementRegistry* CustomElement::registry(const Element& element) |
| 24 { | 23 { |
| 25 return registry(element.document()); | 24 return registry(element.document()); |
| 26 } | 25 } |
| 27 | 26 |
| 28 CustomElementRegistry* CustomElement::registry(const Document& document) | 27 CustomElementRegistry* CustomElement::registry(const Document& document) |
| 29 { | 28 { |
| 30 if (LocalDOMWindow* window = document.executingWindow()) | 29 if (LocalDOMWindow* window = document.executingWindow()) |
| 31 return window->customElements(); | 30 return window->customElements(); |
| 32 return nullptr; | 31 return nullptr; |
| 33 } | 32 } |
| 34 | 33 |
| 35 static CustomElementDefinition* definitionForElementWithoutCheck(const Element&
element) | 34 static CustomElementDefinition* definitionForElementWithoutCheck(const Element&
element) |
| 36 { | 35 { |
| 37 DCHECK_EQ(element.getCustomElementState(), CustomElementState::Custom); | 36 DCHECK_EQ(element.getCustomElementState(), CustomElementState::Custom); |
| 38 return element.customElementDefinition(); | 37 return element.customElementDefinition(); |
| 39 } | 38 } |
| 40 | 39 |
| 41 CustomElementDefinition* CustomElement::definitionForElement(const Element* elem
ent) | 40 CustomElementDefinition* CustomElement::definitionForElement(const Element* elem
ent) |
| 42 { | 41 { |
| 43 if (!element || element->getCustomElementState() != CustomElementState::Cust
om) | 42 if (!element || element->getCustomElementState() != CustomElementState::Cust
om) |
| 44 return nullptr; | 43 return nullptr; |
| 45 return definitionForElementWithoutCheck(*element); | 44 return definitionForElementWithoutCheck(*element); |
| 46 } | 45 } |
| 47 | 46 |
| 48 bool CustomElement::isValidName(const AtomicString& name) | 47 bool CustomElement::isHyphenContainingElementName(const AtomicString& name) |
| 49 { | 48 { |
| 50 if (!name.length() || name[0] < 'a' || name[0] > 'z') | |
| 51 return false; | |
| 52 | |
| 53 bool hasHyphens = false; | |
| 54 for (size_t i = 1; i < name.length(); ) { | |
| 55 UChar32 ch; | |
| 56 if (name.is8Bit()) | |
| 57 ch = name[i++]; | |
| 58 else | |
| 59 U16_NEXT(name.characters16(), i, name.length(), ch); | |
| 60 if (ch == '-') | |
| 61 hasHyphens = true; | |
| 62 else if (!Character::isPotentialCustomElementNameChar(ch)) | |
| 63 return false; | |
| 64 } | |
| 65 if (!hasHyphens) | |
| 66 return false; | |
| 67 | |
| 68 // https://html.spec.whatwg.org/multipage/scripting.html#valid-custom-elemen
t-name | 49 // https://html.spec.whatwg.org/multipage/scripting.html#valid-custom-elemen
t-name |
| 69 DEFINE_STATIC_LOCAL(HashSet<AtomicString>, hyphenContainingElementNames, ({ | 50 DEFINE_STATIC_LOCAL(HashSet<AtomicString>, hyphenContainingElementNames, ({ |
| 70 "annotation-xml", | 51 "annotation-xml", |
| 71 "color-profile", | 52 "color-profile", |
| 72 "font-face", | 53 "font-face", |
| 73 "font-face-src", | 54 "font-face-src", |
| 74 "font-face-uri", | 55 "font-face-uri", |
| 75 "font-face-format", | 56 "font-face-format", |
| 76 "font-face-name", | 57 "font-face-name", |
| 77 "missing-glyph", | 58 "missing-glyph", |
| 78 })); | 59 })); |
| 79 return !hyphenContainingElementNames.contains(name); | 60 return hyphenContainingElementNames.contains(name); |
| 80 } | |
| 81 | |
| 82 bool CustomElement::shouldCreateCustomElement(const AtomicString& localName) | |
| 83 { | |
| 84 return RuntimeEnabledFeatures::customElementsV1Enabled() | |
| 85 && isValidName(localName); | |
| 86 } | 61 } |
| 87 | 62 |
| 88 bool CustomElement::shouldCreateCustomElement(const QualifiedName& tagName) | 63 bool CustomElement::shouldCreateCustomElement(const QualifiedName& tagName) |
| 89 { | 64 { |
| 90 return shouldCreateCustomElement(tagName.localName()) | 65 return shouldCreateCustomElement(tagName.localName()) |
| 91 && tagName.namespaceURI() == HTMLNames::xhtmlNamespaceURI; | 66 && tagName.namespaceURI() == HTMLNames::xhtmlNamespaceURI; |
| 92 } | 67 } |
| 93 | 68 |
| 94 static CustomElementDefinition* definitionForName(const Document& document, cons
t QualifiedName& name) | 69 static CustomElementDefinition* definitionForName(const Document& document, cons
t QualifiedName& name) |
| 95 { | 70 { |
| 96 if (CustomElementRegistry* registry = CustomElement::registry(document)) | 71 if (CustomElementRegistry* registry = CustomElement::registry(document)) |
| 97 return registry->definitionForName(name.localName()); | 72 return registry->definitionForName(name.localName()); |
| 98 return nullptr; | 73 return nullptr; |
| 99 } | 74 } |
| 100 | 75 |
| 101 HTMLElement* CustomElement::createCustomElementSync(Document& document, const At
omicString& localName, ExceptionState& exceptionState) | 76 HTMLElement* CustomElement::createCustomElementSync(Document& document, const At
omicString& localName, ExceptionState* exceptionState) |
| 102 { | 77 { |
| 103 return createCustomElementSync(document, | 78 return createCustomElementSync(document, |
| 104 QualifiedName(nullAtom, localName, HTMLNames::xhtmlNamespaceURI), | 79 QualifiedName(nullAtom, localName, HTMLNames::xhtmlNamespaceURI), |
| 105 exceptionState); | 80 exceptionState); |
| 106 } | 81 } |
| 107 | 82 |
| 108 HTMLElement* CustomElement::createCustomElementSync(Document& document, const Qu
alifiedName& tagName, ExceptionState& exceptionState) | 83 HTMLElement* CustomElement::createCustomElementSync(Document& document, const Qu
alifiedName& tagName, ExceptionState* exceptionState) |
| 109 { | 84 { |
| 110 CHECK(shouldCreateCustomElement(tagName)); | 85 DCHECK(shouldCreateCustomElement(tagName)); |
| 111 | 86 |
| 112 // To create an element: | 87 // To create an element: |
| 113 // https://dom.spec.whatwg.org/#concept-create-element | 88 // https://dom.spec.whatwg.org/#concept-create-element |
| 114 // 6. If definition is non-null, then: | 89 // 6. If definition is non-null, then: |
| 115 // 6.1. If the synchronous custom elements flag is set: | 90 // 6.1. If the synchronous custom elements flag is set: |
| 91 |
| 92 // When invoked from "create an element for a token": |
| 93 // https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-
the-token |
| 94 // 7. If this step throws an exception, then report the exception, |
| 95 // and let element be instead a new element that implements |
| 96 // HTMLUnknownElement. |
| 97 |
| 116 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) | 98 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) |
| 117 return definition->createElementSync(document, tagName, exceptionState); | 99 return definition->createElementSync(document, tagName, exceptionState); |
| 118 | 100 |
| 119 return createUndefinedElement(document, tagName); | 101 return createUndefinedElement(document, tagName); |
| 120 } | 102 } |
| 121 | 103 |
| 122 HTMLElement* CustomElement::createCustomElementSync(Document& document, const Qu
alifiedName& tagName) | |
| 123 { | |
| 124 CHECK(shouldCreateCustomElement(tagName)); | |
| 125 | |
| 126 // When invoked from "create an element for a token": | |
| 127 // https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-
the-token | |
| 128 // 7. If this step throws an exception, then report the exception, | |
| 129 // and let element be instead a new element that implements | |
| 130 // HTMLUnknownElement. | |
| 131 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) | |
| 132 return definition->createElementSync(document, tagName); | |
| 133 | |
| 134 return createUndefinedElement(document, tagName); | |
| 135 } | |
| 136 | |
| 137 HTMLElement* CustomElement::createCustomElementAsync(Document& document, const Q
ualifiedName& tagName) | 104 HTMLElement* CustomElement::createCustomElementAsync(Document& document, const Q
ualifiedName& tagName) |
| 138 { | 105 { |
| 139 CHECK(shouldCreateCustomElement(tagName)); | 106 DCHECK(shouldCreateCustomElement(tagName)); |
| 140 | 107 |
| 141 // To create an element: | 108 // To create an element: |
| 142 // https://dom.spec.whatwg.org/#concept-create-element | 109 // https://dom.spec.whatwg.org/#concept-create-element |
| 143 // 6. If definition is non-null, then: | 110 // 6. If definition is non-null, then: |
| 144 // 6.2. If the synchronous custom elements flag is not set: | 111 // 6.2. If the synchronous custom elements flag is not set: |
| 145 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) | 112 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) |
| 146 return definition->createElementAsync(document, tagName); | 113 return definition->createElementAsync(document, tagName); |
| 147 | 114 |
| 148 return createUndefinedElement(document, tagName); | 115 return createUndefinedElement(document, tagName); |
| 149 } | 116 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 CustomElementRegistry* registry = CustomElement::registry(*element); | 208 CustomElementRegistry* registry = CustomElement::registry(*element); |
| 242 if (!registry) | 209 if (!registry) |
| 243 return; | 210 return; |
| 244 if (CustomElementDefinition* definition = registry->definitionForName(elemen
t->localName())) | 211 if (CustomElementDefinition* definition = registry->definitionForName(elemen
t->localName())) |
| 245 definition->enqueueUpgradeReaction(element); | 212 definition->enqueueUpgradeReaction(element); |
| 246 else | 213 else |
| 247 registry->addCandidate(element); | 214 registry->addCandidate(element); |
| 248 } | 215 } |
| 249 | 216 |
| 250 } // namespace blink | 217 } // namespace blink |
| OLD | NEW |