]> git.proxmox.com Git - extjs.git/blame - extjs/classic/classic/overrides/event/Event.js
add extjs 6.0.1 sources
[extjs.git] / extjs / classic / classic / overrides / event / Event.js
CommitLineData
6527f429
DM
1/**\r
2 *\r
3 */\r
4Ext.define('Ext.overrides.event.Event', {\r
5 override: 'Ext.event.Event',\r
6\r
7 // map of events that should fire global mousedown even if stopped\r
8 mousedownEvents: {\r
9 mousedown: 1,\r
10 pointerdown: 1,\r
11 touchstart: 1\r
12 },\r
13\r
14 /**\r
15 * @method injectEvent\r
16 * @member Ext.event.Event\r
17 * Injects a DOM event using the data in this object and (optionally) a new target.\r
18 * This is a low-level technique and not likely to be used by application code. The\r
19 * currently supported event types are:\r
20 * <p><b>HTMLEvents</b></p>\r
21 * <ul>\r
22 * <li>load</li>\r
23 * <li>unload</li>\r
24 * <li>select</li>\r
25 * <li>change</li>\r
26 * <li>submit</li>\r
27 * <li>reset</li>\r
28 * <li>resize</li>\r
29 * <li>scroll</li>\r
30 * </ul>\r
31 * <p><b>MouseEvents</b></p>\r
32 * <ul>\r
33 * <li>click</li>\r
34 * <li>dblclick</li>\r
35 * <li>mousedown</li>\r
36 * <li>mouseup</li>\r
37 * <li>mouseover</li>\r
38 * <li>mousemove</li>\r
39 * <li>mouseout</li>\r
40 * </ul>\r
41 * <p><b>UIEvents</b></p>\r
42 * <ul>\r
43 * <li>focusin</li>\r
44 * <li>focusout</li>\r
45 * <li>activate</li>\r
46 * <li>focus</li>\r
47 * <li>blur</li>\r
48 * </ul>\r
49 * @param {Ext.Element/HTMLElement} target (optional) If specified, the target for the event. This\r
50 * is likely to be used when relaying a DOM event. If not specified, {@link #getTarget}\r
51 * is used to determine the target.\r
52 */\r
53 injectEvent: (function () {\r
54 var API,\r
55 dispatchers = {}, // keyed by event type (e.g., 'mousedown')\r
56 crazyIEButtons;\r
57\r
58 // Good reference: http://developer.yahoo.com/yui/docs/UserAction.js.html\r
59\r
60 // IE9 has createEvent, but this code causes major problems with htmleditor (it\r
61 // blocks all mouse events and maybe more). TODO\r
62\r
63 if (!Ext.isIE9m && document.createEvent) { // if (DOM compliant)\r
64 API = {\r
65 createHtmlEvent: function (doc, type, bubbles, cancelable) {\r
66 var event = doc.createEvent('HTMLEvents');\r
67\r
68 event.initEvent(type, bubbles, cancelable);\r
69 return event;\r
70 },\r
71\r
72 createMouseEvent: function (doc, type, bubbles, cancelable, detail,\r
73 clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,\r
74 button, relatedTarget) {\r
75 var event = doc.createEvent('MouseEvents'),\r
76 view = doc.defaultView || window;\r
77\r
78 if (event.initMouseEvent) {\r
79 event.initMouseEvent(type, bubbles, cancelable, view, detail,\r
80 clientX, clientY, clientX, clientY, ctrlKey, altKey,\r
81 shiftKey, metaKey, button, relatedTarget);\r
82 } else { // old Safari\r
83 event = doc.createEvent('UIEvents');\r
84 event.initEvent(type, bubbles, cancelable);\r
85 event.view = view;\r
86 event.detail = detail;\r
87 event.screenX = clientX;\r
88 event.screenY = clientY;\r
89 event.clientX = clientX;\r
90 event.clientY = clientY;\r
91 event.ctrlKey = ctrlKey;\r
92 event.altKey = altKey;\r
93 event.metaKey = metaKey;\r
94 event.shiftKey = shiftKey;\r
95 event.button = button;\r
96 event.relatedTarget = relatedTarget;\r
97 }\r
98\r
99 return event;\r
100 },\r
101\r
102 createUIEvent: function (doc, type, bubbles, cancelable, detail) {\r
103 var event = doc.createEvent('UIEvents'),\r
104 view = doc.defaultView || window;\r
105\r
106 event.initUIEvent(type, bubbles, cancelable, view, detail);\r
107 return event;\r
108 },\r
109\r
110 fireEvent: function (target, type, event) {\r
111 target.dispatchEvent(event);\r
112 }\r
113 };\r
114 } else if (document.createEventObject) { // else if (IE)\r
115 crazyIEButtons = { 0: 1, 1: 4, 2: 2 };\r
116\r
117 API = {\r
118 createHtmlEvent: function (doc, type, bubbles, cancelable) {\r
119 var event = doc.createEventObject();\r
120 event.bubbles = bubbles;\r
121 event.cancelable = cancelable;\r
122 return event;\r
123 },\r
124\r
125 createMouseEvent: function (doc, type, bubbles, cancelable, detail,\r
126 clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,\r
127 button, relatedTarget) {\r
128 var event = doc.createEventObject();\r
129 event.bubbles = bubbles;\r
130 event.cancelable = cancelable;\r
131 event.detail = detail;\r
132 event.screenX = clientX;\r
133 event.screenY = clientY;\r
134 event.clientX = clientX;\r
135 event.clientY = clientY;\r
136 event.ctrlKey = ctrlKey;\r
137 event.altKey = altKey;\r
138 event.shiftKey = shiftKey;\r
139 event.metaKey = metaKey;\r
140 event.button = crazyIEButtons[button] || button;\r
141 event.relatedTarget = relatedTarget; // cannot assign to/fromElement\r
142 return event;\r
143 },\r
144\r
145 createUIEvent: function (doc, type, bubbles, cancelable, detail) {\r
146 var event = doc.createEventObject();\r
147 event.bubbles = bubbles;\r
148 event.cancelable = cancelable;\r
149 return event;\r
150 },\r
151\r
152 fireEvent: function (target, type, event) {\r
153 target.fireEvent('on' + type, event);\r
154 }\r
155 };\r
156 }\r
157\r
158 //----------------\r
159 // HTMLEvents\r
160\r
161 Ext.Object.each({\r
162 load: [false, false],\r
163 unload: [false, false],\r
164 select: [true, false],\r
165 change: [true, false],\r
166 submit: [true, true],\r
167 reset: [true, false],\r
168 resize: [true, false],\r
169 scroll: [true, false]\r
170 },\r
171 function (name, value) {\r
172 var bubbles = value[0], cancelable = value[1];\r
173 dispatchers[name] = function (targetEl, srcEvent) {\r
174 var e = API.createHtmlEvent(name, bubbles, cancelable);\r
175 API.fireEvent(targetEl, name, e);\r
176 };\r
177 });\r
178\r
179 //----------------\r
180 // MouseEvents\r
181\r
182 function createMouseEventDispatcher (type, detail) {\r
183 var cancelable = (type !== 'mousemove');\r
184 return function (targetEl, srcEvent) {\r
185 var xy = srcEvent.getXY(),\r
186 e = API.createMouseEvent(targetEl.ownerDocument, type, true, cancelable,\r
187 detail, xy[0], xy[1], srcEvent.ctrlKey, srcEvent.altKey,\r
188 srcEvent.shiftKey, srcEvent.metaKey, srcEvent.button,\r
189 srcEvent.relatedTarget);\r
190 API.fireEvent(targetEl, type, e);\r
191 };\r
192 }\r
193\r
194 Ext.each(['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mousemove', 'mouseout'],\r
195 function (eventName) {\r
196 dispatchers[eventName] = createMouseEventDispatcher(eventName, 1);\r
197 });\r
198\r
199 //----------------\r
200 // UIEvents\r
201\r
202 Ext.Object.each({\r
203 focusin: [true, false],\r
204 focusout: [true, false],\r
205 activate: [true, true],\r
206 focus: [false, false],\r
207 blur: [false, false]\r
208 },\r
209 function (name, value) {\r
210 var bubbles = value[0], cancelable = value[1];\r
211 dispatchers[name] = function (targetEl, srcEvent) {\r
212 var e = API.createUIEvent(targetEl.ownerDocument, name, bubbles, cancelable, 1);\r
213 API.fireEvent(targetEl, name, e);\r
214 };\r
215 });\r
216\r
217 //---------\r
218 if (!API) {\r
219 // not even sure what ancient browsers fall into this category...\r
220\r
221 dispatchers = {}; // never mind all those we just built :P\r
222\r
223 API = {};\r
224 }\r
225\r
226 function cannotInject (target, srcEvent) {\r
227 //<debug>\r
228 // TODO log something\r
229 //</debug>\r
230 }\r
231\r
232 return function (target) {\r
233 var me = this,\r
234 dispatcher = dispatchers[me.type] || cannotInject,\r
235 t = target ? (target.dom || target) : me.getTarget();\r
236\r
237 dispatcher(t, me);\r
238 };\r
239 }()), // call to produce method\r
240\r
241 preventDefault: function() {\r
242 var me = this,\r
243 event = me.browserEvent,\r
244 parentEvent = me.parentEvent,\r
245 unselectable, target;\r
246\r
247\r
248 // This check is for IE8/9. The event object may have been\r
249 // invalidated, so we can't delve into the details of it. If so,\r
250 // just fall out gracefully and don't attempt to do anything.\r
251 if (typeof event.type !== 'unknown') {\r
252 me.defaultPrevented = true;\r
253\r
254 // if the event was created by prototype-chaining a new object to an existing event\r
255 // instance, we need to make sure the parent event is defaultPrevented as well.\r
256 if (parentEvent) {\r
257 parentEvent.defaultPrevented = true;\r
258 }\r
259\r
260 if (event.preventDefault) {\r
261 event.preventDefault();\r
262 } else {\r
263 // The purpose of the code below is for preventDefault to stop focus from\r
264 // occurring like it does in other modern browsers. This only happens in\r
265 // IE8/9 when using attachEvent. The use of unselectable seems the most reliable\r
266 // way to prevent this from happening. We need to use a timeout to restore the\r
267 // unselectable state because if we don't setting it has no effect. It's important\r
268 // to set the atrribute to 'on' as opposed to just setting the property on the DOM element.\r
269 // See the link below for a discussion on the issue:\r
270 // http://bugs.jquery.com/ticket/10345\r
271 if (event.type === 'mousedown') {\r
272 target = event.target;\r
273 unselectable = target.getAttribute('unselectable');\r
274 if (unselectable !== 'on') {\r
275 target.setAttribute('unselectable', 'on');\r
276 Ext.defer(function() {\r
277 target.setAttribute('unselectable', unselectable);\r
278 }, 1);\r
279 }\r
280 }\r
281 // IE9 and earlier do not support preventDefault\r
282 event.returnValue = false;\r
283 // Some keys events require setting the keyCode to -1 to be prevented\r
284 // all ctrl + X and F1 -> F12\r
285 if (event.ctrlKey || event.keyCode > 111 && event.keyCode < 124) {\r
286 event.keyCode = -1;\r
287 }\r
288 }\r
289 }\r
290\r
291 return me;\r
292 },\r
293\r
294 stopPropagation: function() {\r
295 var me = this,\r
296 event = me.browserEvent;\r
297\r
298 // This check is for IE8/9. The event object may have been\r
299 // invalidated, so we can't delve into the details of it. If so,\r
300 // just fall out gracefully and don't attempt to do anything.\r
301 if (typeof event.type !== 'unknown') {\r
302 if (me.mousedownEvents[me.type]) {\r
303 // Fire the "unstoppable" global mousedown event\r
304 // (used for menu hiding, etc)\r
305 Ext.GlobalEvents.fireMouseDown(me);\r
306 }\r
307 me.callParent();\r
308 }\r
309 return me;\r
310 },\r
311\r
312 deprecated: {\r
313 '5.0': {\r
314 methods: {\r
315 /**\r
316 * @method clone\r
317 * @member Ext.event.Event\r
318 * Clones this event.\r
319 * @return {Ext.event.Event} The cloned copy\r
320 * @deprecated 5.0.0\r
321 */\r
322 clone: function() {\r
323 return new this.self(this.browserEvent, this);\r
324 }\r
325 }\r
326 }\r
327 }\r
328}, function() {\r
329 var Event = this,\r
330 btnMap,\r
331 onKeyDown = function(e) {\r
332 if (e.keyCode === 9) {\r
333 Event.forwardTab = !e.shiftKey;\r
334 }\r
335 },\r
336 onKeyUp = function(e) {\r
337 if (e.keyCode === 9) {\r
338 delete Event.forwardTab;\r
339 }\r
340 };\r
341\r
342//<feature legacyBrowser>\r
343 if (Ext.isIE9m) {\r
344 btnMap = {\r
345 0: 0,\r
346 1: 0,\r
347 4: 1,\r
348 2: 2\r
349 };\r
350\r
351 Event.override({\r
352 statics: {\r
353 /**\r
354 * @member Ext.event.Event\r
355 * When events are attached using IE's attachEvent API instead of\r
356 * addEventListener accessing any members of an event object asynchronously\r
357 * results in "Member not found" error. To work around this we fabricate\r
358 * our own event object by copying all of its members to a new object.\r
359 * @param {Event} browserEvent The native browser event object\r
360 * @private\r
361 * @static\r
362 */\r
363 enableIEAsync: function(browserEvent) {\r
364 var name,\r
365 fakeEvent = {};\r
366\r
367 for (name in browserEvent) {\r
368 fakeEvent[name] = browserEvent[name];\r
369 }\r
370\r
371 return fakeEvent;\r
372 }\r
373 },\r
374\r
375 constructor: function(event, info, touchesMap, identifiers) {\r
376 var me = this;\r
377 me.callParent([event, info, touchesMap, identifiers]);\r
378 me.button = btnMap[event.button];\r
379\r
380 if (event.type === 'contextmenu') {\r
381 me.button = 2; // IE8/9 reports click as 0, so we can at least attempt to infer here\r
382 } \r
383\r
384 // IE8 can throw an error when trying to access properties on a browserEvent\r
385 // object when the event has been buffered or delayed. Cache them here\r
386 // so we can access them later.\r
387 me.toElement = event.toElement;\r
388 me.fromElement = event.fromElement;\r
389 },\r
390\r
391 mouseLeaveRe: /(mouseout|mouseleave)/,\r
392 mouseEnterRe: /(mouseover|mouseenter)/,\r
393\r
394 /**\r
395 * @member Ext.event.Event\r
396 * @inheritdoc Ext.event.Event#static-enableIEAsync\r
397 * @private\r
398 */\r
399 enableIEAsync: function(browserEvent) {\r
400 this.browserEvent = this.self.enableIEAsync(browserEvent);\r
401 },\r
402\r
403 getRelatedTarget: function(selector, maxDepth, returnEl) {\r
404 var me = this,\r
405 type, target;\r
406\r
407 if (!me.relatedTarget) {\r
408 type = me.type;\r
409 if (me.mouseLeaveRe.test(type)) {\r
410 target = me.toElement;\r
411 } else if (me.mouseEnterRe.test(type)) {\r
412 target = me.fromElement;\r
413 }\r
414 if (target) {\r
415 me.relatedTarget = me.self.resolveTextNode(target);\r
416 }\r
417 }\r
418\r
419 return me.callParent([selector, maxDepth, returnEl]);\r
420 }\r
421 });\r
422\r
423 // We place these listeners to capture Tab and Shift-Tab key strokes\r
424 // and pass this information in the focus/blur event if it happens\r
425 // between keydown/keyup pair.\r
426 document.attachEvent('onkeydown', onKeyDown);\r
427 document.attachEvent('onkeyup', onKeyUp);\r
428 \r
429 window.attachEvent('onunload', function() {\r
430 document.detachEvent('onkeydown', onKeyDown);\r
431 document.detachEvent('onkeyup', onKeyUp);\r
432 });\r
433 }\r
434 else\r
435//</feature>\r
436 if (document.addEventListener) {\r
437 document.addEventListener('keydown', onKeyDown, true);\r
438 document.addEventListener('keyup', onKeyUp, true);\r
439 }\r
440});\r