PageRenderTime 25ms CodeModel.GetById 19ms app.highlight 4ms RepoModel.GetById 0ms app.codeStats 0ms

/ext-4.0.7/docs/source/KeyMap.html

https://bitbucket.org/srogerf/javascript
HTML | 333 lines | 303 code | 30 blank | 0 comment | 0 complexity | 20c435e272271e2e4f03d5e13850b7d0 MD5 | raw file
  1<!DOCTYPE html>
  2<html>
  3<head>
  4  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5  <title>The source code</title>
  6  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8  <style type="text/css">
  9    .highlight { display: block; background-color: #ddd; }
 10  </style>
 11  <script type="text/javascript">
 12    function highlight() {
 13      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
 14    }
 15  </script>
 16</head>
 17<body onload="prettyPrint(); highlight();">
 18  <pre class="prettyprint lang-js"><span id='Ext-util-KeyMap'>/**
 19</span> * @class Ext.util.KeyMap
 20 * Handles mapping keys to actions for an element. One key map can be used for multiple actions.
 21 * The constructor accepts the same config object as defined by {@link #addBinding}.
 22 * If you bind a callback function to a KeyMap, anytime the KeyMap handles an expected key
 23 * combination it will call the function with this signature (if the match is a multi-key
 24 * combination the callback will still be called only once): (String key, Ext.EventObject e)
 25 * A KeyMap can also handle a string representation of keys. By default KeyMap starts enabled.&lt;br /&gt;
 26 * Usage:
 27 &lt;pre&gt;&lt;code&gt;
 28// map one key by key code
 29var map = new Ext.util.KeyMap(&quot;my-element&quot;, {
 30    key: 13, // or Ext.EventObject.ENTER
 31    fn: myHandler,
 32    scope: myObject
 33});
 34
 35// map multiple keys to one action by string
 36var map = new Ext.util.KeyMap(&quot;my-element&quot;, {
 37    key: &quot;a\r\n\t&quot;,
 38    fn: myHandler,
 39    scope: myObject
 40});
 41
 42// map multiple keys to multiple actions by strings and array of codes
 43var map = new Ext.util.KeyMap(&quot;my-element&quot;, [
 44    {
 45        key: [10,13],
 46        fn: function(){ alert(&quot;Return was pressed&quot;); }
 47    }, {
 48        key: &quot;abc&quot;,
 49        fn: function(){ alert('a, b or c was pressed'); }
 50    }, {
 51        key: &quot;\t&quot;,
 52        ctrl:true,
 53        shift:true,
 54        fn: function(){ alert('Control + shift + tab was pressed.'); }
 55    }
 56]);
 57&lt;/code&gt;&lt;/pre&gt;
 58 */
 59Ext.define('Ext.util.KeyMap', {
 60    alternateClassName: 'Ext.KeyMap',
 61
 62<span id='Ext-util-KeyMap-method-constructor'>    /**
 63</span>     * Creates new KeyMap.
 64     * @param {String/HTMLElement/Ext.Element} el The element or its ID to bind to
 65     * @param {Object} binding The binding (see {@link #addBinding})
 66     * @param {String} [eventName=&quot;keydown&quot;] The event to bind to
 67     */
 68    constructor: function(el, binding, eventName){
 69        var me = this;
 70
 71        Ext.apply(me, {
 72            el: Ext.get(el),
 73            eventName: eventName || me.eventName,
 74            bindings: []
 75        });
 76        if (binding) {
 77            me.addBinding(binding);
 78        }
 79        me.enable();
 80    },
 81
 82    eventName: 'keydown',
 83
 84<span id='Ext-util-KeyMap-method-addBinding'>    /**
 85</span>     * Add a new binding to this KeyMap. The following config object properties are supported:
 86     * &lt;pre&gt;
 87Property            Type             Description
 88----------          ---------------  ----------------------------------------------------------------------
 89key                 String/Array     A single keycode or an array of keycodes to handle
 90shift               Boolean          True to handle key only when shift is pressed, False to handle the key only when shift is not pressed (defaults to undefined)
 91ctrl                Boolean          True to handle key only when ctrl is pressed, False to handle the key only when ctrl is not pressed (defaults to undefined)
 92alt                 Boolean          True to handle key only when alt is pressed, False to handle the key only when alt is not pressed (defaults to undefined)
 93handler             Function         The function to call when KeyMap finds the expected key combination
 94fn                  Function         Alias of handler (for backwards-compatibility)
 95scope               Object           The scope of the callback function
 96defaultEventAction  String           A default action to apply to the event. Possible values are: stopEvent, stopPropagation, preventDefault. If no value is set no action is performed.
 97&lt;/pre&gt;
 98     *
 99     * Usage:
100     * &lt;pre&gt;&lt;code&gt;
101// Create a KeyMap
102var map = new Ext.util.KeyMap(document, {
103    key: Ext.EventObject.ENTER,
104    fn: handleKey,
105    scope: this
106});
107
108//Add a new binding to the existing KeyMap later
109map.addBinding({
110    key: 'abc',
111    shift: true,
112    fn: handleKey,
113    scope: this
114});
115&lt;/code&gt;&lt;/pre&gt;
116     * @param {Object/Object[]} binding A single KeyMap config or an array of configs
117     */
118    addBinding : function(binding){
119        if (Ext.isArray(binding)) {
120            Ext.each(binding, this.addBinding, this);
121            return;
122        }
123
124        var keyCode = binding.key,
125            processed = false,
126            key,
127            keys,
128            keyString,
129            i,
130            len;
131
132        if (Ext.isString(keyCode)) {
133            keys = [];
134            keyString = keyCode.toUpperCase();
135
136            for (i = 0, len = keyString.length; i &lt; len; ++i){
137                keys.push(keyString.charCodeAt(i));
138            }
139            keyCode = keys;
140            processed = true;
141        }
142
143        if (!Ext.isArray(keyCode)) {
144            keyCode = [keyCode];
145        }
146
147        if (!processed) {
148            for (i = 0, len = keyCode.length; i &lt; len; ++i) {
149                key = keyCode[i];
150                if (Ext.isString(key)) {
151                    keyCode[i] = key.toUpperCase().charCodeAt(0);
152                }
153            }
154        }
155
156        this.bindings.push(Ext.apply({
157            keyCode: keyCode
158        }, binding));
159    },
160
161<span id='Ext-util-KeyMap-method-handleKeyDown'>    /**
162</span>     * Process any keydown events on the element
163     * @private
164     * @param {Ext.EventObject} event
165     */
166    handleKeyDown: function(event) {
167        if (this.enabled) { //just in case
168            var bindings = this.bindings,
169                i = 0,
170                len = bindings.length;
171
172            event = this.processEvent(event);
173            for(; i &lt; len; ++i){
174                this.processBinding(bindings[i], event);
175            }
176        }
177    },
178
179<span id='Ext-util-KeyMap-method-processEvent'>    /**
180</span>     * Ugly hack to allow this class to be tested. Currently WebKit gives
181     * no way to raise a key event properly with both
182     * a) A keycode
183     * b) The alt/ctrl/shift modifiers
184     * So we have to simulate them here. Yuk!
185     * This is a stub method intended to be overridden by tests.
186     * More info: https://bugs.webkit.org/show_bug.cgi?id=16735
187     * @private
188     */
189    processEvent: function(event){
190        return event;
191    },
192
193<span id='Ext-util-KeyMap-method-processBinding'>    /**
194</span>     * Process a particular binding and fire the handler if necessary.
195     * @private
196     * @param {Object} binding The binding information
197     * @param {Ext.EventObject} event
198     */
199    processBinding: function(binding, event){
200        if (this.checkModifiers(binding, event)) {
201            var key = event.getKey(),
202                handler = binding.fn || binding.handler,
203                scope = binding.scope || this,
204                keyCode = binding.keyCode,
205                defaultEventAction = binding.defaultEventAction,
206                i,
207                len,
208                keydownEvent = new Ext.EventObjectImpl(event);
209
210
211            for (i = 0, len = keyCode.length; i &lt; len; ++i) {
212                if (key === keyCode[i]) {
213                    if (handler.call(scope, key, event) !== true &amp;&amp; defaultEventAction) {
214                        keydownEvent[defaultEventAction]();
215                    }
216                    break;
217                }
218            }
219        }
220    },
221
222<span id='Ext-util-KeyMap-method-checkModifiers'>    /**
223</span>     * Check if the modifiers on the event match those on the binding
224     * @private
225     * @param {Object} binding
226     * @param {Ext.EventObject} event
227     * @return {Boolean} True if the event matches the binding
228     */
229    checkModifiers: function(binding, e){
230        var keys = ['shift', 'ctrl', 'alt'],
231            i = 0,
232            len = keys.length,
233            val, key;
234
235        for (; i &lt; len; ++i){
236            key = keys[i];
237            val = binding[key];
238            if (!(val === undefined || (val === e[key + 'Key']))) {
239                return false;
240            }
241        }
242        return true;
243    },
244
245<span id='Ext-util-KeyMap-method-on'>    /**
246</span>     * Shorthand for adding a single key listener
247     * @param {Number/Number[]/Object} key Either the numeric key code, array of key codes or an object with the
248     * following options:
249     * {key: (number or array), shift: (true/false), ctrl: (true/false), alt: (true/false)}
250     * @param {Function} fn The function to call
251     * @param {Object} scope (optional) The scope (&lt;code&gt;this&lt;/code&gt; reference) in which the function is executed. Defaults to the browser window.
252     */
253    on: function(key, fn, scope) {
254        var keyCode, shift, ctrl, alt;
255        if (Ext.isObject(key) &amp;&amp; !Ext.isArray(key)) {
256            keyCode = key.key;
257            shift = key.shift;
258            ctrl = key.ctrl;
259            alt = key.alt;
260        } else {
261            keyCode = key;
262        }
263        this.addBinding({
264            key: keyCode,
265            shift: shift,
266            ctrl: ctrl,
267            alt: alt,
268            fn: fn,
269            scope: scope
270        });
271    },
272
273<span id='Ext-util-KeyMap-method-isEnabled'>    /**
274</span>     * Returns true if this KeyMap is enabled
275     * @return {Boolean}
276     */
277    isEnabled : function(){
278        return this.enabled;
279    },
280
281<span id='Ext-util-KeyMap-method-enable'>    /**
282</span>     * Enables this KeyMap
283     */
284    enable: function(){
285        var me = this;
286        
287        if (!me.enabled) {
288            me.el.on(me.eventName, me.handleKeyDown, me);
289            me.enabled = true;
290        }
291    },
292
293<span id='Ext-util-KeyMap-method-disable'>    /**
294</span>     * Disable this KeyMap
295     */
296    disable: function(){
297        var me = this;
298        
299        if (me.enabled) {
300            me.el.removeListener(me.eventName, me.handleKeyDown, me);
301            me.enabled = false;
302        }
303    },
304
305<span id='Ext-util-KeyMap-method-setDisabled'>    /**
306</span>     * Convenience function for setting disabled/enabled by boolean.
307     * @param {Boolean} disabled
308     */
309    setDisabled : function(disabled){
310        if (disabled) {
311            this.disable();
312        } else {
313            this.enable();
314        }
315    },
316
317<span id='Ext-util-KeyMap-method-destroy'>    /**
318</span>     * Destroys the KeyMap instance and removes all handlers.
319     * @param {Boolean} removeEl True to also remove the attached element
320     */
321    destroy: function(removeEl){
322        var me = this;
323
324        me.bindings = [];
325        me.disable();
326        if (removeEl === true) {
327            me.el.remove();
328        }
329        delete me.el;
330    }
331});</pre>
332</body>
333</html>