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