UNPKG

wed

Version:

Wed is a schema-aware editor for XML documents.

321 lines 13.6 kB
/** * Module implementing an class that describes keyboard keys. * @author Louis-Dominique Dubeau * @license MPL 2.0 * @copyright Mangalam Research Center for Buddhist Languages */ var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; define(["require", "exports", "./browsers", "jquery"], function (require, exports, browsers) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); browsers = __importStar(browsers); let id = 0; // tslint:disable-next-line:completed-docs class-name class EITHER_ { toString() { return "EITHER"; } } exports.EITHER_ = EITHER_; /** * Value meaning "either true or false", by opposition to ``true`` and * ``false``. */ exports.EITHER = new EITHER_(); /** * One and only one instance of a Key object exists per set of parameters used * for its construction. So if ``a = new Key(1, 2, 3)`` and ``b = new Key(1, 2, * 3)`` then ``a === b`` is true. The last three parameters are normalized to * boolean values, so ``new Key(1, 2, 3)`` is the same as ``new Key(1, 2, 3, * false, false, false)``. * * Key objects should be considered immutable. Modifying them after their * creation is likely to cause code to execute erratically. * * A note on the handling of the shift key. For key presses, we do not care * whether shift was held or not when the key was pressed. It does not matter to * us whether the user types the letter A because "Shift-a" was pressed or * because the user was in caps lock mode and pressed "a". Conversely, * ``keydown`` and ``keyup`` events concern themselves with Shift. We do want to * distinguish Ctrl-A and Ctrl-Shift-A. (Yes, we use the capital A for both: * browsers report that the key "A" was pressed whether Shift was held or not.) */ class Key { /** * @param hashKey The unique hash which represents this key. * * @param which The character code of the key. * * @param keypress Whether this key is meant to be used for keypress events * rather than keyup and keydown. * * @param keyCode The key code of the key. * * @param charCode The character code of the key. * * @param ctrlKey Whether this key requires the Ctrl key held. * * @param altKey Whether this key requires the Alt key held. * * @param metaKey Whether this key requires the meta key held. * * @param shiftKey Whether this key requires the shift key held. It is invalid * to use this parameter if ``keypress`` is ``true``. When ``keypress`` is * ``false``, an unspecified value here means ``false``. */ constructor(hashKey, which, keypress = true, keyCode, charCode = 0, ctrlKey = false, altKey = false, metaKey = false, shiftKey = exports.EITHER) { if (keypress) { if (shiftKey !== exports.EITHER) { throw new Error("shiftKey with key presses must be EITHER"); } } this.which = which; this.keyCode = keyCode; this.charCode = charCode; this.ctrlKey = ctrlKey; this.altKey = altKey; this.metaKey = metaKey; this.shiftKey = shiftKey; this.keypress = keypress; this.hashKey = hashKey; this.id = id++; } /** * Client code should use the convenience functions provided by this module to * create keys rather than use this function directly. * * @param which The character code of the key. * * @param keypress Whether this key is meant to be used for keypress events * rather than keyup and keydown. * * @param keyCode The key code of the key. * * @param charCode The character code of the key. * * @param ctrlKey Whether this key requires the Ctrl key held. * * @param altKey Whether this key requires the Alt key held. * * @param metaKey Whether this key requires the meta key held. * * @param shiftKey Whether this key requires the shift key held. It is invalid * to use this parameter if ``keypress`` is ``true``. When ``keypress`` is * ``false``, an unspecified value here means ``false``. * * @returns The key corresponding to the parameters. */ static make(which, keypress = true, keyCode, charCode = 0, ctrlKey = false, altKey = false, metaKey = false, shiftKey = exports.EITHER) { // Some separator is necessary because otherwise there would be no way to // distinguish (1, 23, 4, ...) from (12, 3, 4, ...) or (1, 2, 34, ...). const key = [which, keyCode, charCode, ctrlKey, altKey, metaKey, shiftKey, keypress].join(","); // Ensure we have only one of each key created. let cached = Key.__cache[key]; if (cached === undefined) { Key.__cache[key] = cached = new Key(key, which, keypress, keyCode, charCode, ctrlKey, altKey, metaKey, shiftKey); } return cached; } /** * This method compares the key object to an event object. The event object * should have been generated for a keyboard event. This method does not check * the type of object. * * @param ev A jQuery or DOM event object. * @returns True if the key object matches the event, false * otherwise. */ matchesEvent(ev) { return ev.which === this.which && ev.keyCode === this.keyCode && ev.charCode === this.charCode && ev.ctrlKey === this.ctrlKey && ev.altKey === this.altKey && ev.metaKey === this.metaKey && // If shiftKey is undefined, we don't compare it. ((this.shiftKey === exports.EITHER) || (ev.shiftKey === this.shiftKey)) && (this.keypress ? (ev.type === "keypress") : ((ev.type === "keydown") || (ev.type === "keyup"))); } /** * Sets an event object so that it matches this key. If this is not a keypress * event, the event type will be set to keydown. The caller can set it to * keyup as needed. * * @param ev A jQuery or DOM event object. This object is modified by the * method. */ setEventToMatch(ev) { // tslint:disable-next-line:no-any const asAny = ev; asAny.which = this.which; asAny.keyCode = this.keyCode; asAny.charCode = this.charCode; asAny.ctrlKey = this.ctrlKey; asAny.altKey = this.altKey; asAny.metaKey = this.metaKey; if (this.shiftKey !== exports.EITHER) { asAny.shiftKey = this.shiftKey; } if (this.keypress) { asAny.type = "keypress"; } else { asAny.type = "keydown"; } } /** * The uniqueness of the return value this method returns is guaranteed only * per module instance, which generally translates to "per JavaScript * execution context". For instance, if this code is loaded in two different * browser pages, the module will be instantiated once per page and the return * values for Key objects that were created with the same parameters might * differ. So if these two pages communicate with one another they cannot use * the return value of this method to identify objects. * * @returns A hash value that uniquely identifies the object. The value should * be considered to be opaque. */ hash() { return this.id; } /** * @returns True if any modifiers are turned on for this key. False * otherwise. Shift is not considered a modifier for our purposes. */ anyModifier() { return this.ctrlKey || this.altKey || this.metaKey; } } // tslint:disable-next-line:variable-name Key.__cache = Object.create(null); exports.Key = Key; /** This is a [[Key]] that cannot match anything. */ exports.NULL_KEY = Key.make(-1, false, -1); /** * This function creates a key object. * * @param which This parameter can be a string of length one which contains the * character for which we want to create a Key. If a number, it is the character * code of the key. * * @param keypress Whether this key is meant to be used for keypress events * rather than keyup and keydown. * * @param keyCode The key code of the key. * * @param charCode The character code of the key. * * @param ctrlKey Whether this key requires the Ctrl key held. * * @param altKey Whether this key requires the Alt key held. * * @param metaKey Whether this key requires the meta key held. * * @param shiftKey Whether this key requires the shift key held. It is invalid * to use this parameter if ``keypress`` is ``true``. * * @returns The key created. * * @throws {Error} If ``which`` is not a single character string or a number. */ function makeKey(which, keypress = true, keyCode, charCode, ctrlKey = false, altKey = false, metaKey = false, shiftKey = exports.EITHER) { if (typeof (which) === "string") { if (which.length !== 1) { throw new Error("when the first parameter is a string, " + "a one-character string is required"); } which = which.charCodeAt(0); } else if (typeof (which) !== "number") { throw new Error("the first parameter must be a string or number"); } if (keypress === undefined) { keypress = true; } else { keypress = !!keypress; } if (keyCode == null) { keyCode = (keypress && browsers.GECKO) ? 0 : which; } if (charCode == null) { charCode = keypress ? which : 0; } // Normalize ctrlKey = !!ctrlKey; altKey = !!altKey; metaKey = !!metaKey; if (shiftKey !== exports.EITHER) { shiftKey = !!shiftKey; } return Key.make(which, keypress, keyCode, charCode, ctrlKey, altKey, metaKey, shiftKey); } exports.makeKey = makeKey; /** * This function creates a key object which represents a control character (a * character typed while Ctrl is held). * * @param ch This parameter can be a string of length one which contains the * character for which we want to create a Key. If a number, it is the character * code of the key. * * @param shiftKey Whether this is a Ctrl-Shift sequence or not. * * @returns The key created. */ function makeCtrlKey(ch, shiftKey = exports.EITHER) { return makeKey(ch, false, undefined, undefined, true, false, false, shiftKey); } exports.makeCtrlKey = makeCtrlKey; /** * This function creates a key object which represents a meta character (a * character typed while Meta is held). * * @param ch This parameter can be a string of length one which contains the * character for which we want to create a Key. If a number, it is the character * code of the key. * * @param shiftKey Whether this is a Meta-Shift sequence or not. * * @returns The key created. */ function makeMetaKey(ch, shiftKey = exports.EITHER) { return makeKey(ch, false, undefined, undefined, false, false, true, shiftKey); } exports.makeMetaKey = makeMetaKey; /** * This function creates a key object which represents a "control equivalent" * character. A "control equivalent" is equivalent to a control key on all * platforms, except in OS X where it is equivalent to a command key. That is if * one makes a "control equivalent" with the character "X", then on all * platforms it would be equivalent to hitting Ctrl-X, except in OS X where it * is equivalent to hitting Command-X. * * @param ch This parameter can be a string of length one which contains the * character for which we want to create a Key. If a number, it is the character * code of the key. * * @param shiftKey Whether this is a [...]-Shift sequence or not. * * @returns The key created. */ function makeCtrlEqKey(ch, shiftKey = exports.EITHER) { if (!browsers.OSX) { return makeCtrlKey(ch, shiftKey); } // Command === Meta return makeMetaKey(ch, shiftKey); } exports.makeCtrlEqKey = makeCtrlEqKey; }); // LocalWords: jQuery keydown keypress boolean Dubeau MPL Mangalam DOM Ctrl // LocalWords: keyup param keyCode charcode ctrlKey altKey metaKey shiftKey //# sourceMappingURL=key.js.map