Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/events/actioneventwrapper.js
2868 views
1
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
* @fileoverview Action event wrapper implementation.
17
* @author [email protected] (Emil A Eklund)
18
*/
19
20
goog.provide('goog.events.actionEventWrapper');
21
22
goog.require('goog.a11y.aria');
23
goog.require('goog.a11y.aria.Role');
24
goog.require('goog.dom');
25
goog.require('goog.events');
26
/** @suppress {extraRequire} */
27
goog.require('goog.events.EventHandler');
28
goog.require('goog.events.EventType');
29
goog.require('goog.events.EventWrapper');
30
goog.require('goog.events.KeyCodes');
31
goog.require('goog.userAgent');
32
33
34
35
/**
36
* Event wrapper for action handling. Fires when an element is activated either
37
* by clicking it or by focusing it and pressing Enter.
38
*
39
* @constructor
40
* @implements {goog.events.EventWrapper}
41
* @private
42
*/
43
goog.events.ActionEventWrapper_ = function() {};
44
45
/**
46
* @interface
47
* @private
48
*/
49
goog.events.ActionEventWrapper_.FunctionExtension_ = function() {};
50
51
/** @type {!Object|undefined} */
52
goog.events.ActionEventWrapper_.FunctionExtension_.prototype.scope_;
53
54
/** @type {function(?):?|{handleEvent:function(?):?}|null} */
55
goog.events.ActionEventWrapper_.FunctionExtension_.prototype.listener_;
56
57
58
/**
59
* Singleton instance of ActionEventWrapper_.
60
* @type {goog.events.ActionEventWrapper_}
61
*/
62
goog.events.actionEventWrapper = new goog.events.ActionEventWrapper_();
63
64
65
/**
66
* Event types used by the wrapper.
67
*
68
* @type {Array<goog.events.EventType>}
69
* @private
70
*/
71
goog.events.ActionEventWrapper_.EVENT_TYPES_ = [
72
goog.events.EventType.CLICK,
73
goog.userAgent.GECKO ? goog.events.EventType.KEYPRESS :
74
goog.events.EventType.KEYDOWN,
75
goog.events.EventType.KEYUP
76
];
77
78
79
/**
80
* Adds an event listener using the wrapper on a DOM Node or an object that has
81
* implemented {@link goog.events.EventTarget}. A listener can only be added
82
* once to an object.
83
*
84
* @param {goog.events.ListenableType} target The target to listen to events on.
85
* @param {function(?):?|{handleEvent:function(?):?}|null} listener Callback
86
* method, or an object with a handleEvent function.
87
* @param {boolean=} opt_capt Whether to fire in capture phase (defaults to
88
* false).
89
* @param {Object=} opt_scope Element in whose scope to call the listener.
90
* @param {goog.events.EventHandler=} opt_eventHandler Event handler to add
91
* listener to.
92
* @override
93
*/
94
goog.events.ActionEventWrapper_.prototype.listen = function(
95
target, listener, opt_capt, opt_scope, opt_eventHandler) {
96
var callback = function(e) {
97
var listenerFn = goog.events.wrapListener(listener);
98
var role = goog.dom.isElement(e.target) ?
99
goog.a11y.aria.getRole(/** @type {!Element} */ (e.target)) :
100
null;
101
if (e.type == goog.events.EventType.CLICK && e.isMouseActionButton()) {
102
listenerFn.call(opt_scope, e);
103
} else if (
104
(e.keyCode == goog.events.KeyCodes.ENTER ||
105
e.keyCode == goog.events.KeyCodes.MAC_ENTER) &&
106
e.type != goog.events.EventType.KEYUP) {
107
// convert keydown to keypress for backward compatibility.
108
e.type = goog.events.EventType.KEYPRESS;
109
listenerFn.call(opt_scope, e);
110
} else if (
111
e.keyCode == goog.events.KeyCodes.SPACE &&
112
e.type == goog.events.EventType.KEYUP &&
113
(role == goog.a11y.aria.Role.BUTTON ||
114
role == goog.a11y.aria.Role.TAB)) {
115
listenerFn.call(opt_scope, e);
116
e.preventDefault();
117
}
118
};
119
callback.listener_ = listener;
120
callback.scope_ = opt_scope;
121
122
if (opt_eventHandler) {
123
opt_eventHandler.listen(
124
target, goog.events.ActionEventWrapper_.EVENT_TYPES_, callback,
125
opt_capt);
126
} else {
127
goog.events.listen(
128
target, goog.events.ActionEventWrapper_.EVENT_TYPES_, callback,
129
opt_capt);
130
}
131
};
132
133
134
/**
135
* Removes an event listener added using goog.events.EventWrapper.listen.
136
*
137
* @param {goog.events.ListenableType} target The node to remove listener from.
138
* @param {function(?):?|{handleEvent:function(?):?}|null} listener Callback
139
* method, or an object with a handleEvent function.
140
* @param {boolean=} opt_capt Whether to fire in capture phase (defaults to
141
* false).
142
* @param {Object=} opt_scope Element in whose scope to call the listener.
143
* @param {goog.events.EventHandler=} opt_eventHandler Event handler to remove
144
* listener from.
145
* @override
146
*/
147
goog.events.ActionEventWrapper_.prototype.unlisten = function(
148
target, listener, opt_capt, opt_scope, opt_eventHandler) {
149
for (var type, j = 0; type = goog.events.ActionEventWrapper_.EVENT_TYPES_[j];
150
j++) {
151
var listeners = goog.events.getListeners(target, type, !!opt_capt);
152
for (var obj, i = 0; obj = listeners[i]; i++) {
153
var objListener =
154
/** @type {!goog.events.ActionEventWrapper_.FunctionExtension_} */ (
155
obj.listener);
156
if (objListener.listener_ == listener &&
157
objListener.scope_ == opt_scope) {
158
if (opt_eventHandler) {
159
opt_eventHandler.unlisten(
160
target, type, obj.listener, opt_capt, opt_scope);
161
} else {
162
goog.events.unlisten(target, type, obj.listener, opt_capt, opt_scope);
163
}
164
break;
165
}
166
}
167
}
168
};
169
170