Merge branch 'main' into fix/change-tab-workspace-duplicates

This commit is contained in:
Jan Hereš 2024-09-09 22:19:49 +02:00 committed by GitHub
commit 4fc5d9df94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 686 additions and 1109 deletions

View file

@ -3,349 +3,174 @@ const kZKSActions = {
// otherwise "oncommand=" will be added. // otherwise "oncommand=" will be added.
// Split view actions // Split view actions
zenSplitViewGrid: [ zenSplitViewGrid: ["gZenViewSplitter.toggleShortcut('grid')", 'zen-split-view-grid', 'split-view-action'],
"gZenViewSplitter.toggleShortcut('grid')", zenSplitViewVertical: ["gZenViewSplitter.toggleShortcut('vsep')", 'zen-split-view-vertical', 'split-view-action'],
"zen-split-view-grid", zenSplitViewHorizontal: ["gZenViewSplitter.toggleShortcut('hsep')", 'zen-split-view-horizontal', 'split-view-action'],
"split-view-action", zenSplitViewClose: ["gZenViewSplitter.toggleShortcut('unsplit')", 'zen-split-view-close', '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 // Workspace actions
zenChangeWorkspace: [ zenChangeWorkspace: ['ZenWorkspaces.changeWorkspaceShortcut()', 'zen-change-workspace', 'workspace-action'],
"ZenWorkspaces.changeWorkspaceShortcut()",
"zen-change-workspace",
"workspace-action",
],
// manage actions // manage actions
openNewTab: [ openNewTab: ['command:cmd_newNavigatorTabNoEvent', 'open-new-tab', 'tab-action'],
"command:cmd_newNavigatorTabNoEvent", duplicateTab: ["duplicateTabIn(gBrowser.selectedTab, 'tab')", 'duplicate-tab', 'tab-action'],
"open-new-tab", closeTab: ['command:cmd_close', 'close-tab', 'tab-action'],
"tab-action", openNewWindow: ['command:cmd_newNavigator', 'open-new-window', 'tab-action'],
], openNewPrivateWindow: ['command:Tools:PrivateBrowsing', 'open-new-private-window', 'tab-action'],
duplicateTab: [ closeWindow: ['command:cmd_closeWindow', 'close-window', 'tab-action'],
"duplicateTabIn(gBrowser.selectedTab, 'tab')", restoreLastTab: ['undoCloseTab()', 'restore-last-session', 'tab-action'],
"duplicate-tab", restoreLastWindow: ['command:History:UndoCloseWindow', 'restore-last-window', 'tab-action'],
"tab-action", showNextTab: ['gBrowser.tabContainer.advanceSelectedTab(1, true)', 'show-next-tab', 'tab-action'],
], showPreviousTab: ['gBrowser.tabContainer.advanceSelectedTab(-1, true)', 'show-previous-tab', 'tab-action'],
closeTab: ["command:cmd_close", "close-tab", "tab-action"], showAllTabsPanel: ['gTabsPanel.showAllTabsPanel()', 'show-all-tabs-panel', '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 // Compact mode actions
zenToggleCompactMode: [ zenToggleCompactMode: ['gZenCompactModeManager.toggle()', 'zen-toggle-compact-mode', 'compact-mode-action'],
"gZenCompactModeManager.toggle()",
"zen-toggle-compact-mode",
"compact-mode-action",
],
zenToggleCompactModeSidebar: [ zenToggleCompactModeSidebar: [
"gZenCompactModeManager.toggleSidebar()", 'gZenCompactModeManager.toggleSidebar()',
"zen-toggle-compact-mode-sidebar", 'zen-toggle-compact-mode-sidebar',
"compact-mode-action", 'compact-mode-action',
], ],
zenToggleCompactModeToolbar: [ zenToggleCompactModeToolbar: [
"gZenCompactModeManager.toggleToolbar()", 'gZenCompactModeManager.toggleToolbar()',
"zen-toggle-compact-mode-toolbar", 'zen-toggle-compact-mode-toolbar',
"compact-mode-action", 'compact-mode-action',
], ],
// Page actions // Page actions
sendWithMail: ["command:Browser:SendLink", "send-with-mail", "page-action"], sendWithMail: ['command:Browser:SendLink', 'send-with-mail', 'page-action'],
savePage: ["command:Browser:SavePage", "save-page", "page-action"], savePage: ['command:Browser:SavePage', 'save-page', 'page-action'],
printPage: ["command:cmd_print", "print-page", "page-action"], printPage: ['command:cmd_print', 'print-page', 'page-action'],
muteCurrentTab: ["command:cmd_toggleMute", "mute-current-tab", "page-action"], muteCurrentTab: ['command:cmd_toggleMute', 'mute-current-tab', 'page-action'],
showSourceOfPage: [ showSourceOfPage: ['command:View:PageSource', 'show-source-of-page', 'page-action'],
"command:View:PageSource", showPageInfo: ['command:View:PageInfo', 'show-page-info', 'page-action'],
"show-source-of-page",
"page-action",
],
showPageInfo: ["command:View:PageInfo", "show-page-info", "page-action"],
// Visible actions // Visible actions
zoomIn: ["command:cmd_fullZoomEnlarge", "zoom-in", "visible-action"], zoomIn: ['command:cmd_fullZoomEnlarge', 'zoom-in', 'visible-action'],
zoomOut: ["command:cmd_fullZoomReduce", "zoom-out", "visible-action"], zoomOut: ['command:cmd_fullZoomReduce', 'zoom-out', 'visible-action'],
resetZoom: ["command:cmd_fullZoomReset", "reset-zoom", "visible-action"], resetZoom: ['command:cmd_fullZoomReset', 'reset-zoom', 'visible-action'],
// History actions // History actions
back: ["command:Browser:Back", "back", "history-action"], back: ['command:Browser:Back', 'back', 'history-action'],
forward: ["command:Browser:Forward", "forward", "history-action"], forward: ['command:Browser:Forward', 'forward', 'history-action'],
stop: ["command:Browser:Stop", "stop", "history-action"], stop: ['command:Browser:Stop', 'stop', 'history-action'],
reload: ["command:Browser:Reload", "reload", "history-action"], reload: ['command:Browser:Reload', 'reload', 'history-action'],
forceReload: [ forceReload: ['command:Browser:ReloadSkipCache', 'force-reload', 'history-action'],
"command:Browser:ReloadSkipCache",
"force-reload",
"history-action",
],
// search actions // search actions
searchInThisPage: [ searchInThisPage: ["gLazyFindCommand('onFindCommand')", 'search-in-this-page', 'search-action'],
"gLazyFindCommand('onFindCommand')", showNextSearchResult: ["gLazyFindCommand('onFindAgainCommand', false)", 'show-next-search-result', 'search-action'],
"search-in-this-page", showPreviousSearchResult: ["gLazyFindCommand('onFindAgainCommand', true)", 'show-previous-search-result', 'search-action'],
"search-action", searchTheWeb: ['command:Tools:Search', 'search-the-web', '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 // Tools actions
openMigrationWizard: [ openMigrationWizard: ['command:cmd_file_importFromAnotherBrowser', 'open-migration-wizard', 'tools-action'],
"command:cmd_file_importFromAnotherBrowser", quitFromApplication: ['command:goQuitApplication', 'quit-from-application', 'tools-action'],
"open-migration-wizard", enterIntoCustomizeMode: ['gCustomizeMode.enter()', 'enter-into-customize-mode', 'tools-action'],
"tools-action", enterIntoOfflineMode: ['command:cmd_toggleOfflineStatus', 'enter-into-offline-mode', 'tools-action'],
], openScreenCapture: ['command:Browser:Screenshot', 'open-screen-capture', '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 // Bookmark actions
bookmarkThisPage: [ bookmarkThisPage: [
"BrowserPageActions.doCommandForAction(PageActions.actionForID('bookmark'), event, this);", "BrowserPageActions.doCommandForAction(PageActions.actionForID('bookmark'), event, this);",
"bookmark-this-page", 'bookmark-this-page',
"bookmark-action", 'bookmark-action',
], ],
openBookmarkAddTool: [ openBookmarkAddTool: [
"PlacesUIUtils.showBookmarkPagesDialog(PlacesCommandHook.uniqueCurrentPages)", 'PlacesUIUtils.showBookmarkPagesDialog(PlacesCommandHook.uniqueCurrentPages)',
"open-bookmark-add-tool", 'open-bookmark-add-tool',
"bookmark-action", 'bookmark-action',
],
openBookmarksManager: [
"SidebarController.toggle('viewBookmarksSidebar');",
"open-bookmarks-manager",
"bookmark-action",
], ],
openBookmarksManager: ["SidebarController.toggle('viewBookmarksSidebar');", 'open-bookmarks-manager', 'bookmark-action'],
toggleBookmarkToolbar: [ toggleBookmarkToolbar: [
"BookmarkingUI.toggleBookmarksToolbar('bookmark-tools')", "BookmarkingUI.toggleBookmarksToolbar('bookmark-tools')",
"toggle-bookmark-toolbar", 'toggle-bookmark-toolbar',
"bookmark-action", 'bookmark-action',
], ],
// Open Page actions // Open Page actions
openGeneralPreferences: [ openGeneralPreferences: ['openPreferences()', 'open-general-preferences', 'open-page-action'],
"openPreferences()", openPrivacyPreferences: ["openPreferences('panePrivacy')", 'open-privacy-preferences', 'open-page-action'],
"open-general-preferences", openWorkspacesPreferences: ["openPreferences('paneWorkspaces')", 'open-workspaces-preferences', 'open-page-action'],
"open-page-action", openContainersPreferences: ["openPreferences('paneContainers')", 'open-containers-preferences', 'open-page-action'],
], openSearchPreferences: ["openPreferences('paneSearch')", 'open-search-preferences', 'open-page-action'],
openPrivacyPreferences: [ openSyncPreferences: ["openPreferences('paneSync')", 'open-sync-preferences', 'open-page-action'],
"openPreferences('panePrivacy')", openTaskManager: ['command:View:AboutProcesses', 'open-task-manager', 'open-page-action'],
"open-privacy-preferences", openAddonsManager: ['command:Tools:Addons', 'open-addons-manager', 'open-page-action'],
"open-page-action", openHomePage: ['BrowserHome()', 'open-home-page', '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 // History actions
forgetHistory: ["command:Tools:Sanitize", "forget-history", "history-action"], forgetHistory: ['command:Tools:Sanitize', 'forget-history', 'history-action'],
quickForgetHistory: [ quickForgetHistory: ['PlacesUtils.history.clear(true)', 'quick-forget-history', 'history-action'],
"PlacesUtils.history.clear(true)", clearRecentHistory: ['command:cmd_closeWindow', 'clear-recent-history', 'history-action'],
"quick-forget-history", restoreLastSession: ['command:Browser:RestoreLastSession', 'restore-last-session', 'history-action'],
"history-action", searchHistory: ['command:History:SearchHistory', 'search-history', 'history-action'],
], manageHistory: ["PlacesCommandHook.showPlacesOrganizer('History')", 'manage-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 // Downloads actions
openDownloads: [ openDownloads: ['DownloadsPanel.showDownloadsHistory()', 'open-downloads', 'downloads-action'],
"DownloadsPanel.showDownloadsHistory()",
"open-downloads",
"downloads-action",
],
// Sidebar actions // Sidebar actions
showBookmarkSidebar: [ showBookmarkSidebar: ["SidebarController.show('viewBookmarksSidebar')", 'show-bookmark-sidebar', 'sidebar-action'],
"SidebarController.show('viewBookmarksSidebar')", showHistorySidebar: ["SidebarController.show('viewHistorySidebar')", 'show-history-sidebar', 'sidebar-action'],
"show-bookmark-sidebar", showSyncedTabsSidebar: ["SidebarController.show('viewTabsSidebar')", 'show-synced-tabs-sidebar', 'sidebar-action'],
"sidebar-action", reverseSidebarPosition: ['SidebarController.reversePosition()', 'reverse-sidebar', 'sidebar-action'],
], hideSidebar: ['SidebarController.hide()', 'hide-sidebar', 'sidebar-action'],
showHistorySidebar: [ toggleSidebar: ['SidebarController.toggle()', 'toggle-sidebar', 'sidebar-action'],
"SidebarController.show('viewHistorySidebar')", zenToggleWebPanels: ['gZenBrowserManagerSidebar.toggle()', 'zen-toggle-web-panels', 'sidebar-action'],
"show-history-sidebar", zenExpandSidebar: ['gZenVerticalTabsManager.toggleExpand()', 'zen-expand-sidebar', 'sidebar-action'],
"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 = { const kZenDefaultShortcuts = {
// Split view actions // Split view actions
zenSplitViewGrid: "Ctrl+Alt+G", zenSplitViewGrid: 'Ctrl+Alt+G',
zenSplitViewVertical: "Ctrl+Alt+V", zenSplitViewVertical: 'Ctrl+Alt+V',
zenSplitViewHorizontal: "Ctrl+Alt+H", zenSplitViewHorizontal: 'Ctrl+Alt+H',
zenSplitViewClose: "Ctrl+Alt+U", zenSplitViewClose: 'Ctrl+Alt+U',
// Workspace actions // Workspace actions
zenChangeWorkspace: "Ctrl+Shift+E", zenChangeWorkspace: 'Ctrl+Shift+E',
// Compact mode actions // Compact mode actions
zenToggleCompactMode: "Ctrl+Alt+C", zenToggleCompactMode: 'Ctrl+Alt+C',
zenToggleCompactModeSidebar: "Ctrl+Alt+S", zenToggleCompactModeSidebar: 'Ctrl+Alt+S',
zenToggleCompactModeToolbar: "Ctrl+Alt+T", zenToggleCompactModeToolbar: 'Ctrl+Alt+T',
// manage actions // manage actions
zenToggleWebPanels: "Alt+P", zenToggleWebPanels: 'Alt+P',
}; };
// Section: ZenKeyboardShortcuts // Section: ZenKeyboardShortcuts
const kZKSStorageKey = "zen.keyboard.shortcuts"; const kZKSStorageKey = 'zen.keyboard.shortcuts';
const kZKSKeyCodeMap = { const kZKSKeyCodeMap = {
F1: "VK_F1", F1: 'VK_F1',
F2: "VK_F2", F2: 'VK_F2',
F3: "VK_F3", F3: 'VK_F3',
F4: "VK_F4", F4: 'VK_F4',
F5: "VK_F5", F5: 'VK_F5',
F6: "VK_F6", F6: 'VK_F6',
F7: "VK_F7", F7: 'VK_F7',
F8: "VK_F8", F8: 'VK_F8',
F9: "VK_F9", F9: 'VK_F9',
F10: "VK_F10", F10: 'VK_F10',
F11: "VK_F11", F11: 'VK_F11',
F12: "VK_F12", F12: 'VK_F12',
TAB: "VK_TAB", TAB: 'VK_TAB',
ENTER: "VK_RETURN", ENTER: 'VK_RETURN',
ESCAPE: "VK_ESCAPE", ESCAPE: 'VK_ESCAPE',
SPACE: "VK_SPACE", SPACE: 'VK_SPACE',
ARROWLEFT: "VK_LEFT", ARROWLEFT: 'VK_LEFT',
ARROWRIGHT: "VK_RIGHT", ARROWRIGHT: 'VK_RIGHT',
ARROWUP: "VK_UP", ARROWUP: 'VK_UP',
ARROWDOWN: "VK_DOWN", ARROWDOWN: 'VK_DOWN',
DELETE: "VK_DELETE", DELETE: 'VK_DELETE',
BACKSPACE: "VK_BACK", BACKSPACE: 'VK_BACK',
}; };
var gZenKeyboardShortcuts = { var gZenKeyboardShortcuts = {
init() { init() {
if (!Services.prefs.getBoolPref("zen.keyboard.shortcuts.enabled")) { if (!Services.prefs.getBoolPref('zen.keyboard.shortcuts.enabled')) {
return; return;
} }
this._initShortcuts(); this._initShortcuts();
@ -361,7 +186,7 @@ var gZenKeyboardShortcuts = {
} }
this.__savedShortcuts = JSON.parse(data); this.__savedShortcuts = JSON.parse(data);
} catch (e) { } catch (e) {
console.error("Zen CKS: Error parsing saved shortcuts", e); console.error('Zen CKS: Error parsing saved shortcuts', e);
this.__savedShortcuts = {}; this.__savedShortcuts = {};
} }
} }
@ -382,34 +207,16 @@ var gZenKeyboardShortcuts = {
}, },
_parseDefaultShortcut(shortcut) { _parseDefaultShortcut(shortcut) {
let ctrl = shortcut.includes("Ctrl+"); let ctrl = shortcut.includes('Ctrl+');
let alt = shortcut.includes("Alt+"); let alt = shortcut.includes('Alt+');
let shift = shortcut.includes("Shift+"); let shift = shortcut.includes('Shift+');
let meta = shortcut.includes("Meta+"); let meta = shortcut.includes('Meta+');
let key = shortcut.replace(/Ctrl\+|Alt\+|Shift\+|Meta\+/g, ""); let key = shortcut.replace(/Ctrl\+|Alt\+|Shift\+|Meta\+/g, '');
if ( if (['Tab', 'Enter', 'Escape', 'Space', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(key)) {
[
"Tab",
"Enter",
"Escape",
"Space",
"ArrowLeft",
"ArrowRight",
"ArrowUp",
"ArrowDown",
].includes(key)
) {
return { ctrl, alt, shift, meta, key: undefined, keycode: key }; return { ctrl, alt, shift, meta, key: undefined, keycode: key };
} }
let isKeyCode = key.length > 1; let isKeyCode = key.length > 1;
return { return { ctrl, alt, shift, meta, key: isKeyCode ? undefined : key, keycode: isKeyCode ? key : undefined };
ctrl,
alt,
shift,
meta,
key: isKeyCode ? undefined : key,
keycode: isKeyCode ? key : undefined,
};
}, },
_addDefaultShortcuts() { _addDefaultShortcuts() {
@ -432,50 +239,42 @@ var gZenKeyboardShortcuts = {
}, },
_initShortcuts() { _initShortcuts() {
if (window.location.href == "chrome://browser/content/browser.xhtml") { if (window.location.href == 'chrome://browser/content/browser.xhtml') {
console.info("Zen CKS: Initializing shortcuts"); console.info('Zen CKS: Initializing shortcuts');
Services.prefs.addObserver( Services.prefs.addObserver(kZKSStorageKey, this._onShortcutChange.bind(this));
kZKSStorageKey, Services.prefs.addObserver('zen.keyboard.shortcuts.disable-firefox', this._disableFirefoxShortcuts.bind(this));
this._onShortcutChange.bind(this),
);
Services.prefs.addObserver(
"zen.keyboard.shortcuts.disable-firefox",
this._disableFirefoxShortcuts.bind(this),
);
this._initSavedShortcuts(); this._initSavedShortcuts();
this._disableFirefoxShortcuts(); this._disableFirefoxShortcuts();
} }
}, },
_disableFirefoxShortcuts() { _disableFirefoxShortcuts() {
let disable = Services.prefs.getBoolPref( let disable = Services.prefs.getBoolPref('zen.keyboard.shortcuts.disable-firefox');
"zen.keyboard.shortcuts.disable-firefox",
);
if (!disable) { if (!disable) {
return; return;
} }
window.SessionStore.promiseInitialized.then(() => { window.SessionStore.promiseInitialized.then(() => {
let keySet = document.getElementById("mainKeyset"); let keySet = document.getElementById('mainKeyset');
if (!keySet) { if (!keySet) {
throw new Error("Zen CKS: No main keyset found"); throw new Error('Zen CKS: No main keyset found');
} }
for (let child of keySet.children) { for (let child of keySet.children) {
if (!child.id.startsWith("zen-key_")) { if (!child.id.startsWith('zen-key_')) {
child.setAttribute("disabled", true); child.setAttribute('disabled', true);
} }
} }
console.info("Remove already exist shortcut keys"); console.info('Remove already exist shortcut keys');
}); });
}, },
_onShortcutChange() { _onShortcutChange() {
console.info("Zen CKS: Shortcut changed"); console.info('Zen CKS: Shortcut changed');
this.__savedShortcuts = null; this.__savedShortcuts = null;
this._initSavedShortcuts(true); this._initSavedShortcuts(true);
}, },
_getCommandAttribute(action) { _getCommandAttribute(action) {
if (action.startsWith("command:")) { if (action.startsWith('command:')) {
return `command="${action.substring(8)}"`; return `command="${action.substring(8)}"`;
} }
return `oncommand="${action}"`; return `oncommand="${action}"`;
@ -499,7 +298,7 @@ var gZenKeyboardShortcuts = {
modifiers = Object.keys(modifiers) modifiers = Object.keys(modifiers)
.filter((mod) => modifiers[mod]) .filter((mod) => modifiers[mod])
.join(","); .join(',');
if (keycode) { if (keycode) {
const key = kZKSKeyCodeMap[keycode] || keycode; const key = kZKSKeyCodeMap[keycode] || keycode;
@ -524,9 +323,9 @@ var gZenKeyboardShortcuts = {
}, },
_initSavedShortcuts(fromUpdate = false) { _initSavedShortcuts(fromUpdate = false) {
let keySet = document.getElementById("mainKeyset"); let keySet = document.getElementById('mainKeyset');
if (!keySet) { if (!keySet) {
throw new Error("Zen CKS: No main keyset found"); throw new Error('Zen CKS: No main keyset found');
} }
for (let action in kZKSActions) { for (let action in kZKSActions) {
@ -545,9 +344,9 @@ var gZenKeyboardShortcuts = {
}, },
_fixMeinKeyset() { _fixMeinKeyset() {
let keySet = document.getElementById("mainKeyset"); let keySet = document.getElementById('mainKeyset');
if (!keySet) { if (!keySet) {
throw new Error("Zen CKS: No main keyset found"); throw new Error('Zen CKS: No main keyset found');
} }
const parent = keySet.parentElement; const parent = keySet.parentElement;
// We need to re-append the main keyset to the document to make the shortcuts work // We need to re-append the main keyset to the document to make the shortcuts work
@ -564,15 +363,15 @@ var gZenKeyboardShortcuts = {
}, },
shortCutToString(shortcut) { shortCutToString(shortcut) {
let str = ""; let str = '';
if (shortcut.ctrl) { if (shortcut.ctrl) {
str += "Ctrl+"; str += "Ctrl+";
} }
if (shortcut.alt) { if (shortcut.alt) {
str += "Alt+"; str += 'Alt+';
} }
if (shortcut.shift) { if (shortcut.shift) {
str += "Shift+"; str += 'Shift+';
} }
if (shortcut.meta) { if (shortcut.meta) {
str += AppConstants.platform == "macosx" ? "Cmd+" : "Meta+"; str += AppConstants.platform == "macosx" ? "Cmd+" : "Meta+";

View file

@ -44,7 +44,7 @@ var ZenProfileDialogUI = {
_updateCurentProfileId() { _updateCurentProfileId() {
let currentProfile = ProfileService.currentProfile; let currentProfile = ProfileService.currentProfile;
if (!currentProfile) return; if (!currentProfile) return;
let nameContainer = document.getElementById("PanelUI-zen-profiles-current-name"); let nameContainer = document.getElementById('PanelUI-zen-profiles-current-name');
nameContainer.textContent = currentProfile.name; nameContainer.textContent = currentProfile.name;
}, },
@ -64,11 +64,12 @@ var ZenProfileDialogUI = {
// This should be rewritten in HTML eventually. // This should be rewritten in HTML eventually.
// TODO: it could be `window.browsingContext.topChromeWindow.gDialogBox.open` but it does not work with the callback? // TODO: it could be `window.browsingContext.topChromeWindow.gDialogBox.open` but it does not work with the callback?
window.browsingContext.topChromeWindow.openDialog( window.browsingContext.topChromeWindow.openDialog(
"chrome://mozapps/content/profile/createProfileWizard.xhtml", 'chrome://mozapps/content/profile/createProfileWizard.xhtml',
"", '',
"centerscreen,chrome,modal,titlebar", 'centerscreen,chrome,modal,titlebar',
ProfileService, ProfileService,
{ CreateProfile: async (profile) => { {
CreateProfile: async (profile) => {
try { try {
ProfileService.defaultProfile = profile; ProfileService.defaultProfile = profile;
this._flush(); this._flush();
@ -76,13 +77,14 @@ var ZenProfileDialogUI = {
} catch (e) { } catch (e) {
// This can happen on dev-edition. // This can happen on dev-edition.
let [title, msg] = await document.l10n.formatValues([ let [title, msg] = await document.l10n.formatValues([
{ id: "profiles-cannot-set-as-default-title" }, { id: 'profiles-cannot-set-as-default-title' },
{ id: "profiles-cannot-set-as-default-message" }, { id: 'profiles-cannot-set-as-default-message' },
]); ]);
Services.prompt.alert(window, title, msg); Services.prompt.alert(window, title, msg);
} }
} } },
}
); );
}, },
@ -92,14 +94,11 @@ var ZenProfileDialogUI = {
this._updateProfilesList(); this._updateProfilesList();
} catch (e) { } catch (e) {
let [title, msg, button] = await document.l10n.formatValues([ let [title, msg, button] = await document.l10n.formatValues([
{ id: "profiles-flush-fail-title" }, { id: 'profiles-flush-fail-title' },
{ {
id: id: e.result == Cr.NS_ERROR_DATABASE_CHANGED ? 'profiles-flush-conflict' : 'profiles-flush-failed',
e.result == Cr.NS_ERROR_DATABASE_CHANGED
? "profiles-flush-conflict"
: "profiles-flush-failed",
}, },
{ id: "profiles-flush-restart-button" }, { id: 'profiles-flush-restart-button' },
]); ]);
const PS = Ci.nsIPromptService; const PS = Ci.nsIPromptService;
@ -107,8 +106,7 @@ var ZenProfileDialogUI = {
window, window,
title, title,
msg, msg,
PS.BUTTON_POS_0 * PS.BUTTON_TITLE_CANCEL + PS.BUTTON_POS_0 * PS.BUTTON_TITLE_CANCEL + PS.BUTTON_POS_1 * PS.BUTTON_TITLE_IS_STRING,
PS.BUTTON_POS_1 * PS.BUTTON_TITLE_IS_STRING,
null, null,
button, button,
null, null,
@ -122,14 +120,8 @@ var ZenProfileDialogUI = {
}, },
_restart(safeMode) { _restart(safeMode) {
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance( let cancelQuit = Cc['@mozilla.org/supports-PRBool;1'].createInstance(Ci.nsISupportsPRBool);
Ci.nsISupportsPRBool Services.obs.notifyObservers(cancelQuit, 'quit-application-requested', 'restart');
);
Services.obs.notifyObservers(
cancelQuit,
"quit-application-requested",
"restart"
);
if (cancelQuit.data) { if (cancelQuit.data) {
return; return;
@ -142,5 +134,5 @@ var ZenProfileDialogUI = {
} else { } else {
Services.startup.quit(flags); Services.startup.quit(flags);
} }
} },
}; };

View file

@ -9,8 +9,7 @@ var gZenBrowserManagerSidebar = {
_isDragging: false, _isDragging: false,
contextTab: null, contextTab: null,
DEFAULT_MOBILE_USER_AGENT: DEFAULT_MOBILE_USER_AGENT: 'Mozilla/5.0 (Android 12; Mobile; rv:129.0) Gecko/20100101 Firefox/130.0',
"Mozilla/5.0 (Android 12; Mobile; rv:129.0) Gecko/20100101 Firefox/129.0",
MAX_SIDEBAR_PANELS: 8, // +1 for the add panel button MAX_SIDEBAR_PANELS: 8, // +1 for the add panel button
MAX_RUNS: 3, MAX_RUNS: 3,
@ -22,35 +21,28 @@ var gZenBrowserManagerSidebar = {
}, },
get sidebarData() { get sidebarData() {
let services = Services.prefs.getStringPref("zen.sidebar.data"); let services = Services.prefs.getStringPref('zen.sidebar.data');
if (services === "") { if (services === '') {
return {}; return {};
} }
return JSON.parse(services); return JSON.parse(services);
}, },
get shouldCloseOnBlur() { get shouldCloseOnBlur() {
return Services.prefs.getBoolPref("zen.sidebar.close-on-blur"); return Services.prefs.getBoolPref('zen.sidebar.close-on-blur');
}, },
listenForPrefChanges() { listenForPrefChanges() {
Services.prefs.addObserver("zen.sidebar.data", this.handleEvent.bind(this)); Services.prefs.addObserver('zen.sidebar.data', this.handleEvent.bind(this));
Services.prefs.addObserver( Services.prefs.addObserver('zen.sidebar.enabled', this.handleEvent.bind(this));
"zen.sidebar.enabled",
this.handleEvent.bind(this)
);
let sidebar = document.getElementById("zen-sidebar-web-panel"); let sidebar = document.getElementById('zen-sidebar-web-panel');
this.splitterElement.addEventListener( this.splitterElement.addEventListener(
"mousedown", 'mousedown',
function (event) { function (event) {
let computedStyle = window.getComputedStyle(sidebar); let computedStyle = window.getComputedStyle(sidebar);
let maxWidth = parseInt( let maxWidth = parseInt(computedStyle.getPropertyValue('max-width').replace('px', ''));
computedStyle.getPropertyValue("max-width").replace("px", "") let minWidth = parseInt(computedStyle.getPropertyValue('min-width').replace('px', ''));
);
let minWidth = parseInt(
computedStyle.getPropertyValue("min-width").replace("px", "")
);
if (!this._isDragging) { if (!this._isDragging) {
// Prevent multiple resizes // Prevent multiple resizes
@ -70,30 +62,25 @@ var gZenBrowserManagerSidebar = {
let mouseUp = function () { let mouseUp = function () {
this.handleEvent(); this.handleEvent();
this._isDragging = false; this._isDragging = false;
document.removeEventListener("mousemove", mouseMove); document.removeEventListener('mousemove', mouseMove);
document.removeEventListener("mouseup", mouseUp); document.removeEventListener('mouseup', mouseUp);
}.bind(this); }.bind(this);
document.addEventListener("mousemove", mouseMove); document.addEventListener('mousemove', mouseMove);
document.addEventListener("mouseup", mouseUp); document.addEventListener('mouseup', mouseUp);
} }
}.bind(this) }.bind(this)
); );
this.hSplitterElement.addEventListener( this.hSplitterElement.addEventListener(
"mousedown", 'mousedown',
function (event) { function (event) {
let computedStyle = window.getComputedStyle(sidebar); let computedStyle = window.getComputedStyle(sidebar);
const parent = sidebar.parentElement; const parent = sidebar.parentElement;
// relative to avoid the top margin // relative to avoid the top margin
// 20px is the padding // 20px is the padding
let parentRelativeHeight = let parentRelativeHeight =
parent.getBoundingClientRect().height - parent.getBoundingClientRect().height - parent.getBoundingClientRect().top + sidebar.getBoundingClientRect().top - 20;
parent.getBoundingClientRect().top + let minHeight = parseInt(computedStyle.getPropertyValue('min-height').replace('px', ''));
sidebar.getBoundingClientRect().top -
20;
let minHeight = parseInt(
computedStyle.getPropertyValue("min-height").replace("px", "")
);
if (!this._isDragging) { if (!this._isDragging) {
// Prevent multiple resizes // Prevent multiple resizes
this._isDragging = true; this._isDragging = true;
@ -113,11 +100,11 @@ var gZenBrowserManagerSidebar = {
let mouseUp = function () { let mouseUp = function () {
this.handleEvent(); this.handleEvent();
this._isDragging = false; this._isDragging = false;
document.removeEventListener("mousemove", mouseMove); document.removeEventListener('mousemove', mouseMove);
document.removeEventListener("mouseup", mouseUp); document.removeEventListener('mouseup', mouseUp);
}.bind(this); }.bind(this);
document.addEventListener("mousemove", mouseMove); document.addEventListener('mousemove', mouseMove);
document.addEventListener("mouseup", mouseUp); document.addEventListener('mouseup', mouseUp);
} }
}.bind(this) }.bind(this)
); );
@ -126,9 +113,7 @@ var gZenBrowserManagerSidebar = {
}, },
get isFloating() { get isFloating() {
return document return document.getElementById('zen-sidebar-web-panel').hasAttribute('pinned');
.getElementById("zen-sidebar-web-panel")
.hasAttribute("pinned");
}, },
handleEvent() { handleEvent() {
@ -140,40 +125,36 @@ var gZenBrowserManagerSidebar = {
var clickOutsideHandler = this._handleClickOutside.bind(this); var clickOutsideHandler = this._handleClickOutside.bind(this);
let isFloating = this.isFloating; let isFloating = this.isFloating;
if (isFloating && !this._hasRegisteredPinnedClickOutside) { if (isFloating && !this._hasRegisteredPinnedClickOutside) {
document.addEventListener("mouseup", clickOutsideHandler); document.addEventListener('mouseup', clickOutsideHandler);
this._hasRegisteredPinnedClickOutside = true; this._hasRegisteredPinnedClickOutside = true;
} else if (!isFloating && this._hasRegisteredPinnedClickOutside) { } else if (!isFloating && this._hasRegisteredPinnedClickOutside) {
document.removeEventListener("mouseup", clickOutsideHandler); document.removeEventListener('mouseup', clickOutsideHandler);
this._hasRegisteredPinnedClickOutside = false; this._hasRegisteredPinnedClickOutside = false;
} }
const button = document.getElementById("zen-sidepanel-button"); const button = document.getElementById('zen-sidepanel-button');
if (Services.prefs.getBoolPref("zen.sidebar.enabled")) { if (Services.prefs.getBoolPref('zen.sidebar.enabled')) {
button.removeAttribute("hidden"); button.removeAttribute('hidden');
} else { } else {
button.setAttribute("hidden", "true"); button.setAttribute('hidden', 'true');
this._closeSidebarPanel(); this._closeSidebarPanel();
return; return;
} }
}, },
_handleClickOutside(event) { _handleClickOutside(event) {
let sidebar = document.getElementById("zen-sidebar-web-panel"); let sidebar = document.getElementById('zen-sidebar-web-panel');
if ( if (!sidebar.hasAttribute('pinned') || this._isDragging || !this.shouldCloseOnBlur) {
!sidebar.hasAttribute("pinned") ||
this._isDragging ||
!this.shouldCloseOnBlur
) {
return; return;
} }
let target = event.target; let target = event.target;
const closestSelector = [ const closestSelector = [
"#zen-sidebar-web-panel", '#zen-sidebar-web-panel',
"#zen-sidebar-panels-wrapper", '#zen-sidebar-panels-wrapper',
"#zenWebPanelContextMenu", '#zenWebPanelContextMenu',
"#zen-sidebar-web-panel-splitter", '#zen-sidebar-web-panel-splitter',
"#contentAreaContextMenu", '#contentAreaContextMenu',
].join(", "); ].join(', ');
if (target.closest(closestSelector)) { if (target.closest(closestSelector)) {
return; return;
} }
@ -184,9 +165,7 @@ var gZenBrowserManagerSidebar = {
if (!this._currentPanel) { if (!this._currentPanel) {
this._currentPanel = this._lastOpenedPanel; this._currentPanel = this._lastOpenedPanel;
} }
if ( if (document.getElementById('zen-sidebar-web-panel').hasAttribute('hidden')) {
document.getElementById("zen-sidebar-web-panel").hasAttribute("hidden")
) {
this.open(); this.open();
return; return;
} }
@ -194,8 +173,8 @@ var gZenBrowserManagerSidebar = {
}, },
open() { open() {
let sidebar = document.getElementById("zen-sidebar-web-panel"); let sidebar = document.getElementById('zen-sidebar-web-panel');
sidebar.removeAttribute("hidden"); sidebar.removeAttribute('hidden');
this.update(); this.update();
}, },
@ -207,21 +186,19 @@ var gZenBrowserManagerSidebar = {
}, },
_updateSidebarButton() { _updateSidebarButton() {
let button = document.getElementById("zen-sidepanel-button"); let button = document.getElementById('zen-sidepanel-button');
if ( if (!document.getElementById('zen-sidebar-web-panel').hasAttribute('hidden')) {
!document.getElementById("zen-sidebar-web-panel").hasAttribute("hidden") button.setAttribute('open', 'true');
) {
button.setAttribute("open", "true");
} else { } else {
button.removeAttribute("open"); button.removeAttribute('open');
} }
}, },
_updateWebPanels() { _updateWebPanels() {
if (Services.prefs.getBoolPref("zen.sidebar.enabled")) { if (Services.prefs.getBoolPref('zen.sidebar.enabled')) {
this.sidebarElement.removeAttribute("hidden"); this.sidebarElement.removeAttribute('hidden');
} else { } else {
this.sidebarElement.setAttribute("hidden", "true"); this.sidebarElement.setAttribute('hidden', 'true');
this._closeSidebarPanel(); this._closeSidebarPanel();
return; return;
} }
@ -230,75 +207,67 @@ var gZenBrowserManagerSidebar = {
if (!data.data || !data.index) { if (!data.data || !data.index) {
return; return;
} }
this.sidebarElement.innerHTML = ""; this.sidebarElement.innerHTML = '';
for (let site of data.index) { for (let site of data.index) {
let panel = data.data[site]; let panel = data.data[site];
if (!panel || !panel.url) { if (!panel || !panel.url) {
continue; continue;
} }
let button = document.createXULElement("toolbarbutton"); let button = document.createXULElement('toolbarbutton');
button.classList.add( button.classList.add('zen-sidebar-panel-button', 'toolbarbutton-1', 'chromeclass-toolbar-additional');
"zen-sidebar-panel-button", button.setAttribute('flex', '1');
"toolbarbutton-1", button.setAttribute('zen-sidebar-id', site);
"chromeclass-toolbar-additional" button.setAttribute('context', 'zenWebPanelContextMenu');
);
button.setAttribute("flex", "1");
button.setAttribute("zen-sidebar-id", site);
button.setAttribute("context", "zenWebPanelContextMenu");
this._getWebPanelIcon(panel.url, button); this._getWebPanelIcon(panel.url, button);
button.addEventListener("click", this._handleClick.bind(this)); button.addEventListener('click', this._handleClick.bind(this));
button.addEventListener('dragstart', this._handleDragStart.bind(this)); button.addEventListener('dragstart', this._handleDragStart.bind(this));
button.addEventListener('dragover', this._handleDragOver.bind(this)); button.addEventListener('dragover', this._handleDragOver.bind(this));
button.addEventListener('dragenter', this._handleDragEnter.bind(this)); button.addEventListener('dragenter', this._handleDragEnter.bind(this));
button.addEventListener('dragend', this._handleDragEnd.bind(this)); button.addEventListener('dragend', this._handleDragEnd.bind(this));
this.sidebarElement.appendChild(button); this.sidebarElement.appendChild(button);
} }
const addButton = document.getElementById("zen-sidebar-add-panel-button"); const addButton = document.getElementById('zen-sidebar-add-panel-button');
if (data.index.length < this.MAX_SIDEBAR_PANELS) { if (data.index.length < this.MAX_SIDEBAR_PANELS) {
addButton.removeAttribute("hidden"); addButton.removeAttribute('hidden');
} else { } else {
addButton.setAttribute("hidden", "true"); addButton.setAttribute('hidden', 'true');
} }
}, },
async _openAddPanelDialog() { async _openAddPanelDialog() {
let dialogURL = "chrome://browser/content/places/zenNewWebPanel.xhtml"; let dialogURL = 'chrome://browser/content/places/zenNewWebPanel.xhtml';
let features = "centerscreen,chrome,modal,resizable=no"; let features = 'centerscreen,chrome,modal,resizable=no';
let aParentWindow = Services.wm.getMostRecentWindow("navigator:browser"); let aParentWindow = Services.wm.getMostRecentWindow('navigator:browser');
if (aParentWindow?.gDialogBox) { if (aParentWindow?.gDialogBox) {
await aParentWindow.gDialogBox.open(dialogURL, {}); await aParentWindow.gDialogBox.open(dialogURL, {});
} else { } else {
aParentWindow.openDialog(dialogURL, "", features, {}); aParentWindow.openDialog(dialogURL, '', features, {});
} }
}, },
_setPinnedToElements() { _setPinnedToElements() {
let sidebar = document.getElementById("zen-sidebar-web-panel"); let sidebar = document.getElementById('zen-sidebar-web-panel');
sidebar.setAttribute("pinned", "true"); sidebar.setAttribute('pinned', 'true');
document document.getElementById('zen-sidebar-web-panel-pinned').setAttribute('pinned', 'true');
.getElementById("zen-sidebar-web-panel-pinned")
.setAttribute("pinned", "true");
}, },
_removePinnedFromElements() { _removePinnedFromElements() {
let sidebar = document.getElementById("zen-sidebar-web-panel"); let sidebar = document.getElementById('zen-sidebar-web-panel');
sidebar.removeAttribute("pinned"); sidebar.removeAttribute('pinned');
document document.getElementById('zen-sidebar-web-panel-pinned').removeAttribute('pinned');
.getElementById("zen-sidebar-web-panel-pinned")
.removeAttribute("pinned");
}, },
_closeSidebarPanel() { _closeSidebarPanel() {
let sidebar = document.getElementById("zen-sidebar-web-panel"); let sidebar = document.getElementById('zen-sidebar-web-panel');
sidebar.setAttribute("hidden", "true"); sidebar.setAttribute('hidden', 'true');
this._lastOpenedPanel = this._currentPanel; this._lastOpenedPanel = this._currentPanel;
this._currentPanel = null; this._currentPanel = null;
}, },
_handleClick(event) { _handleClick(event) {
let target = event.target; let target = event.target;
let panelId = target.getAttribute("zen-sidebar-id"); let panelId = target.getAttribute('zen-sidebar-id');
if (this._currentPanel === panelId) { if (this._currentPanel === panelId) {
return; return;
} }
@ -316,8 +285,7 @@ var gZenBrowserManagerSidebar = {
event.dataTransfer.setData('text/plain', event.target.id); event.dataTransfer.setData('text/plain', event.target.id);
}, },
_handleDragOver(event) { _handleDragOver(event) {},
},
_handleDragEnter(event) { _handleDragEnter(event) {
const target = event.target; const target = event.target;
@ -336,52 +304,50 @@ var gZenBrowserManagerSidebar = {
let data = this.sidebarData; let data = this.sidebarData;
let newPos = []; let newPos = [];
for (let element of this.__dragingElement.parentNode.children) { for (let element of this.__dragingElement.parentNode.children) {
console.log(element) console.log(element);
let panelId = element.getAttribute("zen-sidebar-id"); let panelId = element.getAttribute('zen-sidebar-id');
newPos.push(panelId); newPos.push(panelId);
} }
data.index = newPos; data.index = newPos;
Services.prefs.setStringPref("zen.sidebar.data", JSON.stringify(data)); Services.prefs.setStringPref('zen.sidebar.data', JSON.stringify(data));
this._currentPanel = this.__dragingElement.getAttribute("zen-sidebar-id"); this._currentPanel = this.__dragingElement.getAttribute('zen-sidebar-id');
this.open(); this.open();
this.__dragingElement = undefined; this.__dragingElement = undefined;
}, },
_createNewPanel(url) { _createNewPanel(url) {
let data = this.sidebarData; let data = this.sidebarData;
let newName = "p" + new Date().getTime(); let newName = 'p' + new Date().getTime();
data.index.push(newName); data.index.push(newName);
data.data[newName] = { data.data[newName] = {
url: url, url: url,
ua: false, ua: false,
}; };
Services.prefs.setStringPref("zen.sidebar.data", JSON.stringify(data)); Services.prefs.setStringPref('zen.sidebar.data', JSON.stringify(data));
this._currentPanel = newName; this._currentPanel = newName;
this.open(); this.open();
}, },
_updateButtons() { _updateButtons() {
for (let button of this.sidebarElement.querySelectorAll( for (let button of this.sidebarElement.querySelectorAll('.zen-sidebar-panel-button')) {
".zen-sidebar-panel-button" if (button.getAttribute('zen-sidebar-id') === this._currentPanel) {
)) { button.setAttribute('selected', 'true');
if (button.getAttribute("zen-sidebar-id") === this._currentPanel) {
button.setAttribute("selected", "true");
} else { } else {
button.removeAttribute("selected"); button.removeAttribute('selected');
} }
} }
}, },
_hideAllWebPanels() { _hideAllWebPanels() {
let sidebar = document.getElementById("zen-sidebar-web-panel"); let sidebar = document.getElementById('zen-sidebar-web-panel');
for (let browser of sidebar.querySelectorAll("browser[zen-sidebar-id]")) { for (let browser of sidebar.querySelectorAll('browser[zen-sidebar-id]')) {
browser.setAttribute("hidden", "true"); browser.setAttribute('hidden', 'true');
browser.docShellIsActive = false; browser.docShellIsActive = false;
} }
}, },
get introductionPanel() { get introductionPanel() {
return document.getElementById("zen-sidebar-introduction-panel"); return document.getElementById('zen-sidebar-introduction-panel');
}, },
_updateWebPanel() { _updateWebPanel() {
@ -389,23 +355,20 @@ var gZenBrowserManagerSidebar = {
// let sidebar = document.getElementById("zen-sidebar-web-panel"); // let sidebar = document.getElementById("zen-sidebar-web-panel");
this._hideAllWebPanels(); this._hideAllWebPanels();
if (!this._currentPanel) { if (!this._currentPanel) {
this.introductionPanel.removeAttribute("hidden"); this.introductionPanel.removeAttribute('hidden');
return; return;
} }
this.introductionPanel.setAttribute("hidden", "true"); this.introductionPanel.setAttribute('hidden', 'true');
let existantWebview = this._getCurrentBrowser(); let existantWebview = this._getCurrentBrowser();
if (existantWebview) { if (existantWebview) {
existantWebview.docShellIsActive = true; existantWebview.docShellIsActive = true;
existantWebview.removeAttribute("hidden"); existantWebview.removeAttribute('hidden');
document.getElementById("zen-sidebar-web-panel-title").textContent = document.getElementById('zen-sidebar-web-panel-title').textContent = existantWebview.contentTitle;
existantWebview.contentTitle;
return; return;
} }
let data = this._getWebPanelData(this._currentPanel); let data = this._getWebPanelData(this._currentPanel);
let browser = this._createWebPanelBrowser(data); let browser = this._createWebPanelBrowser(data);
let browserContainers = document.getElementById( let browserContainers = document.getElementById('zen-sidebar-web-panel-browser-containers');
"zen-sidebar-web-panel-browser-containers"
);
browserContainers.appendChild(browser); browserContainers.appendChild(browser);
if (data.ua) { if (data.ua) {
browser.browsingContext.customUserAgent = this.DEFAULT_MOBILE_USER_AGENT; browser.browsingContext.customUserAgent = this.DEFAULT_MOBILE_USER_AGENT;
@ -426,26 +389,24 @@ var gZenBrowserManagerSidebar = {
}, },
_createWebPanelBrowser(data) { _createWebPanelBrowser(data) {
const titleContainer = document.getElementById( const titleContainer = document.getElementById('zen-sidebar-web-panel-title');
"zen-sidebar-web-panel-title" titleContainer.textContent = 'Loading...';
);
titleContainer.textContent = "Loading...";
let browser = gBrowser.createBrowser({}); let browser = gBrowser.createBrowser({});
browser.setAttribute("disablefullscreen", "true"); browser.setAttribute('disablefullscreen', 'true');
browser.setAttribute("src", data.url); browser.setAttribute('src', data.url);
browser.setAttribute("zen-sidebar-id", data.id); browser.setAttribute('zen-sidebar-id', data.id);
browser.setAttribute("autoscroll", "false"); browser.setAttribute('autoscroll', 'false');
browser.setAttribute("autocompletepopup", "PopupAutoComplete"); browser.setAttribute('autocompletepopup', 'PopupAutoComplete');
browser.setAttribute("contextmenu", "contentAreaContextMenu"); browser.setAttribute('contextmenu', 'contentAreaContextMenu');
browser.addEventListener( browser.addEventListener(
"pagetitlechanged", 'pagetitlechanged',
function (event) { function (event) {
let browser = event.target; let browser = event.target;
let title = browser.contentTitle; let title = browser.contentTitle;
if (!title) { if (!title) {
return; return;
} }
let id = browser.getAttribute("zen-sidebar-id"); let id = browser.getAttribute('zen-sidebar-id');
if (id === this._currentPanel) { if (id === this._currentPanel) {
titleContainer.textContent = title; titleContainer.textContent = title;
} }
@ -456,15 +417,13 @@ var gZenBrowserManagerSidebar = {
_getWebPanelIcon(url, element) { _getWebPanelIcon(url, element) {
let { preferredURI } = Services.uriFixup.getFixupURIInfo(url); let { preferredURI } = Services.uriFixup.getFixupURIInfo(url);
element.setAttribute("image", `page-icon:${preferredURI.spec}`); element.setAttribute('image', `page-icon:${preferredURI.spec}`);
fetch( fetch(`https://s2.googleusercontent.com/s2/favicons?domain_url=${preferredURI.spec}`).then(async (response) => {
`https://s2.googleusercontent.com/s2/favicons?domain_url=${preferredURI.spec}`
).then(async (response) => {
if (response.ok) { if (response.ok) {
let blob = await response.blob(); let blob = await response.blob();
let reader = new FileReader(); let reader = new FileReader();
reader.onload = function () { reader.onload = function () {
element.setAttribute("image", reader.result); element.setAttribute('image', reader.result);
}; };
reader.readAsDataURL(blob); reader.readAsDataURL(blob);
} }
@ -472,7 +431,7 @@ var gZenBrowserManagerSidebar = {
}, },
_getBrowserById(id) { _getBrowserById(id) {
let sidebar = document.getElementById("zen-sidebar-web-panel"); let sidebar = document.getElementById('zen-sidebar-web-panel');
return sidebar.querySelector(`browser[zen-sidebar-id="${id}"]`); return sidebar.querySelector(`browser[zen-sidebar-id="${id}"]`);
}, },
@ -515,8 +474,8 @@ var gZenBrowserManagerSidebar = {
}, },
togglePinned(elem) { togglePinned(elem) {
let sidebar = document.getElementById("zen-sidebar-web-panel"); let sidebar = document.getElementById('zen-sidebar-web-panel');
if (sidebar.hasAttribute("pinned")) { if (sidebar.hasAttribute('pinned')) {
this._removePinnedFromElements(); this._removePinnedFromElements();
} else { } else {
this._setPinnedToElements(); this._setPinnedToElements();
@ -526,27 +485,21 @@ var gZenBrowserManagerSidebar = {
get sidebarElement() { get sidebarElement() {
if (!this._sidebarElement) { if (!this._sidebarElement) {
this._sidebarElement = document.getElementById( this._sidebarElement = document.getElementById('zen-sidebar-panels-sites');
"zen-sidebar-panels-sites"
);
} }
return this._sidebarElement; return this._sidebarElement;
}, },
get splitterElement() { get splitterElement() {
if (!this._splitterElement) { if (!this._splitterElement) {
this._splitterElement = document.getElementById( this._splitterElement = document.getElementById('zen-sidebar-web-panel-splitter');
"zen-sidebar-web-panel-splitter"
);
} }
return this._splitterElement; return this._splitterElement;
}, },
get hSplitterElement() { get hSplitterElement() {
if (!this._hSplitterElement) { if (!this._hSplitterElement) {
this._hSplitterElement = document.getElementById( this._hSplitterElement = document.getElementById('zen-sidebar-web-panel-hsplitter');
"zen-sidebar-web-panel-hsplitter"
);
} }
return this._hSplitterElement; return this._hSplitterElement;
}, },
@ -555,45 +508,33 @@ var gZenBrowserManagerSidebar = {
updateContextMenu(aPopupMenu) { updateContextMenu(aPopupMenu) {
let panel = let panel =
aPopupMenu.triggerNode && aPopupMenu.triggerNode && (aPopupMenu.triggerNode || aPopupMenu.triggerNode.closest('toolbarbutton[zen-sidebar-id]'));
(aPopupMenu.triggerNode ||
aPopupMenu.triggerNode.closest("toolbarbutton[zen-sidebar-id]"));
if (!panel) { if (!panel) {
return; return;
} }
let id = panel.getAttribute("zen-sidebar-id"); let id = panel.getAttribute('zen-sidebar-id');
this.contextTab = id; this.contextTab = id;
let data = this._getWebPanelData(id); let data = this._getWebPanelData(id);
let browser = this._getBrowserById(id); let browser = this._getBrowserById(id);
let isMuted = browser && browser.audioMuted; let isMuted = browser && browser.audioMuted;
let mutedContextItem = document.getElementById( let mutedContextItem = document.getElementById('context_zenToggleMuteWebPanel');
"context_zenToggleMuteWebPanel"
);
document.l10n.setAttributes( document.l10n.setAttributes(
mutedContextItem, mutedContextItem,
!isMuted !isMuted ? 'zen-web-side-panel-context-mute-panel' : 'zen-web-side-panel-context-unmute-panel'
? "zen-web-side-panel-context-mute-panel"
: "zen-web-side-panel-context-unmute-panel"
); );
if (!isMuted) { if (!isMuted) {
mutedContextItem.setAttribute("muted", "true"); mutedContextItem.setAttribute('muted', 'true');
} else { } else {
mutedContextItem.removeAttribute("muted"); mutedContextItem.removeAttribute('muted');
} }
document.l10n.setAttributes( document.l10n.setAttributes(
document.getElementById("context_zenToogleUAWebPanel"), document.getElementById('context_zenToogleUAWebPanel'),
data.ua data.ua ? 'zen-web-side-panel-context-disable-ua' : 'zen-web-side-panel-context-enable-ua'
? "zen-web-side-panel-context-disable-ua"
: "zen-web-side-panel-context-enable-ua"
); );
if (!browser) { if (!browser) {
document document.getElementById('context_zenUnloadWebPanel').setAttribute('disabled', 'true');
.getElementById("context_zenUnloadWebPanel")
.setAttribute("disabled", "true");
} else { } else {
document document.getElementById('context_zenUnloadWebPanel').removeAttribute('disabled');
.getElementById("context_zenUnloadWebPanel")
.removeAttribute("disabled");
} }
}, },
@ -617,13 +558,10 @@ var gZenBrowserManagerSidebar = {
contextToggleUserAgent() { contextToggleUserAgent() {
let browser = this._getBrowserById(this.contextTab); let browser = this._getBrowserById(this.contextTab);
browser.browsingContext.customUserAgent = browser.browsingContext browser.browsingContext.customUserAgent = browser.browsingContext.customUserAgent ? null : this.DEFAULT_MOBILE_USER_AGENT;
.customUserAgent
? null
: this.DEFAULT_MOBILE_USER_AGENT;
let data = this.sidebarData; let data = this.sidebarData;
data.data[this.contextTab].ua = !data.data[this.contextTab].ua; data.data[this.contextTab].ua = !data.data[this.contextTab].ua;
Services.prefs.setStringPref("zen.sidebar.data", JSON.stringify(data)); Services.prefs.setStringPref('zen.sidebar.data', JSON.stringify(data));
browser.reload(); browser.reload();
}, },
@ -634,42 +572,35 @@ var gZenBrowserManagerSidebar = {
let browser = this._getBrowserById(this.contextTab); let browser = this._getBrowserById(this.contextTab);
if (browser) { if (browser) {
browser.remove(); browser.remove();
document.getElementById("zen-sidebar-web-panel-title").textContent = ""; document.getElementById('zen-sidebar-web-panel-title').textContent = '';
} }
this._currentPanel = null; this._currentPanel = null;
this._lastOpenedPanel = null; this._lastOpenedPanel = null;
this.update(); this.update();
Services.prefs.setStringPref("zen.sidebar.data", JSON.stringify(data)); Services.prefs.setStringPref('zen.sidebar.data', JSON.stringify(data));
}, },
contextUnload() { contextUnload() {
let browser = this._getBrowserById(this.contextTab); let browser = this._getBrowserById(this.contextTab);
browser.remove(); browser.remove();
document.getElementById("zen-sidebar-web-panel-title").textContent = ""; document.getElementById('zen-sidebar-web-panel-title').textContent = '';
this._closeSidebarPanel(); this._closeSidebarPanel();
this.close(); this.close();
this._lastOpenedPanel = null; this._lastOpenedPanel = null;
}, },
insertIntoContextMenu() { insertIntoContextMenu() {
const sibling = document.getElementById("context-stripOnShareLink"); const sibling = document.getElementById('context-stripOnShareLink');
const menuitem = document.createXULElement("menuitem"); const menuitem = document.createXULElement('menuitem');
menuitem.setAttribute("id", "context-zenAddToWebPanel"); menuitem.setAttribute('id', 'context-zenAddToWebPanel');
menuitem.setAttribute("hidden", "true"); menuitem.setAttribute('hidden', 'true');
menuitem.setAttribute( menuitem.setAttribute('oncommand', 'gZenBrowserManagerSidebar.addPanelFromContextMenu();');
"oncommand", menuitem.setAttribute('data-l10n-id', 'zen-web-side-panel-context-add-to-panel');
"gZenBrowserManagerSidebar.addPanelFromContextMenu();" sibling.insertAdjacentElement('afterend', menuitem);
);
menuitem.setAttribute(
"data-l10n-id",
"zen-web-side-panel-context-add-to-panel"
);
sibling.insertAdjacentElement("afterend", menuitem);
}, },
addPanelFromContextMenu() { addPanelFromContextMenu() {
const url = const url = gContextMenu.linkURL || gContextMenu.target.ownerDocument.location.href;
gContextMenu.linkURL || gContextMenu.target.ownerDocument.location.href;
this._createNewPanel(url); this._createNewPanel(url);
}, },
}; };

View file

@ -1,5 +1,4 @@
const kZenAccentColorConfigKey = 'zen.theme.accent-color';
const kZenAccentColorConfigKey = "zen.theme.accent-color";
var gZenThemeBuilder = { var gZenThemeBuilder = {
init() { init() {
@ -14,7 +13,7 @@ var gZenThemeBuilder = {
if (this.__builderWrapper) { if (this.__builderWrapper) {
return this.__builderWrapper; return this.__builderWrapper;
} }
this.__builderWrapper = document.getElementById("zen-theme-builder-wrapper"); this.__builderWrapper = document.getElementById('zen-theme-builder-wrapper');
return this.__builderWrapper; return this.__builderWrapper;
}, },
@ -24,7 +23,7 @@ var gZenThemeBuilder = {
return; return;
} }
console.info("gZenThemeBuilder: init builder UI"); console.info('gZenThemeBuilder: init builder UI');
const kTemplate = ` const kTemplate = `
<html:div id="zen-theme-builder"> <html:div id="zen-theme-builder">
@ -46,18 +45,20 @@ var gZenThemeBuilder = {
data = ctx.getImageData(0, 0, w, h), /// get image data data = ctx.getImageData(0, 0, w, h), /// get image data
buffer = data.data, /// and its pixel buffer buffer = data.data, /// and its pixel buffer
len = buffer.length, /// cache length len = buffer.length, /// cache length
x, y = 0, p, px; /// for iterating x,
y = 0,
p,
px; /// for iterating
/// iterating x/y instead of forward to get position the easy way /// iterating x/y instead of forward to get position the easy way
for(;y < h; y++) { for (; y < h; y++) {
/// common value for all x /// common value for all x
p = y * 4 * w; p = y * 4 * w;
for(x = 0; x < w; x++) { for (x = 0; x < w; x++) {
/// next pixel (skipping 4 bytes as each pixel is RGBA bytes) /// next pixel (skipping 4 bytes as each pixel is RGBA bytes)
px = p + x * 4; px = p + x * 4;
/// if red component match check the others /// if red component match check the others
if (buffer[px] === color[0]) { if (buffer[px] === color[0]) {
if (buffer[px + 1] === color[1] && if (buffer[px + 1] === color[1] && buffer[px + 2] === color[2]) {
buffer[px + 2] === color[2]) {
return [x, y]; return [x, y];
} }
} }
@ -68,30 +69,26 @@ var gZenThemeBuilder = {
_hexToRgb(hex) { _hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return [ return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)];
parseInt(result[1], 16),
parseInt(result[2], 16),
parseInt(result[3], 16)
]
}, },
_componentToHex(c) { _componentToHex(c) {
var hex = c.toString(16); var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex; return hex.length == 1 ? '0' + hex : hex;
}, },
_rgbToHex(r, g, b) { _rgbToHex(r, g, b) {
return "#" + this._componentToHex(r) + this._componentToHex(g) + this._componentToHex(b); return '#' + this._componentToHex(r) + this._componentToHex(g) + this._componentToHex(b);
}, },
_initColorPicker() { _initColorPicker() {
const canvas = document.getElementById("zen-theme-builder-color-picker-canvas"); const canvas = document.getElementById('zen-theme-builder-color-picker-canvas');
const thumb = document.getElementById("zen-theme-builder-color-picker-thumb"); const thumb = document.getElementById('zen-theme-builder-color-picker-thumb');
// A all the main colors are all blended together towards the center. // A all the main colors are all blended together towards the center.
// But we also add some random gradients to make it look more interesting. // But we also add some random gradients to make it look more interesting.
// Instead of using a simple gradient, we use a radial gradient. // Instead of using a simple gradient, we use a radial gradient.
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext('2d');
const size = 180; const size = 180;
canvas.width = size; canvas.width = size;
canvas.height = size; canvas.height = size;
@ -123,7 +120,7 @@ var gZenThemeBuilder = {
//ctx.fillRect(0, 0, size, size); //ctx.fillRect(0, 0, size, size);
// Add the thumb. // Add the thumb.
const accentColor = Services.prefs.getStringPref(kZenAccentColorConfigKey, "#aac7ff"); const accentColor = Services.prefs.getStringPref(kZenAccentColorConfigKey, '#aac7ff');
const pos = this._getPositionFromColor(ctx, this._hexToRgb(accentColor)); const pos = this._getPositionFromColor(ctx, this._hexToRgb(accentColor));
let x = pos ? pos[0] : center; let x = pos ? pos[0] : center;
@ -132,23 +129,23 @@ var gZenThemeBuilder = {
thumb.style.left = `${x}px`; thumb.style.left = `${x}px`;
thumb.style.top = `${y}px`; thumb.style.top = `${y}px`;
thumb.addEventListener("mousedown", this._handleThumbMouseDown.bind(this)); thumb.addEventListener('mousedown', this._handleThumbMouseDown.bind(this));
document.addEventListener("mouseup", this._handleThumbMouseUp.bind(this)); document.addEventListener('mouseup', this._handleThumbMouseUp.bind(this));
}, },
_handleThumbMouseDown(e) { _handleThumbMouseDown(e) {
document.addEventListener("mousemove", this._mouseMoveListener); document.addEventListener('mousemove', this._mouseMoveListener);
}, },
_handleThumbMouseUp(e) { _handleThumbMouseUp(e) {
document.removeEventListener("mousemove", this._mouseMoveListener); document.removeEventListener('mousemove', this._mouseMoveListener);
}, },
_handleThumbMouseMove(e) { _handleThumbMouseMove(e) {
const kThumbOffset = 15; const kThumbOffset = 15;
const deck = document.getElementById("zen-theme-builder-color-picker-deck"); const deck = document.getElementById('zen-theme-builder-color-picker-deck');
const thumb = document.getElementById("zen-theme-builder-color-picker-thumb"); const thumb = document.getElementById('zen-theme-builder-color-picker-thumb');
const rect = deck.getBoundingClientRect(); const rect = deck.getBoundingClientRect();
let x = e.clientX - rect.left; let x = e.clientX - rect.left;
let y = e.clientY - rect.top; let y = e.clientY - rect.top;
@ -169,8 +166,8 @@ var gZenThemeBuilder = {
thumb.style.left = `${x}px`; thumb.style.left = `${x}px`;
thumb.style.top = `${y}px`; thumb.style.top = `${y}px`;
const canvas = document.getElementById("zen-theme-builder-color-picker-canvas"); const canvas = document.getElementById('zen-theme-builder-color-picker-canvas');
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(x, y, 1, 1); const imageData = ctx.getImageData(x, y, 1, 1);
// Update the accent color. // Update the accent color.

View file

@ -1,4 +1,3 @@
const kZenStylesheetThemeHeader = ` const kZenStylesheetThemeHeader = `
/* Zen Themes - Generated by ZenThemeImporter. /* Zen Themes - Generated by ZenThemeImporter.
* DO NOT EDIT THIS FILE DIRECTLY! * DO NOT EDIT THIS FILE DIRECTLY!
@ -21,7 +20,7 @@ var gZenStylesheetManager = {
}, },
getThemeCSS(theme) { getThemeCSS(theme) {
let css = "\n"; let css = '\n';
if (theme._readmeURL) { if (theme._readmeURL) {
css += `/* Name: ${theme.name} */\n`; css += `/* Name: ${theme.name} */\n`;
css += `/* Description: ${theme.description} */\n`; css += `/* Description: ${theme.description} */\n`;
@ -30,51 +29,40 @@ var gZenStylesheetManager = {
} }
css += `@import url("${theme._chromeURL}");\n`; css += `@import url("${theme._chromeURL}");\n`;
return css; return css;
} },
}; };
var gZenThemeImporter = new class { var gZenThemeImporter = new (class {
constructor() { constructor() {
console.info("ZenThemeImporter: Initiating Zen theme importer"); console.info('ZenThemeImporter: Initiating Zen theme importer');
try { try {
window.SessionStore.promiseInitialized.then(() => { window.SessionStore.promiseInitialized.then(() => {
this.insertStylesheet(); this.insertStylesheet();
}); });
console.info("ZenThemeImporter: Zen theme imported"); console.info('ZenThemeImporter: Zen theme imported');
} catch (e) { } catch (e) {
console.error("ZenThemeImporter: Error importing Zen theme: ", e); console.error('ZenThemeImporter: Error importing Zen theme: ', e);
} }
Services.prefs.addObserver("zen.themes.updated-value-observer", this.rebuildThemeStylesheet.bind(this), false); Services.prefs.addObserver('zen.themes.updated-value-observer', this.rebuildThemeStylesheet.bind(this), false);
} }
get sss() { get sss() {
if (!this._sss) { if (!this._sss) {
this._sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); this._sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
} }
return this._sss; return this._sss;
} }
get styleSheetPath() { get styleSheetPath() {
return PathUtils.join( return PathUtils.join(PathUtils.profileDir, 'chrome', 'zen-themes.css');
PathUtils.profileDir,
"chrome",
"zen-themes.css"
);
} }
get themesRootPath() { get themesRootPath() {
return PathUtils.join( return PathUtils.join(PathUtils.profileDir, 'chrome', 'zen-themes');
PathUtils.profileDir,
"chrome",
"zen-themes"
);
} }
get themesDataFile() { get themesDataFile() {
return PathUtils.join( return PathUtils.join(PathUtils.profileDir, 'zen-themes.json');
PathUtils.profileDir,
"zen-themes.json"
);
} }
getThemeFolder(theme) { getThemeFolder(theme) {
@ -104,7 +92,7 @@ var gZenThemeImporter = new class {
} }
getStylesheetURIForTheme(theme) { getStylesheetURIForTheme(theme) {
return Services.io.newFileURI(new FileUtils.File(PathUtils.join(this.getThemeFolder(theme), "chrome.css"))); return Services.io.newFileURI(new FileUtils.File(PathUtils.join(this.getThemeFolder(theme), 'chrome.css')));
} }
insertStylesheet() { insertStylesheet() {
@ -124,7 +112,7 @@ var gZenThemeImporter = new class {
} }
async writeStylesheet() { async writeStylesheet() {
const themes = [] const themes = [];
this._themes = null; this._themes = null;
for (let theme of Object.values(await this.getThemes())) { for (let theme of Object.values(await this.getThemes())) {
theme._chromeURL = this.getStylesheetURIForTheme(theme).spec; theme._chromeURL = this.getStylesheetURIForTheme(theme).spec;
@ -132,4 +120,4 @@ var gZenThemeImporter = new class {
} }
await gZenStylesheetManager.writeStylesheet(this.styleSheetPath, themes); await gZenStylesheetManager.writeStylesheet(this.styleSheetPath, themes);
} }
}; })();

View file

@ -1,5 +1,4 @@
var gZenViewSplitter = new (class {
var gZenViewSplitter = new class {
constructor() { constructor() {
this._data = []; this._data = [];
this.currentView = -1; this.currentView = -1;
@ -7,22 +6,22 @@ var gZenViewSplitter = new class {
this.__modifierElement = null; this.__modifierElement = null;
this.__hasSetMenuListener = false; this.__hasSetMenuListener = false;
window.addEventListener("TabClose", this.handleTabClose.bind(this)); window.addEventListener('TabClose', this.handleTabClose.bind(this));
this.initializeContextMenu(); this.initializeContextMenu();
this.insertPageActionButton(); this.insertPageActionButton();
this.insertIntoContextMenu(); this.insertIntoContextMenu();
} }
insertIntoContextMenu() { insertIntoContextMenu() {
const sibling = document.getElementById("context-stripOnShareLink"); const sibling = document.getElementById('context-stripOnShareLink');
const menuitem = document.createXULElement("menuitem"); const menuitem = document.createXULElement('menuitem');
menuitem.setAttribute("id", "context-zenSplitLink"); menuitem.setAttribute('id', 'context-zenSplitLink');
menuitem.setAttribute("hidden", "true"); menuitem.setAttribute('hidden', 'true');
menuitem.setAttribute("oncommand", "gZenViewSplitter.splitLinkInNewTab();"); menuitem.setAttribute('oncommand', 'gZenViewSplitter.splitLinkInNewTab();');
menuitem.setAttribute("data-l10n-id", "zen-split-link"); menuitem.setAttribute('data-l10n-id', 'zen-split-link');
sibling.insertAdjacentElement("afterend", document.createXULElement("menuseparator")); sibling.insertAdjacentElement('afterend', document.createXULElement('menuseparator'));
sibling.insertAdjacentElement("afterend", menuitem); sibling.insertAdjacentElement('afterend', menuitem);
sibling.insertAdjacentElement("afterend", document.createXULElement("menuseparator")); sibling.insertAdjacentElement('afterend', document.createXULElement('menuseparator'));
} }
/** /**
@ -31,7 +30,7 @@ var gZenViewSplitter = new class {
*/ */
handleTabClose(event) { handleTabClose(event) {
const tab = event.target; const tab = event.target;
const groupIndex = this._data.findIndex(group => group.tabs.includes(tab)); const groupIndex = this._data.findIndex((group) => group.tabs.includes(tab));
if (groupIndex < 0) { if (groupIndex < 0) {
return; return;
} }
@ -68,14 +67,14 @@ var gZenViewSplitter = new class {
resetTabState(tab, forUnsplit) { resetTabState(tab, forUnsplit) {
tab.splitView = false; tab.splitView = false;
tab.linkedBrowser.zenModeActive = false; tab.linkedBrowser.zenModeActive = false;
const container = tab.linkedBrowser.closest(".browserSidebarContainer"); const container = tab.linkedBrowser.closest('.browserSidebarContainer');
container.removeAttribute("zen-split"); container.removeAttribute('zen-split');
container.removeAttribute("style"); container.removeAttribute('style');
if (!forUnsplit) { if (!forUnsplit) {
tab.linkedBrowser.docShellIsActive = false; tab.linkedBrowser.docShellIsActive = false;
} else { } else {
container.style.gridArea = "1 / 1"; container.style.gridArea = '1 / 1';
} }
} }
@ -100,24 +99,21 @@ var gZenViewSplitter = new class {
} }
this.currentView = -1; this.currentView = -1;
this.tabBrowserPanel.removeAttribute("zen-split-view"); this.tabBrowserPanel.removeAttribute('zen-split-view');
this.tabBrowserPanel.style.gridTemplateAreas = ""; this.tabBrowserPanel.style.gridTemplateAreas = '';
} }
/** /**
* context menu item display update * context menu item display update
*/ */
insetUpdateContextMenuItems() { insetUpdateContextMenuItems() {
const contentAreaContextMenu = document.getElementById("tabContextMenu"); const contentAreaContextMenu = document.getElementById('tabContextMenu');
contentAreaContextMenu.addEventListener("popupshowing", () => { contentAreaContextMenu.addEventListener('popupshowing', () => {
const tabCountInfo = JSON.stringify({ const tabCountInfo = JSON.stringify({
tabCount: window.gBrowser.selectedTabs.length, tabCount: window.gBrowser.selectedTabs.length,
}); });
document document.getElementById('context_zenSplitTabs').setAttribute('data-l10n-args', tabCountInfo);
.getElementById("context_zenSplitTabs") document.getElementById('context_zenSplitTabs').disabled = !this.contextCanSplitTabs();
.setAttribute("data-l10n-args", tabCountInfo);
document.getElementById("context_zenSplitTabs").disabled =
!this.contextCanSplitTabs();
}); });
} }
@ -132,7 +128,7 @@ var gZenViewSplitter = new class {
oncommand="gZenViewSplitter.contextSplitTabs();"/> oncommand="gZenViewSplitter.contextSplitTabs();"/>
<menuseparator/> <menuseparator/>
`); `);
document.getElementById("context_closeDuplicateTabs").after(element); document.getElementById('context_closeDuplicateTabs').after(element);
} }
/** /**
@ -157,7 +153,7 @@ var gZenViewSplitter = new class {
class="urlbar-icon"/> class="urlbar-icon"/>
</hbox> </hbox>
`); `);
document.getElementById("star-button-box").after(element); document.getElementById('star-button-box').after(element);
} }
/** /**
@ -167,7 +163,7 @@ var gZenViewSplitter = new class {
*/ */
get tabBrowserPanel() { get tabBrowserPanel() {
if (!this._tabBrowserPanel) { if (!this._tabBrowserPanel) {
this._tabBrowserPanel = document.getElementById("tabbrowser-tabpanels"); this._tabBrowserPanel = document.getElementById('tabbrowser-tabpanels');
} }
return this._tabBrowserPanel; return this._tabBrowserPanel;
} }
@ -176,9 +172,7 @@ var gZenViewSplitter = new class {
* Splits a link in a new tab. * Splits a link in a new tab.
*/ */
splitLinkInNewTab() { splitLinkInNewTab() {
const url = const url = window.gContextMenu.linkURL || window.gContextMenu.target.ownerDocument.location.href;
window.gContextMenu.linkURL ||
window.gContextMenu.target.ownerDocument.location.href;
const currentTab = window.gBrowser.selectedTab; const currentTab = window.gBrowser.selectedTab;
const newTab = this.openAndSwitchToTab(url); const newTab = this.openAndSwitchToTab(url);
this.splitTabs([currentTab, newTab]); this.splitTabs([currentTab, newTab]);
@ -229,16 +223,14 @@ var gZenViewSplitter = new class {
* @param {Tab[]} tabs - The tabs to split. * @param {Tab[]} tabs - The tabs to split.
* @param {string} gridType - The type of grid layout. * @param {string} gridType - The type of grid layout.
*/ */
splitTabs(tabs, gridType = "grid") { splitTabs(tabs, gridType = 'grid') {
if (tabs.length < 2) { if (tabs.length < 2) {
return; return;
} }
const existingSplitTab = tabs.find(tab => tab.splitView); const existingSplitTab = tabs.find((tab) => tab.splitView);
if (existingSplitTab) { if (existingSplitTab) {
const groupIndex = this._data.findIndex(group => const groupIndex = this._data.findIndex((group) => group.tabs.includes(existingSplitTab));
group.tabs.includes(existingSplitTab)
);
if (groupIndex >= 0) { if (groupIndex >= 0) {
// Add any tabs that are not already in the group // Add any tabs that are not already in the group
for (const tab of tabs) { for (const tab of tabs) {
@ -266,12 +258,8 @@ var gZenViewSplitter = new class {
* @param {Tab} tab - The tab to update the split view for. * @param {Tab} tab - The tab to update the split view for.
*/ */
updateSplitView(tab) { updateSplitView(tab) {
const splitData = this._data.find(group => group.tabs.includes(tab)); const splitData = this._data.find((group) => group.tabs.includes(tab));
if ( if (!splitData || (this.currentView >= 0 && !this._data[this.currentView].tabs.includes(tab))) {
!splitData ||
(this.currentView >= 0 &&
!this._data[this.currentView].tabs.includes(tab))
) {
this.updateSplitViewButton(true); this.updateSplitViewButton(true);
if (this.currentView >= 0) { if (this.currentView >= 0) {
this.deactivateSplitView(); this.deactivateSplitView();
@ -289,12 +277,12 @@ var gZenViewSplitter = new class {
*/ */
deactivateSplitView() { deactivateSplitView() {
for (const tab of this._data[this.currentView].tabs) { for (const tab of this._data[this.currentView].tabs) {
const container = tab.linkedBrowser.closest(".browserSidebarContainer"); const container = tab.linkedBrowser.closest('.browserSidebarContainer');
this.resetContainerStyle(container); this.resetContainerStyle(container);
container.removeEventListener("click", this.handleTabClick); container.removeEventListener('click', this.handleTabClick);
} }
this.tabBrowserPanel.removeAttribute("zen-split-view"); this.tabBrowserPanel.removeAttribute('zen-split-view');
this.tabBrowserPanel.style.gridTemplateAreas = ""; this.tabBrowserPanel.style.gridTemplateAreas = '';
this.setTabsDocShellState(this._data[this.currentView].tabs, false); this.setTabsDocShellState(this._data[this.currentView].tabs, false);
this.currentView = -1; this.currentView = -1;
} }
@ -306,10 +294,10 @@ var gZenViewSplitter = new class {
* @param {Tab} activeTab - The active tab. * @param {Tab} activeTab - The active tab.
*/ */
activateSplitView(splitData, activeTab) { activateSplitView(splitData, activeTab) {
this.tabBrowserPanel.setAttribute("zen-split-view", "true"); this.tabBrowserPanel.setAttribute('zen-split-view', 'true');
this.currentView = this._data.indexOf(splitData); this.currentView = this._data.indexOf(splitData);
const gridType = splitData.gridType || "grid"; const gridType = splitData.gridType || 'grid';
this.applyGridLayout(splitData.tabs, gridType, activeTab); this.applyGridLayout(splitData.tabs, gridType, activeTab);
this.setTabsDocShellState(splitData.tabs, true); this.setTabsDocShellState(splitData.tabs, true);
@ -329,7 +317,7 @@ var gZenViewSplitter = new class {
tabs.forEach((tab, index) => { tabs.forEach((tab, index) => {
tab.splitView = true; tab.splitView = true;
const container = tab.linkedBrowser.closest(".browserSidebarContainer"); const container = tab.linkedBrowser.closest('.browserSidebarContainer');
this.styleContainer(container, tab === activeTab, index, gridType); this.styleContainer(container, tab === activeTab, index, gridType);
}); });
} }
@ -342,16 +330,16 @@ var gZenViewSplitter = new class {
* @returns {string} The calculated grid areas. * @returns {string} The calculated grid areas.
*/ */
calculateGridAreas(tabs, gridType) { calculateGridAreas(tabs, gridType) {
if (gridType === "grid") { if (gridType === 'grid') {
return this.calculateGridAreasForGrid(tabs); return this.calculateGridAreasForGrid(tabs);
} }
if (gridType === "vsep") { if (gridType === 'vsep') {
return `'${tabs.map((_, j) => `tab${j + 1}`).join(" ")}'`; return `'${tabs.map((_, j) => `tab${j + 1}`).join(' ')}'`;
} }
if (gridType === "hsep") { if (gridType === 'hsep') {
return tabs.map((_, j) => `'tab${j + 1}'`).join(" "); return tabs.map((_, j) => `'tab${j + 1}'`).join(' ');
} }
return ""; return '';
} }
/** /**
@ -361,7 +349,7 @@ var gZenViewSplitter = new class {
* @returns {string} The calculated grid areas. * @returns {string} The calculated grid areas.
*/ */
calculateGridAreasForGrid(tabs) { calculateGridAreasForGrid(tabs) {
const rows = ["", ""]; const rows = ['', ''];
tabs.forEach((_, i) => { tabs.forEach((_, i) => {
if (i % 2 === 0) { if (i % 2 === 0) {
rows[0] += ` tab${i + 1}`; rows[0] += ` tab${i + 1}`;
@ -390,12 +378,12 @@ var gZenViewSplitter = new class {
* @param {string} gridType - The type of grid layout. * @param {string} gridType - The type of grid layout.
*/ */
styleContainer(container, isActive, index, gridType) { styleContainer(container, isActive, index, gridType) {
container.removeAttribute("zen-split-active"); container.removeAttribute('zen-split-active');
if (isActive) { if (isActive) {
container.setAttribute("zen-split-active", "true"); container.setAttribute('zen-split-active', 'true');
} }
container.setAttribute("zen-split-anim", "true"); container.setAttribute('zen-split-anim', 'true');
container.addEventListener("click", this.handleTabClick); container.addEventListener('click', this.handleTabClick);
container.style.gridArea = `tab${index + 1}`; container.style.gridArea = `tab${index + 1}`;
} }
@ -405,11 +393,9 @@ var gZenViewSplitter = new class {
* *
* @param {Event} event - The click event. * @param {Event} event - The click event.
*/ */
handleTabClick = event => { handleTabClick = (event) => {
const container = event.currentTarget; const container = event.currentTarget;
const tab = window.gBrowser.tabs.find( const tab = window.gBrowser.tabs.find((t) => t.linkedBrowser.closest('.browserSidebarContainer') === container);
t => t.linkedBrowser.closest(".browserSidebarContainer") === container
);
if (tab) { if (tab) {
window.gBrowser.selectedTab = tab; window.gBrowser.selectedTab = tab;
} }
@ -431,12 +417,12 @@ var gZenViewSplitter = new class {
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
const browser = tab.linkedBrowser.closest(".browserSidebarContainer"); const browser = tab.linkedBrowser.closest('.browserSidebarContainer');
if (active) { if (active) {
browser.setAttribute("zen-split", "true"); browser.setAttribute('zen-split', 'true');
} else { } else {
browser.removeAttribute("zen-split"); browser.removeAttribute('zen-split');
browser.removeAttribute("style"); browser.removeAttribute('style');
} }
} }
} }
@ -447,9 +433,9 @@ var gZenViewSplitter = new class {
* @param {Element} container - The container element. * @param {Element} container - The container element.
*/ */
resetContainerStyle(container) { resetContainerStyle(container) {
container.removeAttribute("zen-split-active"); container.removeAttribute('zen-split-active');
container.classList.remove("deck-selected"); container.classList.remove('deck-selected');
container.style.gridArea = ""; container.style.gridArea = '';
} }
/** /**
@ -458,11 +444,11 @@ var gZenViewSplitter = new class {
* @param {boolean} hidden - Indicates if the button should be hidden. * @param {boolean} hidden - Indicates if the button should be hidden.
*/ */
updateSplitViewButton(hidden) { updateSplitViewButton(hidden) {
const button = document.getElementById("zen-split-views-box"); const button = document.getElementById('zen-split-views-box');
if (hidden) { if (hidden) {
button?.setAttribute("hidden", "true"); button?.setAttribute('hidden', 'true');
} else { } else {
button?.removeAttribute("hidden"); button?.removeAttribute('hidden');
} }
} }
@ -473,7 +459,7 @@ var gZenViewSplitter = new class {
*/ */
get modifierElement() { get modifierElement() {
if (!this.__modifierElement) { if (!this.__modifierElement) {
const wrapper = document.getElementById("template-zen-split-view-modifier"); const wrapper = document.getElementById('template-zen-split-view-modifier');
const panel = wrapper.content.firstElementChild; const panel = wrapper.content.firstElementChild;
wrapper.replaceWith(wrapper.content); wrapper.replaceWith(wrapper.content);
this.__modifierElement = panel; this.__modifierElement = panel;
@ -497,7 +483,7 @@ var gZenViewSplitter = new class {
} }
window.PanelMultiView.openPopup(panel, target, { window.PanelMultiView.openPopup(panel, target, {
position: "bottomright topright", position: 'bottomright topright',
triggerEvent: event, triggerEvent: event,
}).catch(console.error); }).catch(console.error);
} }
@ -508,16 +494,11 @@ var gZenViewSplitter = new class {
* @param {Element} panel - The panel element. * @param {Element} panel - The panel element.
*/ */
updatePanelUI(panel) { updatePanelUI(panel) {
for (const gridType of ["hsep", "vsep", "grid", "unsplit"]) { for (const gridType of ['hsep', 'vsep', 'grid', 'unsplit']) {
const selector = panel.querySelector( const selector = panel.querySelector(`.zen-split-view-modifier-preview.${gridType}`);
`.zen-split-view-modifier-preview.${gridType}` selector.classList.remove('active');
); if (this.currentView >= 0 && this._data[this.currentView].gridType === gridType) {
selector.classList.remove("active"); selector.classList.add('active');
if (
this.currentView >= 0 &&
this._data[this.currentView].gridType === gridType
) {
selector.classList.add("active");
} }
} }
} }
@ -527,13 +508,9 @@ var gZenViewSplitter = new class {
* @param {Element} panel - The panel element * @param {Element} panel - The panel element
*/ */
setupPanelListeners(panel) { setupPanelListeners(panel) {
for (const gridType of ["hsep", "vsep", "grid", "unsplit"]) { for (const gridType of ['hsep', 'vsep', 'grid', 'unsplit']) {
const selector = panel.querySelector( const selector = panel.querySelector(`.zen-split-view-modifier-preview.${gridType}`);
`.zen-split-view-modifier-preview.${gridType}` selector.addEventListener('click', () => this.handlePanelSelection(gridType, panel));
);
selector.addEventListener("click", () =>
this.handlePanelSelection(gridType, panel)
);
} }
} }
@ -543,7 +520,7 @@ var gZenViewSplitter = new class {
* @param {Element} panel - The panel element * @param {Element} panel - The panel element
*/ */
handlePanelSelection(gridType, panel) { handlePanelSelection(gridType, panel) {
if (gridType === "unsplit") { if (gridType === 'unsplit') {
this.unsplitCurrentView(); this.unsplitCurrentView();
} else { } else {
this._data[this.currentView].gridType = gridType; this._data[this.currentView].gridType = gridType;
@ -581,7 +558,7 @@ var gZenViewSplitter = new class {
} }
toggleShortcut(gridType) { toggleShortcut(gridType) {
if (gridType === "unsplit") { if (gridType === 'unsplit') {
this.unsplitCurrentView(); this.unsplitCurrentView();
return; return;
} }
@ -591,12 +568,18 @@ var gZenViewSplitter = new class {
} }
let nextTabIndex = tabs.indexOf(gBrowser.selectedTab) + 1; let nextTabIndex = tabs.indexOf(gBrowser.selectedTab) + 1;
if (nextTabIndex >= tabs.length) { if (nextTabIndex >= tabs.length) {
nextTabIndex = 0; // Find the first non-hidden tab
nextTabIndex = tabs.findIndex((tab) => !tab.hidden);
} else if (nextTabIndex < 0) { } else if (nextTabIndex < 0) {
nextTabIndex = tabs.length - 1; // reverse find the first non-hidden tab
nextTabIndex = tabs
.slice()
.reverse()
.findIndex((tab) => !tab.hidden);
} }
const selected_tabs = gBrowser.selectedTab.multiselected const selected_tabs = gBrowser.selectedTab.multiselected
? gBrowser.selectedTabs : [gBrowser.selectedTab, tabs[nextTabIndex]]; ? gBrowser.selectedTabs
: [gBrowser.selectedTab, tabs[nextTabIndex]];
this.splitTabs(selected_tabs, gridType); this.splitTabs(selected_tabs, gridType);
} }
} })();

View file

@ -2,33 +2,27 @@ var ZenWorkspaces = {
async init() { async init() {
let docElement = document.documentElement; let docElement = document.documentElement;
if ( if (
docElement.getAttribute("chromehidden").includes("toolbar") || docElement.getAttribute('chromehidden').includes('toolbar') ||
docElement.getAttribute("chromehidden").includes("menubar") || docElement.getAttribute('chromehidden').includes('menubar') ||
docElement.hasAttribute("privatebrowsingmode") docElement.hasAttribute('privatebrowsingmode')
) { ) {
console.warn( console.warn('ZenWorkspaces: !!! ZenWorkspaces is disabled in hidden windows !!!');
"ZenWorkspaces: !!! ZenWorkspaces is disabled in hidden windows !!!",
);
return; // We are in a hidden window, don't initialize ZenWorkspaces return; // We are in a hidden window, don't initialize ZenWorkspaces
} }
console.info("ZenWorkspaces: Initializing ZenWorkspaces..."); console.info('ZenWorkspaces: Initializing ZenWorkspaces...');
window.SessionStore.promiseInitialized.then(async () => { window.SessionStore.promiseInitialized.then(async () => {
await this.initializeWorkspaces(); await this.initializeWorkspaces();
console.info("ZenWorkspaces: ZenWorkspaces initialized"); console.info('ZenWorkspaces: ZenWorkspaces initialized');
}); });
}, },
get workspaceEnabled() { get workspaceEnabled() {
return Services.prefs.getBoolPref("zen.workspaces.enabled", false); return Services.prefs.getBoolPref('zen.workspaces.enabled', false);
}, },
// Wrorkspaces saving/loading // Wrorkspaces saving/loading
get _storeFile() { get _storeFile() {
return PathUtils.join( return PathUtils.join(PathUtils.profileDir, 'zen-workspaces', 'Workspaces.json');
PathUtils.profileDir,
"zen-workspaces",
"Workspaces.json",
);
}, },
async _workspaces() { async _workspaces() {
@ -46,7 +40,7 @@ var ZenWorkspaces = {
throw Error("Shoud've had reloaded the window"); throw Error("Shoud've had reloaded the window");
} else { } else {
this._workspaceCache = null; this._workspaceCache = null;
document.getElementById("zen-workspaces-button")?.remove(); document.getElementById('zen-workspaces-button')?.remove();
for (let tab of gBrowser.tabs) { for (let tab of gBrowser.tabs) {
gBrowser.showTab(tab); gBrowser.showTab(tab);
} }
@ -54,28 +48,21 @@ var ZenWorkspaces = {
}, },
async initializeWorkspaces() { async initializeWorkspaces() {
Services.prefs.addObserver( Services.prefs.addObserver('zen.workspaces.enabled', this.onWorkspacesEnabledChanged.bind(this));
"zen.workspaces.enabled",
this.onWorkspacesEnabledChanged.bind(this),
);
this.initializeWorkspacesButton(); this.initializeWorkspacesButton();
let file = new FileUtils.File(this._storeFile); let file = new FileUtils.File(this._storeFile);
if (!file.exists()) { if (!file.exists()) {
await IOUtils.writeJSON(this._storeFile, {}); await IOUtils.writeJSON(this._storeFile, {});
} }
if (this.workspaceEnabled) { if (this.workspaceEnabled) {
window.addEventListener("TabClose", this.handleTabClose.bind(this)); window.addEventListener('TabClose', this.handleTabClose.bind(this));
let workspaces = await this._workspaces(); let workspaces = await this._workspaces();
if (workspaces.workspaces.length === 0) { if (workspaces.workspaces.length === 0) {
await this.createAndSaveWorkspace("Default Workspace", true); await this.createAndSaveWorkspace('Default Workspace', true);
} else { } else {
let activeWorkspace = workspaces.workspaces.find( let activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used);
(workspace) => workspace.used,
);
if (!activeWorkspace) { if (!activeWorkspace) {
activeWorkspace = workspaces.workspaces.find( activeWorkspace = workspaces.workspaces.find((workspace) => workspace.default);
(workspace) => workspace.default,
);
activeWorkspace.used = true; activeWorkspace.used = true;
await this.saveWorkspaces(); await this.saveWorkspaces();
} }
@ -97,12 +84,10 @@ var ZenWorkspaces = {
return; // Bug when closing tabs from the context menu return; // Bug when closing tabs from the context menu
} }
let tab = event.target; let tab = event.target;
let workspaceID = tab.getAttribute("zen-workspace-id"); let workspaceID = tab.getAttribute('zen-workspace-id');
// If the tab is the last one in the workspace, create a new tab // If the tab is the last one in the workspace, create a new tab
if (workspaceID) { if (workspaceID) {
let tabs = gBrowser.tabs.filter( let tabs = gBrowser.tabs.filter((tab) => tab.getAttribute('zen-workspace-id') === workspaceID);
(tab) => tab.getAttribute("zen-workspace-id") === workspaceID,
);
if (tabs.length === 1) { if (tabs.length === 1) {
this._createNewTabForWorkspace({ uuid: workspaceID }); this._createNewTabForWorkspace({ uuid: workspaceID });
// We still need to close other tabs in the workspace // We still need to close other tabs in the workspace
@ -111,23 +96,21 @@ var ZenWorkspaces = {
} }
}, },
_kIcons: ["🏠", "📄", "💹", "💼", "📧", "✅", "👥"], _kIcons: ['🏠', '📄', '💹', '💼', '📧', '✅', '👥'],
_initializeWorkspaceCreationIcons() { _initializeWorkspaceCreationIcons() {
let container = document.getElementById( let container = document.getElementById('PanelUI-zen-workspaces-create-icons-container');
"PanelUI-zen-workspaces-create-icons-container",
);
for (let icon of this._kIcons) { for (let icon of this._kIcons) {
let button = document.createXULElement("toolbarbutton"); let button = document.createXULElement('toolbarbutton');
button.className = "toolbarbutton-1"; button.className = 'toolbarbutton-1';
button.setAttribute("label", icon); button.setAttribute('label', icon);
button.onclick = ((event) => { button.onclick = ((event) => {
let wasSelected = button.hasAttribute("selected"); let wasSelected = button.hasAttribute('selected');
for (let button of container.children) { for (let button of container.children) {
button.removeAttribute("selected"); button.removeAttribute('selected');
} }
if (!wasSelected) { if (!wasSelected) {
button.setAttribute("selected", "true"); button.setAttribute('selected', 'true');
} }
}).bind(this, button); }).bind(this, button);
container.appendChild(button); container.appendChild(button);
@ -137,16 +120,16 @@ var ZenWorkspaces = {
_initializeWorkspaceEditIcons() { _initializeWorkspaceEditIcons() {
let container = this._workspaceEditIconsContainer; let container = this._workspaceEditIconsContainer;
for (let icon of this._kIcons) { for (let icon of this._kIcons) {
let button = document.createXULElement("toolbarbutton"); let button = document.createXULElement('toolbarbutton');
button.className = "toolbarbutton-1"; button.className = 'toolbarbutton-1';
button.setAttribute("label", icon); button.setAttribute('label', icon);
button.onclick = ((event) => { button.onclick = ((event) => {
let wasSelected = button.hasAttribute("selected"); let wasSelected = button.hasAttribute('selected');
for (let button of container.children) { for (let button of container.children) {
button.removeAttribute("selected"); button.removeAttribute('selected');
} }
if (!wasSelected) { if (!wasSelected) {
button.setAttribute("selected", "true"); button.setAttribute('selected', 'true');
} }
this.onWorkspaceEditChange(); this.onWorkspaceEditChange();
}).bind(this, button); }).bind(this, button);
@ -156,18 +139,16 @@ var ZenWorkspaces = {
async saveWorkspace(workspaceData) { async saveWorkspace(workspaceData) {
let json = await IOUtils.readJSON(this._storeFile); let json = await IOUtils.readJSON(this._storeFile);
if (typeof json.workspaces === "undefined") { if (typeof json.workspaces === 'undefined') {
json.workspaces = []; json.workspaces = [];
} }
let existing = json.workspaces.findIndex( let existing = json.workspaces.findIndex((workspace) => workspace.uuid === workspaceData.uuid);
(workspace) => workspace.uuid === workspaceData.uuid,
);
if (existing >= 0) { if (existing >= 0) {
json.workspaces[existing] = workspaceData; json.workspaces[existing] = workspaceData;
} else { } else {
json.workspaces.push(workspaceData); json.workspaces.push(workspaceData);
} }
console.info("ZenWorkspaces: Saving workspace", workspaceData); console.info('ZenWorkspaces: Saving workspace', workspaceData);
await IOUtils.writeJSON(this._storeFile, json); await IOUtils.writeJSON(this._storeFile, json);
this._workspaceCache = null; this._workspaceCache = null;
@ -176,14 +157,10 @@ var ZenWorkspaces = {
async removeWorkspace(windowID) { async removeWorkspace(windowID) {
let json = await this._workspaces(); let json = await this._workspaces();
console.info("ZenWorkspaces: Removing workspace", windowID); console.info('ZenWorkspaces: Removing workspace', windowID);
await this.changeWorkspace( await this.changeWorkspace(json.workspaces.find((workspace) => workspace.uuid !== windowID));
json.workspaces.find((workspace) => workspace.uuid !== windowID),
);
this._deleteAllTabsInWorkspace(windowID); this._deleteAllTabsInWorkspace(windowID);
json.workspaces = json.workspaces.filter( json.workspaces = json.workspaces.filter((workspace) => workspace.uuid !== windowID);
(workspace) => workspace.uuid !== windowID,
);
await this.unsafeSaveWorkspaces(json); await this.unsafeSaveWorkspaces(json);
await this._propagateWorkspaceData(); await this._propagateWorkspaceData();
await this._updateWorkspacesChangeContextMenu(); await this._updateWorkspacesChangeContextMenu();
@ -202,60 +179,37 @@ var ZenWorkspaces = {
// Workspaces dialog UI management // Workspaces dialog UI management
openSaveDialog() { openSaveDialog() {
let parentPanel = document.getElementById( let parentPanel = document.getElementById('PanelUI-zen-workspaces-multiview');
"PanelUI-zen-workspaces-multiview", PanelUI.showSubView('PanelUI-zen-workspaces-create', parentPanel);
);
PanelUI.showSubView("PanelUI-zen-workspaces-create", parentPanel);
}, },
async openEditDialog(workspaceUuid) { async openEditDialog(workspaceUuid) {
this._workspaceEditDialog.setAttribute( this._workspaceEditDialog.setAttribute('data-workspace-uuid', workspaceUuid);
"data-workspace-uuid", document.getElementById('PanelUI-zen-workspaces-edit-save').setAttribute('disabled', 'true');
workspaceUuid,
);
document
.getElementById("PanelUI-zen-workspaces-edit-save")
.setAttribute("disabled", "true");
let workspaces = (await this._workspaces()).workspaces; let workspaces = (await this._workspaces()).workspaces;
let workspaceData = workspaces.find( let workspaceData = workspaces.find((workspace) => workspace.uuid === workspaceUuid);
(workspace) => workspace.uuid === workspaceUuid,
);
this._workspaceEditInput.textContent = workspaceData.name; this._workspaceEditInput.textContent = workspaceData.name;
this._workspaceEditInput.value = workspaceData.name; this._workspaceEditInput.value = workspaceData.name;
this._workspaceEditInput.setAttribute( this._workspaceEditInput.setAttribute('data-initial-value', workspaceData.name);
"data-initial-value", this._workspaceEditIconsContainer.setAttribute('data-initial-value', workspaceData.icon);
workspaceData.name, document.querySelectorAll('#PanelUI-zen-workspaces-edit-icons-container toolbarbutton').forEach((button) => {
);
this._workspaceEditIconsContainer.setAttribute(
"data-initial-value",
workspaceData.icon,
);
document
.querySelectorAll(
"#PanelUI-zen-workspaces-edit-icons-container toolbarbutton",
)
.forEach((button) => {
if (button.label === workspaceData.icon) { if (button.label === workspaceData.icon) {
button.setAttribute("selected", "true"); button.setAttribute('selected', 'true');
} else { } else {
button.removeAttribute("selected"); button.removeAttribute('selected');
} }
}); });
let parentPanel = document.getElementById( let parentPanel = document.getElementById('PanelUI-zen-workspaces-multiview');
"PanelUI-zen-workspaces-multiview", PanelUI.showSubView('PanelUI-zen-workspaces-edit', parentPanel);
);
PanelUI.showSubView("PanelUI-zen-workspaces-edit", parentPanel);
}, },
closeWorkspacesSubView() { closeWorkspacesSubView() {
let parentPanel = document.getElementById( let parentPanel = document.getElementById('PanelUI-zen-workspaces-multiview');
"PanelUI-zen-workspaces-multiview",
);
parentPanel.goBack(); parentPanel.goBack();
}, },
workspaceHasIcon(workspace) { workspaceHasIcon(workspace) {
return typeof workspace.icon !== "undefined" && workspace.icon !== ""; return typeof workspace.icon !== 'undefined' && workspace.icon !== '';
}, },
getWorkspaceIcon(workspace) { getWorkspaceIcon(workspace) {
@ -266,15 +220,13 @@ var ZenWorkspaces = {
}, },
async _propagateWorkspaceData() { async _propagateWorkspaceData() {
let currentContainer = document.getElementById( let currentContainer = document.getElementById('PanelUI-zen-workspaces-current-info');
"PanelUI-zen-workspaces-current-info", let workspaceList = document.getElementById('PanelUI-zen-workspaces-list');
);
let workspaceList = document.getElementById("PanelUI-zen-workspaces-list");
const createWorkspaceElement = (workspace) => { const createWorkspaceElement = (workspace) => {
let element = document.createXULElement("toolbarbutton"); let element = document.createXULElement('toolbarbutton');
element.className = "subviewbutton"; element.className = 'subviewbutton';
element.setAttribute("tooltiptext", workspace.name); element.setAttribute('tooltiptext', workspace.name);
element.setAttribute("zen-workspace-id", workspace.uuid); element.setAttribute('zen-workspace-id', workspace.uuid);
//element.setAttribute("context", "zenWorkspaceActionsMenu"); //element.setAttribute("context", "zenWorkspaceActionsMenu");
let childs = window.MozXULElement.parseXULToFragment(` let childs = window.MozXULElement.parseXULToFragment(`
<div class="zen-workspace-icon"> <div class="zen-workspace-icon">
@ -287,48 +239,37 @@ var ZenWorkspaces = {
`); `);
// use text content instead of innerHTML to avoid XSS // use text content instead of innerHTML to avoid XSS
childs.querySelector(".zen-workspace-icon").textContent = childs.querySelector('.zen-workspace-icon').textContent = this.getWorkspaceIcon(workspace);
this.getWorkspaceIcon(workspace); childs.querySelector('.zen-workspace-name').textContent = workspace.name;
childs.querySelector(".zen-workspace-name").textContent = workspace.name;
childs childs.querySelector('.zen-workspace-actions').addEventListener('command', (event) => {
.querySelector(".zen-workspace-actions")
.addEventListener("command", (event) => {
let button = event.target; let button = event.target;
this._contextMenuId = button this._contextMenuId = button.closest('toolbarbutton[zen-workspace-id]').getAttribute('zen-workspace-id');
.closest("toolbarbutton[zen-workspace-id]") const popup = button.ownerDocument.getElementById('zenWorkspaceActionsMenu');
.getAttribute("zen-workspace-id"); popup.openPopup(button, 'after_end');
const popup = button.ownerDocument.getElementById(
"zenWorkspaceActionsMenu",
);
popup.openPopup(button, "after_end");
}); });
element.appendChild(childs); element.appendChild(childs);
element.onclick = (async () => { element.onclick = (async () => {
if (event.target.closest(".zen-workspace-actions")) { if (event.target.closest('.zen-workspace-actions')) {
return; // Ignore clicks on the actions button return; // Ignore clicks on the actions button
} }
await this.changeWorkspace(workspace); await this.changeWorkspace(workspace);
let panel = document.getElementById("PanelUI-zen-workspaces"); let panel = document.getElementById('PanelUI-zen-workspaces');
PanelMultiView.hidePopup(panel); PanelMultiView.hidePopup(panel);
document document.getElementById('zen-workspaces-button').removeAttribute('open');
.getElementById("zen-workspaces-button")
.removeAttribute("open");
}).bind(this, workspace); }).bind(this, workspace);
return element; return element;
}; };
let workspaces = await this._workspaces(); let workspaces = await this._workspaces();
let activeWorkspace = workspaces.workspaces.find( let activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used);
(workspace) => workspace.used, currentContainer.innerHTML = '';
); workspaceList.innerHTML = '';
currentContainer.innerHTML = ""; workspaceList.parentNode.style.display = 'flex';
workspaceList.innerHTML = "";
workspaceList.parentNode.style.display = "flex";
if (workspaces.workspaces.length - 1 <= 0) { if (workspaces.workspaces.length - 1 <= 0) {
workspaceList.innerHTML = "No workspaces available"; workspaceList.innerHTML = 'No workspaces available';
workspaceList.setAttribute("empty", "true"); workspaceList.setAttribute('empty', 'true');
} else { } else {
workspaceList.removeAttribute("empty"); workspaceList.removeAttribute('empty');
} }
if (activeWorkspace) { if (activeWorkspace) {
let currentWorkspace = createWorkspaceElement(activeWorkspace); let currentWorkspace = createWorkspaceElement(activeWorkspace);
@ -348,10 +289,10 @@ var ZenWorkspaces = {
return; return;
} }
let target = event.target; let target = event.target;
let panel = document.getElementById("PanelUI-zen-workspaces"); let panel = document.getElementById('PanelUI-zen-workspaces');
await this._propagateWorkspaceData(); await this._propagateWorkspaceData();
PanelMultiView.openPopup(panel, target, { PanelMultiView.openPopup(panel, target, {
position: "bottomright topright", position: 'bottomright topright',
triggerEvent: event, triggerEvent: event,
}).catch(console.error); }).catch(console.error);
}, },
@ -359,29 +300,27 @@ var ZenWorkspaces = {
initializeWorkspacesButton() { initializeWorkspacesButton() {
if (!this.workspaceEnabled) { if (!this.workspaceEnabled) {
return; return;
} else if (document.getElementById("zen-workspaces-button")) { } else if (document.getElementById('zen-workspaces-button')) {
let button = document.getElementById("zen-workspaces-button"); let button = document.getElementById('zen-workspaces-button');
button.removeAttribute("hidden"); button.removeAttribute('hidden');
return; return;
} }
let browserTabs = document.getElementById("tabbrowser-tabs"); let browserTabs = document.getElementById('tabbrowser-tabs');
let button = document.createElement("toolbarbutton"); let button = document.createElement('toolbarbutton');
button.id = "zen-workspaces-button"; button.id = 'zen-workspaces-button';
button.className = "toolbarbutton-1 chromeclass-toolbar-additional"; button.className = 'toolbarbutton-1 chromeclass-toolbar-additional';
button.setAttribute("label", "Workspaces"); button.setAttribute('label', 'Workspaces');
button.setAttribute("tooltiptext", "Workspaces"); button.setAttribute('tooltiptext', 'Workspaces');
button.onclick = this.openWorkspacesDialog.bind(this); button.onclick = this.openWorkspacesDialog.bind(this);
browserTabs.insertAdjacentElement("beforebegin", button); browserTabs.insertAdjacentElement('beforebegin', button);
}, },
async _updateWorkspacesButton() { async _updateWorkspacesButton() {
let button = document.getElementById("zen-workspaces-button"); let button = document.getElementById('zen-workspaces-button');
if (!button) { if (!button) {
return; return;
} }
let activeWorkspace = (await this._workspaces()).workspaces.find( let activeWorkspace = (await this._workspaces()).workspaces.find((workspace) => workspace.used);
(workspace) => workspace.used,
);
if (activeWorkspace) { if (activeWorkspace) {
button.innerHTML = ` button.innerHTML = `
<div class="zen-workspace-sidebar-icon"> <div class="zen-workspace-sidebar-icon">
@ -391,15 +330,11 @@ var ZenWorkspaces = {
`; `;
// use text content instead of innerHTML to avoid XSS // use text content instead of innerHTML to avoid XSS
button.querySelector(".zen-workspace-sidebar-name").textContent = button.querySelector('.zen-workspace-sidebar-name').textContent = activeWorkspace.name;
activeWorkspace.name; button.querySelector('.zen-workspace-sidebar-icon').textContent = this.getWorkspaceIcon(activeWorkspace);
button.querySelector(".zen-workspace-sidebar-icon").textContent =
this.getWorkspaceIcon(activeWorkspace);
if (!this.workspaceHasIcon(activeWorkspace)) { if (!this.workspaceHasIcon(activeWorkspace)) {
button button.querySelector('.zen-workspace-sidebar-icon').setAttribute('no-icon', 'true');
.querySelector(".zen-workspace-sidebar-icon")
.setAttribute("no-icon", "true");
} }
} }
}, },
@ -407,26 +342,24 @@ var ZenWorkspaces = {
// Workspaces management // Workspaces management
get _workspaceCreateInput() { get _workspaceCreateInput() {
return document.getElementById("PanelUI-zen-workspaces-create-input"); return document.getElementById('PanelUI-zen-workspaces-create-input');
}, },
get _workspaceEditDialog() { get _workspaceEditDialog() {
return document.getElementById("PanelUI-zen-workspaces-edit"); return document.getElementById('PanelUI-zen-workspaces-edit');
}, },
get _workspaceEditInput() { get _workspaceEditInput() {
return document.getElementById("PanelUI-zen-workspaces-edit-input"); return document.getElementById('PanelUI-zen-workspaces-edit-input');
}, },
get _workspaceEditIconsContainer() { get _workspaceEditIconsContainer() {
return document.getElementById( return document.getElementById('PanelUI-zen-workspaces-edit-icons-container');
"PanelUI-zen-workspaces-edit-icons-container",
);
}, },
_deleteAllTabsInWorkspace(workspaceID) { _deleteAllTabsInWorkspace(workspaceID) {
for (let tab of gBrowser.tabs) { for (let tab of gBrowser.tabs) {
if (tab.getAttribute("zen-workspace-id") === workspaceID) { if (tab.getAttribute('zen-workspace-id') === workspaceID) {
gBrowser.removeTab(tab, { gBrowser.removeTab(tab, {
animate: true, animate: true,
skipSessionStore: true, skipSessionStore: true,
@ -437,11 +370,11 @@ var ZenWorkspaces = {
}, },
_prepareNewWorkspace(window) { _prepareNewWorkspace(window) {
document.documentElement.setAttribute("zen-workspace-id", window.uuid); document.documentElement.setAttribute('zen-workspace-id', window.uuid);
let tabCount = 0; let tabCount = 0;
for (let tab of gBrowser.tabs) { for (let tab of gBrowser.tabs) {
if (!tab.hasAttribute("zen-workspace-id")) { if (!tab.hasAttribute('zen-workspace-id')) {
tab.setAttribute("zen-workspace-id", window.uuid); tab.setAttribute('zen-workspace-id', window.uuid);
tabCount++; tabCount++;
} }
} }
@ -451,10 +384,8 @@ var ZenWorkspaces = {
}, },
_createNewTabForWorkspace(window) { _createNewTabForWorkspace(window) {
let tab = gZenUIManager.openAndChangeToTab( let tab = gZenUIManager.openAndChangeToTab(Services.prefs.getStringPref('browser.startup.homepage'));
Services.prefs.getStringPref("browser.startup.homepage"), tab.setAttribute('zen-workspace-id', window.uuid);
);
tab.setAttribute("zen-workspace-id", window.uuid);
}, },
async saveWorkspaceFromCreate() { async saveWorkspaceFromCreate() {
@ -462,32 +393,24 @@ var ZenWorkspaces = {
if (!workspaceName) { if (!workspaceName) {
return; return;
} }
this._workspaceCreateInput.value = ""; this._workspaceCreateInput.value = '';
let icon = document.querySelector( let icon = document.querySelector('#PanelUI-zen-workspaces-create-icons-container [selected]');
"#PanelUI-zen-workspaces-create-icons-container [selected]", icon?.removeAttribute('selected');
);
icon?.removeAttribute("selected");
await this.createAndSaveWorkspace(workspaceName, false, icon?.label); await this.createAndSaveWorkspace(workspaceName, false, icon?.label);
document.getElementById("PanelUI-zen-workspaces").hidePopup(true); document.getElementById('PanelUI-zen-workspaces').hidePopup(true);
}, },
async saveWorkspaceFromEdit() { async saveWorkspaceFromEdit() {
let workspaceUuid = this._workspaceEditDialog.getAttribute( let workspaceUuid = this._workspaceEditDialog.getAttribute('data-workspace-uuid');
"data-workspace-uuid",
);
let workspaceName = this._workspaceEditInput.value; let workspaceName = this._workspaceEditInput.value;
if (!workspaceName) { if (!workspaceName) {
return; return;
} }
this._workspaceEditInput.value = ""; this._workspaceEditInput.value = '';
let icon = document.querySelector( let icon = document.querySelector('#PanelUI-zen-workspaces-edit-icons-container [selected]');
"#PanelUI-zen-workspaces-edit-icons-container [selected]", icon?.removeAttribute('selected');
);
icon?.removeAttribute("selected");
let workspaces = (await this._workspaces()).workspaces; let workspaces = (await this._workspaces()).workspaces;
let workspaceData = workspaces.find( let workspaceData = workspaces.find((workspace) => workspace.uuid === workspaceUuid);
(workspace) => workspace.uuid === workspaceUuid,
);
workspaceData.name = workspaceName; workspaceData.name = workspaceName;
workspaceData.icon = icon?.label; workspaceData.icon = icon?.label;
await this.saveWorkspace(workspaceData); await this.saveWorkspace(workspaceData);
@ -497,29 +420,26 @@ var ZenWorkspaces = {
}, },
onWorkspaceCreationNameChange(event) { onWorkspaceCreationNameChange(event) {
let button = document.getElementById("PanelUI-zen-workspaces-create-save"); let button = document.getElementById('PanelUI-zen-workspaces-create-save');
if (this._workspaceCreateInput.value === "") { if (this._workspaceCreateInput.value === '') {
button.setAttribute("disabled", "true"); button.setAttribute('disabled', 'true');
return; return;
} }
button.removeAttribute("disabled"); button.removeAttribute('disabled');
}, },
onWorkspaceEditChange() { onWorkspaceEditChange() {
let button = document.getElementById("PanelUI-zen-workspaces-edit-save"); let button = document.getElementById('PanelUI-zen-workspaces-edit-save');
let name = this._workspaceEditInput.value; let name = this._workspaceEditInput.value;
let icon = document.querySelector( let icon = document.querySelector('#PanelUI-zen-workspaces-edit-icons-container [selected]')?.label;
"#PanelUI-zen-workspaces-edit-icons-container [selected]",
)?.label;
if ( if (
name === this._workspaceEditInput.getAttribute("data-initial-value") && name === this._workspaceEditInput.getAttribute('data-initial-value') &&
icon === icon === this._workspaceEditIconsContainer.getAttribute('data-initial-value')
this._workspaceEditIconsContainer.getAttribute("data-initial-value")
) { ) {
button.setAttribute("disabled", "true"); button.setAttribute('disabled', 'true');
return; return;
} }
button.removeAttribute("disabled"); button.removeAttribute('disabled');
}, },
async changeWorkspace(window, onInit = false) { async changeWorkspace(window, onInit = false) {
@ -532,33 +452,35 @@ var ZenWorkspaces = {
workspace.used = workspace.uuid === window.uuid; workspace.used = workspace.uuid === window.uuid;
} }
this.unsafeSaveWorkspaces(workspaces); this.unsafeSaveWorkspaces(workspaces);
console.info("ZenWorkspaces: Changing workspace to", window.uuid); console.info('ZenWorkspaces: Changing workspace to', window.uuid);
for (let tab of gBrowser.tabs) { for (let tab of gBrowser.tabs) {
if ( if ((tab.getAttribute('zen-workspace-id') === window.uuid && !tab.pinned) || !tab.hasAttribute('zen-workspace-id')) {
(tab.getAttribute("zen-workspace-id") === window.uuid && !tab.pinned) ||
!tab.hasAttribute("zen-workspace-id")
) {
if (!firstTab) { if (!firstTab) {
firstTab = tab; firstTab = tab;
gBrowser.selectedTab = firstTab; } else if (gBrowser.selectedTab === tab) {
// If the selected tab is already in the workspace, we don't want to change it
firstTab = undefined;
} }
gBrowser.showTab(tab); gBrowser.showTab(tab);
if (!tab.hasAttribute("zen-workspace-id")) { if (!tab.hasAttribute('zen-workspace-id')) {
// We add the id to those tabs that got inserted before we initialize the workspaces // We add the id to those tabs that got inserted before we initialize the workspaces
// example use case: opening a link from an external app // example use case: opening a link from an external app
tab.setAttribute("zen-workspace-id", window.uuid); tab.setAttribute('zen-workspace-id', window.uuid);
} }
} }
} }
if (typeof firstTab === "undefined" && !onInit) { if (firstTab) {
gBrowser.selectedTab = firstTab;
}
if (typeof firstTab === 'undefined' && !onInit) {
this._createNewTabForWorkspace(window); this._createNewTabForWorkspace(window);
} }
for (let tab of gBrowser.tabs) { for (let tab of gBrowser.tabs) {
if (tab.getAttribute("zen-workspace-id") !== window.uuid) { if (tab.getAttribute('zen-workspace-id') !== window.uuid) {
gBrowser.hideTab(tab); gBrowser.hideTab(tab);
} }
} }
document.documentElement.setAttribute("zen-workspace-id", window.uuid); document.documentElement.setAttribute('zen-workspace-id', window.uuid);
await this.saveWorkspaces(); await this.saveWorkspaces();
await this._updateWorkspacesButton(); await this._updateWorkspacesButton();
await this._propagateWorkspaceData(); await this._propagateWorkspaceData();
@ -568,23 +490,19 @@ var ZenWorkspaces = {
async _updateWorkspacesChangeContextMenu() { async _updateWorkspacesChangeContextMenu() {
const workspaces = await this._workspaces(); const workspaces = await this._workspaces();
const menuPopup = document.getElementById( const menuPopup = document.getElementById('context-zen-change-workspace-tab-menu-popup');
"context-zen-change-workspace-tab-menu-popup",
);
menuPopup.innerHTML = ""; menuPopup.innerHTML = '';
const activeWorkspace = workspaces.workspaces.find( const activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used);
(workspace) => workspace.used,
);
for (let workspace of workspaces.workspaces) { for (let workspace of workspaces.workspaces) {
const menuItem = document.createXULElement("menuitem"); const menuItem = document.createXULElement('menuitem');
menuItem.setAttribute("label", workspace.name); menuItem.setAttribute('label', workspace.name);
menuItem.setAttribute("zen-workspace-id", workspace.uuid); menuItem.setAttribute('zen-workspace-id', workspace.uuid);
if (workspace.uuid === activeWorkspace.uuid) { if (workspace.uuid === activeWorkspace.uuid) {
menuItem.setAttribute("disabled", "true"); menuItem.setAttribute('disabled', 'true');
} }
menuPopup.appendChild(menuItem); menuPopup.appendChild(menuItem);
@ -603,11 +521,7 @@ var ZenWorkspaces = {
return window; return window;
}, },
async createAndSaveWorkspace( async createAndSaveWorkspace(name = 'New Workspace', isDefault = false, icon = undefined) {
name = "New Workspace",
isDefault = false,
icon = undefined,
) {
if (!this.workspaceEnabled) { if (!this.workspaceEnabled) {
return; return;
} }
@ -618,16 +532,14 @@ var ZenWorkspaces = {
async onLocationChange(browser) { async onLocationChange(browser) {
let tab = gBrowser.getTabForBrowser(browser); let tab = gBrowser.getTabForBrowser(browser);
let workspaceID = tab.getAttribute("zen-workspace-id"); let workspaceID = tab.getAttribute('zen-workspace-id');
if (!workspaceID) { if (!workspaceID) {
let workspaces = await this._workspaces(); let workspaces = await this._workspaces();
let activeWorkspace = workspaces.workspaces.find( let activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used);
(workspace) => workspace.used, if (!activeWorkspace || tab.hasAttribute('hidden')) {
);
if (!activeWorkspace || tab.hasAttribute("hidden")) {
return; return;
} }
tab.setAttribute("zen-workspace-id", activeWorkspace.uuid); tab.setAttribute('zen-workspace-id', activeWorkspace.uuid);
} }
}, },
@ -635,54 +547,40 @@ var ZenWorkspaces = {
_contextMenuId: null, _contextMenuId: null,
async updateContextMenu(_) { async updateContextMenu(_) {
console.assert(this._contextMenuId, "No context menu ID set"); console.assert(this._contextMenuId, 'No context menu ID set');
document document
.querySelector( .querySelector(`#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`)
`#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`, .setAttribute('active', 'true');
)
.setAttribute("active", "true");
const workspaces = await this._workspaces(); const workspaces = await this._workspaces();
let deleteMenuItem = document.getElementById("context_zenDeleteWorkspace"); let deleteMenuItem = document.getElementById('context_zenDeleteWorkspace');
if ( if (
workspaces.workspaces.length <= 1 || workspaces.workspaces.length <= 1 ||
workspaces.workspaces.find( workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId).default
(workspace) => workspace.uuid === this._contextMenuId,
).default
) { ) {
deleteMenuItem.setAttribute("disabled", "true"); deleteMenuItem.setAttribute('disabled', 'true');
} else { } else {
deleteMenuItem.removeAttribute("disabled"); deleteMenuItem.removeAttribute('disabled');
} }
let defaultMenuItem = document.getElementById( let defaultMenuItem = document.getElementById('context_zenSetAsDefaultWorkspace');
"context_zenSetAsDefaultWorkspace", if (workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId).default) {
); defaultMenuItem.setAttribute('disabled', 'true');
if (
workspaces.workspaces.find(
(workspace) => workspace.uuid === this._contextMenuId,
).default
) {
defaultMenuItem.setAttribute("disabled", "true");
} else { } else {
defaultMenuItem.removeAttribute("disabled"); defaultMenuItem.removeAttribute('disabled');
} }
let openMenuItem = document.getElementById("context_zenOpenWorkspace"); let openMenuItem = document.getElementById('context_zenOpenWorkspace');
if ( if (workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId).used) {
workspaces.workspaces.find( openMenuItem.setAttribute('disabled', 'true');
(workspace) => workspace.uuid === this._contextMenuId,
).used
) {
openMenuItem.setAttribute("disabled", "true");
} else { } else {
openMenuItem.removeAttribute("disabled"); openMenuItem.removeAttribute('disabled');
} }
}, },
onContextMenuClose() { onContextMenuClose() {
let target = document.querySelector( let target = document.querySelector(
`#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`, `#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`
); );
if (target) { if (target) {
target.removeAttribute("active"); target.removeAttribute('active');
} }
this._contextMenuId = null; this._contextMenuId = null;
}, },
@ -698,9 +596,7 @@ var ZenWorkspaces = {
async openWorkspace() { async openWorkspace() {
let workspaces = await this._workspaces(); let workspaces = await this._workspaces();
let workspace = workspaces.workspaces.find( let workspace = workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId);
(workspace) => workspace.uuid === this._contextMenuId,
);
await this.changeWorkspace(workspace); await this.changeWorkspace(workspace);
}, },
@ -719,43 +615,33 @@ var ZenWorkspaces = {
async changeWorkspaceShortcut() { async changeWorkspaceShortcut() {
// Cycle through workspaces // Cycle through workspaces
let workspaces = await this._workspaces(); let workspaces = await this._workspaces();
let activeWorkspace = workspaces.workspaces.find( let activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used);
(workspace) => workspace.used,
);
let workspaceIndex = workspaces.workspaces.indexOf(activeWorkspace); let workspaceIndex = workspaces.workspaces.indexOf(activeWorkspace);
let nextWorkspace = let nextWorkspace = workspaces.workspaces[workspaceIndex + 1] || workspaces.workspaces[0];
workspaces.workspaces[workspaceIndex + 1] || workspaces.workspaces[0];
this.changeWorkspace(nextWorkspace); this.changeWorkspace(nextWorkspace);
}, },
_initializeWorkspaceTabContextMenus() { _initializeWorkspaceTabContextMenus() {
const menu = document.createXULElement("menu"); const menu = document.createXULElement('menu');
menu.setAttribute("id", "context-zen-change-workspace-tab"); menu.setAttribute('id', 'context-zen-change-workspace-tab');
menu.setAttribute("data-l10n-id", "context-zen-change-workspace-tab"); menu.setAttribute('data-l10n-id', 'context-zen-change-workspace-tab');
const menuPopup = document.createXULElement("menupopup"); const menuPopup = document.createXULElement('menupopup');
menuPopup.setAttribute("id", "context-zen-change-workspace-tab-menu-popup"); menuPopup.setAttribute('id', 'context-zen-change-workspace-tab-menu-popup');
menuPopup.setAttribute( menuPopup.setAttribute('oncommand', "ZenWorkspaces.changeTabWorkspace(event.target.getAttribute('zen-workspace-id'))");
"oncommand",
"ZenWorkspaces.changeTabWorkspace(event.target.getAttribute('zen-workspace-id'))",
);
menu.appendChild(menuPopup); menu.appendChild(menuPopup);
document.getElementById("context_closeDuplicateTabs").after(menu); document.getElementById('context_closeDuplicateTabs').after(menu);
}, },
async changeTabWorkspace(workspaceID) { async changeTabWorkspace(workspaceID) {
const tabs = TabContextMenu.contextTab.multiselected const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
? gBrowser.selectedTabs
: [TabContextMenu.contextTab];
for (let tab of tabs) { for (let tab of tabs) {
tab.setAttribute("zen-workspace-id", workspaceID); tab.setAttribute('zen-workspace-id', workspaceID);
} }
const workspaces = await this._workspaces(); const workspaces = await this._workspaces();
await this.changeWorkspace( await this.changeWorkspace(workspaces.workspaces.find((workspace) => workspace.uuid === workspaceID));
workspaces.workspaces.find((workspace) => workspace.uuid === workspaceID),
);
}, },
}; };

View file

@ -1,4 +1,3 @@
export class ZenThemeMarketplaceChild extends JSWindowActorChild { export class ZenThemeMarketplaceChild extends JSWindowActorChild {
constructor() { constructor() {
super(); super();
@ -6,9 +5,9 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
handleEvent(event) { handleEvent(event) {
switch (event.type) { switch (event.type) {
case "DOMContentLoaded": case 'DOMContentLoaded':
this.initiateThemeMarketplace(); this.initiateThemeMarketplace();
this.contentWindow.document.addEventListener("ZenCheckForThemeUpdates", this.checkForThemeUpdates.bind(this)); this.contentWindow.document.addEventListener('ZenCheckForThemeUpdates', this.checkForThemeUpdates.bind(this));
break; break;
default: default:
} }
@ -17,7 +16,7 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
// This function will be caleld from about:preferences // This function will be caleld from about:preferences
checkForThemeUpdates(event) { checkForThemeUpdates(event) {
event.preventDefault(); event.preventDefault();
this.sendAsyncMessage("ZenThemeMarketplace:CheckForUpdates"); this.sendAsyncMessage('ZenThemeMarketplace:CheckForUpdates');
} }
initiateThemeMarketplace() { initiateThemeMarketplace() {
@ -27,16 +26,16 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
} }
get actionButton() { get actionButton() {
return this.contentWindow.document.getElementById("install-theme"); return this.contentWindow.document.getElementById('install-theme');
} }
get actionButtonUnnstall() { get actionButtonUnnstall() {
return this.contentWindow.document.getElementById("install-theme-uninstall"); return this.contentWindow.document.getElementById('install-theme-uninstall');
} }
async receiveMessage(message) { async receiveMessage(message) {
switch (message.name) { switch (message.name) {
case "ZenThemeMarketplace:ThemeChanged": { case 'ZenThemeMarketplace:ThemeChanged': {
const themeId = message.data.themeId; const themeId = message.data.themeId;
const actionButton = this.actionButton; const actionButton = this.actionButton;
const actionButtonInstalled = this.actionButtonUnnstall; const actionButtonInstalled = this.actionButtonUnnstall;
@ -44,21 +43,23 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
actionButton.disabled = false; actionButton.disabled = false;
actionButtonInstalled.disabled = false; actionButtonInstalled.disabled = false;
if (await this.isThemeInstalled(themeId)) { if (await this.isThemeInstalled(themeId)) {
actionButton.classList.add("hidden"); actionButton.classList.add('hidden');
actionButtonInstalled.classList.remove("hidden"); actionButtonInstalled.classList.remove('hidden');
} else { } else {
actionButton.classList.remove("hidden"); actionButton.classList.remove('hidden');
actionButtonInstalled.classList.add("hidden"); actionButtonInstalled.classList.add('hidden');
} }
} }
break; break;
} }
case "ZenThemeMarketplace:CheckForUpdatesFinished": { case 'ZenThemeMarketplace:CheckForUpdatesFinished': {
const updates = message.data.updates; const updates = message.data.updates;
this.contentWindow.document.dispatchEvent(new CustomEvent("ZenThemeMarketplace:CheckForUpdatesFinished", { detail: { updates } })); this.contentWindow.document.dispatchEvent(
new CustomEvent('ZenThemeMarketplace:CheckForUpdatesFinished', { detail: { updates } })
);
break; break;
} }
case "ZenThemeMarketplace:GetThemeInfo": { case 'ZenThemeMarketplace:GetThemeInfo': {
const themeId = message.data.themeId; const themeId = message.data.themeId;
const theme = await this.getThemeInfo(themeId); const theme = await this.getThemeInfo(themeId);
return theme; return theme;
@ -69,30 +70,30 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
async addIntallButtons() { async addIntallButtons() {
const actionButton = this.actionButton; const actionButton = this.actionButton;
const actionButtonUnnstall = this.actionButtonUnnstall; const actionButtonUnnstall = this.actionButtonUnnstall;
const errorMessage = this.contentWindow.document.getElementById("install-theme-error"); const errorMessage = this.contentWindow.document.getElementById('install-theme-error');
if (!actionButton || !actionButtonUnnstall) { if (!actionButton || !actionButtonUnnstall) {
return; return;
} }
errorMessage.classList.add("hidden"); errorMessage.classList.add('hidden');
const themeId = actionButton.getAttribute("zen-theme-id"); const themeId = actionButton.getAttribute('zen-theme-id');
if (await this.isThemeInstalled(themeId)) { if (await this.isThemeInstalled(themeId)) {
actionButtonUnnstall.classList.remove("hidden"); actionButtonUnnstall.classList.remove('hidden');
} else { } else {
actionButton.classList.remove("hidden"); actionButton.classList.remove('hidden');
} }
actionButton.addEventListener("click", this.installTheme.bind(this)); actionButton.addEventListener('click', this.installTheme.bind(this));
actionButtonUnnstall.addEventListener("click", this.uninstallTheme.bind(this)); actionButtonUnnstall.addEventListener('click', this.uninstallTheme.bind(this));
} }
async isThemeInstalled(themeId) { async isThemeInstalled(themeId) {
return await this.sendQuery("ZenThemeMarketplace:IsThemeInstalled", { themeId }); return await this.sendQuery('ZenThemeMarketplace:IsThemeInstalled', { themeId });
} }
addTheme(theme) { addTheme(theme) {
this.sendAsyncMessage("ZenThemeMarketplace:InstallTheme", { theme }); this.sendAsyncMessage('ZenThemeMarketplace:InstallTheme', { theme });
} }
getThemeAPIUrl(themeId) { getThemeAPIUrl(themeId) {
@ -101,9 +102,9 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
async getThemeInfo(themeId) { async getThemeInfo(themeId) {
const url = this.getThemeAPIUrl(themeId); const url = this.getThemeAPIUrl(themeId);
console.info("ZTM: Fetching theme info from: ", url); console.info('ZTM: Fetching theme info from: ', url);
const data = await fetch(url, { const data = await fetch(url, {
mode: "no-cors", mode: 'no-cors',
}); });
if (data.ok) { if (data.ok) {
@ -111,7 +112,7 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
const obj = await data.json(); const obj = await data.json();
return obj; return obj;
} catch (e) { } catch (e) {
console.error("ZTM: Error parsing theme info: ", e); console.error('ZTM: Error parsing theme info: ', e);
} }
} else console.log(data.status); } else console.log(data.status);
return null; return null;
@ -120,22 +121,22 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
async uninstallTheme(event) { async uninstallTheme(event) {
const button = event.target; const button = event.target;
button.disabled = true; button.disabled = true;
const themeId = button.getAttribute("zen-theme-id"); const themeId = button.getAttribute('zen-theme-id');
console.info("ZTM: Uninstalling theme with id: ", themeId); console.info('ZTM: Uninstalling theme with id: ', themeId);
this.sendAsyncMessage("ZenThemeMarketplace:UninstallTheme", { themeId }); this.sendAsyncMessage('ZenThemeMarketplace:UninstallTheme', { themeId });
} }
async installTheme(event) { async installTheme(event) {
const button = event.target; const button = event.target;
button.disabled = true; button.disabled = true;
const themeId = button.getAttribute("zen-theme-id"); const themeId = button.getAttribute('zen-theme-id');
console.info("ZTM: Installing theme with id: ", themeId); console.info('ZTM: Installing theme with id: ', themeId);
const theme = await this.getThemeInfo(themeId); const theme = await this.getThemeInfo(themeId);
if (!theme) { if (!theme) {
console.error("ZTM: Error fetching theme info"); console.error('ZTM: Error fetching theme info');
return; return;
} }
this.addTheme(theme); this.addTheme(theme);
} }
}; }

View file

@ -1,4 +1,3 @@
export class ZenThemeMarketplaceParent extends JSWindowActorParent { export class ZenThemeMarketplaceParent extends JSWindowActorParent {
constructor() { constructor() {
super(); super();
@ -6,8 +5,8 @@ export class ZenThemeMarketplaceParent extends JSWindowActorParent {
async receiveMessage(message) { async receiveMessage(message) {
switch (message.name) { switch (message.name) {
case "ZenThemeMarketplace:InstallTheme": { case 'ZenThemeMarketplace:InstallTheme': {
console.info("ZenThemeMarketplaceParent: Updating themes"); console.info('ZenThemeMarketplaceParent: Updating themes');
const theme = message.data.theme; const theme = message.data.theme;
const themes = await this.getThemes(); const themes = await this.getThemes();
themes[theme.id] = theme; themes[theme.id] = theme;
@ -15,8 +14,8 @@ export class ZenThemeMarketplaceParent extends JSWindowActorParent {
this.updateChildProcesses(theme.id); this.updateChildProcesses(theme.id);
break; break;
} }
case "ZenThemeMarketplace:UninstallTheme": { case 'ZenThemeMarketplace:UninstallTheme': {
console.info("ZenThemeMarketplaceParent: Uninstalling theme"); console.info('ZenThemeMarketplaceParent: Uninstalling theme');
const themeId = message.data.themeId; const themeId = message.data.themeId;
const themes = await this.getThemes(); const themes = await this.getThemes();
delete themes[themeId]; delete themes[themeId];
@ -25,58 +24,66 @@ export class ZenThemeMarketplaceParent extends JSWindowActorParent {
this.updateChildProcesses(themeId); this.updateChildProcesses(themeId);
break; break;
} }
case "ZenThemeMarketplace:IsThemeInstalled": { case 'ZenThemeMarketplace:IsThemeInstalled': {
const themeId = message.data.themeId; const themeId = message.data.themeId;
const themes = await this.getThemes(); const themes = await this.getThemes();
return themes[themeId] ? true : false; return themes[themeId] ? true : false;
} }
case "ZenThemeMarketplace:CheckForUpdates": { case 'ZenThemeMarketplace:CheckForUpdates': {
this.checkForThemeUpdates(); this.checkForThemeUpdates();
break; break;
} }
} }
} }
compareversion(version1,version2){ compareversion(version1, version2) {
var result=false; var result = false;
if(typeof version1!=='object'){ version1=version1.toString().split('.'); } if (typeof version1 !== 'object') {
if(typeof version2!=='object'){ version2=version2.toString().split('.'); } version1 = version1.toString().split('.');
for(var i=0;i<(Math.max(version1.length,version2.length));i++){ }
if(version1[i]==undefined){ version1[i]=0; } if (typeof version2 !== 'object') {
if(version2[i]==undefined){ version2[i]=0; } version2 = version2.toString().split('.');
if(Number(version1[i])<Number(version2[i])){ }
result=true; for (var i = 0; i < Math.max(version1.length, version2.length); i++) {
if (version1[i] == undefined) {
version1[i] = 0;
}
if (version2[i] == undefined) {
version2[i] = 0;
}
if (Number(version1[i]) < Number(version2[i])) {
result = true;
break; break;
} }
if(version1[i]!=version2[i]){ if (version1[i] != version2[i]) {
break; break;
} }
} }
return(result); return result;
} }
async checkForThemeUpdates() { async checkForThemeUpdates() {
console.info("ZenThemeMarketplaceParent: Checking for theme updates"); console.info('ZenThemeMarketplaceParent: Checking for theme updates');
let updates = []; let updates = [];
this._themes = null; this._themes = null;
for (const theme of Object.values(await this.getThemes())) { for (const theme of Object.values(await this.getThemes())) {
const themeInfo = await this.sendQuery("ZenThemeMarketplace:GetThemeInfo", { themeId: theme.id }); const themeInfo = await this.sendQuery('ZenThemeMarketplace:GetThemeInfo', { themeId: theme.id });
if (!themeInfo) { if (!themeInfo) {
continue; continue;
} }
if (!this.compareversion(themeInfo.version, theme.version || "0.0.0") && themeInfo.version != theme.version) { if (!this.compareversion(themeInfo.version, theme.version || '0.0.0') && themeInfo.version != theme.version) {
console.info("ZenThemeMarketplaceParent: Theme update found", theme.id, theme.version, themeInfo.version); console.info('ZenThemeMarketplaceParent: Theme update found', theme.id, theme.version, themeInfo.version);
updates.push(themeInfo); updates.push(themeInfo);
await this.removeTheme(theme.id, false); await this.removeTheme(theme.id, false);
this._themes[themeInfo.id] = themeInfo; this._themes[themeInfo.id] = themeInfo;
} }
} }
await this.updateThemes(this._themes); await this.updateThemes(this._themes);
this.sendAsyncMessage("ZenThemeMarketplace:CheckForUpdatesFinished", { updates }); this.sendAsyncMessage('ZenThemeMarketplace:CheckForUpdatesFinished', { updates });
} }
async updateChildProcesses(themeId) { async updateChildProcesses(themeId) {
this.sendAsyncMessage("ZenThemeMarketplace:ThemeChanged", { themeId }); this.sendAsyncMessage('ZenThemeMarketplace:ThemeChanged', { themeId });
} }
async getThemes() { async getThemes() {
@ -112,37 +119,30 @@ export class ZenThemeMarketplaceParent extends JSWindowActorParent {
let buffer = new TextEncoder().encode(content); let buffer = new TextEncoder().encode(content);
await IOUtils.write(path, buffer); await IOUtils.write(path, buffer);
} catch (e) { } catch (e) {
console.error("ZenThemeMarketplaceParent: Error downloading file", url, e); console.error('ZenThemeMarketplaceParent: Error downloading file', url, e);
} }
} }
async downloadThemeFileContents(theme) { async downloadThemeFileContents(theme) {
const themePath = PathUtils.join(this.themesRootPath, theme.id); const themePath = PathUtils.join(this.themesRootPath, theme.id);
await IOUtils.makeDirectory(themePath, { ignoreExisting: true }); await IOUtils.makeDirectory(themePath, { ignoreExisting: true });
await this.downloadUrlToFile(theme.style, PathUtils.join(themePath, "chrome.css"), true); await this.downloadUrlToFile(theme.style, PathUtils.join(themePath, 'chrome.css'), true);
await this.downloadUrlToFile(theme.readme, PathUtils.join(themePath, "readme.md")); await this.downloadUrlToFile(theme.readme, PathUtils.join(themePath, 'readme.md'));
if (theme.preferences) { if (theme.preferences) {
await this.downloadUrlToFile(theme.preferences, PathUtils.join(themePath, "preferences.json")); await this.downloadUrlToFile(theme.preferences, PathUtils.join(themePath, 'preferences.json'));
} }
} }
get themesRootPath() { get themesRootPath() {
return PathUtils.join( return PathUtils.join(PathUtils.profileDir, 'chrome', 'zen-themes');
PathUtils.profileDir,
"chrome",
"zen-themes"
);
} }
get themesDataFile() { get themesDataFile() {
return PathUtils.join( return PathUtils.join(PathUtils.profileDir, 'zen-themes.json');
PathUtils.profileDir,
"zen-themes.json"
);
} }
triggerThemeUpdate() { triggerThemeUpdate() {
const pref = "zen.themes.updated-value-observer"; const pref = 'zen.themes.updated-value-observer';
Services.prefs.setBoolPref(pref, !Services.prefs.getBoolPref(pref)); Services.prefs.setBoolPref(pref, !Services.prefs.getBoolPref(pref));
} }
@ -172,10 +172,10 @@ export class ZenThemeMarketplaceParent extends JSWindowActorParent {
async removeTheme(themeId, triggerUpdate = true) { async removeTheme(themeId, triggerUpdate = true) {
const themePath = PathUtils.join(this.themesRootPath, themeId); const themePath = PathUtils.join(this.themesRootPath, themeId);
console.info("ZenThemeMarketplaceParent: Removing theme ", themePath); console.info('ZenThemeMarketplaceParent: Removing theme ', themePath);
await IOUtils.remove(themePath, { recursive: true, ignoreAbsent: true }); await IOUtils.remove(themePath, { recursive: true, ignoreAbsent: true });
if (triggerUpdate) { if (triggerUpdate) {
this.triggerThemeUpdate(); this.triggerThemeUpdate();
} }
} }
}; }