|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef nsXBLPrototypeHandler_h__ |
|
7 #define nsXBLPrototypeHandler_h__ |
|
8 |
|
9 #include "nsIAtom.h" |
|
10 #include "nsString.h" |
|
11 #include "nsCOMPtr.h" |
|
12 #include "nsIController.h" |
|
13 #include "nsAutoPtr.h" |
|
14 #include "nsXBLEventHandler.h" |
|
15 #include "nsIWeakReference.h" |
|
16 #include "nsIScriptGlobalObject.h" |
|
17 #include "nsCycleCollectionParticipant.h" |
|
18 #include "js/TypeDecls.h" |
|
19 |
|
20 class nsIDOMEvent; |
|
21 class nsIContent; |
|
22 class nsIDOMUIEvent; |
|
23 class nsIDOMKeyEvent; |
|
24 class nsIDOMMouseEvent; |
|
25 class nsIObjectInputStream; |
|
26 class nsIObjectOutputStream; |
|
27 class nsXBLPrototypeBinding; |
|
28 |
|
29 namespace mozilla { |
|
30 namespace dom { |
|
31 class EventTarget; |
|
32 } |
|
33 } |
|
34 |
|
35 #define NS_HANDLER_TYPE_XBL_JS (1 << 0) |
|
36 #define NS_HANDLER_TYPE_XBL_COMMAND (1 << 1) |
|
37 #define NS_HANDLER_TYPE_XUL (1 << 2) |
|
38 #define NS_HANDLER_HAS_ALLOW_UNTRUSTED_ATTR (1 << 4) |
|
39 #define NS_HANDLER_ALLOW_UNTRUSTED (1 << 5) |
|
40 #define NS_HANDLER_TYPE_SYSTEM (1 << 6) |
|
41 #define NS_HANDLER_TYPE_PREVENTDEFAULT (1 << 7) |
|
42 |
|
43 // XXX Use nsIDOMEvent:: codes? |
|
44 #define NS_PHASE_CAPTURING 1 |
|
45 #define NS_PHASE_TARGET 2 |
|
46 #define NS_PHASE_BUBBLING 3 |
|
47 |
|
48 class nsXBLPrototypeHandler |
|
49 { |
|
50 public: |
|
51 // This constructor is used by XBL handlers (both the JS and command shorthand variety) |
|
52 nsXBLPrototypeHandler(const char16_t* aEvent, const char16_t* aPhase, |
|
53 const char16_t* aAction, const char16_t* aCommand, |
|
54 const char16_t* aKeyCode, const char16_t* aCharCode, |
|
55 const char16_t* aModifiers, const char16_t* aButton, |
|
56 const char16_t* aClickCount, const char16_t* aGroup, |
|
57 const char16_t* aPreventDefault, |
|
58 const char16_t* aAllowUntrusted, |
|
59 nsXBLPrototypeBinding* aBinding, |
|
60 uint32_t aLineNumber); |
|
61 |
|
62 // This constructor is used only by XUL key handlers (e.g., <key>) |
|
63 nsXBLPrototypeHandler(nsIContent* aKeyElement); |
|
64 |
|
65 // This constructor is used for handlers loaded from the cache |
|
66 nsXBLPrototypeHandler(nsXBLPrototypeBinding* aBinding); |
|
67 |
|
68 ~nsXBLPrototypeHandler(); |
|
69 |
|
70 // if aCharCode is not zero, it is used instead of the charCode of aKeyEvent. |
|
71 bool KeyEventMatched(nsIDOMKeyEvent* aKeyEvent, |
|
72 uint32_t aCharCode = 0, |
|
73 bool aIgnoreShiftKey = false); |
|
74 inline bool KeyEventMatched(nsIAtom* aEventType, |
|
75 nsIDOMKeyEvent* aEvent, |
|
76 uint32_t aCharCode = 0, |
|
77 bool aIgnoreShiftKey = false) |
|
78 { |
|
79 if (aEventType != mEventName) |
|
80 return false; |
|
81 |
|
82 return KeyEventMatched(aEvent, aCharCode, aIgnoreShiftKey); |
|
83 } |
|
84 |
|
85 bool MouseEventMatched(nsIDOMMouseEvent* aMouseEvent); |
|
86 inline bool MouseEventMatched(nsIAtom* aEventType, |
|
87 nsIDOMMouseEvent* aEvent) |
|
88 { |
|
89 if (aEventType != mEventName) |
|
90 return false; |
|
91 |
|
92 return MouseEventMatched(aEvent); |
|
93 } |
|
94 |
|
95 already_AddRefed<nsIContent> GetHandlerElement(); |
|
96 |
|
97 void AppendHandlerText(const nsAString& aText); |
|
98 |
|
99 uint8_t GetPhase() { return mPhase; } |
|
100 uint8_t GetType() { return mType; } |
|
101 |
|
102 nsXBLPrototypeHandler* GetNextHandler() { return mNextHandler; } |
|
103 void SetNextHandler(nsXBLPrototypeHandler* aHandler) { mNextHandler = aHandler; } |
|
104 |
|
105 nsresult ExecuteHandler(mozilla::dom::EventTarget* aTarget, nsIDOMEvent* aEvent); |
|
106 |
|
107 already_AddRefed<nsIAtom> GetEventName(); |
|
108 void SetEventName(nsIAtom* aName) { mEventName = aName; } |
|
109 |
|
110 nsXBLEventHandler* GetEventHandler() |
|
111 { |
|
112 if (!mHandler) { |
|
113 NS_NewXBLEventHandler(this, mEventName, getter_AddRefs(mHandler)); |
|
114 // XXX Need to signal out of memory? |
|
115 } |
|
116 |
|
117 return mHandler; |
|
118 } |
|
119 |
|
120 nsXBLEventHandler* GetCachedEventHandler() |
|
121 { |
|
122 return mHandler; |
|
123 } |
|
124 |
|
125 bool HasAllowUntrustedAttr() |
|
126 { |
|
127 return (mType & NS_HANDLER_HAS_ALLOW_UNTRUSTED_ATTR) != 0; |
|
128 } |
|
129 |
|
130 // This returns a valid value only if HasAllowUntrustedEventsAttr returns |
|
131 // true. |
|
132 bool AllowUntrustedEvents() |
|
133 { |
|
134 return (mType & NS_HANDLER_ALLOW_UNTRUSTED) != 0; |
|
135 } |
|
136 |
|
137 nsresult Read(nsIObjectInputStream* aStream); |
|
138 nsresult Write(nsIObjectOutputStream* aStream); |
|
139 |
|
140 public: |
|
141 static uint32_t gRefCnt; |
|
142 |
|
143 protected: |
|
144 void Init() { |
|
145 ++gRefCnt; |
|
146 if (gRefCnt == 1) |
|
147 // Get the primary accelerator key. |
|
148 InitAccessKeys(); |
|
149 } |
|
150 |
|
151 already_AddRefed<nsIController> GetController(mozilla::dom::EventTarget* aTarget); |
|
152 |
|
153 inline int32_t GetMatchingKeyCode(const nsAString& aKeyName); |
|
154 void ConstructPrototype(nsIContent* aKeyElement, |
|
155 const char16_t* aEvent=nullptr, const char16_t* aPhase=nullptr, |
|
156 const char16_t* aAction=nullptr, const char16_t* aCommand=nullptr, |
|
157 const char16_t* aKeyCode=nullptr, const char16_t* aCharCode=nullptr, |
|
158 const char16_t* aModifiers=nullptr, const char16_t* aButton=nullptr, |
|
159 const char16_t* aClickCount=nullptr, const char16_t* aGroup=nullptr, |
|
160 const char16_t* aPreventDefault=nullptr, |
|
161 const char16_t* aAllowUntrusted=nullptr); |
|
162 |
|
163 void ReportKeyConflict(const char16_t* aKey, const char16_t* aModifiers, nsIContent* aElement, const char *aMessageName); |
|
164 void GetEventType(nsAString& type); |
|
165 bool ModifiersMatchMask(nsIDOMUIEvent* aEvent, |
|
166 bool aIgnoreShiftKey = false); |
|
167 nsresult DispatchXBLCommand(mozilla::dom::EventTarget* aTarget, nsIDOMEvent* aEvent); |
|
168 nsresult DispatchXULKeyCommand(nsIDOMEvent* aEvent); |
|
169 nsresult EnsureEventHandler(nsIScriptGlobalObject* aGlobal, |
|
170 nsIScriptContext *aBoundContext, nsIAtom *aName, |
|
171 JS::MutableHandle<JSObject*> aHandler); |
|
172 static int32_t KeyToMask(int32_t key); |
|
173 |
|
174 static int32_t kAccelKey; |
|
175 static int32_t kMenuAccessKey; |
|
176 static void InitAccessKeys(); |
|
177 |
|
178 static const int32_t cShift; |
|
179 static const int32_t cAlt; |
|
180 static const int32_t cControl; |
|
181 static const int32_t cMeta; |
|
182 static const int32_t cOS; |
|
183 |
|
184 static const int32_t cShiftMask; |
|
185 static const int32_t cAltMask; |
|
186 static const int32_t cControlMask; |
|
187 static const int32_t cMetaMask; |
|
188 static const int32_t cOSMask; |
|
189 |
|
190 static const int32_t cAllModifiers; |
|
191 |
|
192 protected: |
|
193 union { |
|
194 nsIWeakReference* mHandlerElement; // For XUL <key> element handlers. [STRONG] |
|
195 char16_t* mHandlerText; // For XBL handlers (we don't build an |
|
196 // element for the <handler>, and instead |
|
197 // we cache the JS text or command name |
|
198 // that we should use. |
|
199 }; |
|
200 |
|
201 uint32_t mLineNumber; // The line number we started at in the XBL file |
|
202 |
|
203 // The following four values make up 32 bits. |
|
204 uint8_t mPhase; // The phase (capturing, bubbling) |
|
205 uint8_t mType; // The type of the handler. The handler is either a XUL key |
|
206 // handler, an XBL "command" event, or a normal XBL event with |
|
207 // accompanying JavaScript. The high bit is used to indicate |
|
208 // whether this handler should prevent the default action. |
|
209 uint8_t mMisc; // Miscellaneous extra information. For key events, |
|
210 // stores whether or not we're a key code or char code. |
|
211 // For mouse events, stores the clickCount. |
|
212 |
|
213 int32_t mKeyMask; // Which modifier keys this event handler expects to have down |
|
214 // in order to be matched. |
|
215 |
|
216 // The primary filter information for mouse/key events. |
|
217 int32_t mDetail; // For key events, contains a charcode or keycode. For |
|
218 // mouse events, stores the button info. |
|
219 |
|
220 // Prototype handlers are chained. We own the next handler in the chain. |
|
221 nsXBLPrototypeHandler* mNextHandler; |
|
222 nsCOMPtr<nsIAtom> mEventName; // The type of the event, e.g., "keypress" |
|
223 nsRefPtr<nsXBLEventHandler> mHandler; |
|
224 nsXBLPrototypeBinding* mPrototypeBinding; // the binding owns us |
|
225 }; |
|
226 |
|
227 #endif |