| 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::isHyphenatedSpecElementName(const AtomicString& name) |
| 49 { | 48 { |
| 50 if (!name.length() || name[0] < 'a' || name[0] > 'z') | 49 // Even if Blink does not implement one of the related specs, (for |
| 51 return false; | 50 // example annotation-xml is from MathML, which Blink does not |
| 52 | 51 // implement) we must prohibit using the name because that is |
| 53 bool hasHyphens = false; | 52 // required by the HTML spec which we *do* implement. Don't remove |
| 54 for (size_t i = 1; i < name.length(); ) { | 53 // names from this list without removing them from the HTML spec |
| 55 UChar32 ch; | 54 // first. |
| 56 if (name.is8Bit()) | 55 DEFINE_STATIC_LOCAL(HashSet<AtomicString>, hyphenatedSpecElementNames, ({ |
| 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 | |
| 69 DEFINE_STATIC_LOCAL(HashSet<AtomicString>, hyphenContainingElementNames, ({ | |
| 70 "annotation-xml", | 56 "annotation-xml", |
| 71 "color-profile", | 57 "color-profile", |
| 72 "font-face", | 58 "font-face", |
| 73 "font-face-src", | 59 "font-face-src", |
| 74 "font-face-uri", | 60 "font-face-uri", |
| 75 "font-face-format", | 61 "font-face-format", |
| 76 "font-face-name", | 62 "font-face-name", |
| 77 "missing-glyph", | 63 "missing-glyph", |
| 78 })); | 64 })); |
| 79 return !hyphenContainingElementNames.contains(name); | 65 return hyphenatedSpecElementNames.contains(name); |
| 80 } | 66 } |
| 81 | 67 |
| 82 bool CustomElement::shouldCreateCustomElement(const AtomicString& localName) | 68 bool CustomElement::shouldCreateCustomElement(const AtomicString& localName) |
| 83 { | 69 { |
| 84 return RuntimeEnabledFeatures::customElementsV1Enabled() | 70 return RuntimeEnabledFeatures::customElementsV1Enabled() |
| 85 && isValidName(localName); | 71 && isValidName(localName); |
| 86 } | 72 } |
| 87 | 73 |
| 88 bool CustomElement::shouldCreateCustomElement(const QualifiedName& tagName) | 74 bool CustomElement::shouldCreateCustomElement(const QualifiedName& tagName) |
| 89 { | 75 { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 100 | 86 |
| 101 HTMLElement* CustomElement::createCustomElementSync(Document& document, const At
omicString& localName, ExceptionState& exceptionState) | 87 HTMLElement* CustomElement::createCustomElementSync(Document& document, const At
omicString& localName, ExceptionState& exceptionState) |
| 102 { | 88 { |
| 103 return createCustomElementSync(document, | 89 return createCustomElementSync(document, |
| 104 QualifiedName(nullAtom, localName, HTMLNames::xhtmlNamespaceURI), | 90 QualifiedName(nullAtom, localName, HTMLNames::xhtmlNamespaceURI), |
| 105 exceptionState); | 91 exceptionState); |
| 106 } | 92 } |
| 107 | 93 |
| 108 HTMLElement* CustomElement::createCustomElementSync(Document& document, const Qu
alifiedName& tagName, ExceptionState& exceptionState) | 94 HTMLElement* CustomElement::createCustomElementSync(Document& document, const Qu
alifiedName& tagName, ExceptionState& exceptionState) |
| 109 { | 95 { |
| 110 CHECK(shouldCreateCustomElement(tagName)); | 96 DCHECK(shouldCreateCustomElement(tagName)); |
| 111 | 97 |
| 112 // To create an element: | 98 // To create an element: |
| 113 // https://dom.spec.whatwg.org/#concept-create-element | 99 // https://dom.spec.whatwg.org/#concept-create-element |
| 114 // 6. If definition is non-null, then: | 100 // 6. If definition is non-null, then: |
| 115 // 6.1. If the synchronous custom elements flag is set: | 101 // 6.1. If the synchronous custom elements flag is set: |
| 116 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) | 102 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) |
| 117 return definition->createElementSync(document, tagName, exceptionState); | 103 return definition->createElementSync(document, tagName, exceptionState); |
| 118 | 104 |
| 119 return createUndefinedElement(document, tagName); | 105 return createUndefinedElement(document, tagName); |
| 120 } | 106 } |
| 121 | 107 |
| 122 HTMLElement* CustomElement::createCustomElementSync(Document& document, const Qu
alifiedName& tagName) | 108 HTMLElement* CustomElement::createCustomElementSync(Document& document, const Qu
alifiedName& tagName) |
| 123 { | 109 { |
| 124 CHECK(shouldCreateCustomElement(tagName)); | 110 DCHECK(shouldCreateCustomElement(tagName)); |
| 125 | 111 |
| 126 // When invoked from "create an element for a token": | 112 // When invoked from "create an element for a token": |
| 127 // https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-
the-token | 113 // 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, | 114 // 7. If this step throws an exception, then report the exception, |
| 129 // and let element be instead a new element that implements | 115 // and let element be instead a new element that implements |
| 130 // HTMLUnknownElement. | 116 // HTMLUnknownElement. |
| 131 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) | 117 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) |
| 132 return definition->createElementSync(document, tagName); | 118 return definition->createElementSync(document, tagName); |
| 133 | 119 |
| 134 return createUndefinedElement(document, tagName); | 120 return createUndefinedElement(document, tagName); |
| 135 } | 121 } |
| 136 | 122 |
| 137 HTMLElement* CustomElement::createCustomElementAsync(Document& document, const Q
ualifiedName& tagName) | 123 HTMLElement* CustomElement::createCustomElementAsync(Document& document, const Q
ualifiedName& tagName) |
| 138 { | 124 { |
| 139 CHECK(shouldCreateCustomElement(tagName)); | 125 DCHECK(shouldCreateCustomElement(tagName)); |
| 140 | 126 |
| 141 // To create an element: | 127 // To create an element: |
| 142 // https://dom.spec.whatwg.org/#concept-create-element | 128 // https://dom.spec.whatwg.org/#concept-create-element |
| 143 // 6. If definition is non-null, then: | 129 // 6. If definition is non-null, then: |
| 144 // 6.2. If the synchronous custom elements flag is not set: | 130 // 6.2. If the synchronous custom elements flag is not set: |
| 145 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) | 131 if (CustomElementDefinition* definition = definitionForName(document, tagNam
e)) |
| 146 return definition->createElementAsync(document, tagName); | 132 return definition->createElementAsync(document, tagName); |
| 147 | 133 |
| 148 return createUndefinedElement(document, tagName); | 134 return createUndefinedElement(document, tagName); |
| 149 } | 135 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 CustomElementRegistry* registry = CustomElement::registry(*element); | 227 CustomElementRegistry* registry = CustomElement::registry(*element); |
| 242 if (!registry) | 228 if (!registry) |
| 243 return; | 229 return; |
| 244 if (CustomElementDefinition* definition = registry->definitionForName(elemen
t->localName())) | 230 if (CustomElementDefinition* definition = registry->definitionForName(elemen
t->localName())) |
| 245 definition->enqueueUpgradeReaction(element); | 231 definition->enqueueUpgradeReaction(element); |
| 246 else | 232 else |
| 247 registry->addCandidate(element); | 233 registry->addCandidate(element); |
| 248 } | 234 } |
| 249 | 235 |
| 250 } // namespace blink | 236 } // namespace blink |
| OLD | NEW |