Add custom vtable struct to ClassInfo struct
[WebKit-https.git] / Source / WebCore / bindings / js / JSDOMWindowBase.cpp
1 /*
2  *  Copyright (C) 2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
4  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reseved.
5  *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
20  *  USA
21  */
22
23 #include "config.h"
24 #include "JSDOMWindowBase.h"
25
26 #include "Chrome.h"
27 #include "Console.h"
28 #include "DOMWindow.h"
29 #include "Frame.h"
30 #include "InspectorController.h"
31 #include "JSDOMWindowCustom.h"
32 #include "JSNode.h"
33 #include "Logging.h"
34 #include "Page.h"
35 #include "SecurityOrigin.h"
36 #include "Settings.h"
37 #include "WebCoreJSClientData.h"
38 #include <wtf/MainThread.h>
39
40 using namespace JSC;
41
42 namespace WebCore {
43
44 const ClassInfo JSDOMWindowBase::s_info = { "Window", &JSDOMGlobalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSDOMWindowBase) };
45
46 JSDOMWindowBase::JSDOMWindowBase(JSGlobalData& globalData, Structure* structure, PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell)
47     : JSDOMGlobalObject(globalData, structure, shell->world())
48     , m_impl(window)
49     , m_shell(shell)
50 {
51 }
52
53 void JSDOMWindowBase::finishCreation(JSGlobalData& globalData, JSDOMWindowShell* shell)
54 {
55     Base::finishCreation(globalData, shell);
56     ASSERT(inherits(&s_info));
57
58     GlobalPropertyInfo staticGlobals[] = {
59         GlobalPropertyInfo(Identifier(globalExec(), "document"), jsNull(), DontDelete | ReadOnly),
60         GlobalPropertyInfo(Identifier(globalExec(), "window"), m_shell, DontDelete | ReadOnly)
61     };
62     
63     addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
64 }
65
66 void JSDOMWindowBase::updateDocument()
67 {
68     ASSERT(m_impl->document());
69     ExecState* exec = globalExec();
70     symbolTablePutWithAttributes(exec->globalData(), Identifier(exec, "document"), toJS(exec, this, m_impl->document()), DontDelete | ReadOnly);
71 }
72
73 ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const
74 {
75     return m_impl->document();
76 }
77
78 String JSDOMWindowBase::crossDomainAccessErrorMessage(const JSGlobalObject* other) const
79 {
80     return m_shell->window()->impl()->crossDomainAccessErrorMessage(asJSDOMWindow(other)->impl());
81 }
82
83 void JSDOMWindowBase::printErrorMessage(const String& message) const
84 {
85     printErrorMessageForFrame(impl()->frame(), message);
86 }
87
88 bool JSDOMWindowBase::supportsProfiling() const
89 {
90 #if !ENABLE(JAVASCRIPT_DEBUGGER) || !ENABLE(INSPECTOR)
91     return false;
92 #else
93     Frame* frame = impl()->frame();
94     if (!frame)
95         return false;
96
97     Page* page = frame->page();
98     if (!page)
99         return false;
100
101     return page->inspectorController()->profilerEnabled();
102 #endif
103 }
104
105 bool JSDOMWindowBase::supportsRichSourceInfo() const
106 {
107 #if !ENABLE(JAVASCRIPT_DEBUGGER) || !ENABLE(INSPECTOR)
108     return false;
109 #else
110     Frame* frame = impl()->frame();
111     if (!frame)
112         return false;
113
114     Page* page = frame->page();
115     if (!page)
116         return false;
117
118     bool enabled = page->inspectorController()->enabled();
119     ASSERT(enabled || !debugger());
120     ASSERT(enabled || !supportsProfiling());
121     return enabled;
122 #endif
123 }
124
125 bool JSDOMWindowBase::shouldInterruptScript() const
126 {
127     ASSERT(impl()->frame());
128     Page* page = impl()->frame()->page();
129
130     // See <rdar://problem/5479443>. We don't think that page can ever be NULL
131     // in this case, but if it is, we've gotten into a state where we may have
132     // hung the UI, with no way to ask the client whether to cancel execution.
133     // For now, our solution is just to cancel execution no matter what,
134     // ensuring that we never hang. We might want to consider other solutions
135     // if we discover problems with this one.
136     ASSERT(page);
137     if (!page)
138         return true;
139
140     return page->chrome()->shouldInterruptJavaScript();
141 }
142
143 void JSDOMWindowBase::willRemoveFromWindowShell()
144 {
145     setCurrentEvent(0);
146 }
147
148 JSObject* JSDOMWindowBase::toThisObject(ExecState*) const
149 {
150     return shell();
151 }
152
153 JSValue JSDOMWindowBase::toStrictThisObject(ExecState*) const
154 {
155     return shell();
156 }
157
158 JSDOMWindowShell* JSDOMWindowBase::shell() const
159 {
160     return m_shell;
161 }
162
163 JSGlobalData* JSDOMWindowBase::commonJSGlobalData()
164 {
165     ASSERT(isMainThread());
166
167     static JSGlobalData* globalData = 0;
168     if (!globalData) {
169         globalData = JSGlobalData::createLeaked(ThreadStackTypeLarge, LargeHeap).releaseRef();
170         globalData->timeoutChecker.setTimeoutInterval(10000); // 10 seconds
171 #ifndef NDEBUG
172         globalData->exclusiveThread = currentThread();
173 #endif
174         initNormalWorldClientData(globalData);
175     }
176
177     return globalData;
178 }
179
180 // JSDOMGlobalObject* is ignored, accessing a window in any context will
181 // use that DOMWindow's prototype chain.
182 JSValue toJS(ExecState* exec, JSDOMGlobalObject*, DOMWindow* domWindow)
183 {
184     return toJS(exec, domWindow);
185 }
186
187 JSValue toJS(ExecState* exec, DOMWindow* domWindow)
188 {
189     if (!domWindow)
190         return jsNull();
191     Frame* frame = domWindow->frame();
192     if (!frame)
193         return jsNull();
194     return frame->script()->windowShell(currentWorld(exec));
195 }
196
197 JSDOMWindow* toJSDOMWindow(Frame* frame, DOMWrapperWorld* world)
198 {
199     if (!frame)
200         return 0;
201     return frame->script()->windowShell(world)->window();
202 }
203
204 JSDOMWindow* toJSDOMWindow(JSValue value)
205 {
206     if (!value.isObject())
207         return 0;
208     const ClassInfo* classInfo = asObject(value)->classInfo();
209     if (classInfo == &JSDOMWindow::s_info)
210         return static_cast<JSDOMWindow*>(asObject(value));
211     if (classInfo == &JSDOMWindowShell::s_info)
212         return static_cast<JSDOMWindowShell*>(asObject(value))->window();
213     return 0;
214 }
215
216 } // namespace WebCore