X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6e39d509471fe9b4e2660e0d1631b350d0c66f40..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/docs/source/EventObject.html diff --git a/docs/source/EventObject.html b/docs/source/EventObject.html new file mode 100644 index 00000000..78bc4bde --- /dev/null +++ b/docs/source/EventObject.html @@ -0,0 +1,772 @@ +Sencha Documentation Project
/**
+ * @class Ext.EventObject
+
+Just as {@link Ext.core.Element} wraps around a native DOM node, Ext.EventObject
+wraps the browser's native event-object normalizing cross-browser differences,
+such as which mouse button is clicked, keys pressed, mechanisms to stop
+event-propagation along with a method to prevent default actions from taking place.
+
+For example:
+
+    function handleClick(e, t){ // e is not a standard event object, it is a Ext.EventObject
+        e.preventDefault();
+        var target = e.getTarget(); // same as t (the target HTMLElement)
+        ...
+    }
+
+    var myDiv = {@link Ext#get Ext.get}("myDiv");  // get reference to an {@link Ext.core.Element}
+    myDiv.on(         // 'on' is shorthand for addListener
+        "click",      // perform an action on click of myDiv
+        handleClick   // reference to the action handler
+    );
+
+    // other methods to do the same:
+    Ext.EventManager.on("myDiv", 'click', handleClick);
+    Ext.EventManager.addListener("myDiv", 'click', handleClick);
+
+ * @singleton
+ * @markdown
+ */
+Ext.define('Ext.EventObjectImpl', {
+    uses: ['Ext.util.Point'],
+
+    /** Key constant @type Number */
+    BACKSPACE: 8,
+    /** Key constant @type Number */
+    TAB: 9,
+    /** Key constant @type Number */
+    NUM_CENTER: 12,
+    /** Key constant @type Number */
+    ENTER: 13,
+    /** Key constant @type Number */
+    RETURN: 13,
+    /** Key constant @type Number */
+    SHIFT: 16,
+    /** Key constant @type Number */
+    CTRL: 17,
+    /** Key constant @type Number */
+    ALT: 18,
+    /** Key constant @type Number */
+    PAUSE: 19,
+    /** Key constant @type Number */
+    CAPS_LOCK: 20,
+    /** Key constant @type Number */
+    ESC: 27,
+    /** Key constant @type Number */
+    SPACE: 32,
+    /** Key constant @type Number */
+    PAGE_UP: 33,
+    /** Key constant @type Number */
+    PAGE_DOWN: 34,
+    /** Key constant @type Number */
+    END: 35,
+    /** Key constant @type Number */
+    HOME: 36,
+    /** Key constant @type Number */
+    LEFT: 37,
+    /** Key constant @type Number */
+    UP: 38,
+    /** Key constant @type Number */
+    RIGHT: 39,
+    /** Key constant @type Number */
+    DOWN: 40,
+    /** Key constant @type Number */
+    PRINT_SCREEN: 44,
+    /** Key constant @type Number */
+    INSERT: 45,
+    /** Key constant @type Number */
+    DELETE: 46,
+    /** Key constant @type Number */
+    ZERO: 48,
+    /** Key constant @type Number */
+    ONE: 49,
+    /** Key constant @type Number */
+    TWO: 50,
+    /** Key constant @type Number */
+    THREE: 51,
+    /** Key constant @type Number */
+    FOUR: 52,
+    /** Key constant @type Number */
+    FIVE: 53,
+    /** Key constant @type Number */
+    SIX: 54,
+    /** Key constant @type Number */
+    SEVEN: 55,
+    /** Key constant @type Number */
+    EIGHT: 56,
+    /** Key constant @type Number */
+    NINE: 57,
+    /** Key constant @type Number */
+    A: 65,
+    /** Key constant @type Number */
+    B: 66,
+    /** Key constant @type Number */
+    C: 67,
+    /** Key constant @type Number */
+    D: 68,
+    /** Key constant @type Number */
+    E: 69,
+    /** Key constant @type Number */
+    F: 70,
+    /** Key constant @type Number */
+    G: 71,
+    /** Key constant @type Number */
+    H: 72,
+    /** Key constant @type Number */
+    I: 73,
+    /** Key constant @type Number */
+    J: 74,
+    /** Key constant @type Number */
+    K: 75,
+    /** Key constant @type Number */
+    L: 76,
+    /** Key constant @type Number */
+    M: 77,
+    /** Key constant @type Number */
+    N: 78,
+    /** Key constant @type Number */
+    O: 79,
+    /** Key constant @type Number */
+    P: 80,
+    /** Key constant @type Number */
+    Q: 81,
+    /** Key constant @type Number */
+    R: 82,
+    /** Key constant @type Number */
+    S: 83,
+    /** Key constant @type Number */
+    T: 84,
+    /** Key constant @type Number */
+    U: 85,
+    /** Key constant @type Number */
+    V: 86,
+    /** Key constant @type Number */
+    W: 87,
+    /** Key constant @type Number */
+    X: 88,
+    /** Key constant @type Number */
+    Y: 89,
+    /** Key constant @type Number */
+    Z: 90,
+    /** Key constant @type Number */
+    CONTEXT_MENU: 93,
+    /** Key constant @type Number */
+    NUM_ZERO: 96,
+    /** Key constant @type Number */
+    NUM_ONE: 97,
+    /** Key constant @type Number */
+    NUM_TWO: 98,
+    /** Key constant @type Number */
+    NUM_THREE: 99,
+    /** Key constant @type Number */
+    NUM_FOUR: 100,
+    /** Key constant @type Number */
+    NUM_FIVE: 101,
+    /** Key constant @type Number */
+    NUM_SIX: 102,
+    /** Key constant @type Number */
+    NUM_SEVEN: 103,
+    /** Key constant @type Number */
+    NUM_EIGHT: 104,
+    /** Key constant @type Number */
+    NUM_NINE: 105,
+    /** Key constant @type Number */
+    NUM_MULTIPLY: 106,
+    /** Key constant @type Number */
+    NUM_PLUS: 107,
+    /** Key constant @type Number */
+    NUM_MINUS: 109,
+    /** Key constant @type Number */
+    NUM_PERIOD: 110,
+    /** Key constant @type Number */
+    NUM_DIVISION: 111,
+    /** Key constant @type Number */
+    F1: 112,
+    /** Key constant @type Number */
+    F2: 113,
+    /** Key constant @type Number */
+    F3: 114,
+    /** Key constant @type Number */
+    F4: 115,
+    /** Key constant @type Number */
+    F5: 116,
+    /** Key constant @type Number */
+    F6: 117,
+    /** Key constant @type Number */
+    F7: 118,
+    /** Key constant @type Number */
+    F8: 119,
+    /** Key constant @type Number */
+    F9: 120,
+    /** Key constant @type Number */
+    F10: 121,
+    /** Key constant @type Number */
+    F11: 122,
+    /** Key constant @type Number */
+    F12: 123,
+
+    /**
+     * Simple click regex
+     * @private
+     */
+    clickRe: /(dbl)?click/,
+    // safari keypress events for special keys return bad keycodes
+    safariKeys: {
+        3: 13, // enter
+        63234: 37, // left
+        63235: 39, // right
+        63232: 38, // up
+        63233: 40, // down
+        63276: 33, // page up
+        63277: 34, // page down
+        63272: 46, // delete
+        63273: 36, // home
+        63275: 35 // end
+    },
+    // normalize button clicks, don't see any way to feature detect this.
+    btnMap: Ext.isIE ? {
+        1: 0,
+        4: 1,
+        2: 2
+    } : {
+        0: 0,
+        1: 1,
+        2: 2
+    },
+
+    constructor: function(event, freezeEvent){
+        if (event) {
+            this.setEvent(event.browserEvent || event, freezeEvent);
+        }
+    },
+
+    setEvent: function(event, freezeEvent){
+        var me = this, button, options;
+
+        if (event == me || (event && event.browserEvent)) { // already wrapped
+            return event;
+        }
+        me.browserEvent = event;
+        if (event) {
+            // normalize buttons
+            button = event.button ? me.btnMap[event.button] : (event.which ? event.which - 1 : -1);
+            if (me.clickRe.test(event.type) && button == -1) {
+                button = 0;
+            }
+            options = {
+                type: event.type,
+                button: button,
+                shiftKey: event.shiftKey,
+                // mac metaKey behaves like ctrlKey
+                ctrlKey: event.ctrlKey || event.metaKey || false,
+                altKey: event.altKey,
+                // in getKey these will be normalized for the mac
+                keyCode: event.keyCode,
+                charCode: event.charCode,
+                // cache the targets for the delayed and or buffered events
+                target: Ext.EventManager.getTarget(event),
+                relatedTarget: Ext.EventManager.getRelatedTarget(event),
+                currentTarget: event.currentTarget,
+                xy: (freezeEvent ? me.getXY() : null)
+            };
+        } else {
+            options = {
+                button: -1,
+                shiftKey: false,
+                ctrlKey: false,
+                altKey: false,
+                keyCode: 0,
+                charCode: 0,
+                target: null,
+                xy: [0, 0]
+            };
+        }
+        Ext.apply(me, options);
+        return me;
+    },
+
+    /**
+     * Stop the event (preventDefault and stopPropagation)
+     */
+    stopEvent: function(){
+        this.stopPropagation();
+        this.preventDefault();
+    },
+
+    /**
+     * Prevents the browsers default handling of the event.
+     */
+    preventDefault: function(){
+        if (this.browserEvent) {
+            Ext.EventManager.preventDefault(this.browserEvent);
+        }
+    },
+
+    /**
+     * Cancels bubbling of the event.
+     */
+    stopPropagation: function(){
+        var browserEvent = this.browserEvent;
+
+        if (browserEvent) {
+            if (browserEvent.type == 'mousedown') {
+                Ext.EventManager.stoppedMouseDownEvent.fire(this);
+            }
+            Ext.EventManager.stopPropagation(browserEvent);
+        }
+    },
+
+    /**
+     * Gets the character code for the event.
+     * @return {Number}
+     */
+    getCharCode: function(){
+        return this.charCode || this.keyCode;
+    },
+
+    /**
+     * Returns a normalized keyCode for the event.
+     * @return {Number} The key code
+     */
+    getKey: function(){
+        return this.normalizeKey(this.keyCode || this.charCode);
+    },
+
+    /**
+     * Normalize key codes across browsers
+     * @private
+     * @param {Number} key The key code
+     * @return {Number} The normalized code
+     */
+    normalizeKey: function(key){
+        // can't feature detect this
+        return Ext.isWebKit ? (this.safariKeys[key] || key) : key;
+    },
+
+    /**
+     * Gets the x coordinate of the event.
+     * @return {Number}
+     * @deprecated 4.0 Replaced by {@link #getX}
+     */
+    getPageX: function(){
+        return this.getX();
+    },
+
+    /**
+     * Gets the y coordinate of the event.
+     * @return {Number}
+     * @deprecated 4.0 Replaced by {@link #getY}
+     */
+    getPageY: function(){
+        return this.getY();
+    },
+    
+    /**
+     * Gets the x coordinate of the event.
+     * @return {Number}
+     */
+    getX: function() {
+        return this.getXY()[0];
+    },    
+    
+    /**
+     * Gets the y coordinate of the event.
+     * @return {Number}
+     */
+    getY: function() {
+        return this.getXY()[1];
+    },
+        
+    /**
+     * Gets the page coordinates of the event.
+     * @return {Array} The xy values like [x, y]
+     */
+    getXY: function() {
+        if (!this.xy) {
+            // same for XY
+            this.xy = Ext.EventManager.getPageXY(this.browserEvent);
+        }
+        return this.xy;
+    },
+
+    /**
+     * Gets the target for the event.
+     * @param {String} selector (optional) A simple selector to filter the target or look for an ancestor of the target
+     * @param {Number/Mixed} maxDepth (optional) The max depth to search as a number or element (defaults to 10 || document.body)
+     * @param {Boolean} returnEl (optional) True to return a Ext.core.Element object instead of DOM node
+     * @return {HTMLelement}
+     */
+    getTarget : function(selector, maxDepth, returnEl){
+        if (selector) {
+            return Ext.fly(this.target).findParent(selector, maxDepth, returnEl);
+        }
+        return returnEl ? Ext.get(this.target) : this.target;
+    },
+
+    /**
+     * Gets the related target.
+     * @param {String} selector (optional) A simple selector to filter the target or look for an ancestor of the target
+     * @param {Number/Mixed} maxDepth (optional) The max depth to search as a number or element (defaults to 10 || document.body)
+     * @param {Boolean} returnEl (optional) True to return a Ext.core.Element object instead of DOM node
+     * @return {HTMLElement}
+     */
+    getRelatedTarget : function(selector, maxDepth, returnEl){
+        if (selector) {
+            return Ext.fly(this.relatedTarget).findParent(selector, maxDepth, returnEl);
+        }
+        return returnEl ? Ext.get(this.relatedTarget) : this.relatedTarget;
+    },
+
+    /**
+     * Normalizes mouse wheel delta across browsers
+     * @return {Number} The delta
+     */
+    getWheelDelta : function(){
+        var event = this.browserEvent,
+            delta = 0;
+
+        if (event.wheelDelta) { /* IE/Opera. */
+            delta = event.wheelDelta / 120;
+        } else if (event.detail){ /* Mozilla case. */
+            delta = -event.detail / 3;
+        }
+        return delta;
+    },
+
+    /**
+    * 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.
+    * Example usage:<pre><code>
+// Handle click on any child of an element
+Ext.getBody().on('click', function(e){
+    if(e.within('some-el')){
+        alert('Clicked on a child of some-el!');
+    }
+});
+
+// Handle click directly on an element, ignoring clicks on child nodes
+Ext.getBody().on('click', function(e,t){
+    if((t.id == 'some-el') && !e.within(t, true)){
+        alert('Clicked directly on some-el!');
+    }
+});
+</code></pre>
+     * @param {Mixed} el The id, DOM element or Ext.core.Element to check
+     * @param {Boolean} related (optional) true to test if the related target is within el instead of the target
+     * @param {Boolean} allowEl {optional} true to also check if the passed element is the target or related target
+     * @return {Boolean}
+     */
+    within : function(el, related, allowEl){
+        if(el){
+            var t = related ? this.getRelatedTarget() : this.getTarget(),
+                result;
+
+            if (t) {
+                result = Ext.fly(el).contains(t);
+                if (!result && allowEl) {
+                    result = t == Ext.getDom(el);
+                }
+                return result;
+            }
+        }
+        return false;
+    },
+
+    /**
+     * Checks if the key pressed was a "navigation" key
+     * @return {Boolean} True if the press is a navigation keypress
+     */
+    isNavKeyPress : function(){
+        var me = this,
+            k = this.normalizeKey(me.keyCode);
+
+       return (k >= 33 && k <= 40) ||  // Page Up/Down, End, Home, Left, Up, Right, Down
+       k == me.RETURN ||
+       k == me.TAB ||
+       k == me.ESC;
+    },
+
+    /**
+     * Checks if the key pressed was a "special" key
+     * @return {Boolean} True if the press is a special keypress
+     */
+    isSpecialKey : function(){
+        var k = this.normalizeKey(this.keyCode);
+        return (this.type == 'keypress' && this.ctrlKey) ||
+        this.isNavKeyPress() ||
+        (k == this.BACKSPACE) || // Backspace
+        (k >= 16 && k <= 20) || // Shift, Ctrl, Alt, Pause, Caps Lock
+        (k >= 44 && k <= 46);   // Print Screen, Insert, Delete
+    },
+
+    /**
+     * Returns a point object that consists of the object coordinates.
+     * @return {Ext.util.Point} point
+     */
+    getPoint : function(){
+        var xy = this.getXY();
+        return Ext.create('Ext.util.Point', xy[0], xy[1]);
+    },
+
+   /**
+    * Returns true if the control, meta, shift or alt key was pressed during this event.
+    * @return {Boolean}
+    */
+    hasModifier : function(){
+        return this.ctrlKey || this.altKey || this.shiftKey || this.metaKey;
+    },
+
+    /**
+     * Injects a DOM event using the data in this object and (optionally) a new target.
+     * This is a low-level technique and not likely to be used by application code. The
+     * currently supported event types are:
+     * <p><b>HTMLEvents</b></p>
+     * <ul>
+     * <li>load</li>
+     * <li>unload</li>
+     * <li>select</li>
+     * <li>change</li>
+     * <li>submit</li>
+     * <li>reset</li>
+     * <li>resize</li>
+     * <li>scroll</li>
+     * </ul>
+     * <p><b>MouseEvents</b></p>
+     * <ul>
+     * <li>click</li>
+     * <li>dblclick</li>
+     * <li>mousedown</li>
+     * <li>mouseup</li>
+     * <li>mouseover</li>
+     * <li>mousemove</li>
+     * <li>mouseout</li>
+     * </ul>
+     * <p><b>UIEvents</b></p>
+     * <ul>
+     * <li>focusin</li>
+     * <li>focusout</li>
+     * <li>activate</li>
+     * <li>focus</li>
+     * <li>blur</li>
+     * </ul>
+     * @param {Element/HTMLElement} target If specified, the target for the event. This
+     * is likely to be used when relaying a DOM event. If not specified, {@link #getTarget}
+     * is used to determine the target.
+     */
+    injectEvent: function () {
+        var API,
+            dispatchers = {}; // keyed by event type (e.g., 'mousedown')
+
+        // Good reference: http://developer.yahoo.com/yui/docs/UserAction.js.html
+
+        // IE9 has createEvent, but this code causes major problems with htmleditor (it
+        // blocks all mouse events and maybe more). TODO
+
+        if (!Ext.isIE && document.createEvent) { // if (DOM compliant)
+            API = {
+                createHtmlEvent: function (doc, type, bubbles, cancelable) {
+                    var event = doc.createEvent('HTMLEvents');
+
+                    event.initEvent(type, bubbles, cancelable);
+                    return event;
+                },
+
+                createMouseEvent: function (doc, type, bubbles, cancelable, detail,
+                                            clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
+                                            button, relatedTarget) {
+                    var event = doc.createEvent('MouseEvents'),
+                        view = doc.defaultView || window;
+
+                    if (event.initMouseEvent) {
+                        event.initMouseEvent(type, bubbles, cancelable, view, detail,
+                                    clientX, clientY, clientX, clientY, ctrlKey, altKey,
+                                    shiftKey, metaKey, button, relatedTarget);
+                    } else { // old Safari
+                        event = doc.createEvent('UIEvents');
+                        event.initEvent(type, bubbles, cancelable);
+                        event.view = view;
+                        event.detail = detail;
+                        event.screenX = clientX;
+                        event.screenY = clientY;
+                        event.clientX = clientX;
+                        event.clientY = clientY;
+                        event.ctrlKey = ctrlKey;
+                        event.altKey = altKey;
+                        event.metaKey = metaKey;
+                        event.shiftKey = shiftKey;
+                        event.button = button;
+                        event.relatedTarget = relatedTarget;
+                    }
+
+                    return event;
+                },
+
+                createUIEvent: function (doc, type, bubbles, cancelable, detail) {
+                    var event = doc.createEvent('UIEvents'),
+                        view = doc.defaultView || window;
+
+                    event.initUIEvent(type, bubbles, cancelable, view, detail);
+                    return event;
+                },
+
+                fireEvent: function (target, type, event) {
+                    target.dispatchEvent(event);
+                },
+
+                fixTarget: function (target) {
+                    // Safari3 doesn't have window.dispatchEvent()
+                    if (target == window && !target.dispatchEvent) {
+                        return document;
+                    }
+
+                    return target;
+                }
+            }
+        } else if (document.createEventObject) { // else if (IE)
+            var crazyIEButtons = { 0: 1, 1: 4, 2: 2 };
+
+            API = {
+                createHtmlEvent: function (doc, type, bubbles, cancelable) {
+                    var event = doc.createEventObject();
+                    event.bubbles = bubbles;
+                    event.cancelable = cancelable;
+                    return event;
+                },
+
+                createMouseEvent: function (doc, type, bubbles, cancelable, detail,
+                                            clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
+                                            button, relatedTarget) {
+                    var event = doc.createEventObject();
+                    event.bubbles = bubbles;
+                    event.cancelable = cancelable;
+                    event.detail = detail;
+                    event.screenX = clientX;
+                    event.screenY = clientY;
+                    event.clientX = clientX;
+                    event.clientY = clientY;
+                    event.ctrlKey = ctrlKey;
+                    event.altKey = altKey;
+                    event.shiftKey = shiftKey;
+                    event.metaKey = metaKey;
+                    event.button = crazyIEButtons[button] || button;
+                    event.relatedTarget = relatedTarget; // cannot assign to/fromElement
+                    return event;
+                },
+
+                createUIEvent: function (doc, type, bubbles, cancelable, detail) {
+                    var event = doc.createEventObject();
+                    event.bubbles = bubbles;
+                    event.cancelable = cancelable;
+                    return event;
+                },
+
+                fireEvent: function (target, type, event) {
+                    target.fireEvent('on' + type, event);
+                },
+
+                fixTarget: function (target) {
+                    if (target == document) {
+                        // IE6,IE7 thinks window==document and doesn't have window.fireEvent()
+                        // IE6,IE7 cannot properly call document.fireEvent()
+                        return document.documentElement;
+                    }
+
+                    return target;
+                }
+            };
+        }
+
+        //----------------
+        // HTMLEvents
+
+        Ext.Object.each({
+                load:   [false, false],
+                unload: [false, false],
+                select: [true, false],
+                change: [true, false],
+                submit: [true, true],
+                reset:  [true, false],
+                resize: [true, false],
+                scroll: [true, false]
+            },
+            function (name, value) {
+                var bubbles = value[0], cancelable = value[1];
+                dispatchers[name] = function (targetEl, srcEvent) {
+                    var e = API.createHtmlEvent(name, bubbles, cancelable);
+                    API.fireEvent(targetEl, name, e);
+                };
+            });
+
+        //----------------
+        // MouseEvents
+
+        function createMouseEventDispatcher (type, detail) {
+            var cancelable = (type != 'mousemove');
+            return function (targetEl, srcEvent) {
+                var xy = srcEvent.getXY(),
+                    e = API.createMouseEvent(targetEl.ownerDocument, type, true, cancelable,
+                                detail, xy[0], xy[1], srcEvent.ctrlKey, srcEvent.altKey,
+                                srcEvent.shiftKey, srcEvent.metaKey, srcEvent.button,
+                                srcEvent.relatedTarget);
+                API.fireEvent(targetEl, type, e);
+            };
+        }
+
+        Ext.each(['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mousemove', 'mouseout'],
+            function (eventName) {
+                dispatchers[eventName] = createMouseEventDispatcher(eventName, 1);
+            });
+
+        //----------------
+        // UIEvents
+
+        Ext.Object.each({
+                focusin:  [true, false],
+                focusout: [true, false],
+                activate: [true, true],
+                focus:    [false, false],
+                blur:     [false, false]
+            },
+            function (name, value) {
+                var bubbles = value[0], cancelable = value[1];
+                dispatchers[name] = function (targetEl, srcEvent) {
+                    var e = API.createUIEvent(targetEl.ownerDocument, name, bubbles, cancelable, 1);
+                    API.fireEvent(targetEl, name, e);
+                };
+            });
+
+        //---------
+        if (!API) {
+            // not even sure what ancient browsers fall into this category...
+
+            dispatchers = {}; // never mind all those we just built :P
+
+            API = {
+                fixTarget: function (t) {
+                    return t;
+                }
+            };
+        }
+
+        function cannotInject (target, srcEvent) {
+            //<debug>
+            // TODO log something
+            //</debug>
+        }
+
+        return function (target) {
+            var me = this,
+                dispatcher = dispatchers[me.type] || cannotInject,
+                t = target ? (target.dom || target) : me.getTarget();
+
+            t = API.fixTarget(t);
+            dispatcher(t, me);
+        };
+    }() // call to produce method
+
+}, function() {
+
+Ext.EventObject = new Ext.EventObjectImpl();
+
+});
+
+
\ No newline at end of file