3f3aa287185afb5d48d7ef0717054a154c372dc9Adam Moore * Functionality to listen for one or more specific key combinations.
3f3aa287185afb5d48d7ef0717054a154c372dc9Adam Moore * @module event
3f3aa287185afb5d48d7ef0717054a154c372dc9Adam Moore * @submodule event-key
cd9e4415b30cf09a761815cd149ec546ecc1231cLuke Smith _keysRE: /^(?:up|down|press):|\+(alt|ctrl|meta|shift)/g,
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith mods = Y.Array.hash(spec.match(/\+(?:alt|ctrl|meta|shift)\b/g) || []),
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith type: this._typeRE.test(spec) ? RegExp.$1 : null,
cd9e4415b30cf09a761815cd149ec546ecc1231cLuke Smith // strip type and modifiers from spec, leaving only keyCodes
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith // FIXME: need to support '65,esc' => keypress, keydown
cd9e4415b30cf09a761815cd149ec546ecc1231cLuke Smith // catch sloppy filters, trailing commas, etc 'a,,'
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith // non-numerics are single characters or key names
cd9e4415b30cf09a761815cd149ec546ecc1231cLuke Smith // FIXME: '65,enter' defaults keydown for both
1e30edb58f369ad5c54c33dc7d06d468bc5232b7Luke Smith // FIXME: Character mapping only works for keypress
1e30edb58f369ad5c54c33dc7d06d468bc5232b7Luke Smith // events. Otherwise, it uses String.fromCharCode()
1e30edb58f369ad5c54c33dc7d06d468bc5232b7Luke Smith // from the keyCode, which is wrong.
1e30edb58f369ad5c54c33dc7d06d468bc5232b7Luke Smith // FIXME: stupid assumption that
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith // the keycode of the lower case == the
1e30edb58f369ad5c54c33dc7d06d468bc5232b7Luke Smith // charCode of the upper case
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith // a (key:65,char:97), A (key:65,char:65)
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith // upper case chars get +shift free
cd9e4415b30cf09a761815cd149ec546ecc1231cLuke Smith // Note: without specifying any keyCodes, this becomes a
cd9e4415b30cf09a761815cd149ec546ecc1231cLuke Smith // horribly inefficient alias for 'keydown' (et al), but I
cd9e4415b30cf09a761815cd149ec546ecc1231cLuke Smith // can't abort this subscription for a simple
cd9e4415b30cf09a761815cd149ec546ecc1231cLuke Smith // Y.on('keypress', ...);
cd9e4415b30cf09a761815cd149ec546ecc1231cLuke Smith // Please use keyCodes or just subscribe directly to keydown,
cd9e4415b30cf09a761815cd149ec546ecc1231cLuke Smith // keyup, or keypress
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <p>Add a key listener. The listener will only be notified if the
5af2618af73bd3f008ef0e9b5f982f560c64059bAdam Moore * keystroke detected meets the supplied specification. The
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * specification is a string that is defined as:</p>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <dt>spec</dt>
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove * <dd><code>[{type}:]{code}[,{code}]*</code></dd>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <dt>type</dt>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <dd><code>"down", "up", or "press"</code></dd>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <dt>code</dt>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <dd><code>{keyCode|character|keyName}[+{modifier}]*</code></dd>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <dt>modifier</dt>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <dd><code>"shift", "ctrl", "alt", or "meta"</code></dd>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <dt>keyName</dt>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <dd><code>"enter", "backspace", "esc", "tab", "pageup", or "pagedown"</code></dd>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <p>Examples:</p>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <li><code>Y.on("key", callback, "press:12,65+shift+ctrl", "#my-input");</code></li>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <li><code>Y.delegate("key", preventSubmit, "enter", "#forms", "input[type=text]");</code></li>
b839e41217a63e244d65c3aadf54feec82ddd179Luke Smith * <li><code>Y.one("doc").on("key", viNav, "j,k,l,;");</code></li>
5af2618af73bd3f008ef0e9b5f982f560c64059bAdam Moore * @event key
5af2618af73bd3f008ef0e9b5f982f560c64059bAdam Moore * @param type {string} 'key'
537e74c4e869b8efba925d0e37c0a5636203a23bAdam Moore * @param fn {function} the function to execute
537e74c4e869b8efba925d0e37c0a5636203a23bAdam Moore * @param id {string|HTMLElement|collection} the element(s) to bind
5af2618af73bd3f008ef0e9b5f982f560c64059bAdam Moore * @param spec {string} the keyCode and modifier specification
5af2618af73bd3f008ef0e9b5f982f560c64059bAdam Moore * @param o optional context object
537e74c4e869b8efba925d0e37c0a5636203a23bAdam Moore * @param args 0..n additional arguments to provide to the listener.
5af2618af73bd3f008ef0e9b5f982f560c64059bAdam Moore * @return {Event.Handle} the detach handle