void JSLazyEventListener::parseCode() const { if (m_parsed) return; m_parsed = true; Frame* frame = windowObj()->impl()->frame(); KJSProxy* proxy = 0; if (frame) proxy = frame->scriptProxy(); if (proxy) { ScriptInterpreter* interpreter = proxy->interpreter(); ExecState* exec = interpreter->globalExec(); JSLock lock; JSObject* constr = interpreter->builtinFunction(); List args; UString sourceURL(frame->loader()->url().url()); args.append(eventParameterName()); args.append(jsString(m_code)); m_listener = constr->construct(exec, args, m_functionName, sourceURL, m_lineNumber); // FIXME: is globalExec ok ? FunctionImp* listenerAsFunction = static_cast<FunctionImp*>(m_listener.get()); if (exec->hadException()) { exec->clearException(); // failed to parse, so let's just make this listener a no-op m_listener = 0; } else if (m_originalNode) { // Add the event's home element to the scope // (and the document, and the form - see JSHTMLElement::eventHandlerScope) ScopeChain scope = listenerAsFunction->scope(); JSValue* thisObj = toJS(exec, m_originalNode); if (thisObj->isObject()) { static_cast<JSEventTargetNode*>(thisObj)->pushEventHandlerScope(exec, scope); listenerAsFunction->setScope(scope); } } } // no more need to keep the unparsed code around m_functionName = String(); m_code = String(); if (m_listener) { Window::ListenersMap& listeners = isHTMLEventListener() ? windowObj()->jsHTMLEventListeners() : windowObj()->jsEventListeners(); listeners.set(m_listener, const_cast<JSLazyEventListener*>(this)); } }
void JSAbstractEventListener::handleEvent(Event* ele, bool isWindowEvent) { #ifdef KJS_DEBUGGER if (KJSDebugWin::instance() && KJSDebugWin::instance()->inSession()) return; #endif Event *event = ele; JSObject* listener = listenerObj(); if (!listener) return; Window* window = windowObj(); Frame *frame = window->frame(); if (!frame) return; KJSProxy* proxy = frame->jScript(); if (!proxy) return; JSLock lock; ScriptInterpreter* interpreter = proxy->interpreter(); ExecState* exec = interpreter->globalExec(); JSValue* handleEventFuncValue = listener->get(exec, "handleEvent"); JSObject* handleEventFunc = 0; if (handleEventFuncValue->isObject()) { handleEventFunc = static_cast<JSObject*>(handleEventFuncValue); if (!handleEventFunc->implementsCall()) handleEventFunc = 0; } if (handleEventFunc || listener->implementsCall()) { ref(); List args; args.append(toJS(exec, event)); // Set the event we're handling in the Window object window->setCurrentEvent(event); // ... and in the interpreter interpreter->setCurrentEvent(event); JSValue* retval; if (handleEventFunc) { interpreter->startTimeoutCheck(); retval = handleEventFunc->call(exec, listener, args); } else { JSObject* thisObj; if (isWindowEvent) thisObj = window; else thisObj = static_cast<JSObject*>(toJS(exec, event->currentTarget())); interpreter->startTimeoutCheck(); retval = listener->call(exec, thisObj, args); } interpreter->stopTimeoutCheck(); window->setCurrentEvent(0); interpreter->setCurrentEvent(0); if (exec->hadException()) { JSObject* exception = exec->exception()->toObject(exec); String message = exception->get(exec, messagePropertyName)->toString(exec); int lineNumber = exception->get(exec, "line")->toInt32(exec); String sourceURL = exception->get(exec, "sourceURL")->toString(exec); if (Interpreter::shouldPrintExceptions()) printf("(event handler):%s\n", message.deprecatedString().utf8().data()); frame->addMessageToConsole(message, lineNumber, sourceURL); exec->clearException(); } else { if (!retval->isUndefinedOrNull() && event->storesResultAsString()) event->storeResult(retval->toString(exec)); if (html) { bool retvalbool; if (retval->getBoolean(retvalbool) && !retvalbool) event->preventDefault(); } } Document::updateDocumentsRendering(); deref(); } }