зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1350646: Part 7 - Remove SDK hotkey modules. r=Mossop
MozReview-Commit-ID: JJunKMZwspb --HG-- extra : source : d914c050c9650fb677f6868abf62a84c56e81849
This commit is contained in:
Родитель
fed32bf06a
Коммит
c6d1dd7f89
|
@ -68,7 +68,6 @@ modules = [
|
||||||
'sdk/deprecated/window-utils.js',
|
'sdk/deprecated/window-utils.js',
|
||||||
'sdk/dom/events-shimmed.js',
|
'sdk/dom/events-shimmed.js',
|
||||||
'sdk/dom/events.js',
|
'sdk/dom/events.js',
|
||||||
'sdk/dom/events/keys.js',
|
|
||||||
'sdk/event/chrome.js',
|
'sdk/event/chrome.js',
|
||||||
'sdk/event/core.js',
|
'sdk/event/core.js',
|
||||||
'sdk/event/dom.js',
|
'sdk/event/dom.js',
|
||||||
|
@ -76,7 +75,6 @@ modules = [
|
||||||
'sdk/event/utils.js',
|
'sdk/event/utils.js',
|
||||||
'sdk/frame/utils.js',
|
'sdk/frame/utils.js',
|
||||||
'sdk/fs/path.js',
|
'sdk/fs/path.js',
|
||||||
'sdk/hotkeys.js',
|
|
||||||
'sdk/indexed-db.js',
|
'sdk/indexed-db.js',
|
||||||
'sdk/io/buffer.js',
|
'sdk/io/buffer.js',
|
||||||
'sdk/io/byte-streams.js',
|
'sdk/io/byte-streams.js',
|
||||||
|
@ -84,9 +82,6 @@ modules = [
|
||||||
'sdk/io/fs.js',
|
'sdk/io/fs.js',
|
||||||
'sdk/io/stream.js',
|
'sdk/io/stream.js',
|
||||||
'sdk/io/text-streams.js',
|
'sdk/io/text-streams.js',
|
||||||
'sdk/keyboard/hotkeys.js',
|
|
||||||
'sdk/keyboard/observer.js',
|
|
||||||
'sdk/keyboard/utils.js',
|
|
||||||
'sdk/l10n.js',
|
'sdk/l10n.js',
|
||||||
'sdk/l10n/core.js',
|
'sdk/l10n/core.js',
|
||||||
'sdk/l10n/html.js',
|
'sdk/l10n/html.js',
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
module.metadata = {
|
|
||||||
"stability": "unstable"
|
|
||||||
};
|
|
||||||
|
|
||||||
const { emit } = require("../events");
|
|
||||||
const { getCodeForKey, toJSON } = require("../../keyboard/utils");
|
|
||||||
const { has } = require("../../util/array");
|
|
||||||
const { isString } = require("../../lang/type");
|
|
||||||
|
|
||||||
const INITIALIZER = "initKeyEvent";
|
|
||||||
const CATEGORY = "KeyboardEvent";
|
|
||||||
|
|
||||||
function Options(options) {
|
|
||||||
if (!isString(options))
|
|
||||||
return options;
|
|
||||||
|
|
||||||
var { key, modifiers } = toJSON(options);
|
|
||||||
return {
|
|
||||||
key: key,
|
|
||||||
control: has(modifiers, "control"),
|
|
||||||
alt: has(modifiers, "alt"),
|
|
||||||
shift: has(modifiers, "shift"),
|
|
||||||
meta: has(modifiers, "meta")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var keyEvent = exports.keyEvent = function keyEvent(element, type, options) {
|
|
||||||
|
|
||||||
emit(element, type, {
|
|
||||||
initializer: INITIALIZER,
|
|
||||||
category: CATEGORY,
|
|
||||||
settings: [
|
|
||||||
!("bubbles" in options) || options.bubbles !== false,
|
|
||||||
!("cancelable" in options) || options.cancelable !== false,
|
|
||||||
"window" in options && options.window ? options.window : null,
|
|
||||||
"control" in options && !!options.control,
|
|
||||||
"alt" in options && !!options.alt,
|
|
||||||
"shift" in options && !!options.shift,
|
|
||||||
"meta" in options && !!options.meta,
|
|
||||||
getCodeForKey(options.key) || 0,
|
|
||||||
options.key.length === 1 ? options.key.charCodeAt(0) : 0
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.keyDown = function keyDown(element, options) {
|
|
||||||
keyEvent(element, "keydown", Options(options));
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.keyUp = function keyUp(element, options) {
|
|
||||||
keyEvent(element, "keyup", Options(options));
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.keyPress = function keyPress(element, options) {
|
|
||||||
keyEvent(element, "keypress", Options(options));
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
module.metadata = {
|
|
||||||
"stability": "stable"
|
|
||||||
};
|
|
||||||
|
|
||||||
const INVALID_HOTKEY = "Hotkey must have at least one modifier.";
|
|
||||||
|
|
||||||
const { toJSON: jsonify, toString: stringify,
|
|
||||||
isFunctionKey } = require("./keyboard/utils");
|
|
||||||
const { register, unregister } = require("./keyboard/hotkeys");
|
|
||||||
|
|
||||||
const Hotkey = exports.Hotkey = function Hotkey(options) {
|
|
||||||
if (!(this instanceof Hotkey))
|
|
||||||
return new Hotkey(options);
|
|
||||||
|
|
||||||
// Parsing key combination string.
|
|
||||||
let hotkey = jsonify(options.combo);
|
|
||||||
if (!isFunctionKey(hotkey.key) && !hotkey.modifiers.length) {
|
|
||||||
throw new TypeError(INVALID_HOTKEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.onPress = options.onPress && options.onPress.bind(this);
|
|
||||||
this.toString = stringify.bind(null, hotkey);
|
|
||||||
// Registering listener on keyboard combination enclosed by this hotkey.
|
|
||||||
// Please note that `this.toString()` is a normalized version of
|
|
||||||
// `options.combination` where order of modifiers is sorted and `accel` is
|
|
||||||
// replaced with platform specific key.
|
|
||||||
register(this.toString(), this.onPress);
|
|
||||||
// We freeze instance before returning it in order to make it's properties
|
|
||||||
// read-only.
|
|
||||||
return Object.freeze(this);
|
|
||||||
};
|
|
||||||
Hotkey.prototype.destroy = function destroy() {
|
|
||||||
unregister(this.toString(), this.onPress);
|
|
||||||
};
|
|
|
@ -1,110 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
module.metadata = {
|
|
||||||
"stability": "unstable"
|
|
||||||
};
|
|
||||||
|
|
||||||
const { observer: keyboardObserver } = require("./observer");
|
|
||||||
const { getKeyForCode, normalize, isFunctionKey,
|
|
||||||
MODIFIERS } = require("./utils");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a global `hotkey` that executes `listener` when the key combination
|
|
||||||
* in `hotkey` is pressed. If more then one `listener` is registered on the same
|
|
||||||
* key combination only last one will be executed.
|
|
||||||
*
|
|
||||||
* @param {string} hotkey
|
|
||||||
* Key combination in the format of 'modifier key'.
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
*
|
|
||||||
* "accel s"
|
|
||||||
* "meta shift i"
|
|
||||||
* "control alt d"
|
|
||||||
*
|
|
||||||
* Modifier keynames:
|
|
||||||
*
|
|
||||||
* - **shift**: The Shift key.
|
|
||||||
* - **alt**: The Alt key. On the Macintosh, this is the Option key. On
|
|
||||||
* Macintosh this can only be used in conjunction with another modifier,
|
|
||||||
* since `Alt+Letter` combinations are reserved for entering special
|
|
||||||
* characters in text.
|
|
||||||
* - **meta**: The Meta key. On the Macintosh, this is the Command key.
|
|
||||||
* - **control**: The Control key.
|
|
||||||
* - **accel**: The key used for keyboard shortcuts on the user's platform,
|
|
||||||
* which is Control on Windows and Linux, and Command on Mac. Usually, this
|
|
||||||
* would be the value you would use.
|
|
||||||
*
|
|
||||||
* @param {function} listener
|
|
||||||
* Function to execute when the `hotkey` is executed.
|
|
||||||
*/
|
|
||||||
exports.register = function register(hotkey, listener) {
|
|
||||||
hotkey = normalize(hotkey);
|
|
||||||
hotkeys[hotkey] = listener;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregister a global `hotkey`. If passed `listener` is not the one registered
|
|
||||||
* for the given `hotkey`, the call to this function will be ignored.
|
|
||||||
*
|
|
||||||
* @param {string} hotkey
|
|
||||||
* Key combination in the format of 'modifier key'.
|
|
||||||
* @param {function} listener
|
|
||||||
* Function that will be invoked when the `hotkey` is pressed.
|
|
||||||
*/
|
|
||||||
exports.unregister = function unregister(hotkey, listener) {
|
|
||||||
hotkey = normalize(hotkey);
|
|
||||||
if (hotkeys[hotkey] === listener)
|
|
||||||
delete hotkeys[hotkey];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map of hotkeys and associated functions.
|
|
||||||
*/
|
|
||||||
const hotkeys = exports.hotkeys = {};
|
|
||||||
|
|
||||||
keyboardObserver.on("keydown", function onKeypress(event, window) {
|
|
||||||
let key, modifiers = [];
|
|
||||||
let isChar = "isChar" in event && event.isChar;
|
|
||||||
let which = "which" in event ? event.which : null;
|
|
||||||
let keyCode = "keyCode" in event ? event.keyCode : null;
|
|
||||||
|
|
||||||
if ("shiftKey" in event && event.shiftKey)
|
|
||||||
modifiers.push("shift");
|
|
||||||
if ("altKey" in event && event.altKey)
|
|
||||||
modifiers.push("alt");
|
|
||||||
if ("ctrlKey" in event && event.ctrlKey)
|
|
||||||
modifiers.push("control");
|
|
||||||
if ("metaKey" in event && event.metaKey)
|
|
||||||
modifiers.push("meta");
|
|
||||||
|
|
||||||
// If it's not a printable character then we fall back to a human readable
|
|
||||||
// equivalent of one of the following constants.
|
|
||||||
// http://dxr.mozilla.org/mozilla-central/source/dom/interfaces/events/nsIDOMKeyEvent.idl
|
|
||||||
key = getKeyForCode(keyCode);
|
|
||||||
|
|
||||||
// If only non-function (f1 - f24) key or only modifiers are pressed we don't
|
|
||||||
// have a valid combination so we return immediately (Also, sometimes
|
|
||||||
// `keyCode` may be one for the modifier which means we do not have a
|
|
||||||
// modifier).
|
|
||||||
if (!key || (!isFunctionKey(key) && !modifiers.length) || key in MODIFIERS)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let combination = normalize({ key: key, modifiers: modifiers });
|
|
||||||
let hotkey = hotkeys[combination];
|
|
||||||
|
|
||||||
if (hotkey) {
|
|
||||||
try {
|
|
||||||
hotkey();
|
|
||||||
} catch (exception) {
|
|
||||||
console.exception(exception);
|
|
||||||
} finally {
|
|
||||||
// Work around bug 582052 by preventing the (nonexistent) default action.
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,57 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
module.metadata = {
|
|
||||||
"stability": "unstable"
|
|
||||||
};
|
|
||||||
|
|
||||||
const { Class } = require("../core/heritage");
|
|
||||||
const { EventTarget } = require("../event/target");
|
|
||||||
const { emit } = require("../event/core");
|
|
||||||
const { DOMEventAssembler } = require("../deprecated/events/assembler");
|
|
||||||
const { browserWindowIterator } = require('../deprecated/window-utils');
|
|
||||||
const { isBrowser } = require('../window/utils');
|
|
||||||
const { observer: windowObserver } = require("../windows/observer");
|
|
||||||
|
|
||||||
// Event emitter objects used to register listeners and emit events on them
|
|
||||||
// when they occur.
|
|
||||||
const Observer = Class({
|
|
||||||
implements: [DOMEventAssembler, EventTarget],
|
|
||||||
initialize() {
|
|
||||||
// Adding each opened window to a list of observed windows.
|
|
||||||
windowObserver.on("open", window => {
|
|
||||||
if (isBrowser(window))
|
|
||||||
this.observe(window);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Removing each closed window form the list of observed windows.
|
|
||||||
windowObserver.on("close", window => {
|
|
||||||
if (isBrowser(window))
|
|
||||||
this.ignore(window);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Making observer aware of already opened windows.
|
|
||||||
for (let window of browserWindowIterator()) {
|
|
||||||
this.observe(window);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Events that are supported and emitted by the module.
|
|
||||||
*/
|
|
||||||
supportedEventsTypes: [ "keydown", "keyup", "keypress" ],
|
|
||||||
/**
|
|
||||||
* Function handles all the supported events on all the windows that are
|
|
||||||
* observed. Method is used to proxy events to the listeners registered on
|
|
||||||
* this event emitter.
|
|
||||||
* @param {Event} event
|
|
||||||
* Keyboard event being emitted.
|
|
||||||
*/
|
|
||||||
handleEvent(event) {
|
|
||||||
emit(this, event.type, event, event.target.ownerGlobal || undefined);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
exports.observer = new Observer();
|
|
|
@ -1,189 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
module.metadata = {
|
|
||||||
"stability": "unstable"
|
|
||||||
};
|
|
||||||
|
|
||||||
const { Cc, Ci } = require("chrome");
|
|
||||||
const runtime = require("../system/runtime");
|
|
||||||
const { isString } = require("../lang/type");
|
|
||||||
const array = require("../util/array");
|
|
||||||
|
|
||||||
|
|
||||||
const SWP = "{{SEPARATOR}}";
|
|
||||||
const SEPARATOR = "-"
|
|
||||||
const INVALID_COMBINATION = "Hotkey key combination must contain one or more " +
|
|
||||||
"modifiers and only one key";
|
|
||||||
|
|
||||||
// Map of modifier key mappings.
|
|
||||||
const MODIFIERS = exports.MODIFIERS = {
|
|
||||||
'accel': runtime.OS === "Darwin" ? 'meta' : 'control',
|
|
||||||
'meta': 'meta',
|
|
||||||
'control': 'control',
|
|
||||||
'ctrl': 'control',
|
|
||||||
'option': 'alt',
|
|
||||||
'command': 'meta',
|
|
||||||
'alt': 'alt',
|
|
||||||
'shift': 'shift'
|
|
||||||
};
|
|
||||||
|
|
||||||
// Hash of key:code pairs for all the chars supported by `nsIDOMKeyEvent`.
|
|
||||||
// This is just a copy of the `nsIDOMKeyEvent` hash with normalized names.
|
|
||||||
// @See: http://dxr.mozilla.org/mozilla-central/source/dom/interfaces/events/nsIDOMKeyEvent.idl
|
|
||||||
const CODES = exports.CODES = new function Codes() {
|
|
||||||
let nsIDOMKeyEvent = Ci.nsIDOMKeyEvent;
|
|
||||||
// Names that will be substituted with a shorter analogs.
|
|
||||||
let aliases = {
|
|
||||||
'subtract': '-',
|
|
||||||
'add': '+',
|
|
||||||
'equals': '=',
|
|
||||||
'slash': '/',
|
|
||||||
'backslash': '\\',
|
|
||||||
'openbracket': '[',
|
|
||||||
'closebracket': ']',
|
|
||||||
'quote': '\'',
|
|
||||||
'backquote': '`',
|
|
||||||
'period': '.',
|
|
||||||
'semicolon': ';',
|
|
||||||
'comma': ','
|
|
||||||
};
|
|
||||||
|
|
||||||
// Normalizing keys and copying values to `this` object.
|
|
||||||
Object.keys(nsIDOMKeyEvent).filter(function(key) {
|
|
||||||
// Filter out only key codes.
|
|
||||||
return key.indexOf('DOM_VK') === 0;
|
|
||||||
}).map(function(key) {
|
|
||||||
// Map to key:values
|
|
||||||
return [ key, nsIDOMKeyEvent[key] ];
|
|
||||||
}).map(function([key, value]) {
|
|
||||||
return [ key.replace('DOM_VK_', '').replace('_', '').toLowerCase(), value ];
|
|
||||||
}).forEach(function ([ key, value ]) {
|
|
||||||
this[aliases[key] || key] = value;
|
|
||||||
}, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Inverted `CODES` hash of `code:key`.
|
|
||||||
const KEYS = exports.KEYS = new function Keys() {
|
|
||||||
Object.keys(CODES).forEach(function(key) {
|
|
||||||
this[CODES[key]] = key;
|
|
||||||
}, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.getKeyForCode = function getKeyForCode(code) {
|
|
||||||
return (code in KEYS) && KEYS[code];
|
|
||||||
};
|
|
||||||
exports.getCodeForKey = function getCodeForKey(key) {
|
|
||||||
return (key in CODES) && CODES[key];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility function that takes string or JSON that defines a `hotkey` and
|
|
||||||
* returns normalized string version of it.
|
|
||||||
* @param {JSON|String} hotkey
|
|
||||||
* @param {String} [separator=" "]
|
|
||||||
* Optional string that represents separator used to concatenate keys in the
|
|
||||||
* given `hotkey`.
|
|
||||||
* @returns {String}
|
|
||||||
* @examples
|
|
||||||
*
|
|
||||||
* require("keyboard/hotkeys").normalize("b Shift accel");
|
|
||||||
* // 'control shift b' -> on windows & linux
|
|
||||||
* // 'meta shift b' -> on mac
|
|
||||||
* require("keyboard/hotkeys").normalize("alt-d-shift", "-");
|
|
||||||
* // 'alt shift d'
|
|
||||||
*/
|
|
||||||
var normalize = exports.normalize = function normalize(hotkey, separator) {
|
|
||||||
if (!isString(hotkey))
|
|
||||||
hotkey = toString(hotkey, separator);
|
|
||||||
return toString(toJSON(hotkey, separator), separator);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Utility function that splits a string of characters that defines a `hotkey`
|
|
||||||
* into modifier keys and the defining key.
|
|
||||||
* @param {String} hotkey
|
|
||||||
* @param {String} [separator=" "]
|
|
||||||
* Optional string that represents separator used to concatenate keys in the
|
|
||||||
* given `hotkey`.
|
|
||||||
* @returns {JSON}
|
|
||||||
* @examples
|
|
||||||
*
|
|
||||||
* require("keyboard/hotkeys").toJSON("accel shift b");
|
|
||||||
* // { key: 'b', modifiers: [ 'control', 'shift' ] } -> on windows & linux
|
|
||||||
* // { key: 'b', modifiers: [ 'meta', 'shift' ] } -> on mac
|
|
||||||
*
|
|
||||||
* require("keyboard/hotkeys").normalize("alt-d-shift", "-");
|
|
||||||
* // { key: 'd', modifiers: [ 'alt', 'shift' ] }
|
|
||||||
*/
|
|
||||||
var toJSON = exports.toJSON = function toJSON(hotkey, separator) {
|
|
||||||
separator = separator || SEPARATOR;
|
|
||||||
// Since default separator is `-`, combination may take form of `alt--`. To
|
|
||||||
// avoid misbehavior we replace `--` with `-{{SEPARATOR}}` where
|
|
||||||
// `{{SEPARATOR}}` can be swapped later.
|
|
||||||
hotkey = hotkey.toLowerCase().replace(separator + separator, separator + SWP);
|
|
||||||
|
|
||||||
let value = {};
|
|
||||||
let modifiers = [];
|
|
||||||
let keys = hotkey.split(separator);
|
|
||||||
keys.forEach(function(name) {
|
|
||||||
// If name is `SEPARATOR` than we swap it back.
|
|
||||||
if (name === SWP)
|
|
||||||
name = separator;
|
|
||||||
if (name in MODIFIERS) {
|
|
||||||
array.add(modifiers, MODIFIERS[name]);
|
|
||||||
} else {
|
|
||||||
if (!value.key)
|
|
||||||
value.key = name;
|
|
||||||
else
|
|
||||||
throw new TypeError(INVALID_COMBINATION);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!value.key)
|
|
||||||
throw new TypeError(INVALID_COMBINATION);
|
|
||||||
|
|
||||||
value.modifiers = modifiers.sort();
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility function that takes object that defines a `hotkey` and returns
|
|
||||||
* string representation of it.
|
|
||||||
*
|
|
||||||
* _Please note that this function does not validates data neither it normalizes
|
|
||||||
* it, if you are unsure that data is well formed use `normalize` function
|
|
||||||
* instead.
|
|
||||||
*
|
|
||||||
* @param {JSON} hotkey
|
|
||||||
* @param {String} [separator=" "]
|
|
||||||
* Optional string that represents separator used to concatenate keys in the
|
|
||||||
* given `hotkey`.
|
|
||||||
* @returns {String}
|
|
||||||
* @examples
|
|
||||||
*
|
|
||||||
* require("keyboard/hotkeys").toString({
|
|
||||||
* key: 'b',
|
|
||||||
* modifiers: [ 'control', 'shift' ]
|
|
||||||
* }, '+');
|
|
||||||
* // 'control+shift+b
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
var toString = exports.toString = function toString(hotkey, separator) {
|
|
||||||
let keys = hotkey.modifiers.slice();
|
|
||||||
keys.push(hotkey.key);
|
|
||||||
return keys.join(separator || SEPARATOR);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility function takes `key` name and returns `true` if it's function key
|
|
||||||
* (F1, ..., F24) and `false` if it's not.
|
|
||||||
*/
|
|
||||||
var isFunctionKey = exports.isFunctionKey = function isFunctionKey(key) {
|
|
||||||
var $
|
|
||||||
return key[0].toLowerCase() === 'f' &&
|
|
||||||
($ = parseInt(key.substr(1)), 0 < $ && $ < 25);
|
|
||||||
};
|
|
Загрузка…
Ссылка в новой задаче