khtml Library API Documentation

kjs_events.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /*
00003  *  This file is part of the KDE libraries
00004  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
00005  *  Copyright (C) 2003 Apple Computer, Inc.
00006  *
00007  *  This library is free software; you can redistribute it and/or
00008  *  modify it under the terms of the GNU Library General Public
00009  *  License as published by the Free Software Foundation; either
00010  *  version 2 of the License, or (at your option) any later version.
00011  *
00012  *  This library is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  *  Library General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU Library General Public
00018  *  License along with this library; if not, write to the Free Software
00019  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  */
00021 
00022 #include "kjs_window.h"
00023 #include "kjs_events.h"
00024 #include "kjs_events.lut.h"
00025 #include "kjs_views.h"
00026 #include "kjs_proxy.h"
00027 #include "xml/dom_nodeimpl.h"
00028 #include "xml/dom_docimpl.h"
00029 #include "xml/dom2_eventsimpl.h"
00030 #include "rendering/render_object.h"
00031 #include "xml/dom2_eventsimpl.h"
00032 
00033 #include <kdebug.h>
00034 
00035 using namespace KJS;
00036 using namespace DOM;
00037 
00038 // -------------------------------------------------------------------------
00039 
00040 JSEventListener::JSEventListener(Object _listener, const Object &_win, bool _html)
00041   : listener( _listener ), html( _html ), win( _win )
00042 {
00043     //fprintf(stderr,"JSEventListener::JSEventListener this=%p listener=%p\n",this,listener.imp());
00044     static_cast<Window*>(win.imp())->jsEventListeners.insert(this, this);
00045 }
00046 
00047 JSEventListener::~JSEventListener()
00048 {
00049     static_cast<Window*>(win.imp())->jsEventListeners.remove(this);
00050     //fprintf(stderr,"JSEventListener::~JSEventListener this=%p listener=%p\n",this,listener.imp());
00051 }
00052 
00053 void JSEventListener::handleEvent(DOM::Event &evt)
00054 {
00055 #ifdef KJS_DEBUGGER
00056   if (KJSDebugWin::debugWindow() && KJSDebugWin::debugWindow()->inSession())
00057     return;
00058 #endif
00059   KHTMLPart *part = static_cast<Window*>(win.imp())->part();
00060   KJSProxy *proxy = 0L;
00061   if (part)
00062     proxy = KJSProxy::proxy( part );
00063 
00064   if (proxy && listener.implementsCall()) {
00065     ref();
00066 
00067     KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter());
00068     ExecState *exec = interpreter->globalExec();
00069 
00070     List args;
00071     args.append(getDOMEvent(exec,evt));
00072 
00073     // Set "this" to the event's current target
00074     Object thisObj = Object::dynamicCast(getDOMNode(exec,evt.currentTarget()));
00075     ScopeChain oldScope = listener.scope();
00076     if ( thisObj.isValid() ) {
00077       ScopeChain scope = oldScope;
00078       // Add the event's target element to the scope
00079       // (and the document, and the form - see KJS::HTMLElement::eventHandlerScope)
00080       static_cast<DOMNode*>(thisObj.imp())->pushEventHandlerScope(exec, scope);
00081       listener.setScope( scope );
00082     }
00083     else {
00084       if ( m_hackThisObj.isValid() ) { // special hack for Image
00085         thisObj = m_hackThisObj;
00086       }
00087       else
00088       {
00089         // Window events (window.onload/window.onresize etc.) must have 'this' set to the window.
00090         // DocumentImpl::defaultEventHandler sets currentTarget to 0 to mean 'window'.
00091         thisObj = win;
00092       }
00093     }
00094 
00095     Window *window = static_cast<Window*>(win.imp());
00096     // Set the event we're handling in the Window object
00097     window->setCurrentEvent( &evt );
00098     // ... and in the interpreter
00099     interpreter->setCurrentEvent( &evt );
00100 
00101     KJSCPUGuard guard;
00102     guard.start();
00103     Value retval = listener.call(exec, thisObj, args);
00104     guard.stop();
00105 
00106     listener.setScope( oldScope );
00107 
00108     window->setCurrentEvent( 0 );
00109     interpreter->setCurrentEvent( 0 );
00110     if ( exec->hadException() )
00111       exec->clearException();
00112     else
00113     {
00114       QVariant ret = ValueToVariant(exec, retval);
00115       if (ret.type() == QVariant::Bool && ret.toBool() == false)
00116         evt.preventDefault();
00117     }
00118     window->afterScriptExecution();
00119     deref();
00120   }
00121 }
00122 
00123 DOM::DOMString JSEventListener::eventListenerType()
00124 {
00125     if (html)
00126     return "_khtml_HTMLEventListener";
00127     else
00128     return "_khtml_JSEventListener";
00129 }
00130 
00131 Value KJS::getNodeEventListener(DOM::Node n, int eventId)
00132 {
00133     DOM::EventListener *listener = n.handle()->getHTMLEventListener(eventId);
00134     if (listener)
00135     return static_cast<JSEventListener*>(listener)->listenerObj();
00136     else
00137     return Null();
00138 }
00139 
00140 // -------------------------------------------------------------------------
00141 
00142 const ClassInfo EventConstructor::info = { "EventConstructor", 0, &EventConstructorTable, 0 };
00143 /*
00144 @begin EventConstructorTable 3
00145   CAPTURING_PHASE   DOM::Event::CAPTURING_PHASE DontDelete|ReadOnly
00146   AT_TARGET     DOM::Event::AT_TARGET       DontDelete|ReadOnly
00147   BUBBLING_PHASE    DOM::Event::BUBBLING_PHASE  DontDelete|ReadOnly
00148 # Reverse-engineered from Netscape
00149   MOUSEDOWN     1               DontDelete|ReadOnly
00150   MOUSEUP       2               DontDelete|ReadOnly
00151   MOUSEOVER     4               DontDelete|ReadOnly
00152   MOUSEOUT      8               DontDelete|ReadOnly
00153   MOUSEMOVE     16              DontDelete|ReadOnly
00154   MOUSEDRAG     32              DontDelete|ReadOnly
00155   CLICK         64              DontDelete|ReadOnly
00156   DBLCLICK      128             DontDelete|ReadOnly
00157   KEYDOWN       256             DontDelete|ReadOnly
00158   KEYUP         512             DontDelete|ReadOnly
00159   KEYPRESS      1024                DontDelete|ReadOnly
00160   DRAGDROP      2048                DontDelete|ReadOnly
00161   FOCUS         4096                DontDelete|ReadOnly
00162   BLUR          8192                DontDelete|ReadOnly
00163   SELECT        16384               DontDelete|ReadOnly
00164   CHANGE        32768               DontDelete|ReadOnly
00165 @end
00166 */
00167 
00168 EventConstructor::EventConstructor(ExecState *exec)
00169   : DOMObject(exec->interpreter()->builtinObjectPrototype())
00170 {
00171 }
00172 
00173 Value EventConstructor::tryGet(ExecState *exec, const Identifier &p) const
00174 {
00175   return DOMObjectLookupGetValue<EventConstructor, DOMObject>(exec,p,&EventConstructorTable,this);
00176 }
00177 
00178 Value EventConstructor::getValueProperty(ExecState *, int token) const
00179 {
00180   // We use the token as the value to return directly
00181   return Number(token);
00182 }
00183 
00184 Value KJS::getEventConstructor(ExecState *exec)
00185 {
00186   return cacheGlobalObject<EventConstructor>(exec, "[[event.constructor]]");
00187 }
00188 
00189 // -------------------------------------------------------------------------
00190 
00191 const ClassInfo DOMEvent::info = { "Event", 0, &DOMEventTable, 0 };
00192 /*
00193 @begin DOMEventTable 7
00194   type      DOMEvent::Type      DontDelete|ReadOnly
00195   target    DOMEvent::Target    DontDelete|ReadOnly
00196   currentTarget DOMEvent::CurrentTarget DontDelete|ReadOnly
00197   srcElement    DOMEvent::SrcElement    DontDelete|ReadOnly
00198   eventPhase    DOMEvent::EventPhase    DontDelete|ReadOnly
00199   bubbles   DOMEvent::Bubbles   DontDelete|ReadOnly
00200   cancelable    DOMEvent::Cancelable    DontDelete|ReadOnly
00201   timeStamp DOMEvent::TimeStamp DontDelete|ReadOnly
00202   returnValue   DOMEvent::ReturnValue   DontDelete
00203   cancelBubble  DOMEvent::CancelBubble  DontDelete
00204 @end
00205 @begin DOMEventProtoTable 3
00206   stopPropagation   DOMEvent::StopPropagation   DontDelete|Function 0
00207   preventDefault    DOMEvent::PreventDefault    DontDelete|Function 0
00208   initEvent     DOMEvent::InitEvent     DontDelete|Function 3
00209 @end
00210 */
00211 DEFINE_PROTOTYPE("DOMEvent", DOMEventProto)
00212 IMPLEMENT_PROTOFUNC_DOM(DOMEventProtoFunc)
00213 IMPLEMENT_PROTOTYPE(DOMEventProto, DOMEventProtoFunc)
00214 
00215 DOMEvent::DOMEvent(ExecState *exec, DOM::Event e)
00216   : DOMObject(DOMEventProto::self(exec)), event(e) { }
00217 
00218 DOMEvent::DOMEvent(const Object &proto, DOM::Event e)
00219   : DOMObject(proto), event(e) { }
00220 
00221 DOMEvent::~DOMEvent()
00222 {
00223   ScriptInterpreter::forgetDOMObject(event.handle());
00224 }
00225 
00226 Value DOMEvent::tryGet(ExecState *exec, const Identifier &p) const
00227 {
00228 #ifdef KJS_VERBOSE
00229   kdDebug() << "KJS::DOMEvent::tryGet " << p.qstring() << endl;
00230 #endif
00231   return DOMObjectLookupGetValue<DOMEvent,DOMObject>(exec, p, &DOMEventTable, this );
00232 }
00233 
00234 Value DOMEvent::getValueProperty(ExecState *exec, int token) const
00235 {
00236   switch (token) {
00237   case Type:
00238     return String(event.type());
00239   case Target:
00240   case SrcElement: /*MSIE extension - "the object that fired the event"*/
00241     return getDOMNode(exec,event.target());
00242   case CurrentTarget:
00243     return getDOMNode(exec,event.currentTarget());
00244   case EventPhase:
00245     return Number((unsigned int)event.eventPhase());
00246   case Bubbles:
00247     return Boolean(event.bubbles());
00248   case Cancelable:
00249     return Boolean(event.cancelable());
00250   case TimeStamp:
00251     return Number((long unsigned int)event.timeStamp()); // ### long long ?
00252   case ReturnValue: // MSIE extension
00253     return Boolean(event.handle()->defaultPrevented());
00254   case CancelBubble: // MSIE extension
00255     return Boolean(event.handle()->propagationStopped());
00256   default:
00257     kdDebug(6070) << "WARNING: Unhandled token in DOMEvent::getValueProperty : " << token << endl;
00258     return Value();
00259   }
00260 }
00261 
00262 Value DOMEvent::defaultValue(ExecState *exec, KJS::Type hint) const
00263 {
00264   if (event.handle()->id() == EventImpl::ERROR_EVENT && !event.handle()->message().isNull()) {
00265     return String(event.handle()->message());
00266   }
00267   else
00268     return DOMObject::defaultValue(exec,hint);
00269 }
00270 
00271 void DOMEvent::tryPut(ExecState *exec, const Identifier &propertyName,
00272                       const Value& value, int attr)
00273 {
00274   DOMObjectLookupPut<DOMEvent, DOMObject>(exec, propertyName, value, attr,
00275                                           &DOMEventTable, this);
00276 }
00277 
00278 void DOMEvent::putValueProperty(ExecState *exec, int token, const Value& value, int)
00279 {
00280   switch (token) {
00281   case ReturnValue: // MSIE equivalent for "preventDefault" (but with a way to reset it)
00282     // returnValue=false means "default action of the event on the source object is canceled",
00283     // which means preventDefault(true). Hence the '!'.
00284     event.handle()->preventDefault(!value.toBoolean(exec));
00285     break;
00286   case CancelBubble: // MSIE equivalent for "stopPropagation" (but with a way to reset it)
00287     event.handle()->stopPropagation(value.toBoolean(exec));
00288     break;
00289   default:
00290     break;
00291   }
00292 }
00293 
00294 Value DOMEventProtoFunc::tryCall(ExecState *exec, Object & thisObj, const List &args)
00295 {
00296   KJS_CHECK_THIS( KJS::DOMEvent, thisObj );
00297   DOM::Event event = static_cast<DOMEvent *>( thisObj.imp() )->toEvent();
00298   switch (id) {
00299     case DOMEvent::StopPropagation:
00300       event.stopPropagation();
00301       return Undefined();
00302     case DOMEvent::PreventDefault:
00303       event.preventDefault();
00304       return Undefined();
00305     case DOMEvent::InitEvent:
00306       event.initEvent(args[0].toString(exec).string(),args[1].toBoolean(exec),args[2].toBoolean(exec));
00307       return Undefined();
00308   };
00309   return Undefined();
00310 }
00311 
00312 Value KJS::getDOMEvent(ExecState *exec, DOM::Event e)
00313 {
00314   DOMObject *ret;
00315   if (e.isNull())
00316     return Null();
00317   ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
00318   if ((ret = interp->getDOMObject(e.handle())))
00319     return Value(ret);
00320 
00321   DOM::DOMString module = e.eventModuleName();
00322   if (module == "UIEvents")
00323     ret = new DOMUIEvent(exec, static_cast<DOM::UIEvent>(e));
00324   else if (module == "MouseEvents")
00325     ret = new DOMMouseEvent(exec, static_cast<DOM::MouseEvent>(e));
00326   else if (module == "TextEvents")
00327     ret = new DOMTextEvent(exec, static_cast<DOM::TextEvent>(e));
00328   else if (module == "MutationEvents")
00329     ret = new DOMMutationEvent(exec, static_cast<DOM::MutationEvent>(e));
00330   else
00331     ret = new DOMEvent(exec, e);
00332 
00333   interp->putDOMObject(e.handle(),ret);
00334   return Value(ret);
00335 }
00336 
00337 DOM::Event KJS::toEvent(const Value& val)
00338 {
00339   Object obj = Object::dynamicCast(val);
00340   if (obj.isNull() || !obj.inherits(&DOMEvent::info))
00341     return DOM::Event();
00342 
00343   const DOMEvent *dobj = static_cast<const DOMEvent*>(obj.imp());
00344   return dobj->toEvent();
00345 }
00346 
00347 // -------------------------------------------------------------------------
00348 
00349 
00350 const ClassInfo EventExceptionConstructor::info = { "EventExceptionConstructor", 0, &EventExceptionConstructorTable, 0 };
00351 /*
00352 @begin EventExceptionConstructorTable 1
00353   UNSPECIFIED_EVENT_TYPE_ERR    DOM::EventException::UNSPECIFIED_EVENT_TYPE_ERR DontDelete|ReadOnly
00354 @end
00355 */
00356 EventExceptionConstructor::EventExceptionConstructor(ExecState *exec)
00357   : DOMObject(exec->interpreter()->builtinObjectPrototype())
00358 {
00359 }
00360 
00361 Value EventExceptionConstructor::tryGet(ExecState *exec, const Identifier &p) const
00362 {
00363   return DOMObjectLookupGetValue<EventExceptionConstructor, DOMObject>(exec,p,&EventExceptionConstructorTable,this);
00364 }
00365 
00366 Value EventExceptionConstructor::getValueProperty(ExecState *, int token) const
00367 {
00368   // We use the token as the value to return directly
00369   return Number(token);
00370 }
00371 
00372 Value KJS::getEventExceptionConstructor(ExecState *exec)
00373 {
00374   return cacheGlobalObject<EventExceptionConstructor>(exec, "[[eventException.constructor]]");
00375 }
00376 
00377 // -------------------------------------------------------------------------
00378 
00379 const ClassInfo DOMUIEvent::info = { "UIEvent", &DOMEvent::info, &DOMUIEventTable, 0 };
00380 /*
00381 @begin DOMUIEventTable 7
00382   view      DOMUIEvent::View    DontDelete|ReadOnly
00383   detail    DOMUIEvent::Detail  DontDelete|ReadOnly
00384   keyCode   DOMUIEvent::KeyCode DontDelete|ReadOnly
00385   layerX    DOMUIEvent::LayerX  DontDelete|ReadOnly
00386   layerY    DOMUIEvent::LayerY  DontDelete|ReadOnly
00387   pageX     DOMUIEvent::PageX   DontDelete|ReadOnly
00388   pageY     DOMUIEvent::PageY   DontDelete|ReadOnly
00389   which     DOMUIEvent::Which   DontDelete|ReadOnly
00390 @end
00391 @begin DOMUIEventProtoTable 1
00392   initUIEvent   DOMUIEvent::InitUIEvent DontDelete|Function 5
00393 @end
00394 */
00395 DEFINE_PROTOTYPE("DOMUIEvent",DOMUIEventProto)
00396 IMPLEMENT_PROTOFUNC_DOM(DOMUIEventProtoFunc)
00397 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMUIEventProto,DOMUIEventProtoFunc,DOMEventProto)
00398 
00399 DOMUIEvent::DOMUIEvent(ExecState *exec, DOM::UIEvent ue) :
00400   DOMEvent(DOMUIEventProto::self(exec), ue) {}
00401 
00402 DOMUIEvent::DOMUIEvent(const Object &proto, DOM::UIEvent ue) :
00403   DOMEvent(proto, ue) {}
00404 
00405 DOMUIEvent::~DOMUIEvent()
00406 {
00407 }
00408 
00409 Value DOMUIEvent::tryGet(ExecState *exec, const Identifier &p) const
00410 {
00411   return DOMObjectLookupGetValue<DOMUIEvent,DOMEvent>(exec,p,&DOMUIEventTable,this);
00412 }
00413 
00414 Value DOMUIEvent::getValueProperty(ExecState *exec, int token) const
00415 {
00416   switch (token) {
00417   case View:
00418     return getDOMAbstractView(exec,static_cast<DOM::UIEvent>(event).view());
00419   case Detail:
00420     return Number(static_cast<DOM::UIEvent>(event).detail());
00421   case KeyCode:
00422     // IE-compatibility
00423     return Number(static_cast<DOM::UIEvent>(event).keyCode());
00424   case LayerX:
00425     // NS-compatibility
00426     return Number(static_cast<DOM::UIEvent>(event).layerX());
00427   case LayerY:
00428     // NS-compatibility
00429     return Number(static_cast<DOM::UIEvent>(event).layerY());
00430   case PageX:
00431     // NS-compatibility
00432     if (event.handle() && event.handle()->isMouseEvent()) // defined for mouse events only
00433       return Number(static_cast<DOM::MouseEvent>(event).clientX());
00434     return Number(0);
00435   case PageY:
00436     // NS-compatibility
00437     if (event.handle() && event.handle()->isMouseEvent()) // defined for mouse events only
00438       return Number(static_cast<DOM::MouseEvent>(event).clientY());
00439     return Number(0);
00440   case Which:
00441     // NS-compatibility
00442     return Number(static_cast<DOM::UIEvent>(event).which());
00443   default:
00444     kdDebug(6070) << "WARNING: Unhandled token in DOMUIEvent::getValueProperty : " << token << endl;
00445     return Undefined();
00446   }
00447 }
00448 
00449 Value DOMUIEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00450 {
00451   KJS_CHECK_THIS( KJS::DOMUIEvent, thisObj );
00452   DOM::UIEvent uiEvent = static_cast<DOMUIEvent *>(thisObj.imp())->toUIEvent();
00453   switch (id) {
00454     case DOMUIEvent::InitUIEvent: {
00455       DOM::AbstractView v = toAbstractView(args[3]);
00456       static_cast<DOM::UIEvent>(uiEvent).initUIEvent(args[0].toString(exec).string(),
00457                                                      args[1].toBoolean(exec),
00458                                                      args[2].toBoolean(exec),
00459                                                      v,
00460                                                      args[4].toInteger(exec));
00461       }
00462       return Undefined();
00463   }
00464   return Undefined();
00465 }
00466 
00467 // -------------------------------------------------------------------------
00468 
00469 const ClassInfo DOMMouseEvent::info = { "MouseEvent", &DOMUIEvent::info, &DOMMouseEventTable, 0 };
00470 
00471 /*
00472 @begin DOMMouseEventTable 2
00473   altKey    DOMMouseEvent::AltKey   DontDelete|ReadOnly
00474   button    DOMMouseEvent::Button   DontDelete|ReadOnly
00475   clientX   DOMMouseEvent::ClientX  DontDelete|ReadOnly
00476   clientY   DOMMouseEvent::ClientY  DontDelete|ReadOnly
00477   ctrlKey   DOMMouseEvent::CtrlKey  DontDelete|ReadOnly
00478   fromElement   DOMMouseEvent::FromElement DontDelete|ReadOnly
00479   metaKey   DOMMouseEvent::MetaKey  DontDelete|ReadOnly
00480   offsetX   DOMMouseEvent::OffsetX  DontDelete|ReadOnly
00481   offsetY   DOMMouseEvent::OffsetY  DontDelete|ReadOnly
00482   relatedTarget DOMMouseEvent::RelatedTarget DontDelete|ReadOnly
00483   screenX   DOMMouseEvent::ScreenX  DontDelete|ReadOnly
00484   screenY   DOMMouseEvent::ScreenY  DontDelete|ReadOnly
00485   shiftKey  DOMMouseEvent::ShiftKey DontDelete|ReadOnly
00486   toElement DOMMouseEvent::ToElement    DontDelete|ReadOnly
00487   x     DOMMouseEvent::X    DontDelete|ReadOnly
00488   y     DOMMouseEvent::Y    DontDelete|ReadOnly
00489 @end
00490 @begin DOMMouseEventProtoTable 1
00491   initMouseEvent    DOMMouseEvent::InitMouseEvent   DontDelete|Function 15
00492 @end
00493 */
00494 DEFINE_PROTOTYPE("DOMMouseEvent",DOMMouseEventProto)
00495 IMPLEMENT_PROTOFUNC_DOM(DOMMouseEventProtoFunc)
00496 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMMouseEventProto,DOMMouseEventProtoFunc,DOMUIEventProto)
00497 
00498 DOMMouseEvent::DOMMouseEvent(ExecState *exec, DOM::MouseEvent me) :
00499   DOMUIEvent(DOMMouseEventProto::self(exec), me) {}
00500 
00501 DOMMouseEvent::~DOMMouseEvent()
00502 {
00503 }
00504 
00505 Value DOMMouseEvent::tryGet(ExecState *exec, const Identifier &p) const
00506 {
00507 #ifdef KJS_VERBOSE
00508   kdDebug(6070) << "DOMMouseEvent::tryGet " << p.qstring() << endl;
00509 #endif
00510   return DOMObjectLookupGetValue<DOMMouseEvent,DOMUIEvent>(exec,p,&DOMMouseEventTable,this);
00511 }
00512 
00513 Value DOMMouseEvent::getValueProperty(ExecState *exec, int token) const
00514 {
00515   switch (token) {
00516   case ScreenX:
00517     return Number(static_cast<DOM::MouseEvent>(event).screenX());
00518   case ScreenY:
00519     return Number(static_cast<DOM::MouseEvent>(event).screenY());
00520   case ClientX:
00521   case X:
00522     return Number(static_cast<DOM::MouseEvent>(event).clientX());
00523   case ClientY:
00524   case Y:
00525     return Number(static_cast<DOM::MouseEvent>(event).clientY());
00526   case OffsetX:
00527   case OffsetY: // MSIE extension
00528   {
00529     DOM::Node node = event.target();
00530     node.handle()->getDocument()->updateRendering();
00531     khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L;
00532     int x = static_cast<DOM::MouseEvent>(event).clientX();
00533     int y = static_cast<DOM::MouseEvent>(event).clientY();
00534     if ( rend ) {
00535       int xPos, yPos;
00536       if ( rend->absolutePosition( xPos, yPos ) ) {
00537         kdDebug() << "DOMMouseEvent::getValueProperty rend=" << rend << "  xPos=" << xPos << "  yPos=" << yPos << endl;
00538         x -= xPos;
00539         y -= yPos;
00540       }
00541     }
00542     return Number( token == OffsetX ? x : y );
00543   }
00544   case CtrlKey:
00545     return Boolean(static_cast<DOM::MouseEvent>(event).ctrlKey());
00546   case ShiftKey:
00547     return Boolean(static_cast<DOM::MouseEvent>(event).shiftKey());
00548   case AltKey:
00549     return Boolean(static_cast<DOM::MouseEvent>(event).altKey());
00550   case MetaKey:
00551     return Boolean(static_cast<DOM::MouseEvent>(event).metaKey());
00552   case Button:
00553   {
00554     // Tricky. The DOM (and khtml) use 0 for LMB, 1 for MMB and 2 for RMB
00555     // but MSIE uses 1=LMB, 2=RMB, 4=MMB, as a bitfield
00556     int domButton = static_cast<DOM::MouseEvent>(event).button();
00557     int button = domButton==0 ? 1 : domButton==1 ? 4 : domButton==2 ? 2 : 0;
00558     return Number( (unsigned int)button );
00559   }
00560   case ToElement:
00561     // MSIE extension - "the object toward which the user is moving the mouse pointer"
00562     if (event.handle()->id() == DOM::EventImpl::MOUSEOUT_EVENT)
00563       return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).relatedTarget());
00564     return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).target());
00565   case FromElement:
00566     // MSIE extension - "object from which activation
00567     // or the mouse pointer is exiting during the event" (huh?)
00568     if (event.handle()->id() == DOM::EventImpl::MOUSEOUT_EVENT)
00569       return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).target());
00570     /* fall through */
00571   case RelatedTarget:
00572     return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).relatedTarget());
00573   default:
00574     kdDebug(6070) << "WARNING: Unhandled token in DOMMouseEvent::getValueProperty : " << token << endl;
00575     return Value();
00576   }
00577 }
00578 
00579 Value DOMMouseEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00580 {
00581   KJS_CHECK_THIS( KJS::DOMMouseEvent, thisObj );
00582   DOM::MouseEvent mouseEvent = static_cast<DOMMouseEvent *>(thisObj.imp())->toMouseEvent();
00583   switch (id) {
00584     case DOMMouseEvent::InitMouseEvent:
00585       mouseEvent.initMouseEvent(args[0].toString(exec).string(), // typeArg
00586                                 args[1].toBoolean(exec), // canBubbleArg
00587                                 args[2].toBoolean(exec), // cancelableArg
00588                                 toAbstractView(args[3]), // viewArg
00589                                 args[4].toInteger(exec), // detailArg
00590                                 args[5].toInteger(exec), // screenXArg
00591                                 args[6].toInteger(exec), // screenYArg
00592                                 args[7].toInteger(exec), // clientXArg
00593                                 args[8].toInteger(exec), // clientYArg
00594                                 args[9].toBoolean(exec), // ctrlKeyArg
00595                                 args[10].toBoolean(exec), // altKeyArg
00596                                 args[11].toBoolean(exec), // shiftKeyArg
00597                                 args[12].toBoolean(exec), // metaKeyArg
00598                                 args[13].toInteger(exec), // buttonArg
00599                                 toNode(args[14])); // relatedTargetArg
00600       return Undefined();
00601   }
00602   return Undefined();
00603 }
00604 
00605 // -------------------------------------------------------------------------
00606 
00607 const ClassInfo DOMTextEvent::info = { "TextEvent", &DOMUIEvent::info, &DOMTextEventTable, 0 };
00608 
00609 /*
00610 @begin DOMTextEventTable 2
00611   keyVal     DOMTextEvent::Key       DontDelete|ReadOnly
00612   virtKeyVal     DOMTextEvent::VirtKey        DontDelete|ReadOnly
00613   outputString   DOMTextEvent::OutputString   DontDelete|ReadOnly
00614   inputGenerated DOMTextEvent::InputGenerated DontDelete|ReadOnly
00615   numPad         DOMTextEvent::NumPad         DontDelete|ReadOnly
00616 @end
00617 @begin DOMTextEventProtoTable 1
00618   initTextEvent DOMTextEvent::InitTextEvent DontDelete|Function 10
00619   # Missing: initTextEventNS, initModifier
00620 @end
00621 */
00622 DEFINE_PROTOTYPE("DOMTextEvent",DOMTextEventProto)
00623 IMPLEMENT_PROTOFUNC_DOM(DOMTextEventProtoFunc)
00624 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMTextEventProto,DOMTextEventProtoFunc,DOMUIEventProto)
00625 
00626 DOMTextEvent::DOMTextEvent(ExecState *exec, DOM::TextEvent ke) :
00627   DOMUIEvent(DOMTextEventProto::self(exec), ke) {}
00628 
00629 DOMTextEvent::~DOMTextEvent()
00630 {
00631 }
00632 
00633 Value DOMTextEvent::tryGet(ExecState *exec, const Identifier &p) const
00634 {
00635 #ifdef KJS_VERBOSE
00636   kdDebug(6070) << "DOMTextEvent::tryGet " << p.qstring() << endl;
00637 #endif
00638   return DOMObjectLookupGetValue<DOMTextEvent,DOMUIEvent>(exec,p,&DOMTextEventTable,this);
00639 }
00640 
00641 Value DOMTextEvent::getValueProperty(ExecState *, int token) const
00642 {
00643   switch (token) {
00644   case Key:
00645     return Number(static_cast<DOM::TextEvent>(event).keyVal());
00646   case VirtKey:
00647     return Number(static_cast<DOM::TextEvent>(event).virtKeyVal());
00648   case OutputString:
00649     return String(static_cast<DOM::TextEvent>(event).outputString());
00650   case InputGenerated:
00651     return Boolean(static_cast<DOM::TextEvent>(event).inputGenerated());
00652   case NumPad:
00653     return Boolean(static_cast<DOM::TextEvent>(event).numPad());
00654   default:
00655     kdDebug(6070) << "WARNING: Unhandled token in DOMTextEvent::getValueProperty : " << token << endl;
00656     return Value();
00657   }
00658 }
00659 
00660 Value DOMTextEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00661 {
00662   KJS_CHECK_THIS( KJS::DOMTextEvent, thisObj );
00663   DOM::TextEvent keyEvent = static_cast<DOMTextEvent *>(thisObj.imp())->toTextEvent();
00664   switch (id) {
00665     case DOMTextEvent::InitTextEvent:
00666       keyEvent.initTextEvent(args[0].toString(exec).string(), // typeArg
00667                             args[1].toBoolean(exec), // canBubbleArg
00668                             args[2].toBoolean(exec), // cancelableArg
00669                             toAbstractView(args[3]), // viewArg
00670                             args[4].toInteger(exec), // detailArg
00671                             args[5].toString(exec).string(),  // outputStringArg
00672                             args[6].toInteger(exec), // keyValArg
00673                             args[7].toInteger(exec), // virtKeyValArg
00674                             args[8].toBoolean(exec), // inputGeneratedArg
00675                             args[9].toBoolean(exec));// numPadArg
00676 
00677       return Undefined();
00678   }
00679   return Undefined();
00680 }
00681 
00682 // -------------------------------------------------------------------------
00683 
00684 const ClassInfo MutationEventConstructor::info = { "MutationEventConstructor", 0, &MutationEventConstructorTable, 0 };
00685 /*
00686 @begin MutationEventConstructorTable 3
00687   MODIFICATION  DOM::MutationEvent::MODIFICATION    DontDelete|ReadOnly
00688   ADDITION  DOM::MutationEvent::ADDITION        DontDelete|ReadOnly
00689   REMOVAL   DOM::MutationEvent::REMOVAL     DontDelete|ReadOnly
00690 @end
00691 */
00692 MutationEventConstructor::MutationEventConstructor(ExecState* exec)
00693   : DOMObject(exec->interpreter()->builtinObjectPrototype())
00694 {
00695 }
00696 
00697 Value MutationEventConstructor::tryGet(ExecState *exec, const Identifier &p) const
00698 {
00699   return DOMObjectLookupGetValue<MutationEventConstructor,DOMObject>(exec,p,&MutationEventConstructorTable,this);
00700 }
00701 
00702 Value MutationEventConstructor::getValueProperty(ExecState *, int token) const
00703 {
00704   // We use the token as the value to return directly
00705   return Number(token);
00706 }
00707 
00708 Value KJS::getMutationEventConstructor(ExecState *exec)
00709 {
00710   return cacheGlobalObject<MutationEventConstructor>(exec, "[[mutationEvent.constructor]]");
00711 }
00712 
00713 // -------------------------------------------------------------------------
00714 
00715 const ClassInfo DOMMutationEvent::info = { "MutationEvent", &DOMEvent::info, &DOMMutationEventTable, 0 };
00716 /*
00717 @begin DOMMutationEventTable 5
00718   relatedNode   DOMMutationEvent::RelatedNode   DontDelete|ReadOnly
00719   prevValue DOMMutationEvent::PrevValue DontDelete|ReadOnly
00720   newValue  DOMMutationEvent::NewValue  DontDelete|ReadOnly
00721   attrName  DOMMutationEvent::AttrName  DontDelete|ReadOnly
00722   attrChange    DOMMutationEvent::AttrChange    DontDelete|ReadOnly
00723 @end
00724 @begin DOMMutationEventProtoTable 1
00725   initMutationEvent DOMMutationEvent::InitMutationEvent DontDelete|Function 8
00726 @end
00727 */
00728 DEFINE_PROTOTYPE("DOMMutationEvent",DOMMutationEventProto)
00729 IMPLEMENT_PROTOFUNC_DOM(DOMMutationEventProtoFunc)
00730 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMMutationEventProto,DOMMutationEventProtoFunc,DOMEventProto)
00731 
00732 DOMMutationEvent::DOMMutationEvent(ExecState *exec, DOM::MutationEvent me) :
00733   DOMEvent(DOMMutationEventProto::self(exec), me) {}
00734 
00735 DOMMutationEvent::~DOMMutationEvent()
00736 {
00737 }
00738 
00739 Value DOMMutationEvent::tryGet(ExecState *exec, const Identifier &p) const
00740 {
00741   return DOMObjectLookupGetValue<DOMMutationEvent,DOMEvent>(exec,p,&DOMMutationEventTable,this);
00742 }
00743 
00744 Value DOMMutationEvent::getValueProperty(ExecState *exec, int token) const
00745 {
00746   switch (token) {
00747   case RelatedNode:
00748     return getDOMNode(exec,static_cast<DOM::MutationEvent>(event).relatedNode());
00749   case PrevValue:
00750     return String(static_cast<DOM::MutationEvent>(event).prevValue());
00751   case NewValue:
00752     return String(static_cast<DOM::MutationEvent>(event).newValue());
00753   case AttrName:
00754     return String(static_cast<DOM::MutationEvent>(event).attrName());
00755   case AttrChange:
00756     return Number((unsigned int)static_cast<DOM::MutationEvent>(event).attrChange());
00757   default:
00758     kdDebug(6070) << "WARNING: Unhandled token in DOMMutationEvent::getValueProperty : " << token << endl;
00759     return Value();
00760   }
00761 }
00762 
00763 Value DOMMutationEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00764 {
00765   KJS_CHECK_THIS( KJS::DOMMutationEvent, thisObj );
00766   DOM::MutationEvent mutationEvent = static_cast<DOMMutationEvent *>(thisObj.imp())->toMutationEvent();
00767   switch (id) {
00768     case DOMMutationEvent::InitMutationEvent:
00769       mutationEvent.initMutationEvent(args[0].toString(exec).string(), // typeArg,
00770                                       args[1].toBoolean(exec), // canBubbleArg
00771                                       args[2].toBoolean(exec), // cancelableArg
00772                                       toNode(args[3]), // relatedNodeArg
00773                                       args[4].toString(exec).string(), // prevValueArg
00774                                       args[5].toString(exec).string(), // newValueArg
00775                                       args[6].toString(exec).string(), // attrNameArg
00776                                       args[7].toInteger(exec)); // attrChangeArg
00777       return Undefined();
00778   }
00779   return Undefined();
00780 }
KDE Logo
This file is part of the documentation for khtml Library Version 3.2.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Feb 4 12:37:21 2004 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2003