File indexing completed on 2024-04-28 15:23:12

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