| 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 |