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 "bindings/core/v8/ScriptCustomElementDefinition.h" | 5 #include "bindings/core/v8/ScriptCustomElementDefinition.h" |
6 | 6 |
7 #include "bindings/core/v8/ScriptState.h" | 7 #include "bindings/core/v8/ScriptState.h" |
8 #include "bindings/core/v8/V8Binding.h" | 8 #include "bindings/core/v8/V8Binding.h" |
9 #include "bindings/core/v8/V8BindingMacros.h" | 9 #include "bindings/core/v8/V8BindingMacros.h" |
10 #include "bindings/core/v8/V8CustomElementRegistry.h" | 10 #include "bindings/core/v8/V8CustomElementRegistry.h" |
11 #include "bindings/core/v8/V8Element.h" | 11 #include "bindings/core/v8/V8Element.h" |
12 #include "bindings/core/v8/V8ErrorHandler.h" | 12 #include "bindings/core/v8/V8ErrorHandler.h" |
13 #include "bindings/core/v8/V8HiddenValue.h" | 13 #include "bindings/core/v8/V8HiddenValue.h" |
14 #include "bindings/core/v8/V8ScriptRunner.h" | 14 #include "bindings/core/v8/V8ScriptRunner.h" |
15 #include "bindings/core/v8/V8ThrowException.h" | 15 #include "bindings/core/v8/V8ThrowException.h" |
16 #include "core/dom/ExceptionCode.h" | 16 #include "core/dom/ExceptionCode.h" |
17 #include "core/dom/custom/CustomElement.h" | 17 #include "core/dom/custom/CustomElement.h" |
18 #include "core/events/ErrorEvent.h" | 18 #include "core/events/ErrorEvent.h" |
19 #include "core/html/HTMLElement.h" | 19 #include "core/html/HTMLElement.h" |
20 #include "v8.h" | 20 #include "v8.h" |
21 #include "wtf/Allocator.h" | 21 #include "wtf/Allocator.h" |
22 | 22 |
23 namespace blink { | 23 namespace blink { |
24 | 24 |
25 // Retrieves the custom elements constructor -> name map, creating it | 25 // Retrieves the custom elements constructor -> name map, creating it |
26 // if necessary. The same map is used to keep prototypes alive. | 26 // if necessary. |
27 static v8::Local<v8::Map> ensureCustomElementRegistryMap( | 27 static v8::Local<v8::Map> ensureCustomElementRegistryMap( |
28 ScriptState* scriptState, | 28 ScriptState* scriptState, |
29 CustomElementRegistry* registry) { | 29 CustomElementRegistry* registry) { |
30 CHECK(scriptState->world().isMainWorld()); | 30 CHECK(scriptState->world().isMainWorld()); |
31 v8::Local<v8::String> name = | 31 v8::Local<v8::String> name = |
32 V8HiddenValue::customElementsRegistryMap(scriptState->isolate()); | 32 V8HiddenValue::customElementsRegistryMap(scriptState->isolate()); |
33 v8::Local<v8::Object> wrapper = toV8(registry, scriptState).As<v8::Object>(); | 33 v8::Local<v8::Object> wrapper = toV8(registry, scriptState).As<v8::Object>(); |
34 v8::Local<v8::Value> map = | 34 v8::Local<v8::Value> map = |
35 V8HiddenValue::getHiddenValue(scriptState, wrapper, name); | 35 V8HiddenValue::getHiddenValue(scriptState, wrapper, name); |
36 if (map.IsEmpty()) { | 36 if (map.IsEmpty()) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 | 94 |
95 persistent.set(scriptState->isolate(), value); | 95 persistent.set(scriptState->isolate(), value); |
96 persistent.setPhantom(); | 96 persistent.setPhantom(); |
97 } | 97 } |
98 | 98 |
99 ScriptCustomElementDefinition* ScriptCustomElementDefinition::create( | 99 ScriptCustomElementDefinition* ScriptCustomElementDefinition::create( |
100 ScriptState* scriptState, | 100 ScriptState* scriptState, |
101 CustomElementRegistry* registry, | 101 CustomElementRegistry* registry, |
102 const CustomElementDescriptor& descriptor, | 102 const CustomElementDescriptor& descriptor, |
103 const v8::Local<v8::Object>& constructor, | 103 const v8::Local<v8::Object>& constructor, |
104 const v8::Local<v8::Object>& prototype, | |
105 const v8::Local<v8::Function>& connectedCallback, | 104 const v8::Local<v8::Function>& connectedCallback, |
106 const v8::Local<v8::Function>& disconnectedCallback, | 105 const v8::Local<v8::Function>& disconnectedCallback, |
107 const v8::Local<v8::Function>& adoptedCallback, | 106 const v8::Local<v8::Function>& adoptedCallback, |
108 const v8::Local<v8::Function>& attributeChangedCallback, | 107 const v8::Local<v8::Function>& attributeChangedCallback, |
109 const HashSet<AtomicString>& observedAttributes) { | 108 const HashSet<AtomicString>& observedAttributes) { |
110 ScriptCustomElementDefinition* definition = new ScriptCustomElementDefinition( | 109 ScriptCustomElementDefinition* definition = new ScriptCustomElementDefinition( |
111 scriptState, descriptor, constructor, prototype, connectedCallback, | 110 scriptState, descriptor, constructor, connectedCallback, |
112 disconnectedCallback, adoptedCallback, attributeChangedCallback, | 111 disconnectedCallback, adoptedCallback, attributeChangedCallback, |
113 observedAttributes); | 112 observedAttributes); |
114 | 113 |
115 // Add a constructor -> name mapping to the registry. | 114 // Add a constructor -> name mapping to the registry. |
116 v8::Local<v8::Value> nameValue = | 115 v8::Local<v8::Value> nameValue = |
117 v8String(scriptState->isolate(), descriptor.name()); | 116 v8String(scriptState->isolate(), descriptor.name()); |
118 v8::Local<v8::Map> map = | 117 v8::Local<v8::Map> map = |
119 ensureCustomElementRegistryMap(scriptState, registry); | 118 ensureCustomElementRegistryMap(scriptState, registry); |
120 map->Set(scriptState->context(), constructor, nameValue).ToLocalChecked(); | 119 map->Set(scriptState->context(), constructor, nameValue).ToLocalChecked(); |
121 definition->m_constructor.setPhantom(); | 120 definition->m_constructor.setPhantom(); |
122 | 121 |
123 // We add the prototype and callbacks here to keep them alive. We use the | 122 // We add the callbacks here to keep them alive. We use the name as |
124 // name as the key because it is unique per-registry. | 123 // the key because it is unique per-registry. |
125 v8::Local<v8::Array> array = v8::Array::New(scriptState->isolate(), 5); | 124 v8::Local<v8::Array> array = v8::Array::New(scriptState->isolate(), 5); |
126 keepAlive(array, 0, prototype, definition->m_prototype, scriptState); | 125 keepAlive(array, 0, connectedCallback, definition->m_connectedCallback, |
127 keepAlive(array, 1, connectedCallback, definition->m_connectedCallback, | |
128 scriptState); | 126 scriptState); |
129 keepAlive(array, 2, disconnectedCallback, definition->m_disconnectedCallback, | 127 keepAlive(array, 1, disconnectedCallback, definition->m_disconnectedCallback, |
130 scriptState); | 128 scriptState); |
131 keepAlive(array, 3, adoptedCallback, definition->m_adoptedCallback, | 129 keepAlive(array, 2, adoptedCallback, definition->m_adoptedCallback, |
132 scriptState); | 130 scriptState); |
133 keepAlive(array, 4, attributeChangedCallback, | 131 keepAlive(array, 3, attributeChangedCallback, |
134 definition->m_attributeChangedCallback, scriptState); | 132 definition->m_attributeChangedCallback, scriptState); |
135 map->Set(scriptState->context(), nameValue, array).ToLocalChecked(); | 133 map->Set(scriptState->context(), nameValue, array).ToLocalChecked(); |
136 | 134 |
137 return definition; | 135 return definition; |
138 } | 136 } |
139 | 137 |
140 ScriptCustomElementDefinition::ScriptCustomElementDefinition( | 138 ScriptCustomElementDefinition::ScriptCustomElementDefinition( |
141 ScriptState* scriptState, | 139 ScriptState* scriptState, |
142 const CustomElementDescriptor& descriptor, | 140 const CustomElementDescriptor& descriptor, |
143 const v8::Local<v8::Object>& constructor, | 141 const v8::Local<v8::Object>& constructor, |
144 const v8::Local<v8::Object>& prototype, | |
145 const v8::Local<v8::Function>& connectedCallback, | 142 const v8::Local<v8::Function>& connectedCallback, |
146 const v8::Local<v8::Function>& disconnectedCallback, | 143 const v8::Local<v8::Function>& disconnectedCallback, |
147 const v8::Local<v8::Function>& adoptedCallback, | 144 const v8::Local<v8::Function>& adoptedCallback, |
148 const v8::Local<v8::Function>& attributeChangedCallback, | 145 const v8::Local<v8::Function>& attributeChangedCallback, |
149 const HashSet<AtomicString>& observedAttributes) | 146 const HashSet<AtomicString>& observedAttributes) |
150 : CustomElementDefinition(descriptor, observedAttributes), | 147 : CustomElementDefinition(descriptor, observedAttributes), |
151 m_scriptState(scriptState), | 148 m_scriptState(scriptState), |
152 m_constructor(scriptState->isolate(), constructor) {} | 149 m_constructor(scriptState->isolate(), constructor) {} |
153 | 150 |
154 static void dispatchErrorEvent(v8::Isolate* isolate, | 151 static void dispatchErrorEvent(v8::Isolate* isolate, |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 return nullptr; | 256 return nullptr; |
260 } | 257 } |
261 return V8Element::toImplWithTypeCheck(isolate, result); | 258 return V8Element::toImplWithTypeCheck(isolate, result); |
262 } | 259 } |
263 | 260 |
264 v8::Local<v8::Object> ScriptCustomElementDefinition::constructor() const { | 261 v8::Local<v8::Object> ScriptCustomElementDefinition::constructor() const { |
265 DCHECK(!m_constructor.isEmpty()); | 262 DCHECK(!m_constructor.isEmpty()); |
266 return m_constructor.newLocal(m_scriptState->isolate()); | 263 return m_constructor.newLocal(m_scriptState->isolate()); |
267 } | 264 } |
268 | 265 |
269 v8::Local<v8::Object> ScriptCustomElementDefinition::prototype() const { | |
270 DCHECK(!m_prototype.isEmpty()); | |
271 return m_prototype.newLocal(m_scriptState->isolate()); | |
272 } | |
273 | |
274 // CustomElementDefinition | 266 // CustomElementDefinition |
275 ScriptValue ScriptCustomElementDefinition::getConstructorForScript() { | 267 ScriptValue ScriptCustomElementDefinition::getConstructorForScript() { |
276 return ScriptValue(m_scriptState.get(), constructor()); | 268 return ScriptValue(m_scriptState.get(), constructor()); |
277 } | 269 } |
278 | 270 |
279 bool ScriptCustomElementDefinition::hasConnectedCallback() const { | 271 bool ScriptCustomElementDefinition::hasConnectedCallback() const { |
280 return !m_connectedCallback.isEmpty(); | 272 return !m_connectedCallback.isEmpty(); |
281 } | 273 } |
282 | 274 |
283 bool ScriptCustomElementDefinition::hasDisconnectedCallback() const { | 275 bool ScriptCustomElementDefinition::hasDisconnectedCallback() const { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 v8::Local<v8::Value> argv[] = { | 343 v8::Local<v8::Value> argv[] = { |
352 v8String(isolate, name.localName()), v8StringOrNull(isolate, oldValue), | 344 v8String(isolate, name.localName()), v8StringOrNull(isolate, oldValue), |
353 v8StringOrNull(isolate, newValue), | 345 v8StringOrNull(isolate, newValue), |
354 v8StringOrNull(isolate, name.namespaceURI()), | 346 v8StringOrNull(isolate, name.namespaceURI()), |
355 }; | 347 }; |
356 runCallback(m_attributeChangedCallback.newLocal(isolate), element, | 348 runCallback(m_attributeChangedCallback.newLocal(isolate), element, |
357 WTF_ARRAY_LENGTH(argv), argv); | 349 WTF_ARRAY_LENGTH(argv), argv); |
358 } | 350 } |
359 | 351 |
360 } // namespace blink | 352 } // namespace blink |
OLD | NEW |