From a8df1907b93872e25e0ceb2d8b42d6dad7394a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristijan=20Ribari=C4=87?= Date: Tue, 1 Oct 2024 15:53:07 +0200 Subject: [PATCH] feat: add pinned tab reset on close shortcut Adds a new feature allowing users to reset a pinned tab's URL and title when closing it using the Ctrl+W shortcut. This option can be enabled/disabled in the Zen preferences. The feature also adds a new context menu item to manually reset a pinned tab's URL and title. This menu item appears only when right-clicking a pinned tab. --- src/ZenTabUnloader.mjs | 113 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 6 deletions(-) diff --git a/src/ZenTabUnloader.mjs b/src/ZenTabUnloader.mjs index 801ef63..2b4ac17 100644 --- a/src/ZenTabUnloader.mjs +++ b/src/ZenTabUnloader.mjs @@ -7,6 +7,13 @@ XPCOMUtils.defineLazyPreferenceGetter(lazy, 'zenTabUnloaderExcludedUrls', 'zen.tab-unloader.excluded-urls', ''); + XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "zenPinnedTabResetOnCloseShortcutEnabled", + "zen.tab-unloader.reset-pinned-tab-on-close-shortcut", + false + ); + const ZEN_TAB_UNLOADER_DEFAULT_EXCLUDED_URLS = [ '^about:', '^chrome:', @@ -128,20 +135,114 @@ return; } this.insertIntoContextMenu(); + + this.insertResetTabIntoContextMenu(); + this.initClosePinnedTabShortcut(); this.observer = new ZenTabsObserver(); this.intervalUnloader = new ZenTabsIntervalUnloader(this); this.observer.addTabsListener(this.onTabEvent.bind(this)); } + onCloseTabShortcut(event) { + if ( + event && + (event.ctrlKey || event.metaKey || event.altKey) && + gBrowser.selectedTab.pinned + ) { + const selectedTab = gBrowser.selectedTab; + const url = selectedTab.getAttribute("zen-pinned-url"); + const title = selectedTab.getAttribute("zen-pinned-title"); + + let nextTab = gBrowser.tabContainer.findNextTab(selectedTab, { + direction: 1, + filter: tab => !tab.hidden && !tab.pinned, + }); + + if (!nextTab) { + // If there's no next tab, try to find the previous one + nextTab = gBrowser.tabContainer.findNextTab(selectedTab, { + direction: -1, + filter: tab => !tab.hidden && !tab.pinned, + }); + } + + if (selectedTab) { + // Switch to the next tab + gBrowser.selectedTab = nextTab; + + if (url && this.zenPinnedTabResetOnCloseShortcutEnabled) { + const tabState = SessionStore.getTabState(selectedTab); + const state = JSON.parse(tabState); + let activeIndex = (state.index || state.entries.length) - 1; + // Ensure the index is in bounds. + activeIndex = Math.min(activeIndex, state.entries.length - 1); + activeIndex = Math.max(activeIndex, 0); + state.entries[activeIndex].url = url; + state.entries[activeIndex].title = title; + SessionStore.setTabState(selectedTab, state); + } + + gBrowser.discardBrowser(selectedTab); + + event.stopPropagation(); + event.preventDefault(); + } + } + } + + initClosePinnedTabShortcut() { + let cmdClose = document.getElementById('cmd_close'); + + if (cmdClose) { + cmdClose.addEventListener('command', this.onCloseTabShortcut.bind(lazy)); + } + } + + ResetPinnedTab(){ + const selectedTab = TabContextMenu.contextTab; + + const url = selectedTab.getAttribute("zen-pinned-url"); + const title = selectedTab.getAttribute("zen-pinned-title"); + + if (url) { + const tabState = SessionStore.getTabState(selectedTab); + const state = JSON.parse(tabState); + + let activeIndex = (state.index || state.entries.length) - 1; + // Ensure the index is in bounds. + activeIndex = Math.min(activeIndex, state.entries.length - 1); + activeIndex = Math.max(activeIndex, 0); + state.entries[activeIndex].url = url; + state.entries[activeIndex].title = title; + SessionStore.setTabState(selectedTab, state); + } + } + + insertResetTabIntoContextMenu() { + const element = window.MozXULElement.parseXULToFragment(` +