J   14

Untitled

Guest on 24th May 2021 03:35:06 AM

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

Raw Paste


Login or Register to edit or fork this paste. It's free.