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 |