/* * This file is part of the KDE libraries * Copyright (C) 2001 Peter Kelly (pmk@post.com) * Copyright (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "kjs_window.h" #include "kjs_events.h" #include "kjs_events.lut.h" #include "kjs_views.h" #include "kjs_proxy.h" #include "xml/dom_nodeimpl.h" #include "xml/dom_docimpl.h" #include "xml/dom2_eventsimpl.h" #include "rendering/render_object.h" #include "rendering/render_canvas.h" #include "xml/dom2_eventsimpl.h" #include "tdehtml_part.h" #include using namespace DOM; namespace KJS { // ------------------------------------------------------------------------- JSEventListener::JSEventListener(Object _listener, ObjectImp *_compareListenerImp, const Object &_win, bool _html) : listener( _listener ), compareListenerImp( _compareListenerImp ), html( _html ), win( _win ) { //fprintf(stderr,"JSEventListener::JSEventListener this=%p listener=%p\n",this,listener.imp()); if (compareListenerImp) { static_cast(win.imp())->jsEventListeners.insert(compareListenerImp, this); } } JSEventListener::~JSEventListener() { if (compareListenerImp) { static_cast(win.imp())->jsEventListeners.remove(compareListenerImp); } //fprintf(stderr,"JSEventListener::~JSEventListener this=%p listener=%p\n",this,listener.imp()); } void JSEventListener::handleEvent(DOM::Event &evt) { #ifdef KJS_DEBUGGER if (KJSDebugWin::debugWindow() && KJSDebugWin::debugWindow()->inSession()) return; #endif TDEHTMLPart *part = ::tqqt_cast(static_cast(win.imp())->part()); KJSProxy *proxy = 0L; if (part) proxy = part->jScript(); if (proxy && listener.isValid() && listener.implementsCall()) { ref(); KJS::ScriptInterpreter *interpreter = static_cast(proxy->interpreter()); ExecState *exec = interpreter->globalExec(); List args; args.append(getDOMEvent(exec,evt)); // Set "this" to the event's current target Object thisObj = Object::dynamicCast(getDOMNode(exec,evt.currentTarget())); if ( !thisObj.isValid() ) { // Window events (window.onload/window.onresize etc.) must have 'this' set to the window. // DocumentImpl::defaultEventHandler sets currentTarget to 0 to mean 'window'. thisObj = win; } Window *window = static_cast(win.imp()); // Set the event we're handling in the Window object window->setCurrentEvent( &evt ); // ... and in the interpreter interpreter->setCurrentEvent( &evt ); KJSCPUGuard guard; guard.start(); Value retval = listener.call(exec, thisObj, args); guard.stop(); window->setCurrentEvent( 0 ); interpreter->setCurrentEvent( 0 ); if ( exec->hadException() ) exec->clearException(); else if (html) { TQVariant ret = ValueToVariant(exec, retval); if (ret.type() == TQVariant::Bool && ret.toBool() == false) evt.preventDefault(); } window->afterScriptExecution(); deref(); } } DOM::DOMString JSEventListener::eventListenerType() { if (html) return "_tdehtml_HTMLEventListener"; else return "_tdehtml_JSEventListener"; } Object JSEventListener::listenerObj() const { return listener; } JSLazyEventListener::JSLazyEventListener(const TQString &_code, const TQString &_name, const Object &_win, DOM::NodeImpl* _originalNode) : JSEventListener(Object(), 0, _win, true), code(_code), name(_name), parsed(false) { // We don't retain the original node, because we assume it // will stay alive as long as this handler object is around // and we need to avoid a reference cycle. If JS transfers // this handler to another node, parseCode will be called and // then originalNode is no longer needed. originalNode = _originalNode; } JSLazyEventListener::~JSLazyEventListener() { if (listener.isValid()) { static_cast(win.imp())->jsEventListeners.remove(listener.imp()); } } void JSLazyEventListener::handleEvent(DOM::Event &evt) { parseCode(); if (listener.isValid()) { JSEventListener::handleEvent(evt); } } Object JSLazyEventListener::listenerObj() const { parseCode(); return listener; } void JSLazyEventListener::parseCode() const { if (!parsed) { TDEHTMLPart *part = ::tqqt_cast(static_cast(win.imp())->part()); KJSProxy *proxy = 0L; if (part) proxy = part->jScript(); if (proxy) { KJS::ScriptInterpreter *interpreter = static_cast(proxy->interpreter()); ExecState *exec = interpreter->globalExec(); //KJS::Constructor constr(KJS::Global::current().get("Function").imp()); KJS::Object constr = interpreter->builtinFunction(); KJS::List args; static KJS::String eventString("event"); args.append(eventString); args.append(KJS::String(code)); listener = constr.construct(exec, args); // ### is globalExec ok ? if (exec->hadException()) { exec->clearException(); // failed to parse, so let's just make this listener a no-op listener = Object(); } else if (!listener.inherits(&DeclaredFunctionImp::info)) { listener = Object();// Error creating function } else { DeclaredFunctionImp *declFunc = static_cast(listener.imp()); declFunc->setName(Identifier(static_cast(name))); if (originalNode) { // Add the event's home element to the scope // (and the document, and the form - see KJS::HTMLElement::eventHandlerScope) ScopeChain scope = listener.scope(); Object thisObj = Object::dynamicCast(getDOMNode(exec, originalNode)); if (thisObj.isValid()) { static_cast(thisObj.imp())->pushEventHandlerScope(exec, scope); listener.setScope(scope); } } } } // no more need to keep the unparsed code around code = TQString(); if (listener.isValid()) { static_cast(win.imp())->jsEventListeners.insert(listener.imp(), (KJS::JSEventListener *)(this)); } parsed = true; } } // ------------------------------------------------------------------------- const ClassInfo DOMEvent::info = { "Event", 0, &DOMEventTable, 0 }; /* @begin DOMEventTable 7 type DOMEvent::Type DontDelete|ReadOnly target DOMEvent::Target DontDelete|ReadOnly currentTarget DOMEvent::CurrentTarget DontDelete|ReadOnly srcElement DOMEvent::SrcElement DontDelete|ReadOnly eventPhase DOMEvent::EventPhase DontDelete|ReadOnly bubbles DOMEvent::Bubbles DontDelete|ReadOnly cancelable DOMEvent::Cancelable DontDelete|ReadOnly timeStamp DOMEvent::TimeStamp DontDelete|ReadOnly returnValue DOMEvent::ReturnValue DontDelete cancelBubble DOMEvent::CancelBubble DontDelete @end @begin DOMEventProtoTable 3 stopPropagation DOMEvent::StopPropagation DontDelete|Function 0 preventDefault DOMEvent::PreventDefault DontDelete|Function 0 initEvent DOMEvent::InitEvent DontDelete|Function 3 @end */ KJS_DEFINE_PROTOTYPE(DOMEventProto) IMPLEMENT_PROTOFUNC_DOM(DOMEventProtoFunc) KJS_IMPLEMENT_PROTOTYPE("DOMEvent", DOMEventProto, DOMEventProtoFunc) DOMEvent::DOMEvent(ExecState *exec, DOM::Event e) : DOMObject(DOMEventProto::self(exec)), event(e) { } DOMEvent::DOMEvent(const Object &proto, DOM::Event e) : DOMObject(proto), event(e) { } DOMEvent::~DOMEvent() { ScriptInterpreter::forgetDOMObject(event.handle()); } Value DOMEvent::tryGet(ExecState *exec, const Identifier &p) const { #ifdef KJS_VERBOSE kdDebug() << "KJS::DOMEvent::tryGet " << p.qstring() << endl; #endif return DOMObjectLookupGetValue(exec, p, &DOMEventTable, this ); } Value DOMEvent::getValueProperty(ExecState *exec, int token) const { switch (token) { case Type: return String(event.type()); case Target: case SrcElement: /*MSIE extension - "the object that fired the event"*/ return getDOMNode(exec,event.target()); case CurrentTarget: return getDOMNode(exec,event.currentTarget()); case EventPhase: return Number((unsigned int)event.eventPhase()); case Bubbles: return Boolean(event.bubbles()); case Cancelable: return Boolean(event.cancelable()); case TimeStamp: return Number((long unsigned int)event.timeStamp()); // ### long long ? case ReturnValue: // MSIE extension // return false == cancel, so this returns the -opposite- of defaultPrevented return Boolean(!event.handle()->defaultPrevented()); case CancelBubble: // MSIE extension return Boolean(event.handle()->propagationStopped()); default: kdDebug(6070) << "WARNING: Unhandled token in DOMEvent::getValueProperty : " << token << endl; return Value(); } } Value DOMEvent::defaultValue(ExecState *exec, KJS::Type hint) const { if (event.handle()->id() == EventImpl::ERROR_EVENT && !event.handle()->message().isNull()) { return String(event.handle()->message()); } else return DOMObject::defaultValue(exec,hint); } void DOMEvent::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr) { DOMObjectLookupPut(exec, propertyName, value, attr, &DOMEventTable, this); } void DOMEvent::putValueProperty(ExecState *exec, int token, const Value& value, int) { switch (token) { case ReturnValue: // MSIE equivalent for "preventDefault" (but with a way to reset it) // returnValue=false means "default action of the event on the source object is canceled", // which means preventDefault(true). Hence the '!'. event.handle()->preventDefault(!value.toBoolean(exec)); break; case CancelBubble: // MSIE equivalent for "stopPropagation" (but with a way to reset it) event.handle()->stopPropagation(value.toBoolean(exec)); break; default: break; } } Value DOMEventProtoFunc::tryCall(ExecState *exec, Object & thisObj, const List &args) { KJS_CHECK_THIS( KJS::DOMEvent, thisObj ); DOM::Event event = static_cast( thisObj.imp() )->toEvent(); switch (id) { case DOMEvent::StopPropagation: event.stopPropagation(); return Undefined(); case DOMEvent::PreventDefault: event.preventDefault(); return Undefined(); case DOMEvent::InitEvent: event.initEvent(args[0].toString(exec).string(),args[1].toBoolean(exec),args[2].toBoolean(exec)); return Undefined(); }; return Undefined(); } Value getDOMEvent(ExecState *exec, DOM::Event e) { DOM::EventImpl *ei = e.handle(); if (!ei) return Null(); ScriptInterpreter* interp = static_cast(exec->interpreter()); DOMObject *ret = interp->getDOMObject(ei); if (!ret) { if (ei->isTextInputEvent()) ret = new DOMTextEvent(exec, e); else if (ei->isKeyboardEvent()) ret = new DOMKeyboardEvent(exec, e); else if (ei->isMouseEvent()) ret = new DOMMouseEvent(exec, e); else if (ei->isUIEvent()) ret = new DOMUIEvent(exec, e); else if (ei->isMutationEvent()) ret = new DOMMutationEvent(exec, e); else ret = new DOMEvent(exec, e); interp->putDOMObject(ei, ret); } return Value(ret); } DOM::Event toEvent(const Value& val) { Object obj = Object::dynamicCast(val); if (!obj.isValid() || !obj.inherits(&DOMEvent::info)) return DOM::Event(); const DOMEvent *dobj = static_cast(obj.imp()); return dobj->toEvent(); } // ------------------------------------------------------------------------- /* @begin EventConstantsTable 23 CAPTURING_PHASE DOM::Event::CAPTURING_PHASE DontDelete|ReadOnly AT_TARGET DOM::Event::AT_TARGET DontDelete|ReadOnly BUBBLING_PHASE DOM::Event::BUBBLING_PHASE DontDelete|ReadOnly # Reverse-engineered from Netscape MOUSEDOWN 1 DontDelete|ReadOnly MOUSEUP 2 DontDelete|ReadOnly MOUSEOVER 4 DontDelete|ReadOnly MOUSEOUT 8 DontDelete|ReadOnly MOUSEMOVE 16 DontDelete|ReadOnly MOUSEDRAG 32 DontDelete|ReadOnly CLICK 64 DontDelete|ReadOnly DBLCLICK 128 DontDelete|ReadOnly KEYDOWN 256 DontDelete|ReadOnly KEYUP 512 DontDelete|ReadOnly KEYPRESS 1024 DontDelete|ReadOnly DRAGDROP 2048 DontDelete|ReadOnly FOCUS 4096 DontDelete|ReadOnly BLUR 8192 DontDelete|ReadOnly SELECT 16384 DontDelete|ReadOnly CHANGE 32768 DontDelete|ReadOnly @end */ DEFINE_CONSTANT_TABLE(EventConstants) IMPLEMENT_CONSTANT_TABLE(EventConstants, "EventConstants") IMPLEMENT_PSEUDO_CONSTRUCTOR_WITH_PARENT(EventConstructor, "EventConstructor", DOMEventProto, EventConstants) // ------------------------------------------------------------------------- const ClassInfo EventExceptionConstructor::info = { "EventExceptionConstructor", 0, &EventExceptionConstructorTable, 0 }; /* @begin EventExceptionConstructorTable 1 UNSPECIFIED_EVENT_TYPE_ERR DOM::EventException::UNSPECIFIED_EVENT_TYPE_ERR DontDelete|ReadOnly @end */ EventExceptionConstructor::EventExceptionConstructor(ExecState *exec) : DOMObject(exec->interpreter()->builtinObjectPrototype()) { } Value EventExceptionConstructor::tryGet(ExecState *exec, const Identifier &p) const { return DOMObjectLookupGetValue(exec,p,&EventExceptionConstructorTable,this); } Value EventExceptionConstructor::getValueProperty(ExecState *, int token) const { // We use the token as the value to return directly return Number(token); } Value getEventExceptionConstructor(ExecState *exec) { return cacheGlobalObject(exec, "[[eventException.constructor]]"); } // ------------------------------------------------------------------------- const ClassInfo DOMUIEvent::info = { "UIEvent", &DOMEvent::info, &DOMUIEventTable, 0 }; /* @begin DOMUIEventTable 7 view DOMUIEvent::View DontDelete|ReadOnly detail DOMUIEvent::Detail DontDelete|ReadOnly keyCode DOMUIEvent::KeyCode DontDelete|ReadOnly charCode DOMUIEvent::CharCode DontDelete|ReadOnly layerX DOMUIEvent::LayerX DontDelete|ReadOnly layerY DOMUIEvent::LayerY DontDelete|ReadOnly pageX DOMUIEvent::PageX DontDelete|ReadOnly pageY DOMUIEvent::PageY DontDelete|ReadOnly which DOMUIEvent::Which DontDelete|ReadOnly @end @begin DOMUIEventProtoTable 1 initUIEvent DOMUIEvent::InitUIEvent DontDelete|Function 5 @end */ KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMUIEventProto, DOMEventProto) IMPLEMENT_PROTOFUNC_DOM(DOMUIEventProtoFunc) KJS_IMPLEMENT_PROTOTYPE("DOMUIEvent", DOMUIEventProto, DOMUIEventProtoFunc) DOMUIEvent::DOMUIEvent(ExecState *exec, DOM::UIEvent ue) : DOMEvent(DOMUIEventProto::self(exec), ue) {} DOMUIEvent::DOMUIEvent(const Object &proto, DOM::UIEvent ue) : DOMEvent(proto, ue) {} DOMUIEvent::~DOMUIEvent() { } Value DOMUIEvent::tryGet(ExecState *exec, const Identifier &p) const { return DOMObjectLookupGetValue(exec,p,&DOMUIEventTable,this); } Value DOMUIEvent::getValueProperty(ExecState *exec, int token) const { switch (token) { case View: return getDOMAbstractView(exec,static_cast(event).view()); case Detail: return Number(static_cast(event).detail()); case KeyCode: // IE-compatibility return Number(static_cast(event).keyCode()); case CharCode: // IE-compatibility return Number(static_cast(event).charCode()); case LayerX: // NS-compatibility return Number(static_cast(event).layerX()); case LayerY: // NS-compatibility return Number(static_cast(event).layerY()); case PageX: // NS-compatibility return Number(static_cast(event).pageX()); case PageY: // NS-compatibility return Number(static_cast(event).pageY()); case Which: // NS-compatibility return Number(static_cast(event).which()); default: kdDebug(6070) << "WARNING: Unhandled token in DOMUIEvent::getValueProperty : " << token << endl; return Undefined(); } } Value DOMUIEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args) { KJS_CHECK_THIS( KJS::DOMUIEvent, thisObj ); DOM::UIEvent uiEvent = static_cast(thisObj.imp())->toUIEvent(); switch (id) { case DOMUIEvent::InitUIEvent: { DOM::AbstractView v = toAbstractView(args[3]); static_cast(uiEvent).initUIEvent(args[0].toString(exec).string(), args[1].toBoolean(exec), args[2].toBoolean(exec), v, args[4].toInteger(exec)); } return Undefined(); } return Undefined(); } // ------------------------------------------------------------------------- const ClassInfo DOMMouseEvent::info = { "MouseEvent", &DOMUIEvent::info, &DOMMouseEventTable, 0 }; /* @begin DOMMouseEventTable 2 screenX DOMMouseEvent::ScreenX DontDelete|ReadOnly screenY DOMMouseEvent::ScreenY DontDelete|ReadOnly clientX DOMMouseEvent::ClientX DontDelete|ReadOnly x DOMMouseEvent::X DontDelete|ReadOnly clientY DOMMouseEvent::ClientY DontDelete|ReadOnly y DOMMouseEvent::Y DontDelete|ReadOnly offsetX DOMMouseEvent::OffsetX DontDelete|ReadOnly offsetY DOMMouseEvent::OffsetY DontDelete|ReadOnly ctrlKey DOMMouseEvent::CtrlKey DontDelete|ReadOnly shiftKey DOMMouseEvent::ShiftKey DontDelete|ReadOnly altKey DOMMouseEvent::AltKey DontDelete|ReadOnly metaKey DOMMouseEvent::MetaKey DontDelete|ReadOnly button DOMMouseEvent::Button DontDelete|ReadOnly relatedTarget DOMMouseEvent::RelatedTarget DontDelete|ReadOnly fromElement DOMMouseEvent::FromElement DontDelete|ReadOnly toElement DOMMouseEvent::ToElement DontDelete|ReadOnly @end @begin DOMMouseEventProtoTable 1 initMouseEvent DOMMouseEvent::InitMouseEvent DontDelete|Function 15 @end */ KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMMouseEventProto, DOMUIEventProto) IMPLEMENT_PROTOFUNC_DOM(DOMMouseEventProtoFunc) KJS_IMPLEMENT_PROTOTYPE("DOMMouseEvent", DOMMouseEventProto, DOMMouseEventProtoFunc) DOMMouseEvent::DOMMouseEvent(ExecState *exec, DOM::MouseEvent me) : DOMUIEvent(DOMMouseEventProto::self(exec), me) {} DOMMouseEvent::~DOMMouseEvent() { } Value DOMMouseEvent::tryGet(ExecState *exec, const Identifier &p) const { #ifdef KJS_VERBOSE kdDebug(6070) << "DOMMouseEvent::tryGet " << p.qstring() << endl; #endif return DOMObjectLookupGetValue(exec,p,&DOMMouseEventTable,this); } Value DOMMouseEvent::getValueProperty(ExecState *exec, int token) const { switch (token) { case ScreenX: return Number(static_cast(event).screenX()); case ScreenY: return Number(static_cast(event).screenY()); case ClientX: case X: return Number(static_cast(event).clientX()); case ClientY: case Y: return Number(static_cast(event).clientY()); case OffsetX: case OffsetY: // MSIE extension { DOM::Node node = event.target(); tdehtml::RenderObject *rend = 0; if (node.handle()) { node.handle()->getDocument()->updateRendering(); rend = node.handle()->renderer(); } int x = static_cast(event).clientX(); int y = static_cast(event).clientY(); if ( rend ) { int xPos, yPos; if ( rend->absolutePosition( xPos, yPos ) ) { //kdDebug() << "DOMMouseEvent::getValueProperty rend=" << rend << " xPos=" << xPos << " yPos=" << yPos << endl; x -= xPos; y -= yPos; } if ( rend->canvas() ) { int cYPos, cXPos; rend->canvas()->absolutePosition( cXPos, cYPos, true ); x += cXPos; y += cYPos; } } return Number( token == OffsetX ? x : y ); } case CtrlKey: return Boolean(static_cast(event).ctrlKey()); case ShiftKey: return Boolean(static_cast(event).shiftKey()); case AltKey: return Boolean(static_cast(event).altKey()); case MetaKey: return Boolean(static_cast(event).metaKey()); case Button: { if ( exec->interpreter()->compatMode() == Interpreter::NetscapeCompat ) { return Number(static_cast(event).button()); } // Tricky. The DOM (and tdehtml) use 0 for LMB, 1 for MMB and 2 for RMB // but MSIE uses 1=LMB, 2=RMB, 4=MMB, as a bitfield int domButton = static_cast(event).button(); int button = domButton==0 ? 1 : domButton==1 ? 4 : domButton==2 ? 2 : 0; return Number( (unsigned int)button ); } case ToElement: // MSIE extension - "the object toward which the user is moving the mouse pointer" if (event.handle()->id() == DOM::EventImpl::MOUSEOUT_EVENT) return getDOMNode(exec,static_cast(event).relatedTarget()); return getDOMNode(exec,static_cast(event).target()); case FromElement: // MSIE extension - "object from which activation // or the mouse pointer is exiting during the event" (huh?) if (event.handle()->id() == DOM::EventImpl::MOUSEOUT_EVENT) return getDOMNode(exec,static_cast(event).target()); /* fall through */ case RelatedTarget: return getDOMNode(exec,static_cast(event).relatedTarget()); default: kdDebug(6070) << "WARNING: Unhandled token in DOMMouseEvent::getValueProperty : " << token << endl; return Value(); } } Value DOMMouseEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args) { KJS_CHECK_THIS( KJS::DOMMouseEvent, thisObj ); DOM::MouseEvent mouseEvent = static_cast(thisObj.imp())->toMouseEvent(); switch (id) { case DOMMouseEvent::InitMouseEvent: mouseEvent.initMouseEvent(args[0].toString(exec).string(), // typeArg args[1].toBoolean(exec), // canBubbleArg args[2].toBoolean(exec), // cancelableArg toAbstractView(args[3]), // viewArg args[4].toInteger(exec), // detailArg args[5].toInteger(exec), // screenXArg args[6].toInteger(exec), // screenYArg args[7].toInteger(exec), // clientXArg args[8].toInteger(exec), // clientYArg args[9].toBoolean(exec), // ctrlKeyArg args[10].toBoolean(exec), // altKeyArg args[11].toBoolean(exec), // shiftKeyArg args[12].toBoolean(exec), // metaKeyArg args[13].toInteger(exec), // buttonArg toNode(args[14])); // relatedTargetArg return Undefined(); } return Undefined(); } // ------------------------------------------------------------------------- const ClassInfo DOMKeyEventBase::info = { "KeyEventBase", &DOMUIEvent::info, &DOMKeyEventBaseTable, 0 }; /* @begin DOMKeyEventBaseTable 5 keyVal DOMKeyEventBase::Key DontDelete|ReadOnly virtKeyVal DOMKeyEventBase::VirtKey DontDelete|ReadOnly ctrlKey DOMKeyEventBase::CtrlKey DontDelete|ReadOnly altKey DOMKeyEventBase::AltKey DontDelete|ReadOnly shiftKey DOMKeyEventBase::ShiftKey DontDelete|ReadOnly altKey DOMKeyEventBase::AltKey DontDelete|ReadOnly @end */ DOMKeyEventBase::DOMKeyEventBase(const Object &proto, DOM::TextEvent ke) : DOMUIEvent(proto, ke) {} DOMKeyEventBase::~DOMKeyEventBase() {} Value DOMKeyEventBase::tryGet(ExecState *exec,const Identifier &p) const { #ifdef KJS_VERBOSE kdDebug(6070) << "DOMKeyEventBase::tryGet " << p.qstring() << endl; #endif return DOMObjectLookupGetValue(exec,p,&DOMKeyEventBaseTable,this); } Value DOMKeyEventBase::getValueProperty(ExecState *, int token) const { DOM::KeyEventBaseImpl* tevent = impl(); switch (token) { case Key: return Number(tevent->keyVal()); case VirtKey: return Number(tevent->virtKeyVal()); // these modifier attributes actually belong into a KeyboardEvent interface, // but we want them on "keypress" as well. case CtrlKey: return Boolean(tevent->ctrlKey()); case ShiftKey: return Boolean(tevent->shiftKey()); case AltKey: return Boolean(tevent->altKey()); case MetaKey: return Boolean(tevent->metaKey()); default: kdDebug(6070) << "WARNING: Unhandled token in DOMTextEvent::getValueProperty : " << token << endl; return KJS::Undefined(); } } // ------------------------------------------------------------------------- const ClassInfo DOMTextEvent::info = { "TextEvent", &DOMKeyEventBase::info, &DOMTextEventTable, 0 }; /* @begin DOMTextEventTable 1 data DOMTextEvent::Data DontDelete|ReadOnly @end @begin DOMTextEventProtoTable 1 initTextEvent DOMTextEvent::InitTextEvent DontDelete|Function 5 # Missing: initTextEventNS @end */ KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMTextEventProto, DOMUIEventProto) //Note: no proto in KeyBase IMPLEMENT_PROTOFUNC_DOM(DOMTextEventProtoFunc) KJS_IMPLEMENT_PROTOTYPE("DOMTextEvent", DOMTextEventProto, DOMTextEventProtoFunc) DOMTextEvent::DOMTextEvent(ExecState *exec, DOM::TextEvent ke) : DOMKeyEventBase(DOMTextEventProto::self(exec), ke) {} DOMTextEvent::~DOMTextEvent() { } Value DOMTextEvent::tryGet(ExecState *exec, const Identifier &p) const { #ifdef KJS_VERBOSE kdDebug(6070) << "DOMTextEvent::tryGet " << p.qstring() << endl; #endif return DOMObjectLookupGetValue(exec,p,&DOMTextEventTable,this); } Value DOMTextEvent::getValueProperty(ExecState *, int token) const { DOM::TextEventImpl* tevent = impl(); switch (token) { case Data: return String(tevent->data()); default: kdDebug(6070) << "WARNING: Unhandled token in DOMTextEvent::getValueProperty : " << token << endl; return KJS::Undefined(); } } Value DOMTextEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args) { KJS_CHECK_THIS( KJS::DOMTextEvent, thisObj ); DOM::TextEventImpl* keyEvent = static_cast(thisObj.imp())->impl(); switch (id) { case DOMTextEvent::InitTextEvent: keyEvent->initTextEvent(args[0].toString(exec).string(), // typeArg args[1].toBoolean(exec), // canBubbleArg args[2].toBoolean(exec), // cancelableArg toAbstractView(args[3]), // viewArg args[4].toString(exec).string()); // dataArg return Undefined(); } return Undefined(); } // ------------------------------------------------------------------------- const ClassInfo DOMKeyboardEvent::info = { "KeyboardEvent", &DOMKeyEventBase::info, &DOMKeyboardEventTable, 0 }; /* @begin DOMKeyboardEventTable 2 keyIdentifier DOMKeyboardEvent::KeyIdentifier DontDelete|ReadOnly keyLocation DOMKeyboardEvent::KeyLocation DontDelete|ReadOnly @end @begin DOMKeyboardEventProtoTable 2 initKeyboardEvent DOMKeyboardEvent::InitKeyboardEvent DontDelete|Function 7 getModifierState DOMKeyboardEvent::GetModifierState DontDelete|Function 1 @end */ KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMKeyboardEventProto, DOMUIEventProto) //Note: no proto in KeyBase IMPLEMENT_PROTOFUNC_DOM(DOMKeyboardEventProtoFunc) KJS_IMPLEMENT_PROTOTYPE("DOMKeyboardEvent", DOMKeyboardEventProto, DOMKeyboardEventProtoFunc) DOMKeyboardEvent::DOMKeyboardEvent(ExecState *exec, DOM::TextEvent ke) : DOMKeyEventBase(DOMKeyboardEventProto::self(exec), ke) {} DOMKeyboardEvent::~DOMKeyboardEvent() { } Value DOMKeyboardEvent::tryGet(ExecState *exec, const Identifier &p) const { #ifdef KJS_VERBOSE kdDebug(6070) << "DOMKeyboardEvent::tryGet " << p.qstring() << endl; #endif return DOMObjectLookupGetValue(exec,p,&DOMKeyboardEventTable,this); } Value DOMKeyboardEvent::getValueProperty(ExecState *, int token) const { DOM::KeyboardEventImpl* tevent = impl(); switch (token) { case KeyIdentifier: return String(tevent->keyIdentifier()); case KeyLocation: return Number(tevent->keyLocation()); default: kdDebug(6070) << "WARNING: Unhandled token in DOMKeyboardEvent::getValueProperty : " << token << endl; return KJS::Undefined(); } } Value DOMKeyboardEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args) { KJS_CHECK_THIS( KJS::DOMKeyboardEvent, thisObj ); DOM::KeyboardEventImpl* keyEvent = static_cast(thisObj.imp())->impl(); switch (id) { case DOMKeyboardEvent::InitKeyboardEvent: keyEvent->initKeyboardEvent(args[0].toString(exec).string(), // typeArg args[1].toBoolean(exec), // canBubbleArg args[2].toBoolean(exec), // cancelableArg toAbstractView(args[3]), // viewArg args[4].toString(exec).string(), // keyIdentifierArg args[5].toInteger(exec), // keyLocationArg args[6].toString(exec).string()); //modifiersList break; case DOMKeyboardEvent::GetModifierState: return Boolean(keyEvent->getModifierState(args[0].toString(exec).string())); } return Undefined(); } // ------------------------------------------------------------------------- const ClassInfo KeyboardEventConstructor::info = { "KeyboardEventConstructor", 0, &KeyboardEventConstructorTable, 0 }; /* @begin KeyboardEventConstructorTable 4 DOM_KEY_LOCATION_STANDARD DOM::KeyboardEventImpl::DOM_KEY_LOCATION_STANDARD DontDelete|ReadOnly DOM_KEY_LOCATION_LEFT DOM::KeyboardEventImpl::DOM_KEY_LOCATION_LEFT DontDelete|ReadOnly DOM_KEY_LOCATION_RIGHT DOM::KeyboardEventImpl::DOM_KEY_LOCATION_RIGHT DontDelete|ReadOnly DOM_KEY_LOCATION_NUMPAD DOM::KeyboardEventImpl::DOM_KEY_LOCATION_NUMPAD DontDelete|ReadOnly @end */ KeyboardEventConstructor::KeyboardEventConstructor(ExecState* exec) : DOMObject(exec->interpreter()->builtinObjectPrototype()) {} Value KeyboardEventConstructor::tryGet(ExecState *exec, const Identifier &p) const { return DOMObjectLookupGetValue(exec,p,&KeyboardEventConstructorTable,this); } Value KeyboardEventConstructor::getValueProperty(ExecState *, int token) const { // We use the token as the value to return directly return Number(token); } Value getKeyboardEventConstructor(ExecState *exec) { return cacheGlobalObject(exec, "[[keyboardEvent.constructor]]"); } // ------------------------------------------------------------------------- const ClassInfo MutationEventConstructor::info = { "MutationEventConstructor", 0, &MutationEventConstructorTable, 0 }; /* @begin MutationEventConstructorTable 3 MODIFICATION DOM::MutationEvent::MODIFICATION DontDelete|ReadOnly ADDITION DOM::MutationEvent::ADDITION DontDelete|ReadOnly REMOVAL DOM::MutationEvent::REMOVAL DontDelete|ReadOnly @end */ MutationEventConstructor::MutationEventConstructor(ExecState* exec) : DOMObject(exec->interpreter()->builtinObjectPrototype()) { } Value MutationEventConstructor::tryGet(ExecState *exec, const Identifier &p) const { return DOMObjectLookupGetValue(exec,p,&MutationEventConstructorTable,this); } Value MutationEventConstructor::getValueProperty(ExecState *, int token) const { // We use the token as the value to return directly return Number(token); } Value getMutationEventConstructor(ExecState *exec) { return cacheGlobalObject(exec, "[[mutationEvent.constructor]]"); } // ------------------------------------------------------------------------- const ClassInfo DOMMutationEvent::info = { "MutationEvent", &DOMEvent::info, &DOMMutationEventTable, 0 }; /* @begin DOMMutationEventTable 5 relatedNode DOMMutationEvent::RelatedNode DontDelete|ReadOnly prevValue DOMMutationEvent::PrevValue DontDelete|ReadOnly newValue DOMMutationEvent::NewValue DontDelete|ReadOnly attrName DOMMutationEvent::AttrName DontDelete|ReadOnly attrChange DOMMutationEvent::AttrChange DontDelete|ReadOnly @end @begin DOMMutationEventProtoTable 1 initMutationEvent DOMMutationEvent::InitMutationEvent DontDelete|Function 8 @end */ KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMMutationEventProto, DOMEventProto) IMPLEMENT_PROTOFUNC_DOM(DOMMutationEventProtoFunc) KJS_IMPLEMENT_PROTOTYPE("DOMMutationEvent", DOMMutationEventProto, DOMMutationEventProtoFunc) DOMMutationEvent::DOMMutationEvent(ExecState *exec, DOM::MutationEvent me) : DOMEvent(DOMMutationEventProto::self(exec), me) {} DOMMutationEvent::~DOMMutationEvent() { } Value DOMMutationEvent::tryGet(ExecState *exec, const Identifier &p) const { return DOMObjectLookupGetValue(exec,p,&DOMMutationEventTable,this); } Value DOMMutationEvent::getValueProperty(ExecState *exec, int token) const { switch (token) { case RelatedNode: return getDOMNode(exec,static_cast(event).relatedNode()); case PrevValue: return String(static_cast(event).prevValue()); case NewValue: return String(static_cast(event).newValue()); case AttrName: return String(static_cast(event).attrName()); case AttrChange: return Number((unsigned int)static_cast(event).attrChange()); default: kdDebug(6070) << "WARNING: Unhandled token in DOMMutationEvent::getValueProperty : " << token << endl; return Value(); } } Value DOMMutationEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args) { KJS_CHECK_THIS( KJS::DOMMutationEvent, thisObj ); DOM::MutationEvent mutationEvent = static_cast(thisObj.imp())->toMutationEvent(); switch (id) { case DOMMutationEvent::InitMutationEvent: mutationEvent.initMutationEvent(args[0].toString(exec).string(), // typeArg, args[1].toBoolean(exec), // canBubbleArg args[2].toBoolean(exec), // cancelableArg toNode(args[3]), // relatedNodeArg args[4].toString(exec).string(), // prevValueArg args[5].toString(exec).string(), // newValueArg args[6].toString(exec).string(), // attrNameArg args[7].toInteger(exec)); // attrChangeArg return Undefined(); } return Undefined(); } } //namespace KJS