Bumping manifests a=b2g-bump
[gecko.git] / dom / xbl / nsXBLEventHandler.cpp
blob46cb8743b829f3ec5fad49dcca9ea1cc966e12f9
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/. */
6 #include "nsCOMPtr.h"
7 #include "nsIAtom.h"
8 #include "nsIDOMEventListener.h"
9 #include "nsIDOMKeyEvent.h"
10 #include "nsIDOMMouseEvent.h"
11 #include "nsXBLPrototypeHandler.h"
12 #include "nsContentUtils.h"
13 #include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
14 #include "mozilla/dom/EventTarget.h"
15 #include "mozilla/TextEvents.h"
17 using namespace mozilla;
18 using namespace mozilla::dom;
20 nsXBLEventHandler::nsXBLEventHandler(nsXBLPrototypeHandler* aHandler)
21 : mProtoHandler(aHandler)
25 nsXBLEventHandler::~nsXBLEventHandler()
29 NS_IMPL_ISUPPORTS(nsXBLEventHandler, nsIDOMEventListener)
31 NS_IMETHODIMP
32 nsXBLEventHandler::HandleEvent(nsIDOMEvent* aEvent)
34 if (!mProtoHandler)
35 return NS_ERROR_FAILURE;
37 uint8_t phase = mProtoHandler->GetPhase();
38 if (phase == NS_PHASE_TARGET) {
39 uint16_t eventPhase;
40 aEvent->GetEventPhase(&eventPhase);
41 if (eventPhase != nsIDOMEvent::AT_TARGET)
42 return NS_OK;
45 if (!EventMatched(aEvent))
46 return NS_OK;
48 mProtoHandler->ExecuteHandler(aEvent->InternalDOMEvent()->GetCurrentTarget(),
49 aEvent);
51 return NS_OK;
54 nsXBLMouseEventHandler::nsXBLMouseEventHandler(nsXBLPrototypeHandler* aHandler)
55 : nsXBLEventHandler(aHandler)
59 nsXBLMouseEventHandler::~nsXBLMouseEventHandler()
63 bool
64 nsXBLMouseEventHandler::EventMatched(nsIDOMEvent* aEvent)
66 nsCOMPtr<nsIDOMMouseEvent> mouse(do_QueryInterface(aEvent));
67 return mouse && mProtoHandler->MouseEventMatched(mouse);
70 nsXBLKeyEventHandler::nsXBLKeyEventHandler(nsIAtom* aEventType, uint8_t aPhase,
71 uint8_t aType)
72 : mEventType(aEventType),
73 mPhase(aPhase),
74 mType(aType),
75 mIsBoundToChrome(false),
76 mUsingContentXBLScope(false)
80 nsXBLKeyEventHandler::~nsXBLKeyEventHandler()
84 NS_IMPL_ISUPPORTS(nsXBLKeyEventHandler, nsIDOMEventListener)
86 bool
87 nsXBLKeyEventHandler::ExecuteMatchedHandlers(
88 nsIDOMKeyEvent* aKeyEvent,
89 uint32_t aCharCode,
90 const IgnoreModifierState& aIgnoreModifierState)
92 WidgetEvent* event = aKeyEvent->GetInternalNSEvent();
93 nsCOMPtr<EventTarget> target = aKeyEvent->InternalDOMEvent()->GetCurrentTarget();
95 bool executed = false;
96 for (uint32_t i = 0; i < mProtoHandlers.Length(); ++i) {
97 nsXBLPrototypeHandler* handler = mProtoHandlers[i];
98 bool hasAllowUntrustedAttr = handler->HasAllowUntrustedAttr();
99 if ((event->mFlags.mIsTrusted ||
100 (hasAllowUntrustedAttr && handler->AllowUntrustedEvents()) ||
101 (!hasAllowUntrustedAttr && !mIsBoundToChrome && !mUsingContentXBLScope)) &&
102 handler->KeyEventMatched(aKeyEvent, aCharCode, aIgnoreModifierState)) {
103 handler->ExecuteHandler(target, aKeyEvent);
104 executed = true;
107 #ifdef XP_WIN
108 // Windows native applications ignore Windows-Logo key state when checking
109 // shortcut keys even if the key is pressed. Therefore, if there is no
110 // shortcut key which exactly matches current modifier state, we should
111 // retry to look for a shortcut key without the Windows-Logo key press.
112 if (!executed && !aIgnoreModifierState.mOS) {
113 WidgetKeyboardEvent* keyEvent = event->AsKeyboardEvent();
114 if (keyEvent && keyEvent->IsOS()) {
115 IgnoreModifierState ignoreModifierState(aIgnoreModifierState);
116 ignoreModifierState.mOS = true;
117 return ExecuteMatchedHandlers(aKeyEvent, aCharCode, ignoreModifierState);
120 #endif
121 return executed;
124 NS_IMETHODIMP
125 nsXBLKeyEventHandler::HandleEvent(nsIDOMEvent* aEvent)
127 uint32_t count = mProtoHandlers.Length();
128 if (count == 0)
129 return NS_ERROR_FAILURE;
131 if (mPhase == NS_PHASE_TARGET) {
132 uint16_t eventPhase;
133 aEvent->GetEventPhase(&eventPhase);
134 if (eventPhase != nsIDOMEvent::AT_TARGET)
135 return NS_OK;
138 nsCOMPtr<nsIDOMKeyEvent> key(do_QueryInterface(aEvent));
139 if (!key)
140 return NS_OK;
142 nsAutoTArray<nsShortcutCandidate, 10> accessKeys;
143 nsContentUtils::GetAccelKeyCandidates(key, accessKeys);
145 if (accessKeys.IsEmpty()) {
146 ExecuteMatchedHandlers(key, 0, IgnoreModifierState());
147 return NS_OK;
150 for (uint32_t i = 0; i < accessKeys.Length(); ++i) {
151 IgnoreModifierState ignoreModifierState;
152 ignoreModifierState.mShift = accessKeys[i].mIgnoreShift;
153 if (ExecuteMatchedHandlers(key, accessKeys[i].mCharCode,
154 ignoreModifierState)) {
155 return NS_OK;
158 return NS_OK;
161 ///////////////////////////////////////////////////////////////////////////////////
163 nsresult
164 NS_NewXBLEventHandler(nsXBLPrototypeHandler* aHandler,
165 nsIAtom* aEventType,
166 nsXBLEventHandler** aResult)
168 switch (nsContentUtils::GetEventClassID(nsDependentAtomString(aEventType))) {
169 case eDragEventClass:
170 case eMouseEventClass:
171 case eMouseScrollEventClass:
172 case eWheelEventClass:
173 case eSimpleGestureEventClass:
174 *aResult = new nsXBLMouseEventHandler(aHandler);
175 break;
176 default:
177 *aResult = new nsXBLEventHandler(aHandler);
178 break;
181 if (!*aResult)
182 return NS_ERROR_OUT_OF_MEMORY;
184 NS_ADDREF(*aResult);
186 return NS_OK;
189 nsresult
190 NS_NewXBLKeyEventHandler(nsIAtom* aEventType, uint8_t aPhase, uint8_t aType,
191 nsXBLKeyEventHandler** aResult)
193 *aResult = new nsXBLKeyEventHandler(aEventType, aPhase, aType);
195 if (!*aResult)
196 return NS_ERROR_OUT_OF_MEMORY;
198 NS_ADDREF(*aResult);
200 return NS_OK;