~ubuntu-branches/ubuntu/utopic/moodle/utopic

« back to all changes in this revision

Viewing changes to lib/yuilib/3.13.0/event-key/event-key.js

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2014-05-12 16:10:38 UTC
  • mfrom: (36.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20140512161038-puyqf65k4e0s8ytz
Tags: 2.6.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
YUI 3.13.0 (build 508226d)
 
3
Copyright 2013 Yahoo! Inc. All rights reserved.
 
4
Licensed under the BSD License.
 
5
http://yuilibrary.com/license/
 
6
*/
 
7
 
 
8
YUI.add('event-key', function (Y, NAME) {
 
9
 
 
10
/**
 
11
 * Functionality to listen for one or more specific key combinations.
 
12
 * @module event
 
13
 * @submodule event-key
 
14
 */
 
15
 
 
16
var ALT      = "+alt",
 
17
    CTRL     = "+ctrl",
 
18
    META     = "+meta",
 
19
    SHIFT    = "+shift",
 
20
 
 
21
    trim     = Y.Lang.trim,
 
22
 
 
23
    eventDef = {
 
24
        KEY_MAP: {
 
25
            enter    : 13,
 
26
            esc      : 27,
 
27
            backspace: 8,
 
28
            tab      : 9,
 
29
            pageup   : 33,
 
30
            pagedown : 34
 
31
        },
 
32
 
 
33
        _typeRE: /^(up|down|press):/,
 
34
        _keysRE: /^(?:up|down|press):|\+(alt|ctrl|meta|shift)/g,
 
35
 
 
36
        processArgs: function (args) {
 
37
            var spec = args.splice(3,1)[0],
 
38
                mods = Y.Array.hash(spec.match(/\+(?:alt|ctrl|meta|shift)\b/g) || []),
 
39
                config = {
 
40
                    type: this._typeRE.test(spec) ? RegExp.$1 : null,
 
41
                    mods: mods,
 
42
                    keys: null
 
43
                },
 
44
                // strip type and modifiers from spec, leaving only keyCodes
 
45
                bits = spec.replace(this._keysRE, ''),
 
46
                chr, uc, lc, i;
 
47
 
 
48
            if (bits) {
 
49
                bits = bits.split(',');
 
50
 
 
51
                config.keys = {};
 
52
 
 
53
                // FIXME: need to support '65,esc' => keypress, keydown
 
54
                for (i = bits.length - 1; i >= 0; --i) {
 
55
                    chr = trim(bits[i]);
 
56
 
 
57
                    // catch sloppy filters, trailing commas, etc 'a,,'
 
58
                    if (!chr) {
 
59
                        continue;
 
60
                    }
 
61
 
 
62
                    // non-numerics are single characters or key names
 
63
                    if (+chr == chr) {
 
64
                        config.keys[chr] = mods;
 
65
                    } else {
 
66
                        lc = chr.toLowerCase();
 
67
 
 
68
                        if (this.KEY_MAP[lc]) {
 
69
                            config.keys[this.KEY_MAP[lc]] = mods;
 
70
                            // FIXME: '65,enter' defaults keydown for both
 
71
                            if (!config.type) {
 
72
                                config.type = "down"; // safest
 
73
                            }
 
74
                        } else {
 
75
                            // FIXME: Character mapping only works for keypress
 
76
                            // events. Otherwise, it uses String.fromCharCode()
 
77
                            // from the keyCode, which is wrong.
 
78
                            chr = chr.charAt(0);
 
79
                            uc  = chr.toUpperCase();
 
80
 
 
81
                            if (mods["+shift"]) {
 
82
                                chr = uc;
 
83
                            }
 
84
 
 
85
                            // FIXME: stupid assumption that
 
86
                            // the keycode of the lower case == the
 
87
                            // charCode of the upper case
 
88
                            // a (key:65,char:97), A (key:65,char:65)
 
89
                            config.keys[chr.charCodeAt(0)] =
 
90
                                (chr === uc) ?
 
91
                                    // upper case chars get +shift free
 
92
                                    Y.merge(mods, { "+shift": true }) :
 
93
                                    mods;
 
94
                        }
 
95
                    }
 
96
                }
 
97
            }
 
98
 
 
99
            if (!config.type) {
 
100
                config.type = "press";
 
101
            }
 
102
 
 
103
            return config;
 
104
        },
 
105
 
 
106
        on: function (node, sub, notifier, filter) {
 
107
            var spec   = sub._extra,
 
108
                type   = "key" + spec.type,
 
109
                keys   = spec.keys,
 
110
                method = (filter) ? "delegate" : "on";
 
111
 
 
112
            // Note: without specifying any keyCodes, this becomes a
 
113
            // horribly inefficient alias for 'keydown' (et al), but I
 
114
            // can't abort this subscription for a simple
 
115
            // Y.on('keypress', ...);
 
116
            // Please use keyCodes or just subscribe directly to keydown,
 
117
            // keyup, or keypress
 
118
            sub._detach = node[method](type, function (e) {
 
119
                var key = keys ? keys[e.which] : spec.mods;
 
120
 
 
121
                if (key &&
 
122
                    (!key[ALT]   || (key[ALT]   && e.altKey)) &&
 
123
                    (!key[CTRL]  || (key[CTRL]  && e.ctrlKey)) &&
 
124
                    (!key[META]  || (key[META]  && e.metaKey)) &&
 
125
                    (!key[SHIFT] || (key[SHIFT] && e.shiftKey)))
 
126
                {
 
127
                    notifier.fire(e);
 
128
                }
 
129
            }, filter);
 
130
        },
 
131
 
 
132
        detach: function (node, sub, notifier) {
 
133
            sub._detach.detach();
 
134
        }
 
135
    };
 
136
 
 
137
eventDef.delegate = eventDef.on;
 
138
eventDef.detachDelegate = eventDef.detach;
 
139
 
 
140
/**
 
141
 * <p>Add a key listener.  The listener will only be notified if the
 
142
 * keystroke detected meets the supplied specification.  The
 
143
 * specification is a string that is defined as:</p>
 
144
 *
 
145
 * <dl>
 
146
 *   <dt>spec</dt>
 
147
 *   <dd><code>[{type}:]{code}[,{code}]*</code></dd>
 
148
 *   <dt>type</dt>
 
149
 *   <dd><code>"down", "up", or "press"</code></dd>
 
150
 *   <dt>code</dt>
 
151
 *   <dd><code>{keyCode|character|keyName}[+{modifier}]*</code></dd>
 
152
 *   <dt>modifier</dt>
 
153
 *   <dd><code>"shift", "ctrl", "alt", or "meta"</code></dd>
 
154
 *   <dt>keyName</dt>
 
155
 *   <dd><code>"enter", "backspace", "esc", "tab", "pageup", or "pagedown"</code></dd>
 
156
 * </dl>
 
157
 *
 
158
 * <p>Examples:</p>
 
159
 * <ul>
 
160
 *   <li><code>Y.on("key", callback, "press:12,65+shift+ctrl", "#my-input");</code></li>
 
161
 *   <li><code>Y.delegate("key", preventSubmit, "#forms", "enter", "input[type=text]");</code></li>
 
162
 *   <li><code>Y.one("doc").on("key", viNav, "j,k,l,;");</code></li>
 
163
 * </ul>
 
164
 *
 
165
 * @event key
 
166
 * @for YUI
 
167
 * @param type {string} 'key'
 
168
 * @param fn {function} the function to execute
 
169
 * @param id {string|HTMLElement|collection} the element(s) to bind
 
170
 * @param spec {string} the keyCode and modifier specification
 
171
 * @param o optional context object
 
172
 * @param args 0..n additional arguments to provide to the listener.
 
173
 * @return {Event.Handle} the detach handle
 
174
 */
 
175
Y.Event.define('key', eventDef, true);
 
176
 
 
177
 
 
178
}, '3.13.0', {"requires": ["event-synthetic"]});