| 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 #include "wtf/OwnPtr.h" | 63 #include "wtf/OwnPtr.h" |
| 64 #include "wtf/StringExtras.h" | 64 #include "wtf/StringExtras.h" |
| 65 #include "wtf/text/CString.h" | 65 #include "wtf/text/CString.h" |
| 66 #include <algorithm> | 66 #include <algorithm> |
| 67 #include <utility> | 67 #include <utility> |
| 68 #include <v8-debug.h> | 68 #include <v8-debug.h> |
| 69 #include <v8.h> | 69 #include <v8.h> |
| 70 | 70 |
| 71 namespace blink { | 71 namespace blink { |
| 72 | 72 |
| 73 static void checkDocumentWrapper(v8::Handle<v8::Object> wrapper, Document* docum
ent) | 73 static void checkDocumentWrapper(v8::Local<v8::Object> wrapper, Document* docume
nt) |
| 74 { | 74 { |
| 75 ASSERT(V8Document::toImpl(wrapper) == document); | 75 ASSERT(V8Document::toImpl(wrapper) == document); |
| 76 ASSERT(!document->isHTMLDocument() || (V8Document::toImpl(v8::Handle<v8::Obj
ect>::Cast(wrapper->GetPrototype())) == document)); | 76 ASSERT(!document->isHTMLDocument() || (V8Document::toImpl(v8::Local<v8::Obje
ct>::Cast(wrapper->GetPrototype())) == document)); |
| 77 } | 77 } |
| 78 | 78 |
| 79 PassOwnPtrWillBeRawPtr<WindowProxy> WindowProxy::create(Frame* frame, DOMWrapper
World& world, v8::Isolate* isolate) | 79 PassOwnPtrWillBeRawPtr<WindowProxy> WindowProxy::create(Frame* frame, DOMWrapper
World& world, v8::Isolate* isolate) |
| 80 { | 80 { |
| 81 return adoptPtrWillBeNoop(new WindowProxy(frame, &world, isolate)); | 81 return adoptPtrWillBeNoop(new WindowProxy(frame, &world, isolate)); |
| 82 } | 82 } |
| 83 | 83 |
| 84 WindowProxy::WindowProxy(Frame* frame, PassRefPtr<DOMWrapperWorld> world, v8::Is
olate* isolate) | 84 WindowProxy::WindowProxy(Frame* frame, PassRefPtr<DOMWrapperWorld> world, v8::Is
olate* isolate) |
| 85 : m_frame(frame) | 85 : m_frame(frame) |
| 86 , m_isolate(isolate) | 86 , m_isolate(isolate) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 98 { | 98 { |
| 99 visitor->trace(m_frame); | 99 visitor->trace(m_frame); |
| 100 } | 100 } |
| 101 | 101 |
| 102 void WindowProxy::disposeContext(GlobalDetachmentBehavior behavior) | 102 void WindowProxy::disposeContext(GlobalDetachmentBehavior behavior) |
| 103 { | 103 { |
| 104 if (!isContextInitialized()) | 104 if (!isContextInitialized()) |
| 105 return; | 105 return; |
| 106 | 106 |
| 107 v8::HandleScope handleScope(m_isolate); | 107 v8::HandleScope handleScope(m_isolate); |
| 108 v8::Handle<v8::Context> context = m_scriptState->context(); | 108 v8::Local<v8::Context> context = m_scriptState->context(); |
| 109 if (m_frame->isLocalFrame()) { | 109 if (m_frame->isLocalFrame()) { |
| 110 LocalFrame* frame = toLocalFrame(m_frame); | 110 LocalFrame* frame = toLocalFrame(m_frame); |
| 111 // The embedder could run arbitrary code in response to the willReleaseS
criptContext callback, so all disposing should happen after it returns. | 111 // The embedder could run arbitrary code in response to the willReleaseS
criptContext callback, so all disposing should happen after it returns. |
| 112 frame->loader().client()->willReleaseScriptContext(context, m_world->wor
ldId()); | 112 frame->loader().client()->willReleaseScriptContext(context, m_world->wor
ldId()); |
| 113 InspectorInstrumentation::willReleaseScriptContext(frame, m_scriptState.
get()); | 113 InspectorInstrumentation::willReleaseScriptContext(frame, m_scriptState.
get()); |
| 114 } | 114 } |
| 115 | 115 |
| 116 m_document.clear(); | 116 m_document.clear(); |
| 117 | 117 |
| 118 if (behavior == DetachGlobal) | 118 if (behavior == DetachGlobal) |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 ScriptForbiddenScope::AllowUserAgentScript allowScript; | 210 ScriptForbiddenScope::AllowUserAgentScript allowScript; |
| 211 | 211 |
| 212 v8::HandleScope handleScope(m_isolate); | 212 v8::HandleScope handleScope(m_isolate); |
| 213 | 213 |
| 214 createContext(); | 214 createContext(); |
| 215 | 215 |
| 216 if (!isContextInitialized()) | 216 if (!isContextInitialized()) |
| 217 return false; | 217 return false; |
| 218 | 218 |
| 219 ScriptState::Scope scope(m_scriptState.get()); | 219 ScriptState::Scope scope(m_scriptState.get()); |
| 220 v8::Handle<v8::Context> context = m_scriptState->context(); | 220 v8::Local<v8::Context> context = m_scriptState->context(); |
| 221 if (m_global.isEmpty()) { | 221 if (m_global.isEmpty()) { |
| 222 m_global.set(m_isolate, context->Global()); | 222 m_global.set(m_isolate, context->Global()); |
| 223 if (m_global.isEmpty()) { | 223 if (m_global.isEmpty()) { |
| 224 disposeContext(DoNotDetachGlobal); | 224 disposeContext(DoNotDetachGlobal); |
| 225 return false; | 225 return false; |
| 226 } | 226 } |
| 227 } | 227 } |
| 228 | 228 |
| 229 if (!installDOMWindow()) { | 229 if (!installDOMWindow()) { |
| 230 disposeContext(DoNotDetachGlobal); | 230 disposeContext(DoNotDetachGlobal); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 int worldId = m_world->worldId(); | 281 int worldId = m_world->worldId(); |
| 282 for (const auto* extension : extensions) { | 282 for (const auto* extension : extensions) { |
| 283 if (!frame->loader().client()->allowScriptExtension(extension->name(
), extensionGroup, worldId)) | 283 if (!frame->loader().client()->allowScriptExtension(extension->name(
), extensionGroup, worldId)) |
| 284 continue; | 284 continue; |
| 285 | 285 |
| 286 extensionNames.append(extension->name()); | 286 extensionNames.append(extension->name()); |
| 287 } | 287 } |
| 288 } | 288 } |
| 289 v8::ExtensionConfiguration extensionConfiguration(extensionNames.size(), ext
ensionNames.data()); | 289 v8::ExtensionConfiguration extensionConfiguration(extensionNames.size(), ext
ensionNames.data()); |
| 290 | 290 |
| 291 v8::Handle<v8::Context> context = v8::Context::New(m_isolate, &extensionConf
iguration, globalTemplate, m_global.newLocal(m_isolate)); | 291 v8::Local<v8::Context> context = v8::Context::New(m_isolate, &extensionConfi
guration, globalTemplate, m_global.newLocal(m_isolate)); |
| 292 if (context.IsEmpty()) | 292 if (context.IsEmpty()) |
| 293 return; | 293 return; |
| 294 m_scriptState = ScriptState::create(context, m_world); | 294 m_scriptState = ScriptState::create(context, m_world); |
| 295 | 295 |
| 296 double contextCreationDurationInMilliseconds = (currentTime() - contextCreat
ionStartInSeconds) * 1000; | 296 double contextCreationDurationInMilliseconds = (currentTime() - contextCreat
ionStartInSeconds) * 1000; |
| 297 const char* histogramName = "WebCore.WindowProxy.createContext.MainWorld"; | 297 const char* histogramName = "WebCore.WindowProxy.createContext.MainWorld"; |
| 298 if (!m_world->isMainWorld()) | 298 if (!m_world->isMainWorld()) |
| 299 histogramName = "WebCore.WindowProxy.createContext.IsolatedWorld"; | 299 histogramName = "WebCore.WindowProxy.createContext.IsolatedWorld"; |
| 300 blink::Platform::current()->histogramCustomCounts(histogramName, contextCrea
tionDurationInMilliseconds, 0, 10000, 50); | 300 blink::Platform::current()->histogramCustomCounts(histogramName, contextCrea
tionDurationInMilliseconds, 0, 10000, 50); |
| 301 } | 301 } |
| 302 | 302 |
| 303 static v8::Handle<v8::Object> toInnerGlobalObject(v8::Handle<v8::Context> contex
t) | 303 static v8::Local<v8::Object> toInnerGlobalObject(v8::Local<v8::Context> context) |
| 304 { | 304 { |
| 305 return v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype()); | 305 return v8::Local<v8::Object>::Cast(context->Global()->GetPrototype()); |
| 306 } | 306 } |
| 307 | 307 |
| 308 bool WindowProxy::installDOMWindow() | 308 bool WindowProxy::installDOMWindow() |
| 309 { | 309 { |
| 310 DOMWindow* window = m_frame->domWindow(); | 310 DOMWindow* window = m_frame->domWindow(); |
| 311 const WrapperTypeInfo* wrapperTypeInfo = window->wrapperTypeInfo(); | 311 const WrapperTypeInfo* wrapperTypeInfo = window->wrapperTypeInfo(); |
| 312 v8::Local<v8::Object> windowWrapper = V8ObjectConstructor::newInstance(m_iso
late, m_scriptState->perContextData()->constructorForType(wrapperTypeInfo)); | 312 v8::Local<v8::Object> windowWrapper = V8ObjectConstructor::newInstance(m_iso
late, m_scriptState->perContextData()->constructorForType(wrapperTypeInfo)); |
| 313 if (windowWrapper.IsEmpty()) | 313 if (windowWrapper.IsEmpty()) |
| 314 return false; | 314 return false; |
| 315 | 315 |
| 316 V8DOMWrapper::setNativeInfo(v8::Handle<v8::Object>::Cast(windowWrapper->GetP
rototype()), wrapperTypeInfo, window); | 316 V8DOMWrapper::setNativeInfo(v8::Local<v8::Object>::Cast(windowWrapper->GetPr
ototype()), wrapperTypeInfo, window); |
| 317 | 317 |
| 318 // Install the windowWrapper as the prototype of the innerGlobalObject. | 318 // Install the windowWrapper as the prototype of the innerGlobalObject. |
| 319 // The full structure of the global object is as follows: | 319 // The full structure of the global object is as follows: |
| 320 // | 320 // |
| 321 // outerGlobalObject (Empty object, remains after navigation) | 321 // outerGlobalObject (Empty object, remains after navigation) |
| 322 // -- has prototype --> innerGlobalObject (Holds global variables, changes
during navigation) | 322 // -- has prototype --> innerGlobalObject (Holds global variables, changes
during navigation) |
| 323 // -- has prototype --> DOMWindow instance | 323 // -- has prototype --> DOMWindow instance |
| 324 // -- has prototype --> Window.prototype | 324 // -- has prototype --> Window.prototype |
| 325 // -- has prototype --> Object.prototype | 325 // -- has prototype --> Object.prototype |
| 326 // | 326 // |
| 327 // Note: Much of this prototype structure is hidden from web content. The | 327 // Note: Much of this prototype structure is hidden from web content. The |
| 328 // outer, inner, and DOMWindow instance all appear to be the same | 328 // outer, inner, and DOMWindow instance all appear to be the same |
| 329 // JavaScript object. | 329 // JavaScript object. |
| 330 v8::Local<v8::Context> context = m_scriptState->context(); | 330 v8::Local<v8::Context> context = m_scriptState->context(); |
| 331 v8::Local<v8::Object> innerGlobalObject = toInnerGlobalObject(m_scriptState-
>context()); | 331 v8::Local<v8::Object> innerGlobalObject = toInnerGlobalObject(m_scriptState-
>context()); |
| 332 V8DOMWrapper::setNativeInfo(innerGlobalObject, wrapperTypeInfo, window); | 332 V8DOMWrapper::setNativeInfo(innerGlobalObject, wrapperTypeInfo, window); |
| 333 if (!v8CallBoolean(innerGlobalObject->SetPrototype(context, windowWrapper))) | 333 if (!v8CallBoolean(innerGlobalObject->SetPrototype(context, windowWrapper))) |
| 334 return false; | 334 return false; |
| 335 V8DOMWrapper::associateObjectWithWrapper(m_isolate, window, wrapperTypeInfo,
windowWrapper); | 335 V8DOMWrapper::associateObjectWithWrapper(m_isolate, window, wrapperTypeInfo,
windowWrapper); |
| 336 V8PagePopupControllerBinding::installPagePopupController(context, windowWrap
per); | 336 V8PagePopupControllerBinding::installPagePopupController(context, windowWrap
per); |
| 337 return true; | 337 return true; |
| 338 } | 338 } |
| 339 | 339 |
| 340 void WindowProxy::updateDocumentWrapper(v8::Handle<v8::Object> wrapper) | 340 void WindowProxy::updateDocumentWrapper(v8::Local<v8::Object> wrapper) |
| 341 { | 341 { |
| 342 ASSERT(m_world->isMainWorld()); | 342 ASSERT(m_world->isMainWorld()); |
| 343 m_document.set(m_isolate, wrapper); | 343 m_document.set(m_isolate, wrapper); |
| 344 } | 344 } |
| 345 | 345 |
| 346 void WindowProxy::updateDocumentProperty() | 346 void WindowProxy::updateDocumentProperty() |
| 347 { | 347 { |
| 348 if (!m_world->isMainWorld()) | 348 if (!m_world->isMainWorld()) |
| 349 return; | 349 return; |
| 350 | 350 |
| 351 if (m_frame->isRemoteFrame()) { | 351 if (m_frame->isRemoteFrame()) { |
| 352 return; | 352 return; |
| 353 } | 353 } |
| 354 | 354 |
| 355 ScriptState::Scope scope(m_scriptState.get()); | 355 ScriptState::Scope scope(m_scriptState.get()); |
| 356 v8::Handle<v8::Context> context = m_scriptState->context(); | 356 v8::Local<v8::Context> context = m_scriptState->context(); |
| 357 LocalFrame* frame = toLocalFrame(m_frame); | 357 LocalFrame* frame = toLocalFrame(m_frame); |
| 358 v8::Handle<v8::Value> documentWrapper = toV8(frame->document(), context->Glo
bal(), context->GetIsolate()); | 358 v8::Local<v8::Value> documentWrapper = toV8(frame->document(), context->Glob
al(), context->GetIsolate()); |
| 359 ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmp
ty()); | 359 ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmp
ty()); |
| 360 if (m_document.isEmpty()) | 360 if (m_document.isEmpty()) |
| 361 updateDocumentWrapper(v8::Handle<v8::Object>::Cast(documentWrapper)); | 361 updateDocumentWrapper(v8::Local<v8::Object>::Cast(documentWrapper)); |
| 362 checkDocumentWrapper(m_document.newLocal(m_isolate), frame->document()); | 362 checkDocumentWrapper(m_document.newLocal(m_isolate), frame->document()); |
| 363 | 363 |
| 364 ASSERT(documentWrapper->IsObject()); | 364 ASSERT(documentWrapper->IsObject()); |
| 365 if (!v8CallBoolean(context->Global()->ForceSet(context, v8AtomicString(m_iso
late, "document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadO
nly | v8::DontDelete)))) | 365 if (!v8CallBoolean(context->Global()->ForceSet(context, v8AtomicString(m_iso
late, "document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadO
nly | v8::DontDelete)))) |
| 366 return; | 366 return; |
| 367 | 367 |
| 368 // We also stash a reference to the document on the inner global object so t
hat | 368 // We also stash a reference to the document on the inner global object so t
hat |
| 369 // LocalDOMWindow objects we obtain from JavaScript references are guarantee
d to have | 369 // LocalDOMWindow objects we obtain from JavaScript references are guarantee
d to have |
| 370 // live Document objects. | 370 // live Document objects. |
| 371 V8HiddenValue::setHiddenValue(m_isolate, toInnerGlobalObject(context), V8Hid
denValue::document(m_isolate), documentWrapper); | 371 V8HiddenValue::setHiddenValue(m_isolate, toInnerGlobalObject(context), V8Hid
denValue::document(m_isolate), documentWrapper); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 395 if (origin && !delaySet) | 395 if (origin && !delaySet) |
| 396 token = origin->toString(); | 396 token = origin->toString(); |
| 397 | 397 |
| 398 // An empty or "null" token means we always have to call | 398 // An empty or "null" token means we always have to call |
| 399 // canAccess. The toString method on securityOrigins returns the | 399 // canAccess. The toString method on securityOrigins returns the |
| 400 // string "null" for empty security origins and for security | 400 // string "null" for empty security origins and for security |
| 401 // origins that should only allow access to themselves. In this | 401 // origins that should only allow access to themselves. In this |
| 402 // case, we use the global object as the security token to avoid | 402 // case, we use the global object as the security token to avoid |
| 403 // calling canAccess when a script accesses its own objects. | 403 // calling canAccess when a script accesses its own objects. |
| 404 v8::HandleScope handleScope(m_isolate); | 404 v8::HandleScope handleScope(m_isolate); |
| 405 v8::Handle<v8::Context> context = m_scriptState->context(); | 405 v8::Local<v8::Context> context = m_scriptState->context(); |
| 406 if (token.isEmpty() || token == "null") { | 406 if (token.isEmpty() || token == "null") { |
| 407 context->UseDefaultSecurityToken(); | 407 context->UseDefaultSecurityToken(); |
| 408 return; | 408 return; |
| 409 } | 409 } |
| 410 | 410 |
| 411 if (m_world->isPrivateScriptIsolatedWorld()) | 411 if (m_world->isPrivateScriptIsolatedWorld()) |
| 412 token = "private-script://" + token; | 412 token = "private-script://" + token; |
| 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(v8AtomicString(m_isolate, utf8Token.data(), utf8To
ken.length())); | 417 context->SetSecurityToken(v8AtomicString(m_isolate, utf8Token.data(), utf8To
ken.length())); |
| 418 } | 418 } |
| 419 | 419 |
| 420 void WindowProxy::updateDocument() | 420 void WindowProxy::updateDocument() |
| 421 { | 421 { |
| 422 ASSERT(m_world->isMainWorld()); | 422 ASSERT(m_world->isMainWorld()); |
| 423 if (!isGlobalInitialized()) | 423 if (!isGlobalInitialized()) |
| 424 return; | 424 return; |
| 425 if (!isContextInitialized()) | 425 if (!isContextInitialized()) |
| 426 return; | 426 return; |
| 427 updateActivityLogger(); | 427 updateActivityLogger(); |
| 428 updateDocumentProperty(); | 428 updateDocumentProperty(); |
| 429 updateSecurityOrigin(m_frame->securityContext()->securityOrigin()); | 429 updateSecurityOrigin(m_frame->securityContext()->securityOrigin()); |
| 430 } | 430 } |
| 431 | 431 |
| 432 static v8::Handle<v8::Value> getNamedProperty(HTMLDocument* htmlDocument, const
AtomicString& key, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) | 432 static v8::Local<v8::Value> getNamedProperty(HTMLDocument* htmlDocument, const A
tomicString& key, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) |
| 433 { | 433 { |
| 434 if (!htmlDocument->hasNamedItem(key) && !htmlDocument->hasExtraNamedItem(key
)) | 434 if (!htmlDocument->hasNamedItem(key) && !htmlDocument->hasExtraNamedItem(key
)) |
| 435 return v8Undefined(); | 435 return v8Undefined(); |
| 436 | 436 |
| 437 RefPtrWillBeRawPtr<DocumentNameCollection> items = htmlDocument->documentNam
edItems(key); | 437 RefPtrWillBeRawPtr<DocumentNameCollection> items = htmlDocument->documentNam
edItems(key); |
| 438 if (items->isEmpty()) | 438 if (items->isEmpty()) |
| 439 return v8Undefined(); | 439 return v8Undefined(); |
| 440 | 440 |
| 441 if (items->hasExactlyOneItem()) { | 441 if (items->hasExactlyOneItem()) { |
| 442 HTMLElement* element = items->item(0); | 442 HTMLElement* element = items->item(0); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 ASSERT(m_world->isMainWorld()); | 488 ASSERT(m_world->isMainWorld()); |
| 489 | 489 |
| 490 if (!isContextInitialized()) | 490 if (!isContextInitialized()) |
| 491 return; | 491 return; |
| 492 | 492 |
| 493 if (document->hasNamedItem(name) || document->hasExtraNamedItem(name)) | 493 if (document->hasNamedItem(name) || document->hasExtraNamedItem(name)) |
| 494 return; | 494 return; |
| 495 | 495 |
| 496 ScriptState::Scope scope(m_scriptState.get()); | 496 ScriptState::Scope scope(m_scriptState.get()); |
| 497 ASSERT(!m_document.isEmpty()); | 497 ASSERT(!m_document.isEmpty()); |
| 498 v8::Handle<v8::Object> documentHandle = m_document.newLocal(m_isolate); | 498 v8::Local<v8::Object> documentHandle = m_document.newLocal(m_isolate); |
| 499 checkDocumentWrapper(documentHandle, document); | 499 checkDocumentWrapper(documentHandle, document); |
| 500 documentHandle->Delete(m_isolate->GetCurrentContext(), v8String(m_isolate, n
ame)); | 500 documentHandle->Delete(m_isolate->GetCurrentContext(), v8String(m_isolate, n
ame)); |
| 501 } | 501 } |
| 502 | 502 |
| 503 void WindowProxy::updateSecurityOrigin(SecurityOrigin* origin) | 503 void WindowProxy::updateSecurityOrigin(SecurityOrigin* origin) |
| 504 { | 504 { |
| 505 ASSERT(m_world->isMainWorld()); | 505 ASSERT(m_world->isMainWorld()); |
| 506 if (!isContextInitialized()) | 506 if (!isContextInitialized()) |
| 507 return; | 507 return; |
| 508 setSecurityToken(origin); | 508 setSecurityToken(origin); |
| 509 } | 509 } |
| 510 | 510 |
| 511 } // namespace blink | 511 } // namespace blink |
| OLD | NEW |