void WindowProxy::updateDocumentProperty() { if (!m_world->isMainWorld()) return; if (m_frame->isRemoteFrame()) { return; } ScriptState::Scope scope(m_scriptState.get()); v8::Local<v8::Context> context = m_scriptState->context(); LocalFrame* frame = toLocalFrame(m_frame); v8::Local<v8::Value> documentWrapper = toV8(frame->document(), context->Global(), context->GetIsolate()); if (documentWrapper.IsEmpty()) return; ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmpty()); if (m_document.isEmpty()) updateDocumentWrapper(v8::Local<v8::Object>::Cast(documentWrapper)); checkDocumentWrapper(m_document.newLocal(m_isolate), frame->document()); ASSERT(documentWrapper->IsObject()); // TODO(bashi): Avoid using ForceSet(). When we use accessors to implement // attributes, we may be able to remove updateDocumentProperty(). if (!v8CallBoolean(context->Global()->ForceSet(context, v8AtomicString(m_isolate, "document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)))) return; // We also stash a reference to the document on the inner global object so that // LocalDOMWindow objects we obtain from JavaScript references are guaranteed to have // live Document objects. V8HiddenValue::setHiddenValue(m_isolate, toInnerGlobalObject(context), V8HiddenValue::document(m_isolate), documentWrapper); }
void V8DOMWindowShell::updateDocumentProperty() { if (!m_world->isMainWorld()) return; v8::HandleScope handleScope; // FIXME: Should we use a new Local handle here? v8::Context::Scope contextScope(m_context.get()); v8::Handle<v8::Value> documentWrapper = toV8(m_frame->document()); ASSERT(documentWrapper == m_document.get() || m_document.isEmpty()); if (m_document.isEmpty()) updateDocumentWrapper(v8::Handle<v8::Object>::Cast(documentWrapper)); checkDocumentWrapper(m_document.get(), m_frame->document()); // If instantiation of the document wrapper fails, clear the cache // and let the DOMWindow accessor handle access to the document. if (documentWrapper.IsEmpty()) { clearDocumentProperty(); return; } ASSERT(documentWrapper->IsObject()); m_context->Global()->ForceSet(v8::String::New("document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)); // We also stash a reference to the document on the inner global object so that // DOMWindow objects we obtain from JavaScript references are guaranteed to have // live Document objects. toInnerGlobalObject(m_context.get())->SetHiddenValue(V8HiddenPropertyName::document(), documentWrapper); }
bool V8WindowShell::installDOMWindow() { DOMWrapperWorld::setInitializingWindow(true); DOMWindow* window = m_frame->domWindow(); v8::Local<v8::Object> windowWrapper = V8ObjectConstructor::newInstance(V8PerContextData::from(m_contextHolder->context())->constructorForType(&V8Window::wrapperTypeInfo)); if (windowWrapper.IsEmpty()) return false; V8Window::installPerContextEnabledProperties(windowWrapper, window, m_isolate); V8DOMWrapper::setNativeInfo(v8::Handle<v8::Object>::Cast(windowWrapper->GetPrototype()), &V8Window::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 --> 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::Handle<v8::Object> innerGlobalObject = toInnerGlobalObject(m_contextHolder->context()); V8DOMWrapper::setNativeInfo(innerGlobalObject, &V8Window::wrapperTypeInfo, window); innerGlobalObject->SetPrototype(windowWrapper); V8DOMWrapper::associateObjectWithWrapper<V8Window>(PassRefPtr<DOMWindow>(window), &V8Window::wrapperTypeInfo, windowWrapper, m_isolate, WrapperConfiguration::Dependent); DOMWrapperWorld::setInitializingWindow(false); return true; }
bool V8DOMWindowShell::installDOMWindow() { DOMWindow* window = m_frame->document()->domWindow(); v8::Local<v8::Object> windowWrapper = V8ObjectConstructor::newInstance(V8PerContextData::from(m_context.get())->constructorForType(&V8DOMWindow::info)); if (windowWrapper.IsEmpty()) return false; V8DOMWindow::installPerContextProperties(windowWrapper, window); V8DOMWrapper::setDOMWrapper(windowWrapper, &V8DOMWindow::info, window); V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(windowWrapper->GetPrototype()), &V8DOMWindow::info, window); V8DOMWrapper::setJSWrapperForDOMObject(PassRefPtr<DOMWindow>(window), windowWrapper); // 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 --> 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::Handle<v8::Object> innerGlobalObject = toInnerGlobalObject(m_context.get()); V8DOMWrapper::setDOMWrapper(innerGlobalObject, &V8DOMWindow::info, window); innerGlobalObject->SetPrototype(windowWrapper); return true; }
WorldContextHandle::WorldContextHandle(WorldToUse worldToUse) : m_worldToUse(worldToUse) { if (worldToUse == UseMainWorld || worldToUse == UseWorkerWorld) return; #if ENABLE(WORKERS) // FIXME We are duplicating a lot of effort here checking the context for the worker and for the isolated world. if (v8::Context::InContext()) { v8::Handle<v8::Context> context = v8::Context::GetCurrent(); if (!context.IsEmpty()) { if (UNLIKELY(!V8DOMWrapper::isWrapperOfType(toInnerGlobalObject(context), &V8DOMWindow::info))) { m_worldToUse = UseWorkerWorld; return; } } } #endif v8::Local<v8::Context> isolatedContext = V8DOMWindowShell::enteredIsolatedContext(); if (LIKELY(isolatedContext.IsEmpty())) { m_worldToUse = UseMainWorld; return; } m_context = SharedPersistent<v8::Context>::create(isolatedContext); }
PassRefPtr<EventListener> V8EventListenerList::getEventListener(v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup) { v8::Handle<v8::Context> context = v8::Context::GetCurrent(); if (context.IsEmpty()) return 0; if (lookup == ListenerFindOnly) return V8EventListenerList::findWrapper(value, isAttribute); if (V8DOMWrapper::isWrapperOfType(toInnerGlobalObject(context), &V8Window::info)) return V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute); return V8EventListenerList::findOrCreateWrapper<V8WorkerGlobalScopeEventListener>(value, isAttribute); }
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); V8DOMWrapper::setNativeInfo(v8::Local<v8::Object>::Cast(windowWrapper->GetPrototype()), 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 --> 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); return true; }
void WindowProxy::updateDocumentProperty() { ScriptState::Scope scope(m_scriptState.get()); v8::Handle<v8::Context> context = m_scriptState->context(); v8::Handle<v8::Value> documentWrapper = toV8(m_frame->document(), context->Global(), context->GetIsolate()); ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmpty()); if (m_document.isEmpty()) updateDocumentWrapper(v8::Handle<v8::Object>::Cast(documentWrapper)); // If instantiation of the document wrapper fails, clear the cache // and let the LocalDOMWindow accessor handle access to the document. if (documentWrapper.IsEmpty()) { clearDocumentProperty(); return; } ASSERT(documentWrapper->IsObject()); context->Global()->ForceSet(v8AtomicString(m_isolate, "document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)); // We also stash a reference to the document on the inner global object so that // LocalDOMWindow objects we obtain from JavaScript references are guaranteed to have // live Document objects. V8HiddenValue::setHiddenValue(m_isolate, toInnerGlobalObject(context), V8HiddenValue::document(m_isolate), documentWrapper); }
bool WindowProxy::installDOMWindow() { LocalDOMWindow* window = m_frame->domWindow(); v8::Local<v8::Object> windowWrapper = V8ObjectConstructor::newInstance(m_isolate, m_scriptState->perContextData()->constructorForType(&V8Window::wrapperTypeInfo)); if (windowWrapper.IsEmpty()) return false; V8DOMWrapper::setNativeInfoForHiddenWrapper(v8::Handle<v8::Object>::Cast(windowWrapper->GetPrototype()), &V8Window::wrapperTypeInfo, V8Window::toScriptWrappableBase(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 --> LocalDOMWindow instance // -- has prototype --> Window.prototype // -- has prototype --> Object.prototype // // Note: Much of this prototype structure is hidden from web content. The // outer, inner, and LocalDOMWindow instance all appear to be the same // JavaScript object. // // Note: With Oilpan, the LocalDOMWindow object is garbage collected. // Persistent references to this inner global object view of the LocalDOMWindow // aren't kept, as that would prevent the global object from ever being released. // It is safe not to do so, as the wrapper for the LocalDOMWindow being installed here // already keeps a persistent reference, and it along with the inner global object // views of the LocalDOMWindow will die together once that wrapper clears the persistent // reference. v8::Handle<v8::Object> innerGlobalObject = toInnerGlobalObject(m_scriptState->context()); V8DOMWrapper::setNativeInfoForHiddenWrapper(innerGlobalObject, &V8Window::wrapperTypeInfo, V8Window::toScriptWrappableBase(window)); innerGlobalObject->SetPrototype(windowWrapper); V8DOMWrapper::associateObjectWithWrapper<V8Window>(PassRefPtr<LocalDOMWindow>(window), &V8Window::wrapperTypeInfo, windowWrapper, m_isolate); V8Window::installConditionallyEnabledProperties(windowWrapper, m_isolate); return true; }
V8DOMWindowShell* V8DOMWindowShell::enteredIsolatedWorldContext() { return static_cast<V8DOMWindowShell*>(toInnerGlobalObject(v8::Context::GetEntered())->GetPointerFromInternalField(V8DOMWindow::enteredIsolatedWorldIndex)); }
static void setIsolatedWorldField(V8DOMWindowShell* shell, v8::Local<v8::Context> context) { toInnerGlobalObject(context)->SetPointerInInternalField(V8DOMWindow::enteredIsolatedWorldIndex, shell); }