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