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