void JSEventListener::handleEvent(DOM::Event &evt) { KHTMLPart *part = qobject_cast<KHTMLPart*>(static_cast<Window*>(win.get())->part()); KJSProxy *proxy = 0L; if (part) proxy = part->jScript(); if (proxy && listener && listener->implementsCall()) { #ifdef KJS_DEBUGGER //### This is the wrong place to do this --- we need // a more global/general stategy to prevent unwanted event loop recursion issues. if (proxy->debugEnabled() && DebugWindow::window()->inSession()) return; #endif ref(); KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter()); ExecState *exec = interpreter->globalExec(); List args; args.append(getDOMEvent(exec,evt.handle())); JSObject *thisObj = 0; // Check whether handler is a function or an object with handleEvent method if (listener == compareListenerImp) { // Set "this" to the event's current target thisObj = getEventTarget(exec,evt.handle()->currentTarget())->getObject(); } else { thisObj = compareListenerImp; } if ( !thisObj ) { // ### can this still happen? eventTarget should be window on Window events now. thisObj = win; } Window *window = static_cast<Window*>(win.get()); // Set the event we're handling in the Window object window->setCurrentEvent( evt.handle() ); // ... and in the interpreter interpreter->setCurrentEvent( &evt ); interpreter->startCPUGuard(); JSValue *retval = listener->call(exec, thisObj, args); interpreter->stopCPUGuard(); window->setCurrentEvent( 0 ); interpreter->setCurrentEvent( 0 ); if ( exec->hadException() ) exec->clearException(); else if (html) { QVariant ret = ValueToVariant(exec, retval); if (ret.type() == QVariant::Bool && ret.toBool() == false) evt.preventDefault(); } window->afterScriptExecution(); deref(); } }
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(); } }
void JSLazyEventListener::parseCode() const { if (!parsed) { KHTMLPart *part = qobject_cast<KHTMLPart*>(static_cast<Window*>(win.get())->part()); KJSProxy *proxy = 0L; if (part) proxy = part->jScript(); if (proxy) { KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter()); ExecState *exec = interpreter->globalExec(); //KJS::Constructor constr(KJS::Global::current().get("Function").imp()); KJS::FunctionObjectImp *constr = static_cast<KJS::FunctionObjectImp*>(interpreter->builtinFunction()); KJS::List args; if (svg) args.append(jsString("evt")); else args.append(jsString("event")); args.append(jsString(code)); listener = constr->construct(exec, args, Identifier(UString(name)), url, lineNum); // ### is globalExec ok ? compareListenerImp = listener; if (exec->hadException()) { exec->clearException(); // failed to parse, so let's just make this listener a no-op listener = 0; } else if (!listener->inherits(&DeclaredFunctionImp::info)) { listener = 0;// Error creating function } else { DeclaredFunctionImp *declFunc = static_cast<DeclaredFunctionImp*>(listener.get()); if (originalNode) { // Add the event's home element to the scope // (and the document, and the form - see KJS::HTMLElement::eventHandlerScope) ScopeChain scope = declFunc->scope(); JSObject *thisObj = getDOMNode(exec, originalNode)->getObject(); if (thisObj) { static_cast<DOMNode*>(thisObj)->pushEventHandlerScope(exec, scope); declFunc->setScope(scope); } } } } // no more need to keep the unparsed code around code.clear(); if (listener) { static_cast<Window*>(win.get())->jsEventListeners.insert(QPair<void*, bool>(compareListenerImp.get(), true), (KJS::JSEventListener *)(this)); } parsed = true; } }