diff -r 000000000000 -r 4f2f89ce4247 WebCore/bindings/js/JSDOMWindowBase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebCore/bindings/js/JSDOMWindowBase.cpp Fri Sep 17 09:02:29 2010 +0300 @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2006 Jon Shier (jshier@iastate.edu) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reseved. + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#include "config.h" +#include "JSDOMWindowBase.h" + +#include "Chrome.h" +#include "Console.h" +#include "DOMWindow.h" +#include "Frame.h" +#include "InspectorController.h" +#include "JSDOMWindowCustom.h" +#include "JSNode.h" +#include "Logging.h" +#include "Page.h" +#include "ScriptController.h" +#include "SecurityOrigin.h" +#include "Settings.h" +#include "WebCoreJSClientData.h" +#include +#include + +using namespace JSC; + +namespace WebCore { + +const ClassInfo JSDOMWindowBase::s_info = { "Window", &JSDOMGlobalObject::s_info, 0, 0 }; + +JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData(PassRefPtr window, JSDOMWindowShell* shell) + : JSDOMGlobalObjectData(shell->world(), destroyJSDOMWindowBaseData) + , impl(window) + , shell(shell) +{ +} + +JSDOMWindowBase::JSDOMWindowBase(NonNullPassRefPtr structure, PassRefPtr window, JSDOMWindowShell* shell) + : JSDOMGlobalObject(structure, new JSDOMWindowBaseData(window, shell), shell) +{ + GlobalPropertyInfo staticGlobals[] = { + GlobalPropertyInfo(Identifier(globalExec(), "document"), jsNull(), DontDelete | ReadOnly), + GlobalPropertyInfo(Identifier(globalExec(), "window"), d()->shell, DontDelete | ReadOnly) + }; + + addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo)); +} + +void JSDOMWindowBase::updateDocument() +{ + ASSERT(d()->impl->document()); + ExecState* exec = globalExec(); + symbolTablePutWithAttributes(Identifier(exec, "document"), toJS(exec, this, d()->impl->document()), DontDelete | ReadOnly); +} + +ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const +{ + return d()->impl->document(); +} + +String JSDOMWindowBase::crossDomainAccessErrorMessage(const JSGlobalObject* other) const +{ + KURL originURL = asJSDOMWindow(other)->impl()->url(); + KURL targetURL = d()->shell->window()->impl()->url(); + if (originURL.isNull() || targetURL.isNull()) + return String(); + + // FIXME: this error message should contain more specifics of why the same origin check has failed. + return String::format("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains, protocols and ports must match.\n", + targetURL.string().utf8().data(), originURL.string().utf8().data()); +} + +void JSDOMWindowBase::printErrorMessage(const String& message) const +{ + printErrorMessageForFrame(impl()->frame(), message); +} + +ExecState* JSDOMWindowBase::globalExec() +{ + // We need to make sure that any script execution happening in this + // frame does not destroy it + if (Frame *frame = impl()->frame()) + frame->keepAlive(); + return Base::globalExec(); +} + +bool JSDOMWindowBase::supportsProfiling() const +{ +#if !ENABLE(JAVASCRIPT_DEBUGGER) || !ENABLE(INSPECTOR) + return false; +#else + Frame* frame = impl()->frame(); + if (!frame) + return false; + + Page* page = frame->page(); + if (!page) + return false; + + return page->inspectorController()->profilerEnabled(); +#endif +} + +bool JSDOMWindowBase::shouldInterruptScript() const +{ + ASSERT(impl()->frame()); + Page* page = impl()->frame()->page(); + + // See . We don't think that page can ever be NULL + // in this case, but if it is, we've gotten into a state where we may have + // hung the UI, with no way to ask the client whether to cancel execution. + // For now, our solution is just to cancel execution no matter what, + // ensuring that we never hang. We might want to consider other solutions + // if we discover problems with this one. + ASSERT(page); + if (!page) + return true; + + return page->chrome()->shouldInterruptJavaScript(); +} + +void JSDOMWindowBase::willRemoveFromWindowShell() +{ + setCurrentEvent(0); +} + +JSObject* JSDOMWindowBase::toThisObject(ExecState*) const +{ + return shell(); +} + +JSDOMWindowShell* JSDOMWindowBase::shell() const +{ + return d()->shell; +} + +JSGlobalData* JSDOMWindowBase::commonJSGlobalData() +{ + ASSERT(isMainThread()); + + static JSGlobalData* globalData = 0; + if (!globalData) { + globalData = JSGlobalData::createLeaked(ThreadStackTypeLarge).releaseRef(); + globalData->timeoutChecker.setTimeoutInterval(10000); // 10 seconds +#ifndef NDEBUG + globalData->exclusiveThread = currentThread(); +#endif + initNormalWorldClientData(globalData); + } + + return globalData; +} + +void JSDOMWindowBase::destroyJSDOMWindowBaseData(void* jsDOMWindowBaseData) +{ + delete static_cast(jsDOMWindowBaseData); +} + +// JSDOMGlobalObject* is ignored, accessing a window in any context will +// use that DOMWindow's prototype chain. +JSValue toJS(ExecState* exec, JSDOMGlobalObject*, DOMWindow* domWindow) +{ + return toJS(exec, domWindow); +} + +JSValue toJS(ExecState* exec, DOMWindow* domWindow) +{ + if (!domWindow) + return jsNull(); + Frame* frame = domWindow->frame(); + if (!frame) + return jsNull(); + return frame->script()->windowShell(currentWorld(exec)); +} + +JSDOMWindow* toJSDOMWindow(Frame* frame, DOMWrapperWorld* world) +{ + if (!frame) + return 0; + return frame->script()->windowShell(world)->window(); +} + +JSDOMWindow* toJSDOMWindow(JSValue value) +{ + if (!value.isObject()) + return 0; + const ClassInfo* classInfo = asObject(value)->classInfo(); + if (classInfo == &JSDOMWindow::s_info) + return static_cast(asObject(value)); + if (classInfo == &JSDOMWindowShell::s_info) + return static_cast(asObject(value))->window(); + return 0; +} + +} // namespace WebCore