Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 19 additions & 29 deletions src/command-event.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS206: Consider reworking classes to avoid initClass
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
// This custom subclass of CustomEvent exists to provide the ::abortKeyBinding
// method, as well as versions of the ::stopPropagation methods that record the
// intent to stop propagation so event bubbling can be properly simulated for
Expand All @@ -13,30 +7,26 @@
// *must* be called with an exact CustomEvent instance. We work around this fact
// by building a CustomEvent directly, then injecting this object into the
// prototype chain by setting its __proto__ property.
let CommandEvent;
module.exports =
(CommandEvent = (function() {
CommandEvent = class CommandEvent extends CustomEvent {
static initClass() {
this.prototype.keyBindingAborted = false;
this.prototype.propagationStopped = false;
}
class CommandEvent extends CustomEvent {
constructor() {
super();
this.keyBindingAborted = false;
this.propagationStopped = false;
}

abortKeyBinding() {
this.stopImmediatePropagation();
return this.keyBindingAborted = true;
}
abortKeyBinding() {
this.stopImmediatePropagation();
return this.keyBindingAborted = true;
}

stopPropagation() {
this.propagationStopped = true;
return super.stopPropagation(...arguments);
}
stopPropagation() {
this.propagationStopped = true;
return super.stopPropagation();
}

stopImmediatePropagation() {
this.propagationStopped = true;
return super.stopImmediatePropagation(...arguments);
}
};
CommandEvent.initClass();
return CommandEvent;
})());
stopImmediatePropagation() {
this.propagationStopped = true;
return super.stopImmediatePropagation();
}
}
39 changes: 19 additions & 20 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ const NUMPAD_KEY_NAMES_BY_KEYBOARD_EVENT_CODE = {
};

