]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * Just as {@link Ext.dom.Element} wraps around a native DOM node, {@link Ext.event.Event} wraps the browser's native\r | |
3 | * event-object normalizing cross-browser differences such as mechanisms to stop event-propagation along with a method\r | |
4 | * to prevent default actions from taking place.\r | |
5 | *\r | |
6 | * Here is a simple example of how you use it:\r | |
7 | *\r | |
8 | * @example preview\r | |
9 | * var container = Ext.create('Ext.Container', {\r | |
10 | * layout: 'fit',\r | |
11 | * renderTo: Ext.getBody(),\r | |
12 | * items: [{\r | |
13 | * id: 'logger',\r | |
14 | * styleHtmlContent: true,\r | |
15 | * html: 'Click somewhere!',\r | |
16 | * padding: 5\r | |
17 | * }]\r | |
18 | * });\r | |
19 | *\r | |
20 | * container.getEl().on({\r | |
21 | * click: function(e, node) {\r | |
22 | * var string = '';\r | |
23 | *\r | |
24 | * string += 'You clicked at: <strong>{ x: ' + e.pageX + ', y: ' + e.pageY + ' }</strong> <i>(e.pageX & e.pageY)</i>';\r | |
25 | * string += '<hr />';\r | |
26 | * string += 'The HTMLElement you clicked has the className of: <strong>' + e.target.className + '</strong> <i>(e.target)</i>';\r | |
27 | * string += '<hr />';\r | |
28 | * string += 'The HTMLElement which has the listener has a className of: <strong>' + e.currentTarget.className + '</strong> <i>(e.currentTarget)</i>';\r | |
29 | *\r | |
30 | * Ext.getCmp('logger').setHtml(string);\r | |
31 | * }\r | |
32 | * });\r | |
33 | *\r | |
34 | * ## Recognizers\r | |
35 | *\r | |
36 | * Ext JS includes many default event recognizers to know when a user interacts with the application.\r | |
37 | *\r | |
38 | * For a full list of default recognizers, and more information, please view the {@link Ext.event.gesture.Recognizer} documentation.\r | |
39 | * \r | |
40 | * This class also provides a set of constants for use with key events. These are useful\r | |
41 | * for determining if a specific key was pressed, and are available both on instances,\r | |
42 | * and as static properties of the class. The following two statements are equivalent:\r | |
43 | * \r | |
44 | * if (e.getKey() === Ext.event.Event.TAB) {\r | |
45 | * // tab key was pressed\r | |
46 | * }\r | |
47 | * \r | |
48 | * if (e.getKey() === e.TAB) {\r | |
49 | * // tab key was pressed\r | |
50 | * }\r | |
51 | */\r | |
52 | Ext.define('Ext.event.Event', {\r | |
53 | alternateClassName: 'Ext.EventObjectImpl',\r | |
54 | \r | |
55 | requires: [\r | |
56 | 'Ext.util.Point'\r | |
57 | ],\r | |
58 | \r | |
59 | /**\r | |
60 | * @property {Number} distance\r | |
61 | * The distance of the event.\r | |
62 | *\r | |
63 | * **This is only available when the event type is `swipe` and `pinch`.**\r | |
64 | */\r | |
65 | \r | |
66 | /**\r | |
67 | * @property {HTMLElement} target\r | |
68 | * The element that fired this event. For the element whose handlers are currently\r | |
69 | * being processed, i.e. the element that the event handler was attached to, use\r | |
70 | * `currentTarget`\r | |
71 | */\r | |
72 | \r | |
73 | /**\r | |
74 | * @property {HTMLElement} currentTarget\r | |
75 | * Refers to the element the event handler was attached to, vs the `target`, which is\r | |
76 | * the actual element that fired the event. For example, if the event bubbles, the\r | |
77 | * `target` element may be a descendant of the `currentTarget`, as the event may\r | |
78 | * have been triggered on the `target` and then bubbled up to the `currentTarget`\r | |
79 | * where it was handled.\r | |
80 | */\r | |
81 | \r | |
82 | /**\r | |
83 | * @property {HTMLElement} delegatedTarget\r | |
84 | * Same as `currentTarget`\r | |
85 | * @deprecated 5.0.0 use {@link #currentTarget} instead.\r | |
86 | */\r | |
87 | \r | |
88 | /**\r | |
89 | * @property {Number} button\r | |
90 | * Indicates which mouse button caused the event for mouse events, for example\r | |
91 | * `mousedown`, `click`, `mouseup`:\r | |
92 | * - `0` for left button.\r | |
93 | * - `1` for middle button.\r | |
94 | * - `2` for right button.\r | |
95 | *\r | |
96 | * *Note*: In IE8 & IE9, the `click` event does not provide the button.\r | |
97 | */\r | |
98 | \r | |
99 | /**\r | |
100 | * @property {Number} pageX The browsers x coordinate of the event.\r | |
101 | * Note: this only works in browsers that support pageX on the native browser event\r | |
102 | * object (pageX is not natively supported in IE9 and earlier). In Ext JS, for a\r | |
103 | * cross browser normalized x-coordinate use {@link #getX}\r | |
104 | */\r | |
105 | \r | |
106 | /**\r | |
107 | * @property {Number} pageY The browsers y coordinate of the event.\r | |
108 | * Note: this only works in browsers that support pageY on the native browser event\r | |
109 | * object (pageY is not natively supported in IE9 and earlier). In Ext JS, for a\r | |
110 | * cross browser normalized y-coordinate use {@link #getY}\r | |
111 | */\r | |
112 | \r | |
113 | /**\r | |
114 | * @property {Boolean} ctrlKey\r | |
115 | * True if the control key was down during the event.\r | |
116 | * In Mac this will also be true when meta key was down.\r | |
117 | */\r | |
118 | /**\r | |
119 | * @property {Boolean} altKey\r | |
120 | * True if the alt key was down during the event.\r | |
121 | */\r | |
122 | /**\r | |
123 | * @property {Boolean} shiftKey\r | |
124 | * True if the shift key was down during the event.\r | |
125 | */\r | |
126 | \r | |
127 | /**\r | |
128 | * @property {Event} browserEvent\r | |
129 | * The raw browser event which this object wraps.\r | |
130 | */\r | |
131 | \r | |
132 | isStopped: false,\r | |
133 | \r | |
134 | /**\r | |
135 | * @property {Boolean}\r | |
136 | * Indicates whether or not {@link #preventDefault preventDefault()} was called on the event.\r | |
137 | */\r | |
138 | defaultPrevented: false,\r | |
139 | \r | |
140 | isEvent: true,\r | |
141 | \r | |
142 | statics: {\r | |
143 | resolveTextNode: function(node) {\r | |
144 | return (node && node.nodeType === 3) ? node.parentNode : node;\r | |
145 | },\r | |
146 | \r | |
147 | /**\r | |
148 | * @private\r | |
149 | */\r | |
150 | pointerEvents: {\r | |
151 | pointerdown: 1,\r | |
152 | pointermove: 1,\r | |
153 | pointerup: 1,\r | |
154 | pointercancel: 1,\r | |
155 | pointerover: 1,\r | |
156 | pointerout: 1,\r | |
157 | pointerenter: 1,\r | |
158 | pointerleave: 1,\r | |
159 | MSPointerDown: 1,\r | |
160 | MSPointerMove: 1,\r | |
161 | MSPointerUp: 1,\r | |
162 | MSPointerOver: 1,\r | |
163 | MSPointerOut: 1,\r | |
164 | MSPointerCancel: 1,\r | |
165 | MSPointerEnter: 1,\r | |
166 | MSPointerLeave: 1\r | |
167 | },\r | |
168 | \r | |
169 | /**\r | |
170 | * @private\r | |
171 | */\r | |
172 | mouseEvents: {\r | |
173 | mousedown: 1,\r | |
174 | mousemove: 1,\r | |
175 | mouseup: 1,\r | |
176 | mouseover: 1,\r | |
177 | mouseout: 1,\r | |
178 | mouseenter: 1,\r | |
179 | mouseleave: 1\r | |
180 | },\r | |
181 | \r | |
182 | /**\r | |
183 | * @private\r | |
184 | * These are tracked separately from mouseEvents because the mouseEvents map\r | |
185 | * is used by Dom publisher to eliminate duplicate events on devices that fire\r | |
186 | * multiple kinds of events (mouse, touch, pointer). Adding click events to the\r | |
187 | * mouse events map can cause click events to be blocked from firing in some cases.\r | |
188 | */\r | |
189 | clickEvents: {\r | |
190 | click: 1,\r | |
191 | dblclick: 1\r | |
192 | },\r | |
193 | \r | |
194 | /**\r | |
195 | * @private\r | |
196 | */\r | |
197 | touchEvents: {\r | |
198 | touchstart: 1,\r | |
199 | touchmove: 1,\r | |
200 | touchend: 1,\r | |
201 | touchcancel: 1\r | |
202 | },\r | |
203 | \r | |
204 | /**\r | |
205 | * @private\r | |
206 | */\r | |
207 | focusEvents: {\r | |
208 | focus: 1,\r | |
209 | blur: 1,\r | |
210 | focusin: 1,\r | |
211 | focusout: 1,\r | |
212 | focusenter: 1,\r | |
213 | focusleave: 1\r | |
214 | },\r | |
215 | \r | |
216 | // msPointerTypes in IE10 are numbers, in the w3c spec they are strings.\r | |
217 | // this map allows us to normalize the pointerType for an event\r | |
218 | // http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\r | |
219 | // http://msdn.microsoft.com/en-us/library/ie/hh772359(v=vs.85).aspx\r | |
220 | pointerTypes: {\r | |
221 | 2: 'touch',\r | |
222 | 3: 'pen',\r | |
223 | 4: 'mouse',\r | |
224 | touch: 'touch',\r | |
225 | pen: 'pen',\r | |
226 | mouse: 'mouse'\r | |
227 | }\r | |
228 | },\r | |
229 | \r | |
230 | constructor: function(event) {\r | |
231 | var me = this,\r | |
232 | self = me.self,\r | |
233 | resolveTextNode = me.self.resolveTextNode,\r | |
234 | changedTouches = event.changedTouches,\r | |
235 | // The target object from which to obtain the coordinates (pageX, pageY). For\r | |
236 | // mouse and pointer events this is simply the event object itself, but touch\r | |
237 | // events have their coordinates on the "Touch" object(s) instead.\r | |
238 | coordinateOwner = changedTouches ? changedTouches[0] : event,\r | |
239 | type = event.type,\r | |
240 | pointerType, relatedTarget;\r | |
241 | \r | |
242 | me.pageX = coordinateOwner.pageX;\r | |
243 | me.pageY = coordinateOwner.pageY;\r | |
244 | \r | |
245 | me.target = me.delegatedTarget = resolveTextNode(event.target);\r | |
246 | relatedTarget = event.relatedTarget;\r | |
247 | if (relatedTarget) {\r | |
248 | me.relatedTarget = resolveTextNode(relatedTarget);\r | |
249 | }\r | |
250 | \r | |
251 | me.browserEvent = me.event = event;\r | |
252 | me.type = type;\r | |
253 | // set button to 0 if undefined so that touchstart, touchend, and tap will quack\r | |
254 | // like left mouse button mousedown mouseup, and click\r | |
255 | me.button = event.button || 0;\r | |
256 | me.shiftKey = event.shiftKey;\r | |
257 | // mac metaKey behaves like ctrlKey\r | |
258 | me.ctrlKey = event.ctrlKey || event.metaKey || false;\r | |
259 | me.altKey = event.altKey;\r | |
260 | me.charCode = event.charCode;\r | |
261 | me.keyCode = event.keyCode;\r | |
262 | \r | |
263 | me.buttons = event.buttons;\r | |
264 | // When invoking synthetic events, current APIs do not\r | |
265 | // have the ability to specify the buttons config, which\r | |
266 | // defaults to button. For buttons, 0 means no button\r | |
267 | // is pressed, whereas for button, 0 means left click.\r | |
268 | // Normalize that here\r | |
269 | if (me.button === 0 && me.buttons === 0) {\r | |
270 | me.buttons = 1;\r | |
271 | }\r | |
272 | \r | |
273 | if (self.forwardTab !== undefined && self.focusEvents[type]) {\r | |
274 | me.forwardTab = self.forwardTab;\r | |
275 | }\r | |
276 | \r | |
277 | if (self.mouseEvents[type] || self.clickEvents[type]) {\r | |
278 | pointerType = 'mouse';\r | |
279 | } else if (self.pointerEvents[type]) {\r | |
280 | pointerType = self.pointerTypes[event.pointerType];\r | |
281 | } else if (self.touchEvents[type]) {\r | |
282 | pointerType = 'touch';\r | |
283 | }\r | |
284 | \r | |
285 | if (pointerType) {\r | |
286 | me.pointerType = pointerType;\r | |
287 | }\r | |
288 | \r | |
289 | me.timeStamp = me.time = +(event.timeStamp || new Date());\r | |
290 | },\r | |
291 | \r | |
292 | /**\r | |
293 | * Creates a new Event object that is prototype-chained to this event. Useful for\r | |
294 | * creating identical events so that certain properties can be changed without\r | |
295 | * affecting the original event. For example, translated events have their "type"\r | |
296 | * corrected in this manner.\r | |
297 | * @param {Object} props properties to set on the chained event\r | |
298 | * @private\r | |
299 | */\r | |
300 | chain: function(props) {\r | |
301 | var e = Ext.Object.chain(this);\r | |
302 | e.parentEvent = this; // needed for stopPropagation\r | |
303 | return Ext.apply(e, props);\r | |
304 | },\r | |
305 | \r | |
306 | /**\r | |
307 | * Correctly scales a given wheel delta.\r | |
308 | * @param {Number} delta The delta value.\r | |
309 | * @private\r | |
310 | */\r | |
311 | correctWheelDelta: function (delta) {\r | |
312 | var scale = this.WHEEL_SCALE,\r | |
313 | ret = Math.round(delta / scale);\r | |
314 | \r | |
315 | if (!ret && delta) {\r | |
316 | ret = (delta < 0) ? -1 : 1; // don't allow non-zero deltas to go to zero!\r | |
317 | }\r | |
318 | \r | |
319 | return ret;\r | |
320 | },\r | |
321 | \r | |
322 | /**\r | |
323 | * Gets the character code for the event.\r | |
324 | * @return {Number}\r | |
325 | */\r | |
326 | getCharCode: function(){\r | |
327 | return this.charCode || this.keyCode;\r | |
328 | },\r | |
329 | \r | |
330 | /**\r | |
331 | * Returns a normalized keyCode for the event.\r | |
332 | * @return {Number} The key code\r | |
333 | */\r | |
334 | getKey: function(){\r | |
335 | return this.keyCode || this.charCode;\r | |
336 | },\r | |
337 | \r | |
338 | /**\r | |
339 | * Returns the name of the keyCode for the event.\r | |
340 | * @return {String} The key name\r | |
341 | */\r | |
342 | getKeyName: function() {\r | |
343 | return this.keyCodes[this.keyCode];\r | |
344 | },\r | |
345 | \r | |
346 | /**\r | |
347 | * Returns a point object that consists of the object coordinates.\r | |
348 | * @return {Ext.util.Point} point\r | |
349 | */\r | |
350 | getPoint: function(){\r | |
351 | var xy = this.getXY();\r | |
352 | return new Ext.util.Point(xy[0], xy[1]);\r | |
353 | },\r | |
354 | \r | |
355 | /**\r | |
356 | * Gets the related target.\r | |
357 | * @param {String} [selector] A simple selector to filter the target or look for an\r | |
358 | * ancestor of the target. See {@link Ext.dom.Query} for information about simple\r | |
359 | * selectors.\r | |
360 | * @param {Number/HTMLElement} [maxDepth] The max depth to search as a number or\r | |
361 | * element (defaults to 10 || document.body).\r | |
362 | * @param {Boolean} [returnEl] `true` to return a Ext.Element object instead of DOM\r | |
363 | * node.\r | |
364 | * @return {HTMLElement}\r | |
365 | */\r | |
366 | getRelatedTarget: function(selector, maxDepth, returnEl){\r | |
367 | var relatedTarget = this.relatedTarget,\r | |
368 | target = null;\r | |
369 | \r | |
370 | if (relatedTarget) {\r | |
371 | if (selector) {\r | |
372 | target = Ext.fly(relatedTarget).findParent(selector, maxDepth, returnEl);\r | |
373 | } else {\r | |
374 | target = returnEl ? Ext.get(relatedTarget) : relatedTarget;\r | |
375 | }\r | |
376 | }\r | |
377 | return target;\r | |
378 | },\r | |
379 | \r | |
380 | /**\r | |
381 | * Gets the target for the event.\r | |
382 | * @param {String} selector (optional) A simple selector to filter the target or look\r | |
383 | * for an ancestor of the target\r | |
384 | * @param {Number/Mixed} [maxDepth=10||document.body] (optional) The max depth to\r | |
385 | * search as a number or element (defaults to 10 || document.body)\r | |
386 | * @param {Boolean} returnEl (optional) `true` to return a Ext.Element object instead\r | |
387 | * of DOM node.\r | |
388 | * @return {HTMLElement}\r | |
389 | */\r | |
390 | getTarget: function(selector, maxDepth, returnEl) {\r | |
391 | return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) :\r | |
392 | (returnEl ? Ext.get(this.target) : this.target);\r | |
393 | },\r | |
394 | \r | |
395 | /**\r | |
396 | * Returns the time of the event.\r | |
397 | * @return {Date}\r | |
398 | */\r | |
399 | getTime: function() {\r | |
400 | return this.time;\r | |
401 | },\r | |
402 | \r | |
403 | /**\r | |
404 | * Normalizes mouse wheel y-delta across browsers. To get x-delta information, use\r | |
405 | * {@link #getWheelDeltas} instead.\r | |
406 | * @return {Number} The mouse wheel y-delta\r | |
407 | */\r | |
408 | getWheelDelta: function(){\r | |
409 | var deltas = this.getWheelDeltas();\r | |
410 | \r | |
411 | return deltas.y;\r | |
412 | },\r | |
413 | \r | |
414 | /**\r | |
415 | * Returns the mouse wheel deltas for this event.\r | |
416 | * @return {Object} An object with "x" and "y" properties holding the mouse wheel deltas.\r | |
417 | */\r | |
418 | getWheelDeltas: function () {\r | |
419 | var me = this,\r | |
420 | event = me.browserEvent,\r | |
421 | dx = 0, dy = 0; // the deltas\r | |
422 | \r | |
423 | if (Ext.isDefined(event.wheelDeltaX)) { // WebKit has both dimensions\r | |
424 | dx = event.wheelDeltaX;\r | |
425 | dy = event.wheelDeltaY;\r | |
426 | } else if (event.wheelDelta) { // old WebKit and IE\r | |
427 | dy = event.wheelDelta;\r | |
428 | } else if (event.detail) { // Gecko\r | |
429 | dy = -event.detail; // gecko is backwards\r | |
430 | \r | |
431 | // Gecko sometimes returns really big values if the user changes settings to\r | |
432 | // scroll a whole page per scroll\r | |
433 | if (dy > 100) {\r | |
434 | dy = 3;\r | |
435 | } else if (dy < -100) {\r | |
436 | dy = -3;\r | |
437 | }\r | |
438 | \r | |
439 | // Firefox 3.1 adds an axis field to the event to indicate direction of\r | |
440 | // scroll. See https://developer.mozilla.org/en/Gecko-Specific_DOM_Events\r | |
441 | if (Ext.isDefined(event.axis) && event.axis === event.HORIZONTAL_AXIS) {\r | |
442 | dx = dy;\r | |
443 | dy = 0;\r | |
444 | }\r | |
445 | }\r | |
446 | \r | |
447 | return {\r | |
448 | x: me.correctWheelDelta(dx),\r | |
449 | y: me.correctWheelDelta(dy)\r | |
450 | };\r | |
451 | },\r | |
452 | \r | |
453 | /**\r | |
454 | * Gets the x coordinate of the event.\r | |
455 | * @return {Number}\r | |
456 | */\r | |
457 | getX: function() {\r | |
458 | return this.getXY()[0];\r | |
459 | },\r | |
460 | \r | |
461 | /**\r | |
462 | * Gets the X and Y coordinates of the event.\r | |
463 | * @return {Number[]} The xy values like [x, y]\r | |
464 | */\r | |
465 | getXY: function() {\r | |
466 | var me = this,\r | |
467 | xy = me.xy;\r | |
468 | \r | |
469 | if (!xy) {\r | |
470 | xy = me.xy = [me.pageX, me.pageY];\r | |
471 | //<feature legacyBrowser>\r | |
472 | var x = xy[0],\r | |
473 | browserEvent, doc, docEl, body;\r | |
474 | \r | |
475 | // pageX/pageY not available (undefined, not null), use clientX/clientY instead\r | |
476 | if (!x && x !== 0) {\r | |
477 | browserEvent = me.browserEvent;\r | |
478 | doc = document;\r | |
479 | docEl = doc.documentElement;\r | |
480 | body = doc.body;\r | |
481 | xy[0] = browserEvent.clientX +\r | |
482 | (docEl && docEl.scrollLeft || body && body.scrollLeft || 0) -\r | |
483 | (docEl && docEl.clientLeft || body && body.clientLeft || 0);\r | |
484 | xy[1] = browserEvent.clientY +\r | |
485 | (docEl && docEl.scrollTop || body && body.scrollTop || 0) -\r | |
486 | (docEl && docEl.clientTop || body && body.clientTop || 0);\r | |
487 | }\r | |
488 | //</feature>\r | |
489 | }\r | |
490 | \r | |
491 | return xy;\r | |
492 | },\r | |
493 | \r | |
494 | /**\r | |
495 | * Gets the y coordinate of the event.\r | |
496 | * @return {Number}\r | |
497 | */\r | |
498 | getY: function() {\r | |
499 | return this.getXY()[1];\r | |
500 | },\r | |
501 | \r | |
502 | /**\r | |
503 | * Returns true if the control, meta, shift or alt key was pressed during this event.\r | |
504 | * @return {Boolean}\r | |
505 | */\r | |
506 | hasModifier: function() {\r | |
507 | var me = this;\r | |
508 | return !!(me.ctrlKey || me.altKey || me.shiftKey || me.metaKey);\r | |
509 | },\r | |
510 | \r | |
511 | /**\r | |
512 | * Checks if the key pressed was a "navigation" key. A navigation key is defined by\r | |
513 | * these keys:\r | |
514 | *\r | |
515 | * - Page Up\r | |
516 | * - Page Down\r | |
517 | * - End\r | |
518 | * - Home\r | |
519 | * - Left\r | |
520 | * - Up\r | |
521 | * - Right\r | |
522 | * - Down\r | |
523 | * - Return\r | |
524 | * - Tab\r | |
525 | * - Esc\r | |
526 | *\r | |
527 | * @param {Boolean} [scrollableOnly] Only check navigation keys that can cause\r | |
528 | * element scrolling by their default action.\r | |
529 | *\r | |
530 | * @return {Boolean} `true` if the press is a navigation keypress\r | |
531 | */\r | |
532 | isNavKeyPress: function(scrollableOnly) {\r | |
533 | var me = this,\r | |
534 | k = me.keyCode,\r | |
535 | isKeyPress = me.type === 'keypress';\r | |
536 | \r | |
537 | // See specs for description of behaviour\r | |
538 | return ((!isKeyPress || Ext.isGecko) && k >= 33 && k <= 40) || // Page Up/Down, End, Home, Left, Up, Right, Down\r | |
539 | (!scrollableOnly &&\r | |
540 | (k === me.RETURN ||\r | |
541 | k === me.TAB ||\r | |
542 | k === me.ESC));\r | |
543 | },\r | |
544 | \r | |
545 | /**\r | |
546 | * Checks if the key pressed was a "special" key. A special key is defined as one of\r | |
547 | * these keys:\r | |
548 | *\r | |
549 | * - Page Up\r | |
550 | * - Page Down\r | |
551 | * - End\r | |
552 | * - Home\r | |
553 | * - Left arrow\r | |
554 | * - Up arrow\r | |
555 | * - Right arrow\r | |
556 | * - Down arrow\r | |
557 | * - Return\r | |
558 | * - Tab\r | |
559 | * - Esc\r | |
560 | * - Backspace\r | |
561 | * - Delete\r | |
562 | * - Shift\r | |
563 | * - Ctrl\r | |
564 | * - Alt\r | |
565 | * - Pause\r | |
566 | * - Caps Lock\r | |
567 | * - Print Screen\r | |
568 | * - Insert\r | |
569 | *\r | |
570 | * @return {Boolean} `true` if the key for this event is special\r | |
571 | */\r | |
572 | isSpecialKey: function() {\r | |
573 | var me = this,\r | |
574 | k = me.keyCode,\r | |
575 | isGecko = Ext.isGecko,\r | |
576 | isKeyPress = me.type === 'keypress';\r | |
577 | \r | |
578 | // See specs for description of behaviour\r | |
579 | return (isGecko && isKeyPress && me.charCode === 0) ||\r | |
580 | (this.isNavKeyPress()) ||\r | |
581 | (k === me.BACKSPACE) ||\r | |
582 | (k === me.ENTER) ||\r | |
583 | (k >= 16 && k <= 20) || // Shift, Ctrl, Alt, Pause, Caps Lock\r | |
584 | ((!isKeyPress || isGecko) && k >= 44 && k <= 46); // Print Screen, Insert, Delete\r | |
585 | },\r | |
586 | \r | |
587 | makeUnpreventable: function() {\r | |
588 | this.browserEvent.preventDefault = Ext.emptyFn;\r | |
589 | },\r | |
590 | \r | |
591 | /**\r | |
592 | * Prevents the browsers default handling of the event.\r | |
593 | * @chainable\r | |
594 | */\r | |
595 | preventDefault: function() {\r | |
596 | var me = this,\r | |
597 | parentEvent = me.parentEvent;\r | |
598 | \r | |
599 | me.defaultPrevented = true;\r | |
600 | \r | |
601 | // if the event was created by prototype-chaining a new object to an existing event\r | |
602 | // instance, we need to make sure the parent event is defaultPrevented as well.\r | |
603 | if (parentEvent) {\r | |
604 | parentEvent.defaultPrevented = true;\r | |
605 | }\r | |
606 | \r | |
607 | me.browserEvent.preventDefault();\r | |
608 | \r | |
609 | return me;\r | |
610 | },\r | |
611 | \r | |
612 | setCurrentTarget: function(target) {\r | |
613 | this.currentTarget = this.delegatedTarget = target;\r | |
614 | },\r | |
615 | \r | |
616 | /**\r | |
617 | * Stop the event (`{@link #preventDefault}` and `{@link #stopPropagation}`).\r | |
618 | * @chainable\r | |
619 | */\r | |
620 | stopEvent: function() {\r | |
621 | return this.preventDefault().stopPropagation();\r | |
622 | },\r | |
623 | \r | |
624 | /**\r | |
625 | * Cancels bubbling of the event.\r | |
626 | * @chainable\r | |
627 | */\r | |
628 | stopPropagation: function() {\r | |
629 | var me = this,\r | |
630 | browserEvent = me.browserEvent,\r | |
631 | parentEvent = me.parentEvent;\r | |
632 | \r | |
633 | // Set isStopped for delegated event listeners. Dom publisher will check this\r | |
634 | // property during its emulated propagation phase (see doPublish)\r | |
635 | me.isStopped = true;\r | |
636 | \r | |
637 | // if the event was created by prototype-chaining a new object to an existing event\r | |
638 | // instance, we need to make sure the parent event is stopped. This feature most\r | |
639 | // likely comes into play when dealing with event translation. For example on touch\r | |
640 | // browsers addListener('mousedown') actually attaches a 'touchstart' listener behind\r | |
641 | // the scenes. When the 'touchstart' event is dispatched, the event system will\r | |
642 | // create a "chained" copy of the event object before correcting its type back to\r | |
643 | // 'mousedown' and calling the handler. When propagating the event we look at the\r | |
644 | // original event, not the chained one to determine if propagation should continue,\r | |
645 | // so the isStopped property must be set on the parentEvent or stopPropagation\r | |
646 | // will not work.\r | |
647 | if (parentEvent) {\r | |
648 | parentEvent.isStopped = true;\r | |
649 | }\r | |
650 | \r | |
651 | //<feature legacyBrowser>\r | |
652 | if (!browserEvent.stopPropagation) {\r | |
653 | // IE < 10 does not have stopPropagation()\r | |
654 | browserEvent.cancelBubble = true;\r | |
655 | return me;\r | |
656 | }\r | |
657 | //</feature>\r | |
658 | \r | |
659 | // For non-delegated event listeners (those that are directly attached to the\r | |
660 | // DOM element) we need to call the browserEvent's stopPropagation() method.\r | |
661 | browserEvent.stopPropagation();\r | |
662 | \r | |
663 | return me;\r | |
664 | },\r | |
665 | \r | |
666 | /**\r | |
667 | * Returns true if the target of this event is a child of `el`. Unless the allowEl\r | |
668 | * parameter is set, it will return false if if the target is `el`.\r | |
669 | * Example usage:\r | |
670 | * \r | |
671 | * // Handle click on any child of an element\r | |
672 | * Ext.getBody().on('click', function(e){\r | |
673 | * if(e.within('some-el')){\r | |
674 | * alert('Clicked on a child of some-el!');\r | |
675 | * }\r | |
676 | * });\r | |
677 | * \r | |
678 | * // Handle click directly on an element, ignoring clicks on child nodes\r | |
679 | * Ext.getBody().on('click', function(e,t){\r | |
680 | * if((t.id == 'some-el') && !e.within(t, true)){\r | |
681 | * alert('Clicked directly on some-el!');\r | |
682 | * }\r | |
683 | * });\r | |
684 | * \r | |
685 | * @param {String/HTMLElement/Ext.dom.Element} el The id, DOM element or Ext.Element to check\r | |
686 | * @param {Boolean} [related] `true` to test if the related target is within el instead\r | |
687 | * of the target\r | |
688 | * @param {Boolean} [allowEl] `true` to also check if the passed element is the target\r | |
689 | * or related target\r | |
690 | * @return {Boolean}\r | |
691 | */\r | |
692 | within: function(el, related, allowEl){\r | |
693 | var t;\r | |
694 | if (el) {\r | |
695 | t = related ? this.getRelatedTarget() : this.getTarget();\r | |
696 | }\r | |
697 | \r | |
698 | return t ? Ext.fly(el).contains(t) || !!(allowEl && t === Ext.getDom(el)) : false;\r | |
699 | },\r | |
700 | \r | |
701 | deprecated: {\r | |
702 | '4.0': {\r | |
703 | methods: {\r | |
704 | \r | |
705 | /**\r | |
706 | * Gets the x coordinate of the event.\r | |
707 | * @return {Number}\r | |
708 | * @deprecated 4.0 use {@link #getX} instead\r | |
709 | */\r | |
710 | getPageX: 'getX',\r | |
711 | \r | |
712 | /**\r | |
713 | * Gets the y coordinate of the event.\r | |
714 | * @return {Number}\r | |
715 | * @deprecated 4.0 use {@link #getY} instead\r | |
716 | */\r | |
717 | getPageY: 'getY'\r | |
718 | }\r | |
719 | }\r | |
720 | }\r | |
721 | }, function(Event) {\r | |
722 | var prototype = Event.prototype,\r | |
723 | constants = {\r | |
724 | /** Key constant @type Number */\r | |
725 | BACKSPACE: 8,\r | |
726 | /** Key constant @type Number */\r | |
727 | TAB: 9,\r | |
728 | /** Key constant @type Number */\r | |
729 | NUM_CENTER: 12,\r | |
730 | /** Key constant @type Number */\r | |
731 | ENTER: 13,\r | |
732 | /** Key constant @type Number */\r | |
733 | RETURN: 13,\r | |
734 | /** Key constant @type Number */\r | |
735 | SHIFT: 16,\r | |
736 | /** Key constant @type Number */\r | |
737 | CTRL: 17,\r | |
738 | /** Key constant @type Number */\r | |
739 | ALT: 18,\r | |
740 | /** Key constant @type Number */\r | |
741 | PAUSE: 19,\r | |
742 | /** Key constant @type Number */\r | |
743 | CAPS_LOCK: 20,\r | |
744 | /** Key constant @type Number */\r | |
745 | ESC: 27,\r | |
746 | /** Key constant @type Number */\r | |
747 | SPACE: 32,\r | |
748 | /** Key constant @type Number */\r | |
749 | PAGE_UP: 33,\r | |
750 | /** Key constant @type Number */\r | |
751 | PAGE_DOWN: 34,\r | |
752 | /** Key constant @type Number */\r | |
753 | END: 35,\r | |
754 | /** Key constant @type Number */\r | |
755 | HOME: 36,\r | |
756 | /** Key constant @type Number */\r | |
757 | LEFT: 37,\r | |
758 | /** Key constant @type Number */\r | |
759 | UP: 38,\r | |
760 | /** Key constant @type Number */\r | |
761 | RIGHT: 39,\r | |
762 | /** Key constant @type Number */\r | |
763 | DOWN: 40,\r | |
764 | /** Key constant @type Number */\r | |
765 | PRINT_SCREEN: 44,\r | |
766 | /** Key constant @type Number */\r | |
767 | INSERT: 45,\r | |
768 | /** Key constant @type Number */\r | |
769 | DELETE: 46,\r | |
770 | /** Key constant @type Number */\r | |
771 | ZERO: 48,\r | |
772 | /** Key constant @type Number */\r | |
773 | ONE: 49,\r | |
774 | /** Key constant @type Number */\r | |
775 | TWO: 50,\r | |
776 | /** Key constant @type Number */\r | |
777 | THREE: 51,\r | |
778 | /** Key constant @type Number */\r | |
779 | FOUR: 52,\r | |
780 | /** Key constant @type Number */\r | |
781 | FIVE: 53,\r | |
782 | /** Key constant @type Number */\r | |
783 | SIX: 54,\r | |
784 | /** Key constant @type Number */\r | |
785 | SEVEN: 55,\r | |
786 | /** Key constant @type Number */\r | |
787 | EIGHT: 56,\r | |
788 | /** Key constant @type Number */\r | |
789 | NINE: 57,\r | |
790 | /** Key constant @type Number */\r | |
791 | A: 65,\r | |
792 | /** Key constant @type Number */\r | |
793 | B: 66,\r | |
794 | /** Key constant @type Number */\r | |
795 | C: 67,\r | |
796 | /** Key constant @type Number */\r | |
797 | D: 68,\r | |
798 | /** Key constant @type Number */\r | |
799 | E: 69,\r | |
800 | /** Key constant @type Number */\r | |
801 | F: 70,\r | |
802 | /** Key constant @type Number */\r | |
803 | G: 71,\r | |
804 | /** Key constant @type Number */\r | |
805 | H: 72,\r | |
806 | /** Key constant @type Number */\r | |
807 | I: 73,\r | |
808 | /** Key constant @type Number */\r | |
809 | J: 74,\r | |
810 | /** Key constant @type Number */\r | |
811 | K: 75,\r | |
812 | /** Key constant @type Number */\r | |
813 | L: 76,\r | |
814 | /** Key constant @type Number */\r | |
815 | M: 77,\r | |
816 | /** Key constant @type Number */\r | |
817 | N: 78,\r | |
818 | /** Key constant @type Number */\r | |
819 | O: 79,\r | |
820 | /** Key constant @type Number */\r | |
821 | P: 80,\r | |
822 | /** Key constant @type Number */\r | |
823 | Q: 81,\r | |
824 | /** Key constant @type Number */\r | |
825 | R: 82,\r | |
826 | /** Key constant @type Number */\r | |
827 | S: 83,\r | |
828 | /** Key constant @type Number */\r | |
829 | T: 84,\r | |
830 | /** Key constant @type Number */\r | |
831 | U: 85,\r | |
832 | /** Key constant @type Number */\r | |
833 | V: 86,\r | |
834 | /** Key constant @type Number */\r | |
835 | W: 87,\r | |
836 | /** Key constant @type Number */\r | |
837 | X: 88,\r | |
838 | /** Key constant @type Number */\r | |
839 | Y: 89,\r | |
840 | /** Key constant @type Number */\r | |
841 | Z: 90,\r | |
842 | /** Key constant @type Number */\r | |
843 | CONTEXT_MENU: 93,\r | |
844 | /** Key constant @type Number */\r | |
845 | NUM_ZERO: 96,\r | |
846 | /** Key constant @type Number */\r | |
847 | NUM_ONE: 97,\r | |
848 | /** Key constant @type Number */\r | |
849 | NUM_TWO: 98,\r | |
850 | /** Key constant @type Number */\r | |
851 | NUM_THREE: 99,\r | |
852 | /** Key constant @type Number */\r | |
853 | NUM_FOUR: 100,\r | |
854 | /** Key constant @type Number */\r | |
855 | NUM_FIVE: 101,\r | |
856 | /** Key constant @type Number */\r | |
857 | NUM_SIX: 102,\r | |
858 | /** Key constant @type Number */\r | |
859 | NUM_SEVEN: 103,\r | |
860 | /** Key constant @type Number */\r | |
861 | NUM_EIGHT: 104,\r | |
862 | /** Key constant @type Number */\r | |
863 | NUM_NINE: 105,\r | |
864 | /** Key constant @type Number */\r | |
865 | NUM_MULTIPLY: 106,\r | |
866 | /** Key constant @type Number */\r | |
867 | NUM_PLUS: 107,\r | |
868 | /** Key constant @type Number */\r | |
869 | NUM_MINUS: 109,\r | |
870 | /** Key constant @type Number */\r | |
871 | NUM_PERIOD: 110,\r | |
872 | /** Key constant @type Number */\r | |
873 | NUM_DIVISION: 111,\r | |
874 | /** Key constant @type Number */\r | |
875 | F1: 112,\r | |
876 | /** Key constant @type Number */\r | |
877 | F2: 113,\r | |
878 | /** Key constant @type Number */\r | |
879 | F3: 114,\r | |
880 | /** Key constant @type Number */\r | |
881 | F4: 115,\r | |
882 | /** Key constant @type Number */\r | |
883 | F5: 116,\r | |
884 | /** Key constant @type Number */\r | |
885 | F6: 117,\r | |
886 | /** Key constant @type Number */\r | |
887 | F7: 118,\r | |
888 | /** Key constant @type Number */\r | |
889 | F8: 119,\r | |
890 | /** Key constant @type Number */\r | |
891 | F9: 120,\r | |
892 | /** Key constant @type Number */\r | |
893 | F10: 121,\r | |
894 | /** Key constant @type Number */\r | |
895 | F11: 122,\r | |
896 | /** Key constant @type Number */\r | |
897 | F12: 123,\r | |
898 | \r | |
899 | /**\r | |
900 | * The mouse wheel delta scaling factor. This value depends on browser version and OS and\r | |
901 | * attempts to produce a similar scrolling experience across all platforms and browsers.\r | |
902 | *\r | |
903 | * To change this value:\r | |
904 | *\r | |
905 | * Ext.event.Event.prototype.WHEEL_SCALE = 72;\r | |
906 | *\r | |
907 | * @type Number\r | |
908 | * @property\r | |
909 | */\r | |
910 | WHEEL_SCALE: (function () {\r | |
911 | var scale;\r | |
912 | \r | |
913 | if (Ext.isGecko) {\r | |
914 | // Firefox uses 3 on all platforms\r | |
915 | scale = 3;\r | |
916 | } else if (Ext.isMac) {\r | |
917 | // Continuous scrolling devices have momentum and produce much more scroll than\r | |
918 | // discrete devices on the same OS and browser. To make things exciting, Safari\r | |
919 | // (and not Chrome) changed from small values to 120 (like IE).\r | |
920 | \r | |
921 | if (Ext.isSafari && Ext.webKitVersion >= 532.0) {\r | |
922 | // Safari changed the scrolling factor to match IE (for details see\r | |
923 | // https://bugs.webkit.org/show_bug.cgi?id=24368). The WebKit version where this\r | |
924 | // change was introduced was 532.0\r | |
925 | // Detailed discussion:\r | |
926 | // https://bugs.webkit.org/show_bug.cgi?id=29601\r | |
927 | // http://trac.webkit.org/browser/trunk/WebKit/chromium/src/mac/WebInputEventFactory.mm#L1063\r | |
928 | scale = 120;\r | |
929 | } else {\r | |
930 | // MS optical wheel mouse produces multiples of 12 which is close enough\r | |
931 | // to help tame the speed of the continuous mice...\r | |
932 | scale = 12;\r | |
933 | }\r | |
934 | \r | |
935 | // Momentum scrolling produces very fast scrolling, so increase the scale factor\r | |
936 | // to help produce similar results cross platform. This could be even larger and\r | |
937 | // it would help those mice, but other mice would become almost unusable as a\r | |
938 | // result (since we cannot tell which device type is in use).\r | |
939 | scale *= 3;\r | |
940 | } else {\r | |
941 | // IE, Opera and other Windows browsers use 120.\r | |
942 | scale = 120;\r | |
943 | }\r | |
944 | \r | |
945 | return scale;\r | |
946 | }())\r | |
947 | },\r | |
948 | keyCodes = {},\r | |
949 | keyName, keyCode;\r | |
950 | \r | |
951 | Ext.apply(Event, constants);\r | |
952 | Ext.apply(prototype, constants);\r | |
953 | \r | |
954 | // Don't need that\r | |
955 | delete constants.WHEEL_SCALE;\r | |
956 | \r | |
957 | // ENTER and RETURN has the same keyCode, but since RETURN\r | |
958 | // comes later it will win over ENTER down there. However\r | |
959 | // ENTER is used more often and feels more natural.\r | |
960 | delete constants.RETURN;\r | |
961 | \r | |
962 | // We need this to do reverse lookup of key name by its code\r | |
963 | for (keyName in constants) {\r | |
964 | keyCode = constants[keyName];\r | |
965 | keyCodes[keyCode] = keyName;\r | |
966 | }\r | |
967 | \r | |
968 | prototype.keyCodes = keyCodes;\r | |
969 | \r | |
970 | /**\r | |
971 | * @private\r | |
972 | * Returns the X and Y coordinates of this event without regard to any RTL\r | |
973 | * direction settings.\r | |
974 | */\r | |
975 | prototype.getTrueXY = prototype.getXY;\r | |
976 | });\r |