diff --git a/src/browser/base/content/zen-assets.inc.xhtml b/src/browser/base/content/zen-assets.inc.xhtml
index 0ae64eab2..a61105b51 100644
--- a/src/browser/base/content/zen-assets.inc.xhtml
+++ b/src/browser/base/content/zen-assets.inc.xhtml
@@ -48,7 +48,6 @@
-
diff --git a/src/browser/base/content/zen-assets.jar.inc.mn b/src/browser/base/content/zen-assets.jar.inc.mn
index 8825284ba..efee1ce48 100644
--- a/src/browser/base/content/zen-assets.jar.inc.mn
+++ b/src/browser/base/content/zen-assets.jar.inc.mn
@@ -51,7 +51,6 @@
content/browser/zen-components/ZenKeyboardShortcuts.mjs (../../zen/kbs/ZenKeyboardShortcuts.mjs)
- content/browser/zen-components/ZenPinnedTabsStorage.mjs (../../zen/tabs/ZenPinnedTabsStorage.mjs)
content/browser/zen-components/ZenPinnedTabManager.mjs (../../zen/tabs/ZenPinnedTabManager.mjs)
* content/browser/zen-styles/zen-tabs.css (../../zen/tabs/zen-tabs.css)
content/browser/zen-styles/zen-tabs/vertical-tabs.css (../../zen/tabs/zen-tabs/vertical-tabs.css)
diff --git a/src/browser/components/sessionstore/SessionStore-sys-mjs.patch b/src/browser/components/sessionstore/SessionStore-sys-mjs.patch
index 66bcc8301..ef89b7892 100644
--- a/src/browser/components/sessionstore/SessionStore-sys-mjs.patch
+++ b/src/browser/components/sessionstore/SessionStore-sys-mjs.patch
@@ -1,5 +1,5 @@
diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs
-index eb62ff3e733e43fdaa299babddea3ba0125abb06..09567fe1be2af56429b60cbcbb36aa477fa68794 100644
+index eb62ff3e733e43fdaa299babddea3ba0125abb06..1ca2e7327e72824805a93c18cb7e3dfd499c66d7 100644
--- a/browser/components/sessionstore/SessionStore.sys.mjs
+++ b/browser/components/sessionstore/SessionStore.sys.mjs
@@ -126,6 +126,8 @@ const TAB_EVENTS = [
@@ -33,7 +33,7 @@ index eb62ff3e733e43fdaa299babddea3ba0125abb06..09567fe1be2af56429b60cbcbb36aa47
let isRegularWindow =
!isPrivateWindow && !isTaskbarTab && aWindow.toolbar.visible;
+ if (!aInitialState && isRegularWindow) {
-+ aInitialState = ZenSessionStore.getNewWindowData(this._windows);
++ aInitialState = lazy.ZenSessionStore.getNewWindowData(this._windows);
+ this.restoreWindows(aWindow, aInitialState, {});
+ }
@@ -171,8 +171,8 @@ index eb62ff3e733e43fdaa299babddea3ba0125abb06..09567fe1be2af56429b60cbcbb36aa47
+ if (tabData.zenHasStaticLabel) {
+ tab.setAttribute("zen-has-static-label", "true");
+ }
-+ if (tabData.zenPinnedId) {
-+ tab.setAttribute("zen-pin-id", tabData.zenPinnedId);
++ if (tabData.zenSyncId) {
++ tab.setAttribute("zen-sync-id", tabData.zenSyncId);
+ }
+ if (tabData.zenDefaultUserContextId) {
+ tab.setAttribute("zenDefaultUserContextId", true);
diff --git a/src/browser/components/sessionstore/TabState-sys-mjs.patch b/src/browser/components/sessionstore/TabState-sys-mjs.patch
index 2100e2334..cfeea5035 100644
--- a/src/browser/components/sessionstore/TabState-sys-mjs.patch
+++ b/src/browser/components/sessionstore/TabState-sys-mjs.patch
@@ -1,5 +1,5 @@
diff --git a/browser/components/sessionstore/TabState.sys.mjs b/browser/components/sessionstore/TabState.sys.mjs
-index 82721356d191055bec0d4b0ca49e481221988801..1ea5c394c704da295149443d7794961a12f2060b 100644
+index 82721356d191055bec0d4b0ca49e481221988801..d1323fe17c995611ebdfe2869b0ccd2d45bcfa11 100644
--- a/browser/components/sessionstore/TabState.sys.mjs
+++ b/browser/components/sessionstore/TabState.sys.mjs
@@ -85,7 +85,22 @@ class _TabState {
@@ -7,7 +7,7 @@ index 82721356d191055bec0d4b0ca49e481221988801..1ea5c394c704da295149443d7794961a
}
+ tabData.zenWorkspace = tab.getAttribute("zen-workspace-id");
-+ tabData.zenPinnedId = tab.getAttribute("zen-pin-id");
++ tabData.zenSyncId = tab.getAttribute("zen-sync-id");
+ tabData.zenEssential = tab.getAttribute("zen-essential");
+ tabData.pinned = tabData.pinned || tabData.zenEssential;
+ tabData.zenDefaultUserContextId = tab.getAttribute("zenDefaultUserContextId");
diff --git a/src/browser/components/tabbrowser/content/tab-js.patch b/src/browser/components/tabbrowser/content/tab-js.patch
index 997098854..f9f19d12d 100644
--- a/src/browser/components/tabbrowser/content/tab-js.patch
+++ b/src/browser/components/tabbrowser/content/tab-js.patch
@@ -121,14 +121,6 @@ index 425aaf8c8e4adf1507eb0d8ded671f8295544b04..12988986c4cf00990c1d1b2e4be362ef
on_click(event) {
if (event.button != 0) {
return;
-@@ -570,6 +592,7 @@
- )
- );
- } else {
-+ gZenPinnedTabManager._removePinnedAttributes(this, true);
- gBrowser.removeTab(this, {
- animate: true,
- triggeringEvent: event,
@@ -582,6 +605,14 @@
// (see tabbrowser-tabs 'click' handler).
gBrowser.tabContainer._blockDblClick = true;
diff --git a/src/browser/components/tabbrowser/content/tabbrowser-js.patch b/src/browser/components/tabbrowser/content/tabbrowser-js.patch
index 11561149a..ccccb80c7 100644
--- a/src/browser/components/tabbrowser/content/tabbrowser-js.patch
+++ b/src/browser/components/tabbrowser/content/tabbrowser-js.patch
@@ -477,16 +477,6 @@ index c099e8646b9341a3ff55bf394037c8fc2769969b..0d524a0519bbbdf304a594d1fb56c394
TabBarVisibility.update();
}
-@@ -4553,6 +4680,9 @@
- return;
- }
-
-+ for (let tab of selectedTabs) {
-+ gZenPinnedTabManager._removePinnedAttributes(tab, true);
-+ }
- this.removeTabs(selectedTabs, { isUserTriggered, telemetrySource });
- }
-
@@ -4814,6 +4944,7 @@
telemetrySource,
} = {}
@@ -838,11 +828,3 @@ index c099e8646b9341a3ff55bf394037c8fc2769969b..0d524a0519bbbdf304a594d1fb56c394
// Build Ask Chat items
TabContextMenu.GenAI.buildTabMenu(
document.getElementById("context_askChat"),
-@@ -9763,6 +9944,7 @@ var TabContextMenu = {
- )
- );
- } else {
-+ gZenPinnedTabManager._removePinnedAttributes(this.contextTab, true);
- gBrowser.removeTab(this.contextTab, {
- animate: true,
- ...gBrowser.TabMetrics.userTriggeredContext(
diff --git a/src/zen/common/ZenSessionStore.mjs b/src/zen/common/ZenSessionStore.mjs
index 2b86d886e..3ad0e706b 100644
--- a/src/zen/common/ZenSessionStore.mjs
+++ b/src/zen/common/ZenSessionStore.mjs
@@ -15,8 +15,8 @@
if (tabData.zenWorkspace) {
tab.setAttribute('zen-workspace-id', tabData.zenWorkspace);
}
- if (tabData.zenPinnedId) {
- tab.setAttribute('zen-pin-id', tabData.zenPinnedId);
+ if (tabData.zenSyncId) {
+ tab.setAttribute('zen-sync-id', tabData.zenSyncId);
}
if (tabData.zenHasStaticLabel) {
tab.setAttribute('zen-has-static-label', 'true');
diff --git a/src/zen/common/ZenUIManager.mjs b/src/zen/common/ZenUIManager.mjs
index a95f7e60d..d597c463d 100644
--- a/src/zen/common/ZenUIManager.mjs
+++ b/src/zen/common/ZenUIManager.mjs
@@ -1249,14 +1249,6 @@ var gZenVerticalTabsManager = {
} else {
gBrowser.setTabTitle(this._tabEdited);
}
- if (this._tabEdited.getAttribute('zen-pin-id')) {
- // Update pin title in storage
- await gZenPinnedTabManager.updatePinTitle(
- this._tabEdited,
- this._tabEdited.label,
- !!newName
- );
- }
// Maybe add some confetti here?!?
gZenUIManager.motion.animate(
diff --git a/src/zen/folders/ZenFolders.mjs b/src/zen/folders/ZenFolders.mjs
index 3d181132b..c2b328378 100644
--- a/src/zen/folders/ZenFolders.mjs
+++ b/src/zen/folders/ZenFolders.mjs
@@ -508,9 +508,6 @@
tabs = [emptyTab, ...filteredTabs];
const folder = this._createFolderNode(options);
- if (options.initialPinId) {
- folder.setAttribute('zen-pin-id', options.initialPinId);
- }
if (options.insertAfter) {
options.insertAfter.after(folder);
@@ -940,7 +937,7 @@
if (!parentFolder && folder.hasAttribute('split-view-group')) continue;
const emptyFolderTabs = folder.tabs
.filter((tab) => tab.hasAttribute('zen-empty-tab'))
- .map((tab) => tab.getAttribute('zen-pin-id'));
+ .map((tab) => tab.getAttribute('zen-sync-id'));
let prevSiblingInfo = null;
const prevSibling = folder.previousElementSibling;
@@ -949,8 +946,8 @@
if (prevSibling) {
if (gBrowser.isTabGroup(prevSibling)) {
prevSiblingInfo = { type: 'group', id: prevSibling.id };
- } else if (gBrowser.isTab(prevSibling) && prevSibling.hasAttribute('zen-pin-id')) {
- const zenPinId = prevSibling.getAttribute('zen-pin-id');
+ } else if (gBrowser.isTab(prevSibling) && prevSibling.hasAttribute('zen-sync-id')) {
+ const zenPinId = prevSibling.getAttribute('zen-sync-id');
prevSiblingInfo = { type: 'tab', id: zenPinId };
} else {
prevSiblingInfo = { type: 'start', id: null };
@@ -969,7 +966,7 @@
prevSiblingInfo: prevSiblingInfo,
emptyTabIds: emptyFolderTabs,
userIcon: userIcon?.getAttribute('href'),
- pinId: folder.getAttribute('zen-pin-id'),
+ syncId: folder.getAttribute('zen-sync-id'),
// note: We shouldn't be using the workspace-id anywhere, we are just
// remembering it for the pinned tabs manager to use it later.
workspaceId: folder.getAttribute('zen-workspace-id'),
@@ -996,9 +993,9 @@
tabFolderWorkingData.set(folderData.id, workingData);
const oldGroup = document.getElementById(folderData.id);
- folderData.emptyTabIds.forEach((zenPinId) => {
+ folderData.emptyTabIds.forEach((zenSyncId) => {
oldGroup
- ?.querySelector(`tab[zen-pin-id="${zenPinId}"]`)
+ ?.querySelector(`tab[zen-sync-id="${zenSyncId}"]`)
?.setAttribute('zen-empty-tab', true);
});
if (oldGroup) {
@@ -1011,7 +1008,7 @@
saveOnWindowClose: folderData.saveOnWindowClose,
workspaceId: folderData.workspaceId,
});
- folder.setAttribute('zen-pin-id', folderData.pinId);
+ folder.setAttribute('zen-sync-id', folderData.syncId);
workingData.node = folder;
oldGroup.before(folder);
} else {
@@ -1044,7 +1041,7 @@
switch (stateData?.prevSiblingInfo?.type) {
case 'tab': {
const tab = parentWorkingData.node.querySelector(
- `[zen-pin-id="${stateData.prevSiblingInfo.id}"]`
+ `[zen-sync-id="${stateData.prevSiblingInfo.id}"]`
);
tab.after(node);
break;
diff --git a/src/zen/sessionstore/ZenSessionManager.sys.mjs b/src/zen/sessionstore/ZenSessionManager.sys.mjs
index 5120319bc..e8cf59114 100644
--- a/src/zen/sessionstore/ZenSessionManager.sys.mjs
+++ b/src/zen/sessionstore/ZenSessionManager.sys.mjs
@@ -2,13 +2,6 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-import {
- cancelIdleCallback,
- clearTimeout,
- requestIdleCallback,
- setTimeout,
-} from 'resource://gre/modules/Timer.sys.mjs';
-
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
@@ -19,7 +12,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
SessionStore: 'resource:///modules/sessionstore/SessionStore.sys.mjs',
});
-const TAB_CUSTOM_VALUES = new WeakMap();
const LAZY_COLLECT_THRESHOLD = 5 * 60 * 1000; // 5 minutes
const OBSERVING = ['sessionstore-state-write-complete', 'browser-window-before-show'];
@@ -76,6 +68,7 @@ class nsZenSessionManager {
/** Handles the browser-window-before-show observer notification. */
#onBeforeBrowserWindowShown(aWindow) {
// TODO: Initialize new window
+ void aWindow;
}
get #topMostWindow() {
@@ -113,10 +106,8 @@ class nsZenSessionManager {
* @param forceUpdate
* Forces us to recollect data and will bypass and update the
* corresponding caches.
- * @param zIndex
- * The z-index of the window.
*/
- #collectWindowData(window, forceUpdate = false, zIndex = 0) {
+ #collectWindowData(window, forceUpdate = false) {
let sidebarData = this.#sidebar;
if (!sidebarData || forceUpdate) {
sidebarData = {};
@@ -164,7 +155,8 @@ class nsZenSessionManager {
}
getNewWindowData(aWindows) {
- return { windows: [Cu.cloneInto(aWindows[Object.keys(aWindows)[0]], {})] };
+ let newWindow = { ...Cu.cloneInto(aWindows[Object.keys(aWindows)[0]], {}), ...this.#sidebar };
+ return { windows: [newWindow] };
}
}
diff --git a/src/zen/tabs/ZenPinnedTabManager.mjs b/src/zen/tabs/ZenPinnedTabManager.mjs
index e555a3346..245819a91 100644
--- a/src/zen/tabs/ZenPinnedTabManager.mjs
+++ b/src/zen/tabs/ZenPinnedTabManager.mjs
@@ -5,23 +5,7 @@
const lazy = {};
class ZenPinnedTabsObserver {
- static ALL_EVENTS = [
- 'TabPinned',
- 'TabUnpinned',
- 'TabMove',
- 'TabGroupCreate',
- 'TabGroupRemoved',
- 'TabGroupMoved',
- 'ZenFolderRenamed',
- 'ZenFolderIconChanged',
- 'TabGroupCollapse',
- 'TabGroupExpand',
- 'TabGrouped',
- 'TabUngrouped',
- 'ZenFolderChangedWorkspace',
- 'TabAddedToEssentials',
- 'TabRemovedFromEssentials',
- ];
+ static ALL_EVENTS = ['TabPinned', 'TabUnpinned'];
#listeners = [];
@@ -103,21 +87,8 @@
onTabIconChanged(tab, url = null) {
tab.dispatchEvent(new CustomEvent('ZenTabIconChanged', { bubbles: true, detail: { tab } }));
const iconUrl = url ?? tab.iconImage.src;
- if (!iconUrl && tab.hasAttribute('zen-pin-id')) {
- try {
- setTimeout(async () => {
- const favicon = await this.getFaviconAsBase64(tab.linkedBrowser.currentURI);
- if (favicon) {
- gBrowser.setIcon(tab, favicon);
- }
- });
- } catch {
- // Handle error
- }
- } else {
- if (tab.hasAttribute('zen-essential')) {
- tab.style.setProperty('--zen-essential-tab-icon', `url(${iconUrl})`);
- }
+ if (tab.hasAttribute('zen-essential')) {
+ tab.style.setProperty('--zen-essential-tab-icon', `url(${iconUrl})`);
}
}
@@ -149,71 +120,6 @@
return lazy.zenTabsEssentialsMax;
}
- async refreshPinnedTabs({ init = false } = {}) {
- if (!this.enabled) {
- return;
- }
- await ZenPinnedTabsStorage.promiseInitialized;
- await this.#initializePinsCache();
- setTimeout(async () => {
- // Execute in a separate task to avoid blocking the main thread
- await SessionStore.promiseAllWindowsRestored;
- await gZenWorkspaces.promiseInitialized;
- await this.#initializePinnedTabs(init);
- if (init) {
- this._hasFinishedLoading = true;
- }
- }, 10);
- }
-
- async #initializePinsCache() {
- try {
- // Get pin data
- const pins = await ZenPinnedTabsStorage.getPins();
-
- // Enhance pins with favicons
- this._pinsCache = await Promise.all(
- pins.map(async (pin) => {
- try {
- if (pin.isGroup) {
- return pin; // Skip groups for now
- }
- const image = await this.getFaviconAsBase64(Services.io.newURI(pin.url));
- return {
- ...pin,
- iconUrl: image || null,
- };
- } catch {
- // If favicon fetch fails, continue without icon
- return {
- ...pin,
- iconUrl: null,
- };
- }
- })
- );
- } catch (ex) {
- console.error('Failed to initialize pins cache:', ex);
- this._pinsCache = [];
- }
-
- this.log(`Initialized pins cache with ${this._pinsCache.length} pins`);
- return this._pinsCache;
- }
-
- #finishedInitializingPins() {
- if (this.hasInitializedPins) {
- return;
- }
- this._resolvePinnedInitializedInternal();
- delete this._resolvePinnedInitializedInternal;
- this.hasInitializedPins = true;
- }
-
- async #initializePinnedTabs(init = false) {
- this.#finishedInitializingPins();
- }
-
_onPinnedTabEvent(action, event) {
if (!this.enabled) return;
const tab = event.target;
@@ -223,230 +129,22 @@
}
switch (action) {
case 'TabPinned':
- case 'TabAddedToEssentials':
tab._zenClickEventListener = this._zenClickEventListener;
tab.addEventListener('click', tab._zenClickEventListener);
- this._setPinnedAttributes(tab);
break;
- case 'TabRemovedFromEssentials':
- if (tab.pinned) {
- this.#onTabMove(tab);
- break;
- }
// [Fall through]
case 'TabUnpinned':
- this._removePinnedAttributes(tab);
if (tab._zenClickEventListener) {
tab.removeEventListener('click', tab._zenClickEventListener);
delete tab._zenClickEventListener;
}
break;
- case 'TabMove':
- this.#onTabMove(tab);
- break;
- case 'TabGroupCreate':
- this.#onTabGroupCreate(event);
- break;
- case 'TabGroupRemoved':
- this.#onTabGroupRemoved(event);
- break;
- case 'TabGroupMoved':
- this.#onTabGroupMoved(event);
- break;
- case 'ZenFolderRenamed':
- case 'ZenFolderIconChanged':
- case 'TabGroupCollapse':
- case 'TabGroupExpand':
- case 'ZenFolderChangedWorkspace':
- this.#updateGroupInfo(event.originalTarget);
- break;
- case 'TabGrouped':
- this.#onTabGrouped(event);
- break;
- case 'TabUngrouped':
- this.#onTabUngrouped(event);
- break;
default:
console.warn('ZenPinnedTabManager: Unhandled tab event', action);
break;
}
}
- async #onTabGroupCreate(event) {
- const group = event.originalTarget;
- if (!group.isZenFolder) {
- return;
- }
- if (group.hasAttribute('zen-pin-id')) {
- return; // Group already exists in storage
- }
- const workspaceId = group.getAttribute('zen-workspace-id');
- let id = await ZenPinnedTabsStorage.createGroup(
- group.name,
- group.iconURL,
- group.collapsed,
- workspaceId,
- group.getAttribute('zen-pin-id'),
- group._pPos
- );
- group.setAttribute('zen-pin-id', id);
- for (const tab of group.tabs) {
- // Only add it if the tab is directly under the group
- if (
- tab.pinned &&
- tab.hasAttribute('zen-pin-id') &&
- tab.group === group &&
- this.hasInitializedPins
- ) {
- const tabPinId = tab.getAttribute('zen-pin-id');
- await ZenPinnedTabsStorage.addTabToGroup(tabPinId, id, /* position */ tab._pPos);
- }
- }
- await this.refreshPinnedTabs();
- }
-
- async #onTabGrouped(event) {
- const tab = event.detail;
- const group = tab.group;
- if (!group.isZenFolder) {
- return;
- }
- const pinId = group.getAttribute('zen-pin-id');
- const tabPinId = tab.getAttribute('zen-pin-id');
- const tabPin = this._pinsCache?.find((p) => p.uuid === tabPinId);
- if (!tabPin || !tabPin.group) {
- return;
- }
- ZenPinnedTabsStorage.addTabToGroup(tabPinId, pinId, /* position */ tab._pPos);
- }
-
- async #onTabUngrouped(event) {
- const tab = event.detail;
- const group = tab.group;
- if (!group?.isZenFolder) {
- return;
- }
- const tabPinId = tab.getAttribute('zen-pin-id');
- const tabPin = this._pinsCache?.find((p) => p.uuid === tabPinId);
- if (!tabPin) {
- return;
- }
- ZenPinnedTabsStorage.removeTabFromGroup(tabPinId, /* position */ tab._pPos);
- }
-
- async #updateGroupInfo(group) {
- if (!group?.isZenFolder) {
- return;
- }
- const pinId = group.getAttribute('zen-pin-id');
- const groupPin = this._pinsCache?.find((p) => p.uuid === pinId);
- if (groupPin) {
- groupPin.title = group.name;
- groupPin.folderIcon = group.iconURL;
- groupPin.isFolderCollapsed = group.collapsed;
- groupPin.position = group._pPos;
- groupPin.parentUuid = group.group?.getAttribute('zen-pin-id') || null;
- groupPin.workspaceUuid = group.getAttribute('zen-workspace-id') || null;
- await this.savePin(groupPin);
- for (const item of group.allItems) {
- if (gBrowser.isTabGroup(item)) {
- await this.#updateGroupInfo(item);
- } else {
- await this.#onTabMove(item);
- }
- }
- }
- }
-
- async #onTabGroupRemoved(event) {
- const group = event.originalTarget;
- if (!group.isZenFolder) {
- return;
- }
- await ZenPinnedTabsStorage.removePin(group.getAttribute('zen-pin-id'));
- group.removeAttribute('zen-pin-id');
- }
-
- async #onTabGroupMoved(event) {
- const group = event.originalTarget;
- if (!group.isZenFolder) {
- return;
- }
- const newIndex = group._pPos;
- const pinId = group.getAttribute('zen-pin-id');
- if (!pinId) {
- return;
- }
- for (const tab of group.allItemsRecursive) {
- if (tab.pinned && tab.getAttribute('zen-pin-id') === pinId) {
- const pin = this._pinsCache.find((p) => p.uuid === pinId);
- if (pin) {
- pin.position = tab._pPos;
- pin.parentUuid = tab.group?.getAttribute('zen-pin-id') || null;
- pin.workspaceUuid = group.getAttribute('zen-workspace-id');
- await this.savePin(pin, false);
- }
- break;
- }
- }
- const groupPin = this._pinsCache?.find((p) => p.uuid === pinId);
- if (groupPin) {
- groupPin.position = newIndex;
- groupPin.parentUuid = group.group?.getAttribute('zen-pin-id');
- groupPin.workspaceUuid = group.getAttribute('zen-workspace-id');
- await this.savePin(groupPin);
- }
- }
-
- async #onTabMove(tab) {
- if (!tab.pinned || !this._pinsCache) {
- return;
- }
-
- const allTabs = [...gBrowser.tabs, ...gBrowser.tabGroups];
- for (let i = 0; i < allTabs.length; i++) {
- const otherTab = allTabs[i];
- if (
- otherTab.pinned &&
- otherTab.getAttribute('zen-pin-id') !== tab.getAttribute('zen-pin-id')
- ) {
- const actualPin = this._pinsCache.find(
- (pin) => pin.uuid === otherTab.getAttribute('zen-pin-id')
- );
- if (!actualPin) {
- continue;
- }
- actualPin.position = otherTab._pPos;
- actualPin.workspaceUuid = otherTab.getAttribute('zen-workspace-id');
- actualPin.parentUuid = otherTab.group?.getAttribute('zen-pin-id') || null;
- await this.savePin(actualPin, false);
- }
- }
-
- const actualPin = this._pinsCache.find((pin) => pin.uuid === tab.getAttribute('zen-pin-id'));
-
- if (!actualPin) {
- return;
- }
- actualPin.position = tab._pPos;
- actualPin.isEssential = tab.hasAttribute('zen-essential');
- actualPin.parentUuid = tab.group?.getAttribute('zen-pin-id') || null;
- actualPin.workspaceUuid = tab.getAttribute('zen-workspace-id') || null;
-
- // There was a bug where the title and hasStaticLabel attribute were not being set
- // This is a workaround to fix that
- if (tab.hasAttribute('zen-has-static-label')) {
- actualPin.editedTitle = true;
- actualPin.title = tab.label;
- }
- await this.savePin(actualPin);
- tab.dispatchEvent(
- new CustomEvent('ZenPinnedTabMoved', {
- detail: { tab },
- })
- );
- }
-
async _onTabClick(e) {
const tab = e.target?.closest('tab');
if (e.button === 1 && tab) {
@@ -476,106 +174,10 @@
return;
}
- const browser = tab.linkedBrowser;
-
- const pin = this._pinsCache.find((pin) => pin.uuid === tab.getAttribute('zen-pin-id'));
-
- if (!pin) {
- return;
- }
-
- const userContextId = tab.getAttribute('usercontextid');
-
- pin.title = tab.label || browser.contentTitle;
- pin.url = browser.currentURI.spec;
- pin.workspaceUuid = tab.getAttribute('zen-workspace-id');
- pin.userContextId = userContextId ? parseInt(userContextId, 10) : 0;
-
- await this.savePin(pin);
this.resetPinChangedUrl(tab);
- await this.refreshPinnedTabs();
gZenUIManager.showToast('zen-pinned-tab-replaced');
}
- async _setPinnedAttributes(tab) {
- if (
- tab.hasAttribute('zen-pin-id') ||
- !this._hasFinishedLoading ||
- tab.hasAttribute('zen-empty-tab')
- ) {
- return;
- }
-
- this.log(`Setting pinned attributes for tab ${tab.linkedBrowser.currentURI.spec}`);
- const browser = tab.linkedBrowser;
-
- const uuid = gZenUIManager.generateUuidv4();
- const userContextId = tab.getAttribute('usercontextid');
-
- let entry = null;
-
- if (tab.getAttribute('zen-pinned-entry')) {
- entry = JSON.parse(tab.getAttribute('zen-pinned-entry'));
- }
-
- await this.savePin({
- uuid,
- title: entry?.title || tab.label || browser.contentTitle,
- url: entry?.url || browser.currentURI.spec,
- containerTabId: userContextId ? parseInt(userContextId, 10) : 0,
- workspaceUuid: tab.getAttribute('zen-workspace-id'),
- isEssential: tab.getAttribute('zen-essential') === 'true',
- parentUuid: tab.group?.getAttribute('zen-pin-id') || null,
- position: tab._pPos,
- });
-
- tab.setAttribute('zen-pin-id', uuid);
- tab.dispatchEvent(
- new CustomEvent('ZenPinnedTabCreated', {
- detail: { tab },
- })
- );
-
- // This is used while migrating old pins to new system - we don't want to refresh when migrating
- if (tab.getAttribute('zen-pinned-entry')) {
- tab.removeAttribute('zen-pinned-entry');
- return;
- }
- this.onLocationChange(browser);
- await this.refreshPinnedTabs();
- }
-
- async _removePinnedAttributes(tab, isClosing = false) {
- tab.removeAttribute('zen-has-static-label');
- if (!tab.getAttribute('zen-pin-id') || this._temporarilyUnpiningEssential) {
- return;
- }
-
- if (Services.startup.shuttingDown || window.skipNextCanClose) {
- return;
- }
-
- this.log(`Removing pinned attributes for tab ${tab.getAttribute('zen-pin-id')}`);
- await ZenPinnedTabsStorage.removePin(tab.getAttribute('zen-pin-id'));
- this.resetPinChangedUrl(tab);
-
- if (!isClosing) {
- tab.removeAttribute('zen-pin-id');
- tab.removeAttribute('zen-essential'); // Just in case
-
- if (!tab.hasAttribute('zen-workspace-id') && gZenWorkspaces.workspaceEnabled) {
- const workspace = await gZenWorkspaces.getActiveWorkspace();
- tab.setAttribute('zen-workspace-id', workspace.uuid);
- }
- }
- await this.refreshPinnedTabs();
- tab.dispatchEvent(
- new CustomEvent('ZenPinnedTabRemoved', {
- detail: { tab },
- })
- );
- }
-
_initClosePinnedTabShortcut() {
let cmdClose = document.getElementById('cmd_close');
@@ -584,21 +186,6 @@
}
}
- async savePin(pin, notifyObservers = true) {
- if (!this.hasInitializedPins && !gZenUIManager.testingEnabled) {
- return;
- }
- const existingPin = this._pinsCache.find((p) => p.uuid === pin.uuid);
- if (existingPin) {
- Object.assign(existingPin, pin);
- } else {
- // We shouldn't need it, but just in case there's
- // a race condition while making new pinned tabs.
- this._pinsCache.push(pin);
- }
- await ZenPinnedTabsStorage.savePin(pin, notifyObservers);
- }
-
async onCloseTabShortcut(
event,
selectedTab = gBrowser.selectedTab,
@@ -821,12 +408,6 @@
tab.removeAttribute('zen-workspace-id');
}
if (tab.pinned && tab.hasAttribute('zen-pin-id')) {
- const pin = this._pinsCache.find((pin) => pin.uuid === tab.getAttribute('zen-pin-id'));
- if (pin) {
- pin.isEssential = true;
- pin.workspaceUuid = null;
- this.savePin(pin);
- }
gBrowser.zenHandleTabMove(tab, () => {
if (tab.ownerGlobal !== window) {
tab = gBrowser.adoptTab(tab, {
@@ -1217,11 +798,8 @@
return document.documentElement.getAttribute('zen-sidebar-expanded') === 'true';
}
- async updatePinTitle(tab, newTitle, isEdited = true, notifyObservers = true) {
+ async updatePinTitle(tab, newTitle, isEdited = true) {
const uuid = tab.getAttribute('zen-pin-id');
- await ZenPinnedTabsStorage.updatePinTitle(uuid, newTitle, isEdited, notifyObservers);
-
- await this.refreshPinnedTabs();
const browsers = Services.wm.getEnumerator('navigator:browser');
diff --git a/src/zen/tabs/ZenPinnedTabsStorage.mjs b/src/zen/tabs/ZenPinnedTabsStorage.mjs
deleted file mode 100644
index 425dbf2d1..000000000
--- a/src/zen/tabs/ZenPinnedTabsStorage.mjs
+++ /dev/null
@@ -1,635 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-var ZenPinnedTabsStorage = {
- async init() {
- await this._ensureTable();
- },
-
- async _ensureTable() {
- await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage._ensureTable', async (db) => {
- // Create the pins table if it doesn't exist
- await db.execute(`
- CREATE TABLE IF NOT EXISTS zen_pins (
- id INTEGER PRIMARY KEY,
- uuid TEXT UNIQUE NOT NULL,
- title TEXT NOT NULL,
- url TEXT,
- container_id INTEGER,
- workspace_uuid TEXT,
- position INTEGER NOT NULL DEFAULT 0,
- is_essential BOOLEAN NOT NULL DEFAULT 0,
- is_group BOOLEAN NOT NULL DEFAULT 0,
- created_at INTEGER NOT NULL,
- updated_at INTEGER NOT NULL
- )
- `);
-
- const columns = await db.execute(`PRAGMA table_info(zen_pins)`);
- const columnNames = columns.map((row) => row.getResultByName('name'));
-
- // Helper function to add column if it doesn't exist
- const addColumnIfNotExists = async (columnName, definition) => {
- if (!columnNames.includes(columnName)) {
- await db.execute(`ALTER TABLE zen_pins ADD COLUMN ${columnName} ${definition}`);
- }
- };
-
- await addColumnIfNotExists('edited_title', 'BOOLEAN NOT NULL DEFAULT 0');
- await addColumnIfNotExists('is_folder_collapsed', 'BOOLEAN NOT NULL DEFAULT 0');
- await addColumnIfNotExists('folder_icon', 'TEXT DEFAULT NULL');
- await addColumnIfNotExists('folder_parent_uuid', 'TEXT DEFAULT NULL');
-
- await db.execute(`
- CREATE INDEX IF NOT EXISTS idx_zen_pins_uuid ON zen_pins(uuid)
- `);
-
- await db.execute(`
- CREATE TABLE IF NOT EXISTS zen_pins_changes (
- uuid TEXT PRIMARY KEY,
- timestamp INTEGER NOT NULL
- )
- `);
-
- await db.execute(`
- CREATE INDEX IF NOT EXISTS idx_zen_pins_changes_uuid ON zen_pins_changes(uuid)
- `);
-
- this._resolveInitialized();
- });
- },
-
- /**
- * Private helper method to notify observers with a list of changed UUIDs.
- * @param {string} event - The observer event name.
- * @param {Array} uuids - Array of changed workspace UUIDs.
- */
- _notifyPinsChanged(event, uuids) {
- if (uuids.length === 0) return; // No changes to notify
-
- // Convert the array of UUIDs to a JSON string
- const data = JSON.stringify(uuids);
-
- Services.obs.notifyObservers(null, event, data);
- },
-
- async savePin(pin, notifyObservers = true) {
- const changedUUIDs = new Set();
-
- await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.savePin', async (db) => {
- await db.executeTransaction(async () => {
- const now = Date.now();
-
- let newPosition;
- if ('position' in pin && Number.isFinite(pin.position)) {
- newPosition = pin.position;
- } else {
- // Get the maximum position within the same parent group (or null for root level)
- const maxPositionResult = await db.execute(
- `
- SELECT MAX("position") as max_position
- FROM zen_pins
- WHERE COALESCE(folder_parent_uuid, '') = COALESCE(:folder_parent_uuid, '')
- `,
- { folder_parent_uuid: pin.parentUuid || null }
- );
- const maxPosition = maxPositionResult[0].getResultByName('max_position') || 0;
- newPosition = maxPosition + 1000;
- }
-
- // Insert or replace the pin
- await db.executeCached(
- `
- INSERT OR REPLACE INTO zen_pins (
- uuid, title, url, container_id, workspace_uuid, position,
- is_essential, is_group, folder_parent_uuid, edited_title, created_at,
- updated_at, is_folder_collapsed, folder_icon
- ) VALUES (
- :uuid, :title, :url, :container_id, :workspace_uuid, :position,
- :is_essential, :is_group, :folder_parent_uuid, :edited_title,
- COALESCE((SELECT created_at FROM zen_pins WHERE uuid = :uuid), :now),
- :now, :is_folder_collapsed, :folder_icon
- )
- `,
- {
- uuid: pin.uuid,
- title: pin.title,
- url: pin.isGroup ? '' : pin.url,
- container_id: pin.containerTabId || null,
- workspace_uuid: pin.workspaceUuid || null,
- position: newPosition,
- is_essential: pin.isEssential || false,
- is_group: pin.isGroup || false,
- folder_parent_uuid: pin.parentUuid || null,
- edited_title: pin.editedTitle || false,
- now,
- folder_icon: pin.folderIcon || null,
- is_folder_collapsed: pin.isFolderCollapsed || false,
- }
- );
-
- await db.execute(
- `
- INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
- VALUES (:uuid, :timestamp)
- `,
- {
- uuid: pin.uuid,
- timestamp: Math.floor(now / 1000),
- }
- );
-
- changedUUIDs.add(pin.uuid);
- await this.updateLastChangeTimestamp(db);
- });
- });
-
- if (notifyObservers) {
- this._notifyPinsChanged('zen-pin-updated', Array.from(changedUUIDs));
- }
- },
-
- async getPins() {
- const db = await PlacesUtils.promiseDBConnection();
- const rows = await db.executeCached(`
- SELECT * FROM zen_pins
- ORDER BY position ASC
- `);
- return rows.map((row) => ({
- uuid: row.getResultByName('uuid'),
- title: row.getResultByName('title'),
- url: row.getResultByName('url'),
- containerTabId: row.getResultByName('container_id'),
- workspaceUuid: row.getResultByName('workspace_uuid'),
- position: row.getResultByName('position'),
- isEssential: Boolean(row.getResultByName('is_essential')),
- isGroup: Boolean(row.getResultByName('is_group')),
- parentUuid: row.getResultByName('folder_parent_uuid'),
- editedTitle: Boolean(row.getResultByName('edited_title')),
- folderIcon: row.getResultByName('folder_icon'),
- isFolderCollapsed: Boolean(row.getResultByName('is_folder_collapsed')),
- }));
- },
-
- /**
- * Create a new group
- * @param {string} title - The title of the group
- * @param {string} workspaceUuid - The workspace UUID (optional)
- * @param {string} parentUuid - The parent group UUID (optional, null for root level)
- * @param {number} position - The position of the group (optional, will auto-calculate if not provided)
- * @param {boolean} notifyObservers - Whether to notify observers (default: true)
- * @returns {Promise} The UUID of the created group
- */
- async createGroup(
- title,
- icon = null,
- isCollapsed = false,
- workspaceUuid = null,
- parentUuid = null,
- position = null,
- notifyObservers = true
- ) {
- if (!title || typeof title !== 'string') {
- throw new Error('Group title is required and must be a string');
- }
-
- const groupUuid = gZenUIManager.generateUuidv4();
-
- const groupPin = {
- uuid: groupUuid,
- title,
- folderIcon: icon || null,
- isFolderCollapsed: isCollapsed || false,
- workspaceUuid,
- parentUuid,
- position,
- isGroup: true,
- isEssential: false,
- editedTitle: true, // Group titles are always considered edited
- };
-
- await this.savePin(groupPin, notifyObservers);
- return groupUuid;
- },
-
- /**
- * Add an existing tab/pin to a group
- * @param {string} tabUuid - The UUID of the tab to add to the group
- * @param {string} groupUuid - The UUID of the target group
- * @param {number} position - The position within the group (optional, will append if not provided)
- * @param {boolean} notifyObservers - Whether to notify observers (default: true)
- */
- async addTabToGroup(tabUuid, groupUuid, position = null, notifyObservers = true) {
- if (!tabUuid || !groupUuid) {
- throw new Error('Both tabUuid and groupUuid are required');
- }
-
- const changedUUIDs = new Set();
-
- await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.addTabToGroup', async (db) => {
- await db.executeTransaction(async () => {
- // Verify the group exists and is actually a group
- const groupCheck = await db.execute(
- `SELECT is_group FROM zen_pins WHERE uuid = :groupUuid`,
- { groupUuid }
- );
-
- if (groupCheck.length === 0) {
- throw new Error(`Group with UUID ${groupUuid} does not exist`);
- }
-
- if (!groupCheck[0].getResultByName('is_group')) {
- throw new Error(`Pin with UUID ${groupUuid} is not a group`);
- }
-
- const tabCheck = await db.execute(`SELECT uuid FROM zen_pins WHERE uuid = :tabUuid`, {
- tabUuid,
- });
-
- if (tabCheck.length === 0) {
- throw new Error(`Tab with UUID ${tabUuid} does not exist`);
- }
-
- const now = Date.now();
- let newPosition;
-
- if (position !== null && Number.isFinite(position)) {
- newPosition = position;
- } else {
- // Get the maximum position within the group
- const maxPositionResult = await db.execute(
- `SELECT MAX("position") as max_position FROM zen_pins WHERE folder_parent_uuid = :groupUuid`,
- { groupUuid }
- );
- const maxPosition = maxPositionResult[0].getResultByName('max_position') || 0;
- newPosition = maxPosition + 1000;
- }
-
- await db.execute(
- `
- UPDATE zen_pins
- SET folder_parent_uuid = :groupUuid,
- position = :newPosition,
- updated_at = :now
- WHERE uuid = :tabUuid
- `,
- {
- tabUuid,
- groupUuid,
- newPosition,
- now,
- }
- );
-
- changedUUIDs.add(tabUuid);
-
- await db.execute(
- `
- INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
- VALUES (:uuid, :timestamp)
- `,
- {
- uuid: tabUuid,
- timestamp: Math.floor(now / 1000),
- }
- );
-
- await this.updateLastChangeTimestamp(db);
- });
- });
-
- if (notifyObservers) {
- this._notifyPinsChanged('zen-pin-updated', Array.from(changedUUIDs));
- }
- },
-
- /**
- * Remove a tab from its group (move to root level)
- * @param {string} tabUuid - The UUID of the tab to remove from its group
- * @param {number} newPosition - The new position at root level (optional, will append if not provided)
- * @param {boolean} notifyObservers - Whether to notify observers (default: true)
- */
- async removeTabFromGroup(tabUuid, newPosition = null, notifyObservers = true) {
- if (!tabUuid) {
- throw new Error('tabUuid is required');
- }
-
- const changedUUIDs = new Set();
-
- await PlacesUtils.withConnectionWrapper(
- 'ZenPinnedTabsStorage.removeTabFromGroup',
- async (db) => {
- await db.executeTransaction(async () => {
- // Verify the tab exists and is in a group
- const tabCheck = await db.execute(
- `SELECT folder_parent_uuid FROM zen_pins WHERE uuid = :tabUuid`,
- { tabUuid }
- );
-
- if (tabCheck.length === 0) {
- throw new Error(`Tab with UUID ${tabUuid} does not exist`);
- }
-
- if (!tabCheck[0].getResultByName('folder_parent_uuid')) {
- return;
- }
-
- const now = Date.now();
- let finalPosition;
-
- if (newPosition !== null && Number.isFinite(newPosition)) {
- finalPosition = newPosition;
- } else {
- // Get the maximum position at root level (where folder_parent_uuid is null)
- const maxPositionResult = await db.execute(
- `SELECT MAX("position") as max_position FROM zen_pins WHERE folder_parent_uuid IS NULL`
- );
- const maxPosition = maxPositionResult[0].getResultByName('max_position') || 0;
- finalPosition = maxPosition + 1000;
- }
-
- // Update the tab to be at root level
- await db.execute(
- `
- UPDATE zen_pins
- SET folder_parent_uuid = NULL,
- position = :newPosition,
- updated_at = :now
- WHERE uuid = :tabUuid
- `,
- {
- tabUuid,
- newPosition: finalPosition,
- now,
- }
- );
-
- changedUUIDs.add(tabUuid);
-
- // Record the change
- await db.execute(
- `
- INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
- VALUES (:uuid, :timestamp)
- `,
- {
- uuid: tabUuid,
- timestamp: Math.floor(now / 1000),
- }
- );
-
- await this.updateLastChangeTimestamp(db);
- });
- }
- );
-
- if (notifyObservers) {
- this._notifyPinsChanged('zen-pin-updated', Array.from(changedUUIDs));
- }
- },
-
- async removePin(uuid, notifyObservers = true) {
- const changedUUIDs = [uuid];
-
- await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.removePin', async (db) => {
- await db.executeTransaction(async () => {
- // Get all child UUIDs first for change tracking
- const children = await db.execute(
- `SELECT uuid FROM zen_pins WHERE folder_parent_uuid = :uuid`,
- {
- uuid,
- }
- );
-
- // Add child UUIDs to changedUUIDs array
- for (const child of children) {
- changedUUIDs.push(child.getResultByName('uuid'));
- }
-
- // Delete the pin/group itself
- await db.execute(`DELETE FROM zen_pins WHERE uuid = :uuid`, { uuid });
-
- // Record the changes
- const now = Math.floor(Date.now() / 1000);
- for (const changedUuid of changedUUIDs) {
- await db.execute(
- `
- INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
- VALUES (:uuid, :timestamp)
- `,
- {
- uuid: changedUuid,
- timestamp: now,
- }
- );
- }
-
- await this.updateLastChangeTimestamp(db);
- });
- });
-
- if (notifyObservers) {
- this._notifyPinsChanged('zen-pin-removed', changedUUIDs);
- }
- },
-
- async wipeAllPins() {
- await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.wipeAllPins', async (db) => {
- await db.execute(`DELETE FROM zen_pins`);
- await db.execute(`DELETE FROM zen_pins_changes`);
- await this.updateLastChangeTimestamp(db);
- });
- },
-
- async markChanged(uuid) {
- await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.markChanged', async (db) => {
- const now = Date.now();
- await db.execute(
- `
- INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
- VALUES (:uuid, :timestamp)
- `,
- {
- uuid,
- timestamp: Math.floor(now / 1000),
- }
- );
- });
- },
-
- async getChangedIDs() {
- const db = await PlacesUtils.promiseDBConnection();
- const rows = await db.execute(`
- SELECT uuid, timestamp FROM zen_pins_changes
- `);
- const changes = {};
- for (const row of rows) {
- changes[row.getResultByName('uuid')] = row.getResultByName('timestamp');
- }
- return changes;
- },
-
- async clearChangedIDs() {
- await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.clearChangedIDs', async (db) => {
- await db.execute(`DELETE FROM zen_pins_changes`);
- });
- },
-
- shouldReorderPins(before, current, after) {
- const minGap = 1; // Minimum allowed gap between positions
- return (
- (before !== null && current - before < minGap) || (after !== null && after - current < minGap)
- );
- },
-
- async reorderAllPins(db, changedUUIDs) {
- const pins = await db.execute(`
- SELECT uuid
- FROM zen_pins
- ORDER BY position ASC
- `);
-
- for (let i = 0; i < pins.length; i++) {
- const newPosition = (i + 1) * 1000; // Use large increments
- await db.execute(
- `
- UPDATE zen_pins
- SET position = :newPosition
- WHERE uuid = :uuid
- `,
- { newPosition, uuid: pins[i].getResultByName('uuid') }
- );
- changedUUIDs.add(pins[i].getResultByName('uuid'));
- }
- },
-
- async updateLastChangeTimestamp(db) {
- const now = Date.now();
- await db.execute(
- `
- INSERT OR REPLACE INTO moz_meta (key, value)
- VALUES ('zen_pins_last_change', :now)
- `,
- { now }
- );
- },
-
- async getLastChangeTimestamp() {
- const db = await PlacesUtils.promiseDBConnection();
- const result = await db.executeCached(`
- SELECT value FROM moz_meta WHERE key = 'zen_pins_last_change'
- `);
- return result.length ? parseInt(result[0].getResultByName('value'), 10) : 0;
- },
-
- async updatePinPositions(pins) {
- const changedUUIDs = new Set();
-
- await PlacesUtils.withConnectionWrapper(
- 'ZenPinnedTabsStorage.updatePinPositions',
- async (db) => {
- await db.executeTransaction(async () => {
- const now = Date.now();
-
- for (let i = 0; i < pins.length; i++) {
- const pin = pins[i];
- const newPosition = (i + 1) * 1000;
-
- await db.execute(
- `
- UPDATE zen_pins
- SET position = :newPosition
- WHERE uuid = :uuid
- `,
- { newPosition, uuid: pin.uuid }
- );
-
- changedUUIDs.add(pin.uuid);
-
- // Record the change
- await db.execute(
- `
- INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
- VALUES (:uuid, :timestamp)
- `,
- {
- uuid: pin.uuid,
- timestamp: Math.floor(now / 1000),
- }
- );
- }
-
- await this.updateLastChangeTimestamp(db);
- });
- }
- );
-
- this._notifyPinsChanged('zen-pin-updated', Array.from(changedUUIDs));
- },
-
- async updatePinTitle(uuid, newTitle, isEdited = true, notifyObservers = true) {
- if (!uuid || typeof newTitle !== 'string') {
- throw new Error('Invalid parameters: uuid and newTitle are required');
- }
-
- const changedUUIDs = new Set();
-
- await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.updatePinTitle', async (db) => {
- await db.executeTransaction(async () => {
- const now = Date.now();
-
- // Update the pin's title and edited_title flag
- const result = await db.execute(
- `
- UPDATE zen_pins
- SET title = :newTitle,
- edited_title = :isEdited,
- updated_at = :now
- WHERE uuid = :uuid
- `,
- {
- uuid,
- newTitle,
- isEdited,
- now,
- }
- );
-
- // Only proceed with change tracking if a row was actually updated
- if (result.rowsAffected > 0) {
- changedUUIDs.add(uuid);
-
- // Record the change
- await db.execute(
- `
- INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
- VALUES (:uuid, :timestamp)
- `,
- {
- uuid,
- timestamp: Math.floor(now / 1000),
- }
- );
-
- await this.updateLastChangeTimestamp(db);
- }
- });
- });
-
- if (notifyObservers && changedUUIDs.size > 0) {
- this._notifyPinsChanged('zen-pin-updated', Array.from(changedUUIDs));
- }
- },
-
- async __dropTables() {
- await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.__dropTables', async (db) => {
- await db.execute(`DROP TABLE IF EXISTS zen_pins`);
- await db.execute(`DROP TABLE IF EXISTS zen_pins_changes`);
- });
- },
-};
-
-ZenPinnedTabsStorage.promiseInitialized = new Promise((resolve) => {
- ZenPinnedTabsStorage._resolveInitialized = resolve;
- ZenPinnedTabsStorage.init();
-});
diff --git a/src/zen/workspaces/ZenWindowSyncing.mjs b/src/zen/workspaces/ZenWindowSyncing.mjs
index 857f9fc9c..4c06ae0e0 100644
--- a/src/zen/workspaces/ZenWindowSyncing.mjs
+++ b/src/zen/workspaces/ZenWindowSyncing.mjs
@@ -293,14 +293,14 @@
targetTab.getAttribute('zen-workspace-id')
);
}
- duplicatedTab.setAttribute('zen-pin-id', targetTab.getAttribute('zen-pin-id'));
duplicatedTab.setAttribute('zen-sync-id', targetTab.getAttribute('zen-sync-id'));
}
#onTabGroupCreate(event) {
- const targetGroup = event.target;
- const isSplitView = targetGroup.classList.contains('zen-split-view');
- const isFolder = targetGroup.isZenFolder;
+ void event;
+ //const targetGroup = event.target;
+ //const isSplitView = targetGroup.classList.contains('zen-split-view');
+ //const isFolder = targetGroup.isZenFolder;
}
}
diff --git a/src/zen/workspaces/ZenWorkspaces.mjs b/src/zen/workspaces/ZenWorkspaces.mjs
index a54c1ebfe..f19ba7277 100644
--- a/src/zen/workspaces/ZenWorkspaces.mjs
+++ b/src/zen/workspaces/ZenWorkspaces.mjs
@@ -932,7 +932,6 @@ var gZenWorkspaces = new (class extends nsZenMultiWindowFeature {
await this.workspaceBookmarks();
await this.initializeTabsStripSections();
this._initializeEmptyTab();
- await gZenPinnedTabManager.refreshPinnedTabs({ init: true });
await this.changeWorkspace(activeWorkspace, { onInit: true });
this.#fixTabPositions();
this.onWindowResize();
@@ -1471,11 +1470,6 @@ var gZenWorkspaces = new (class extends nsZenMultiWindowFeature {
!tab.hasAttribute('zen-empty-tab') &&
!tab.hasAttribute('zen-essential')
);
- for (const tab of tabs) {
- if (tab.pinned) {
- await ZenPinnedTabsStorage.removePin(tab.getAttribute('zen-pin-id'));
- }
- }
gBrowser.removeTabs(tabs, {
animate: false,
skipSessionStore: true,