 Chromium Code Reviews
 Chromium Code Reviews Issue 2024073002:
  Add callbacks to ScriptCustomElementDefinition  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 2024073002:
  Add callbacks to ScriptCustomElementDefinition  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| Index: third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp | 
| diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp | 
| index 879fac4ecdfd1b38f444b0883ebaad761c1bde21..443eea7211cec7db7e301fd032aba32fa827be26 100644 | 
| --- a/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp | 
| +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp | 
| @@ -4,6 +4,7 @@ | 
| #include "bindings/core/v8/ScriptCustomElementDefinition.h" | 
| +#include "bindings/core/v8/ScriptCustomElementDefinitionBuilder.h" | 
| #include "bindings/core/v8/ScriptState.h" | 
| #include "bindings/core/v8/V8Binding.h" | 
| #include "bindings/core/v8/V8CustomElementsRegistry.h" | 
| @@ -74,50 +75,69 @@ ScriptCustomElementDefinition* ScriptCustomElementDefinition::forConstructor( | 
| return static_cast<ScriptCustomElementDefinition*>(definition); | 
| } | 
| +static void keepAliveIfNotEmpty(v8::Local<v8::Array>& array, uint32_t index, | 
| + const v8::Local<v8::Object>& value, | 
| + ScopedPersistent<v8::Object>& persistent, | 
| + ScriptState* scriptState) | 
| +{ | 
| + if (value.IsEmpty()) | 
| + return; | 
| + | 
| + v8CallOrCrash(array->Set(scriptState->context(), index, value)); | 
| + | 
| + persistent.set(scriptState->isolate(), value); | 
| + persistent.setPhantom(); | 
| +} | 
| + | 
| ScriptCustomElementDefinition* ScriptCustomElementDefinition::create( | 
| - ScriptState* scriptState, | 
| - CustomElementsRegistry* registry, | 
| const CustomElementDescriptor& descriptor, | 
| - const v8::Local<v8::Object>& constructor, | 
| - const v8::Local<v8::Object>& prototype) | 
| + const ScriptCustomElementDefinitionBuilder& builder) | 
| { | 
| ScriptCustomElementDefinition* definition = | 
| - new ScriptCustomElementDefinition( | 
| - scriptState, | 
| - descriptor, | 
| - constructor, | 
| - prototype); | 
| + new ScriptCustomElementDefinition(descriptor, builder); | 
| // Add a constructor -> name mapping to the registry. | 
| + ScriptState* scriptState = builder.m_scriptState.get(); | 
| v8::Local<v8::Value> nameValue = | 
| v8String(scriptState->isolate(), descriptor.name()); | 
| v8::Local<v8::Map> map = | 
| - ensureCustomElementsRegistryMap(scriptState, registry); | 
| - v8CallOrCrash(map->Set(scriptState->context(), constructor, nameValue)); | 
| - // We add the prototype here to keep it alive; we make it a value | 
| - // not a key so authors cannot return another constructor as a | 
| - // prototype to overwrite a constructor in this map. We use the | 
| - // name because it is unique per-registry. | 
| - v8CallOrCrash(map->Set(scriptState->context(), nameValue, prototype)); | 
| + ensureCustomElementsRegistryMap(scriptState, builder.m_registry); | 
| + v8CallOrCrash(map->Set(scriptState->context(), builder.m_constructor, nameValue)); | 
| + | 
| + // We add the prototype and callbacks here to keep them alive. We use the | 
| + // name as the key because it is unique per-registry. | 
| + v8::Local<v8::Array> array = v8::Array::New(scriptState->isolate(), 4); | 
| 
yosin_UTC9
2016/06/02 01:33:37
I'll add "whenDefinedPromise" here, so JS side val
 | 
| + v8CallOrCrash(array->Set(scriptState->context(), 0, builder.m_prototype)); | 
| 
dominicc (has gone to gerrit)
2016/06/02 00:31:27
Why not use keepAliveIfNotEmpty for m_prototype to
 
kojii
2016/06/02 03:18:08
Done.
 | 
| +#define V(index, name) \ | 
| 
yosin_UTC9
2016/06/02 01:33:38
We should have FOR_EACH_XXX() and it should be use
 
kojii
2016/06/02 03:18:08
I know, but I don't like it, esp. when the list is
 
yosin_UTC9
2016/06/02 04:30:31
Since list is used for parameter of ctor, it might
 | 
| + keepAliveIfNotEmpty(array, index, builder.m_##name, definition->m_##name, scriptState) | 
| + V(1, connectedCallback); | 
| + V(2, disconnectedCallback); | 
| + V(3, attributeChangedCallback); | 
| +#undef V | 
| + v8CallOrCrash(map->Set(scriptState->context(), nameValue, array)); | 
| return definition; | 
| } | 
| ScriptCustomElementDefinition::ScriptCustomElementDefinition( | 
| - ScriptState* scriptState, | 
| const CustomElementDescriptor& descriptor, | 
| - const v8::Local<v8::Object>& constructor, | 
| - const v8::Local<v8::Object>& prototype) | 
| + const ScriptCustomElementDefinitionBuilder& builder) | 
| : CustomElementDefinition(descriptor) | 
| - , m_scriptState(scriptState) | 
| - , m_constructor(scriptState->isolate(), constructor) | 
| - , m_prototype(scriptState->isolate(), prototype) | 
| + , m_scriptState(builder.m_scriptState) | 
| + , m_constructor(builder.m_scriptState->isolate(), builder.m_constructor) | 
| 
dominicc (has gone to gerrit)
2016/06/02 00:31:27
I guess you could just use m_scriptState at this p
 
kojii
2016/06/02 03:18:08
This was reverted, see comments in ScriptCustomEle
 | 
| + , m_prototype(builder.m_scriptState->isolate(), builder.m_prototype) | 
| { | 
| // These objects are kept alive by references from the | 
| // CustomElementsRegistry wrapper set up by | 
| // ScriptCustomElementDefinition::create. | 
| m_constructor.setPhantom(); | 
| m_prototype.setPhantom(); | 
| + | 
| + if (builder.m_observedAttributes.isEmpty()) | 
| + return; | 
| + m_observedAttributes.reserveCapacityForSize(builder.m_observedAttributes.size()); | 
| + for (const auto& attribute : builder.m_observedAttributes) | 
| + m_observedAttributes.add(attribute); | 
| } | 
| v8::Local<v8::Object> ScriptCustomElementDefinition::constructor() const |