aboutsummaryrefslogtreecommitdiff
path: root/ext/js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-03-27 13:21:34 -0400
committerGitHub <noreply@github.com>2021-03-27 13:21:34 -0400
commit422f011facc4beba59bbe66a80bcc6aeb3648c6b (patch)
treee161151d76895b283e33b3bcbb7ca21b9cb6a5b2 /ext/js
parentaf768624ac3a08dad11ceed3f009e942a84323af (diff)
Update hotkey settings design (#1564)
* Update PopupMenu event prevention * Use vars for button padding * Add button-inner-label style * Add input-button button * Update display of scope selection * Add hidden argument text input field * Remove unnecessary calls * Display a strike through the enabled button when no scopes are selected
Diffstat (limited to 'ext/js')
-rw-r--r--ext/js/dom/popup-menu.js14
-rw-r--r--ext/js/pages/settings/keyboard-shortcuts-controller.js93
2 files changed, 82 insertions, 25 deletions
diff --git a/ext/js/dom/popup-menu.js b/ext/js/dom/popup-menu.js
index af076baa..d8c75869 100644
--- a/ext/js/dom/popup-menu.js
+++ b/ext/js/dom/popup-menu.js
@@ -86,17 +86,19 @@ class PopupMenu extends EventDispatcher {
_onMenuContainerClick(e) {
if (e.currentTarget !== e.target) { return; }
- e.stopPropagation();
- e.preventDefault();
- this._close(null, 'outside', true, e);
+ if (this._close(null, 'outside', true, e)) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
}
_onMenuItemClick(e) {
const item = e.currentTarget;
if (item.disabled) { return; }
- e.stopPropagation();
- e.preventDefault();
- this._close(item, 'item', true, e);
+ if (this._close(item, 'item', true, e)) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
}
_onWindowResize() {
diff --git a/ext/js/pages/settings/keyboard-shortcuts-controller.js b/ext/js/pages/settings/keyboard-shortcuts-controller.js
index 99b16f06..514928d7 100644
--- a/ext/js/pages/settings/keyboard-shortcuts-controller.js
+++ b/ext/js/pages/settings/keyboard-shortcuts-controller.js
@@ -164,10 +164,11 @@ class KeyboardShortcutHotkeyEntry {
this._eventListeners = new EventListenerCollection();
this._inputField = null;
this._actionSelect = null;
- this._scopeCheckboxes = null;
- this._scopeCheckboxContainers = null;
this._basePath = `inputs.hotkeys[${this._index}]`;
this._stringComparer = stringComparer;
+ this._enabledButton = null;
+ this._scopeMenu = null;
+ this._scopeMenuEventListeners = new EventListenerCollection();
}
prepare() {
@@ -176,13 +177,12 @@ class KeyboardShortcutHotkeyEntry {
const menuButton = node.querySelector('.hotkey-list-item-button');
const input = node.querySelector('.hotkey-list-item-input');
const action = node.querySelector('.hotkey-list-item-action');
- const scopeCheckboxes = node.querySelectorAll('.hotkey-scope-checkbox');
- const scopeCheckboxContainers = node.querySelectorAll('.hotkey-scope-checkbox-container');
const enabledToggle = node.querySelector('.hotkey-list-item-enabled');
+ const scopesButton = node.querySelector('.hotkey-list-item-scopes-button');
+ const enabledButton = node.querySelector('.hotkey-list-item-enabled-button');
this._actionSelect = action;
- this._scopeCheckboxes = scopeCheckboxes;
- this._scopeCheckboxContainers = scopeCheckboxContainers;
+ this._enabledButton = enabledButton;
this._inputField = new KeyboardMouseInputField(input, null, this._os);
this._inputField.prepare(this._data.key, this._data.modifiers, false, true);
@@ -192,12 +192,10 @@ class KeyboardShortcutHotkeyEntry {
enabledToggle.checked = this._data.enabled;
enabledToggle.dataset.setting = `${this._basePath}.enabled`;
- this._updateCheckboxVisibility();
- this._updateCheckboxStates();
+ this._updateScopesButton();
- for (const scopeCheckbox of scopeCheckboxes) {
- this._eventListeners.addEventListener(scopeCheckbox, 'change', this._onScopeCheckboxChange.bind(this), false);
- }
+ this._eventListeners.addEventListener(scopesButton, 'menuOpen', this._onScopesMenuOpen.bind(this));
+ this._eventListeners.addEventListener(scopesButton, 'menuClose', this._onScopesMenuClose.bind(this));
this._eventListeners.addEventListener(menuButton, 'menuClose', this._onMenuClose.bind(this), false);
this._eventListeners.addEventListener(this._actionSelect, 'change', this._onActionSelectChange.bind(this), false);
this._eventListeners.on(this._inputField, 'change', this._onInputFieldChange.bind(this));
@@ -206,6 +204,7 @@ class KeyboardShortcutHotkeyEntry {
cleanup() {
this._eventListeners.removeAllEventListeners();
this._inputField.cleanup();
+ this._clearScopeMenu();
if (this._node.parentNode !== null) {
this._node.parentNode.removeChild(this._node);
}
@@ -227,6 +226,24 @@ class KeyboardShortcutHotkeyEntry {
}
}
+ _onScopesMenuOpen(e) {
+ const {menu} = e.detail;
+ this._scopeMenu = menu;
+ this._updateScopeMenuItems(menu);
+ this._updateDisplay(menu.containerNode); // Fix a animation issue due to changing checkbox values
+ }
+
+ _onScopesMenuClose(e) {
+ const {menu, action} = e.detail;
+ if (action === 'toggleScope') {
+ e.preventDefault();
+ return;
+ }
+ if (this._scopeMenu === menu) {
+ this._clearScopeMenu();
+ }
+ }
+
_onInputFieldChange({key, modifiers}) {
this._setKeyAndModifiers(key, modifiers);
}
@@ -277,6 +294,8 @@ class KeyboardShortcutHotkeyEntry {
scopes.splice(index, 1);
}
+ this._updateScopesButton();
+
await this._modifyProfileSettings([{
action: 'set',
path: `${this._basePath}.scopes`,
@@ -346,17 +365,13 @@ class KeyboardShortcutHotkeyEntry {
}
_updateCheckboxStates() {
- const scopes = this._data.scopes;
- for (const scopeCheckbox of this._scopeCheckboxes) {
- scopeCheckbox.checked = scopes.includes(scopeCheckbox.dataset.scope);
- }
+ if (this._scopeMenu === null) { return; }
+ this._updateScopeMenuItems(this._scopeMenu);
}
_updateCheckboxVisibility() {
- const validScopes = this._getValidScopesForAction(this._data.action);
- for (const node of this._scopeCheckboxContainers) {
- node.hidden = !(validScopes === null || validScopes.has(node.dataset.scope));
- }
+ if (this._scopeMenu === null) { return; }
+ this._updateScopeMenuItems(this._scopeMenu);
}
_getValidScopesForAction(action) {
@@ -364,4 +379,44 @@ class KeyboardShortcutHotkeyEntry {
const scopesString = (optionNode !== null ? optionNode.dataset.scopes : void 0);
return (typeof scopesString === 'string' ? new Set(scopesString.split(' ')) : null);
}
+
+ _updateScopeMenuItems(menu) {
+ this._scopeMenuEventListeners.removeAllEventListeners();
+
+ const scopes = this._data.scopes;
+ const validScopes = this._getValidScopesForAction(this._data.action);
+
+ const bodyNode = menu.bodyNode;
+ const menuItems = bodyNode.querySelectorAll('.popup-menu-item');
+ for (const menuItem of menuItems) {
+ if (menuItem.dataset.menuAction !== 'toggleScope') { continue; }
+
+ const {scope} = menuItem.dataset;
+ menuItem.hidden = !(validScopes === null || validScopes.has(scope));
+
+ const checkbox = menuItem.querySelector('.hotkey-scope-checkbox');
+ if (checkbox !== null) {
+ checkbox.checked = scopes.includes(scope);
+ this._scopeMenuEventListeners.addEventListener(checkbox, 'change', this._onScopeCheckboxChange.bind(this), false);
+ }
+ }
+ }
+
+ _clearScopeMenu() {
+ this._scopeMenuEventListeners.removeAllEventListeners();
+ this._scopeMenu = null;
+ }
+
+ _updateScopesButton() {
+ const {scopes} = this._data;
+ this._enabledButton.dataset.scopeCount = `${scopes.length}`;
+ }
+
+ _updateDisplay(node) {
+ const {style} = node;
+ const {display} = style;
+ style.display = 'none';
+ getComputedStyle(node).getPropertyValue('display');
+ style.display = display;
+ }
}