Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(233)

Unified Diff: third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp

Issue 2003033004: Split custom element script use and move it into bindings (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add missing CORE_EXPORT header. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
new file mode 100644
index 0000000000000000000000000000000000000000..5e94cd255f4dccb177ff9251148379cb98a3679d
--- /dev/null
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp
@@ -0,0 +1,145 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "bindings/core/v8/ScriptCustomElementDefinition.h"
+
+#include "bindings/core/v8/ScriptState.h"
+#include "bindings/core/v8/V8CustomElementsRegistry.h"
+#include "bindings/core/v8/V8HiddenValue.h"
+#include "bindings/core/v8/V8PerContextData.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "v8.h"
+#include "wtf/Allocator.h"
+#include "wtf/Noncopyable.h"
+
+namespace blink {
+
+// Custom elements stores state off the registry's wrapper. To avoid leaking
+// contexts, that state should be manipulated in the registry's wrapper
+// context. This helper retrieves the wrapper and enters its context.
+class RegistryScriptStateScope {
+ STACK_ALLOCATED();
+ WTF_MAKE_NONCOPYABLE(RegistryScriptStateScope);
+public:
+ RegistryScriptStateScope(
+ ScriptState* current,
+ CustomElementsRegistry* registry)
+ : m_registry(toV8(registry, current).As<v8::Object>())
+ , m_scriptState(ScriptState::from(m_registry->CreationContext()))
Yuki 2016/05/26 07:48:40 What script state are you expecting here? It's th
dominicc (has gone to gerrit) 2016/05/27 04:54:17 OK, added some examples.
+ , m_scope(m_scriptState)
+ {
+ CHECK(current->world().isMainWorld());
+ }
+
+ ScriptState* scriptState() const { return m_scriptState; }
+ ScriptState* operator->() const { return m_scriptState; }
+ const v8::Local<v8::Object>& wrapper() const { return m_registry; }
+
+private:
+ v8::Local<v8::Object> m_registry;
+ ScriptState* m_scriptState;
+ ScriptState::Scope m_scope;
+};
+
+// Retrieves the custom elements constructor -> ID map, creating it if
+// necessary. The same map is used to keep prototypes alive.
+static v8::Local<v8::Map> ensureCustomElementsRegistryMap(
+ RegistryScriptStateScope& scope)
+{
+ v8::Local<v8::String> name = V8HiddenValue::customElementsRegistryMap(
+ scope->isolate());
+ v8::Local<v8::Value> map = V8HiddenValue::getHiddenValue(
+ scope.scriptState(),
+ scope.wrapper(),
+ name);
+ if (map.IsEmpty()) {
+ map = v8::Map::New(scope->isolate());
+ V8HiddenValue::setHiddenValue(
+ scope.scriptState(),
+ scope.wrapper(),
+ name,
+ map);
+ }
+ return map.As<v8::Map>();
+}
+
+ScriptCustomElementDefinition* ScriptCustomElementDefinition::forConstructor(
+ ScriptState* scriptState,
+ CustomElementsRegistry* registry,
+ const v8::Local<v8::Value>& constructor)
+{
+ if (!scriptState->contextIsValid())
+ return nullptr;
+ RegistryScriptStateScope scope(scriptState, registry);
haraken 2016/05/26 08:33:46 Why do you need to enter ScriptState's scope here?
dominicc (has gone to gerrit) 2016/05/27 04:54:17 When the HTMLElement constructor uses forConstruct
+ v8::Local<v8::Map> map = ensureCustomElementsRegistryMap(scope);
+ v8::Local<v8::Value> entry = v8CallOrCrash(
+ map->Get(scope->context(), constructor));
+ if (!entry->IsUint32())
+ return nullptr;
+ uint32_t id = v8CallOrCrash(entry->Uint32Value(scope->context()));
+ if (V8PerContextData* perContextData = scope->perContextData())
+ return perContextData->customElements()->getDefinition(id);
+ return nullptr;
+}
+
+ScriptCustomElementDefinition* ScriptCustomElementDefinition::create(
+ ScriptState* scriptState,
+ CustomElementsRegistry* registry,
+ const CustomElementDescriptor& descriptor,
+ const v8::Local<v8::Object>& constructor,
+ const v8::Local<v8::Object>& prototype)
+{
+ ScriptCustomElementDefinition* def = new ScriptCustomElementDefinition(
+ scriptState,
+ descriptor,
+ constructor,
+ prototype);
+
+ RegistryScriptStateScope scope(scriptState, registry);
+ V8PerContextData* perContextData = scope->perContextData();
+ if (!perContextData)
+ return nullptr;
+ uint32_t id = perContextData->customElements()->addDefinition(def);
+
+ // Add a constructor -> ID mapping to the registry.
+ v8::Local<v8::Value> idValue =
+ v8::Integer::NewFromUnsigned(scope->isolate(), id);
+ v8::Local<v8::Map> map = ensureCustomElementsRegistryMap(scope);
+ v8CallOrCrash(map->Set(scope->context(), constructor, idValue));
+ v8CallOrCrash(map->Set(scope->context(), idValue, prototype));
+
+ return def;
+}
+
+ScriptCustomElementDefinition::ScriptCustomElementDefinition(
+ ScriptState* scriptState,
+ const CustomElementDescriptor& descriptor,
+ const v8::Local<v8::Object>& constructor,
+ const v8::Local<v8::Object>& prototype)
+ : CustomElementDefinition(descriptor)
+ , m_constructor(scriptState->isolate(), constructor)
+ , m_prototype(scriptState->isolate(), prototype)
+{
+ // These objects are kept alive by references from the
+ // CustomElementsRegistry wrapper set up by
+ // ScriptCustomElementDefinition::create.
+ m_constructor.setPhantom();
+ m_prototype.setPhantom();
+}
+
+v8::Local<v8::Object> ScriptCustomElementDefinition::constructor(
+ ScriptState* scriptState) const
+{
+ DCHECK(!m_constructor.isEmpty());
+ return m_constructor.newLocal(scriptState->isolate());
+}
+
+v8::Local<v8::Object> ScriptCustomElementDefinition::prototype(
+ ScriptState* scriptState) const
+{
+ DCHECK(!m_prototype.isEmpty());
+ return m_prototype.newLocal(scriptState->isolate());
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698