• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "CString.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 "ScriptController.h"
36 #include "SecurityOrigin.h"
37 #include "Settings.h"
38 
39 using namespace JSC;
40 
41 namespace WebCore {
42 
43 const ClassInfo JSDOMWindowBase::s_info = { "Window", 0, 0, 0 };
44 
JSDOMWindowBaseData(PassRefPtr<DOMWindow> window,JSDOMWindowShell * shell)45 JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData(PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell)
46     : impl(window)
47     , shell(shell)
48 {
49 }
50 
JSDOMWindowBase(PassRefPtr<Structure> structure,PassRefPtr<DOMWindow> window,JSDOMWindowShell * shell)51 JSDOMWindowBase::JSDOMWindowBase(PassRefPtr<Structure> structure, PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell)
52     : JSDOMGlobalObject(structure, new JSDOMWindowBaseData(window, shell), shell)
53 {
54     GlobalPropertyInfo staticGlobals[] = {
55         GlobalPropertyInfo(Identifier(globalExec(), "document"), jsNull(), DontDelete | ReadOnly),
56         GlobalPropertyInfo(Identifier(globalExec(), "window"), d()->shell, DontDelete | ReadOnly)
57     };
58 
59     addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo));
60 }
61 
updateDocument()62 void JSDOMWindowBase::updateDocument()
63 {
64     ASSERT(d()->impl->document());
65     ExecState* exec = globalExec();
66     symbolTablePutWithAttributes(Identifier(exec, "document"), toJS(exec, this, d()->impl->document()), DontDelete | ReadOnly);
67 }
68 
scriptExecutionContext() const69 ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const
70 {
71     return d()->impl->document();
72 }
73 
crossDomainAccessErrorMessage(const JSGlobalObject * other) const74 String JSDOMWindowBase::crossDomainAccessErrorMessage(const JSGlobalObject* other) const
75 {
76     KURL originURL = asJSDOMWindow(other)->impl()->url();
77     KURL targetURL = impl()->frame()->document()->url();
78     if (originURL.isNull() || targetURL.isNull())
79         return String();
80 
81     // FIXME: this error message should contain more specifics of why the same origin check has failed.
82     return String::format("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains, protocols and ports must match.\n",
83         targetURL.string().utf8().data(), originURL.string().utf8().data());
84 }
85 
printErrorMessage(const String & message) const86 void JSDOMWindowBase::printErrorMessage(const String& message) const
87 {
88     if (message.isEmpty())
89         return;
90 
91     Frame* frame = impl()->frame();
92     if (!frame)
93         return;
94 
95     Settings* settings = frame->settings();
96     if (!settings)
97         return;
98 
99     if (settings->privateBrowsingEnabled())
100         return;
101 
102     impl()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL.
103 }
104 
globalExec()105 ExecState* JSDOMWindowBase::globalExec()
106 {
107     // We need to make sure that any script execution happening in this
108     // frame does not destroy it
109     if (Frame *frame = impl()->frame())
110         frame->keepAlive();
111     return Base::globalExec();
112 }
113 
supportsProfiling() const114 bool JSDOMWindowBase::supportsProfiling() const
115 {
116 #if !ENABLE(JAVASCRIPT_DEBUGGER)
117     return false;
118 #else
119     Frame* frame = impl()->frame();
120     if (!frame)
121         return false;
122 
123     Page* page = frame->page();
124     if (!page)
125         return false;
126 
127     return page->inspectorController()->profilerEnabled();
128 #endif
129 }
130 
shouldInterruptScript() const131 bool JSDOMWindowBase::shouldInterruptScript() const
132 {
133     ASSERT(impl()->frame());
134     Page* page = impl()->frame()->page();
135 
136     // See <rdar://problem/5479443>. We don't think that page can ever be NULL
137     // in this case, but if it is, we've gotten into a state where we may have
138     // hung the UI, with no way to ask the client whether to cancel execution.
139     // For now, our solution is just to cancel execution no matter what,
140     // ensuring that we never hang. We might want to consider other solutions
141     // if we discover problems with this one.
142     ASSERT(page);
143     if (!page)
144         return true;
145 
146     return page->chrome()->shouldInterruptJavaScript();
147 }
148 
willRemoveFromWindowShell()149 void JSDOMWindowBase::willRemoveFromWindowShell()
150 {
151     setCurrentEvent(0);
152 }
153 
toThisObject(ExecState *) const154 JSObject* JSDOMWindowBase::toThisObject(ExecState*) const
155 {
156     return shell();
157 }
158 
shell() const159 JSDOMWindowShell* JSDOMWindowBase::shell() const
160 {
161     return d()->shell;
162 }
163 
commonJSGlobalData()164 JSGlobalData* JSDOMWindowBase::commonJSGlobalData()
165 {
166     static JSGlobalData* globalData;
167     if (!globalData) {
168         globalData = JSGlobalData::createLeaked().releaseRef();
169         globalData->timeoutChecker.setTimeoutInterval(10000); // 10 seconds
170     }
171 
172     return globalData;
173 }
174 
175 // JSDOMGlobalObject* is ignored, accesing a window in any context will
176 // use that DOMWindow's prototype chain.
toJS(ExecState * exec,JSDOMGlobalObject *,DOMWindow * domWindow)177 JSValue toJS(ExecState* exec, JSDOMGlobalObject*, DOMWindow* domWindow)
178 {
179     return toJS(exec, domWindow);
180 }
181 
toJS(ExecState *,DOMWindow * domWindow)182 JSValue toJS(ExecState*, DOMWindow* domWindow)
183 {
184     if (!domWindow)
185         return jsNull();
186     Frame* frame = domWindow->frame();
187     if (!frame)
188         return jsNull();
189     return frame->script()->windowShell();
190 }
191 
toJSDOMWindow(Frame * frame)192 JSDOMWindow* toJSDOMWindow(Frame* frame)
193 {
194     if (!frame)
195         return 0;
196     return frame->script()->windowShell()->window();
197 }
198 
toJSDOMWindow(JSValue value)199 JSDOMWindow* toJSDOMWindow(JSValue value)
200 {
201     if (!value.isObject())
202         return 0;
203     const ClassInfo* classInfo = asObject(value)->classInfo();
204     if (classInfo == &JSDOMWindow::s_info)
205         return static_cast<JSDOMWindow*>(asObject(value));
206     if (classInfo == &JSDOMWindowShell::s_info)
207         return static_cast<JSDOMWindowShell*>(asObject(value))->window();
208     return 0;
209 }
210 
211 } // namespace WebCore
212