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 |