#include "config.h"
#include "kjs_proxy.h"
#include "Chrome.h"
#include "Document.h"
#include "Event.h"
#include "EventNames.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "GCController.h"
#include "JSDocument.h"
#include "JSDOMWindow.h"
#include "Page.h"
#include "Settings.h"
#include "kjs_events.h"
#include "kjs_window.h"
#if ENABLE(SVG)
#include "JSSVGLazyEventListener.h"
#endif
using namespace KJS;
using namespace WebCore::EventNames;
namespace WebCore {
KJSProxy::KJSProxy(Frame* frame)
: m_frame(frame)
, m_handlerLineno(0)
, m_processingTimerCallback(0)
, m_processingInlineCode(0)
{
}
KJSProxy::~KJSProxy()
{
if (m_globalObject) {
m_globalObject = 0;
gcController().garbageCollectSoon();
}
}
JSValue* KJSProxy::evaluate(const String& filename, int baseLine, const String& str)
{
initScriptIfNeeded();
ExecState* exec = m_globalObject->globalExec();
m_processingInlineCode = filename.isNull();
JSLock lock;
m_frame->keepAlive();
JSValue* thisNode = Window::retrieve(m_frame);
m_globalObject->startTimeoutCheck();
Completion comp = Interpreter::evaluate(exec, filename, baseLine, reinterpret_cast<const KJS::UChar*>(str.characters()), str.length(), thisNode);
m_globalObject->stopTimeoutCheck();
if (comp.complType() == Normal || comp.complType() == ReturnValue) {
m_processingInlineCode = false;
return comp.value();
}
if (comp.complType() == Throw) {
UString errorMessage = comp.value()->toString(exec);
int lineNumber = comp.value()->toObject(exec)->get(exec, "line")->toInt32(exec);
UString sourceURL = comp.value()->toObject(exec)->get(exec, "sourceURL")->toString(exec);
if (Page* page = m_frame->page())
page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, errorMessage, lineNumber, sourceURL);
}
m_processingInlineCode = false;
return 0;
}
void KJSProxy::clear()
{
if (m_globalObject)
m_globalObject->clear();
}
EventListener* KJSProxy::createHTMLEventHandler(const String& functionName, const String& code, Node* node)
{
initScriptIfNeeded();
JSLock lock;
return new JSLazyEventListener(functionName, code, Window::retrieveWindow(m_frame), node, m_handlerLineno);
}
#if ENABLE(SVG)
EventListener* KJSProxy::createSVGEventHandler(const String& functionName, const String& code, Node* node)
{
initScriptIfNeeded();
JSLock lock;
return new JSSVGLazyEventListener(functionName, code, Window::retrieveWindow(m_frame), node, m_handlerLineno);
}
#endif
void KJSProxy::finishedWithEvent(Event* event)
{
ScriptInterpreter::forgetDOMObject(event);
}
void KJSProxy::initScript()
{
if (m_globalObject)
return;
JSLock lock;
m_globalObject = new JSDOMWindow(m_frame->domWindow());
String userAgent = m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->url() : KURL());
if (userAgent.find("Microsoft") >= 0 || userAgent.find("MSIE") >= 0)
m_globalObject->setCompatMode(IECompat);
else {
if (userAgent.find("Mozilla") >= 0 && userAgent.find("compatible") == -1)
m_globalObject->setCompatMode(NetscapeCompat);
}
m_frame->loader()->dispatchWindowObjectAvailable();
}
void KJSProxy::clearDocumentWrapper()
{
if (!m_globalObject)
return;
JSLock lock;
m_globalObject->removeDirect("document");
}
bool KJSProxy::processingUserGesture() const
{
if (!m_globalObject)
return false;
if (Event* event = m_globalObject->currentEvent()) {
const AtomicString& type = event->type();
if ( type == clickEvent || type == mousedownEvent ||
type == mouseupEvent || type == dblclickEvent ||
type == keydownEvent || type == keypressEvent ||
type == keyupEvent ||
type == selectEvent || type == changeEvent ||
type == focusEvent || type == blurEvent ||
type == submitEvent)
return true;
} else { if (m_processingInlineCode && !m_processingTimerCallback) {
return true;
}
}
return false;
}
bool KJSProxy::isEnabled()
{
Settings* settings = m_frame->settings();
return (settings && settings->isJavaScriptEnabled());
}
}