File indexing completed on 2023-09-24 04:06:10
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 0004 * Copyright (C) 2003 Apple Computer, Inc. 0005 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public 0017 * License along with this library; if not, write to the Free Software 0018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0019 */ 0020 0021 #ifndef _KJS_EVENTS_H_ 0022 #define _KJS_EVENTS_H_ 0023 0024 #include "ecma/kjs_dom.h" 0025 #include "dom/dom2_events.h" 0026 #include "dom/dom_misc.h" 0027 #include "xml/dom2_eventsimpl.h" 0028 0029 namespace KJS 0030 { 0031 0032 class Window; 0033 0034 class JSEventListener : public DOM::EventListener 0035 { 0036 public: 0037 /** 0038 * @param _listener the function object, that will be called when the event is emitted 0039 * @param _compareListenerImp Compare Listener implementation. 0040 * @param _win Window object, for memory management and caching. 0041 * @param _html \c true if it is HTML. 0042 * Never create a JSEventListener directly, use Window::getJSEventListener. 0043 */ 0044 JSEventListener(JSObject *_listener, JSObject *_compareListenerImp, JSObject *_win, bool _html = false); 0045 virtual ~JSEventListener(); 0046 void handleEvent(DOM::Event &evt) override; 0047 DOM::DOMString eventListenerType() override; 0048 // Return the KJS function object executed when this event is emitted 0049 virtual JSObject *listenerObj() const; 0050 // for Window::clear(). This is a bad hack though. The JSEventListener might not get deleted 0051 // if it was added to a DOM node in another frame (#61467). But calling removeEventListener on 0052 // all nodes we're listening to is quite difficult. 0053 void clear() 0054 { 0055 listener = nullptr; 0056 compareListenerImp = nullptr; 0057 } 0058 bool isHTMLEventListener() const 0059 { 0060 return html; 0061 } 0062 0063 protected: 0064 mutable ProtectedPtr<JSObject> listener; 0065 // Storing a different JSObject ptr is needed to support addEventListener(.. [Object] ..) calls 0066 // In the real-life case (where a 'function' is passed to addEventListener) we can directly call 0067 // the 'listener' object and can cache the 'listener.imp()'. If the event listener should be removed 0068 // the implementation will call removeEventListener(.. [Function] ..), and we can lookup the event 0069 // listener by the passed function's imp() ptr. 0070 // In the only dom-approved way (passing an Object to add/removeEventListener), the 'listener' 0071 // variable stores the function object 'passedListener.handleEvent'. But we need to cache 0072 // the imp() ptr of the 'passedListener' function _object_, as the implementation will 0073 // call removeEventListener(.. [Object ..] on removal, and now we can successfully lookup 0074 // the correct event listener, as well as the 'listener.handleEvent' function, we need to call. 0075 mutable ProtectedPtr<JSObject> compareListenerImp; 0076 bool html; 0077 mutable ProtectedPtr<JSObject> win; 0078 }; 0079 0080 class JSLazyEventListener : public JSEventListener 0081 { 0082 public: 0083 JSLazyEventListener(const QString &_code, const QString &_url, int _lineNum, 0084 const QString &_name, JSObject *_win, DOM::NodeImpl *node, bool _svg = false); 0085 ~JSLazyEventListener(); 0086 void handleEvent(DOM::Event &evt) override; 0087 JSObject *listenerObj() const override; 0088 private: 0089 void parseCode() const; 0090 0091 mutable QString code; 0092 mutable QString url; 0093 int lineNum; 0094 0095 mutable QString name; 0096 mutable bool parsed; 0097 DOM::NodeImpl *originalNode; 0098 bool svg; 0099 }; 0100 0101 // Constructor for Event - currently only used for some global vars 0102 DEFINE_PSEUDO_CONSTRUCTOR(EventConstructor) 0103 0104 class DOMEvent : public DOMObject 0105 { 0106 public: 0107 // Build a DOMEvent 0108 DOMEvent(ExecState *exec, DOM::EventImpl *e); 0109 DOMEvent(JSObject *proto, DOM::EventImpl *e); 0110 ~DOMEvent(); 0111 0112 using KJS::JSObject::getOwnPropertySlot; 0113 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0114 JSValue *getValueProperty(ExecState *, int token) const; 0115 using KJS::JSObject::put; 0116 virtual void put(ExecState *exec, const Identifier &propertyName, 0117 JSValue *value, int attr = None) override; 0118 JSValue *defaultValue(ExecState *exec, KJS::JSType hint) const override; 0119 void putValueProperty(ExecState *exec, int token, JSValue *value, int); 0120 const ClassInfo *classInfo() const override 0121 { 0122 return &info; 0123 } 0124 static const ClassInfo info; 0125 enum { Type, Target, CurrentTarget, EventPhase, Bubbles, 0126 Cancelable, TimeStamp, StopPropagation, PreventDefault, InitEvent, 0127 // MS IE equivalents 0128 SrcElement, ReturnValue, CancelBubble 0129 }; 0130 DOM::EventImpl *impl() const 0131 { 0132 return m_impl.get(); 0133 } 0134 protected: 0135 SharedPtr<DOM::EventImpl> m_impl; 0136 }; 0137 0138 JSValue *getDOMEvent(ExecState *exec, DOM::EventImpl *e); 0139 0140 /** 0141 * Convert an object to an Event. Returns a null Event if not possible. 0142 */ 0143 DOM::EventImpl *toEvent(JSValue *); 0144 0145 // Constructor object EventException 0146 class EventExceptionConstructor : public DOMObject 0147 { 0148 public: 0149 EventExceptionConstructor(ExecState *); 0150 using KJS::JSObject::getOwnPropertySlot; 0151 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0152 JSValue *getValueProperty(ExecState *, int token) const; 0153 // no put - all read-only 0154 const ClassInfo *classInfo() const override 0155 { 0156 return &info; 0157 } 0158 static const ClassInfo info; 0159 }; 0160 0161 JSValue *getEventExceptionConstructor(ExecState *exec); 0162 0163 class DOMUIEvent : public DOMEvent 0164 { 0165 public: 0166 // Build a DOMUIEvent 0167 DOMUIEvent(ExecState *exec, DOM::UIEventImpl *ue); 0168 DOMUIEvent(JSObject *proto, DOM::UIEventImpl *ue); 0169 ~DOMUIEvent(); 0170 using KJS::JSObject::getOwnPropertySlot; 0171 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0172 JSValue *getValueProperty(ExecState *, int token) const; 0173 // no put - all read-only 0174 const ClassInfo *classInfo() const override 0175 { 0176 return &info; 0177 } 0178 static const ClassInfo info; 0179 enum { View, Detail, KeyCode, CharCode, LayerX, LayerY, PageX, PageY, Which, InitUIEvent }; 0180 DOM::UIEventImpl *impl() const 0181 { 0182 return static_cast<DOM::UIEventImpl *>(m_impl.get()); 0183 } 0184 }; 0185 0186 class DOMMouseEvent : public DOMUIEvent 0187 { 0188 public: 0189 DOMMouseEvent(ExecState *exec, DOM::MouseEventImpl *me); 0190 ~DOMMouseEvent(); 0191 using KJS::JSObject::getOwnPropertySlot; 0192 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0193 JSValue *getValueProperty(ExecState *, int token) const; 0194 // no put - all read-only 0195 const ClassInfo *classInfo() const override 0196 { 0197 return &info; 0198 } 0199 static const ClassInfo info; 0200 enum { ScreenX, ScreenY, ClientX, X, ClientY, Y, OffsetX, OffsetY, 0201 CtrlKey, ShiftKey, AltKey, 0202 MetaKey, Button, RelatedTarget, FromElement, ToElement, 0203 InitMouseEvent 0204 }; 0205 DOM::MouseEventImpl *impl() const 0206 { 0207 return static_cast<DOM::MouseEventImpl *>(m_impl.get()); 0208 } 0209 }; 0210 0211 class DOMKeyEventBase : public DOMUIEvent 0212 { 0213 public: 0214 DOMKeyEventBase(JSObject *proto, DOM::KeyEventBaseImpl *ke); 0215 ~DOMKeyEventBase(); 0216 0217 using KJS::JSObject::getOwnPropertySlot; 0218 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0219 JSValue *getValueProperty(ExecState *, int token) const; 0220 // no put - all read-only 0221 const ClassInfo *classInfo() const override 0222 { 0223 return &info; 0224 } 0225 static const ClassInfo info; 0226 enum { Key, VirtKey, CtrlKey, ShiftKey, AltKey, MetaKey }; 0227 DOM::KeyEventBaseImpl *impl() const 0228 { 0229 return static_cast<DOM::KeyEventBaseImpl *>(m_impl.get()); 0230 } 0231 }; 0232 0233 class DOMTextEvent : public DOMKeyEventBase 0234 { 0235 public: 0236 DOMTextEvent(ExecState *exec, DOM::TextEventImpl *ke); 0237 ~DOMTextEvent(); 0238 using KJS::JSObject::getOwnPropertySlot; 0239 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0240 JSValue *getValueProperty(ExecState *, int token) const; 0241 // no put - all read-only 0242 const ClassInfo *classInfo() const override 0243 { 0244 return &info; 0245 } 0246 static const ClassInfo info; 0247 enum {Data, InitTextEvent}; 0248 DOM::TextEventImpl *impl() const 0249 { 0250 return static_cast<DOM::TextEventImpl *>(m_impl.get()); 0251 } 0252 }; 0253 0254 class DOMKeyboardEvent : public DOMKeyEventBase 0255 { 0256 public: 0257 DOMKeyboardEvent(ExecState *exec, DOM::KeyboardEventImpl *ke); 0258 ~DOMKeyboardEvent(); 0259 using KJS::JSObject::getOwnPropertySlot; 0260 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0261 JSValue *getValueProperty(ExecState *, int token) const; 0262 // no put - all read-only 0263 const ClassInfo *classInfo() const override 0264 { 0265 return &info; 0266 } 0267 static const ClassInfo info; 0268 enum {KeyIdentifier, KeyLocation, GetModifierState, InitKeyboardEvent}; 0269 DOM::KeyboardEventImpl *impl() const 0270 { 0271 return static_cast<DOM::KeyboardEventImpl *>(m_impl.get()); 0272 } 0273 }; 0274 0275 // Constructor object KeyboardEvent 0276 class KeyboardEventConstructor : public DOMObject 0277 { 0278 public: 0279 KeyboardEventConstructor(ExecState *); 0280 using KJS::JSObject::getOwnPropertySlot; 0281 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0282 JSValue *getValueProperty(ExecState *, int token) const; 0283 // no put - all read-only 0284 const ClassInfo *classInfo() const override 0285 { 0286 return &info; 0287 } 0288 static const ClassInfo info; 0289 }; 0290 0291 JSValue *getKeyboardEventConstructor(ExecState *exec); 0292 0293 // Constructor object MutationEvent 0294 class MutationEventConstructor : public DOMObject 0295 { 0296 public: 0297 MutationEventConstructor(ExecState *); 0298 using KJS::JSObject::getOwnPropertySlot; 0299 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0300 JSValue *getValueProperty(ExecState *, int token) const; 0301 // no put - all read-only 0302 const ClassInfo *classInfo() const override 0303 { 0304 return &info; 0305 } 0306 static const ClassInfo info; 0307 }; 0308 0309 JSValue *getMutationEventConstructor(ExecState *exec); 0310 0311 class DOMMutationEvent : public DOMEvent 0312 { 0313 public: 0314 DOMMutationEvent(ExecState *exec, DOM::MutationEventImpl *me); 0315 ~DOMMutationEvent(); 0316 using KJS::JSObject::getOwnPropertySlot; 0317 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0318 JSValue *getValueProperty(ExecState *, int token) const; 0319 // no put - all read-only 0320 const ClassInfo *classInfo() const override 0321 { 0322 return &info; 0323 } 0324 static const ClassInfo info; 0325 enum { AttrChange, RelatedNode, AttrName, PrevValue, NewValue, 0326 InitMutationEvent 0327 }; 0328 DOM::MutationEventImpl *impl() const 0329 { 0330 return static_cast<DOM::MutationEventImpl *>(m_impl.get()); 0331 } 0332 }; 0333 0334 class DOMMessageEvent: public DOMEvent 0335 { 0336 public: 0337 DOMMessageEvent(ExecState *exec, DOM::MessageEventImpl *me); 0338 0339 using KJS::JSObject::getOwnPropertySlot; 0340 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0341 JSValue *getValueProperty(ExecState *, int token) const; 0342 // no put - all read-only 0343 const ClassInfo *classInfo() const override 0344 { 0345 return &info; 0346 } 0347 static const ClassInfo info; 0348 enum { Data, Origin, Source, LastEventId, InitMessageEvent }; 0349 DOM::MessageEventImpl *impl() const 0350 { 0351 return static_cast<DOM::MessageEventImpl *>(m_impl.get()); 0352 } 0353 }; 0354 0355 DEFINE_PSEUDO_CONSTRUCTOR(MessageEventPseudoCtor) 0356 0357 class DOMHashChangeEvent : public DOMEvent 0358 { 0359 public: 0360 DOMHashChangeEvent(ExecState *exec, DOM::HashChangeEventImpl *me); 0361 0362 using KJS::JSObject::getOwnPropertySlot; 0363 bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override; 0364 JSValue *getValueProperty(ExecState *, int token) const; 0365 // no put - all read-only 0366 const ClassInfo *classInfo() const override 0367 { 0368 return &info; 0369 } 0370 static const ClassInfo info; 0371 enum { NewUrl, OldUrl, InitHashChangeEvent }; 0372 DOM::HashChangeEventImpl *impl() const 0373 { 0374 return static_cast<DOM::HashChangeEventImpl *>(m_impl.get()); 0375 } 0376 }; 0377 DEFINE_PSEUDO_CONSTRUCTOR(HashChangeEventPseudoCtor) 0378 0379 } // namespace 0380 0381 #endif