JSLazyEventListener.cpp [plain text]
#include "config.h"
#include "JSLazyEventListener.h"
#include "Frame.h"
#include "JSNode.h"
#include <runtime/FunctionConstructor.h>
#include <runtime/JSLock.h>
#include <wtf/RefCountedLeakCounter.h>
using namespace JSC;
namespace WebCore {
#ifndef NDEBUG
static WTF::RefCountedLeakCounter eventListenerCounter("JSLazyEventListener");
#endif
JSLazyEventListener::JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber)
: JSEventListener(0, globalObject, true)
, m_functionName(functionName)
, m_eventParameterName(eventParameterName)
, m_code(code)
, m_parsed(false)
, m_lineNumber(lineNumber)
, m_originalNode(node)
{
if (m_lineNumber == 0)
m_lineNumber = 1;
#ifndef NDEBUG
eventListenerCounter.increment();
#endif
}
JSLazyEventListener::~JSLazyEventListener()
{
#ifndef NDEBUG
eventListenerCounter.decrement();
#endif
}
JSObject* JSLazyEventListener::jsFunction() const
{
parseCode();
return m_jsFunction;
}
void JSLazyEventListener::parseCode() const
{
if (m_parsed)
return;
ScriptExecutionContext* executionContext = m_globalObject->scriptExecutionContext();
ASSERT(executionContext);
if (!executionContext)
return;
if (executionContext->isDocument()) {
JSDOMWindow* window = static_cast<JSDOMWindow*>(m_globalObject);
Frame* frame = window->impl()->frame();
if (!frame)
return;
ScriptController* script = frame->script();
if (!script->isEnabled() || script->isPaused())
return;
}
m_parsed = true;
ExecState* exec = m_globalObject->globalExec();
MarkedArgumentBuffer args;
UString sourceURL(executionContext->url().string());
args.append(jsNontrivialString(exec, m_eventParameterName));
args.append(jsString(exec, m_code));
m_jsFunction = constructFunction(exec, args, Identifier(exec, m_functionName), sourceURL, m_lineNumber);
JSFunction* listenerAsFunction = static_cast<JSFunction*>(m_jsFunction);
if (exec->hadException()) {
exec->clearException();
m_jsFunction = 0;
} else if (m_originalNode) {
ScopeChain scope = listenerAsFunction->scope();
JSValue thisObj = toJS(exec, m_originalNode);
if (thisObj.isObject()) {
static_cast<JSNode*>(asObject(thisObj))->pushEventHandlerScope(exec, scope);
listenerAsFunction->setScope(scope);
}
}
m_functionName = String();
m_code = String();
m_eventParameterName = String();
}
}