aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-01-14 17:54:09 -0500
committerGitHub <noreply@github.com>2021-01-14 17:54:09 -0500
commit351d9b2e8e9ec8877b156a0c166e9e211d0e7007 (patch)
tree548293eca3c901e7976069ea542684ad489f2e26
parent5ae3acf6ff4d68379d9ea73c6ec90b8dfa69c6ad (diff)
Update KeyboardMouseInputField (#1232)
* Assign missing type * Update KeyboardMouseInputField to use an array instead of a string * Use "modifiers" instead of "value" or "inputs" * Simplify * Add support for using keys * Use bool args instead of a string
-rw-r--r--ext/bg/js/settings/keyboard-mouse-input-field.js159
-rw-r--r--ext/bg/js/settings/profile-conditions-ui.js25
-rw-r--r--ext/bg/js/settings/scan-inputs-controller.js22
3 files changed, 131 insertions, 75 deletions
diff --git a/ext/bg/js/settings/keyboard-mouse-input-field.js b/ext/bg/js/settings/keyboard-mouse-input-field.js
index 08425562..448841f6 100644
--- a/ext/bg/js/settings/keyboard-mouse-input-field.js
+++ b/ext/bg/js/settings/keyboard-mouse-input-field.js
@@ -27,7 +27,7 @@ class KeyboardMouseInputField extends EventDispatcher {
this._isPointerTypeSupported = isPointerTypeSupported;
this._keySeparator = ' + ';
this._inputNameMap = new Map(DocumentUtil.getModifierKeys(os));
- this._keyPriorities = new Map([
+ this._modifierPriorities = new Map([
['meta', -4],
['ctrl', -3],
['alt', -2],
@@ -35,25 +35,29 @@ class KeyboardMouseInputField extends EventDispatcher {
]);
this._mouseInputNamePattern = /^mouse(\d+)$/;
this._eventListeners = new EventListenerCollection();
- this._value = '';
- this._type = null;
+ this._key = null;
+ this._modifiers = [];
this._penPointerIds = new Set();
+ this._mouseModifiersSupported = false;
+ this._keySupported = false;
}
- get value() {
- return this._value;
+ get modifiers() {
+ return this._modifiers;
}
- prepare(value, type) {
+ prepare(key, modifiers, mouseModifiersSupported=false, keySupported=false) {
this.cleanup();
- this._value = value;
- const modifiers = this._splitValue(value);
- const {displayValue} = this._getInputStrings(modifiers);
+ this._key = key;
+ this._modifiers = this._sortModifiers(modifiers);
+ this._mouseModifiersSupported = mouseModifiersSupported;
+ this._keySupported = keySupported;
+ this._updateDisplayString();
const events = [
[this._inputNode, 'keydown', this._onModifierKeyDown.bind(this), false]
];
- if (type === 'modifierInputs' && this._mouseButton !== null) {
+ if (mouseModifiersSupported && this._mouseButton !== null) {
events.push(
[this._mouseButton, 'mousedown', this._onMouseButtonMouseDown.bind(this), false],
[this._mouseButton, 'pointerdown', this._onMouseButtonPointerDown.bind(this), false],
@@ -64,7 +68,6 @@ class KeyboardMouseInputField extends EventDispatcher {
[this._mouseButton, 'contextmenu', this._onMouseButtonContextMenu.bind(this), false]
);
}
- this._inputNode.value = displayValue;
for (const args of events) {
this._eventListeners.addEventListener(...args);
}
@@ -72,35 +75,33 @@ class KeyboardMouseInputField extends EventDispatcher {
cleanup() {
this._eventListeners.removeAllEventListeners();
- this._value = '';
- this._type = null;
+ this._modifiers = [];
+ this._key = null;
+ this._mouseModifiersSupported = false;
+ this._keySupported = false;
this._penPointerIds.clear();
}
clearInputs() {
- this._updateInputs([]);
+ this._updateModifiers([], null);
}
// Private
- _splitValue(value) {
- return value.split(/[,;\s]+/).map((v) => v.trim().toLowerCase()).filter((v) => v.length > 0);
- }
-
- _sortInputs(inputs) {
+ _sortModifiers(modifiers) {
const pattern = this._mouseInputNamePattern;
- const keyPriorities = this._keyPriorities;
- const inputInfos = inputs.map((value, index) => {
- const match = pattern.exec(value);
+ const keyPriorities = this._modifierPriorities;
+ const modifierInfos = modifiers.map((modifier, index) => {
+ const match = pattern.exec(modifier);
if (match !== null) {
- return [value, 1, Number.parseInt(match[1], 10), index];
+ return [modifier, 1, Number.parseInt(match[1], 10), index];
} else {
- let priority = keyPriorities.get(value);
+ let priority = keyPriorities.get(modifier);
if (typeof priority === 'undefined') { priority = 0; }
- return [value, 0, priority, index];
+ return [modifier, 0, priority, index];
}
});
- inputInfos.sort((a, b) => {
+ modifierInfos.sort((a, b) => {
let i = a[1] - b[1];
if (i !== 0) { return i; }
@@ -113,36 +114,37 @@ class KeyboardMouseInputField extends EventDispatcher {
i = a[3] - b[3];
return i;
});
- return inputInfos.map(([value]) => value);
+ return modifierInfos.map(([modifier]) => modifier);
}
- _getInputStrings(inputs) {
- let value = '';
+ _updateDisplayString() {
let displayValue = '';
let first = true;
- for (const input of inputs) {
- const {name} = this._getInputName(input);
+ for (const modifier of this._modifiers) {
+ const {name} = this._getModifierName(modifier);
if (first) {
first = false;
} else {
- value += ', ';
displayValue += this._keySeparator;
}
- value += input;
displayValue += name;
}
- return {value, displayValue};
+ if (this._key !== null) {
+ if (!first) { displayValue += this._keySeparator; }
+ displayValue += this._key;
+ }
+ this._inputNode.value = displayValue;
}
- _getInputName(value) {
+ _getModifierName(modifier) {
const pattern = this._mouseInputNamePattern;
- const match = pattern.exec(value);
+ const match = pattern.exec(modifier);
if (match !== null) {
return {name: `Mouse ${match[1]}`, type: 'mouse'};
}
- let name = this._inputNameMap.get(value);
- if (typeof name === 'undefined') { name = value; }
+ let name = this._inputNameMap.get(modifier);
+ if (typeof name === 'undefined') { name = modifier; }
return {name, type: 'key'};
}
@@ -166,24 +168,40 @@ class KeyboardMouseInputField extends EventDispatcher {
return modifiers;
}
+ _isModifierKey(keyName) {
+ switch (keyName) {
+ case 'Alt':
+ case 'Control':
+ case 'Meta':
+ case 'Shift':
+ return true;
+ default:
+ return false;
+ }
+ }
+
_onModifierKeyDown(e) {
e.preventDefault();
const key = DocumentUtil.getKeyFromEvent(e);
- switch (key) {
- case 'Escape':
- case 'Backspace':
- this.clearInputs();
- break;
- default:
- this._addInputs(this._getModifierKeys(e));
- break;
+ if (this._keySupported) {
+ this._updateModifiers([...this._getModifierKeys(e)], this._isModifierKey(key) ? void 0 : key);
+ } else {
+ switch (key) {
+ case 'Escape':
+ case 'Backspace':
+ this.clearInputs();
+ break;
+ default:
+ this._addModifiers(this._getModifierKeys(e));
+ break;
+ }
}
}
_onMouseButtonMouseDown(e) {
e.preventDefault();
- this._addInputs(DocumentUtil.getActiveButtons(e));
+ this._addModifiers(DocumentUtil.getActiveButtons(e));
}
_onMouseButtonPointerDown(e) {
@@ -200,7 +218,7 @@ class KeyboardMouseInputField extends EventDispatcher {
return;
}
e.preventDefault();
- this._addInputs(DocumentUtil.getActiveButtons(e));
+ this._addModifiers(DocumentUtil.getActiveButtons(e));
}
_onMouseButtonPointerOver(e) {
@@ -227,22 +245,41 @@ class KeyboardMouseInputField extends EventDispatcher {
e.preventDefault();
}
- _addInputs(newInputs) {
- const inputs = new Set(this._splitValue(this._value));
- for (const input of newInputs) {
- inputs.add(input);
+ _addModifiers(newModifiers, newKey) {
+ const modifiers = new Set(this._modifiers);
+ for (const modifier of newModifiers) {
+ modifiers.add(modifier);
+ }
+ this._updateModifiers([...modifiers], newKey);
+ }
+
+ _updateModifiers(modifiers, newKey) {
+ modifiers = this._sortModifiers(modifiers);
+
+ let changed = false;
+ if (typeof newKey !== 'undefined' && this._key !== newKey) {
+ this._key = newKey;
+ changed = true;
+ }
+ if (!this._areArraysEqual(this._modifiers, modifiers)) {
+ this._modifiers = modifiers;
+ changed = true;
+ }
+
+ this._updateDisplayString();
+ if (changed) {
+ this.trigger('change', {modifiers: this._modifiers, key: this._key});
}
- this._updateInputs([...inputs]);
}
- _updateInputs(inputs) {
- inputs = this._sortInputs(inputs);
+ _areArraysEqual(array1, array2) {
+ const length = array1.length;
+ if (length !== array2.length) { return false; }
+
+ for (let i = 0; i < length; ++i) {
+ if (array1[i] !== array2[i]) { return false; }
+ }
- const node = this._inputNode;
- const {value, displayValue} = this._getInputStrings(inputs);
- node.value = displayValue;
- if (this._value === value) { return; }
- this._value = value;
- this.trigger('change', {value, displayValue});
+ return true;
}
}
diff --git a/ext/bg/js/settings/profile-conditions-ui.js b/ext/bg/js/settings/profile-conditions-ui.js
index 69319574..77c9db77 100644
--- a/ext/bg/js/settings/profile-conditions-ui.js
+++ b/ext/bg/js/settings/profile-conditions-ui.js
@@ -525,11 +525,12 @@ class ProfileConditionUI {
}
}
- _onModifierInputChange({validate, normalize}, {value}) {
- const okay = this._validateValue(value, validate);
- this._value = value;
+ _onModifierInputChange({validate, normalize}, {modifiers}) {
+ modifiers = this._joinModifiers(modifiers);
+ const okay = this._validateValue(modifiers, validate);
+ this._value = modifiers;
if (okay) {
- const normalizedValue = this._normalizeValue(value, normalize);
+ const normalizedValue = this._normalizeValue(modifiers, normalize);
this.settingsController.setGlobalSetting(this.getPath('value'), normalizedValue);
}
}
@@ -589,7 +590,7 @@ class ProfileConditionUI {
let inputType = 'text';
let inputValue = value;
let inputStep = null;
- let mouseButtonHidden = true;
+ let showMouseButton = false;
const events = [];
const inputData = {validate, normalize};
const node = this._valueInput;
@@ -603,9 +604,9 @@ class ProfileConditionUI {
case 'modifierKeys':
case 'modifierInputs':
inputValue = null;
- mouseButtonHidden = (type !== 'modifierInputs');
+ showMouseButton = (type === 'modifierInputs');
this._kbmInputField = this._parent.parent.createKeyboardMouseInputField(node, this._mouseButton);
- this._kbmInputField.prepare(value, type);
+ this._kbmInputField.prepare(null, this._splitModifiers(value), showMouseButton, false);
events.push(['on', this._kbmInputField, 'change', this._onModifierInputChange.bind(this, inputData), false]);
break;
default: // 'string'
@@ -624,7 +625,7 @@ class ProfileConditionUI {
} else {
node.removeAttribute('step');
}
- this._mouseButtonContainer.hidden = mouseButtonHidden;
+ this._mouseButtonContainer.hidden = !showMouseButton;
for (const args of events) {
this._inputEventListeners.addGeneric(...args);
}
@@ -645,4 +646,12 @@ class ProfileConditionUI {
_removeSelf() {
this._parent.removeCondition(this);
}
+
+ _splitModifiers(modifiersString) {
+ return modifiersString.split(/[,;\s]+/).map((v) => v.trim().toLowerCase()).filter((v) => v.length > 0);
+ }
+
+ _joinModifiers(modifiersArray) {
+ return modifiersArray.join(', ');
+ }
}
diff --git a/ext/bg/js/settings/scan-inputs-controller.js b/ext/bg/js/settings/scan-inputs-controller.js
index 462b9683..b8b3f710 100644
--- a/ext/bg/js/settings/scan-inputs-controller.js
+++ b/ext/bg/js/settings/scan-inputs-controller.js
@@ -199,8 +199,8 @@ class ScanInputField {
const isPointerTypeSupported = this._isPointerTypeSupported.bind(this);
this._includeInputField = new KeyboardMouseInputField(includeInputNode, includeMouseButton, this._os, isPointerTypeSupported);
this._excludeInputField = new KeyboardMouseInputField(excludeInputNode, excludeMouseButton, this._os, isPointerTypeSupported);
- this._includeInputField.prepare(include, 'modifierInputs');
- this._excludeInputField.prepare(exclude, 'modifierInputs');
+ this._includeInputField.prepare(null, this._splitModifiers(include), true, false);
+ this._excludeInputField.prepare(null, this._splitModifiers(exclude), true, false);
this._eventListeners.on(this._includeInputField, 'change', this._onIncludeValueChange.bind(this));
this._eventListeners.on(this._excludeInputField, 'change', this._onExcludeValueChange.bind(this));
@@ -230,12 +230,14 @@ class ScanInputField {
// Private
- _onIncludeValueChange({value}) {
- this._parent.setProperty(this._index, 'include', value, true);
+ _onIncludeValueChange({modifiers}) {
+ modifiers = this._joinModifiers(modifiers);
+ this._parent.setProperty(this._index, 'include', modifiers, true);
}
- _onExcludeValueChange({value}) {
- this._parent.setProperty(this._index, 'exclude', value, true);
+ _onExcludeValueChange({modifiers}) {
+ modifiers = this._joinModifiers(modifiers);
+ this._parent.setProperty(this._index, 'exclude', modifiers, true);
}
_onRemoveClick(e) {
@@ -296,4 +298,12 @@ class ScanInputField {
this._node.dataset.showAdvanced = `${showAdvanced}`;
this._parent.setProperty(this._index, 'options.showAdvanced', showAdvanced, false);
}
+
+ _splitModifiers(modifiersString) {
+ return modifiersString.split(/[,;\s]+/).map((v) => v.trim().toLowerCase()).filter((v) => v.length > 0);
+ }
+
+ _joinModifiers(modifiersArray) {
+ return modifiersArray.join(', ');
+ }
}