mirror of
https://github.com/zen-browser/desktop.git
synced 2026-08-22 22:50:53 +00:00
Merge branch 'zen-browser:dev' into improved-color-picker
This commit is contained in:
@@ -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() {
|
||||
@@ -85,7 +83,7 @@
|
||||
_initSidebarScrolling() {
|
||||
// Disable smooth scroll
|
||||
const canSmoothScroll = Services.prefs.getBoolPref('zen.startup.smooth-scroll-in-tabs', false);
|
||||
const tabsWrapper = document.getElementById('zen-browser-tabs-wrapper');
|
||||
const tabsWrapper = document.getElementById('zen-tabs-wrapper');
|
||||
gBrowser.tabContainer.addEventListener('wheel', (event) => {
|
||||
if (canSmoothScroll) return;
|
||||
event.preventDefault(); // Prevent the smooth scroll behavior
|
||||
@@ -94,8 +92,8 @@
|
||||
// Detect overflow and underflow
|
||||
const observer = new ResizeObserver((_) => {
|
||||
const tabContainer = gBrowser.tabContainer;
|
||||
const isVertical = tabContainer.getAttribute('orient') === 'vertical';
|
||||
let contentSize = tabsWrapper.getBoundingClientRect()[isVertical ? 'height' : 'width'];
|
||||
// const isVertical = tabContainer.getAttribute('orient') === 'vertical';
|
||||
// let contentSize = tabsWrapper.getBoundingClientRect()[isVertical ? 'height' : 'width'];
|
||||
// NOTE: This should be contentSize > scrollClientSize, but due
|
||||
// to how Gecko internally rounds in those cases, we allow for some
|
||||
// minor differences (the internal Gecko layout size is 1/60th of a
|
||||
|
||||
@@ -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(
|
||||
@@ -27,6 +25,7 @@ var gZenUIManager = {
|
||||
|
||||
SessionStore.promiseAllWindowsRestored.then(() => {
|
||||
this._hasLoadedDOM = true;
|
||||
this.updateTabsToolbar();
|
||||
});
|
||||
|
||||
window.addEventListener('TabClose', this.onTabClose.bind(this));
|
||||
@@ -35,7 +34,7 @@ var gZenUIManager = {
|
||||
|
||||
updateTabsToolbar() {
|
||||
// Set tabs max-height to the "toolbar-items" height
|
||||
const tabs = document.getElementById('zen-browser-tabs-wrapper');
|
||||
const tabs = this.tabsWrapper;
|
||||
// Remove tabs so we can accurately calculate the height
|
||||
// without them affecting the height of the toolbar
|
||||
for (const tab of gBrowser.tabs) {
|
||||
@@ -62,7 +61,7 @@ var gZenUIManager = {
|
||||
if (this._tabsWrapper) {
|
||||
return this._tabsWrapper;
|
||||
}
|
||||
this._tabsWrapper = document.getElementById('zen-browser-tabs-wrapper');
|
||||
this._tabsWrapper = document.getElementById('zen-tabs-wrapper');
|
||||
return this._tabsWrapper;
|
||||
},
|
||||
|
||||
@@ -148,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,
|
||||
@@ -169,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;
|
||||
@@ -187,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 {
|
||||
@@ -240,13 +243,14 @@ var gZenVerticalTabsManager = {
|
||||
window.addEventListener('customizationstarting', this._preCustomize.bind(this));
|
||||
window.addEventListener('aftercustomization', this._postCustomize.bind(this));
|
||||
|
||||
window.addEventListener('DOMContentLoaded', updateEvent, { once: true });
|
||||
|
||||
const tabs = document.getElementById('tabbrowser-tabs');
|
||||
this._updateEvent();
|
||||
|
||||
if (!this.isWindowsStyledButtons) {
|
||||
document.documentElement.setAttribute('zen-window-buttons-reversed', true);
|
||||
}
|
||||
|
||||
this._renameTabHalt = this.renameTabHalt.bind(this);
|
||||
gBrowser.tabContainer.addEventListener('dblclick', this.renameTabStart.bind(this));
|
||||
},
|
||||
|
||||
toggleExpand() {
|
||||
@@ -414,7 +418,10 @@ var gZenVerticalTabsManager = {
|
||||
gBrowser.tabContainer.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal');
|
||||
gBrowser.tabContainer.arrowScrollbox.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal');
|
||||
// on purpose, we set the orient to horizontal, because the arrowScrollbox is vertical
|
||||
gBrowser.tabContainer.arrowScrollbox.scrollbox.setAttribute('orient', isVerticalTabs ? 'horizontal' : 'vertical');
|
||||
gBrowser.tabContainer.arrowScrollbox.scrollbox.setAttribute(
|
||||
'orient',
|
||||
isVerticalTabs && ZenWorkspaces.workspaceEnabled ? 'horizontal' : 'vertical'
|
||||
);
|
||||
|
||||
const buttonsTarget = document.getElementById('zen-sidebar-top-buttons-customization-target');
|
||||
if (isRightSide) {
|
||||
@@ -568,6 +575,7 @@ var gZenVerticalTabsManager = {
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
gZenUIManager.updateTabsToolbar();
|
||||
this._isUpdating = false;
|
||||
},
|
||||
|
||||
@@ -608,4 +616,81 @@ var gZenVerticalTabsManager = {
|
||||
}
|
||||
target.appendChild(child);
|
||||
},
|
||||
|
||||
renameTabKeydown(event) {
|
||||
if (event.key === 'Enter') {
|
||||
let label = this._tabEdited.querySelector('.tab-label-container-editing');
|
||||
let input = this._tabEdited.querySelector('#tab-label-input');
|
||||
let newName = input.value.trim();
|
||||
|
||||
// Check if name is blank, reset if so
|
||||
// Always remove, so we can always rename and if it's empty,
|
||||
// it will reset to the original name anyway
|
||||
this._tabEdited.removeAttribute('zen-has-static-label');
|
||||
if (newName) {
|
||||
gBrowser._setTabLabel(this._tabEdited, newName);
|
||||
this._tabEdited.setAttribute('zen-has-static-label', 'true');
|
||||
} else {
|
||||
gBrowser.setTabTitle(this._tabEdited);
|
||||
}
|
||||
|
||||
// Maybe add some confetti here?!?
|
||||
gZenUIManager.motion.animate(this._tabEdited, {
|
||||
scale: [1, 0.98, 1],
|
||||
}, {
|
||||
duration: 0.25,
|
||||
});
|
||||
|
||||
this._tabEdited.querySelector('.tab-editor-container').remove();
|
||||
label.classList.remove('tab-label-container-editing');
|
||||
|
||||
this._tabEdited = null;
|
||||
} else if (event.key === 'Escape') {
|
||||
event.target.blur();
|
||||
}
|
||||
},
|
||||
|
||||
renameTabStart(event) {
|
||||
if (
|
||||
this._tabEdited ||
|
||||
!Services.prefs.getBoolPref('zen.tabs.rename-tabs') ||
|
||||
Services.prefs.getBoolPref('browser.tabs.closeTabByDblclick') ||
|
||||
!gZenVerticalTabsManager._prefsSidebarExpanded
|
||||
)
|
||||
return;
|
||||
this._tabEdited = event.target.closest('.tabbrowser-tab');
|
||||
if (!this._tabEdited || !this._tabEdited.pinned || this._tabEdited.hasAttribute('zen-essential')) {
|
||||
this._tabEdited = null;
|
||||
return;
|
||||
}
|
||||
const label = this._tabEdited.querySelector('.tab-label-container');
|
||||
label.classList.add('tab-label-container-editing');
|
||||
|
||||
const container = window.MozXULElement.parseXULToFragment(`
|
||||
<vbox class="tab-label-container tab-editor-container" flex="1" align="start" pack="center"></vbox>
|
||||
`);
|
||||
label.after(container);
|
||||
const containerHtml = this._tabEdited.querySelector('.tab-editor-container');
|
||||
const input = document.createElement('input');
|
||||
input.id = 'tab-label-input';
|
||||
input.value = this._tabEdited.label;
|
||||
input.addEventListener('keydown', this.renameTabKeydown.bind(this));
|
||||
|
||||
containerHtml.appendChild(input);
|
||||
input.focus();
|
||||
input.select();
|
||||
|
||||
input.addEventListener('blur', this._renameTabHalt);
|
||||
},
|
||||
|
||||
renameTabHalt(event) {
|
||||
if (document.activeElement === event.target || !this._tabEdited) {
|
||||
return;
|
||||
}
|
||||
this._tabEdited.querySelector('.tab-editor-container').remove();
|
||||
const label = this._tabEdited.querySelector('.tab-label-container-editing');
|
||||
label.classList.remove('tab-label-container-editing');
|
||||
|
||||
this._tabEdited = null;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml
|
||||
index a0a382643a2f74b6d789f3641ef300eed202d5e9..340475da315e67b2dd4f93567547cde703a90ee8 100644
|
||||
index a0a382643a2f74b6d789f3641ef300eed202d5e9..7a2be5fe6cdecb771ce3326008085ae402a465de 100644
|
||||
--- a/browser/base/content/navigator-toolbox.inc.xhtml
|
||||
+++ b/browser/base/content/navigator-toolbox.inc.xhtml
|
||||
@@ -2,7 +2,7 @@
|
||||
@@ -40,17 +40,18 @@ index a0a382643a2f74b6d789f3641ef300eed202d5e9..340475da315e67b2dd4f93567547cde7
|
||||
<tabs id="tabbrowser-tabs"
|
||||
is="tabbrowser-tabs"
|
||||
aria-multiselectable="true"
|
||||
@@ -50,6 +50,9 @@
|
||||
@@ -50,6 +50,10 @@
|
||||
tooltip="tabbrowser-tab-tooltip"
|
||||
orient="horizontal"
|
||||
stopwatchid="FX_TAB_CLICK_MS">
|
||||
+<html:div id="zen-essentials-container" skipintoolbarset="true"></html:div>
|
||||
+<hbox id="zen-current-workspace-indicator-container"></hbox>
|
||||
+<html:div id="zen-browser-tabs-wrapper">
|
||||
+<html:div id="zen-tabs-wrapper">
|
||||
+<html:div id="zen-browser-tabs-container">
|
||||
<hbox class="tab-drop-indicator" hidden="true"/>
|
||||
# If the name (tabbrowser-arrowscrollbox) or structure of this changes
|
||||
# significantly, there is an optimization in
|
||||
@@ -57,7 +60,7 @@
|
||||
@@ -57,7 +61,7 @@
|
||||
# the current structure that we may want to revisit.
|
||||
<html:div id="vertical-pinned-tabs-container" tabindex="-1"></html:div>
|
||||
<html:div id="vertical-pinned-tabs-container-separator"></html:div>
|
||||
@@ -59,15 +60,16 @@ index a0a382643a2f74b6d789f3641ef300eed202d5e9..340475da315e67b2dd4f93567547cde7
|
||||
<tab is="tabbrowser-tab" class="tabbrowser-tab" selected="true" visuallyselected="" fadein=""/>
|
||||
<hbox id="tabbrowser-arrowscrollbox-periphery">
|
||||
<toolbartabstop/>
|
||||
@@ -75,6 +78,7 @@
|
||||
@@ -75,6 +79,8 @@
|
||||
tooltip="dynamic-shortcut-tooltip"
|
||||
data-l10n-id="tabs-toolbar-new-tab"/>
|
||||
<html:span id="tabbrowser-tab-a11y-desc" hidden="true"/>
|
||||
+</html:div>
|
||||
+</html:div>
|
||||
</tabs>
|
||||
|
||||
<toolbarbutton id="new-tab-button"
|
||||
@@ -100,11 +104,12 @@
|
||||
@@ -100,11 +106,12 @@
|
||||
#include private-browsing-indicator.inc.xhtml
|
||||
<toolbarbutton id="content-analysis-indicator"
|
||||
class="toolbarbutton-1 content-analysis-indicator-icon"/>
|
||||
@@ -83,7 +85,7 @@ index a0a382643a2f74b6d789f3641ef300eed202d5e9..340475da315e67b2dd4f93567547cde7
|
||||
<toolbar id="nav-bar"
|
||||
class="browser-toolbar chromeclass-location"
|
||||
data-l10n-id="navbar-accessible"
|
||||
@@ -490,10 +495,12 @@
|
||||
@@ -490,10 +497,12 @@
|
||||
consumeanchor="PanelUI-button"
|
||||
data-l10n-id="appmenu-menu-button-closed2"/>
|
||||
</toolbaritem>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/base/content/navigator-toolbox.js b/browser/base/content/navigator-toolbox.js
|
||||
index 64ded8fb2c08f1dbfec8fe08ab427a24b53f1169..3434a833c4d1220554b4df6eeeed83f500c6f812 100644
|
||||
index 64ded8fb2c08f1dbfec8fe08ab427a24b53f1169..9e1e888554279b6e1df3bc1cb907afd2ccb330ca 100644
|
||||
--- a/browser/base/content/navigator-toolbox.js
|
||||
+++ b/browser/base/content/navigator-toolbox.js
|
||||
@@ -8,7 +8,7 @@
|
||||
@@ -15,7 +15,7 @@ index 64ded8fb2c08f1dbfec8fe08ab427a24b53f1169..3434a833c4d1220554b4df6eeeed83f5
|
||||
#reload-button ,
|
||||
#urlbar-go-button,
|
||||
#reader-mode-button,
|
||||
+ #zen-browser-tabs-wrapper,
|
||||
+ #zen-tabs-wrapper,
|
||||
#picture-in-picture-button,
|
||||
#shopping-sidebar-button,
|
||||
#urlbar-zoom-button,
|
||||
@@ -23,7 +23,7 @@ index 64ded8fb2c08f1dbfec8fe08ab427a24b53f1169..3434a833c4d1220554b4df6eeeed83f5
|
||||
case "vertical-tabs-newtab-button":
|
||||
case "tabs-newtab-button":
|
||||
case "new-tab-button":
|
||||
+ case "zen-browser-tabs-wrapper":
|
||||
+ case "zen-tabs-wrapper":
|
||||
gBrowser.handleNewTabMiddleClick(element, event);
|
||||
break;
|
||||
|
||||
|
||||
@@ -126,8 +126,7 @@
|
||||
width: 98%;
|
||||
transition: margin 0.2s ease-in-out, background 0.2s ease-in-out, max-height 0.2s ease-in-out;
|
||||
|
||||
#vertical-pinned-tabs-container .zen-workspace-tabs-section[active]:not(:has(tab:not([hidden]))) &,
|
||||
#tabbrowser-tabs:not(:has(#tabbrowser-arrowscrollbox .zen-workspace-tabs-section[active] tab:not([hidden]))) & {
|
||||
#vertical-pinned-tabs-container .zen-workspace-tabs-section[hide-separator] & {
|
||||
max-height: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -281,10 +280,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&[selected] .tab-background {
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
@media (-moz-bool-pref: 'zen.tabs.dim-pending') {
|
||||
&[pending='true'] .tab-icon-image {
|
||||
opacity: 0.5;
|
||||
@@ -327,13 +322,18 @@
|
||||
/* On essentials, glance tabs are floating */
|
||||
&[zen-essential='true'] .tabbrowser-tab {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
--tab-collapsed-width: 35px;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
--tab-collapsed-width: 34px;
|
||||
--tab-min-height: 16px;
|
||||
width: var(--tab-collapsed-width) !important;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
& .tab-background {
|
||||
/* Solid colors because we don't want to show the background */
|
||||
background: light-dark(rgb(249, 249, 249), rgb(63, 63, 63)) !important;
|
||||
border: 2px solid light-dark(rgba(0, 0, 0, 0.4), rgba(255, 255, 255, 0.4));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -366,20 +366,25 @@
|
||||
}
|
||||
}
|
||||
|
||||
#zen-browser-tabs-wrapper {
|
||||
#zen-tabs-wrapper {
|
||||
min-height: fit-content;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
#zen-browser-tabs-container {
|
||||
overflow-x: clip !important; /* might break custom css with new design, so let's force it */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#vertical-pinned-tabs-container {
|
||||
padding-inline-end: 0 !important;
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
min-height: fit-content !important;
|
||||
overflow: visible;
|
||||
overflow-x: clip;
|
||||
overflow-y: visible;
|
||||
max-height: unset !important;
|
||||
|
||||
& .tabbrowser-tab:not(:hover) .tab-background:not([selected]):not([multiselected]) {
|
||||
@@ -950,7 +955,7 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#zen-essentials-container .tabbrowser-tab {
|
||||
#zen-essentials-container > .tabbrowser-tab {
|
||||
--toolbarbutton-inner-padding: 0;
|
||||
max-width: unset;
|
||||
width: 100% !important;
|
||||
@@ -990,7 +995,7 @@
|
||||
}
|
||||
|
||||
@media (-moz-bool-pref: 'zen.theme.essentials-favicon-bg') {
|
||||
&[visuallyselected] .tab-background {
|
||||
&[visuallyselected] > .tab-stack > .tab-background {
|
||||
&::after {
|
||||
content: "";
|
||||
inset: -50%;
|
||||
@@ -1134,6 +1139,20 @@
|
||||
box-shadow: -3px 0 6px -2px var(--toolbarbutton-active-background, rgba(0, 255, 0, 0.2));
|
||||
}
|
||||
|
||||
/* Renaming tabs */
|
||||
.tab-label-container-editing {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#tab-label-input {
|
||||
white-space: nowrap;
|
||||
overflow-x: scroll;
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Section: tab workspaces stylings */
|
||||
.zen-workspace-tabs-section {
|
||||
position: absolute;
|
||||
|
||||
@@ -161,11 +161,10 @@
|
||||
|
||||
@media (-moz-windows-mica) or (-moz-platform: macos) {
|
||||
background: transparent;
|
||||
--zen-themed-toolbar-bg-transparency: 0;
|
||||
--zen-themed-toolbar-bg-transparent: light-dark(
|
||||
rgba(255, 255, 255, var(--zen-themed-toolbar-bg-transparency)),
|
||||
rgba(0, 0, 0, var(--zen-themed-toolbar-bg-transparency))
|
||||
);
|
||||
--zen-themed-toolbar-bg-transparent: transparent;
|
||||
@media (-moz-bool-pref: 'zen.widget.windows.acrylic') {
|
||||
--zen-themed-toolbar-bg-transparent: color-mix(in srgb, var(--zen-themed-toolbar-bg) 85%, transparent 15%);
|
||||
}
|
||||
}
|
||||
|
||||
--toolbar-field-background-color: var(--zen-colors-input-bg) !important;
|
||||
|
||||
@@ -456,7 +456,8 @@
|
||||
position: absolute;
|
||||
max-height: var(--zen-workspace-indicator-height);
|
||||
min-height: var(--zen-workspace-indicator-height);
|
||||
gap: 5px;
|
||||
gap: 12px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex-direction: row !important;
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
this.initCanvas();
|
||||
this.initCustomColorInput();
|
||||
|
||||
ZenWorkspaces.addChangeListeners(this.onWorkspaceChange.bind(this));
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addListener(this.onDarkModeChange.bind(this));
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,9 @@
|
||||
return;
|
||||
}
|
||||
|
||||
await this._refreshPinnedTabs(newWorkspace, { init: onInit });
|
||||
if (onInit) {
|
||||
await this._refreshPinnedTabs(newWorkspace, { init: onInit });
|
||||
}
|
||||
}
|
||||
|
||||
log(message) {
|
||||
@@ -152,7 +154,7 @@
|
||||
const pinsToCreate = new Set(pins.map((p) => p.uuid));
|
||||
|
||||
// First pass: identify existing tabs and remove those without pins
|
||||
for (let tab of gBrowser.tabs) {
|
||||
for (let tab of ZenWorkspaces.allStoredTabs) {
|
||||
const pinId = tab.getAttribute('zen-pin-id');
|
||||
if (!pinId) {
|
||||
continue;
|
||||
@@ -178,10 +180,6 @@
|
||||
continue; // Skip pins that already have tabs
|
||||
}
|
||||
|
||||
if (!this._shouldShowPin(pin, currentWorkspace, workspaces)) {
|
||||
continue; // Skip pins not relevant to current workspace
|
||||
}
|
||||
|
||||
let params = {
|
||||
skipAnimation: true,
|
||||
allowInheritPrincipal: false,
|
||||
@@ -234,6 +232,13 @@
|
||||
|
||||
this.log(`Created new pinned tab for pin ${pin.uuid} (isEssential: ${pin.isEssential})`);
|
||||
gBrowser.pinTab(newTab);
|
||||
if (!pin.isEssential) {
|
||||
const contaienr = document.querySelector(
|
||||
`#vertical-pinned-tabs-container .zen-workspace-tabs-section[zen-workspace-id="${pin.workspaceUuid}"]`
|
||||
);
|
||||
contaienr.insertBefore(newTab, contaienr.lastChild);
|
||||
}
|
||||
gBrowser.tabContainer._invalidateCachedTabs();
|
||||
|
||||
newTab.initialize();
|
||||
}
|
||||
@@ -244,43 +249,7 @@
|
||||
}
|
||||
|
||||
gBrowser._updateTabBarForPinnedTabs();
|
||||
}
|
||||
|
||||
_shouldShowPin(pin, currentWorkspace, workspaces) {
|
||||
const isEssential = pin.isEssential;
|
||||
const pinWorkspaceUuid = pin.workspaceUuid;
|
||||
const pinContextId = pin.containerTabId ? pin.containerTabId.toString() : '0';
|
||||
const workspaceContextId = currentWorkspace.containerTabId?.toString() || '0';
|
||||
const containerSpecificEssentials = ZenWorkspaces.containerSpecificEssentials;
|
||||
|
||||
// Handle essential pins
|
||||
if (isEssential) {
|
||||
if (!containerSpecificEssentials) {
|
||||
return true; // Show all essential pins when containerSpecificEssentials is false
|
||||
}
|
||||
|
||||
if (workspaceContextId !== '0') {
|
||||
// In workspaces with default container: Show essentials that match the container
|
||||
return pinContextId === workspaceContextId;
|
||||
} else {
|
||||
// In workspaces without a default container: Show essentials that aren't in container-specific workspaces
|
||||
// or have userContextId="0" or no userContextId
|
||||
return (
|
||||
!pinContextId ||
|
||||
pinContextId === '0' ||
|
||||
!workspaces.workspaces.some((workspace) => workspace.containerTabId === parseInt(pinContextId, 10))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// For non-essential pins
|
||||
if (!pinWorkspaceUuid) {
|
||||
// Pins without a workspace belong to all workspaces (if that's your desired behavior)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Show if pin belongs to current workspace
|
||||
return pinWorkspaceUuid === currentWorkspace.uuid;
|
||||
gZenUIManager.updateTabsToolbar();
|
||||
}
|
||||
|
||||
_onPinnedTabEvent(action, event) {
|
||||
@@ -646,68 +615,70 @@
|
||||
document.getElementById('context_zen-pinned-tab-separator').hidden = !isVisible;
|
||||
}
|
||||
|
||||
moveToAnotherTabContainerIfNecessary(event, draggedTab) {
|
||||
moveToAnotherTabContainerIfNecessary(event, movingTabs) {
|
||||
const pinnedTabsTarget =
|
||||
event.target.closest('#vertical-pinned-tabs-container') || event.target.closest('.zen-current-workspace-indicator');
|
||||
const essentialTabsTarget = event.target.closest('#zen-essentials-container');
|
||||
const tabsTarget = event.target.closest('#tabbrowser-arrowscrollbox');
|
||||
|
||||
let moved = false;
|
||||
let isVertical = this.expandedSidebarMode;
|
||||
let isRegularTabs = false;
|
||||
// Check for pinned tabs container
|
||||
if (pinnedTabsTarget) {
|
||||
if (!draggedTab.pinned) {
|
||||
gBrowser.pinTab(draggedTab);
|
||||
moved = true;
|
||||
} else if (draggedTab.hasAttribute('zen-essential')) {
|
||||
this.removeEssentials(draggedTab);
|
||||
gBrowser.pinTab(draggedTab);
|
||||
moved = true;
|
||||
}
|
||||
}
|
||||
// Check for essentials container
|
||||
else if (essentialTabsTarget) {
|
||||
if (!draggedTab.hasAttribute('zen-essential')) {
|
||||
this.addToEssentials(draggedTab);
|
||||
moved = true;
|
||||
isVertical = false;
|
||||
}
|
||||
}
|
||||
// Check for normal tabs container
|
||||
else if (tabsTarget || event.target.id === 'zen-browser-tabs-wrapper') {
|
||||
if (draggedTab.pinned && !draggedTab.hasAttribute('zen-essential')) {
|
||||
gBrowser.unpinTab(draggedTab);
|
||||
moved = true;
|
||||
isRegularTabs = true;
|
||||
} else if (draggedTab.hasAttribute('zen-essential')) {
|
||||
this.removeEssentials(draggedTab);
|
||||
moved = true;
|
||||
isRegularTabs = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the tab was moved, adjust its position relative to the target tab
|
||||
if (moved) {
|
||||
const targetTab = event.target.closest('.tabbrowser-tab');
|
||||
if (targetTab) {
|
||||
const rect = targetTab.getBoundingClientRect();
|
||||
let newIndex = targetTab._tPos;
|
||||
|
||||
if (isVertical) {
|
||||
const middleY = targetTab.screenY + rect.height / 2;
|
||||
if (!isRegularTabs && event.screenY > middleY) {
|
||||
newIndex++;
|
||||
} else if (isRegularTabs && event.screenY < middleY) {
|
||||
newIndex--;
|
||||
}
|
||||
} else {
|
||||
const middleX = targetTab.screenX + rect.width / 2;
|
||||
if (event.screenX > middleX) {
|
||||
newIndex++;
|
||||
}
|
||||
let moved = false;
|
||||
for (const draggedTab of movingTabs) {
|
||||
let isRegularTabs = false;
|
||||
// Check for pinned tabs container
|
||||
if (pinnedTabsTarget) {
|
||||
if (!draggedTab.pinned) {
|
||||
gBrowser.pinTab(draggedTab);
|
||||
moved = true;
|
||||
} else if (draggedTab.hasAttribute('zen-essential')) {
|
||||
this.removeEssentials(draggedTab);
|
||||
gBrowser.pinTab(draggedTab);
|
||||
moved = true;
|
||||
}
|
||||
}
|
||||
// Check for essentials container
|
||||
else if (essentialTabsTarget) {
|
||||
if (!draggedTab.hasAttribute('zen-essential')) {
|
||||
this.addToEssentials(draggedTab);
|
||||
moved = true;
|
||||
isVertical = false;
|
||||
}
|
||||
}
|
||||
// Check for normal tabs container
|
||||
else if (tabsTarget || event.target.id === 'zen-tabs-wrapper') {
|
||||
if (draggedTab.pinned && !draggedTab.hasAttribute('zen-essential')) {
|
||||
gBrowser.unpinTab(draggedTab);
|
||||
moved = true;
|
||||
isRegularTabs = true;
|
||||
} else if (draggedTab.hasAttribute('zen-essential')) {
|
||||
this.removeEssentials(draggedTab);
|
||||
moved = true;
|
||||
isRegularTabs = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the tab was moved, adjust its position relative to the target tab
|
||||
if (moved) {
|
||||
const targetTab = event.target.closest('.tabbrowser-tab');
|
||||
if (targetTab) {
|
||||
const rect = targetTab.getBoundingClientRect();
|
||||
let newIndex = targetTab._tPos;
|
||||
|
||||
if (isVertical) {
|
||||
const middleY = targetTab.screenY + rect.height / 2;
|
||||
if (!isRegularTabs && event.screenY > middleY) {
|
||||
newIndex++;
|
||||
} else if (isRegularTabs && event.screenY < middleY) {
|
||||
newIndex--;
|
||||
}
|
||||
} else {
|
||||
const middleX = targetTab.screenX + rect.width / 2;
|
||||
if (event.screenX > middleX) {
|
||||
newIndex++;
|
||||
}
|
||||
}
|
||||
gBrowser.moveTabTo(draggedTab, newIndex);
|
||||
}
|
||||
gBrowser.moveTabTo(draggedTab, newIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ var ZenPinnedTabsStorage = {
|
||||
CREATE INDEX IF NOT EXISTS idx_zen_pins_changes_uuid ON zen_pins_changes(uuid)
|
||||
`);
|
||||
|
||||
await SessionStore.promiseInitialized;
|
||||
this._resolveInitialized();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -28,13 +28,17 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
this._resolvePinnedInitialized = resolve;
|
||||
});
|
||||
|
||||
promiseSectionsInitialized = new Promise((resolve) => {
|
||||
this._resolveSectionsInitialized = resolve;
|
||||
});
|
||||
|
||||
workspaceIndicatorXUL = `
|
||||
<hbox class="zen-current-workspace-indicator-icon"></hbox>
|
||||
<hbox class="zen-current-workspace-indicator-name"></hbox>
|
||||
`;
|
||||
|
||||
async waitForPromises() {
|
||||
await Promise.all([this.promiseDBInitialized, this.promisePinnedInitialized, SessionStore.promiseAllWindowsRestored]);
|
||||
await Promise.all([this.promiseDBInitialized, this.promisePinnedInitialized]);
|
||||
}
|
||||
|
||||
async init() {
|
||||
@@ -75,18 +79,25 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
);
|
||||
ChromeUtils.defineLazyGetter(this, 'tabContainer', () => document.getElementById('tabbrowser-tabs'));
|
||||
this._activeWorkspace = Services.prefs.getStringPref('zen.workspaces.active', '');
|
||||
this._delayedStartup();
|
||||
await SessionStore.promiseInitialized;
|
||||
if (!this._hasInitializedTabsStrip) {
|
||||
await this.delayedStartup();
|
||||
}
|
||||
await this.promiseSectionsInitialized;
|
||||
window.addEventListener(
|
||||
'MozAfterPaint',
|
||||
async () => {
|
||||
await SessionStore.promiseAllWindowsRestored;
|
||||
await this.afterLoadInit();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
}
|
||||
|
||||
async _delayedStartup() {
|
||||
if (!this.workspaceEnabled) {
|
||||
return;
|
||||
}
|
||||
this._pinnedTabsResizeObserver = new ResizeObserver(this.onPinnedTabsResize.bind(this));
|
||||
await this.waitForPromises();
|
||||
await this.initializeWorkspaces();
|
||||
async afterLoadInit() {
|
||||
console.info('ZenWorkspaces: ZenWorkspaces initialized');
|
||||
|
||||
await this.initializeWorkspaces();
|
||||
if (Services.prefs.getBoolPref('zen.workspaces.swipe-actions', false) && this.workspaceEnabled) {
|
||||
this.initializeGestureHandlers();
|
||||
this.initializeWorkspaceNavigation();
|
||||
@@ -103,6 +114,16 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
);
|
||||
}
|
||||
|
||||
async delayedStartup() {
|
||||
if (!this.workspaceEnabled) {
|
||||
return;
|
||||
}
|
||||
this._pinnedTabsResizeObserver = new ResizeObserver(this.onPinnedTabsResize.bind(this));
|
||||
await this.waitForPromises();
|
||||
await this.initializeTabsStripSections();
|
||||
this._resolveSectionsInitialized();
|
||||
}
|
||||
|
||||
registerPinnedResizeObserver() {
|
||||
if (!this._hasInitializedTabsStrip) {
|
||||
return;
|
||||
@@ -117,7 +138,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
get activeWorkspaceStrip() {
|
||||
if (!this.workspaceEnabled || !this._hasInitializedTabsStrip) {
|
||||
if (!this._hasInitializedTabsStrip) {
|
||||
return gBrowser.tabContainer.arrowScrollbox;
|
||||
}
|
||||
const activeWorkspace = this.activeWorkspace;
|
||||
@@ -147,23 +168,34 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
|
||||
async initializeTabsStripSections() {
|
||||
const perifery = document.getElementById('tabbrowser-arrowscrollbox-periphery');
|
||||
const tabs = gBrowser.tabContainer.allTabs.filter((tab) => !tab.pinned);
|
||||
for (const workspace of (await this._workspaces()).workspaces) {
|
||||
const tabs = gBrowser.tabContainer.allTabs;
|
||||
const workspaces = await this._workspaces();
|
||||
for (const workspace of workspaces.workspaces) {
|
||||
this._createWorkspaceTabsSection(workspace, tabs, perifery);
|
||||
}
|
||||
if (tabs.length) {
|
||||
const defaultSelectedContainer = document.querySelector(
|
||||
`#tabbrowser-arrowscrollbox .zen-workspace-tabs-section[zen-workspace-id="${this.activeWorkspace}"]`
|
||||
);
|
||||
for (const tab of tabs) {
|
||||
// before to the last child (perifery)
|
||||
defaultSelectedContainer.insertBefore(tab, defaultSelectedContainer.lastChild);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
this.tabContainer._invalidateCachedTabs();
|
||||
}
|
||||
perifery.setAttribute('hidden', 'true');
|
||||
this._hasInitializedTabsStrip = true;
|
||||
this.registerPinnedResizeObserver();
|
||||
this._fixIndicatorsNames(workspaces);
|
||||
}
|
||||
|
||||
_createWorkspaceSection(workspace) {
|
||||
@@ -200,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) {
|
||||
@@ -208,7 +243,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
section.appendChild(tab);
|
||||
}
|
||||
}
|
||||
this.tabContainer._invalidateCachedTabs();
|
||||
}
|
||||
|
||||
initializeWorkspaceNavigation() {
|
||||
@@ -359,7 +393,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const delta = event.delta * 500;
|
||||
const delta = event.delta * 300;
|
||||
this._swipeState.lastDelta = delta;
|
||||
|
||||
if (Math.abs(delta) > 1) {
|
||||
@@ -509,26 +543,20 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
this._initializeWorkspaceTabContextMenus();
|
||||
await this.workspaceBookmarks();
|
||||
window.addEventListener('TabBrowserInserted', this.onTabBrowserInserted.bind(this));
|
||||
window.addEventListener('TabOpen', this.updateTabsContainers.bind(this));
|
||||
let workspaces = await this._workspaces();
|
||||
let activeWorkspace = null;
|
||||
if (workspaces.workspaces.length === 0) {
|
||||
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;
|
||||
}
|
||||
await this.initializeTabsStripSections();
|
||||
try {
|
||||
if (activeWorkspace) {
|
||||
window.gZenThemePicker = new ZenThemePicker();
|
||||
await this.changeWorkspace(activeWorkspace, { onInit: true });
|
||||
gBrowser.tabContainer._positionPinnedTabs();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('ZenWorkspaces: Error initializing theme picker', e);
|
||||
@@ -748,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
|
||||
|
||||
@@ -1306,7 +1338,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
tab.setAttribute('zen-workspace-id', workspaceID);
|
||||
const parent = tab.pinned ? '#zen-browser-tabs-pinned ' : '#zen-browser-tabs ';
|
||||
const container = document.querySelector(parent + '.zen-browser-tabs-container');
|
||||
const container = document.querySelector(parent + '.zen-workspace-tabs-section');
|
||||
if (container) {
|
||||
container.insertBefore(tab, container.firstChild);
|
||||
}
|
||||
@@ -1331,8 +1363,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
let tab = gZenUIManager.openAndChangeToTab(BROWSER_NEW_TAB_URL);
|
||||
|
||||
if (window.uuid) {
|
||||
this.moveTabToWorkspace(tab, window.uuid);
|
||||
tab.setAttribute('zen-workspace-id', window.uuid);
|
||||
}
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
async saveWorkspaceFromCreate() {
|
||||
@@ -1397,8 +1431,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
if (!this.workspaceEnabled || this._inChangingWorkspace) {
|
||||
return;
|
||||
}
|
||||
|
||||
await SessionStore.promiseInitialized;
|
||||
this._inChangingWorkspace = true;
|
||||
try {
|
||||
await this._performWorkspaceChange(window, ...args);
|
||||
@@ -1438,11 +1470,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
|
||||
// Second pass: Handle tab selection
|
||||
this.tabContainer._invalidateCachedTabs();
|
||||
await this._handleTabSelection(window, onInit, containerId, workspaces, previousWorkspace.uuid);
|
||||
this.tabContainer._updateVerticalPinnedTabs();
|
||||
const tabToSelect = await this._handleTabSelection(window, onInit, containerId, workspaces, previousWorkspace.uuid);
|
||||
|
||||
// Update UI and state
|
||||
await this._updateWorkspaceState(window, onInit);
|
||||
await this._updateWorkspaceState(window, onInit, tabToSelect);
|
||||
}
|
||||
|
||||
_updateMarginTopPinnedTabs(arrowscrollbox, pinnedContainer) {
|
||||
@@ -1463,13 +1494,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
for (const container of document.querySelectorAll(selector)) {
|
||||
container.style.transform = `translateX(${newTransform + offsetPixels / 2}%)`;
|
||||
container.style.opacity = offsetPixels ? 1 : !newTransform;
|
||||
}
|
||||
if (!justMove) {
|
||||
const pinnedContainerId = '#vertical-pinned-tabs-container ';
|
||||
const arrowScrollboxId = '#tabbrowser-arrowscrollbox ';
|
||||
const pinnedContainer = document.querySelector(pinnedContainerId + selector);
|
||||
const arrowScrollbox = document.querySelector(arrowScrollboxId + selector);
|
||||
this._updateMarginTopPinnedTabs(arrowScrollbox, pinnedContainer);
|
||||
if (!offsetPixels && !container.hasAttribute('active')) {
|
||||
container.setAttribute('hidden', 'true');
|
||||
} else {
|
||||
container.removeAttribute('hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1499,7 +1528,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
}
|
||||
|
||||
async _animateTabs(newWorkspace, shouldAnimate) {
|
||||
async _animateTabs(newWorkspace, shouldAnimate, tabToSelect = null) {
|
||||
this._animatingChange = true;
|
||||
const animations = [];
|
||||
const workspaces = await this._workspaces();
|
||||
@@ -1512,6 +1541,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
const newTransform = `translateX(${offset}%)`;
|
||||
const isCurrent = offset === 0;
|
||||
if (shouldAnimate) {
|
||||
element.removeAttribute('hidden');
|
||||
if (isCurrent) {
|
||||
element.style.opacity = 1;
|
||||
}
|
||||
@@ -1533,15 +1563,14 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
if (offset === 0) {
|
||||
element.setAttribute('active', 'true');
|
||||
if (tabToSelect != gBrowser.selectedTab) {
|
||||
gBrowser.selectedTab = tabToSelect;
|
||||
}
|
||||
} else {
|
||||
element.removeAttribute('active');
|
||||
}
|
||||
}
|
||||
await Promise.all(animations);
|
||||
if (this._beforeSelectedTab) {
|
||||
this._beforeSelectedTab._visuallySelected = false;
|
||||
this._beforeSelectedTab = null;
|
||||
}
|
||||
this._animatingChange = false;
|
||||
}
|
||||
|
||||
@@ -1588,7 +1617,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
// Show if tab belongs to current workspace
|
||||
return true;
|
||||
return tabWorkspaceId === workspaceUuid;
|
||||
}
|
||||
|
||||
async _handleTabSelection(window, onInit, containerId, workspaces, previousWorkspaceId) {
|
||||
@@ -1615,22 +1644,23 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
// If we found a tab to select, select it
|
||||
if (tabToSelect) {
|
||||
gBrowser.selectedTab = tabToSelect;
|
||||
this._lastSelectedWorkspaceTabs[window.uuid] = tabToSelect;
|
||||
} else if (!onInit) {
|
||||
if (!onInit && !tabToSelect) {
|
||||
// Create new tab if needed and no suitable tab was found
|
||||
const newTab = this._createNewTabForWorkspace(window);
|
||||
gBrowser.selectedTab = newTab;
|
||||
this._lastSelectedWorkspaceTabs[window.uuid] = newTab;
|
||||
tabToSelect = newTab;
|
||||
}
|
||||
if (tabToSelect) {
|
||||
tabToSelect._visuallySelected = true;
|
||||
}
|
||||
|
||||
// Always make sure we always unselect the tab from the old workspace
|
||||
currentSelectedTab._selected = false;
|
||||
currentSelectedTab._visuallySelected = true; // we do want to animate the tab deselection
|
||||
this._beforeSelectedTab = currentSelectedTab;
|
||||
if (currentSelectedTab && currentSelectedTab !== tabToSelect) {
|
||||
currentSelectedTab._selected = false;
|
||||
}
|
||||
return tabToSelect;
|
||||
}
|
||||
|
||||
async _updateWorkspaceState(window, onInit) {
|
||||
async _updateWorkspaceState(window, onInit, tabToSelect) {
|
||||
// Update document state
|
||||
document.documentElement.setAttribute('zen-workspace-id', window.uuid);
|
||||
|
||||
@@ -1639,10 +1669,16 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
|
||||
// Update workspace UI
|
||||
await this._updateWorkspacesChangeContextMenu();
|
||||
document.getElementById('tabbrowser-tabs')._positionPinnedTabs();
|
||||
gZenUIManager.updateTabsToolbar();
|
||||
await this._propagateWorkspaceData({ clearCache: false });
|
||||
|
||||
gZenThemePicker.onWorkspaceChange(window);
|
||||
|
||||
document.getElementById('zen-tabs-wrapper').style.scrollbarWidth = 'none';
|
||||
await this._animateTabs(window, !onInit && !this._animatingChange, tabToSelect);
|
||||
await this._organizeWorkspaceStripLocations(window, true);
|
||||
document.getElementById('zen-tabs-wrapper').style.scrollbarWidth = '';
|
||||
|
||||
// Notify listeners
|
||||
if (this._changeListeners?.length) {
|
||||
for (const listener of this._changeListeners) {
|
||||
@@ -1650,13 +1686,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
}
|
||||
|
||||
await this._animateTabs(window, !onInit && !this._animatingChange);
|
||||
|
||||
// Reset bookmarks
|
||||
this._invalidateBookmarkContainers();
|
||||
|
||||
// Update workspace indicator
|
||||
await this.updateWorkspaceIndicator();
|
||||
await this.updateWorkspaceIndicator(window, this.workspaceIndicator);
|
||||
}
|
||||
|
||||
_invalidateBookmarkContainers() {
|
||||
@@ -1693,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,
|
||||
@@ -1703,9 +1737,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
};
|
||||
this._prepareNewWorkspace(window);
|
||||
const perifery = document.querySelector('#tabbrowser-arrowscrollbox-periphery[hidden]');
|
||||
preifery?.removeAttribute('hidden');
|
||||
this._createWorkspaceTabsSection(window, [], perifery);
|
||||
preifery.setAttribute('hidden', 'true');
|
||||
perifery?.removeAttribute('hidden');
|
||||
this._createWorkspaceTabsSection(window, tabs, perifery);
|
||||
perifery.setAttribute('hidden', 'true');
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -1713,15 +1747,37 @@ 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;
|
||||
}
|
||||
|
||||
updateTabsContainers() {
|
||||
this.onPinnedTabsResize([{ target: this.pinnedTabsContainer }]);
|
||||
}
|
||||
|
||||
updateShouldHideSeparator(arrowScrollbox, pinnedContainer) {
|
||||
const shouldHideSeparator = pinnedContainer.children.length === 1 || arrowScrollbox.children.length === 1;
|
||||
if (shouldHideSeparator) {
|
||||
pinnedContainer.setAttribute('hide-separator', 'true');
|
||||
} else {
|
||||
pinnedContainer.removeAttribute('hide-separator');
|
||||
}
|
||||
}
|
||||
|
||||
onPinnedTabsResize(entries) {
|
||||
if (!this.workspaceEnabled) {
|
||||
if (!this._hasInitializedTabsStrip) {
|
||||
return;
|
||||
}
|
||||
for (const entry of entries) {
|
||||
@@ -1730,6 +1786,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
`#tabbrowser-arrowscrollbox .zen-workspace-tabs-section[zen-workspace-id="${workspaceId}"]`
|
||||
);
|
||||
this._updateMarginTopPinnedTabs(arrowScrollbox, entry.target);
|
||||
this.updateShouldHideSeparator(arrowScrollbox, entry.target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1768,19 +1825,28 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
// Switch workspace if needed
|
||||
if (workspaceID && workspaceID !== activeWorkspace.uuid) {
|
||||
if (workspaceID && workspaceID !== activeWorkspace.uuid && parent.ZenWorkspaces._hasInitializedTabsStrip) {
|
||||
await parent.ZenWorkspaces.changeWorkspace({ uuid: workspaceID });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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');
|
||||
@@ -1796,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
|
||||
@@ -2026,4 +2095,43 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
// Return true only if the bookmark is in another workspace and not in the active one
|
||||
return isInOtherWorkspace && !isInActiveWorkspace;
|
||||
}
|
||||
|
||||
// Session restore functions
|
||||
get allStoredTabs() {
|
||||
if (!this._hasInitializedTabsStrip) {
|
||||
const children = Array.from(this.tabboxChildren);
|
||||
children.pop(); // Remove the last child which is the new tab button
|
||||
return children;
|
||||
}
|
||||
|
||||
const tabs = [];
|
||||
// we need to go through each tab in each container
|
||||
const essentialsContainer = document.getElementById('zen-essentials-container');
|
||||
const pinnedContainers = document.querySelectorAll('#vertical-pinned-tabs-container .zen-workspace-tabs-section');
|
||||
const normalContainers = document.querySelectorAll('#tabbrowser-arrowscrollbox .zen-workspace-tabs-section');
|
||||
const containers = [essentialsContainer, ...pinnedContainers, ...normalContainers];
|
||||
for (const container of containers) {
|
||||
for (const tab of container.children) {
|
||||
if (tab.tagName === 'tab' || tab.tagName == 'tab-group') {
|
||||
tabs.push(tab);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tabs;
|
||||
}
|
||||
|
||||
get pinnedTabCount() {
|
||||
return this.pinnedTabsContainer.children.length - 1;
|
||||
}
|
||||
|
||||
get normalTabCount() {
|
||||
return this.tabboxChildren.length - 1;
|
||||
}
|
||||
|
||||
get allWorkspaceTabs() {
|
||||
const currentWorkspace = this.activeWorkspace;
|
||||
return this.allStoredTabs.filter(
|
||||
(tab) => tab.hasAttribute('zen-essential') || tab.getAttribute('zen-workspace-id') === currentWorkspace
|
||||
);
|
||||
}
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user