mirror of
https://github.com/zen-browser/components.git
synced 2025-07-08 14:39:58 +02:00
Refactor ZenWorkspaces to use async/await for shortcutSwitchTo method
This commit is contained in:
parent
b4b3c1f0d4
commit
a97e7e65ed
2 changed files with 325 additions and 208 deletions
|
@ -1,147 +1,3 @@
|
||||||
const kZKSActions = {
|
|
||||||
// Note: If they start with "command:", it means that "command=" will be added to the key element,
|
|
||||||
// otherwise "oncommand=" will be added.
|
|
||||||
|
|
||||||
// Split view actions
|
|
||||||
zenSplitViewGrid: ["gZenViewSplitter.toggleShortcut('grid')", 'zen-split-view-grid', 'split-view-action'],
|
|
||||||
zenSplitViewVertical: ["gZenViewSplitter.toggleShortcut('vsep')", 'zen-split-view-vertical', 'split-view-action'],
|
|
||||||
zenSplitViewHorizontal: ["gZenViewSplitter.toggleShortcut('hsep')", 'zen-split-view-horizontal', 'split-view-action'],
|
|
||||||
zenSplitViewClose: ["gZenViewSplitter.toggleShortcut('unsplit')", 'zen-split-view-close', 'split-view-action'],
|
|
||||||
|
|
||||||
// Workspace actions
|
|
||||||
zenChangeWorkspace: ['ZenWorkspaces.changeWorkspaceShortcut()', 'zen-change-workspace', 'workspace-action'],
|
|
||||||
zenChangeWorkspaceBack: ['ZenWorkspaces.changeWorkspaceShortcut(-1)', 'zen-change-workspace-back', 'workspace-action'],
|
|
||||||
|
|
||||||
// manage actions
|
|
||||||
openNewTab: ['command:cmd_newNavigatorTabNoEvent', 'open-new-tab', 'tab-action'],
|
|
||||||
duplicateTab: ["duplicateTabIn(gBrowser.selectedTab, 'tab')", 'duplicate-tab', 'tab-action'],
|
|
||||||
closeTab: ['command:cmd_close', 'close-tab', 'tab-action'],
|
|
||||||
openNewWindow: ['command:cmd_newNavigator', 'open-new-window', 'tab-action'],
|
|
||||||
openNewPrivateWindow: ['command:Tools:PrivateBrowsing', 'open-new-private-window', 'tab-action'],
|
|
||||||
closeWindow: ['command:cmd_closeWindow', 'close-window', 'tab-action'],
|
|
||||||
restoreLastTab: ['undoCloseTab()', 'restore-last-session', 'tab-action'],
|
|
||||||
restoreLastWindow: ['command:History:UndoCloseWindow', 'restore-last-window', 'tab-action'],
|
|
||||||
showNextTab: ['gBrowser.tabContainer.advanceSelectedTab(1, true)', 'show-next-tab', 'tab-action'],
|
|
||||||
showPreviousTab: ['gBrowser.tabContainer.advanceSelectedTab(-1, true)', 'show-previous-tab', 'tab-action'],
|
|
||||||
showAllTabsPanel: ['gTabsPanel.showAllTabsPanel()', 'show-all-tabs-panel', 'tab-action'],
|
|
||||||
|
|
||||||
// Compact mode actions
|
|
||||||
zenToggleCompactMode: ['gZenCompactModeManager.toggle()', 'zen-toggle-compact-mode', 'compact-mode-action'],
|
|
||||||
zenToggleCompactModeSidebar: [
|
|
||||||
'gZenCompactModeManager.toggleSidebar()',
|
|
||||||
'zen-toggle-compact-mode-sidebar',
|
|
||||||
'compact-mode-action',
|
|
||||||
],
|
|
||||||
zenToggleCompactModeToolbar: [
|
|
||||||
'gZenCompactModeManager.toggleToolbar()',
|
|
||||||
'zen-toggle-compact-mode-toolbar',
|
|
||||||
'compact-mode-action',
|
|
||||||
],
|
|
||||||
|
|
||||||
// Page actions
|
|
||||||
sendWithMail: ['command:Browser:SendLink', 'send-with-mail', 'page-action'],
|
|
||||||
savePage: ['command:Browser:SavePage', 'save-page', 'page-action'],
|
|
||||||
printPage: ['command:cmd_print', 'print-page', 'page-action'],
|
|
||||||
muteCurrentTab: ['command:cmd_toggleMute', 'mute-current-tab', 'page-action'],
|
|
||||||
showSourceOfPage: ['command:View:PageSource', 'show-source-of-page', 'page-action'],
|
|
||||||
showPageInfo: ['command:View:PageInfo', 'show-page-info', 'page-action'],
|
|
||||||
|
|
||||||
// Visible actions
|
|
||||||
zoomIn: ['command:cmd_fullZoomEnlarge', 'zoom-in', 'visible-action'],
|
|
||||||
zoomOut: ['command:cmd_fullZoomReduce', 'zoom-out', 'visible-action'],
|
|
||||||
resetZoom: ['command:cmd_fullZoomReset', 'reset-zoom', 'visible-action'],
|
|
||||||
|
|
||||||
// History actions
|
|
||||||
back: ['command:Browser:Back', 'back', 'history-action'],
|
|
||||||
forward: ['command:Browser:Forward', 'forward', 'history-action'],
|
|
||||||
stop: ['command:Browser:Stop', 'stop', 'history-action'],
|
|
||||||
reload: ['command:Browser:Reload', 'reload', 'history-action'],
|
|
||||||
forceReload: ['command:Browser:ReloadSkipCache', 'force-reload', 'history-action'],
|
|
||||||
|
|
||||||
// search actions
|
|
||||||
searchInThisPage: ["gLazyFindCommand('onFindCommand')", 'search-in-this-page', 'search-action'],
|
|
||||||
showNextSearchResult: ["gLazyFindCommand('onFindAgainCommand', false)", 'show-next-search-result', 'search-action'],
|
|
||||||
showPreviousSearchResult: ["gLazyFindCommand('onFindAgainCommand', true)", 'show-previous-search-result', 'search-action'],
|
|
||||||
searchTheWeb: ['command:Tools:Search', 'search-the-web', 'search-action'],
|
|
||||||
|
|
||||||
// Tools actions
|
|
||||||
openMigrationWizard: ['command:cmd_file_importFromAnotherBrowser', 'open-migration-wizard', 'tools-action'],
|
|
||||||
quitFromApplication: ['command:goQuitApplication', 'quit-from-application', 'tools-action'],
|
|
||||||
enterIntoCustomizeMode: ['gCustomizeMode.enter()', 'enter-into-customize-mode', 'tools-action'],
|
|
||||||
enterIntoOfflineMode: ['command:cmd_toggleOfflineStatus', 'enter-into-offline-mode', 'tools-action'],
|
|
||||||
openScreenCapture: ['command:Browser:Screenshot', 'open-screen-capture', 'tools-action'],
|
|
||||||
|
|
||||||
// Bookmark actions
|
|
||||||
bookmarkThisPage: [
|
|
||||||
"BrowserPageActions.doCommandForAction(PageActions.actionForID('bookmark'), event, this);",
|
|
||||||
'bookmark-this-page',
|
|
||||||
'bookmark-action',
|
|
||||||
],
|
|
||||||
openBookmarkAddTool: [
|
|
||||||
'PlacesUIUtils.showBookmarkPagesDialog(PlacesCommandHook.uniqueCurrentPages)',
|
|
||||||
'open-bookmark-add-tool',
|
|
||||||
'bookmark-action',
|
|
||||||
],
|
|
||||||
openBookmarksManager: ["SidebarController.toggle('viewBookmarksSidebar');", 'open-bookmarks-manager', 'bookmark-action'],
|
|
||||||
toggleBookmarkToolbar: [
|
|
||||||
"BookmarkingUI.toggleBookmarksToolbar('bookmark-tools')",
|
|
||||||
'toggle-bookmark-toolbar',
|
|
||||||
'bookmark-action',
|
|
||||||
],
|
|
||||||
|
|
||||||
// Open Page actions
|
|
||||||
openGeneralPreferences: ['openPreferences()', 'open-general-preferences', 'open-page-action'],
|
|
||||||
openPrivacyPreferences: ["openPreferences('panePrivacy')", 'open-privacy-preferences', 'open-page-action'],
|
|
||||||
openWorkspacesPreferences: ["openPreferences('paneWorkspaces')", 'open-workspaces-preferences', 'open-page-action'],
|
|
||||||
openContainersPreferences: ["openPreferences('paneContainers')", 'open-containers-preferences', 'open-page-action'],
|
|
||||||
openSearchPreferences: ["openPreferences('paneSearch')", 'open-search-preferences', 'open-page-action'],
|
|
||||||
openSyncPreferences: ["openPreferences('paneSync')", 'open-sync-preferences', 'open-page-action'],
|
|
||||||
openTaskManager: ['command:View:AboutProcesses', 'open-task-manager', 'open-page-action'],
|
|
||||||
openAddonsManager: ['command:Tools:Addons', 'open-addons-manager', 'open-page-action'],
|
|
||||||
openHomePage: ['BrowserHome()', 'open-home-page', 'open-page-action'],
|
|
||||||
|
|
||||||
// History actions
|
|
||||||
forgetHistory: ['command:Tools:Sanitize', 'forget-history', 'history-action'],
|
|
||||||
quickForgetHistory: ['PlacesUtils.history.clear(true)', 'quick-forget-history', 'history-action'],
|
|
||||||
clearRecentHistory: ['command:cmd_closeWindow', 'clear-recent-history', 'history-action'],
|
|
||||||
restoreLastSession: ['command:Browser:RestoreLastSession', 'restore-last-session', 'history-action'],
|
|
||||||
searchHistory: ['command:History:SearchHistory', 'search-history', 'history-action'],
|
|
||||||
manageHistory: ["PlacesCommandHook.showPlacesOrganizer('History')", 'manage-history', 'history-action'],
|
|
||||||
|
|
||||||
// Downloads actions
|
|
||||||
openDownloads: ['DownloadsPanel.showDownloadsHistory()', 'open-downloads', 'downloads-action'],
|
|
||||||
|
|
||||||
// Sidebar actions
|
|
||||||
showBookmarkSidebar: ["SidebarController.show('viewBookmarksSidebar')", 'show-bookmark-sidebar', 'sidebar-action'],
|
|
||||||
showHistorySidebar: ["SidebarController.show('viewHistorySidebar')", 'show-history-sidebar', 'sidebar-action'],
|
|
||||||
showSyncedTabsSidebar: ["SidebarController.show('viewTabsSidebar')", 'show-synced-tabs-sidebar', 'sidebar-action'],
|
|
||||||
reverseSidebarPosition: ['SidebarController.reversePosition()', 'reverse-sidebar', 'sidebar-action'],
|
|
||||||
hideSidebar: ['SidebarController.hide()', 'hide-sidebar', 'sidebar-action'],
|
|
||||||
toggleSidebar: ['SidebarController.toggle()', 'toggle-sidebar', 'sidebar-action'],
|
|
||||||
zenToggleWebPanels: ['gZenBrowserManagerSidebar.toggle()', 'zen-toggle-web-panels', 'sidebar-action'],
|
|
||||||
};
|
|
||||||
|
|
||||||
const kZenDefaultShortcuts = {
|
|
||||||
// Split view actions
|
|
||||||
zenSplitViewGrid: 'Ctrl+Alt+G',
|
|
||||||
zenSplitViewVertical: 'Ctrl+Alt+V',
|
|
||||||
zenSplitViewHorizontal: 'Ctrl+Alt+H',
|
|
||||||
zenSplitViewClose: 'Ctrl+Alt+U',
|
|
||||||
|
|
||||||
// Workspace actions
|
|
||||||
zenChangeWorkspace: 'Ctrl+E',
|
|
||||||
zenChangeWorkspaceBack: 'Ctrl+Shift+E',
|
|
||||||
|
|
||||||
// Compact mode actions
|
|
||||||
zenToggleCompactMode: 'Ctrl+Alt+C',
|
|
||||||
zenToggleCompactModeSidebar: 'Ctrl+Alt+S',
|
|
||||||
zenToggleCompactModeToolbar: 'Ctrl+Alt+T',
|
|
||||||
|
|
||||||
// manage actions
|
|
||||||
zenToggleWebPanels: 'Alt+P',
|
|
||||||
};
|
|
||||||
|
|
||||||
// Section: ZenKeyboardShortcuts
|
|
||||||
|
|
||||||
const KEYCODE_MAP = {
|
const KEYCODE_MAP = {
|
||||||
F1: 'VK_F1',
|
F1: 'VK_F1',
|
||||||
|
@ -168,9 +24,74 @@ const KEYCODE_MAP = {
|
||||||
BACKSPACE: 'VK_BACK',
|
BACKSPACE: 'VK_BACK',
|
||||||
};
|
};
|
||||||
|
|
||||||
const ZEN_SHORTCUTS_GROUP = 'zen';
|
const defaultKeyboardGroups = {
|
||||||
const FIREFOX_SHORTCUTS_GROUP = 'firefox';
|
windowAndTabManagement: [
|
||||||
const VALID_SHORTCUT_GROUPS = [ZEN_SHORTCUTS_GROUP, FIREFOX_SHORTCUTS_GROUP];
|
"zen-window-new-shortcut",
|
||||||
|
"zen-tab-new-shortcut",
|
||||||
|
"zen-key-enter-full-screen",
|
||||||
|
"zen-key-exit-full-screen",
|
||||||
|
"zen-quit-app-shortcut"
|
||||||
|
],
|
||||||
|
navigation: [
|
||||||
|
"zen-key-go-back",
|
||||||
|
"zen-key-go-forward",
|
||||||
|
"zen-nav-back-shortcut-alt",
|
||||||
|
"zen-nav-fwd-shortcut-alt",
|
||||||
|
"zen-nav-reload-shortcut-2",
|
||||||
|
"zen-nav-reload-shortcut-skip-cache",
|
||||||
|
"zen-nav-reload-shortcut",
|
||||||
|
"zen-key-stop"
|
||||||
|
],
|
||||||
|
searchAndFind: [
|
||||||
|
"zen-search-focus-shortcut",
|
||||||
|
"zen-search-focus-shortcut-alt",
|
||||||
|
"zen-find-shortcut",
|
||||||
|
"zen-search-find-again-shortcut-2",
|
||||||
|
"zen-search-find-again-shortcut",
|
||||||
|
"zen-search-find-again-shortcut-prev",
|
||||||
|
],
|
||||||
|
pageOperations: [
|
||||||
|
"zen-location-open-shortcut",
|
||||||
|
"zen-location-open-shortcut-alt",
|
||||||
|
"zen-save-page-shortcut",
|
||||||
|
"zen-print-shortcut",
|
||||||
|
"zen-page-source-shortcut",
|
||||||
|
"zen-page-info-shortcut",
|
||||||
|
"zen-reader-mode-toggle-shortcut-other",
|
||||||
|
"zen-picture-in-picture-toggle-shortcut"
|
||||||
|
],
|
||||||
|
historyAndBookmarks: [
|
||||||
|
"zen-history-show-all-shortcut",
|
||||||
|
"zen-bookmark-this-page-shortcut",
|
||||||
|
"zen-bookmark-show-library-shortcut"
|
||||||
|
],
|
||||||
|
mediaAndDisplay: [
|
||||||
|
"zen-mute-toggle-shortcut",
|
||||||
|
"zen-full-zoom-reduce-shortcut",
|
||||||
|
"zen-full-zoom-enlarge-shortcut",
|
||||||
|
"zen-full-zoom-reset-shortcut",
|
||||||
|
"zen-bidi-switch-direction-shortcut",
|
||||||
|
"zen-private-browsing-shortcut",
|
||||||
|
"zen-screenshot-shortcut"
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const fixedL10nIds = {
|
||||||
|
cmd_findPrevious: 'zen-search-find-again-shortcut-prev',
|
||||||
|
"Browser:ReloadSkipCache": "zen-nav-reload-shortcut-skip-cache",
|
||||||
|
cmd_close: "zen-close-tab-shortcut",
|
||||||
|
};
|
||||||
|
|
||||||
|
const ZEN_COMPACT_MODE_SHORTCUTS_GROUP = 'zen-compact-mode';
|
||||||
|
const ZEN_WORKSPACE_SHORTCUTS_GROUP = 'zen-workspace';
|
||||||
|
const ZEN_OTHER_SHORTCUTS_GROUP = 'zen-other';
|
||||||
|
const FIREFOX_SHORTCUTS_GROUP = 'zen-kbs-invalid';
|
||||||
|
const VALID_SHORTCUT_GROUPS = [
|
||||||
|
ZEN_COMPACT_MODE_SHORTCUTS_GROUP,
|
||||||
|
ZEN_WORKSPACE_SHORTCUTS_GROUP,
|
||||||
|
ZEN_OTHER_SHORTCUTS_GROUP,
|
||||||
|
'other', ...Object.keys(defaultKeyboardGroups)
|
||||||
|
];
|
||||||
|
|
||||||
class KeyShortcutModifiers {
|
class KeyShortcutModifiers {
|
||||||
#ctrl = false;
|
#ctrl = false;
|
||||||
|
@ -211,6 +132,11 @@ class KeyShortcutModifiers {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used to avoid any future changes to the object
|
||||||
|
static fromObject({ctrl = false, alt = false, shift = false, meta = false}) {
|
||||||
|
return new KeyShortcutModifiers(ctrl, alt, shift, meta);
|
||||||
|
}
|
||||||
|
|
||||||
toUserString() {
|
toUserString() {
|
||||||
let str = '';
|
let str = '';
|
||||||
if (this.#ctrl) {
|
if (this.#ctrl) {
|
||||||
|
@ -228,6 +154,18 @@ class KeyShortcutModifiers {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
equals(other) {
|
||||||
|
if (!other) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
this.#ctrl == other.#ctrl &&
|
||||||
|
this.#alt == other.#alt &&
|
||||||
|
this.#shift == other.#shift &&
|
||||||
|
this.#meta == other.#meta
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
let str = '';
|
let str = '';
|
||||||
if (this.#ctrl) {
|
if (this.#ctrl) {
|
||||||
|
@ -271,9 +209,9 @@ class KeyShortcut {
|
||||||
#reserved = false;
|
#reserved = false;
|
||||||
#internal = false;
|
#internal = false;
|
||||||
|
|
||||||
constructor(id, key, keycode, group, modifiers, action, l10nId, disabled, reserved, internal) {
|
constructor(id, key, keycode, group, modifiers, action, l10nId, disabled = false, reserved = false, internal = false) {
|
||||||
this.#id = id;
|
this.#id = id;
|
||||||
this.#key = key;
|
this.#key = key?.toLowerCase();
|
||||||
this.#keycode = keycode;
|
this.#keycode = keycode;
|
||||||
|
|
||||||
if (!VALID_SHORTCUT_GROUPS.includes(group)) {
|
if (!VALID_SHORTCUT_GROUPS.includes(group)) {
|
||||||
|
@ -283,12 +221,16 @@ class KeyShortcut {
|
||||||
this.#group = group;
|
this.#group = group;
|
||||||
this.#modifiers = modifiers;
|
this.#modifiers = modifiers;
|
||||||
this.#action = action;
|
this.#action = action;
|
||||||
this.#l10nId = l10nId;
|
this.#l10nId = KeyShortcut.sanitizeL10nId(l10nId, action);
|
||||||
this.#disabled = disabled;
|
this.#disabled = disabled;
|
||||||
this.#reserved = reserved;
|
this.#reserved = reserved;
|
||||||
this.#internal = internal;
|
this.#internal = internal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isEmpty() {
|
||||||
|
return !this.#key && !this.#keycode;
|
||||||
|
}
|
||||||
|
|
||||||
static parseFromSaved(json) {
|
static parseFromSaved(json) {
|
||||||
let rv = [];
|
let rv = [];
|
||||||
|
|
||||||
|
@ -299,6 +241,16 @@ class KeyShortcut {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getGroupFromL10nId(l10nId) {
|
||||||
|
// Find inside defaultKeyboardGroups
|
||||||
|
for (let group of Object.keys(defaultKeyboardGroups)) {
|
||||||
|
if (defaultKeyboardGroups[group].includes(l10nId)) {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'other';
|
||||||
|
}
|
||||||
|
|
||||||
static #parseFromJSON(json) {
|
static #parseFromJSON(json) {
|
||||||
return new KeyShortcut(
|
return new KeyShortcut(
|
||||||
json['id'],
|
json['id'],
|
||||||
|
@ -314,12 +266,12 @@ class KeyShortcut {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static parseFromXHTML(key, group) {
|
static parseFromXHTML(key) {
|
||||||
return new KeyShortcut(
|
return new KeyShortcut(
|
||||||
key.getAttribute('id'),
|
key.getAttribute('id'),
|
||||||
key.getAttribute('key'),
|
key.getAttribute('key'),
|
||||||
key.getAttribute('keycode'),
|
key.getAttribute('keycode'),
|
||||||
group,
|
KeyShortcut.getGroupFromL10nId(KeyShortcut.sanitizeL10nId(key.getAttribute('data-l10n-id'))),
|
||||||
KeyShortcutModifiers.parseFromXHTMLAttribute(key.getAttribute('modifiers')),
|
KeyShortcutModifiers.parseFromXHTMLAttribute(key.getAttribute('modifiers')),
|
||||||
key.getAttribute('command'),
|
key.getAttribute('command'),
|
||||||
key.getAttribute('data-l10n-id'),
|
key.getAttribute('data-l10n-id'),
|
||||||
|
@ -329,37 +281,46 @@ class KeyShortcut {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
toXHTMLElement() {
|
static sanitizeL10nId(id, action) {
|
||||||
let str = '<key';
|
if (!id || id.startsWith('zen-')) {
|
||||||
if (this.#id) {
|
return id;
|
||||||
str += ` id="${this.#id}"`;
|
}
|
||||||
}
|
// Check if any action is on the list of fixed l10n ids
|
||||||
|
if (fixedL10nIds[action]) {
|
||||||
if (this.#key) {
|
return fixedL10nIds[action];
|
||||||
str += ` key="${this.#key}"`;
|
}
|
||||||
|
return `zen-${id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toXHTMLElement(window) {
|
||||||
|
let key = window.document.createXULElement('key');
|
||||||
|
key.id = this.#id;
|
||||||
if (this.#keycode) {
|
if (this.#keycode) {
|
||||||
str += ` keycode="${this.#keycode}"`;
|
key.setAttribute('keycode', this.#keycode);
|
||||||
|
} else {
|
||||||
|
// note to "mr. macos": Better use setAttribute, because without it, there's a
|
||||||
|
// risk of malforming the XUL element.
|
||||||
|
key.setAttribute('key', this.#key);
|
||||||
}
|
}
|
||||||
|
key.setAttribute('group', this.#group);
|
||||||
|
|
||||||
str += ` group="${this.#group}"`;
|
// note to "mr. macos": We add the `zen-` prefix because since firefox hasnt been built with the
|
||||||
|
// shortcuts in mind, it will siply just override the shortcuts with whatever the default is.
|
||||||
if (this.#l10nId) {
|
// note that this l10n id is not used for actually translating the key's label, but rather to
|
||||||
str += ` data-l10n-id="${this.#l10nId}"`;
|
// identify the default keybinds.
|
||||||
|
key.setAttribute('data-l10n-id', this.#l10nId);
|
||||||
|
key.setAttribute('modifiers', this.#modifiers.toString());
|
||||||
|
if (this.#action?.startsWith('code:')) {
|
||||||
|
key.setAttribute('oncommand', this.#action.substring(5));
|
||||||
|
} else {
|
||||||
|
key.setAttribute('command', this.#action);
|
||||||
}
|
}
|
||||||
|
key.setAttribute('disabled', this.#disabled);
|
||||||
|
key.setAttribute('reserved', this.#reserved);
|
||||||
|
key.setAttribute('internal', this.#internal);
|
||||||
|
key.setAttribute('zen-keybind', 'true');
|
||||||
|
|
||||||
if (this.#modifiers) {
|
return key;
|
||||||
str += ` modifiers="${this.#modifiers.toString()}"`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.#action) {
|
|
||||||
str += ` command="${this.#action}"`;
|
|
||||||
}
|
|
||||||
|
|
||||||
str += ` disabled="${this.#disabled}" reserved="${this.#reserved}" internal="${this.#internal}"/>`;
|
|
||||||
|
|
||||||
return window.MozXULElement.parseXULToFragment(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getID() {
|
getID() {
|
||||||
|
@ -382,6 +343,30 @@ class KeyShortcut {
|
||||||
return this.#modifiers;
|
return this.#modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getKeyName() {
|
||||||
|
return this.#key;
|
||||||
|
}
|
||||||
|
|
||||||
|
getKeyCode() {
|
||||||
|
return this.#keycode;
|
||||||
|
}
|
||||||
|
|
||||||
|
getKeyNameOrCode() {
|
||||||
|
return this.#key ? this.#key : this.#keycode;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDisabled() {
|
||||||
|
return this.#disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
isReserved() {
|
||||||
|
return this.#reserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
isInternal() {
|
||||||
|
return this.#internal;
|
||||||
|
}
|
||||||
|
|
||||||
setModifiers(modifiers) {
|
setModifiers(modifiers) {
|
||||||
if ((!modifiers) instanceof KeyShortcutModifiers) {
|
if ((!modifiers) instanceof KeyShortcutModifiers) {
|
||||||
throw new Error('Only KeyShortcutModifiers allowed');
|
throw new Error('Only KeyShortcutModifiers allowed');
|
||||||
|
@ -408,9 +393,15 @@ class KeyShortcut {
|
||||||
let str = this.#modifiers.toUserString();
|
let str = this.#modifiers.toUserString();
|
||||||
|
|
||||||
if (this.#key) {
|
if (this.#key) {
|
||||||
str += this.#key;
|
str += this.#key.toUpperCase();
|
||||||
} else if (this.#keycode) {
|
} else if (this.#keycode) {
|
||||||
str += this.#keycode;
|
// Get the key from the value
|
||||||
|
for (let [key, value] of Object.entries(KEYCODE_MAP)) {
|
||||||
|
if (value == this.#keycode) {
|
||||||
|
str += key.toLowerCase();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -476,7 +467,7 @@ var gZenKeyboardShortcutsManager = {
|
||||||
|
|
||||||
this._currentShortcutList = await this._loadSaved();
|
this._currentShortcutList = await this._loadSaved();
|
||||||
|
|
||||||
// TODO: add some sort of observer to listen for changes in the shortcuts file
|
this._applyShortcuts();
|
||||||
|
|
||||||
await this._saveShortcuts();
|
await this._saveShortcuts();
|
||||||
|
|
||||||
|
@ -499,43 +490,146 @@ var gZenKeyboardShortcutsManager = {
|
||||||
},
|
},
|
||||||
|
|
||||||
_loadDefaults() {
|
_loadDefaults() {
|
||||||
|
console.info('Zen CKS: Loading default shortcuts...');
|
||||||
let keySet = document.getElementById('mainKeyset');
|
let keySet = document.getElementById('mainKeyset');
|
||||||
let newShortcutList = [];
|
let newShortcutList = [];
|
||||||
|
|
||||||
// Firefox's standard keyset
|
// Firefox's standard keyset
|
||||||
for (let key of keySet.children) {
|
for (let key of keySet.children) {
|
||||||
let parsed = KeyShortcut.parseFromXHTML(key, FIREFOX_SHORTCUTS_GROUP);
|
let parsed = KeyShortcut.parseFromXHTML(key);
|
||||||
newShortcutList.push(parsed);
|
newShortcutList.push(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add Zen's custom actions
|
// Compact mode's keyset
|
||||||
|
newShortcutList.push(
|
||||||
|
new KeyShortcut(
|
||||||
|
'zen-compact-mode-toggle',
|
||||||
|
'C',
|
||||||
|
'',
|
||||||
|
ZEN_COMPACT_MODE_SHORTCUTS_GROUP,
|
||||||
|
KeyShortcutModifiers.fromObject({ctrl: true, alt: true}),
|
||||||
|
'code:gZenCompactModeManager.toggle()',
|
||||||
|
'zen-compact-mode-shortcut-toggle'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
newShortcutList.push(
|
||||||
|
new KeyShortcut(
|
||||||
|
'zen-compact-mode-show-sidebar',
|
||||||
|
'S',
|
||||||
|
'',
|
||||||
|
ZEN_COMPACT_MODE_SHORTCUTS_GROUP,
|
||||||
|
KeyShortcutModifiers.fromObject({ctrl: true, alt: true}),
|
||||||
|
'code:gZenCompactModeManager.toggleSidebar()',
|
||||||
|
'zen-compact-mode-shortcut-show-sidebar'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
newShortcutList.push(
|
||||||
|
new KeyShortcut(
|
||||||
|
'zen-compact-mode-show-toolbar',
|
||||||
|
'T',
|
||||||
|
'',
|
||||||
|
ZEN_COMPACT_MODE_SHORTCUTS_GROUP,
|
||||||
|
KeyShortcutModifiers.fromObject({ctrl: true, alt: true}),
|
||||||
|
'code:gZenCompactModeManager.toggleToolbar()',
|
||||||
|
'zen-compact-mode-shortcut-show-toolbar'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Workspace's keyset
|
||||||
|
// TODO:
|
||||||
|
for (let i = 10; i > 0; i--) {
|
||||||
|
newShortcutList.push(
|
||||||
|
new KeyShortcut(
|
||||||
|
`zen-workspace-switch-${i}`,
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
ZEN_WORKSPACE_SHORTCUTS_GROUP,
|
||||||
|
KeyShortcutModifiers.fromObject({}),
|
||||||
|
`code:ZenWorkspaces.shortcutSwitchTo(${i - 1})`,
|
||||||
|
`zen-workspace-shortcut-switch-${i}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
newShortcutList.push(
|
||||||
|
new KeyShortcut(
|
||||||
|
'zen-workspace-forward',
|
||||||
|
'E',
|
||||||
|
'',
|
||||||
|
ZEN_WORKSPACE_SHORTCUTS_GROUP,
|
||||||
|
KeyShortcutModifiers.fromObject({ctrl: true, alt: true}),
|
||||||
|
'code:ZenWorkspaces.changeWorkspaceShortcut()',
|
||||||
|
'zen-workspace-shortcut-forward'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
newShortcutList.push(
|
||||||
|
new KeyShortcut(
|
||||||
|
'zen-workspace-backward',
|
||||||
|
'Q',
|
||||||
|
'',
|
||||||
|
ZEN_WORKSPACE_SHORTCUTS_GROUP,
|
||||||
|
KeyShortcutModifiers.fromObject({ctrl: true, alt: true}),
|
||||||
|
'code:ZenWorkspaces.changeWorkspaceShortcut(-1)',
|
||||||
|
'zen-workspace-shortcut-backward'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Other keyset
|
||||||
|
newShortcutList.push(
|
||||||
|
new KeyShortcut(
|
||||||
|
'zen-toggle-web-panel',
|
||||||
|
'P',
|
||||||
|
'',
|
||||||
|
ZEN_OTHER_SHORTCUTS_GROUP,
|
||||||
|
KeyShortcutModifiers.fromObject({alt: true}),
|
||||||
|
'code:gZenBrowserManagerSidebar.toggle()',
|
||||||
|
'zen-web-panel-shortcut-toggle'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
newShortcutList.push(
|
||||||
|
new KeyShortcut(
|
||||||
|
'zen-toggle-sidebar',
|
||||||
|
'B',
|
||||||
|
'',
|
||||||
|
ZEN_OTHER_SHORTCUTS_GROUP,
|
||||||
|
KeyShortcutModifiers.fromObject({alt: true}),
|
||||||
|
'code:gZenVerticalTabsManager.toggleExpand()',
|
||||||
|
'zen-sidebar-shortcut-toggle'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return newShortcutList;
|
return newShortcutList;
|
||||||
},
|
},
|
||||||
|
|
||||||
_applyShortcuts() {
|
_applyShortcuts() {
|
||||||
console.debug('Applying shortcuts...');
|
for (const browser of ZenThemesCommon.browsers) {
|
||||||
|
let mainKeyset = browser.document.getElementById('mainKeyset');
|
||||||
let mainKeyset = document.getElementById('mainKeyset');
|
|
||||||
if (!mainKeyset) {
|
if (!mainKeyset) {
|
||||||
throw new Error('Main keyset not found');
|
throw new Error('Main keyset not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent = mainKeyset.parentElement;
|
let parent = mainKeyset.parentElement;
|
||||||
|
|
||||||
parent.removeChild(mainKeyset);
|
mainKeyset.remove();
|
||||||
mainKeyset.innerHTML = [];
|
const children = mainKeyset.children;
|
||||||
|
for (let i = children.length - 1; i >= 0; i--) {
|
||||||
|
let key = children[i];
|
||||||
|
key.remove();
|
||||||
|
}
|
||||||
if (mainKeyset.children.length > 0) {
|
if (mainKeyset.children.length > 0) {
|
||||||
throw new Error('Child list not empty');
|
throw new Error('Child list not empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let key of this._currentShortcutList) {
|
for (let key of this._currentShortcutList) {
|
||||||
let child = key.toXHTMLElement();
|
if (key.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let child = key.toXHTMLElement(browser);
|
||||||
mainKeyset.appendChild(child);
|
mainKeyset.appendChild(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.prepend(mainKeyset);
|
parent.prepend(mainKeyset);
|
||||||
console.debug('Shortcuts applied...');
|
console.debug('Shortcuts applied...');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async _saveShortcuts() {
|
async _saveShortcuts() {
|
||||||
|
@ -547,18 +641,20 @@ var gZenKeyboardShortcutsManager = {
|
||||||
await gZenKeyboardShortcutsStorage.save(json);
|
await gZenKeyboardShortcutsStorage.save(json);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
triggerShortcutRebuild() {
|
||||||
|
this._applyShortcuts();
|
||||||
|
},
|
||||||
|
|
||||||
async setShortcut(action, shortcut, modifiers) {
|
async setShortcut(action, shortcut, modifiers) {
|
||||||
if (!action) {
|
if (!action) {
|
||||||
throw new Error('Action cannot be null');
|
throw new Error('Action cannot be null');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsetting shortcut
|
// Unsetting shortcut
|
||||||
let filteredShortcuts = this._currentShortcutList.filter((key) => key.getAction() == action);
|
for (let targetShortcut of this._currentShortcutList) {
|
||||||
if (!filteredShortcuts) {
|
if (targetShortcut.getAction() != action) {
|
||||||
throw new Error('Shortcut for action ' + action + ' not found');
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let targetShortcut of filteredShortcuts) {
|
|
||||||
if (!shortcut && !modifiers) {
|
if (!shortcut && !modifiers) {
|
||||||
targetShortcut.clearKeybind();
|
targetShortcut.clearKeybind();
|
||||||
} else {
|
} else {
|
||||||
|
@ -567,9 +663,8 @@ var gZenKeyboardShortcutsManager = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.debug(this._currentShortcutList);
|
|
||||||
|
|
||||||
await this._saveShortcuts();
|
await this._saveShortcuts();
|
||||||
|
this.triggerShortcutRebuild();
|
||||||
},
|
},
|
||||||
|
|
||||||
async getModifiableShortcuts() {
|
async getModifiableShortcuts() {
|
||||||
|
@ -587,4 +682,19 @@ var gZenKeyboardShortcutsManager = {
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
checkForConflicts(shortcut, modifiers, id, action) {
|
||||||
|
for (let targetShortcut of this._currentShortcutList) {
|
||||||
|
if ((targetShortcut.getID() == id)
|
||||||
|
|| (action == targetShortcut.getAction())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetShortcut.getModifiers().equals(modifiers) && targetShortcut.getKeyNameOrCode() == shortcut) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -833,5 +833,12 @@ var ZenWorkspaces = {
|
||||||
}
|
}
|
||||||
return [activeWorkspaceUserContextId, true];
|
return [activeWorkspaceUserContextId, true];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async shortcutSwitchTo(index) {
|
||||||
|
const workspaces = await this._workspaces();
|
||||||
|
// The index may be out of bounds, so we need to wrap it around
|
||||||
|
const workspaceToSwitch = workspaces.workspaces[(index + workspaces.workspaces.length) % workspaces.workspaces.length];
|
||||||
|
await this.changeWorkspace(workspaceToSwitch);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue