diff --git a/src/browser/base/content/ZenStartup.mjs b/src/browser/base/content/ZenStartup.mjs index 5ce8930be..69259844b 100644 --- a/src/browser/base/content/ZenStartup.mjs +++ b/src/browser/base/content/ZenStartup.mjs @@ -3,11 +3,9 @@ var ZenStartup = { init() { this.openWatermark(); - window.SessionStore.promiseInitialized.then(() => { - this._changeSidebarLocation(); - this._zenInitBrowserLayout(); - this._initSearchBar(); - }); + this._changeSidebarLocation(); + this._zenInitBrowserLayout(); + this._initSearchBar(); }, _zenInitBrowserLayout() { diff --git a/src/browser/base/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs index e9f32b5b7..3613dca34 100644 --- a/src/browser/base/content/ZenUIManager.mjs +++ b/src/browser/base/content/ZenUIManager.mjs @@ -14,9 +14,7 @@ var gZenUIManager = { return ChromeUtils.importESModule('chrome://browser/content/zen-vendor/motion.min.mjs', { global: 'current' }); }); - new ResizeObserver(gZenCommonActions.throttle(this.updateTabsToolbar.bind(this), this.sidebarHeightThrottle)).observe( - document.getElementById('TabsToolbar') - ); + new ResizeObserver(this.updateTabsToolbar.bind(this)).observe(document.getElementById('TabsToolbar')); new ResizeObserver( gZenCommonActions.throttle( @@ -149,8 +147,8 @@ var gZenUIManager = { this.__currentPopupTrackElement = null; }, - get newtabButton() { - return ZenWorkspaces.activeWorkspaceStrip.querySelector('#tabs-newtab-button'); + get newtabButtons() { + return document.querySelectorAll('#tabs-newtab-button'); }, _prevUrlbarLabel: null, @@ -170,7 +168,9 @@ var gZenUIManager = { this._prevUrlbarLabel = gURLBar._untrimmedValue; gURLBar._zenHandleUrlbarClose = this.handleUrlbarClose.bind(this); gURLBar.setAttribute('zen-newtab', true); - this.newtabButton.setAttribute('in-urlbar', true); + for (const button of this.newtabButtons) { + button.setAttribute('in-urlbar', true); + } document.getElementById('Browser:OpenLocation').doCommand(); gURLBar.search(this._lastSearch); return true; @@ -188,7 +188,9 @@ var gZenUIManager = { gURLBar.removeAttribute('zen-newtab'); this._lastTab._visuallySelected = true; this._lastTab = null; - this.newtabButton.removeAttribute('in-urlbar'); + for (const button of this.newtabButtons) { + button.removeAttribute('in-urlbar'); + } if (onSwitch) { this.clearUrlbarData(); } else { @@ -241,7 +243,7 @@ var gZenVerticalTabsManager = { window.addEventListener('customizationstarting', this._preCustomize.bind(this)); window.addEventListener('aftercustomization', this._postCustomize.bind(this)); - window.addEventListener('MozAfterPaint', updateEvent, { once: true }); + this._updateEvent(); if (!this.isWindowsStyledButtons) { document.documentElement.setAttribute('zen-window-buttons-reversed', true); @@ -570,6 +572,7 @@ var gZenVerticalTabsManager = { } catch (e) { console.error(e); } + gZenUIManager.updateTabsToolbar(); this._isUpdating = false; }, diff --git a/src/browser/base/zen-components/ZenPinnedTabManager.mjs b/src/browser/base/zen-components/ZenPinnedTabManager.mjs index c81e6a670..3bb7f747f 100644 --- a/src/browser/base/zen-components/ZenPinnedTabManager.mjs +++ b/src/browser/base/zen-components/ZenPinnedTabManager.mjs @@ -238,6 +238,7 @@ ); contaienr.insertBefore(newTab, contaienr.lastChild); } + gBrowser.tabContainer._invalidateCachedTabs(); newTab.initialize(); } @@ -248,6 +249,7 @@ } gBrowser._updateTabBarForPinnedTabs(); + gZenUIManager.updateTabsToolbar(); } _onPinnedTabEvent(action, event) { diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 0991160cf..7baabccac 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -177,16 +177,19 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { const defaultSelectedContainer = document.querySelector( `#tabbrowser-arrowscrollbox .zen-workspace-tabs-section[zen-workspace-id="${this.activeWorkspace}"]` ); - const pinnedContainer = document.querySelector( - `#vertical-pinned-tabs-container .zen-workspace-tabs-section[zen-workspace-id="${this.activeWorkspace}"]` - ); - for (const tab of tabs) { - if (tab.pinned) { - pinnedContainer.insertBefore(tab, pinnedContainer.lastChild); - continue; + // New profile with no workspaces does not have a default selected container + if (defaultSelectedContainer) { + const pinnedContainer = document.querySelector( + `#vertical-pinned-tabs-container .zen-workspace-tabs-section[zen-workspace-id="${this.activeWorkspace}"]` + ); + for (const tab of tabs) { + if (tab.pinned) { + pinnedContainer.insertBefore(tab, pinnedContainer.lastChild); + continue; + } + // before to the last child (perifery) + defaultSelectedContainer.insertBefore(tab, defaultSelectedContainer.lastChild); } - // before to the last child (perifery) - defaultSelectedContainer.insertBefore(tab, defaultSelectedContainer.lastChild); } } perifery.setAttribute('hidden', 'true'); @@ -229,6 +232,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { _organizeTabsToWorkspaceSections(workspace, section, pinnedSection, tabs) { const workspaceTabs = Array.from(tabs).filter((tab) => tab.getAttribute('zen-workspace-id') === workspace.uuid); for (const tab of workspaceTabs) { + if (tab.hasAttribute('zen-essential')) { + continue; // Ignore essentials as they need to be in their own section + } // remove tab from list tabs.splice(tabs.indexOf(tab), 1); if (tab.pinned) { @@ -544,14 +550,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { activeWorkspace = await this.createAndSaveWorkspace('Default Workspace', true, '🏠'); } else { activeWorkspace = await this.getActiveWorkspace(); - if (!activeWorkspace) { - activeWorkspace = workspaces.workspaces.find((workspace) => workspace.default); - this.activeWorkspace = activeWorkspace?.uuid; - } - if (!activeWorkspace) { - activeWorkspace = workspaces.workspaces[0]; - this.activeWorkspace = activeWorkspace?.uuid; - } + this.activeWorkspace = activeWorkspace?.uuid; } try { if (activeWorkspace) { @@ -777,7 +776,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { async getActiveWorkspace() { const workspaces = await this._workspaces(); - return workspaces.workspaces.find((workspace) => workspace.uuid === this.activeWorkspace) ?? workspaces.workspaces[0]; + return ( + workspaces.workspaces.find((workspace) => workspace.uuid === this.activeWorkspace) ?? + workspaces.workspaces.find((workspace) => workspace.default) ?? + workspaces.workspaces[0] + ); } // Workspaces dialog UI management @@ -1492,9 +1495,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { container.style.transform = `translateX(${newTransform + offsetPixels / 2}%)`; container.style.opacity = offsetPixels ? 1 : !newTransform; if (!offsetPixels && !container.hasAttribute('active')) { - container.style.position = 'fixed'; + container.setAttribute('hidden', 'true'); } else { - container.style.removeProperty('position'); + container.removeAttribute('hidden'); } } } @@ -1538,7 +1541,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { const newTransform = `translateX(${offset}%)`; const isCurrent = offset === 0; if (shouldAnimate) { - element.style.removeProperty('position'); + element.removeAttribute('hidden'); if (isCurrent) { element.style.opacity = 1; } @@ -1562,16 +1565,12 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { element.setAttribute('active', 'true'); if (tabToSelect != gBrowser.selectedTab) { gBrowser.selectedTab = tabToSelect; - tabToSelect._visuallySelected = false; } } else { element.removeAttribute('active'); } } await Promise.all(animations); - if (tabToSelect) { - tabToSelect._visuallySelected = true; - } this._animatingChange = false; } @@ -1650,7 +1649,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { const newTab = this._createNewTabForWorkspace(window); tabToSelect = newTab; } - tabToSelect._visuallySelected = true; + if (tabToSelect) { + tabToSelect._visuallySelected = true; + } // Always make sure we always unselect the tab from the old workspace if (currentSelectedTab && currentSelectedTab !== tabToSelect) { @@ -1726,7 +1727,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } } - _createWorkspaceData(name, isDefault, icon) { + _createWorkspaceData(name, isDefault, icon, tabs) { let window = { uuid: gZenUIManager.generateUuidv4(), default: isDefault, @@ -1737,7 +1738,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { this._prepareNewWorkspace(window); const perifery = document.querySelector('#tabbrowser-arrowscrollbox-periphery[hidden]'); perifery?.removeAttribute('hidden'); - this._createWorkspaceTabsSection(window, [], perifery); + this._createWorkspaceTabsSection(window, tabs, perifery); perifery.setAttribute('hidden', 'true'); return window; } @@ -1746,10 +1747,19 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { if (!this.workspaceEnabled) { return; } - let workspaceData = this._createWorkspaceData(name, isDefault, icon); + // get extra tabs remaning (e.g. on new profiles) and just move them to the new workspace + const extraTabs = Array.from(gBrowser.tabContainer.arrowScrollbox.children).filter( + (child) => child.tagName === 'tab' && !child.hasAttribute('zen-workspace-id') + ); + let workspaceData = this._createWorkspaceData(name, isDefault, icon, extraTabs); await this.saveWorkspace(workspaceData); - await this.changeWorkspace(workspaceData); this.registerPinnedResizeObserver(); + let changed = extraTabs.length > 0; + if (changed) { + gBrowser.tabContainer._invalidateCachedTabs(); + gBrowser.selectedTab = extraTabs[0]; + } + await this.changeWorkspace(workspaceData); return workspaceData; } @@ -1822,12 +1832,21 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } makeSurePinTabIsInCorrectPosition() { + if (!this.pinnedTabsContainer) { + return 0; // until we initialize the pinned tabs container + } const tabsInsidePinTab = Array.from(this.pinnedTabsContainer.parentElement.children).filter( (child) => child.tagName === 'tab' ); let changed = false; for (const tab of tabsInsidePinTab) { + if (tab.getAttribute('zen-glance-tab') === 'true') { + continue; + } if (tab.getAttribute('zen-essential') === 'true') { + const container = document.getElementById('zen-essentials-container'); + container.appendChild(tab); + changed = true; continue; } const workspaceId = tab.getAttribute('zen-workspace-id'); @@ -1843,6 +1862,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { if (changed) { gBrowser.tabContainer._invalidateCachedTabs(); } + // Return the number of essentials INSIDE the pinned tabs container so we can correctly change their parent + return Array.from(this.pinnedTabsContainer.children).filter((child) => child.getAttribute('zen-essential') === 'true') + .length; } // Context menu management diff --git a/src/browser/components/tabbrowser/content/tabbrowser-js.patch b/src/browser/components/tabbrowser/content/tabbrowser-js.patch index 5511152c7..6790f1ba4 100644 --- a/src/browser/components/tabbrowser/content/tabbrowser-js.patch +++ b/src/browser/components/tabbrowser/content/tabbrowser-js.patch @@ -1,5 +1,5 @@ diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js -index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..bdebb5eeb16c1c7b9fd0d0266d5fa7b5e12e95a1 100644 +index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..5db2380df21f4b25a6c03bfa457b62093051cc9a 100644 --- a/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js @@ -406,11 +406,39 @@ @@ -9,7 +9,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..bdebb5eeb16c1c7b9fd0d0266d5fa7b5 + get _numVisiblePinTabs() { + let i = 0; + for (let tab of this.tabs) { -+ if (!tab.pinned) { ++ if (!tab.pinned && !tab.hasAttribute("zen-glance-tab")) { + break; + } + if (!tab.hidden) { @@ -22,7 +22,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..bdebb5eeb16c1c7b9fd0d0266d5fa7b5 + get _numZenEssentials() { + let i = 0; + for (let tab of this.tabs) { -+ if (!tab.hasAttribute("zen-essential")) { ++ if (!tab.hasAttribute("zen-essential") && !tab.hasAttribute("zen-glance-tab")) { + break; + } + if (!tab.hidden) { @@ -37,14 +37,14 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..bdebb5eeb16c1c7b9fd0d0266d5fa7b5 - if (!this.tabs[i].pinned) { + let i = 0; + for (let tab of this.tabs) { -+ if (!tab.pinned) { ++ if (!tab.pinned && !tab.hasAttribute("zen-glance-tab")) { break; } + i++; } return i; } -@@ -807,10 +835,10 @@ +@@ -807,7 +835,7 @@ this.showTab(aTab); if (this.tabContainer.verticalMode) { this._handleTabMove(aTab, () => @@ -52,12 +52,8 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..bdebb5eeb16c1c7b9fd0d0266d5fa7b5 + aTab.hasAttribute("zen-essential") ? document.getElementById("zen-essentials-container").appendChild(aTab) : this.verticalPinnedTabsContainer.insertBefore(aTab, this.verticalPinnedTabsContainer.lastChild) ); } else { -- this.moveTabTo(aTab, this.pinnedTabCount, { forceStandaloneTab: true }); -+ this.moveTabTo(aTab, this._numVisiblePinTabs, { forceStandaloneTab: true }); - } - aTab.setAttribute("pinned", "true"); - this._updateTabBarForPinnedTabs(); -@@ -828,10 +856,10 @@ + this.moveTabTo(aTab, this.pinnedTabCount, { forceStandaloneTab: true }); +@@ -828,7 +856,7 @@ // the moving of a tab from the vertical pinned tabs container // and back into arrowscrollbox. aTab.removeAttribute("pinned"); @@ -65,11 +61,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..bdebb5eeb16c1c7b9fd0d0266d5fa7b5 + ZenWorkspaces.activeWorkspaceStrip.prepend(aTab); }); } else { -- this.moveTabTo(aTab, this.pinnedTabCount - 1, { -+ this.moveTabTo(aTab, this._numVisiblePinTabs - 1, { - forceStandaloneTab: true, - }); - aTab.removeAttribute("pinned"); + this.moveTabTo(aTab, this.pinnedTabCount - 1, { @@ -1055,6 +1083,8 @@ let LOCAL_PROTOCOLS = ["chrome:", "about:", "resource:", "data:"]; @@ -232,20 +224,11 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..bdebb5eeb16c1c7b9fd0d0266d5fa7b5 if (typeof index != "number") { // Move the new tab after another tab if needed, to the end otherwise. - index = Infinity; -+ index = Services.prefs.getBoolPref("zen.view.show-newtab-button-top") ? this._numVisiblePinTabs : Infinity; ++ index = Services.prefs.getBoolPref("zen.view.show-newtab-button-top") ? this.pinnedTabCount : Infinity; if ( !bulkOrderedOpen && ((openerTab && -@@ -3773,14 +3855,14 @@ - // Ensure index is within bounds. - if (tab.pinned) { - index = Math.max(index, 0); -- index = Math.min(index, this.pinnedTabCount); -+ index = Math.min(index, this._numVisiblePinTabs); - } else { -- index = Math.max(index, this.pinnedTabCount); -+ index = Math.max(index, this._numVisiblePinTabs); - index = Math.min(index, this.tabs.length); +@@ -3780,7 +3862,7 @@ } /** @type {MozTabbrowserTab|undefined} */ diff --git a/src/browser/components/tabbrowser/content/tabs-js.patch b/src/browser/components/tabbrowser/content/tabs-js.patch index c4903a593..878c2193a 100644 --- a/src/browser/components/tabbrowser/content/tabs-js.patch +++ b/src/browser/components/tabbrowser/content/tabs-js.patch @@ -1,5 +1,5 @@ diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js -index 8aeb244ffca9f48661805f5b7d860b5896055562..2e8cacae772cca001fc7374ddd8281e0cb7f1f3f 100644 +index 8aeb244ffca9f48661805f5b7d860b5896055562..3d323615040dcb5e379519878fb7874d5b28de81 100644 --- a/browser/components/tabbrowser/content/tabs.js +++ b/browser/components/tabbrowser/content/tabs.js @@ -94,7 +94,7 @@ @@ -261,8 +261,8 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..2e8cacae772cca001fc7374ddd8281e0 - if (gBrowser.pinnedTabCount !== verticalTabsContainer.children.length) { - let tabs = this.visibleTabs; -+ ZenWorkspaces.makeSurePinTabIsInCorrectPosition(); -+ if (gBrowser.pinnedTabCount !== (verticalTabsContainer.children.length - 1 + document.getElementById("zen-essentials-container").children.length)) { ++ let count = ZenWorkspaces.makeSurePinTabIsInCorrectPosition(); ++ if (gBrowser.pinnedTabCount !== (verticalTabsContainer.children.length - count - 1 + document.getElementById("zen-essentials-container").children.length)) { + let tabs = this.allTabs.filter(tab => !tab.hasAttribute("zen-glance-tab")); for (let i = 0; i < numPinned; i++) { tabs[i].style.marginInlineStart = "";