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/. */
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
)
32 nsXBLEventHandler::HandleEvent(nsIDOMEvent
* aEvent
)
35 return NS_ERROR_FAILURE
;
37 uint8_t phase
= mProtoHandler
->GetPhase();
38 if (phase
== NS_PHASE_TARGET
) {
40 aEvent
->GetEventPhase(&eventPhase
);
41 if (eventPhase
!= nsIDOMEvent::AT_TARGET
)
45 if (!EventMatched(aEvent
))
48 mProtoHandler
->ExecuteHandler(aEvent
->InternalDOMEvent()->GetCurrentTarget(),
54 nsXBLMouseEventHandler::nsXBLMouseEventHandler(nsXBLPrototypeHandler
* aHandler
)
55 : nsXBLEventHandler(aHandler
)
59 nsXBLMouseEventHandler::~nsXBLMouseEventHandler()
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
,
72 : mEventType(aEventType
),
75 mIsBoundToChrome(false),
76 mUsingContentXBLScope(false)
80 nsXBLKeyEventHandler::~nsXBLKeyEventHandler()
84 NS_IMPL_ISUPPORTS(nsXBLKeyEventHandler
, nsIDOMEventListener
)
87 nsXBLKeyEventHandler::ExecuteMatchedHandlers(
88 nsIDOMKeyEvent
* aKeyEvent
,
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
);
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
);
125 nsXBLKeyEventHandler::HandleEvent(nsIDOMEvent
* aEvent
)
127 uint32_t count
= mProtoHandlers
.Length();
129 return NS_ERROR_FAILURE
;
131 if (mPhase
== NS_PHASE_TARGET
) {
133 aEvent
->GetEventPhase(&eventPhase
);
134 if (eventPhase
!= nsIDOMEvent::AT_TARGET
)
138 nsCOMPtr
<nsIDOMKeyEvent
> key(do_QueryInterface(aEvent
));
142 nsAutoTArray
<nsShortcutCandidate
, 10> accessKeys
;
143 nsContentUtils::GetAccelKeyCandidates(key
, accessKeys
);
145 if (accessKeys
.IsEmpty()) {
146 ExecuteMatchedHandlers(key
, 0, IgnoreModifierState());
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
)) {
161 ///////////////////////////////////////////////////////////////////////////////////
164 NS_NewXBLEventHandler(nsXBLPrototypeHandler
* aHandler
,
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
);
177 *aResult
= new nsXBLEventHandler(aHandler
);
182 return NS_ERROR_OUT_OF_MEMORY
;
190 NS_NewXBLKeyEventHandler(nsIAtom
* aEventType
, uint8_t aPhase
, uint8_t aType
,
191 nsXBLKeyEventHandler
** aResult
)
193 *aResult
= new nsXBLKeyEventHandler(aEventType
, aPhase
, aType
);
196 return NS_ERROR_OUT_OF_MEMORY
;