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 12 matching lines...) Expand all Loading... |
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 "bindings/core/v8/WindowProxy.h" | 31 #include "bindings/core/v8/WindowProxy.h" |
32 | 32 |
33 #include "bindings/core/v8/ConditionalFeatures.h" | |
34 #include "bindings/core/v8/DOMWrapperWorld.h" | |
35 #include "bindings/core/v8/ScriptController.h" | |
36 #include "bindings/core/v8/ToV8.h" | |
37 #include "bindings/core/v8/V8Binding.h" | 33 #include "bindings/core/v8/V8Binding.h" |
38 #include "bindings/core/v8/V8DOMActivityLogger.h" | 34 #include "bindings/core/v8/V8DOMWrapper.h" |
39 #include "bindings/core/v8/V8Document.h" | |
40 #include "bindings/core/v8/V8GCForContextDispose.h" | 35 #include "bindings/core/v8/V8GCForContextDispose.h" |
41 #include "bindings/core/v8/V8HTMLCollection.h" | |
42 #include "bindings/core/v8/V8HTMLDocument.h" | |
43 #include "bindings/core/v8/V8HiddenValue.h" | |
44 #include "bindings/core/v8/V8Initializer.h" | |
45 #include "bindings/core/v8/V8ObjectConstructor.h" | |
46 #include "bindings/core/v8/V8PagePopupControllerBinding.h" | 36 #include "bindings/core/v8/V8PagePopupControllerBinding.h" |
47 #include "bindings/core/v8/V8PrivateProperty.h" | 37 #include "core/frame/DOMWindow.h" |
48 #include "bindings/core/v8/V8Window.h" | 38 #include "core/frame/Frame.h" |
49 #include "core/frame/LocalFrame.h" | |
50 #include "core/frame/csp/ContentSecurityPolicy.h" | |
51 #include "core/html/DocumentNameCollection.h" | |
52 #include "core/html/HTMLCollection.h" | |
53 #include "core/html/HTMLIFrameElement.h" | |
54 #include "core/inspector/InspectorInstrumentation.h" | |
55 #include "core/inspector/MainThreadDebugger.h" | |
56 #include "core/loader/DocumentLoader.h" | |
57 #include "core/loader/FrameLoader.h" | |
58 #include "core/loader/FrameLoaderClient.h" | |
59 #include "core/origin_trials/OriginTrialContext.h" | |
60 #include "platform/Histogram.h" | |
61 #include "platform/RuntimeEnabledFeatures.h" | |
62 #include "platform/ScriptForbiddenScope.h" | |
63 #include "platform/heap/Handle.h" | |
64 #include "platform/instrumentation/tracing/TraceEvent.h" | |
65 #include "platform/weborigin/SecurityOrigin.h" | |
66 #include "public/platform/Platform.h" | |
67 #include "wtf/Assertions.h" | 39 #include "wtf/Assertions.h" |
68 #include "wtf/StringExtras.h" | |
69 #include "wtf/text/CString.h" | |
70 #include <algorithm> | |
71 #include <utility> | 40 #include <utility> |
72 #include <v8-debug.h> | |
73 #include <v8.h> | 41 #include <v8.h> |
74 | 42 |
75 namespace blink { | 43 namespace blink { |
76 | 44 |
77 WindowProxy* WindowProxy::create(v8::Isolate* isolate, | |
78 Frame* frame, | |
79 DOMWrapperWorld& world) { | |
80 return new WindowProxy(frame, &world, isolate); | |
81 } | |
82 | |
83 WindowProxy::WindowProxy(Frame* frame, | |
84 PassRefPtr<DOMWrapperWorld> world, | |
85 v8::Isolate* isolate) | |
86 : m_frame(frame), | |
87 m_isolate(isolate), | |
88 m_world(world), | |
89 m_lifecycle(Lifecycle::ContextUninitialized) {} | |
90 | |
91 WindowProxy::~WindowProxy() { | 45 WindowProxy::~WindowProxy() { |
92 // clearForClose() or clearForNavigation() must be invoked before destruction | 46 // clearForClose() or clearForNavigation() must be invoked before destruction |
93 // starts. | 47 // starts. |
94 DCHECK(m_lifecycle != Lifecycle::ContextInitialized); | 48 DCHECK(m_lifecycle != Lifecycle::ContextInitialized); |
95 } | 49 } |
96 | 50 |
97 DEFINE_TRACE(WindowProxy) { | 51 DEFINE_TRACE(WindowProxy) { |
98 visitor->trace(m_frame); | 52 visitor->trace(m_frame); |
99 } | 53 } |
100 | 54 |
| 55 WindowProxy::WindowProxy(v8::Isolate* isolate, |
| 56 Frame& frame, |
| 57 RefPtr<DOMWrapperWorld> world) |
| 58 : m_isolate(isolate), |
| 59 m_frame(frame), |
| 60 |
| 61 m_world(std::move(world)), |
| 62 m_lifecycle(Lifecycle::ContextUninitialized) {} |
| 63 |
101 void WindowProxy::disposeContext(GlobalDetachmentBehavior behavior) { | 64 void WindowProxy::disposeContext(GlobalDetachmentBehavior behavior) { |
102 if (m_lifecycle != Lifecycle::ContextInitialized) | 65 DCHECK(m_lifecycle == Lifecycle::ContextInitialized); |
103 return; | |
104 | |
105 ScriptState::Scope scope(m_scriptState.get()); | |
106 v8::Local<v8::Context> context = m_scriptState->context(); | |
107 if (m_frame->isLocalFrame()) { | |
108 LocalFrame* frame = toLocalFrame(m_frame); | |
109 // The embedder could run arbitrary code in response to the | |
110 // willReleaseScriptContext callback, so all disposing should happen after | |
111 // it returns. | |
112 frame->loader().client()->willReleaseScriptContext(context, | |
113 m_world->worldId()); | |
114 MainThreadDebugger::instance()->contextWillBeDestroyed(m_scriptState.get()); | |
115 } | |
116 | 66 |
117 if (behavior == DetachGlobal) { | 67 if (behavior == DetachGlobal) { |
| 68 v8::Local<v8::Context> context = m_scriptState->context(); |
118 // Clean up state on the global proxy, which will be reused. | 69 // Clean up state on the global proxy, which will be reused. |
119 if (!m_globalProxy.isEmpty()) { | 70 if (!m_globalProxy.isEmpty()) { |
120 // TODO(yukishiino): This DCHECK failed on Canary (M57) and Dev (M56). | 71 // TODO(yukishiino): This DCHECK failed on Canary (M57) and Dev (M56). |
121 // We need to figure out why m_globalProxy != context->Global(). | 72 // We need to figure out why m_globalProxy != context->Global(). |
122 DCHECK(m_globalProxy == context->Global()); | 73 DCHECK(m_globalProxy == context->Global()); |
123 DCHECK_EQ(toScriptWrappable(context->Global()), | 74 DCHECK_EQ(toScriptWrappable(context->Global()), |
124 toScriptWrappable( | 75 toScriptWrappable( |
125 context->Global()->GetPrototype().As<v8::Object>())); | 76 context->Global()->GetPrototype().As<v8::Object>())); |
126 m_globalProxy.get().SetWrapperClassId(0); | 77 m_globalProxy.get().SetWrapperClassId(0); |
127 } | 78 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 // When a frame navigates to a new page, the inner window is cut off | 166 // When a frame navigates to a new page, the inner window is cut off |
216 // the outer window, and the outer window identify is preserved for | 167 // the outer window, and the outer window identify is preserved for |
217 // the frame. However, a new inner window is created for the new page. | 168 // the frame. However, a new inner window is created for the new page. |
218 // If there are JS code holds a closure to the old inner window, | 169 // If there are JS code holds a closure to the old inner window, |
219 // it won't be able to reach the outer window via its global object. | 170 // it won't be able to reach the outer window via its global object. |
220 void WindowProxy::initializeIfNeeded() { | 171 void WindowProxy::initializeIfNeeded() { |
221 // TODO(haraken): It is wrong to re-initialize an already detached window | 172 // TODO(haraken): It is wrong to re-initialize an already detached window |
222 // proxy. This must be 'if(m_lifecycle == Lifecycle::ContextUninitialized)'. | 173 // proxy. This must be 'if(m_lifecycle == Lifecycle::ContextUninitialized)'. |
223 if (m_lifecycle != Lifecycle::ContextInitialized) { | 174 if (m_lifecycle != Lifecycle::ContextInitialized) { |
224 initialize(); | 175 initialize(); |
225 if (m_world->isMainWorld() && m_frame->isLocalFrame()) | |
226 toLocalFrame(m_frame)->loader().dispatchDidClearWindowObjectInMainWorld(); | |
227 } | 176 } |
228 } | 177 } |
229 | 178 |
230 void WindowProxy::initialize() { | |
231 TRACE_EVENT1("v8", "WindowProxy::initialize", "isMainWindow", | |
232 m_frame->isMainFrame()); | |
233 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( | |
234 m_frame->isMainFrame() ? "Blink.Binding.InitializeMainWindowProxy" | |
235 : "Blink.Binding.InitializeNonMainWindowProxy"); | |
236 | |
237 ScriptForbiddenScope::AllowUserAgentScript allowScript; | |
238 | |
239 v8::HandleScope handleScope(m_isolate); | |
240 | |
241 createContext(); | |
242 | |
243 ScriptState::Scope scope(m_scriptState.get()); | |
244 v8::Local<v8::Context> context = m_scriptState->context(); | |
245 if (m_globalProxy.isEmpty()) { | |
246 m_globalProxy.set(m_isolate, context->Global()); | |
247 CHECK(!m_globalProxy.isEmpty()); | |
248 } | |
249 | |
250 setupWindowPrototypeChain(); | |
251 | |
252 SecurityOrigin* origin = 0; | |
253 if (m_world->isMainWorld()) { | |
254 // ActivityLogger for main world is updated within updateDocument(). | |
255 updateDocument(); | |
256 origin = m_frame->securityContext()->getSecurityOrigin(); | |
257 // FIXME: Can this be removed when CSP moves to browser? | |
258 ContentSecurityPolicy* csp = | |
259 m_frame->securityContext()->contentSecurityPolicy(); | |
260 context->AllowCodeGenerationFromStrings( | |
261 csp->allowEval(0, ContentSecurityPolicy::SuppressReport)); | |
262 context->SetErrorMessageForCodeGenerationFromStrings( | |
263 v8String(m_isolate, csp->evalDisabledErrorMessage())); | |
264 } else { | |
265 updateActivityLogger(); | |
266 origin = m_world->isolatedWorldSecurityOrigin(); | |
267 setSecurityToken(origin); | |
268 } | |
269 | |
270 if (m_frame->isLocalFrame()) { | |
271 LocalFrame* frame = toLocalFrame(m_frame); | |
272 MainThreadDebugger::instance()->contextCreated(m_scriptState.get(), frame, | |
273 origin); | |
274 frame->loader().client()->didCreateScriptContext( | |
275 context, m_world->extensionGroup(), m_world->worldId()); | |
276 } | |
277 // If conditional features for window have been queued before the V8 context | |
278 // was ready, then inject them into the context now | |
279 if (m_world->isMainWorld()) { | |
280 installPendingConditionalFeaturesOnWindow(m_scriptState.get()); | |
281 } | |
282 } | |
283 | |
284 void WindowProxy::createContext() { | |
285 // Create a new v8::Context with the window object as the global object | |
286 // (aka the inner global). Reuse the global proxy object (aka the outer | |
287 // global) if it already exists. See the comments in | |
288 // setupWindowPrototypeChain for the structure of the prototype chain of | |
289 // the global object. | |
290 v8::Local<v8::ObjectTemplate> globalTemplate = | |
291 V8Window::domTemplate(m_isolate, *m_world)->InstanceTemplate(); | |
292 CHECK(!globalTemplate.IsEmpty()); | |
293 | |
294 // FIXME: It's not clear what the right thing to do for remote frames is. | |
295 // The extensions registered don't generally seem to make sense for remote | |
296 // frames, so skip it for now. | |
297 Vector<const char*> extensionNames; | |
298 if (m_frame->isLocalFrame()) { | |
299 LocalFrame* frame = toLocalFrame(m_frame); | |
300 // Dynamically tell v8 about our extensions now. | |
301 const V8Extensions& extensions = ScriptController::registeredExtensions(); | |
302 extensionNames.reserveInitialCapacity(extensions.size()); | |
303 int extensionGroup = m_world->extensionGroup(); | |
304 int worldId = m_world->worldId(); | |
305 for (const auto* extension : extensions) { | |
306 if (!frame->loader().client()->allowScriptExtension( | |
307 extension->name(), extensionGroup, worldId)) | |
308 continue; | |
309 | |
310 extensionNames.push_back(extension->name()); | |
311 } | |
312 } | |
313 v8::ExtensionConfiguration extensionConfiguration(extensionNames.size(), | |
314 extensionNames.data()); | |
315 | |
316 v8::Local<v8::Context> context; | |
317 { | |
318 V8PerIsolateData::UseCounterDisabledScope useCounterDisabled( | |
319 V8PerIsolateData::from(m_isolate)); | |
320 context = | |
321 v8::Context::New(m_isolate, &extensionConfiguration, globalTemplate, | |
322 m_globalProxy.newLocal(m_isolate)); | |
323 } | |
324 CHECK(!context.IsEmpty()); | |
325 | |
326 m_scriptState = ScriptState::create(context, m_world); | |
327 | |
328 // TODO(haraken): Currently we cannot enable the following DCHECK because | |
329 // an already detached window proxy can be re-initialized. This is wrong. | |
330 // DCHECK(m_lifecycle == Lifecycle::ContextUninitialized); | |
331 m_lifecycle = Lifecycle::ContextInitialized; | |
332 DCHECK(m_scriptState->contextIsValid()); | |
333 } | |
334 | |
335 void WindowProxy::setupWindowPrototypeChain() { | 179 void WindowProxy::setupWindowPrototypeChain() { |
336 // Associate the window wrapper object and its prototype chain with the | 180 // Associate the window wrapper object and its prototype chain with the |
337 // corresponding native DOMWindow object. | 181 // corresponding native DOMWindow object. |
338 // The full structure of the global object's prototype chain is as follows: | 182 // The full structure of the global object's prototype chain is as follows: |
339 // | 183 // |
340 // global proxy object [1] | 184 // global proxy object [1] |
341 // -- has prototype --> global object (window wrapper object) [2] | 185 // -- has prototype --> global object (window wrapper object) [2] |
342 // -- has prototype --> Window.prototype | 186 // -- has prototype --> Window.prototype |
343 // -- has prototype --> WindowProperties [3] | 187 // -- has prototype --> WindowProperties [3] |
344 // -- has prototype --> EventTarget.prototype | 188 // -- has prototype --> EventTarget.prototype |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 CHECK(!windowProperties.IsEmpty()); | 236 CHECK(!windowProperties.IsEmpty()); |
393 V8DOMWrapper::setNativeInfo(m_isolate, windowProperties, wrapperTypeInfo, | 237 V8DOMWrapper::setNativeInfo(m_isolate, windowProperties, wrapperTypeInfo, |
394 window); | 238 window); |
395 | 239 |
396 // TODO(keishi): Remove installPagePopupController and implement | 240 // TODO(keishi): Remove installPagePopupController and implement |
397 // PagePopupController in another way. | 241 // PagePopupController in another way. |
398 V8PagePopupControllerBinding::installPagePopupController(context, | 242 V8PagePopupControllerBinding::installPagePopupController(context, |
399 windowWrapper); | 243 windowWrapper); |
400 } | 244 } |
401 | 245 |
402 void WindowProxy::updateDocumentProperty() { | |
403 DCHECK(m_world->isMainWorld()); | |
404 | |
405 if (m_frame->isRemoteFrame()) | |
406 return; | |
407 | |
408 ScriptState::Scope scope(m_scriptState.get()); | |
409 v8::Local<v8::Context> context = m_scriptState->context(); | |
410 LocalFrame* frame = toLocalFrame(m_frame); | |
411 v8::Local<v8::Value> documentWrapper = | |
412 ToV8(frame->document(), context->Global(), m_isolate); | |
413 DCHECK(documentWrapper->IsObject()); | |
414 // Update the cached accessor for window.document. | |
415 CHECK(V8PrivateProperty::getWindowDocumentCachedAccessor(m_isolate).set( | |
416 context, context->Global(), documentWrapper)); | |
417 } | |
418 | |
419 void WindowProxy::updateActivityLogger() { | |
420 m_scriptState->perContextData()->setActivityLogger( | |
421 V8DOMActivityLogger::activityLogger( | |
422 m_world->worldId(), | |
423 m_frame->isLocalFrame() && toLocalFrame(m_frame)->document() | |
424 ? toLocalFrame(m_frame)->document()->baseURI() | |
425 : KURL())); | |
426 } | |
427 | |
428 void WindowProxy::setSecurityToken(SecurityOrigin* origin) { | |
429 // If two tokens are equal, then the SecurityOrigins canAccess each other. | |
430 // If two tokens are not equal, then we have to call canAccess. | |
431 // Note: we can't use the HTTPOrigin if it was set from the DOM. | |
432 String token; | |
433 // There are two situations where v8 needs to do a full canAccess check, | |
434 // so set an empty security token instead: | |
435 // - document.domain was modified | |
436 // - the frame is remote | |
437 bool delaySet = m_frame->isRemoteFrame() || | |
438 (m_world->isMainWorld() && origin->domainWasSetInDOM()); | |
439 if (origin && !delaySet) | |
440 token = origin->toString(); | |
441 | |
442 // An empty or "null" token means we always have to call | |
443 // canAccess. The toString method on securityOrigins returns the | |
444 // string "null" for empty security origins and for security | |
445 // origins that should only allow access to themselves. In this | |
446 // case, we use the global object as the security token to avoid | |
447 // calling canAccess when a script accesses its own objects. | |
448 v8::HandleScope handleScope(m_isolate); | |
449 v8::Local<v8::Context> context = m_scriptState->context(); | |
450 if (token.isEmpty() || token == "null") { | |
451 context->UseDefaultSecurityToken(); | |
452 return; | |
453 } | |
454 | |
455 if (m_world->isIsolatedWorld()) { | |
456 SecurityOrigin* frameSecurityOrigin = | |
457 m_frame->securityContext()->getSecurityOrigin(); | |
458 String frameSecurityToken = frameSecurityOrigin->toString(); | |
459 // We need to check the return value of domainWasSetInDOM() on the | |
460 // frame's SecurityOrigin because, if that's the case, only | |
461 // SecurityOrigin::m_domain would have been modified. | |
462 // m_domain is not used by SecurityOrigin::toString(), so we would end | |
463 // up generating the same token that was already set. | |
464 if (frameSecurityOrigin->domainWasSetInDOM() || | |
465 frameSecurityToken.isEmpty() || frameSecurityToken == "null") { | |
466 context->UseDefaultSecurityToken(); | |
467 return; | |
468 } | |
469 token = frameSecurityToken + token; | |
470 } | |
471 | |
472 // NOTE: V8 does identity comparison in fast path, must use a symbol | |
473 // as the security token. | |
474 context->SetSecurityToken(v8AtomicString(m_isolate, token)); | |
475 } | |
476 | |
477 void WindowProxy::updateDocument() { | |
478 DCHECK(m_world->isMainWorld()); | |
479 // For an uninitialized main window proxy, there's nothing we need | |
480 // to update. The update is done when the window proxy gets initialized later. | |
481 if (m_lifecycle == Lifecycle::ContextUninitialized) | |
482 return; | |
483 // TODO(yukishiino): Is it okay to not update document when the context | |
484 // is detached? It's not trivial to fix this because udpateDocumentProperty | |
485 // requires a not-yet-detached context to instantiate a document wrapper. | |
486 if (m_lifecycle == Lifecycle::ContextDetached) | |
487 return; | |
488 | |
489 updateActivityLogger(); | |
490 updateDocumentProperty(); | |
491 updateSecurityOrigin(m_frame->securityContext()->getSecurityOrigin()); | |
492 } | |
493 | |
494 static v8::Local<v8::Value> getNamedProperty( | |
495 HTMLDocument* htmlDocument, | |
496 const AtomicString& key, | |
497 v8::Local<v8::Object> creationContext, | |
498 v8::Isolate* isolate) { | |
499 if (!htmlDocument->hasNamedItem(key) && !htmlDocument->hasExtraNamedItem(key)) | |
500 return v8Undefined(); | |
501 | |
502 DocumentNameCollection* items = htmlDocument->documentNamedItems(key); | |
503 if (items->isEmpty()) | |
504 return v8Undefined(); | |
505 | |
506 if (items->hasExactlyOneItem()) { | |
507 HTMLElement* element = items->item(0); | |
508 ASSERT(element); | |
509 Frame* frame = isHTMLIFrameElement(*element) | |
510 ? toHTMLIFrameElement(*element).contentFrame() | |
511 : 0; | |
512 if (frame) | |
513 return ToV8(frame->domWindow(), creationContext, isolate); | |
514 return ToV8(element, creationContext, isolate); | |
515 } | |
516 return ToV8(items, creationContext, isolate); | |
517 } | |
518 | |
519 static void getter(v8::Local<v8::Name> property, | |
520 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
521 if (!property->IsString()) | |
522 return; | |
523 // FIXME: Consider passing StringImpl directly. | |
524 AtomicString name = toCoreAtomicString(property.As<v8::String>()); | |
525 HTMLDocument* htmlDocument = V8HTMLDocument::toImpl(info.Holder()); | |
526 ASSERT(htmlDocument); | |
527 v8::Local<v8::Value> result = | |
528 getNamedProperty(htmlDocument, name, info.Holder(), info.GetIsolate()); | |
529 if (!result.IsEmpty()) { | |
530 v8SetReturnValue(info, result); | |
531 return; | |
532 } | |
533 v8::Local<v8::Value> value; | |
534 if (info.Holder() | |
535 ->GetRealNamedPropertyInPrototypeChain( | |
536 info.GetIsolate()->GetCurrentContext(), property.As<v8::String>()) | |
537 .ToLocal(&value)) | |
538 v8SetReturnValue(info, value); | |
539 } | |
540 | |
541 void WindowProxy::namedItemAdded(HTMLDocument* document, | |
542 const AtomicString& name) { | |
543 DCHECK(m_world->isMainWorld()); | |
544 | |
545 // Context must be initialized before this point. | |
546 DCHECK(m_lifecycle >= Lifecycle::ContextInitialized); | |
547 // TODO(yukishiino): Is it okay to not update named properties | |
548 // after the context gets detached? | |
549 if (m_lifecycle == Lifecycle::ContextDetached) | |
550 return; | |
551 | |
552 ScriptState::Scope scope(m_scriptState.get()); | |
553 v8::Local<v8::Object> documentWrapper = | |
554 m_world->domDataStore().get(document, m_isolate); | |
555 // TODO(yukishiino,peria): We should check if the own property with the same | |
556 // name already exists or not, and if it exists, we shouldn't define a new | |
557 // accessor property (it fails). | |
558 documentWrapper->SetAccessor(m_isolate->GetCurrentContext(), | |
559 v8String(m_isolate, name), getter); | |
560 } | |
561 | |
562 void WindowProxy::namedItemRemoved(HTMLDocument* document, | |
563 const AtomicString& name) { | |
564 DCHECK(m_world->isMainWorld()); | |
565 | |
566 // Context must be initialized before this point. | |
567 DCHECK(m_lifecycle >= Lifecycle::ContextInitialized); | |
568 // TODO(yukishiino): Is it okay to not update named properties | |
569 // after the context gets detached? | |
570 if (m_lifecycle == Lifecycle::ContextDetached) | |
571 return; | |
572 | |
573 if (document->hasNamedItem(name) || document->hasExtraNamedItem(name)) | |
574 return; | |
575 ScriptState::Scope scope(m_scriptState.get()); | |
576 v8::Local<v8::Object> documentWrapper = | |
577 m_world->domDataStore().get(document, m_isolate); | |
578 documentWrapper | |
579 ->Delete(m_isolate->GetCurrentContext(), v8String(m_isolate, name)) | |
580 .ToChecked(); | |
581 } | |
582 | |
583 void WindowProxy::updateSecurityOrigin(SecurityOrigin* origin) { | |
584 // For an uninitialized main window proxy, there's nothing we need | |
585 // to update. The update is done when the window proxy gets initialized later. | |
586 if (m_lifecycle == Lifecycle::ContextUninitialized) | |
587 return; | |
588 // TODO(yukishiino): Is it okay to not update security origin when the context | |
589 // is detached? | |
590 if (m_lifecycle == Lifecycle::ContextDetached) | |
591 return; | |
592 | |
593 setSecurityToken(origin); | |
594 } | |
595 | |
596 } // namespace blink | 246 } // namespace blink |
OLD | NEW |