示例#1
0
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();
  }
}
示例#2
0
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;
  }
}