# khtml Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

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

This file is part of the documentation for khtml Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:33:18 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003