fix: Fixed restoring folders not working when the empty tab is not first, b=no-bug, c=folders, tabs, tests

This commit is contained in:
Mr. M
2025-08-19 14:17:35 +02:00
parent 04105c3c5e
commit e7a9aba3c0
7 changed files with 68 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js
index caea196b22b4689f55780a528661d87b52f4e728..54f3be2b115f6b3691792796f758534aec90206d 100644 index caea196b22b4689f55780a528661d87b52f4e728..9c1e141b6b2121d32f30c82862b597146f664b34 100644
--- a/browser/components/tabbrowser/content/tabgroup.js --- a/browser/components/tabbrowser/content/tabgroup.js
+++ b/browser/components/tabbrowser/content/tabgroup.js +++ b/browser/components/tabbrowser/content/tabgroup.js
@@ -13,10 +13,12 @@ @@ -13,10 +13,12 @@
@@ -18,7 +18,7 @@ index caea196b22b4689f55780a528661d87b52f4e728..54f3be2b115f6b3691792796f758534a
<vbox class="tab-group-overflow-count-container" pack="center"> <vbox class="tab-group-overflow-count-container" pack="center">
<label class="tab-group-overflow-count" role="button" /> <label class="tab-group-overflow-count" role="button" />
</vbox> </vbox>
@@ -57,20 +59,27 @@ @@ -57,20 +59,26 @@
} }
connectedCallback() { connectedCallback() {
@@ -46,11 +46,10 @@ index caea196b22b4689f55780a528661d87b52f4e728..54f3be2b115f6b3691792796f758534a
- return; - return;
- } - }
+ if (!this._initialized) { + if (!this._initialized) {
+
this._initialized = true; this._initialized = true;
this.saveOnWindowClose = true; this.saveOnWindowClose = true;
@@ -97,11 +106,10 @@ @@ -97,11 +105,14 @@
this.#labelElement.container = gBrowser.tabContainer; this.#labelElement.container = gBrowser.tabContainer;
this.#labelElement.group = this; this.#labelElement.group = this;
@@ -61,12 +60,16 @@ index caea196b22b4689f55780a528661d87b52f4e728..54f3be2b115f6b3691792796f758534a
- }); - });
+ this.appendChild = function (child) { + this.appendChild = function (child) {
+ this.querySelector(".tab-group-container").appendChild(child); + this.querySelector(".tab-group-container").appendChild(child);
+ for (let tab of this.tabs) {
+ if (tab.hasAttribute("zen-empty-tab") && tab.group === this) {
+ this.querySelector(".zen-tab-group-start").after(tab);
+ }
+ }
+ }; + };
+
this.#updateLabelAriaAttributes(); this.#updateLabelAriaAttributes();
this.#updateCollapsedAriaAttributes(); this.#updateCollapsedAriaAttributes();
@@ -127,6 +135,8 @@ @@ -127,6 +138,8 @@
// mounts after getting created by `Tabbrowser.adoptTabGroup`. // mounts after getting created by `Tabbrowser.adoptTabGroup`.
this.#wasCreatedByAdoption = false; this.#wasCreatedByAdoption = false;
} }
@@ -75,7 +78,7 @@ index caea196b22b4689f55780a528661d87b52f4e728..54f3be2b115f6b3691792796f758534a
resetDefaultGroupName = () => { resetDefaultGroupName = () => {
this.#defaultGroupName = ""; this.#defaultGroupName = "";
@@ -197,7 +207,10 @@ @@ -197,7 +210,10 @@
} }
}); });
} }
@@ -87,7 +90,7 @@ index caea196b22b4689f55780a528661d87b52f4e728..54f3be2b115f6b3691792796f758534a
} }
get color() { get color() {
@@ -338,12 +351,61 @@ @@ -338,12 +354,61 @@
tabGroupName, tabGroupName,
}) })
.then(result => { .then(result => {
@@ -151,7 +154,7 @@ index caea196b22b4689f55780a528661d87b52f4e728..54f3be2b115f6b3691792796f758534a
} }
/** /**
@@ -373,7 +435,7 @@ @@ -373,7 +438,7 @@
*/ */
addTabs(tabs, metricsContext) { addTabs(tabs, metricsContext) {
for (let tab of tabs) { for (let tab of tabs) {
@@ -160,7 +163,7 @@ index caea196b22b4689f55780a528661d87b52f4e728..54f3be2b115f6b3691792796f758534a
tab.ownerGlobal.gBrowser.unpinTab(tab); tab.ownerGlobal.gBrowser.unpinTab(tab);
} }
let tabToMove = let tabToMove =
@@ -437,7 +499,7 @@ @@ -437,7 +502,7 @@
*/ */
on_click(event) { on_click(event) {
let isToggleElement = let isToggleElement =
@@ -169,11 +172,10 @@ index caea196b22b4689f55780a528661d87b52f4e728..54f3be2b115f6b3691792796f758534a
event.target === this.#overflowCountLabel; event.target === this.#overflowCountLabel;
if (isToggleElement && event.button === 0) { if (isToggleElement && event.button === 0) {
event.preventDefault(); event.preventDefault();
@@ -470,5 +532,6 @@ @@ -470,5 +535,6 @@
} }
} }
+ window.MozTabbrowserTabGroup = MozTabbrowserTabGroup; + window.MozTabbrowserTabGroup = MozTabbrowserTabGroup;
customElements.define("tab-group", MozTabbrowserTabGroup); customElements.define("tab-group", MozTabbrowserTabGroup);
} }

View File

@@ -613,9 +613,13 @@
gBrowser.pinTab(tab); gBrowser.pinTab(tab);
} }
const pinnedContainer = options.workspaceId const workspacePinned = gZenWorkspaces.workspaceElement(
? gZenWorkspaces.workspaceElement(options.workspaceId).pinnedTabsContainer options.workspaceId
: gZenWorkspaces.pinnedTabsContainer; )?.pinnedTabsContainer;
const pinnedContainer =
options.workspaceId && workspacePinned
? workspacePinned
: gZenWorkspaces.pinnedTabsContainer;
const insertBefore = const insertBefore =
options.insertBefore || pinnedContainer.querySelector('.pinned-tabs-container-separator'); options.insertBefore || pinnedContainer.querySelector('.pinned-tabs-container-separator');
const emptyTab = gBrowser.addTab('about:blank', { const emptyTab = gBrowser.addTab('about:blank', {
@@ -1327,7 +1331,7 @@
if (parentWorkingData && parentWorkingData.node) { if (parentWorkingData && parentWorkingData.node) {
switch (stateData?.prevSiblingInfo?.type) { switch (stateData?.prevSiblingInfo?.type) {
case 'group': { case 'group': {
const folder = document.querySelector(`[id="${stateData.prevSiblingInfo.id}"]`); const folder = document.getElementById(stateData.prevSiblingInfo.id);
gBrowser.moveTabAfter(node, folder); gBrowser.moveTabAfter(node, folder);
break; break;
} }

View File

@@ -278,7 +278,7 @@ zen-folder {
fill-opacity: 0.9; fill-opacity: 0.9;
-moz-context-properties: fill, fill-opacity; -moz-context-properties: fill, fill-opacity;
fill: var(--zen-folder-stroke); fill: var(--zen-folder-stroke);
transform: translate(-180%, 8%); transform: translate(-180%, 9%);
} }
} }

View File

@@ -245,6 +245,7 @@
} }
const groups = new Map(); const groups = new Map();
const pendingTabsInsideGroups = {};
// Third pass: create new tabs for pins that don't have tabs // Third pass: create new tabs for pins that don't have tabs
for (let pin of pins) { for (let pin of pins) {
@@ -262,6 +263,13 @@
tabs.push(existingTab); tabs.push(existingTab);
} }
} }
// We still need to iterate through pending tabs since the database
// query doesn't guarantee the order of insertion
for (const [parentUuid, folderTabs] of Object.entries(pendingTabsInsideGroups)) {
if (parentUuid === pin.uuid) {
tabs.push(...folderTabs);
}
}
const group = gZenFolders.createFolder(tabs, { const group = gZenFolders.createFolder(tabs, {
label: pin.title, label: pin.title,
collapsed: pin.isFolderCollapsed, collapsed: pin.isFolderCollapsed,
@@ -338,6 +346,12 @@
const parentGroup = groups.get(pin.parentUuid); const parentGroup = groups.get(pin.parentUuid);
if (parentGroup) { if (parentGroup) {
parentGroup.querySelector('.tab-group-container').appendChild(newTab); parentGroup.querySelector('.tab-group-container').appendChild(newTab);
} else {
if (pendingTabsInsideGroups[pin.parentUuid]) {
pendingTabsInsideGroups[pin.parentUuid].push(newTab);
} else {
pendingTabsInsideGroups[pin.parentUuid] = [newTab];
}
} }
} else { } else {
if (!pin.isEssential) { if (!pin.isEssential) {

View File

@@ -13,5 +13,6 @@ support-files = [
["browser_folder_owner_tabs.js"] ["browser_folder_owner_tabs.js"]
["browser_folder_density.js"] ["browser_folder_density.js"]
["browser_folder_max_subfolders.js"] ["browser_folder_max_subfolders.js"]
["browser_folder_empty_tab.js"]
["browser_folder_issue_9885.js"] ["browser_folder_issue_9885.js"]

View File

@@ -0,0 +1,22 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Empty_Tab_First() {
const tab = gBrowser.selectedTab;
const [tab1, tab2] = await Promise.all([addTabTo(gBrowser), addTabTo(gBrowser)]);
const folder = await gZenFolders.createFolder([tab1], {
renameFolder: false,
});
Assert.equal(folder.tabs.length, 2, 'Folder should contain the original tab');
ok(folder.tabs[0].hasAttribute('zen-empty-tab'), 'First tab should be an empty tab');
folder.appendChild(tab2);
Assert.equal(folder.tabs.length, 3, 'Folder should contain the second tab');
ok(folder.tabs[0].hasAttribute('zen-empty-tab'), 'First tab should be an empty tab');
await removeFolder(folder);
});

View File

@@ -18,3 +18,11 @@ async function openFolderContextMenu(folder) {
}); });
await menuEvent; await menuEvent;
} }
async function addTabTo(targetBrowser, url = 'http://mochi.test:8888/', params = {}) {
params.skipAnimation = true;
const tab = BrowserTestUtils.addTab(targetBrowser, url, params);
const browser = targetBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
return tab;
}