[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/event-key/ -> event-key.js (source)

   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"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1