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

Side by Side Diff: sky/engine/bindings/core/v8/WindowProxy.cpp

Issue 922053002: Remove unused V8 integration code in Sky (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 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 unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "sky/engine/config.h"
32 #include "sky/engine/bindings/core/v8/WindowProxy.h"
33
34 #include <algorithm>
35 #include <utility>
36
37 #include "bindings/core/v8/V8Document.h"
38 #include "bindings/core/v8/V8Window.h"
39 #include "gen/sky/platform/RuntimeEnabledFeatures.h"
40 #include "sky/engine/bindings/core/v8/DOMWrapperWorld.h"
41 #include "sky/engine/bindings/core/v8/ScriptController.h"
42 #include "sky/engine/bindings/core/v8/V8Binding.h"
43 #include "sky/engine/bindings/core/v8/V8GCForContextDispose.h"
44 #include "sky/engine/bindings/core/v8/V8HiddenValue.h"
45 #include "sky/engine/bindings/core/v8/V8Initializer.h"
46 #include "sky/engine/bindings/core/v8/V8ObjectConstructor.h"
47 #include "sky/engine/core/frame/LocalFrame.h"
48 #include "sky/engine/core/loader/FrameLoaderClient.h"
49 #include "sky/engine/platform/ScriptForbiddenScope.h"
50 #include "sky/engine/platform/TraceEvent.h"
51 #include "sky/engine/public/platform/Platform.h"
52 #include "sky/engine/wtf/Assertions.h"
53 #include "sky/engine/wtf/OwnPtr.h"
54 #include "sky/engine/wtf/StringExtras.h"
55 #include "sky/engine/wtf/text/CString.h"
56 #include "v8/include/v8-debug.h"
57 #include "v8/include/v8.h"
58
59 namespace blink {
60
61 PassOwnPtr<WindowProxy> WindowProxy::create(LocalFrame* frame, DOMWrapperWorld& world, v8::Isolate* isolate)
62 {
63 return adoptPtr(new WindowProxy(frame, &world, isolate));
64 }
65
66 WindowProxy::WindowProxy(LocalFrame* frame, PassRefPtr<DOMWrapperWorld> world, v 8::Isolate* isolate)
67 : m_frame(frame)
68 , m_isolate(isolate)
69 , m_world(world)
70 {
71 }
72
73 void WindowProxy::disposeContext(GlobalDetachmentBehavior behavior)
74 {
75 if (!isContextInitialized())
76 return;
77
78 v8::HandleScope handleScope(m_isolate);
79 v8::Handle<v8::Context> context = m_scriptState->context();
80 m_frame->loaderClient()->willReleaseScriptContext(context);
81
82 if (behavior == DetachGlobal)
83 context->DetachGlobal();
84
85 m_scriptState->disposePerContextData();
86
87 // It's likely that disposing the context has created a lot of
88 // garbage. Notify V8 about this so it'll have a chance of cleaning
89 // it up when idle.
90 V8GCForContextDispose::instanceTemplate().notifyContextDisposed();
91 }
92
93 void WindowProxy::clearForClose()
94 {
95 if (!isContextInitialized())
96 return;
97
98 m_document.clear();
99 disposeContext(DoNotDetachGlobal);
100 }
101
102 void WindowProxy::clearForNavigation()
103 {
104 if (!isContextInitialized())
105 return;
106
107 ScriptState::Scope scope(m_scriptState.get());
108
109 m_document.clear();
110
111 v8::Handle<v8::Object> windowWrapper = V8Window::findInstanceInPrototypeChai n(m_global.newLocal(m_isolate), m_isolate);
112 ASSERT(!windowWrapper.IsEmpty());
113 windowWrapper->TurnOnAccessCheck();
114 disposeContext(DetachGlobal);
115 }
116
117 // Create a new environment and setup the global object.
118 //
119 // The global object corresponds to a LocalDOMWindow instance. However, to
120 // allow properties of the JS LocalDOMWindow instance to be shadowed, we
121 // use a shadow object as the global object and use the JS LocalDOMWindow
122 // instance as the prototype for that shadow object. The JS LocalDOMWindow
123 // instance is undetectable from JavaScript code because the __proto__
124 // accessors skip that object.
125 //
126 // The shadow object and the LocalDOMWindow instance are seen as one object
127 // from JavaScript. The JavaScript object that corresponds to a
128 // LocalDOMWindow instance is the shadow object. When mapping a LocalDOMWindow
129 // instance to a V8 object, we return the shadow object.
130 //
131 // To implement split-window, see
132 // 1) https://bugs.webkit.org/show_bug.cgi?id=17249
133 // 2) https://wiki.mozilla.org/Gecko:SplitWindow
134 // 3) https://bugzilla.mozilla.org/show_bug.cgi?id=296639
135 // we need to split the shadow object further into two objects:
136 // an outer window and an inner window. The inner window is the hidden
137 // prototype of the outer window. The inner window is the default
138 // global object of the context. A variable declared in the global
139 // scope is a property of the inner window.
140 //
141 // The outer window sticks to a LocalFrame, it is exposed to JavaScript
142 // via window.window, window.self, window.parent, etc. The outer window
143 // has a security token which is the domain. The outer window cannot
144 // have its own properties. window.foo = 'x' is delegated to the
145 // inner window.
146 //
147 // When a frame navigates to a new page, the inner window is cut off
148 // the outer window, and the outer window identify is preserved for
149 // the frame. However, a new inner window is created for the new page.
150 // If there are JS code holds a closure to the old inner window,
151 // it won't be able to reach the outer window via its global object.
152 bool WindowProxy::initializeIfNeeded()
153 {
154 if (isContextInitialized())
155 return true;
156
157 DOMWrapperWorld::setWorldOfInitializingWindow(m_world.get());
158 bool result = initialize();
159 DOMWrapperWorld::setWorldOfInitializingWindow(0);
160 return result;
161 }
162
163 bool WindowProxy::initialize()
164 {
165 TRACE_EVENT0("v8", "WindowProxy::initialize");
166 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "InitializeWindow");
167
168 ScriptForbiddenScope::AllowUserAgentScript allowScript;
169
170 v8::HandleScope handleScope(m_isolate);
171
172 createContext();
173
174 if (!isContextInitialized())
175 return false;
176
177 ScriptState::Scope scope(m_scriptState.get());
178 v8::Handle<v8::Context> context = m_scriptState->context();
179 if (m_global.isEmpty()) {
180 m_global.set(m_isolate, context->Global());
181 if (m_global.isEmpty()) {
182 disposeContext(DoNotDetachGlobal);
183 return false;
184 }
185 }
186
187 if (!installDOMWindow()) {
188 disposeContext(DoNotDetachGlobal);
189 return false;
190 }
191
192 updateDocument();
193 m_frame->loaderClient()->didCreateScriptContext(context);
194 return true;
195 }
196
197 void WindowProxy::createContext()
198 {
199 // Create a new environment using an empty template for the shadow
200 // object. Reuse the global object if one has been created earlier.
201 v8::Handle<v8::ObjectTemplate> globalTemplate = V8Window::getShadowObjectTem plate(m_isolate);
202 if (globalTemplate.IsEmpty())
203 return;
204
205 double contextCreationStartInSeconds = currentTime();
206
207 // Dynamically tell v8 about our extensions now.
208 const V8Extensions& extensions = ScriptController::registeredExtensions();
209 OwnPtr<const char*[]> extensionNames = adoptArrayPtr(new const char*[extensi ons.size()]);
210 int index = 0;
211 for (size_t i = 0; i < extensions.size(); ++i) {
212 extensionNames[index++] = extensions[i]->name();
213 }
214 v8::ExtensionConfiguration extensionConfiguration(index, extensionNames.get( ));
215
216 v8::Handle<v8::Context> context = v8::Context::New(m_isolate, &extensionConf iguration, globalTemplate, m_global.newLocal(m_isolate));
217 if (context.IsEmpty())
218 return;
219 m_scriptState = ScriptState::create(context, m_world);
220
221 double contextCreationDurationInMilliseconds = (currentTime() - contextCreat ionStartInSeconds) * 1000;
222 const char* histogramName = "WebCore.WindowProxy.createContext.MainWorld";
223 if (!m_world->isMainWorld())
224 histogramName = "WebCore.WindowProxy.createContext.IsolatedWorld";
225 blink::Platform::current()->histogramCustomCounts(histogramName, contextCrea tionDurationInMilliseconds, 0, 10000, 50);
226 }
227
228 static v8::Handle<v8::Object> toInnerGlobalObject(v8::Handle<v8::Context> contex t)
229 {
230 return v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype());
231 }
232
233 bool WindowProxy::installDOMWindow()
234 {
235 LocalDOMWindow* window = m_frame->domWindow();
236 v8::Local<v8::Object> windowWrapper = V8ObjectConstructor::newInstance(m_iso late, m_scriptState->perContextData()->constructorForType(&V8Window::wrapperType Info));
237 if (windowWrapper.IsEmpty())
238 return false;
239
240 V8DOMWrapper::setNativeInfoForHiddenWrapper(v8::Handle<v8::Object>::Cast(win dowWrapper->GetPrototype()), &V8Window::wrapperTypeInfo, V8Window::toScriptWrapp ableBase(window));
241
242 // Install the windowWrapper as the prototype of the innerGlobalObject.
243 // The full structure of the global object is as follows:
244 //
245 // outerGlobalObject (Empty object, remains after navigation)
246 // -- has prototype --> innerGlobalObject (Holds global variables, changes during navigation)
247 // -- has prototype --> LocalDOMWindow instance
248 // -- has prototype --> Window.prototype
249 // -- has prototype --> Object.prototype
250 //
251 // Note: Much of this prototype structure is hidden from web content. The
252 // outer, inner, and LocalDOMWindow instance all appear to be the same
253 // JavaScript object.
254 //
255 // Note: With Oilpan, the LocalDOMWindow object is garbage collected.
256 // Persistent references to this inner global object view of the Local DOMWindow
257 // aren't kept, as that would prevent the global object from ever bein g released.
258 // It is safe not to do so, as the wrapper for the LocalDOMWindow bein g installed here
259 // already keeps a persistent reference, and it along with the inner g lobal object
260 // views of the LocalDOMWindow will die together once that wrapper cle ars the persistent
261 // reference.
262 v8::Handle<v8::Object> innerGlobalObject = toInnerGlobalObject(m_scriptState ->context());
263 V8DOMWrapper::setNativeInfoForHiddenWrapper(innerGlobalObject, &V8Window::wr apperTypeInfo, V8Window::toScriptWrappableBase(window));
264 innerGlobalObject->SetPrototype(windowWrapper);
265 V8DOMWrapper::associateObjectWithWrapper<V8Window>(PassRefPtr<LocalDOMWindow >(window), &V8Window::wrapperTypeInfo, windowWrapper, m_isolate);
266 V8Window::installConditionallyEnabledProperties(windowWrapper, m_isolate);
267 return true;
268 }
269
270 void WindowProxy::updateDocumentWrapper(v8::Handle<v8::Object> wrapper)
271 {
272 ASSERT(m_world->isMainWorld());
273 m_document.set(m_isolate, wrapper);
274 }
275
276 void WindowProxy::updateDocumentProperty()
277 {
278 ScriptState::Scope scope(m_scriptState.get());
279 v8::Handle<v8::Context> context = m_scriptState->context();
280 v8::Handle<v8::Value> documentWrapper = toV8(m_frame->document(), context->G lobal(), context->GetIsolate());
281 ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmp ty());
282 if (m_document.isEmpty())
283 updateDocumentWrapper(v8::Handle<v8::Object>::Cast(documentWrapper));
284
285 ASSERT(documentWrapper->IsObject());
286 context->Global()->ForceSet(v8AtomicString(m_isolate, "document"), documentW rapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
287
288 // We also stash a reference to the document on the inner global object so t hat
289 // LocalDOMWindow objects we obtain from JavaScript references are guarantee d to have
290 // live Document objects.
291 V8HiddenValue::setHiddenValue(m_isolate, toInnerGlobalObject(context), V8Hid denValue::document(m_isolate), documentWrapper);
292 }
293
294 void WindowProxy::updateDocument()
295 {
296 ASSERT(m_world->isMainWorld());
297 if (!isGlobalInitialized())
298 return;
299 if (!isContextInitialized())
300 return;
301 updateDocumentProperty();
302 }
303
304 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/bindings/core/v8/WindowProxy.h ('k') | sky/engine/bindings/core/v8/WrapperTypeInfo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698