JSLazyEventListener.cpp [plain text]
#include "config.h"
#include "JSLazyEventListener.h"
#include "Frame.h"
#include "JSEventTargetNode.h"
#include <runtime/FunctionConstructor.h>
using namespace JSC;
namespace WebCore {
JSLazyEventListener::JSLazyEventListener(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber)
: JSProtectedEventListener(0, globalObject, true)
, m_functionName(functionName)
, m_code(code)
, m_parsed(false)
, m_lineNumber(lineNumber)
, m_originalNode(node)
, m_type(type)
{
if (m_lineNumber == 0)
m_lineNumber = 1;
}
JSObject* JSLazyEventListener::function() const
{
parseCode();
return m_listener;
}
static inline JSValuePtr eventParameterName(JSLazyEventListener::LazyEventListenerType type, ExecState* exec)
{
switch (type) {
case JSLazyEventListener::HTMLLazyEventListener:
return jsNontrivialString(exec, "event");
#if ENABLE(SVG)
case JSLazyEventListener::SVGLazyEventListener:
return jsNontrivialString(exec, "evt");
#endif
}
ASSERT_NOT_REACHED();
return jsUndefined();
}
void JSLazyEventListener::parseCode() const
{
if (m_parsed)
return;
if (m_globalObject->scriptExecutionContext()->isDocument()) {
JSDOMWindow* window = static_cast<JSDOMWindow*>(m_globalObject.get());
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();
ArgList args;
UString sourceURL(m_globalObject->scriptExecutionContext()->url().string());
args.append(eventParameterName(m_type, exec));
args.append(jsString(exec, m_code));
m_listener = constructFunction(exec, args, Identifier(exec, m_functionName), sourceURL, m_lineNumber);
JSFunction* listenerAsFunction = static_cast<JSFunction*>(m_listener.get());
if (exec->hadException()) {
exec->clearException();
m_listener = 0;
} else if (m_originalNode) {
ScopeChain scope = listenerAsFunction->scope();
JSValuePtr thisObj = toJS(exec, m_originalNode);
if (thisObj.isObject()) {
static_cast<JSEventTargetNode*>(asObject(thisObj))->pushEventHandlerScope(exec, scope);
listenerAsFunction->setScope(scope);
}
}
m_functionName = String();
m_code = String();
if (m_listener) {
ASSERT(isInline());
JSDOMWindow::ProtectedListenersMap& listeners = m_globalObject->jsProtectedInlineEventListeners();
listeners.set(m_listener, const_cast<JSLazyEventListener*>(this));
}
}
}