/ext-4.0.7/src/core/src/EventObject.js
JavaScript | 883 lines | 468 code | 77 blank | 338 comment | 80 complexity | a30f801da6b45b07c95e9ca2f16e4709 MD5 | raw file
1/*
2
3This file is part of Ext JS 4
4
5Copyright (c) 2011 Sencha Inc
6
7Contact: http://www.sencha.com/contact
8
9GNU General Public License Usage
10This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14*/
15/**
16 * @class Ext.EventObject
17
18Just as {@link Ext.Element} wraps around a native DOM node, Ext.EventObject
19wraps the browser's native event-object normalizing cross-browser differences,
20such as which mouse button is clicked, keys pressed, mechanisms to stop
21event-propagation along with a method to prevent default actions from taking place.
22
23For example:
24
25 function handleClick(e, t){ // e is not a standard event object, it is a Ext.EventObject
26 e.preventDefault();
27 var target = e.getTarget(); // same as t (the target HTMLElement)
28 ...
29 }
30
31 var myDiv = {@link Ext#get Ext.get}("myDiv"); // get reference to an {@link Ext.Element}
32 myDiv.on( // 'on' is shorthand for addListener
33 "click", // perform an action on click of myDiv
34 handleClick // reference to the action handler
35 );
36
37 // other methods to do the same:
38 Ext.EventManager.on("myDiv", 'click', handleClick);
39 Ext.EventManager.addListener("myDiv", 'click', handleClick);
40
41 * @singleton
42 * @markdown
43 */
44Ext.define('Ext.EventObjectImpl', {
45 uses: ['Ext.util.Point'],
46
47 /** Key constant @type Number */
48 BACKSPACE: 8,
49 /** Key constant @type Number */
50 TAB: 9,
51 /** Key constant @type Number */
52 NUM_CENTER: 12,
53 /** Key constant @type Number */
54 ENTER: 13,
55 /** Key constant @type Number */
56 RETURN: 13,
57 /** Key constant @type Number */
58 SHIFT: 16,
59 /** Key constant @type Number */
60 CTRL: 17,
61 /** Key constant @type Number */
62 ALT: 18,
63 /** Key constant @type Number */
64 PAUSE: 19,
65 /** Key constant @type Number */
66 CAPS_LOCK: 20,
67 /** Key constant @type Number */
68 ESC: 27,
69 /** Key constant @type Number */
70 SPACE: 32,
71 /** Key constant @type Number */
72 PAGE_UP: 33,
73 /** Key constant @type Number */
74 PAGE_DOWN: 34,
75 /** Key constant @type Number */
76 END: 35,
77 /** Key constant @type Number */
78 HOME: 36,
79 /** Key constant @type Number */
80 LEFT: 37,
81 /** Key constant @type Number */
82 UP: 38,
83 /** Key constant @type Number */
84 RIGHT: 39,
85 /** Key constant @type Number */
86 DOWN: 40,
87 /** Key constant @type Number */
88 PRINT_SCREEN: 44,
89 /** Key constant @type Number */
90 INSERT: 45,
91 /** Key constant @type Number */
92 DELETE: 46,
93 /** Key constant @type Number */
94 ZERO: 48,
95 /** Key constant @type Number */
96 ONE: 49,
97 /** Key constant @type Number */
98 TWO: 50,
99 /** Key constant @type Number */
100 THREE: 51,
101 /** Key constant @type Number */
102 FOUR: 52,
103 /** Key constant @type Number */
104 FIVE: 53,
105 /** Key constant @type Number */
106 SIX: 54,
107 /** Key constant @type Number */
108 SEVEN: 55,
109 /** Key constant @type Number */
110 EIGHT: 56,
111 /** Key constant @type Number */
112 NINE: 57,
113 /** Key constant @type Number */
114 A: 65,
115 /** Key constant @type Number */
116 B: 66,
117 /** Key constant @type Number */
118 C: 67,
119 /** Key constant @type Number */
120 D: 68,
121 /** Key constant @type Number */
122 E: 69,
123 /** Key constant @type Number */
124 F: 70,
125 /** Key constant @type Number */
126 G: 71,
127 /** Key constant @type Number */
128 H: 72,
129 /** Key constant @type Number */
130 I: 73,
131 /** Key constant @type Number */
132 J: 74,
133 /** Key constant @type Number */
134 K: 75,
135 /** Key constant @type Number */
136 L: 76,
137 /** Key constant @type Number */
138 M: 77,
139 /** Key constant @type Number */
140 N: 78,
141 /** Key constant @type Number */
142 O: 79,
143 /** Key constant @type Number */
144 P: 80,
145 /** Key constant @type Number */
146 Q: 81,
147 /** Key constant @type Number */
148 R: 82,
149 /** Key constant @type Number */
150 S: 83,
151 /** Key constant @type Number */
152 T: 84,
153 /** Key constant @type Number */
154 U: 85,
155 /** Key constant @type Number */
156 V: 86,
157 /** Key constant @type Number */
158 W: 87,
159 /** Key constant @type Number */
160 X: 88,
161 /** Key constant @type Number */
162 Y: 89,
163 /** Key constant @type Number */
164 Z: 90,
165 /** Key constant @type Number */
166 CONTEXT_MENU: 93,
167 /** Key constant @type Number */
168 NUM_ZERO: 96,
169 /** Key constant @type Number */
170 NUM_ONE: 97,
171 /** Key constant @type Number */
172 NUM_TWO: 98,
173 /** Key constant @type Number */
174 NUM_THREE: 99,
175 /** Key constant @type Number */
176 NUM_FOUR: 100,
177 /** Key constant @type Number */
178 NUM_FIVE: 101,
179 /** Key constant @type Number */
180 NUM_SIX: 102,
181 /** Key constant @type Number */
182 NUM_SEVEN: 103,
183 /** Key constant @type Number */
184 NUM_EIGHT: 104,
185 /** Key constant @type Number */
186 NUM_NINE: 105,
187 /** Key constant @type Number */
188 NUM_MULTIPLY: 106,
189 /** Key constant @type Number */
190 NUM_PLUS: 107,
191 /** Key constant @type Number */
192 NUM_MINUS: 109,
193 /** Key constant @type Number */
194 NUM_PERIOD: 110,
195 /** Key constant @type Number */
196 NUM_DIVISION: 111,
197 /** Key constant @type Number */
198 F1: 112,
199 /** Key constant @type Number */
200 F2: 113,
201 /** Key constant @type Number */
202 F3: 114,
203 /** Key constant @type Number */
204 F4: 115,
205 /** Key constant @type Number */
206 F5: 116,
207 /** Key constant @type Number */
208 F6: 117,
209 /** Key constant @type Number */
210 F7: 118,
211 /** Key constant @type Number */
212 F8: 119,
213 /** Key constant @type Number */
214 F9: 120,
215 /** Key constant @type Number */
216 F10: 121,
217 /** Key constant @type Number */
218 F11: 122,
219 /** Key constant @type Number */
220 F12: 123,
221 /**
222 * The mouse wheel delta scaling factor. This value depends on browser version and OS and
223 * attempts to produce a similar scrolling experience across all platforms and browsers.
224 *
225 * To change this value:
226 *
227 * Ext.EventObjectImpl.prototype.WHEEL_SCALE = 72;
228 *
229 * @type Number
230 * @markdown
231 */
232 WHEEL_SCALE: (function () {
233 var scale;
234
235 if (Ext.isGecko) {
236 // Firefox uses 3 on all platforms
237 scale = 3;
238 } else if (Ext.isMac) {
239 // Continuous scrolling devices have momentum and produce much more scroll than
240 // discrete devices on the same OS and browser. To make things exciting, Safari
241 // (and not Chrome) changed from small values to 120 (like IE).
242
243 if (Ext.isSafari && Ext.webKitVersion >= 532.0) {
244 // Safari changed the scrolling factor to match IE (for details see
245 // https://bugs.webkit.org/show_bug.cgi?id=24368). The WebKit version where this
246 // change was introduced was 532.0
247 // Detailed discussion:
248 // https://bugs.webkit.org/show_bug.cgi?id=29601
249 // http://trac.webkit.org/browser/trunk/WebKit/chromium/src/mac/WebInputEventFactory.mm#L1063
250 scale = 120;
251 } else {
252 // MS optical wheel mouse produces multiples of 12 which is close enough
253 // to help tame the speed of the continuous mice...
254 scale = 12;
255 }
256
257 // Momentum scrolling produces very fast scrolling, so increase the scale factor
258 // to help produce similar results cross platform. This could be even larger and
259 // it would help those mice, but other mice would become almost unusable as a
260 // result (since we cannot tell which device type is in use).
261 scale *= 3;
262 } else {
263 // IE, Opera and other Windows browsers use 120.
264 scale = 120;
265 }
266
267 return scale;
268 })(),
269
270 /**
271 * Simple click regex
272 * @private
273 */
274 clickRe: /(dbl)?click/,
275 // safari keypress events for special keys return bad keycodes
276 safariKeys: {
277 3: 13, // enter
278 63234: 37, // left
279 63235: 39, // right
280 63232: 38, // up
281 63233: 40, // down
282 63276: 33, // page up
283 63277: 34, // page down
284 63272: 46, // delete
285 63273: 36, // home
286 63275: 35 // end
287 },
288 // normalize button clicks, don't see any way to feature detect this.
289 btnMap: Ext.isIE ? {
290 1: 0,
291 4: 1,
292 2: 2
293 } : {
294 0: 0,
295 1: 1,
296 2: 2
297 },
298
299 constructor: function(event, freezeEvent){
300 if (event) {
301 this.setEvent(event.browserEvent || event, freezeEvent);
302 }
303 },
304
305 setEvent: function(event, freezeEvent){
306 var me = this, button, options;
307
308 if (event == me || (event && event.browserEvent)) { // already wrapped
309 return event;
310 }
311 me.browserEvent = event;
312 if (event) {
313 // normalize buttons
314 button = event.button ? me.btnMap[event.button] : (event.which ? event.which - 1 : -1);
315 if (me.clickRe.test(event.type) && button == -1) {
316 button = 0;
317 }
318 options = {
319 type: event.type,
320 button: button,
321 shiftKey: event.shiftKey,
322 // mac metaKey behaves like ctrlKey
323 ctrlKey: event.ctrlKey || event.metaKey || false,
324 altKey: event.altKey,
325 // in getKey these will be normalized for the mac
326 keyCode: event.keyCode,
327 charCode: event.charCode,
328 // cache the targets for the delayed and or buffered events
329 target: Ext.EventManager.getTarget(event),
330 relatedTarget: Ext.EventManager.getRelatedTarget(event),
331 currentTarget: event.currentTarget,
332 xy: (freezeEvent ? me.getXY() : null)
333 };
334 } else {
335 options = {
336 button: -1,
337 shiftKey: false,
338 ctrlKey: false,
339 altKey: false,
340 keyCode: 0,
341 charCode: 0,
342 target: null,
343 xy: [0, 0]
344 };
345 }
346 Ext.apply(me, options);
347 return me;
348 },
349
350 /**
351 * Stop the event (preventDefault and stopPropagation)
352 */
353 stopEvent: function(){
354 this.stopPropagation();
355 this.preventDefault();
356 },
357
358 /**
359 * Prevents the browsers default handling of the event.
360 */
361 preventDefault: function(){
362 if (this.browserEvent) {
363 Ext.EventManager.preventDefault(this.browserEvent);
364 }
365 },
366
367 /**
368 * Cancels bubbling of the event.
369 */
370 stopPropagation: function(){
371 var browserEvent = this.browserEvent;
372
373 if (browserEvent) {
374 if (browserEvent.type == 'mousedown') {
375 Ext.EventManager.stoppedMouseDownEvent.fire(this);
376 }
377 Ext.EventManager.stopPropagation(browserEvent);
378 }
379 },
380
381 /**
382 * Gets the character code for the event.
383 * @return {Number}
384 */
385 getCharCode: function(){
386 return this.charCode || this.keyCode;
387 },
388
389 /**
390 * Returns a normalized keyCode for the event.
391 * @return {Number} The key code
392 */
393 getKey: function(){
394 return this.normalizeKey(this.keyCode || this.charCode);
395 },
396
397 /**
398 * Normalize key codes across browsers
399 * @private
400 * @param {Number} key The key code
401 * @return {Number} The normalized code
402 */
403 normalizeKey: function(key){
404 // can't feature detect this
405 return Ext.isWebKit ? (this.safariKeys[key] || key) : key;
406 },
407
408 /**
409 * Gets the x coordinate of the event.
410 * @return {Number}
411 * @deprecated 4.0 Replaced by {@link #getX}
412 */
413 getPageX: function(){
414 return this.getX();
415 },
416
417 /**
418 * Gets the y coordinate of the event.
419 * @return {Number}
420 * @deprecated 4.0 Replaced by {@link #getY}
421 */
422 getPageY: function(){
423 return this.getY();
424 },
425
426 /**
427 * Gets the x coordinate of the event.
428 * @return {Number}
429 */
430 getX: function() {
431 return this.getXY()[0];
432 },
433
434 /**
435 * Gets the y coordinate of the event.
436 * @return {Number}
437 */
438 getY: function() {
439 return this.getXY()[1];
440 },
441
442 /**
443 * Gets the page coordinates of the event.
444 * @return {Number[]} The xy values like [x, y]
445 */
446 getXY: function() {
447 if (!this.xy) {
448 // same for XY
449 this.xy = Ext.EventManager.getPageXY(this.browserEvent);
450 }
451 return this.xy;
452 },
453
454 /**
455 * Gets the target for the event.
456 * @param {String} selector (optional) A simple selector to filter the target or look for an ancestor of the target
457 * @param {Number/HTMLElement} maxDepth (optional) The max depth to search as a number or element (defaults to 10 || document.body)
458 * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node
459 * @return {HTMLElement}
460 */
461 getTarget : function(selector, maxDepth, returnEl){
462 if (selector) {
463 return Ext.fly(this.target).findParent(selector, maxDepth, returnEl);
464 }
465 return returnEl ? Ext.get(this.target) : this.target;
466 },
467
468 /**
469 * Gets the related target.
470 * @param {String} selector (optional) A simple selector to filter the target or look for an ancestor of the target
471 * @param {Number/HTMLElement} maxDepth (optional) The max depth to search as a number or element (defaults to 10 || document.body)
472 * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node
473 * @return {HTMLElement}
474 */
475 getRelatedTarget : function(selector, maxDepth, returnEl){
476 if (selector) {
477 return Ext.fly(this.relatedTarget).findParent(selector, maxDepth, returnEl);
478 }
479 return returnEl ? Ext.get(this.relatedTarget) : this.relatedTarget;
480 },
481
482 /**
483 * Correctly scales a given wheel delta.
484 * @param {Number} delta The delta value.
485 */
486 correctWheelDelta : function (delta) {
487 var scale = this.WHEEL_SCALE,
488 ret = Math.round(delta / scale);
489
490 if (!ret && delta) {
491 ret = (delta < 0) ? -1 : 1; // don't allow non-zero deltas to go to zero!
492 }
493
494 return ret;
495 },
496
497 /**
498 * Returns the mouse wheel deltas for this event.
499 * @return {Object} An object with "x" and "y" properties holding the mouse wheel deltas.
500 */
501 getWheelDeltas : function () {
502 var me = this,
503 event = me.browserEvent,
504 dx = 0, dy = 0; // the deltas
505
506 if (Ext.isDefined(event.wheelDeltaX)) { // WebKit has both dimensions
507 dx = event.wheelDeltaX;
508 dy = event.wheelDeltaY;
509 } else if (event.wheelDelta) { // old WebKit and IE
510 dy = event.wheelDelta;
511 } else if (event.detail) { // Gecko
512 dy = -event.detail; // gecko is backwards
513
514 // Gecko sometimes returns really big values if the user changes settings to
515 // scroll a whole page per scroll
516 if (dy > 100) {
517 dy = 3;
518 } else if (dy < -100) {
519 dy = -3;
520 }
521
522 // Firefox 3.1 adds an axis field to the event to indicate direction of
523 // scroll. See https://developer.mozilla.org/en/Gecko-Specific_DOM_Events
524 if (Ext.isDefined(event.axis) && event.axis === event.HORIZONTAL_AXIS) {
525 dx = dy;
526 dy = 0;
527 }
528 }
529
530 return {
531 x: me.correctWheelDelta(dx),
532 y: me.correctWheelDelta(dy)
533 };
534 },
535
536 /**
537 * Normalizes mouse wheel y-delta across browsers. To get x-delta information, use
538 * {@link #getWheelDeltas} instead.
539 * @return {Number} The mouse wheel y-delta
540 */
541 getWheelDelta : function(){
542 var deltas = this.getWheelDeltas();
543
544 return deltas.y;
545 },
546
547 /**
548 * Returns true if the target of this event is a child of el. Unless the allowEl parameter is set, it will return false if if the target is el.
549 * Example usage:<pre><code>
550// Handle click on any child of an element
551Ext.getBody().on('click', function(e){
552 if(e.within('some-el')){
553 alert('Clicked on a child of some-el!');
554 }
555});
556
557// Handle click directly on an element, ignoring clicks on child nodes
558Ext.getBody().on('click', function(e,t){
559 if((t.id == 'some-el') && !e.within(t, true)){
560 alert('Clicked directly on some-el!');
561 }
562});
563</code></pre>
564 * @param {String/HTMLElement/Ext.Element} el The id, DOM element or Ext.Element to check
565 * @param {Boolean} related (optional) true to test if the related target is within el instead of the target
566 * @param {Boolean} allowEl (optional) true to also check if the passed element is the target or related target
567 * @return {Boolean}
568 */
569 within : function(el, related, allowEl){
570 if(el){
571 var t = related ? this.getRelatedTarget() : this.getTarget(),
572 result;
573
574 if (t) {
575 result = Ext.fly(el).contains(t);
576 if (!result && allowEl) {
577 result = t == Ext.getDom(el);
578 }
579 return result;
580 }
581 }
582 return false;
583 },
584
585 /**
586 * Checks if the key pressed was a "navigation" key
587 * @return {Boolean} True if the press is a navigation keypress
588 */
589 isNavKeyPress : function(){
590 var me = this,
591 k = this.normalizeKey(me.keyCode);
592
593 return (k >= 33 && k <= 40) || // Page Up/Down, End, Home, Left, Up, Right, Down
594 k == me.RETURN ||
595 k == me.TAB ||
596 k == me.ESC;
597 },
598
599 /**
600 * Checks if the key pressed was a "special" key
601 * @return {Boolean} True if the press is a special keypress
602 */
603 isSpecialKey : function(){
604 var k = this.normalizeKey(this.keyCode);
605 return (this.type == 'keypress' && this.ctrlKey) ||
606 this.isNavKeyPress() ||
607 (k == this.BACKSPACE) || // Backspace
608 (k >= 16 && k <= 20) || // Shift, Ctrl, Alt, Pause, Caps Lock
609 (k >= 44 && k <= 46); // Print Screen, Insert, Delete
610 },
611
612 /**
613 * Returns a point object that consists of the object coordinates.
614 * @return {Ext.util.Point} point
615 */
616 getPoint : function(){
617 var xy = this.getXY();
618 return Ext.create('Ext.util.Point', xy[0], xy[1]);
619 },
620
621 /**
622 * Returns true if the control, meta, shift or alt key was pressed during this event.
623 * @return {Boolean}
624 */
625 hasModifier : function(){
626 return this.ctrlKey || this.altKey || this.shiftKey || this.metaKey;
627 },
628
629 /**
630 * Injects a DOM event using the data in this object and (optionally) a new target.
631 * This is a low-level technique and not likely to be used by application code. The
632 * currently supported event types are:
633 * <p><b>HTMLEvents</b></p>
634 * <ul>
635 * <li>load</li>
636 * <li>unload</li>
637 * <li>select</li>
638 * <li>change</li>
639 * <li>submit</li>
640 * <li>reset</li>
641 * <li>resize</li>
642 * <li>scroll</li>
643 * </ul>
644 * <p><b>MouseEvents</b></p>
645 * <ul>
646 * <li>click</li>
647 * <li>dblclick</li>
648 * <li>mousedown</li>
649 * <li>mouseup</li>
650 * <li>mouseover</li>
651 * <li>mousemove</li>
652 * <li>mouseout</li>
653 * </ul>
654 * <p><b>UIEvents</b></p>
655 * <ul>
656 * <li>focusin</li>
657 * <li>focusout</li>
658 * <li>activate</li>
659 * <li>focus</li>
660 * <li>blur</li>
661 * </ul>
662 * @param {Ext.Element/HTMLElement} target (optional) If specified, the target for the event. This
663 * is likely to be used when relaying a DOM event. If not specified, {@link #getTarget}
664 * is used to determine the target.
665 */
666 injectEvent: function () {
667 var API,
668 dispatchers = {}; // keyed by event type (e.g., 'mousedown')
669
670 // Good reference: http://developer.yahoo.com/yui/docs/UserAction.js.html
671
672 // IE9 has createEvent, but this code causes major problems with htmleditor (it
673 // blocks all mouse events and maybe more). TODO
674
675 if (!Ext.isIE && document.createEvent) { // if (DOM compliant)
676 API = {
677 createHtmlEvent: function (doc, type, bubbles, cancelable) {
678 var event = doc.createEvent('HTMLEvents');
679
680 event.initEvent(type, bubbles, cancelable);
681 return event;
682 },
683
684 createMouseEvent: function (doc, type, bubbles, cancelable, detail,
685 clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
686 button, relatedTarget) {
687 var event = doc.createEvent('MouseEvents'),
688 view = doc.defaultView || window;
689
690 if (event.initMouseEvent) {
691 event.initMouseEvent(type, bubbles, cancelable, view, detail,
692 clientX, clientY, clientX, clientY, ctrlKey, altKey,
693 shiftKey, metaKey, button, relatedTarget);
694 } else { // old Safari
695 event = doc.createEvent('UIEvents');
696 event.initEvent(type, bubbles, cancelable);
697 event.view = view;
698 event.detail = detail;
699 event.screenX = clientX;
700 event.screenY = clientY;
701 event.clientX = clientX;
702 event.clientY = clientY;
703 event.ctrlKey = ctrlKey;
704 event.altKey = altKey;
705 event.metaKey = metaKey;
706 event.shiftKey = shiftKey;
707 event.button = button;
708 event.relatedTarget = relatedTarget;
709 }
710
711 return event;
712 },
713
714 createUIEvent: function (doc, type, bubbles, cancelable, detail) {
715 var event = doc.createEvent('UIEvents'),
716 view = doc.defaultView || window;
717
718 event.initUIEvent(type, bubbles, cancelable, view, detail);
719 return event;
720 },
721
722 fireEvent: function (target, type, event) {
723 target.dispatchEvent(event);
724 },
725
726 fixTarget: function (target) {
727 // Safari3 doesn't have window.dispatchEvent()
728 if (target == window && !target.dispatchEvent) {
729 return document;
730 }
731
732 return target;
733 }
734 };
735 } else if (document.createEventObject) { // else if (IE)
736 var crazyIEButtons = { 0: 1, 1: 4, 2: 2 };
737
738 API = {
739 createHtmlEvent: function (doc, type, bubbles, cancelable) {
740 var event = doc.createEventObject();
741 event.bubbles = bubbles;
742 event.cancelable = cancelable;
743 return event;
744 },
745
746 createMouseEvent: function (doc, type, bubbles, cancelable, detail,
747 clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
748 button, relatedTarget) {
749 var event = doc.createEventObject();
750 event.bubbles = bubbles;
751 event.cancelable = cancelable;
752 event.detail = detail;
753 event.screenX = clientX;
754 event.screenY = clientY;
755 event.clientX = clientX;
756 event.clientY = clientY;
757 event.ctrlKey = ctrlKey;
758 event.altKey = altKey;
759 event.shiftKey = shiftKey;
760 event.metaKey = metaKey;
761 event.button = crazyIEButtons[button] || button;
762 event.relatedTarget = relatedTarget; // cannot assign to/fromElement
763 return event;
764 },
765
766 createUIEvent: function (doc, type, bubbles, cancelable, detail) {
767 var event = doc.createEventObject();
768 event.bubbles = bubbles;
769 event.cancelable = cancelable;
770 return event;
771 },
772
773 fireEvent: function (target, type, event) {
774 target.fireEvent('on' + type, event);
775 },
776
777 fixTarget: function (target) {
778 if (target == document) {
779 // IE6,IE7 thinks window==document and doesn't have window.fireEvent()
780 // IE6,IE7 cannot properly call document.fireEvent()
781 return document.documentElement;
782 }
783
784 return target;
785 }
786 };
787 }
788
789 //----------------
790 // HTMLEvents
791
792 Ext.Object.each({
793 load: [false, false],
794 unload: [false, false],
795 select: [true, false],
796 change: [true, false],
797 submit: [true, true],
798 reset: [true, false],
799 resize: [true, false],
800 scroll: [true, false]
801 },
802 function (name, value) {
803 var bubbles = value[0], cancelable = value[1];
804 dispatchers[name] = function (targetEl, srcEvent) {
805 var e = API.createHtmlEvent(name, bubbles, cancelable);
806 API.fireEvent(targetEl, name, e);
807 };
808 });
809
810 //----------------
811 // MouseEvents
812
813 function createMouseEventDispatcher (type, detail) {
814 var cancelable = (type != 'mousemove');
815 return function (targetEl, srcEvent) {
816 var xy = srcEvent.getXY(),
817 e = API.createMouseEvent(targetEl.ownerDocument, type, true, cancelable,
818 detail, xy[0], xy[1], srcEvent.ctrlKey, srcEvent.altKey,
819 srcEvent.shiftKey, srcEvent.metaKey, srcEvent.button,
820 srcEvent.relatedTarget);
821 API.fireEvent(targetEl, type, e);
822 };
823 }
824
825 Ext.each(['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mousemove', 'mouseout'],
826 function (eventName) {
827 dispatchers[eventName] = createMouseEventDispatcher(eventName, 1);
828 });
829
830 //----------------
831 // UIEvents
832
833 Ext.Object.each({
834 focusin: [true, false],
835 focusout: [true, false],
836 activate: [true, true],
837 focus: [false, false],
838 blur: [false, false]
839 },
840 function (name, value) {
841 var bubbles = value[0], cancelable = value[1];
842 dispatchers[name] = function (targetEl, srcEvent) {
843 var e = API.createUIEvent(targetEl.ownerDocument, name, bubbles, cancelable, 1);
844 API.fireEvent(targetEl, name, e);
845 };
846 });
847
848 //---------
849 if (!API) {
850 // not even sure what ancient browsers fall into this category...
851
852 dispatchers = {}; // never mind all those we just built :P
853
854 API = {
855 fixTarget: function (t) {
856 return t;
857 }
858 };
859 }
860
861 function cannotInject (target, srcEvent) {
862 //<debug>
863 // TODO log something
864 //</debug>
865 }
866
867 return function (target) {
868 var me = this,
869 dispatcher = dispatchers[me.type] || cannotInject,
870 t = target ? (target.dom || target) : me.getTarget();
871
872 t = API.fixTarget(t);
873 dispatcher(t, me);
874 };
875 }() // call to produce method
876
877}, function() {
878
879Ext.EventObject = new Ext.EventObjectImpl();
880
881});
882
883