OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 11 matching lines...) Expand all Loading... |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "bindings/v8/V8WindowShell.h" | 32 #include "bindings/v8/V8DOMWindowShell.h" |
33 | 33 |
| 34 #include <v8-debug.h> |
| 35 #include <v8-i18n/include/extension.h> |
| 36 #include <v8.h> |
| 37 #include <algorithm> |
| 38 #include <utility> |
34 #include "RuntimeEnabledFeatures.h" | 39 #include "RuntimeEnabledFeatures.h" |
| 40 #include "V8DOMWindow.h" |
35 #include "V8Document.h" | 41 #include "V8Document.h" |
36 #include "V8HTMLCollection.h" | 42 #include "V8HTMLCollection.h" |
37 #include "V8HTMLDocument.h" | 43 #include "V8HTMLDocument.h" |
38 #include "V8Window.h" | |
39 #include "bindings/v8/DOMWrapperWorld.h" | 44 #include "bindings/v8/DOMWrapperWorld.h" |
40 #include "bindings/v8/DateExtension.h" | 45 #include "bindings/v8/DateExtension.h" |
41 #include "bindings/v8/ScriptController.h" | 46 #include "bindings/v8/ScriptController.h" |
42 #include "bindings/v8/V8Binding.h" | 47 #include "bindings/v8/V8Binding.h" |
43 #include "bindings/v8/V8GCForContextDispose.h" | 48 #include "bindings/v8/V8GCForContextDispose.h" |
44 #include "bindings/v8/V8HiddenPropertyName.h" | 49 #include "bindings/v8/V8HiddenPropertyName.h" |
45 #include "bindings/v8/V8Initializer.h" | 50 #include "bindings/v8/V8Initializer.h" |
46 #include "bindings/v8/V8ObjectConstructor.h" | 51 #include "bindings/v8/V8ObjectConstructor.h" |
47 #include "bindings/v8/V8PerContextData.h" | 52 #include "bindings/v8/V8PerContextData.h" |
48 #include "core/html/HTMLCollection.h" | 53 #include "core/html/HTMLCollection.h" |
49 #include "core/html/HTMLIFrameElement.h" | 54 #include "core/html/HTMLIFrameElement.h" |
50 #include "core/inspector/InspectorInstrumentation.h" | 55 #include "core/inspector/InspectorInstrumentation.h" |
51 #include "core/loader/DocumentLoader.h" | 56 #include "core/loader/DocumentLoader.h" |
52 #include "core/loader/FrameLoader.h" | 57 #include "core/loader/FrameLoader.h" |
53 #include "core/loader/FrameLoaderClient.h" | 58 #include "core/loader/FrameLoaderClient.h" |
54 #include "core/page/ContentSecurityPolicy.h" | 59 #include "core/page/ContentSecurityPolicy.h" |
55 #include "core/page/Frame.h" | 60 #include "core/page/Frame.h" |
56 #include "core/page/Page.h" | 61 #include "core/page/Page.h" |
57 #include "core/platform/HistogramSupport.h" | 62 #include "core/platform/HistogramSupport.h" |
58 #include "weborigin/SecurityOrigin.h" | 63 #include "weborigin/SecurityOrigin.h" |
59 #include "wtf/Assertions.h" | 64 #include "wtf/Assertions.h" |
60 #include "wtf/OwnArrayPtr.h" | 65 #include "wtf/OwnArrayPtr.h" |
61 #include "wtf/StringExtras.h" | 66 #include "wtf/StringExtras.h" |
62 #include "wtf/text/CString.h" | 67 #include "wtf/text/CString.h" |
63 #include <algorithm> | |
64 #include <utility> | |
65 #include <v8-debug.h> | |
66 #include <v8-i18n/include/extension.h> | |
67 #include <v8.h> | |
68 | 68 |
69 namespace WebCore { | 69 namespace WebCore { |
70 | 70 |
71 static void checkDocumentWrapper(v8::Handle<v8::Object> wrapper, Document* docum
ent) | 71 static void checkDocumentWrapper(v8::Handle<v8::Object> wrapper, Document* docum
ent) |
72 { | 72 { |
73 ASSERT(V8Document::toNative(wrapper) == document); | 73 ASSERT(V8Document::toNative(wrapper) == document); |
74 ASSERT(!document->isHTMLDocument() || (V8Document::toNative(v8::Handle<v8::O
bject>::Cast(wrapper->GetPrototype())) == document)); | 74 ASSERT(!document->isHTMLDocument() || (V8Document::toNative(v8::Handle<v8::O
bject>::Cast(wrapper->GetPrototype())) == document)); |
75 } | 75 } |
76 | 76 |
77 static void setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContex
t, int debugId) | 77 static void setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContex
t, int debugId) |
78 { | 78 { |
79 V8PerContextDebugData::setContextDebugData(targetContext, "injected", debugI
d); | 79 V8PerContextDebugData::setContextDebugData(targetContext, "injected", debugI
d); |
80 } | 80 } |
81 | 81 |
82 PassOwnPtr<V8WindowShell> V8WindowShell::create(Frame* frame, PassRefPtr<DOMWrap
perWorld> world, v8::Isolate* isolate) | 82 PassOwnPtr<V8DOMWindowShell> V8DOMWindowShell::create(Frame* frame, PassRefPtr<D
OMWrapperWorld> world, v8::Isolate* isolate) |
83 { | 83 { |
84 return adoptPtr(new V8WindowShell(frame, world, isolate)); | 84 return adoptPtr(new V8DOMWindowShell(frame, world, isolate)); |
85 } | 85 } |
86 | 86 |
87 V8WindowShell::V8WindowShell(Frame* frame, PassRefPtr<DOMWrapperWorld> world, v8
::Isolate* isolate) | 87 V8DOMWindowShell::V8DOMWindowShell(Frame* frame, PassRefPtr<DOMWrapperWorld> wor
ld, v8::Isolate* isolate) |
88 : m_frame(frame) | 88 : m_frame(frame) |
89 , m_world(world) | 89 , m_world(world) |
90 , m_isolate(isolate) | 90 , m_isolate(isolate) |
91 { | 91 { |
92 } | 92 } |
93 | 93 |
94 void V8WindowShell::disposeContext() | 94 void V8DOMWindowShell::disposeContext() |
95 { | 95 { |
96 m_perContextData.clear(); | 96 m_perContextData.clear(); |
97 | 97 |
98 if (m_context.isEmpty()) | 98 if (m_context.isEmpty()) |
99 return; | 99 return; |
100 | 100 |
101 v8::HandleScope handleScope(m_isolate); | 101 v8::HandleScope handleScope(m_isolate); |
102 m_frame->loader()->client()->willReleaseScriptContext(m_context.newLocal(m_i
solate), m_world->worldId()); | 102 m_frame->loader()->client()->willReleaseScriptContext(m_context.newLocal(m_i
solate), m_world->worldId()); |
103 | 103 |
104 m_context.clear(); | 104 m_context.clear(); |
105 | 105 |
106 // It's likely that disposing the context has created a lot of | 106 // It's likely that disposing the context has created a lot of |
107 // garbage. Notify V8 about this so it'll have a chance of cleaning | 107 // garbage. Notify V8 about this so it'll have a chance of cleaning |
108 // it up when idle. | 108 // it up when idle. |
109 bool isMainFrame = m_frame->page() && (m_frame->page()->mainFrame() == m_fra
me); | 109 bool isMainFrame = m_frame->page() && (m_frame->page()->mainFrame() == m_fra
me); |
110 V8GCForContextDispose::instance().notifyContextDisposed(isMainFrame); | 110 V8GCForContextDispose::instance().notifyContextDisposed(isMainFrame); |
111 } | 111 } |
112 | 112 |
113 void V8WindowShell::clearForClose(bool destroyGlobal) | 113 void V8DOMWindowShell::clearForClose(bool destroyGlobal) |
114 { | 114 { |
115 if (destroyGlobal) | 115 if (destroyGlobal) |
116 m_global.clear(); | 116 m_global.clear(); |
117 | 117 |
118 if (m_context.isEmpty()) | 118 if (m_context.isEmpty()) |
119 return; | 119 return; |
120 | 120 |
121 m_document.clear(); | 121 m_document.clear(); |
122 disposeContext(); | 122 disposeContext(); |
123 } | 123 } |
124 | 124 |
125 void V8WindowShell::clearForNavigation() | 125 void V8DOMWindowShell::clearForNavigation() |
126 { | 126 { |
127 if (m_context.isEmpty()) | 127 if (m_context.isEmpty()) |
128 return; | 128 return; |
129 | 129 |
130 v8::HandleScope handleScope(m_isolate); | 130 v8::HandleScope handleScope(m_isolate); |
131 m_document.clear(); | 131 m_document.clear(); |
132 | 132 |
133 v8::Handle<v8::Context> context = m_context.newLocal(m_isolate); | 133 v8::Handle<v8::Context> context = m_context.newLocal(m_isolate); |
134 v8::Context::Scope contextScope(context); | 134 v8::Context::Scope contextScope(context); |
135 | 135 |
136 // Clear the document wrapper cache before turning on access checks on | 136 // Clear the document wrapper cache before turning on access checks on |
137 // the old DOMWindow wrapper. This way, access to the document wrapper | 137 // the old DOMWindow wrapper. This way, access to the document wrapper |
138 // will be protected by the security checks on the DOMWindow wrapper. | 138 // will be protected by the security checks on the DOMWindow wrapper. |
139 clearDocumentProperty(); | 139 clearDocumentProperty(); |
140 | 140 |
141 v8::Handle<v8::Object> windowWrapper = m_global.newLocal(m_isolate)->FindIns
tanceInPrototypeChain(V8Window::GetTemplate(m_isolate, worldTypeInMainThread(m_i
solate))); | 141 v8::Handle<v8::Object> windowWrapper = m_global.newLocal(m_isolate)->FindIns
tanceInPrototypeChain(V8DOMWindow::GetTemplate(m_isolate, worldTypeInMainThread(
m_isolate))); |
142 ASSERT(!windowWrapper.IsEmpty()); | 142 ASSERT(!windowWrapper.IsEmpty()); |
143 windowWrapper->TurnOnAccessCheck(); | 143 windowWrapper->TurnOnAccessCheck(); |
144 context->DetachGlobal(); | 144 context->DetachGlobal(); |
145 disposeContext(); | 145 disposeContext(); |
146 } | 146 } |
147 | 147 |
148 // Create a new environment and setup the global object. | 148 // Create a new environment and setup the global object. |
149 // | 149 // |
150 // The global object corresponds to a DOMWindow instance. However, to | 150 // The global object corresponds to a DOMWindow instance. However, to |
151 // allow properties of the JS DOMWindow instance to be shadowed, we | 151 // allow properties of the JS DOMWindow instance to be shadowed, we |
(...skipping 21 matching lines...) Expand all Loading... |
173 // via window.window, window.self, window.parent, etc. The outer window | 173 // via window.window, window.self, window.parent, etc. The outer window |
174 // has a security token which is the domain. The outer window cannot | 174 // has a security token which is the domain. The outer window cannot |
175 // have its own properties. window.foo = 'x' is delegated to the | 175 // have its own properties. window.foo = 'x' is delegated to the |
176 // inner window. | 176 // inner window. |
177 // | 177 // |
178 // When a frame navigates to a new page, the inner window is cut off | 178 // When a frame navigates to a new page, the inner window is cut off |
179 // the outer window, and the outer window identify is preserved for | 179 // the outer window, and the outer window identify is preserved for |
180 // the frame. However, a new inner window is created for the new page. | 180 // the frame. However, a new inner window is created for the new page. |
181 // If there are JS code holds a closure to the old inner window, | 181 // If there are JS code holds a closure to the old inner window, |
182 // it won't be able to reach the outer window via its global object. | 182 // it won't be able to reach the outer window via its global object. |
183 bool V8WindowShell::initializeIfNeeded() | 183 bool V8DOMWindowShell::initializeIfNeeded() |
184 { | 184 { |
185 if (!m_context.isEmpty()) | 185 if (!m_context.isEmpty()) |
186 return true; | 186 return true; |
187 | 187 |
188 v8::HandleScope handleScope(m_isolate); | 188 v8::HandleScope handleScope(m_isolate); |
189 | 189 |
190 V8Initializer::initializeMainThreadIfNeeded(m_isolate); | 190 V8Initializer::initializeMainThreadIfNeeded(m_isolate); |
191 | 191 |
192 createContext(); | 192 createContext(); |
193 if (m_context.isEmpty()) | 193 if (m_context.isEmpty()) |
194 return false; | 194 return false; |
195 | 195 |
196 v8::Handle<v8::Context> context = m_context.newLocal(m_isolate); | 196 v8::Handle<v8::Context> context = m_context.newLocal(m_isolate); |
197 | 197 |
198 m_world->setIsolatedWorldField(context); | 198 m_world->setIsolatedWorldField(context); |
199 | 199 |
200 bool isMainWorld = m_world->isMainWorld(); | 200 bool isMainWorld = m_world->isMainWorld(); |
201 | 201 |
202 v8::Context::Scope contextScope(context); | 202 v8::Context::Scope contextScope(context); |
203 | 203 |
204 if (m_global.isEmpty()) { | 204 if (m_global.isEmpty()) { |
205 m_global.set(m_isolate, context->Global()); | 205 m_global.set(m_isolate, context->Global()); |
206 if (m_global.isEmpty()) { | 206 if (m_global.isEmpty()) { |
207 disposeContext(); | 207 disposeContext(); |
208 return false; | 208 return false; |
209 } | 209 } |
210 } | 210 } |
211 | 211 |
212 if (!isMainWorld) { | 212 if (!isMainWorld) { |
213 V8WindowShell* mainWindow = m_frame->script()->existingWindowShell(mainT
hreadNormalWorld()); | 213 V8DOMWindowShell* mainWindow = m_frame->script()->existingWindowShell(ma
inThreadNormalWorld()); |
214 if (mainWindow && !mainWindow->context().IsEmpty()) | 214 if (mainWindow && !mainWindow->context().IsEmpty()) |
215 setInjectedScriptContextDebugId(context, m_frame->script()->contextD
ebugId(mainWindow->context())); | 215 setInjectedScriptContextDebugId(context, m_frame->script()->contextD
ebugId(mainWindow->context())); |
216 } | 216 } |
217 | 217 |
218 m_perContextData = V8PerContextData::create(context); | 218 m_perContextData = V8PerContextData::create(context); |
219 if (!m_perContextData->init()) { | 219 if (!m_perContextData->init()) { |
220 disposeContext(); | 220 disposeContext(); |
221 return false; | 221 return false; |
222 } | 222 } |
223 m_perContextData->setActivityLogger(DOMWrapperWorld::activityLogger(m_world-
>worldId())); | 223 m_perContextData->setActivityLogger(DOMWrapperWorld::activityLogger(m_world-
>worldId())); |
(...skipping 22 matching lines...) Expand all Loading... |
246 SecurityOrigin* origin = m_world->isolatedWorldSecurityOrigin(); | 246 SecurityOrigin* origin = m_world->isolatedWorldSecurityOrigin(); |
247 if (origin && InspectorInstrumentation::hasFrontends()) { | 247 if (origin && InspectorInstrumentation::hasFrontends()) { |
248 ScriptState* scriptState = ScriptState::forContext(v8::Local<v8::Con
text>::New(context)); | 248 ScriptState* scriptState = ScriptState::forContext(v8::Local<v8::Con
text>::New(context)); |
249 InspectorInstrumentation::didCreateIsolatedContext(m_frame, scriptSt
ate, origin); | 249 InspectorInstrumentation::didCreateIsolatedContext(m_frame, scriptSt
ate, origin); |
250 } | 250 } |
251 } | 251 } |
252 m_frame->loader()->client()->didCreateScriptContext(context, m_world->extens
ionGroup(), m_world->worldId()); | 252 m_frame->loader()->client()->didCreateScriptContext(context, m_world->extens
ionGroup(), m_world->worldId()); |
253 return true; | 253 return true; |
254 } | 254 } |
255 | 255 |
256 void V8WindowShell::createContext() | 256 void V8DOMWindowShell::createContext() |
257 { | 257 { |
258 // The activeDocumentLoader pointer could be 0 during frame shutdown. | 258 // The activeDocumentLoader pointer could be 0 during frame shutdown. |
259 // FIXME: Can we remove this check? | 259 // FIXME: Can we remove this check? |
260 if (!m_frame->loader()->activeDocumentLoader()) | 260 if (!m_frame->loader()->activeDocumentLoader()) |
261 return; | 261 return; |
262 | 262 |
263 // Create a new environment using an empty template for the shadow | 263 // Create a new environment using an empty template for the shadow |
264 // object. Reuse the global object if one has been created earlier. | 264 // object. Reuse the global object if one has been created earlier. |
265 v8::Handle<v8::ObjectTemplate> globalTemplate = V8Window::GetShadowObjectTem
plate(m_isolate, m_world->isMainWorld() ? MainWorld : IsolatedWorld); | 265 v8::Handle<v8::ObjectTemplate> globalTemplate = V8DOMWindow::GetShadowObject
Template(m_isolate, m_world->isMainWorld() ? MainWorld : IsolatedWorld); |
266 if (globalTemplate.IsEmpty()) | 266 if (globalTemplate.IsEmpty()) |
267 return; | 267 return; |
268 | 268 |
269 double contextCreationStartInSeconds = currentTime(); | 269 double contextCreationStartInSeconds = currentTime(); |
270 | 270 |
271 // Used to avoid sleep calls in unload handlers. | 271 // Used to avoid sleep calls in unload handlers. |
272 ScriptController::registerExtensionIfNeeded(DateExtension::get()); | 272 ScriptController::registerExtensionIfNeeded(DateExtension::get()); |
273 | 273 |
274 // Enables experimental i18n API in V8. | 274 // Enables experimental i18n API in V8. |
275 if (RuntimeEnabledFeatures::javaScriptI18NAPIEnabled()) | 275 if (RuntimeEnabledFeatures::javaScriptI18NAPIEnabled()) |
(...skipping 12 matching lines...) Expand all Loading... |
288 continue; | 288 continue; |
289 | 289 |
290 extensionNames[index++] = extensions[i]->name(); | 290 extensionNames[index++] = extensions[i]->name(); |
291 } | 291 } |
292 v8::ExtensionConfiguration extensionConfiguration(index, extensionNames.get(
)); | 292 v8::ExtensionConfiguration extensionConfiguration(index, extensionNames.get(
)); |
293 | 293 |
294 v8::HandleScope handleScope(m_isolate); | 294 v8::HandleScope handleScope(m_isolate); |
295 m_context.set(m_isolate, v8::Context::New(m_isolate, &extensionConfiguration
, globalTemplate, m_global.newLocal(m_isolate))); | 295 m_context.set(m_isolate, v8::Context::New(m_isolate, &extensionConfiguration
, globalTemplate, m_global.newLocal(m_isolate))); |
296 | 296 |
297 double contextCreationDurationInMilliseconds = (currentTime() - contextCreat
ionStartInSeconds) * 1000; | 297 double contextCreationDurationInMilliseconds = (currentTime() - contextCreat
ionStartInSeconds) * 1000; |
298 const char* histogramName = "WebCore.V8WindowShell.createContext.MainWorld"; | 298 const char* histogramName = "WebCore.V8DOMWindowShell.createContext.MainWorl
d"; |
299 if (!m_world->isMainWorld()) | 299 if (!m_world->isMainWorld()) |
300 histogramName = "WebCore.V8WindowShell.createContext.IsolatedWorld"; | 300 histogramName = "WebCore.V8DOMWindowShell.createContext.IsolatedWorld"; |
301 HistogramSupport::histogramCustomCounts(histogramName, contextCreationDurati
onInMilliseconds, 0, 10000, 50); | 301 HistogramSupport::histogramCustomCounts(histogramName, contextCreationDurati
onInMilliseconds, 0, 10000, 50); |
302 } | 302 } |
303 | 303 |
304 bool V8WindowShell::installDOMWindow() | 304 bool V8DOMWindowShell::installDOMWindow() |
305 { | 305 { |
306 DOMWrapperWorld::setInitializingWindow(true); | 306 DOMWrapperWorld::setInitializingWindow(true); |
307 DOMWindow* window = m_frame->document()->domWindow(); | 307 DOMWindow* window = m_frame->document()->domWindow(); |
308 v8::Local<v8::Object> windowWrapper = V8ObjectConstructor::newInstance(V8Per
ContextData::from(m_context.get())->constructorForType(&V8Window::info)); | 308 v8::Local<v8::Object> windowWrapper = V8ObjectConstructor::newInstance(V8Per
ContextData::from(m_context.get())->constructorForType(&V8DOMWindow::info)); |
309 if (windowWrapper.IsEmpty()) | 309 if (windowWrapper.IsEmpty()) |
310 return false; | 310 return false; |
311 | 311 |
312 V8Window::installPerContextProperties(windowWrapper, window, m_isolate); | 312 V8DOMWindow::installPerContextProperties(windowWrapper, window, m_isolate); |
313 | 313 |
314 V8DOMWrapper::setNativeInfo(v8::Handle<v8::Object>::Cast(windowWrapper->GetP
rototype()), &V8Window::info, window); | 314 V8DOMWrapper::setNativeInfo(v8::Handle<v8::Object>::Cast(windowWrapper->GetP
rototype()), &V8DOMWindow::info, window); |
315 | 315 |
316 // Install the windowWrapper as the prototype of the innerGlobalObject. | 316 // Install the windowWrapper as the prototype of the innerGlobalObject. |
317 // The full structure of the global object is as follows: | 317 // The full structure of the global object is as follows: |
318 // | 318 // |
319 // outerGlobalObject (Empty object, remains after navigation) | 319 // outerGlobalObject (Empty object, remains after navigation) |
320 // -- has prototype --> innerGlobalObject (Holds global variables, changes
during navigation) | 320 // -- has prototype --> innerGlobalObject (Holds global variables, changes
during navigation) |
321 // -- has prototype --> DOMWindow instance | 321 // -- has prototype --> DOMWindow instance |
322 // -- has prototype --> Window.prototype | 322 // -- has prototype --> Window.prototype |
323 // -- has prototype --> Object.prototype | 323 // -- has prototype --> Object.prototype |
324 // | 324 // |
325 // Note: Much of this prototype structure is hidden from web content. The | 325 // Note: Much of this prototype structure is hidden from web content. The |
326 // outer, inner, and DOMWindow instance all appear to be the same | 326 // outer, inner, and DOMWindow instance all appear to be the same |
327 // JavaScript object. | 327 // JavaScript object. |
328 // | 328 // |
329 v8::Handle<v8::Object> innerGlobalObject = toInnerGlobalObject(m_context.new
Local(m_isolate)); | 329 v8::Handle<v8::Object> innerGlobalObject = toInnerGlobalObject(m_context.new
Local(m_isolate)); |
330 V8DOMWrapper::setNativeInfo(innerGlobalObject, &V8Window::info, window); | 330 V8DOMWrapper::setNativeInfo(innerGlobalObject, &V8DOMWindow::info, window); |
331 innerGlobalObject->SetPrototype(windowWrapper); | 331 innerGlobalObject->SetPrototype(windowWrapper); |
332 V8DOMWrapper::associateObjectWithWrapper(PassRefPtr<DOMWindow>(window), &V8W
indow::info, windowWrapper, m_isolate, WrapperConfiguration::Dependent); | 332 V8DOMWrapper::associateObjectWithWrapper(PassRefPtr<DOMWindow>(window), &V8D
OMWindow::info, windowWrapper, m_isolate, WrapperConfiguration::Dependent); |
333 DOMWrapperWorld::setInitializingWindow(false); | 333 DOMWrapperWorld::setInitializingWindow(false); |
334 return true; | 334 return true; |
335 } | 335 } |
336 | 336 |
337 void V8WindowShell::updateDocumentWrapper(v8::Handle<v8::Object> wrapper) | 337 void V8DOMWindowShell::updateDocumentWrapper(v8::Handle<v8::Object> wrapper) |
338 { | 338 { |
339 ASSERT(m_world->isMainWorld()); | 339 ASSERT(m_world->isMainWorld()); |
340 m_document.set(m_isolate, wrapper); | 340 m_document.set(m_isolate, wrapper); |
341 } | 341 } |
342 | 342 |
343 void V8WindowShell::updateDocumentProperty() | 343 void V8DOMWindowShell::updateDocumentProperty() |
344 { | 344 { |
345 if (!m_world->isMainWorld()) | 345 if (!m_world->isMainWorld()) |
346 return; | 346 return; |
347 | 347 |
348 v8::HandleScope handleScope(m_isolate); | 348 v8::HandleScope handleScope(m_isolate); |
349 v8::Handle<v8::Context> context = m_context.newLocal(m_isolate); | 349 v8::Handle<v8::Context> context = m_context.newLocal(m_isolate); |
350 v8::Context::Scope contextScope(context); | 350 v8::Context::Scope contextScope(context); |
351 | 351 |
352 v8::Handle<v8::Value> documentWrapper = toV8(m_frame->document(), v8::Handle
<v8::Object>(), context->GetIsolate()); | 352 v8::Handle<v8::Value> documentWrapper = toV8(m_frame->document(), v8::Handle
<v8::Object>(), context->GetIsolate()); |
353 ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmp
ty()); | 353 ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmp
ty()); |
354 if (m_document.isEmpty()) | 354 if (m_document.isEmpty()) |
355 updateDocumentWrapper(v8::Handle<v8::Object>::Cast(documentWrapper)); | 355 updateDocumentWrapper(v8::Handle<v8::Object>::Cast(documentWrapper)); |
356 checkDocumentWrapper(m_document.newLocal(m_isolate), m_frame->document()); | 356 checkDocumentWrapper(m_document.newLocal(m_isolate), m_frame->document()); |
357 | 357 |
358 // If instantiation of the document wrapper fails, clear the cache | 358 // If instantiation of the document wrapper fails, clear the cache |
359 // and let the DOMWindow accessor handle access to the document. | 359 // and let the DOMWindow accessor handle access to the document. |
360 if (documentWrapper.IsEmpty()) { | 360 if (documentWrapper.IsEmpty()) { |
361 clearDocumentProperty(); | 361 clearDocumentProperty(); |
362 return; | 362 return; |
363 } | 363 } |
364 ASSERT(documentWrapper->IsObject()); | 364 ASSERT(documentWrapper->IsObject()); |
365 context->Global()->ForceSet(v8::String::NewSymbol("document"), documentWrapp
er, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)); | 365 context->Global()->ForceSet(v8::String::NewSymbol("document"), documentWrapp
er, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)); |
366 | 366 |
367 // We also stash a reference to the document on the inner global object so t
hat | 367 // We also stash a reference to the document on the inner global object so t
hat |
368 // DOMWindow objects we obtain from JavaScript references are guaranteed to
have | 368 // DOMWindow objects we obtain from JavaScript references are guaranteed to
have |
369 // live Document objects. | 369 // live Document objects. |
370 toInnerGlobalObject(context)->SetHiddenValue(V8HiddenPropertyName::document(
), documentWrapper); | 370 toInnerGlobalObject(context)->SetHiddenValue(V8HiddenPropertyName::document(
), documentWrapper); |
371 } | 371 } |
372 | 372 |
373 void V8WindowShell::clearDocumentProperty() | 373 void V8DOMWindowShell::clearDocumentProperty() |
374 { | 374 { |
375 ASSERT(!m_context.isEmpty()); | 375 ASSERT(!m_context.isEmpty()); |
376 if (!m_world->isMainWorld()) | 376 if (!m_world->isMainWorld()) |
377 return; | 377 return; |
378 v8::HandleScope handleScope(m_isolate); | 378 v8::HandleScope handleScope(m_isolate); |
379 m_context.newLocal(m_isolate)->Global()->ForceDelete(v8::String::NewSymbol("
document")); | 379 m_context.newLocal(m_isolate)->Global()->ForceDelete(v8::String::NewSymbol("
document")); |
380 } | 380 } |
381 | 381 |
382 void V8WindowShell::setSecurityToken() | 382 void V8DOMWindowShell::setSecurityToken() |
383 { | 383 { |
384 ASSERT(m_world->isMainWorld()); | 384 ASSERT(m_world->isMainWorld()); |
385 | 385 |
386 Document* document = m_frame->document(); | 386 Document* document = m_frame->document(); |
387 | 387 |
388 // Ask the document's SecurityOrigin to generate a security token. | 388 // Ask the document's SecurityOrigin to generate a security token. |
389 // If two tokens are equal, then the SecurityOrigins canAccess each other. | 389 // If two tokens are equal, then the SecurityOrigins canAccess each other. |
390 // If two tokens are not equal, then we have to call canAccess. | 390 // If two tokens are not equal, then we have to call canAccess. |
391 // Note: we can't use the HTTPOrigin if it was set from the DOM. | 391 // Note: we can't use the HTTPOrigin if it was set from the DOM. |
392 SecurityOrigin* origin = document->securityOrigin(); | 392 SecurityOrigin* origin = document->securityOrigin(); |
(...skipping 17 matching lines...) Expand all Loading... |
410 context->UseDefaultSecurityToken(); | 410 context->UseDefaultSecurityToken(); |
411 return; | 411 return; |
412 } | 412 } |
413 | 413 |
414 CString utf8Token = token.utf8(); | 414 CString utf8Token = token.utf8(); |
415 // NOTE: V8 does identity comparison in fast path, must use a symbol | 415 // NOTE: V8 does identity comparison in fast path, must use a symbol |
416 // as the security token. | 416 // as the security token. |
417 context->SetSecurityToken(v8::String::NewSymbol(utf8Token.data(), utf8Token.
length())); | 417 context->SetSecurityToken(v8::String::NewSymbol(utf8Token.data(), utf8Token.
length())); |
418 } | 418 } |
419 | 419 |
420 void V8WindowShell::updateDocument() | 420 void V8DOMWindowShell::updateDocument() |
421 { | 421 { |
422 ASSERT(m_world->isMainWorld()); | 422 ASSERT(m_world->isMainWorld()); |
423 if (m_global.isEmpty()) | 423 if (m_global.isEmpty()) |
424 return; | 424 return; |
425 if (m_context.isEmpty()) | 425 if (m_context.isEmpty()) |
426 return; | 426 return; |
427 updateDocumentProperty(); | 427 updateDocumentProperty(); |
428 updateSecurityOrigin(); | 428 updateSecurityOrigin(); |
429 } | 429 } |
430 | 430 |
(...skipping 27 matching lines...) Expand all Loading... |
458 v8SetReturnValue(info, result); | 458 v8SetReturnValue(info, result); |
459 return; | 459 return; |
460 } | 460 } |
461 v8::Handle<v8::Value> prototype = info.Holder()->GetPrototype(); | 461 v8::Handle<v8::Value> prototype = info.Holder()->GetPrototype(); |
462 if (prototype->IsObject()) { | 462 if (prototype->IsObject()) { |
463 v8SetReturnValue(info, prototype.As<v8::Object>()->Get(property)); | 463 v8SetReturnValue(info, prototype.As<v8::Object>()->Get(property)); |
464 return; | 464 return; |
465 } | 465 } |
466 } | 466 } |
467 | 467 |
468 void V8WindowShell::namedItemAdded(HTMLDocument* document, const AtomicString& n
ame) | 468 void V8DOMWindowShell::namedItemAdded(HTMLDocument* document, const AtomicString
& name) |
469 { | 469 { |
470 ASSERT(m_world->isMainWorld()); | 470 ASSERT(m_world->isMainWorld()); |
471 | 471 |
472 if (m_context.isEmpty()) | 472 if (m_context.isEmpty()) |
473 return; | 473 return; |
474 | 474 |
475 v8::HandleScope handleScope(m_isolate); | 475 v8::HandleScope handleScope(m_isolate); |
476 v8::Context::Scope contextScope(m_context.get()); | 476 v8::Context::Scope contextScope(m_context.get()); |
477 | 477 |
478 ASSERT(!m_document.isEmpty()); | 478 ASSERT(!m_document.isEmpty()); |
479 v8::Handle<v8::Object> documentHandle = m_document.newLocal(m_isolate); | 479 v8::Handle<v8::Object> documentHandle = m_document.newLocal(m_isolate); |
480 checkDocumentWrapper(documentHandle, document); | 480 checkDocumentWrapper(documentHandle, document); |
481 documentHandle->SetAccessor(v8String(name, m_isolate), getter); | 481 documentHandle->SetAccessor(v8String(name, m_isolate), getter); |
482 } | 482 } |
483 | 483 |
484 void V8WindowShell::namedItemRemoved(HTMLDocument* document, const AtomicString&
name) | 484 void V8DOMWindowShell::namedItemRemoved(HTMLDocument* document, const AtomicStri
ng& name) |
485 { | 485 { |
486 ASSERT(m_world->isMainWorld()); | 486 ASSERT(m_world->isMainWorld()); |
487 | 487 |
488 if (m_context.isEmpty()) | 488 if (m_context.isEmpty()) |
489 return; | 489 return; |
490 | 490 |
491 if (document->hasNamedItem(name.impl()) || document->hasExtraNamedItem(name.
impl())) | 491 if (document->hasNamedItem(name.impl()) || document->hasExtraNamedItem(name.
impl())) |
492 return; | 492 return; |
493 | 493 |
494 v8::HandleScope handleScope(m_isolate); | 494 v8::HandleScope handleScope(m_isolate); |
495 v8::Context::Scope contextScope(m_context.get()); | 495 v8::Context::Scope contextScope(m_context.get()); |
496 | 496 |
497 ASSERT(!m_document.isEmpty()); | 497 ASSERT(!m_document.isEmpty()); |
498 v8::Handle<v8::Object> documentHandle = m_document.newLocal(m_isolate); | 498 v8::Handle<v8::Object> documentHandle = m_document.newLocal(m_isolate); |
499 checkDocumentWrapper(documentHandle, document); | 499 checkDocumentWrapper(documentHandle, document); |
500 documentHandle->Delete(v8String(name, m_isolate)); | 500 documentHandle->Delete(v8String(name, m_isolate)); |
501 } | 501 } |
502 | 502 |
503 void V8WindowShell::updateSecurityOrigin() | 503 void V8DOMWindowShell::updateSecurityOrigin() |
504 { | 504 { |
505 ASSERT(m_world->isMainWorld()); | 505 ASSERT(m_world->isMainWorld()); |
506 if (m_context.isEmpty()) | 506 if (m_context.isEmpty()) |
507 return; | 507 return; |
508 v8::HandleScope handleScope; | 508 v8::HandleScope handleScope; |
509 setSecurityToken(); | 509 setSecurityToken(); |
510 } | 510 } |
511 | 511 |
512 } // WebCore | 512 } // WebCore |
OLD | NEW |