Back to index

lightning-sunbird  0.9+nobinonly
nsEventListenerManager.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef nsEventListenerManager_h__
00039 #define nsEventListenerManager_h__
00040 
00041 #include "nsIEventListenerManager.h"
00042 #include "jsapi.h"
00043 #include "nsCOMPtr.h"
00044 #include "nsIDOMEventReceiver.h"
00045 #include "nsIDOM3EventTarget.h"
00046 #include "nsHashtable.h"
00047 #include "nsIScriptContext.h"
00048 #include "nsJSUtils.h"
00049 
00050 class nsIDOMEvent;
00051 class nsIAtom;
00052 
00053 typedef struct {
00054   // The nsMarkedJSFunctionHolder does magic to avoid holding strong
00055   // references to listeners implemented in JS.  Instead, it protects
00056   // them from garbage collection using nsDOMClassInfo::PreserveWrapper,
00057   // which protects the event listener from garbage collection as long
00058   // as it is still reachable from JS using C++ getters.  (It exposes
00059   // reachability information to the JS GC instead of treating the C++
00060   // reachability information as own-in root-out, which creates roots
00061   // that cause reference cycles to entrain garbage.)
00062   nsMarkedJSFunctionHolder<nsIDOMEventListener> mListener;
00063 
00064   PRUint16 mFlags;
00065   PRUint16 mGroupFlags;
00066   PRUint8  mSubType;
00067   PRUint8  mHandlerIsString;
00068   PRUint8  mSubTypeCapture;
00069 } nsListenerStruct;
00070 
00071 //These define the internal type of the EventListenerManager
00072 //No listener type defined, should happen only at creation
00073 #define NS_ELM_NONE   0
00074 //Simple indicates only a single event listener group type (i.e. mouse, key) 
00075 #define NS_ELM_SINGLE 1
00076 //Multi indicates any number of listener group types accessed as member vars
00077 #define NS_ELM_MULTI  2
00078 //Hash indicates any number of listener group types accessed out of a hash
00079 #define NS_ELM_HASH   4
00080 
00081 enum EventArrayType {
00082   eEventArrayType_Mouse = 0,
00083   eEventArrayType_MouseMotion = 1,
00084   eEventArrayType_ContextMenu = 2,
00085   eEventArrayType_Key = 3,
00086   eEventArrayType_Load = 4,
00087   eEventArrayType_Focus = 5,
00088   eEventArrayType_Form = 6,
00089   eEventArrayType_Drag = 7,
00090   eEventArrayType_Paint = 8,
00091   eEventArrayType_Text = 9,
00092   eEventArrayType_Composition = 10,
00093   eEventArrayType_XUL = 11,
00094   eEventArrayType_Scroll = 12,
00095   eEventArrayType_Mutation = 13,
00096   eEventArrayType_DOMUI = 14,
00097   eEventArrayType_PageTransition = 15,
00098 #ifdef MOZ_SVG
00099   eEventArrayType_SVG = 16,
00100   eEventArrayType_SVGZoom = 17,
00101 #endif // MOZ_SVG
00102   eEventArrayType_Hash,
00103   eEventArrayType_None
00104 };
00105 
00106 //Keep this in line with event array types, not counting
00107 //types HASH and NONE
00108 #define EVENT_ARRAY_TYPE_LENGTH eEventArrayType_Hash
00109 
00110 /*
00111  * Event listener manager
00112  */
00113 
00114 class nsEventListenerManager : public nsIEventListenerManager,
00115                                public nsIDOMEventReceiver,
00116                                public nsIDOM3EventTarget
00117 {
00118 
00119 public:
00120   nsEventListenerManager();
00121   virtual ~nsEventListenerManager();
00122 
00123   NS_DECL_ISUPPORTS
00124 
00129   NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener,
00130                                    const nsIID& aIID, PRInt32 aFlags);
00131   NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener,
00132                                       const nsIID& aIID, PRInt32 aFlags);
00133   NS_IMETHOD AddEventListenerByType(nsIDOMEventListener *aListener,
00134                                     const nsAString& type,
00135                                     PRInt32 aFlags,
00136                                     nsIDOMEventGroup* aEvtGroup);
00137   NS_IMETHOD RemoveEventListenerByType(nsIDOMEventListener *aListener,
00138                                        const nsAString& type,
00139                                        PRInt32 aFlags,
00140                                        nsIDOMEventGroup* aEvtGroup);
00141   NS_IMETHOD AddScriptEventListener(nsISupports *aObject,
00142                                     nsIAtom *aName,
00143                                     const nsAString& aFunc,
00144                                     PRBool aDeferCompilation,
00145                                     PRBool aPermitUntrustedEvents);
00146   NS_IMETHOD RegisterScriptEventListener(nsIScriptContext *aContext,
00147                                          JSObject *aScopeObject,
00148                                          nsISupports *aObject,
00149                                          nsIAtom* aName);
00150   NS_IMETHOD RemoveScriptEventListener(nsIAtom *aName);
00151   NS_IMETHOD CompileScriptEventListener(nsIScriptContext *aContext,
00152                                         JSObject *aScopeObject,
00153                                         nsISupports *aObject,
00154                                         nsIAtom* aName, PRBool *aDidCompile);
00155 
00156   NS_IMETHOD CaptureEvent(PRInt32 aEventTypes);
00157   NS_IMETHOD ReleaseEvent(PRInt32 aEventTypes);
00158 
00159   NS_IMETHOD HandleEvent(nsPresContext* aPresContext, 
00160                          nsEvent* aEvent, 
00161                          nsIDOMEvent** aDOMEvent,
00162                          nsIDOMEventTarget* aCurrentTarget,
00163                          PRUint32 aFlags,
00164                          nsEventStatus* aEventStatus);
00165 
00166   NS_IMETHOD CreateEvent(nsPresContext* aPresContext, 
00167                          nsEvent* aEvent,
00168                          const nsAString& aEventType,
00169                          nsIDOMEvent** aDOMEvent);
00170 
00171   NS_IMETHOD Disconnect(PRBool aUnusedParam = PR_FALSE);
00172 
00173   NS_IMETHOD SetListenerTarget(nsISupports* aTarget);
00174 
00175   NS_IMETHOD HasMutationListeners(PRBool* aListener)
00176   {
00177     *aListener = (GetListenersByType(eEventArrayType_Mutation, nsnull,
00178                                      PR_FALSE) != nsnull);
00179     return NS_OK;
00180   }
00181 
00182   NS_IMETHOD GetSystemEventGroupLM(nsIDOMEventGroup** aGroup);
00183 
00184   virtual PRBool HasUnloadListeners();
00185 
00186   static nsresult GetIdentifiersForType(nsIAtom* aType,
00187                                         EventArrayType* aArrayType,
00188                                         PRInt32* aSubType);
00189 
00190   // nsIDOMEventTarget
00191   NS_DECL_NSIDOMEVENTTARGET
00192 
00193   // nsIDOM3EventTarget
00194   NS_DECL_NSIDOM3EVENTTARGET
00195 
00196   // nsIDOMEventReceiver interface
00197   NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener,
00198                                    const nsIID& aIID);
00199   NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener,
00200                                       const nsIID& aIID);
00201   NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
00202   NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
00203   NS_IMETHOD GetSystemEventGroup(nsIDOMEventGroup** aGroup);
00204 
00205   static void Shutdown();
00206 
00207 protected:
00208   nsresult HandleEventSubType(nsListenerStruct* aListenerStruct,
00209                               nsIDOMEventListener* aListener,
00210                               nsIDOMEvent* aDOMEvent,
00211                               nsIDOMEventTarget* aCurrentTarget,
00212                               PRUint32 aSubType,
00213                               PRUint32 aPhaseFlags);
00214   nsresult CompileEventHandlerInternal(nsIScriptContext *aContext,
00215                                        JSObject *aScopeObject,
00216                                        nsISupports *aObject,
00217                                        nsIAtom *aName,
00218                                        nsListenerStruct *aListenerStruct,
00219                                        nsIDOMEventTarget* aCurrentTarget,
00220                                        PRUint32 aSubType);
00221   nsListenerStruct* FindJSEventListener(EventArrayType aType);
00222   nsresult SetJSEventListener(nsIScriptContext *aContext,
00223                               JSObject *aScopeObject, nsISupports *aObject,
00224                               nsIAtom* aName, PRBool aIsString,
00225                               PRBool aPermitUntrustedEvents);
00226   nsresult AddEventListener(nsIDOMEventListener *aListener, 
00227                             EventArrayType aType, 
00228                             PRInt32 aSubType,
00229                             nsHashKey* aKey,
00230                             PRInt32 aFlags,
00231                             nsIDOMEventGroup* aEvtGrp);
00232   nsresult RemoveEventListener(nsIDOMEventListener *aListener,
00233                                EventArrayType aType,
00234                                PRInt32 aSubType,
00235                                nsHashKey* aKey,
00236                                PRInt32 aFlags,
00237                                nsIDOMEventGroup* aEvtGrp);
00238   void ReleaseListeners(nsVoidArray** aListeners);
00239   nsresult RemoveAllListeners();
00240   nsresult FlipCaptureBit(PRInt32 aEventTypes, PRBool aInitCapture);
00241   nsVoidArray* GetListenersByType(EventArrayType aType, nsHashKey* aKey, PRBool aCreate);
00242   EventArrayType GetTypeForIID(const nsIID& aIID);
00243   nsresult FixContextMenuEvent(nsPresContext* aPresContext,
00244                                nsIDOMEventTarget* aCurrentTarget,
00245                                nsEvent* aEvent,
00246                                nsIDOMEvent** aDOMEvent);
00247   PRBool PrepareToUseCaretPosition(nsIWidget* aEventWidget,
00248                                    nsEvent* aEvent,
00249                                    nsIPresShell* aShell);
00250   void GetCoordinatesFor(nsIDOMElement *aCurrentEl, nsPresContext *aPresContext,
00251                          nsIPresShell *aPresShell, nsPoint& aTargetPt);
00252   nsresult GetDOM2EventGroup(nsIDOMEventGroup** aGroup);
00253 
00254   PRUint8 mManagerType;
00255   PRPackedBool mListenersRemoved;
00256 
00257   EventArrayType mSingleListenerType;
00258   nsVoidArray* mSingleListener;
00259   nsVoidArray* mMultiListeners;
00260   nsHashtable* mGenericListeners;
00261   static PRUint32 mInstanceCount;
00262 
00263   nsISupports* mTarget;  //WEAK
00264 
00265   static jsval sAddListenerID;
00266 };
00267 
00268 
00269 //Set of defines for distinguishing event handlers within listener groupings
00270 //XXX Current usage allows no more than 7 types per listener grouping
00271 
00272 #define NS_EVENT_BITS_NONE    0x00
00273 
00274 //nsIDOMMouseListener
00275 #define NS_EVENT_BITS_MOUSE_NONE        0x00
00276 #define NS_EVENT_BITS_MOUSE_MOUSEDOWN   0x01
00277 #define NS_EVENT_BITS_MOUSE_MOUSEUP     0x02
00278 #define NS_EVENT_BITS_MOUSE_CLICK       0x04
00279 #define NS_EVENT_BITS_MOUSE_DBLCLICK    0x08
00280 #define NS_EVENT_BITS_MOUSE_MOUSEOVER   0x10
00281 #define NS_EVENT_BITS_MOUSE_MOUSEOUT    0x20
00282 
00283 //nsIDOMMouseMotionListener
00284 #define NS_EVENT_BITS_MOUSEMOTION_NONE        0x00
00285 #define NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE   0x01
00286 #define NS_EVENT_BITS_MOUSEMOTION_DRAGMOVE    0x02
00287 
00288 //nsIDOMContextMenuListener
00289 #define NS_EVENT_BITS_CONTEXTMENU_NONE   0x00
00290 #define NS_EVENT_BITS_CONTEXTMENU        0x01
00291 
00292 //nsIDOMKeyListener
00293 #define NS_EVENT_BITS_KEY_NONE      0x00
00294 #define NS_EVENT_BITS_KEY_KEYDOWN   0x01
00295 #define NS_EVENT_BITS_KEY_KEYUP     0x02
00296 #define NS_EVENT_BITS_KEY_KEYPRESS  0x04
00297 
00298 //nsIDOMTextListener
00299 #define NS_EVENT_BITS_TEXT_NONE      0x00
00300 #define NS_EVENT_BITS_TEXT_TEXT      0x01
00301 
00302 //nsIDOMCompositionListener
00303 #define NS_EVENT_BITS_COMPOSITION_NONE           0x00
00304 #define NS_EVENT_BITS_COMPOSITION_START          0x01
00305 #define NS_EVENT_BITS_COMPOSITION_END            0x02
00306 #define NS_EVENT_BITS_COMPOSITION_QUERY          0x04
00307 #define NS_EVENT_BITS_COMPOSITION_RECONVERSION   0x08
00308 #define NS_EVENT_BITS_COMPOSITION_QUERYCARETRECT 0x10
00309 
00310 //nsIDOMFocusListener
00311 #define NS_EVENT_BITS_FOCUS_NONE    0x00
00312 #define NS_EVENT_BITS_FOCUS_FOCUS   0x01
00313 #define NS_EVENT_BITS_FOCUS_BLUR    0x02
00314 
00315 //nsIDOMFormListener
00316 #define NS_EVENT_BITS_FORM_NONE     0x00
00317 #define NS_EVENT_BITS_FORM_SUBMIT   0x01
00318 #define NS_EVENT_BITS_FORM_RESET    0x02
00319 #define NS_EVENT_BITS_FORM_CHANGE   0x04
00320 #define NS_EVENT_BITS_FORM_SELECT   0x08
00321 #define NS_EVENT_BITS_FORM_INPUT    0x10
00322 
00323 //nsIDOMLoadListener
00324 #define NS_EVENT_BITS_LOAD_NONE              0x00
00325 #define NS_EVENT_BITS_LOAD_LOAD              0x01
00326 #define NS_EVENT_BITS_LOAD_UNLOAD            0x02
00327 #define NS_EVENT_BITS_LOAD_ABORT             0x04
00328 #define NS_EVENT_BITS_LOAD_ERROR             0x08
00329 #define NS_EVENT_BITS_LOAD_BEFORE_UNLOAD     0x10
00330 
00331 //nsIDOMXULListener
00332 #define NS_EVENT_BITS_XUL_NONE               0x00
00333 #define NS_EVENT_BITS_XUL_POPUP_SHOWING      0x01
00334 #define NS_EVENT_BITS_XUL_CLOSE              0x02
00335 #define NS_EVENT_BITS_XUL_POPUP_HIDING       0x04
00336 #define NS_EVENT_BITS_XUL_COMMAND            0x08
00337 #define NS_EVENT_BITS_XUL_BROADCAST          0x10
00338 #define NS_EVENT_BITS_XUL_COMMAND_UPDATE     0x20
00339 #define NS_EVENT_BITS_XUL_POPUP_SHOWN        0x40
00340 #define NS_EVENT_BITS_XUL_POPUP_HIDDEN       0x80
00341 
00342 //nsIScrollListener
00343 #define NS_EVENT_BITS_SCROLLPORT_NONE             0x00
00344 #define NS_EVENT_BITS_SCROLLPORT_OVERFLOW         0x01
00345 #define NS_EVENT_BITS_SCROLLPORT_UNDERFLOW        0x02
00346 #define NS_EVENT_BITS_SCROLLPORT_OVERFLOWCHANGED  0x04
00347 
00348 //nsIDOMDragListener
00349 #define NS_EVENT_BITS_DRAG_NONE     0x00
00350 #define NS_EVENT_BITS_DRAG_ENTER    0x01
00351 #define NS_EVENT_BITS_DRAG_OVER     0x02
00352 #define NS_EVENT_BITS_DRAG_EXIT     0x04
00353 #define NS_EVENT_BITS_DRAG_DROP     0x08
00354 #define NS_EVENT_BITS_DRAG_GESTURE  0x10
00355 
00356 //nsIDOMPaintListener
00357 #define NS_EVENT_BITS_PAINT_NONE    0x00
00358 #define NS_EVENT_BITS_PAINT_PAINT   0x01
00359 #define NS_EVENT_BITS_PAINT_RESIZE  0x02
00360 #define NS_EVENT_BITS_PAINT_SCROLL  0x04
00361 
00362 //nsIDOMMutationListener
00363 // These bits are found in nsMutationEvent.h.
00364 
00365 //nsIDOMContextMenuListener
00366 #define NS_EVENT_BITS_CONTEXT_NONE  0x00
00367 #define NS_EVENT_BITS_CONTEXT_MENU  0x01
00368 
00369 // nsIDOMUIListener
00370 #define NS_EVENT_BITS_UI_NONE      0x00
00371 #define NS_EVENT_BITS_UI_ACTIVATE  0x01
00372 #define NS_EVENT_BITS_UI_FOCUSIN   0x02
00373 #define NS_EVENT_BITS_UI_FOCUSOUT  0x04
00374 
00375 // nsIDOMPageTransitionListener
00376 #define NS_EVENT_BITS_PAGETRANSITION_NONE 0x00
00377 #define NS_EVENT_BITS_PAGETRANSITION_SHOW 0x01
00378 #define NS_EVENT_BITS_PAGETRANSITION_HIDE 0x02
00379 
00380 #ifdef MOZ_SVG
00381 // nsIDOMSVGEventListener
00382 #define NS_EVENT_BITS_SVG_NONE      0x00
00383 #define NS_EVENT_BITS_SVG_LOAD      0x01
00384 #define NS_EVENT_BITS_SVG_UNLOAD    0x02
00385 #define NS_EVENT_BITS_SVG_ABORT     0x04
00386 #define NS_EVENT_BITS_SVG_ERROR     0x08
00387 #define NS_EVENT_BITS_SVG_RESIZE    0x10
00388 #define NS_EVENT_BITS_SVG_SCROLL    0x20
00389 
00390 // nsIDOMSVGZoomEventListener
00391 #define NS_EVENT_BITS_SVGZOOM_NONE  0x00
00392 #define NS_EVENT_BITS_SVGZOOM_ZOOM  0x01
00393 #endif // MOZ_SVG
00394 
00395 #endif // nsEventListenerManager_h__