| 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 |