const LATIN_KEYMAP_CACHE = new WeakMap();
const isLatinKeymap = function(keymap) {

function isLatinKeymap(keymap) {
if (keymap == null) { return true; }

let isLatin = LATIN_KEYMAP_CACHE.get(keymap);
Expand All @@ -61,21 +62,21 @@ const isLatinKeymap = function(keymap) {

const isASCIICharacter = character => (character != null) && (character.length === 1) && (character.charCodeAt(0) <= 127);

var isLatinCharacter = character => (character != null) && (character.length === 1) && (character.charCodeAt(0) <= 0x024F);
const isLatinCharacter = character => (character != null) && (character.length === 1) && (character.charCodeAt(0) <= 0x024F);

const isUpperCaseCharacter = character => (character != null) && (character.length === 1) && (character.toLowerCase() !== character);

const isLowerCaseCharacter = character => (character != null) && (character.length === 1) && (character.toUpperCase() !== character);

let usKeymap = null;
const usCharactersForKeyCode = function(code) {
function usCharactersForKeyCode(code) {
if (usKeymap == null) { usKeymap = require('./us-keymap'); }
return usKeymap[code];
};

let slovakCmdKeymap = null;
let slovakQwertyCmdKeymap = null;
const slovakCmdCharactersForKeyCode = function(code, layout) {
function slovakCmdCharactersForKeyCode(code, layout) {
if (slovakCmdKeymap == null) { slovakCmdKeymap = require('./slovak-cmd-keymap'); }
if (slovakQwertyCmdKeymap == null) { slovakQwertyCmdKeymap = require('./slovak-qwerty-cmd-keymap'); }

Expand All @@ -88,9 +89,9 @@ const slovakCmdCharactersForKeyCode = function(code, layout) {

exports.normalizeKeystrokes = function(keystrokes) {
const normalizedKeystrokes = [];
for (var keystroke of Array.from(keystrokes.split(WHITESPACE_REGEX))) {
var normalizedKeystroke;
if (normalizedKeystroke = normalizeKeystroke(keystroke)) {
for (const keystroke of keystrokes.split(WHITESPACE_REGEX)) {
const normalizedKeystroke = normalizeKeystroke(keystroke);
if (normalizedKeystroke) {
normalizedKeystrokes.push(normalizedKeystroke);
} else {
return false;
Expand All @@ -99,9 +100,9 @@ exports.normalizeKeystrokes = function(keystrokes) {
return normalizedKeystrokes.join(' ');
};

var normalizeKeystroke = function(keystroke) {
let keyup;
if (keyup = isKeyup(keystroke)) {
function normalizeKeystroke(keystroke) {
let keyup = isKeyup(keystroke);
if (keyup) {
keystroke = keystroke.slice(1);
}
const keys = parseKeystroke(keystroke);
Expand Down Expand Up @@ -146,15 +147,15 @@ var normalizeKeystroke = function(keystroke) {
return keystroke;
};

var parseKeystroke = function(keystroke) {
function parseKeystroke(keystroke) {
const keys = [];
let keyStart = 0;
for (let index = 0; index < keystroke.length; index++) {
var character = keystroke[index];
for (let i = 0; i < keystroke.length; i++) {
var character = keystroke[i];
if (character === '-') {
if (index > keyStart) {
keys.push(keystroke.substring(keyStart, index));
keyStart = index + 1;
if (i > keyStart) {
keys.push(keystroke.substring(keyStart, i));
keyStart = i + 1;

// The keystroke has a trailing - and is invalid
if (keyStart === keystroke.length) { return false; }
Expand Down Expand Up @@ -353,7 +354,7 @@ exports.keystrokeForKeyboardEvent = function(event, customKeystrokeResolvers) {
return keystroke;
};

var nonAltModifiedKeyForKeyboardEvent = function(event) {
function nonAltModifiedKeyForKeyboardEvent(event) {
let characters;
if (event.code && (characters = __guard__(KeyboardLayout.getCurrentKeymap(), x => x[event.code]))) {
if (event.shiftKey) {
Expand Down Expand Up @@ -393,9 +394,7 @@ exports.getModifierKeys = function(keystroke) {
return mod_keys;
};


var buildKeyboardEvent = function(key, eventType, param) {
if (param == null) { param = {}; }
function buildKeyboardEvent(key, eventType, param = {}) {
const {ctrl, shift, alt, cmd, keyCode, target, location} = param;
const ctrlKey = ctrl != null ? ctrl : false;
const altKey = alt != null ? alt : false;
Expand Down
188 changes: 86 additions & 102 deletions src/key-binding.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
/*
* decaffeinate suggestions:
* DS101: Remove unnecessary use of Array.from
* DS102: Remove unnecessary code created because of implicit returns
* DS206: Consider reworking classes to avoid initClass
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
let KeyBinding;
const {calculateSpecificity, MODIFIERS, isKeyup} = require('./helpers');

const MATCH_TYPES = {
Expand All @@ -17,116 +8,109 @@ const MATCH_TYPES = {
module.exports.MATCH_TYPES = MATCH_TYPES;

module.exports.KeyBinding =
(KeyBinding = (function() {
KeyBinding = class KeyBinding {
static initClass() {
this.currentIndex = 1;

this.prototype.enabled = true;
}
class KeyBinding {
static currentIndex = 1;
enabled = true;

constructor(source, command, keystrokes, selector, priority) {
this.source = source;
this.command = command;
this.keystrokes = keystrokes;
this.priority = priority;
this.keystrokeArray = this.keystrokes.split(' ');
this.keystrokeCount = this.keystrokeArray.length;
this.selector = selector.replace(/!important/g, '');
this.specificity = calculateSpecificity(selector);
this.index = this.constructor.currentIndex++;
this.cachedKeyups = null;
}
constructor(source, command, keystrokes, selector, priority) {
this.source = source;
this.command = command;
this.keystrokes = keystrokes;
this.priority = priority;
this.keystrokeArray = this.keystrokes.split(' ');
this.keystrokeCount = this.keystrokeArray.length;
this.selector = selector.replace(/!important/g, '');
this.specificity = calculateSpecificity(selector);
this.index = this.constructor.currentIndex++;
this.cachedKeyups = null;
}

matches(keystroke) {
const multiKeystroke = /\s/.test(keystroke);
if (multiKeystroke) {
return keystroke === this.keystroke;
} else {
return keystroke.split(' ')[0] === this.keystroke.split(' ')[0];
}
matches(keystroke) {
const multiKeystroke = /\s/.test(keystroke);
if (multiKeystroke) {
return keystroke === this.keystroke;
} else {
return keystroke.split(' ')[0] === this.keystroke.split(' ')[0];
}
}

compare(keyBinding) {
if (keyBinding.priority === this.priority) {
if (keyBinding.specificity === this.specificity) {
return keyBinding.index - this.index;
} else {
return keyBinding.specificity - this.specificity;
}
compare(keyBinding) {
if (keyBinding.priority === this.priority) {
if (keyBinding.specificity === this.specificity) {
return keyBinding.index - this.index;
} else {
return keyBinding.priority - this.priority;
return keyBinding.specificity - this.specificity;
}
} else {
return keyBinding.priority - this.priority;
}
}

// Return the keyup portion of the binding, if any, as an array of
// keystrokes.
getKeyups() {
if (this.cachedKeyups != null) { return this.cachedKeyups; }
for (let i = 0; i < this.keystrokeArray.length; i++) {
var keystroke = this.keystrokeArray[i];
if (isKeyup(keystroke)) { return this.cachedKeyups = this.keystrokeArray.slice(i); }
}
// Return the keyup portion of the binding, if any, as an array of
// keystrokes.
getKeyups() {
if (this.cachedKeyups != null) { return this.cachedKeyups; }
for (let i = 0; i < this.keystrokeArray.length; i++) {
var keystroke = this.keystrokeArray[i];
if (isKeyup(keystroke)) { return this.cachedKeyups = this.keystrokeArray.slice(i); }
}
}

// userKeystrokes is an array of keystrokes e.g.
// ['ctrl-y', 'ctrl-x', '^x']
matchesKeystrokes(userKeystrokes) {
let userKeystrokeIndex = -1;
let userKeystrokesHasKeydownEvent = false;
const matchesNextUserKeystroke = function(bindingKeystroke) {
while (userKeystrokeIndex < (userKeystrokes.length - 1)) {
userKeystrokeIndex += 1;
var userKeystroke = userKeystrokes[userKeystrokeIndex];
var isKeydownEvent = !isKeyup(userKeystroke);
if (isKeydownEvent) { userKeystrokesHasKeydownEvent = true; }
if (bindingKeystroke === userKeystroke) {
return true;
} else if (isKeydownEvent) {
return false;
}
// userKeystrokes is an array of keystrokes e.g.
// ['ctrl-y', 'ctrl-x', '^x']
matchesKeystrokes(userKeystrokes) {
let userKeystrokeIndex = -1;
let userKeystrokesHasKeydownEvent = false;
const matchesNextUserKeystroke = function(bindingKeystroke) {
while (userKeystrokeIndex < (userKeystrokes.length - 1)) {
userKeystrokeIndex += 1;
var userKeystroke = userKeystrokes[userKeystrokeIndex];
var isKeydownEvent = !isKeyup(userKeystroke);
if (isKeydownEvent) { userKeystrokesHasKeydownEvent = true; }
if (bindingKeystroke === userKeystroke) {
return true;
} else if (isKeydownEvent) {
return false;
}
return null;
};
}
return null;
};

let isPartialMatch = false;
let bindingRemainderContainsOnlyKeyups = true;
const bindingKeystrokeIndex = 0;
for (var bindingKeystroke of Array.from(this.keystrokeArray)) {
if (!isPartialMatch) {
var doesMatch = matchesNextUserKeystroke(bindingKeystroke);
if (doesMatch === false) {
let isPartialMatch = false;
let bindingRemainderContainsOnlyKeyups = true;
const bindingKeystrokeIndex = 0;
for (const bindingKeystroke of this.keystrokeArray) {
if (!isPartialMatch) {
var doesMatch = matchesNextUserKeystroke(bindingKeystroke);
if (doesMatch === false) {
return false;
} else if (doesMatch === null) {
// Make sure userKeystrokes with only keyup events don't match everything
if (userKeystrokesHasKeydownEvent) {
isPartialMatch = true;
} else {
return false;
} else if (doesMatch === null) {
// Make sure userKeystrokes with only keyup events don't match everything
if (userKeystrokesHasKeydownEvent) {
isPartialMatch = true;
} else {
return false;
}
}
}
}

if (isPartialMatch) {
if (!isKeyup(bindingKeystroke)) { bindingRemainderContainsOnlyKeyups = false; }
}
if (isPartialMatch) {
if (!isKeyup(bindingKeystroke)) { bindingRemainderContainsOnlyKeyups = false; }
}
}

// Bindings that match the beginning of the user's keystrokes are not a match.
// e.g. This is not a match. It would have been a match on the previous keystroke:
// bindingKeystrokes = ['ctrl-tab', '^tab']
// userKeystrokes = ['ctrl-tab', '^tab', '^ctrl']
if (userKeystrokeIndex < (userKeystrokes.length - 1)) { return false; }
// Bindings that match the beginning of the user's keystrokes are not a match.
// e.g. This is not a match. It would have been a match on the previous keystroke:
// bindingKeystrokes = ['ctrl-tab', '^tab']
// userKeystrokes = ['ctrl-tab', '^tab', '^ctrl']
if (userKeystrokeIndex < (userKeystrokes.length - 1)) { return false; }

if (isPartialMatch && bindingRemainderContainsOnlyKeyups) {
return MATCH_TYPES.PENDING_KEYUP;
} else if (isPartialMatch) {
return MATCH_TYPES.PARTIAL;
} else {
return MATCH_TYPES.EXACT;
}
if (isPartialMatch && bindingRemainderContainsOnlyKeyups) {
return MATCH_TYPES.PENDING_KEYUP;
} else if (isPartialMatch) {
return MATCH_TYPES.PARTIAL;
} else {
return MATCH_TYPES.EXACT;
}
};
KeyBinding.initClass();
return KeyBinding;
})());
}
}
Loading