JSDOMWindowBase.cpp [plain text]
#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 "SecurityOrigin.h"
#include "Settings.h"
#include "WebCoreJSClientData.h"
#include <wtf/MainThread.h>
#include "ChromeClient.h"
#include "WebSafeGCActivityCallback.h"
using namespace JSC;
namespace WebCore {
const ClassInfo JSDOMWindowBase::s_info = { "Window", &JSDOMGlobalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSDOMWindowBase) };
const GlobalObjectMethodTable JSDOMWindowBase::s_globalObjectMethodTable = { &allowsAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript
, &shouldInterruptScriptBeforeTimeout
};
JSDOMWindowBase::JSDOMWindowBase(JSGlobalData& globalData, Structure* structure, PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell)
: JSDOMGlobalObject(globalData, structure, shell->world(), &s_globalObjectMethodTable)
, m_impl(window)
, m_shell(shell)
{
}
void JSDOMWindowBase::finishCreation(JSGlobalData& globalData, JSDOMWindowShell* shell)
{
Base::finishCreation(globalData, shell);
ASSERT(inherits(&s_info));
GlobalPropertyInfo staticGlobals[] = {
GlobalPropertyInfo(Identifier(globalExec(), "document"), jsNull(), DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(globalExec(), "window"), m_shell, DontDelete | ReadOnly)
};
addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
}
void JSDOMWindowBase::destroy(JSCell* cell)
{
jsCast<JSDOMWindowBase*>(cell)->JSDOMWindowBase::~JSDOMWindowBase();
}
void JSDOMWindowBase::updateDocument()
{
ASSERT(m_impl->document());
ExecState* exec = globalExec();
symbolTablePutWithAttributes(exec->globalData(), Identifier(exec, "document"), toJS(exec, this, m_impl->document()), DontDelete | ReadOnly);
}
ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const
{
return m_impl->document();
}
String JSDOMWindowBase::crossDomainAccessErrorMessage(const JSGlobalObject* other) const
{
return m_shell->window()->impl()->crossDomainAccessErrorMessage(asJSDOMWindow(other)->impl());
}
void JSDOMWindowBase::printErrorMessage(const String& message) const
{
printErrorMessageForFrame(impl()->frame(), message);
}
bool JSDOMWindowBase::allowsAccessFrom(const JSGlobalObject* thisObject, ExecState* exec)
{
JSGlobalObject* otherObject = exec->lexicalGlobalObject();
const JSDOMWindow* originWindow = asJSDOMWindow(otherObject);
const JSDOMWindow* targetWindow = asJSDOMWindow(thisObject);
if (originWindow == targetWindow)
return true;
const SecurityOrigin* originSecurityOrigin = originWindow->impl()->securityOrigin();
const SecurityOrigin* targetSecurityOrigin = targetWindow->impl()->securityOrigin();
if (originSecurityOrigin->canAccess(targetSecurityOrigin))
return true;
targetWindow->printErrorMessage(targetWindow->crossDomainAccessErrorMessage(otherObject));
return false;
}
bool JSDOMWindowBase::supportsProfiling(const JSGlobalObject* object)
{
#if !ENABLE(JAVASCRIPT_DEBUGGER) || !ENABLE(INSPECTOR)
return false;
#else
const JSDOMWindowBase* thisObject = static_cast<const JSDOMWindowBase*>(object);
Frame* frame = thisObject->impl()->frame();
if (!frame)
return false;
Page* page = frame->page();
if (!page)
return false;
#if ENABLE(INSPECTOR)
return page->inspectorController()->profilerEnabled();
#else
return false;
#endif // ENABLE(INSPECTOR)
#endif
}
bool JSDOMWindowBase::supportsRichSourceInfo(const JSGlobalObject* object)
{
#if !ENABLE(JAVASCRIPT_DEBUGGER) || !ENABLE(INSPECTOR)
return false;
#else
const JSDOMWindowBase* thisObject = static_cast<const JSDOMWindowBase*>(object);
Frame* frame = thisObject->impl()->frame();
if (!frame)
return false;
Page* page = frame->page();
if (!page)
return false;
bool enabled = page->inspectorController()->enabled();
ASSERT(enabled || !thisObject->debugger());
ASSERT(enabled || !supportsProfiling(thisObject));
return enabled;
#endif
}
bool JSDOMWindowBase::shouldInterruptScript(const JSGlobalObject* object)
{
const JSDOMWindowBase* thisObject = static_cast<const JSDOMWindowBase*>(object);
ASSERT(thisObject->impl()->frame());
Page* page = thisObject->impl()->frame()->page();
ASSERT(page);
if (!page)
return true;
return page->chrome()->shouldInterruptJavaScript();
}
bool JSDOMWindowBase::shouldInterruptScriptBeforeTimeout(const JSGlobalObject* object)
{
const JSDOMWindowBase* thisObject = static_cast<const JSDOMWindowBase*>(object);
DOMWindow* domWindow = thisObject->impl();
if (domWindow->frame() && domWindow->frame()->page() && domWindow->frame()->page()->chrome()->client()->isStopping())
return true;
return JSGlobalObject::shouldInterruptScriptBeforeTimeout(object);
}
void JSDOMWindowBase::willRemoveFromWindowShell()
{
setCurrentEvent(0);
}
JSObject* JSDOMWindowBase::toThisObject(JSCell* cell, ExecState*)
{
return jsCast<JSDOMWindowBase*>(cell)->shell();
}
JSDOMWindowShell* JSDOMWindowBase::shell() const
{
return m_shell;
}
JSGlobalData* JSDOMWindowBase::commonJSGlobalData()
{
ASSERT(isMainThread() || pthread_main_np());
JSGlobalData*& globalData = commonJSGlobalDataInternal();
if (!globalData) {
globalData = JSGlobalData::createLeaked(ThreadStackTypeLarge, LargeHeap).leakRef();
globalData->timeoutChecker.setTimeoutInterval(20000); PassOwnPtr<WebSafeGCActivityCallback> activityCallback = WebSafeGCActivityCallback::create(&globalData->heap);
globalData->heap.setActivityCallback(activityCallback.leakPtr());
globalData->makeUsableFromMultipleThreads();
globalData->heap.machineThreads().addCurrentThread();
initNormalWorldClientData(globalData);
}
return globalData;
}
bool JSDOMWindowBase::commonJSGlobalDataExists()
{
return commonJSGlobalDataInternal();
}
JSGlobalData*& JSDOMWindowBase::commonJSGlobalDataInternal()
{
ASSERT(isMainThread() || pthread_main_np());
static JSGlobalData* commonJSGlobalData;
return commonJSGlobalData;
}
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 jsCast<JSDOMWindow*>(asObject(value));
if (classInfo == &JSDOMWindowShell::s_info)
return jsCast<JSDOMWindowShell*>(asObject(value))->window();
return 0;
}
}