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 "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 }
KDE Logo
This file is part of the documentation for khtml Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 12 23:31:33 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003