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

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

Issue 1858613002: bindings: Makes the window object be the inner global object. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Synced. Created 4 years, 8 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/WindowProxy.cpp
diff --git a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp
index 66ce71ac973e8a8ef739a4aaba78ef4e96481258..2d89e2bafdb11b9981f1af7ffc2d11f969f12d8e 100644
--- a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp
@@ -245,7 +245,7 @@ bool WindowProxy::initialize()
}
}
- if (!installDOMWindow()) {
+ if (!setupWindowPrototypeChain()) {
disposeContext(DoNotDetachGlobal);
return false;
}
@@ -272,32 +272,6 @@ bool WindowProxy::initialize()
return true;
}
-namespace {
-
-void configureInnerGlobalObjectTemplate(v8::Local<v8::ObjectTemplate> templ, v8::Isolate* isolate)
-{
- // Install a security handler with V8.
- templ->SetAccessCheckCallback(V8Window::securityCheckCustom, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&V8Window::wrapperTypeInfo)));
- templ->SetInternalFieldCount(V8Window::internalFieldCount);
-}
-
-v8::Local<v8::ObjectTemplate> getInnerGlobalObjectTemplate(v8::Isolate* isolate)
-{
- // It is OK to share the same object template between the main world and
- // non-main worlds because the inner global object doesn't install any
- // DOM attributes/methods.
- DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, innerGlobalObjectTemplate, ());
- if (innerGlobalObjectTemplate.IsEmpty()) {
- TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "BuildDOMTemplate");
- v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
- configureInnerGlobalObjectTemplate(templ, isolate);
- innerGlobalObjectTemplate.Reset(isolate, templ);
- }
- return v8::Local<v8::ObjectTemplate>::New(isolate, innerGlobalObjectTemplate);
-}
-
-} // namespace
-
void WindowProxy::createContext()
{
// FIXME: This should be a null check of m_frame->client(), but there are still some edge cases
@@ -305,9 +279,12 @@ void WindowProxy::createContext()
if (m_frame->isLocalFrame() && !toLocalFrame(m_frame)->loader().documentLoader())
return;
- // Create a new environment using an empty template for the shadow
- // object. Reuse the global object if one has been created earlier.
- v8::Local<v8::ObjectTemplate> globalTemplate = getInnerGlobalObjectTemplate(m_isolate);
+ // Create a new v8::Context with the window object as the global object
+ // (aka the inner global). Reuse the global proxy object (aka the outer
+ // global) if it already exists. See the comments in
+ // setupWindowPrototypeChain for the structure of the prototype chain of
+ // the global object.
+ v8::Local<v8::ObjectTemplate> globalTemplate = V8Window::domTemplate(m_isolate, *m_world)->InstanceTemplate();
if (globalTemplate.IsEmpty())
return;
@@ -331,56 +308,64 @@ void WindowProxy::createContext()
}
v8::ExtensionConfiguration extensionConfiguration(extensionNames.size(), extensionNames.data());
- v8::Local<v8::Context> context = v8::Context::New(m_isolate, &extensionConfiguration, globalTemplate, m_global.newLocal(m_isolate));
+ v8::Local<v8::Context> context;
+ {
+ V8PerIsolateData::UseCounterDisabledScope useCounterDisabled(V8PerIsolateData::from(m_isolate));
+ context = v8::Context::New(m_isolate, &extensionConfiguration, globalTemplate, m_global.newLocal(m_isolate));
+ }
if (context.IsEmpty())
return;
m_scriptState = ScriptState::create(context, m_world);
}
-static v8::Local<v8::Object> toInnerGlobalObject(v8::Local<v8::Context> context)
+bool WindowProxy::setupWindowPrototypeChain()
{
- return v8::Local<v8::Object>::Cast(context->Global()->GetPrototype());
-}
+ // Associate the window wrapper object and its prototype chain with the
+ // corresponding native DOMWindow object.
+ // The full structure of the global object's prototype chain is as follows:
+ //
+ // global proxy object [1]
+ // -- has prototype --> global object (window wrapper object) [2]
+ // -- has prototype --> Window.prototype
+ // -- has prototype --> WindowProperties [3]
+ // -- has prototype --> EventTarget.prototype
+ // -- has prototype --> Object.prototype
+ // -- has prototype --> null
+ //
+ // [1] Global proxy object is as known as "outer global object". It's an
+ // empty object and remains after navigation. When navigated, points to
+ // a different global object as the prototype object.
+ // [2] Global object is as known as "inner global object" or "window wrapper
+ // object". The prototype chain between global proxy object and global
+ // object is NOT observable from user JavaScript code. All other
+ // prototype chains are observable. Global proxy object and global object
+ // together appear to be the same single JavaScript object. See also:
+ // https://wiki.mozilla.org/Gecko:SplitWindow
+ // global object (= window wrapper object) provides most of Window's DOM
+ // attributes and operations. Also global variables defined by user
+ // JavaScript are placed on this object. When navigated, a new global
+ // object is created together with a new v8::Context, but the global proxy
+ // object doesn't change.
+ // [3] WindowProperties is a named properties object of Window interface.
-bool WindowProxy::installDOMWindow()
-{
DOMWindow* window = m_frame->domWindow();
const WrapperTypeInfo* wrapperTypeInfo = window->wrapperTypeInfo();
- v8::Local<v8::Object> windowWrapper;
- v8::Local<v8::Function> constructor = m_scriptState->perContextData()->constructorForType(wrapperTypeInfo);
- if (constructor.IsEmpty())
- return false;
- if (!V8ObjectConstructor::newInstance(m_isolate, constructor).ToLocal(&windowWrapper))
- return false;
- windowWrapper = V8DOMWrapper::associateObjectWithWrapper(m_isolate, window, wrapperTypeInfo, windowWrapper);
- v8::Local<v8::Object> windowPrototype = v8::Local<v8::Object>::Cast(windowWrapper->GetPrototype());
+ v8::Local<v8::Context> context = m_scriptState->context();
+ // The global proxy object. Note this is not the global object.
+ v8::Local<v8::Object> globalProxy = context->Global();
+ // The global object, aka window wrapper object.
+ v8::Local<v8::Object> windowWrapper = globalProxy->GetPrototype().As<v8::Object>();
+ windowWrapper = V8DOMWrapper::associateObjectWithWrapper(m_isolate, window, wrapperTypeInfo, windowWrapper);
+ // The prototype object of Window interface.
+ v8::Local<v8::Object> windowPrototype = windowWrapper->GetPrototype().As<v8::Object>();
RELEASE_ASSERT(!windowPrototype.IsEmpty());
V8DOMWrapper::setNativeInfo(windowPrototype, wrapperTypeInfo, window);
- v8::Local<v8::Object> windowProperties = v8::Local<v8::Object>::Cast(windowPrototype->GetPrototype());
+ // The named properties object of Window interface.
+ v8::Local<v8::Object> windowProperties = windowPrototype->GetPrototype().As<v8::Object>();
RELEASE_ASSERT(!windowProperties.IsEmpty());
V8DOMWrapper::setNativeInfo(windowProperties, wrapperTypeInfo, window);
- // Install the windowWrapper as the prototype of the innerGlobalObject.
- // The full structure of the global object is as follows:
- //
- // outerGlobalObject (Empty object, remains after navigation)
- // -- has prototype --> innerGlobalObject (Holds global variables, changes during navigation)
- // -- has prototype --> DOMWindow instance
- // -- has prototype --> Window.prototype
- // -- has prototype --> WindowProperties (named properties object)
- // -- has prototype --> EventTarget.prototype
- // -- has prototype --> Object.prototype
- //
- // Note: Much of this prototype structure is hidden from web content. The
- // outer, inner, and DOMWindow instance all appear to be the same
- // JavaScript object.
- v8::Local<v8::Context> context = m_scriptState->context();
- v8::Local<v8::Object> innerGlobalObject = toInnerGlobalObject(m_scriptState->context());
- V8DOMWrapper::setNativeInfo(innerGlobalObject, wrapperTypeInfo, window);
- if (!v8CallBoolean(innerGlobalObject->SetPrototype(context, windowWrapper)))
- return false;
-
// TODO(keishi): Remove installPagePopupController and implement
// PagePopupController in another way.
V8PagePopupControllerBinding::installPagePopupController(context, windowWrapper);

Powered by Google App Engine
This is Rietveld 408576698