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/CustomElementDefinition.h" | 5 #include "core/dom/custom/CustomElementDefinition.h" |
6 | 6 |
| 7 #include "core/dom/ExceptionCode.h" |
| 8 #include "core/dom/custom/CustomElement.h" |
| 9 #include "core/html/HTMLElement.h" |
| 10 |
7 namespace blink { | 11 namespace blink { |
8 | 12 |
9 CustomElementDefinition::CustomElementDefinition( | 13 CustomElementDefinition::CustomElementDefinition( |
10 const CustomElementDescriptor& descriptor) | 14 const CustomElementDescriptor& descriptor) |
11 : m_descriptor(descriptor) | 15 : m_descriptor(descriptor) |
12 { | 16 { |
13 } | 17 } |
14 | 18 |
15 CustomElementDefinition::~CustomElementDefinition() | 19 CustomElementDefinition::~CustomElementDefinition() |
16 { | 20 { |
17 } | 21 } |
18 | 22 |
19 DEFINE_TRACE(CustomElementDefinition) | 23 DEFINE_TRACE(CustomElementDefinition) |
20 { | 24 { |
21 visitor->trace(m_constructionStack); | 25 visitor->trace(m_constructionStack); |
22 } | 26 } |
23 | 27 |
| 28 HTMLElement* CustomElementDefinition::createElementAsync(Document& document, con
st QualifiedName& tagName) |
| 29 { |
| 30 // https://dom.spec.whatwg.org/#concept-create-element |
| 31 // 6. If definition is non-null, then: |
| 32 // 6.2. If the synchronous custom elements flag is not set: |
| 33 // 6.2.1. Set result to a new element that implements the HTMLElement |
| 34 // interface, with no attributes, namespace set to the HTML namespace, |
| 35 // namespace prefix set to prefix, local name set to localName, custom |
| 36 // element state set to "undefined", and node document set to document. |
| 37 HTMLElement* element = HTMLElement::create(tagName, document); |
| 38 element->setCustomElementState(CustomElementState::Undefined); |
| 39 // 6.2.2. Enqueue a custom element upgrade reaction given result and |
| 40 // definition. |
| 41 CustomElement::enqueueUpgradeReaction(element, this); |
| 42 return element; |
| 43 } |
| 44 |
24 // https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-elem
ent | 45 // https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-elem
ent |
25 void CustomElementDefinition::upgrade(Element* element) | 46 void CustomElementDefinition::upgrade(Element* element) |
26 { | 47 { |
27 // TODO(dominicc): When the attributeChangedCallback is implemented, | 48 // TODO(dominicc): When the attributeChangedCallback is implemented, |
28 // enqueue reactions for attributes here. | 49 // enqueue reactions for attributes here. |
29 // TODO(dominicc): When the connectedCallback is implemented, enqueue | 50 // TODO(dominicc): When the connectedCallback is implemented, enqueue |
30 // reactions here, if applicable. | 51 // reactions here, if applicable. |
31 | 52 |
32 m_constructionStack.append(element); | 53 m_constructionStack.append(element); |
33 size_t depth = m_constructionStack.size(); | 54 size_t depth = m_constructionStack.size(); |
34 | 55 |
35 bool succeeded = runConstructor(element); | 56 bool succeeded = runConstructor(element); |
36 | 57 |
37 // Pop the construction stack. | 58 // Pop the construction stack. |
38 if (m_constructionStack.last().get()) | 59 if (m_constructionStack.last().get()) |
39 DCHECK_EQ(m_constructionStack.last(), element); | 60 DCHECK_EQ(m_constructionStack.last(), element); |
40 DCHECK_EQ(m_constructionStack.size(), depth); // It's a *stack*. | 61 DCHECK_EQ(m_constructionStack.size(), depth); // It's a *stack*. |
41 m_constructionStack.removeLast(); | 62 m_constructionStack.removeLast(); |
42 | 63 |
43 if (!succeeded) | 64 if (!succeeded) |
44 return; | 65 return; |
45 | 66 |
46 CHECK(element->getCustomElementState() == CustomElementState::Custom); | 67 CHECK(element->getCustomElementState() == CustomElementState::Custom); |
47 } | 68 } |
48 | 69 |
| 70 static String errorMessageForConstructorResult(Element* element, |
| 71 Document& document, const QualifiedName& tagName) |
| 72 { |
| 73 // https://dom.spec.whatwg.org/#concept-create-element |
| 74 // 6.1.4. If result's attribute list is not empty, then throw a NotSupported
Error. |
| 75 if (element->hasAttributes()) |
| 76 return "The result must not have attributes"; |
| 77 // 6.1.5. If result has children, then throw a NotSupportedError. |
| 78 if (element->hasChildren()) |
| 79 return "The result must not have children"; |
| 80 // 6.1.6. If result's parent is not null, then throw a NotSupportedError. |
| 81 if (element->parentNode()) |
| 82 return "The result must not have a parent"; |
| 83 // 6.1.7. If result's node document is not document, then throw a NotSupport
edError. |
| 84 if (&element->document() != &document) |
| 85 return "The result must be in the same document"; |
| 86 // 6.1.8. If result's namespace is not the HTML namespace, then throw a NotS
upportedError. |
| 87 if (element->namespaceURI() != HTMLNames::xhtmlNamespaceURI) |
| 88 return "The result must have HTML namespace"; |
| 89 // 6.1.9. If result's local name is not equal to localName, then throw a Not
SupportedError. |
| 90 if (element->localName() != tagName.localName()) |
| 91 return "The result must have the same localName"; |
| 92 return String(); |
| 93 } |
| 94 |
| 95 void CustomElementDefinition::checkConstructorResult(Element* element, |
| 96 Document& document, const QualifiedName& tagName, |
| 97 ExceptionState& exceptionState) |
| 98 { |
| 99 // https://dom.spec.whatwg.org/#concept-create-element |
| 100 // 6.1.3. If result does not implement the HTMLElement interface, throw a Ty
peError. |
| 101 // See https://github.com/whatwg/html/issues/1402 for more clarifications. |
| 102 if (!element || !element->isHTMLElement()) { |
| 103 exceptionState.throwTypeError("The result must implement HTMLElement int
erface"); |
| 104 return; |
| 105 } |
| 106 |
| 107 // 6.1.4. through 6.1.9. |
| 108 const String message = errorMessageForConstructorResult(element, document, t
agName); |
| 109 if (!message.isEmpty()) |
| 110 exceptionState.throwDOMException(NotSupportedError, message); |
| 111 } |
| 112 |
49 } // namespace blink | 113 } // namespace blink |
OLD | NEW |