diff options
Diffstat (limited to 'Source/WebCore/bindings/js/JSDOMWindowBase.cpp')
-rw-r--r-- | Source/WebCore/bindings/js/JSDOMWindowBase.cpp | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/Source/WebCore/bindings/js/JSDOMWindowBase.cpp b/Source/WebCore/bindings/js/JSDOMWindowBase.cpp new file mode 100644 index 0000000..68c0088 --- /dev/null +++ b/Source/WebCore/bindings/js/JSDOMWindowBase.cpp @@ -0,0 +1,232 @@ +/* + * 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 <wtf/Threading.h> +#include <wtf/text/StringConcatenate.h> + +using namespace JSC; + +namespace WebCore { + +const ClassInfo JSDOMWindowBase::s_info = { "Window", &JSDOMGlobalObject::s_info, 0, 0 }; + +JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData(PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell) + : JSDOMGlobalObjectData(shell->world(), destroyJSDOMWindowBaseData) + , impl(window) + , shell(shell) +{ +} + +JSDOMWindowBase::JSDOMWindowBase(NonNullPassRefPtr<Structure> structure, PassRefPtr<DOMWindow> 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, WTF_ARRAY_LENGTH(staticGlobals)); +} + +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 +{ + return d()->shell->window()->impl()->crossDomainAccessErrorMessage(asJSDOMWindow(other)->impl()); +} + +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::supportsRichSourceInfo() const +{ +#if PLATFORM(ANDROID) + return true; +#elif !ENABLE(JAVASCRIPT_DEBUGGER) || !ENABLE(INSPECTOR) + return false; +#else + Frame* frame = impl()->frame(); + if (!frame) + return false; + + Page* page = frame->page(); + if (!page) + return false; + + bool enabled = page->inspectorController()->enabled(); + ASSERT(enabled || !debugger()); + ASSERT(enabled || !supportsProfiling()); + return enabled; +#endif +} + +bool JSDOMWindowBase::shouldInterruptScript() const +{ + ASSERT(impl()->frame()); + Page* page = impl()->frame()->page(); + + // See <rdar://problem/5479443>. 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(); +} + +JSValue JSDOMWindowBase::toStrictThisObject(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*>(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<JSDOMWindow*>(asObject(value)); + if (classInfo == &JSDOMWindowShell::s_info) + return static_cast<JSDOMWindowShell*>(asObject(value))->window(); + return 0; +} + +} // namespace WebCore |