Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / v8 / custom / V8WindowCustom.cpp
1 /*
2  * Copyright (C) 2009, 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
29  */
30
31 #include "config.h"
32 #include "bindings/core/v8/V8Window.h"
33
34 #include "bindings/core/v8/V8HTMLCollection.h"
35 #include "bindings/core/v8/V8Node.h"
36 #include "bindings/v8/BindingSecurity.h"
37 #include "bindings/v8/ExceptionMessages.h"
38 #include "bindings/v8/ExceptionState.h"
39 #include "bindings/v8/ScheduledAction.h"
40 #include "bindings/v8/ScriptController.h"
41 #include "bindings/v8/ScriptSourceCode.h"
42 #include "bindings/v8/SerializedScriptValue.h"
43 #include "bindings/v8/V8Binding.h"
44 #include "bindings/v8/V8EventListener.h"
45 #include "bindings/v8/V8EventListenerList.h"
46 #include "bindings/v8/V8GCForContextDispose.h"
47 #include "bindings/v8/V8HiddenValue.h"
48 #include "core/dom/ExceptionCode.h"
49 #include "core/dom/MessagePort.h"
50 #include "core/html/HTMLCollection.h"
51 #include "core/html/HTMLDocument.h"
52 #include "core/inspector/ScriptCallStack.h"
53 #include "core/loader/FrameLoadRequest.h"
54 #include "core/loader/FrameLoader.h"
55 #include "core/frame/DOMTimer.h"
56 #include "core/frame/LocalDOMWindow.h"
57 #include "core/frame/DOMWindowTimers.h"
58 #include "core/frame/FrameView.h"
59 #include "core/frame/LocalFrame.h"
60 #include "core/frame/Settings.h"
61 #include "core/frame/csp/ContentSecurityPolicy.h"
62 #include "core/storage/Storage.h"
63 #include "platform/PlatformScreen.h"
64 #include "platform/graphics/media/MediaPlayer.h"
65 #include "wtf/ArrayBuffer.h"
66 #include "wtf/Assertions.h"
67 #include "wtf/OwnPtr.h"
68
69 namespace WebCore {
70
71 // FIXME: There is a lot of duplication with SetTimeoutOrInterval() in V8WorkerGlobalScopeCustom.cpp.
72 // We should refactor this.
73 static void windowSetTimeoutImpl(const v8::FunctionCallbackInfo<v8::Value>& info, bool singleShot, ExceptionState& exceptionState)
74 {
75     int argumentCount = info.Length();
76
77     if (argumentCount < 1)
78         return;
79
80     LocalDOMWindow* impl = V8Window::toNative(info.Holder());
81     if (!impl->frame() || !impl->document()) {
82         exceptionState.throwDOMException(InvalidAccessError, "No script context is available in which to execute the script.");
83         return;
84     }
85     ScriptState* scriptState = ScriptState::current(info.GetIsolate());
86     v8::Handle<v8::Value> function = info[0];
87     String functionString;
88     if (!function->IsFunction()) {
89         if (function->IsString()) {
90             functionString = toCoreString(function.As<v8::String>());
91         } else {
92             v8::Handle<v8::String> v8String = function->ToString();
93
94             // Bail out if string conversion failed.
95             if (v8String.IsEmpty())
96                 return;
97
98             functionString = toCoreString(v8String);
99         }
100
101         // Don't allow setting timeouts to run empty functions!
102         // (Bug 1009597)
103         if (!functionString.length())
104             return;
105     }
106
107     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState))
108         return;
109
110     OwnPtr<ScheduledAction> action;
111     if (function->IsFunction()) {
112         int paramCount = argumentCount >= 2 ? argumentCount - 2 : 0;
113         OwnPtr<v8::Local<v8::Value>[]> params;
114         if (paramCount > 0) {
115             params = adoptArrayPtr(new v8::Local<v8::Value>[paramCount]);
116             for (int i = 0; i < paramCount; i++) {
117                 // parameters must be globalized
118                 params[i] = info[i+2];
119             }
120         }
121
122         // params is passed to action, and released in action's destructor
123         ASSERT(impl->frame());
124         action = adoptPtr(new ScheduledAction(scriptState, v8::Handle<v8::Function>::Cast(function), paramCount, params.get(), info.GetIsolate()));
125     } else {
126         if (impl->document() && !impl->document()->contentSecurityPolicy()->allowEval()) {
127             v8SetReturnValue(info, 0);
128             return;
129         }
130         ASSERT(impl->frame());
131         action = adoptPtr(new ScheduledAction(scriptState, functionString, KURL(), info.GetIsolate()));
132     }
133
134     int32_t timeout = argumentCount >= 2 ? info[1]->Int32Value() : 0;
135     int timerId;
136     if (singleShot)
137         timerId = DOMWindowTimers::setTimeout(*impl, action.release(), timeout);
138     else
139         timerId = DOMWindowTimers::setInterval(*impl, action.release(), timeout);
140
141     // Try to do the idle notification before the timeout expires to get better
142     // use of any idle time. Aim for the middle of the interval for simplicity.
143     if (timeout >= 0) {
144         double maximumFireInterval = static_cast<double>(timeout) / 1000 / 2;
145         V8GCForContextDispose::instanceTemplate().notifyIdleSooner(maximumFireInterval);
146     }
147
148     v8SetReturnValue(info, timerId);
149 }
150
151 void V8Window::eventAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
152 {
153     LocalFrame* frame = V8Window::toNative(info.Holder())->frame();
154     ExceptionState exceptionState(ExceptionState::GetterContext, "event", "Window", info.Holder(), info.GetIsolate());
155     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), frame, exceptionState)) {
156         exceptionState.throwIfNeeded();
157         return;
158     }
159
160     v8::Handle<v8::Value> jsEvent = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder()->CreationContext()->Global(), V8HiddenValue::event(info.GetIsolate()));
161     if (jsEvent.IsEmpty())
162         return;
163     v8SetReturnValue(info, jsEvent);
164 }
165
166 void V8Window::eventAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
167 {
168     LocalFrame* frame = V8Window::toNative(info.Holder())->frame();
169     ExceptionState exceptionState(ExceptionState::SetterContext, "event", "Window", info.Holder(), info.GetIsolate());
170     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), frame, exceptionState)) {
171         exceptionState.throwIfNeeded();
172         return;
173     }
174
175     V8HiddenValue::setHiddenValue(info.GetIsolate(), info.Holder()->CreationContext()->Global(), V8HiddenValue::event(info.GetIsolate()), value);
176 }
177
178 void V8Window::frameElementAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
179 {
180     LocalDOMWindow* impl = V8Window::toNative(info.Holder());
181     ExceptionState exceptionState(ExceptionState::GetterContext, "frame", "Window", info.Holder(), info.GetIsolate());
182     if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), impl->frameElement(), exceptionState)) {
183         v8SetReturnValueNull(info);
184         exceptionState.throwIfNeeded();
185         return;
186     }
187
188     // The wrapper for an <iframe> should get its prototype from the context of the frame it's in, rather than its own frame.
189     // So, use its containing document as the creation context when wrapping.
190     v8::Handle<v8::Value> creationContext = toV8(&impl->frameElement()->document(), info.Holder(), info.GetIsolate());
191     RELEASE_ASSERT(!creationContext.IsEmpty());
192     v8::Handle<v8::Value> wrapper = toV8(impl->frameElement(), v8::Handle<v8::Object>::Cast(creationContext), info.GetIsolate());
193     v8SetReturnValue(info, wrapper);
194 }
195
196 void V8Window::openerAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
197 {
198     LocalDOMWindow* impl = V8Window::toNative(info.Holder());
199     ExceptionState exceptionState(ExceptionState::SetterContext, "opener", "Window", info.Holder(), info.GetIsolate());
200     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
201         exceptionState.throwIfNeeded();
202         return;
203     }
204
205     // Opener can be shadowed if it is in the same domain.
206     // Have a special handling of null value to behave
207     // like Firefox. See bug http://b/1224887 & http://b/791706.
208     if (value->IsNull()) {
209         // impl->frame() cannot be null,
210         // otherwise, SameOrigin check would have failed.
211         ASSERT(impl->frame());
212         impl->frame()->loader().setOpener(0);
213     }
214
215     // Delete the accessor from this object.
216     info.Holder()->Delete(v8AtomicString(info.GetIsolate(), "opener"));
217
218     // Put property on the front (this) object.
219     if (info.This()->IsObject())
220         v8::Handle<v8::Object>::Cast(info.This())->Set(v8AtomicString(info.GetIsolate(), "opener"), value);
221 }
222
223 static bool isLegacyTargetOriginDesignation(v8::Handle<v8::Value> value)
224 {
225     if (value->IsString() || value->IsStringObject())
226         return true;
227     return false;
228 }
229
230
231 void V8Window::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
232 {
233     // None of these need to be RefPtr because info and context are guaranteed
234     // to hold on to them.
235     LocalDOMWindow* window = V8Window::toNative(info.Holder());
236     LocalDOMWindow* source = callingDOMWindow(info.GetIsolate());
237
238     ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", "Window", info.Holder(), info.GetIsolate());
239
240     // If called directly by WebCore we don't have a calling context.
241     if (!source) {
242         exceptionState.throwTypeError("No active calling context exists.");
243         exceptionState.throwIfNeeded();
244         return;
245     }
246
247     // This function has variable arguments and can be:
248     // Per current spec:
249     //   postMessage(message, targetOrigin)
250     //   postMessage(message, targetOrigin, {sequence of transferrables})
251     // Legacy non-standard implementations in webkit allowed:
252     //   postMessage(message, {sequence of transferrables}, targetOrigin);
253     MessagePortArray portArray;
254     ArrayBufferArray arrayBufferArray;
255     int targetOriginArgIndex = 1;
256     if (info.Length() > 2) {
257         int transferablesArgIndex = 2;
258         if (isLegacyTargetOriginDesignation(info[2])) {
259             targetOriginArgIndex = 2;
260             transferablesArgIndex = 1;
261         }
262         if (!SerializedScriptValue::extractTransferables(info[transferablesArgIndex], transferablesArgIndex, portArray, arrayBufferArray, exceptionState, info.GetIsolate())) {
263             exceptionState.throwIfNeeded();
264             return;
265         }
266     }
267     TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, targetOrigin, info[targetOriginArgIndex]);
268
269     RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &portArray, &arrayBufferArray, exceptionState, info.GetIsolate());
270     if (exceptionState.throwIfNeeded())
271         return;
272
273     window->postMessage(message.release(), &portArray, targetOrigin, source, exceptionState);
274     exceptionState.throwIfNeeded();
275 }
276
277 // FIXME(fqian): returning string is cheating, and we should
278 // fix this by calling toString function on the receiver.
279 // However, V8 implements toString in JavaScript, which requires
280 // switching context of receiver. I consider it is dangerous.
281 void V8Window::toStringMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
282 {
283     v8::Handle<v8::Object> domWrapper = V8Window::findInstanceInPrototypeChain(info.This(), info.GetIsolate());
284     if (domWrapper.IsEmpty()) {
285         v8SetReturnValue(info, info.This()->ObjectProtoToString());
286         return;
287     }
288     v8SetReturnValue(info, domWrapper->ObjectProtoToString());
289 }
290
291 class DialogHandler {
292 public:
293     explicit DialogHandler(v8::Handle<v8::Value> dialogArguments, ScriptState* scriptState)
294         : m_scriptState(scriptState)
295         , m_dialogArguments(dialogArguments)
296     {
297     }
298
299     void dialogCreated(LocalDOMWindow*);
300     v8::Handle<v8::Value> returnValue() const;
301
302 private:
303     RefPtr<ScriptState> m_scriptState;
304     RefPtr<ScriptState> m_scriptStateForDialogFrame;
305     v8::Handle<v8::Value> m_dialogArguments;
306 };
307
308 void DialogHandler::dialogCreated(LocalDOMWindow* dialogFrame)
309 {
310     if (m_dialogArguments.IsEmpty())
311         return;
312     v8::Handle<v8::Context> context = toV8Context(dialogFrame->frame(), m_scriptState->world());
313     if (context.IsEmpty())
314         return;
315     m_scriptStateForDialogFrame = ScriptState::from(context);
316
317     ScriptState::Scope scope(m_scriptStateForDialogFrame.get());
318     m_scriptStateForDialogFrame->context()->Global()->Set(v8AtomicString(m_scriptState->isolate(), "dialogArguments"), m_dialogArguments);
319 }
320
321 v8::Handle<v8::Value> DialogHandler::returnValue() const
322 {
323     if (!m_scriptStateForDialogFrame)
324         return v8Undefined();
325     ASSERT(!m_scriptStateForDialogFrame->contextIsEmpty());
326
327     v8::Isolate* isolate = m_scriptStateForDialogFrame->isolate();
328     v8::EscapableHandleScope handleScope(isolate);
329     ScriptState::Scope scope(m_scriptStateForDialogFrame.get());
330     v8::Local<v8::Value> returnValue = m_scriptStateForDialogFrame->context()->Global()->Get(v8AtomicString(isolate, "returnValue"));
331     if (returnValue.IsEmpty())
332         return v8Undefined();
333     return handleScope.Escape(returnValue);
334 }
335
336 static void setUpDialog(LocalDOMWindow* dialog, void* handler)
337 {
338     static_cast<DialogHandler*>(handler)->dialogCreated(dialog);
339 }
340
341 void V8Window::showModalDialogMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
342 {
343     LocalDOMWindow* impl = V8Window::toNative(info.Holder());
344     ExceptionState exceptionState(ExceptionState::ExecutionContext, "showModalDialog", "Window", info.Holder(), info.GetIsolate());
345     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
346         exceptionState.throwIfNeeded();
347         return;
348     }
349
350     TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, urlString, info[0]);
351     DialogHandler handler(info[1], ScriptState::current(info.GetIsolate()));
352     TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, dialogFeaturesString, info[2]);
353
354     impl->showModalDialog(urlString, dialogFeaturesString, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate()), setUpDialog, &handler);
355
356     v8SetReturnValue(info, handler.returnValue());
357 }
358
359 void V8Window::openMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
360 {
361     LocalDOMWindow* impl = V8Window::toNative(info.Holder());
362     ExceptionState exceptionState(ExceptionState::ExecutionContext, "open", "Window", info.Holder(), info.GetIsolate());
363     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
364         exceptionState.throwIfNeeded();
365         return;
366     }
367
368     TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, urlString, info[0]);
369     AtomicString frameName;
370     if (info[1]->IsUndefined() || info[1]->IsNull()) {
371         frameName = "_blank";
372     } else {
373         TOSTRING_VOID(V8StringResource<>, frameNameResource, info[1]);
374         frameName = frameNameResource;
375     }
376     TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, windowFeaturesString, info[2]);
377
378     RefPtrWillBeRawPtr<LocalDOMWindow> openedWindow = impl->open(urlString, frameName, windowFeaturesString, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate()));
379     if (!openedWindow)
380         return;
381
382     v8SetReturnValueFast(info, openedWindow.release(), impl);
383 }
384
385 void V8Window::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
386 {
387
388     LocalDOMWindow* window = V8Window::toNative(info.Holder());
389     if (!window)
390         return;
391
392     LocalFrame* frame = window->frame();
393     // window is detached from a frame.
394     if (!frame)
395         return;
396
397     // Search sub-frames.
398     AtomicString propName = toCoreAtomicString(name);
399     Frame* child = frame->tree().scopedChild(propName);
400     if (child) {
401         v8SetReturnValueFast(info, child->domWindow(), window);
402         return;
403     }
404
405     // Search IDL functions defined in the prototype
406     if (!info.Holder()->GetRealNamedProperty(name).IsEmpty())
407         return;
408
409     // Search named items in the document.
410     Document* doc = frame->document();
411
412     if (doc && doc->isHTMLDocument()) {
413         if (toHTMLDocument(doc)->hasNamedItem(propName) || doc->hasElementWithId(propName.impl())) {
414             RefPtrWillBeRawPtr<HTMLCollection> items = doc->windowNamedItems(propName);
415             if (!items->isEmpty()) {
416                 if (items->hasExactlyOneItem()) {
417                     v8SetReturnValueFast(info, items->item(0), window);
418                     return;
419                 }
420                 v8SetReturnValueFast(info, items.release(), window);
421                 return;
422             }
423         }
424     }
425 }
426
427
428 void V8Window::setTimeoutMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
429 {
430     ExceptionState exceptionState(ExceptionState::ExecutionContext, "setTimeout", "Window", info.Holder(), info.GetIsolate());
431     windowSetTimeoutImpl(info, true, exceptionState);
432     exceptionState.throwIfNeeded();
433 }
434
435
436 void V8Window::setIntervalMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
437 {
438     ExceptionState exceptionState(ExceptionState::ExecutionContext, "setInterval", "Window", info.Holder(), info.GetIsolate());
439     windowSetTimeoutImpl(info, false, exceptionState);
440     exceptionState.throwIfNeeded();
441 }
442
443 bool V8Window::namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
444 {
445     v8::Isolate* isolate = v8::Isolate::GetCurrent();
446     v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host, isolate);
447     if (window.IsEmpty())
448         return false; // the frame is gone.
449
450     LocalDOMWindow* targetWindow = V8Window::toNative(window);
451
452     ASSERT(targetWindow);
453
454     LocalFrame* target = targetWindow->frame();
455     if (!target)
456         return false;
457
458     // Notify the loader's client if the initial document has been accessed.
459     if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument())
460         target->loader().didAccessInitialDocument();
461
462     if (key->IsString()) {
463         DEFINE_STATIC_LOCAL(const AtomicString, nameOfProtoProperty, ("__proto__", AtomicString::ConstructFromLiteral));
464
465         AtomicString name = toCoreAtomicString(key.As<v8::String>());
466         Frame* childFrame = target->tree().scopedChild(name);
467         // Notice that we can't call HasRealNamedProperty for ACCESS_HAS
468         // because that would generate infinite recursion.
469         if (type == v8::ACCESS_HAS && childFrame)
470             return true;
471         // We need to explicitly compare against nameOfProtoProperty because
472         // V8's JSObject::LocalLookup finds __proto__ before
473         // interceptors and even when __proto__ isn't a "real named property".
474         v8::Handle<v8::String> keyString = key.As<v8::String>();
475         if (type == v8::ACCESS_GET
476             && childFrame
477             && !host->HasRealNamedProperty(keyString)
478             && !window->HasRealNamedProperty(keyString)
479             && name != nameOfProtoProperty)
480             return true;
481     }
482
483     return BindingSecurity::shouldAllowAccessToFrame(isolate, target, DoNotReportSecurityError);
484 }
485
486 bool V8Window::indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
487 {
488     v8::Isolate* isolate = v8::Isolate::GetCurrent();
489     v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host, isolate);
490     if (window.IsEmpty())
491         return false;
492
493     LocalDOMWindow* targetWindow = V8Window::toNative(window);
494
495     ASSERT(targetWindow);
496
497     LocalFrame* target = targetWindow->frame();
498     if (!target)
499         return false;
500
501     // Notify the loader's client if the initial document has been accessed.
502     if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument())
503         target->loader().didAccessInitialDocument();
504
505     Frame* childFrame = target->tree().scopedChild(index);
506
507     // Notice that we can't call HasRealNamedProperty for ACCESS_HAS
508     // because that would generate infinite recursion.
509     if (type == v8::ACCESS_HAS && childFrame)
510         return true;
511     if (type == v8::ACCESS_GET
512         && childFrame
513         && !host->HasRealIndexedProperty(index)
514         && !window->HasRealIndexedProperty(index))
515         return true;
516
517     return BindingSecurity::shouldAllowAccessToFrame(isolate, target, DoNotReportSecurityError);
518 }
519
520 v8::Handle<v8::Value> toV8(LocalDOMWindow* window, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
521 {
522     // Notice that we explicitly ignore creationContext because the LocalDOMWindow is its own creationContext.
523
524     if (!window)
525         return v8::Null(isolate);
526     // Initializes environment of a frame, and return the global object
527     // of the frame.
528     LocalFrame* frame = window->frame();
529     if (!frame)
530         return v8Undefined();
531
532     v8::Handle<v8::Context> context = toV8Context(frame, DOMWrapperWorld::current(isolate));
533     if (context.IsEmpty())
534         return v8Undefined();
535
536     v8::Handle<v8::Object> global = context->Global();
537     ASSERT(!global.IsEmpty());
538     return global;
539 }
540
541 } // namespace WebCore