feat: Added new workspace creation form, b=no-bug, c=tabs, common, compact-mode, workspaces

This commit is contained in:
Mr. M
2025-06-10 20:49:14 +02:00
parent e1974d9f81
commit 847aef5b02
22 changed files with 574 additions and 45 deletions

View File

@@ -30,7 +30,7 @@ Zen is a firefox-based browser with the aim of pushing your productivity to a ne
### Firefox Versions
- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `139.0.4`! 🚀
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 139.0.1`!
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 139.0.4`!
### Contributing

2
l10n

Submodule l10n updated: 751793cd1f...a98bf79797

View File

@@ -56,3 +56,4 @@
<script type="text/javascript" src="chrome://browser/content/zen-components/ZenMediaController.mjs"></script>
<script type="text/javascript" src="chrome://browser/content/zen-components/ZenDownloadAnimation.mjs"></script>
<script type="text/javascript" src="chrome://browser/content/zen-components/ZenEmojiPicker.mjs"></script>
<script type="text/javascript" src="chrome://browser/content/zen-components/ZenWorkspaceCreation.mjs"></script>

View File

@@ -44,6 +44,7 @@
content/browser/zen-components/ZenWorkspaceIcons.mjs (../../zen/workspaces/ZenWorkspaceIcons.mjs)
content/browser/zen-components/ZenWorkspace.mjs (../../zen/workspaces/ZenWorkspace.mjs)
content/browser/zen-components/ZenWorkspaces.mjs (../../zen/workspaces/ZenWorkspaces.mjs)
content/browser/zen-components/ZenWorkspaceCreation.mjs (../../zen/workspaces/ZenWorkspaceCreation.mjs)
content/browser/zen-components/ZenWorkspacesStorage.mjs (../../zen/workspaces/ZenWorkspacesStorage.mjs)
content/browser/zen-components/ZenWorkspacesSync.mjs (../../zen/workspaces/ZenWorkspacesSync.mjs)
content/browser/zen-components/ZenGradientGenerator.mjs (../../zen/workspaces/ZenGradientGenerator.mjs)

View File

@@ -40,6 +40,7 @@
<command id="cmd_zenChangeWorkspaceName" />
<command id="cmd_zenChangeWorkspaceIcon" />
<command id="cmd_zenOpenWorkspacePanel" />
<command id="cmd_zenOpenWorkspaceCreation" />
<command id="cmd_zenPinnedTabReset" />
<command id="cmd_zenPinnedTabResetNoTab" />

View File

@@ -66,7 +66,7 @@
<toolbarbutton id="PanelUI-zen-workspaces-reorder-mode" class="subviewbutton">
<image></image>
</toolbarbutton>
<toolbarbutton id="PanelUI-zen-workspaces-new" class="subviewbutton">
<toolbarbutton id="PanelUI-zen-workspaces-new" class="subviewbutton" command="cmd_zenOpenWorkspaceCreation">
<image></image>
</toolbarbutton>
</hbox>
@@ -85,11 +85,17 @@
<hbox id="PanelUI-zen-emojis-picker-list" />
</panel>
<menupopup id="zenCreateNewPopup">
<menuitem data-l10n-id="tabs-toolbar-new-tab" command="cmd_newNavigatorTab" image="chrome://browser/skin/zen-icons/plus.svg" />
<menuseparator/>
<menuitem data-l10n-id="zen-panel-ui-workspaces-create" command="cmd_zenOpenWorkspaceCreation" image="chrome://browser/skin/zen-icons/duplicate-tab.svg" />
</menupopup>
<menupopup id="zenWorkspaceMoreActions">
<menuitem id="context_zenEditWorkspace" data-l10n-id="zen-workspaces-panel-change-name" command="cmd_zenChangeWorkspaceName"/>
<menuitem id="context_zenEditWorkspace" data-l10n-id="zen-panel-ui-workspaces-create" command="cmd_zenChangeWorkspaceName"/>
<menuitem id="context_zenEditWorkspaceIcon" data-l10n-id="zen-workspaces-panel-change-icon" command="cmd_zenChangeWorkspaceIcon"/>
<menuitem class="zenToolbarThemePicker"
data-l10n-id="zen-workspaces-change-gradient"
data-l10n-id="zen-workspaces-change-theme"
command="cmd_zenOpenZenThemePicker"/>
<menu id="context_zenWorkspacesOpenInContainerTab"
data-l10n-id="zen-workspaces-panel-context-open-in-container-tab"

View File

@@ -10,4 +10,5 @@
mode="icons">
<toolbarbutton removable="true" class="chromeclass-toolbar-additional toolbarbutton-1 zen-sidebar-action-button" id="zen-expand-sidebar-button" command="cmd_zenToggleSidebar" data-l10n-id="sidebar-zen-expand"></toolbarbutton>
<zen-workspace-icons id="zen-workspaces-button" overflows="false" removable="false"></zen-workspace-icons>
<toolbarbutton removable="true" class="chromeclass-toolbar-additional toolbarbutton-1 zen-sidebar-action-button" id="zen-create-new-button" context="zenCreateNewPopup" data-l10n-id="sidebar-zen-create-new"></toolbarbutton>
</toolbar>

View File

@@ -1,7 +1,16 @@
diff --git a/browser/themes/shared/tabbrowser/tabs.css b/browser/themes/shared/tabbrowser/tabs.css
index 5b9ad123d819c6ef068acd427416957a1d0939fe..311caa27ee268c95215d459be02a93d20e129f8b 100644
index 5b9ad123d819c6ef068acd427416957a1d0939fe..543d42dab2d84593f491a5652fcfe272ede59857 100644
--- a/browser/themes/shared/tabbrowser/tabs.css
+++ b/browser/themes/shared/tabbrowser/tabs.css
@@ -19,7 +19,7 @@
--tab-group-line-thickness: 2px;
--tab-group-line-toolbar-border-distance: 1px;
/* Collapsed tabs should be square, so set width to match the min height */
- --tab-collapsed-background-width: var(--tab-min-height);
+ --tab-collapsed-background-width: 48px;
--tab-collapsed-width: calc(var(--tab-collapsed-background-width) + 2 * var(--tab-inner-inline-margin));
--tab-inner-inline-margin: var(--space-medium);
--tab-inline-padding: 8px;
@@ -33,7 +33,7 @@
--tab-block-margin: 4px;
--tab-icon-end-margin: 5.5px;

View File

@@ -180,6 +180,7 @@
#zoom-in-button,
#tabs-newtab-button,
#zen-create-new-button,
#new-tab-button,
#appMenu-zoomEnlarge-button2,
#PanelUI-zen-profiles-newProfile,
@@ -767,3 +768,20 @@
#zen-media-pip-button {
list-style-image: url('chrome://global/skin/media/picture-in-picture-open.svg');
}
#zenCreateNewPopup > menuitem image {
-moz-context-properties: fill;
fill: currentColor;
}
#zen-create-new-button {
border-radius: var(--tab-border-radius);
&:hover {
background: var(--toolbarbutton-active-background);
}
& image {
background: transparent !important;
}
}

View File

@@ -6,7 +6,7 @@ export var ZenCustomizableUI = new (class {
constructor() {}
TYPE_TOOLBAR = 'toolbar';
defaultSidebarIcons = ['preferences-button', 'zen-workspaces-button', 'downloads-button'];
defaultSidebarIcons = ['downloads-button', 'zen-workspaces-button', 'zen-create-new-button'];
startup(CustomizableUIInternal) {
CustomizableUIInternal.registerArea(
@@ -100,9 +100,34 @@ export var ZenCustomizableUI = new (class {
elem.setAttribute('removable', 'true');
}
this._initCreateNewButton(window);
this._moveWindowButtons(window);
}
_initCreateNewButton(window) {
const button = window.document.getElementById('zen-create-new-button');
button.addEventListener('command', () => {
const image = button.querySelector('image');
const popup = window.document.getElementById('zenCreateNewPopup');
button.setAttribute('open', 'true');
const handlePopupHidden = () => {
button.removeAttribute('open');
window.gZenUIManager.motion.animate(
image,
{ transform: ['rotate(45deg)', 'rotate(0deg)'] },
{ duration: 0.2 }
);
};
popup.addEventListener('popuphidden', handlePopupHidden, { once: true });
popup.openPopup(button, 'after_start');
window.gZenUIManager.motion.animate(
image,
{ transform: ['rotate(0deg)', 'rotate(45deg)'] },
{ duration: 0.2 }
);
});
}
_moveWindowButtons(window) {
const windowControls = window.document.getElementsByClassName('titlebar-buttonbox-container');
const toolboxIcons = window.document.getElementById(

View File

@@ -3,7 +3,7 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
{
var ZenStartup = {
_watermarkIgnoreElements: ['zen-browser-background', 'zen-toast-container'],
_watermarkIgnoreElements: ['zen-toast-container'],
async init() {
this.openWatermark();

View File

@@ -11,7 +11,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
class ZenUIMigration {
PREF_NAME = 'zen.migration.version';
MIGRATION_VERSION = 4;
MIGRATION_VERSION = 5;
init(isNewProfile, win) {
if (!isNewProfile) {

View File

@@ -104,6 +104,9 @@ document.addEventListener(
case 'cmd_zenOpenWorkspacePanel':
gZenWorkspaces.openWorkspacesDialog(event);
break;
case 'cmd_zenOpenWorkspaceCreation':
gZenWorkspaces.openWorkspaceCreation(event);
break;
default:
if (event.target.id.startsWith('cmd_zenWorkspaceSwitch')) {
const index = parseInt(event.target.id.replace('cmd_zenWorkspaceSwitch', ''), 10) - 1;

View File

@@ -211,8 +211,10 @@ var gZenCompactModeManager = {
return;
}
let sidebarWidth = this.sidebar.getBoundingClientRect().width;
const shouldRecalculate =
this.preference || document.documentElement.hasAttribute('zen-creating-workspace');
if (sidebarWidth > 1) {
if (this.preference && gZenVerticalTabsManager._prefsSidebarExpanded) {
if (shouldRecalculate && gZenVerticalTabsManager._prefsSidebarExpanded) {
sidebarWidth = Math.max(sidebarWidth, 150);
}
// Second variable to get the genuine width of the sidebar
@@ -220,7 +222,7 @@ var gZenCompactModeManager = {
window.dispatchEvent(new window.Event('resize')); // To recalculate the layout
if (
event &&
this.preference &&
shouldRecalculate &&
gZenVerticalTabsManager._prefsSidebarExpanded &&
!gZenVerticalTabsManager._hadSidebarCollapse
) {

View File

@@ -48,7 +48,7 @@
}
#navigator-toolbox {
--zen-toolbox-max-width: 66px !important;
--zen-toolbox-max-width: 74px !important;
--zen-compact-float: var(--zen-element-separation);
/* Initial padding for when we are animating */

View File

@@ -718,9 +718,15 @@
/* Define fixed width and padding for collapsed state */
:root:not([zen-sidebar-expanded='true']) {
--tab-min-width: 36px !important;
--tab-min-width: 48px !important;
--zen-toolbox-padding: 6px !important;
--zen-toolbox-max-width: calc(var(--tab-min-width) + var(--zen-toolbox-padding) * 2);
/* We can't show the rename input properly in collapsed state,
so hide the workspace edit input */
#context_zenEditWorkspace {
display: none;
}
}
#navigator-toolbox:not([zen-sidebar-expanded='true']) {
@@ -735,14 +741,22 @@
display: none !important;
}
/* Center and dim workspace indicator */
& .zen-current-workspace-indicator {
padding-left: 0;
padding-right: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
opacity: 0.4;
& .zen-workspaces-actions {
position: absolute;
width: 100%;
height: 100%;
}
&:is([open='true'], :hover) .zen-current-workspace-indicator-icon {
display: none;
}
}
/* Center items in essentials container */
@@ -801,8 +815,12 @@
/* Style new tab button area */
& #tabbrowser-arrowscrollbox-periphery {
& > toolbarbutton {
margin: 0 auto !important; /* Center the button */
padding: 0 !important; /* Remove padding */
margin-left: auto !important; /* Center the button */
margin-right: auto !important; /* Center the button */
& image {
width: 100%;
}
}
/* Adjust separator */
&::before {

View File

@@ -69,15 +69,20 @@
initContextMenu() {
const menu = window.MozXULElement.parseXULToFragment(`
<menuitem id="zenToolbarThemePicker"
data-lazy-l10n-id="zen-workspaces-change-gradient"
data-lazy-l10n-id="zen-workspaces-change-theme"
command="cmd_zenOpenZenThemePicker"/>
`);
document.getElementById('toolbar-context-customize').before(menu);
}
openThemePicker(event) {
PanelMultiView.openPopup(this.panel, this.toolbox, {
position: 'topright topleft',
const target = event.explicitOriginalTarget?.classList?.contains(
'zen-workspace-creation-edit-theme-button'
)
? event.explicitOriginalTarget
: this.toolbox;
PanelMultiView.openPopup(this.panel, target, {
position: 'bottomright topright',
triggerEvent: event,
});
}

View File

@@ -5,7 +5,7 @@
class ZenWorkspace extends MozXULElement {
static get markup() {
return `
<vbox class="zen-workspace-tabs-section zen-current-workspace-indicator" flex="1">
<vbox class="zen-workspace-tabs-section zen-current-workspace-indicator" flex="1" context="zenWorkspaceMoreActions">
<hbox class="zen-current-workspace-indicator-icon"></hbox>
<hbox class="zen-current-workspace-indicator-name" flex="1"></hbox>
<toolbarbutton class="toolbarbutton-1 chromeclass-toolbar-additional zen-workspaces-actions" context="zenWorkspaceMoreActions"></toolbarbutton>
@@ -199,16 +199,16 @@
onActionsCommand(event) {
event.stopPropagation();
const popup = document.getElementById('zenWorkspaceMoreActions');
event.target.setAttribute('open', 'true');
const target = event.target;
target.setAttribute('open', 'true');
this.indicator.setAttribute('open', 'true');
popup.addEventListener(
'popuphidden',
() => {
event.target.removeAttribute('open');
this.indicator.removeAttribute('open');
},
{ once: true }
);
const handlePopupHidden = (event) => {
if (event.target !== popup) return;
target.removeAttribute('open');
this.indicator.removeAttribute('open');
popup.removeEventListener('popuphidden', handlePopupHidden);
};
popup.addEventListener('popuphidden', handlePopupHidden);
popup.openPopup(event.target, 'after_start');
}
}

View File

@@ -0,0 +1,246 @@
{
class ZenWorkspaceCreation extends MozXULElement {
#wasInCollapsedMode = false;
promiseInitialized = new Promise((resolve) => {
this.resolveInitialized = resolve;
});
#hiddenElements = [];
static get elementsToDisable() {
return [
'cmd_zenOpenWorkspacePanel',
'cmd_zenOpenWorkspaceCreation',
'cmd_zenToggleSidebar',
'cmd_newNavigatorTab',
'cmd_newNavigatorTabNoEvent',
];
}
static get markup() {
return `
<vbox class="zen-workspace-creation" flex="1">
<form>
<vbox>
<html:h1 data-l10n-id="zen-workspace-creation-title" class="zen-workspace-creation-title" />
<label data-l10n-id="zen-workspace-creation-label" class="zen-workspace-creation-label" />
</vbox>
<vbox class="zen-workspace-creation-form">
<hbox class="zen-workspace-creation-name-wrapper">
<toolbarbutton class="zen-workspace-creation-icon-label" />
<html:input
class="zen-workspace-creation-name"
type="text"
data-l10n-id="zen-workspace-creation-name" />
</hbox>
<hbox class="zen-workspace-creation-profile-wrapper">
<label class="zen-workspace-creation-profile-label" data-l10n-id="zen-workspace-creation-profile" />
<button class="zen-workspace-creation-profile" />
</hbox>
<button
class="zen-workspace-creation-edit-theme-button"
data-l10n-id="zen-workspaces-change-theme"
command="cmd_zenOpenZenThemePicker" />
<menupopup class="zen-workspace-creation-profiles-popup" />
</vbox>
<vbox class="zen-workspace-creation-buttons">
<button class="zen-workspace-creation-create-button footer-button primary"
data-l10n-id="zen-panel-ui-workspaces-create" disabled="true" />
<button class="zen-workspace-creation-cancel-button footer-button"
data-l10n-id="zen-general-cancel-label" />
</vbox>
</form>
</vbox>
`;
}
get workspaceId() {
return this.getAttribute('workspace-id');
}
connectedCallback() {
if (this.delayConnectedCallback()) {
// If we are not ready yet, or if we have already connected, we
// don't need to do anything.
return;
}
document.documentElement.setAttribute('zen-creating-workspace', 'true');
this.appendChild(this.constructor.fragment);
this.initializeAttributeInheritance();
this.#wasInCollapsedMode =
document.documentElement.getAttribute('zen-sidebar-expanded') !== 'true';
gNavToolbox.setAttribute('zen-sidebar-expanded', 'true');
document.documentElement.setAttribute('zen-sidebar-expanded', 'true');
window.docShell.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIAppWindow)
.rollupAllPopups();
this.handleZenWorkspacesChangeBind = this.handleZenWorkspacesChange.bind(this);
for (const element of this.parentElement.children) {
if (element !== this) {
element.hidden = true;
this.#hiddenElements.push(element);
}
}
gBrowser.tabContainer.style.visibility = 'collapse';
if (gZenVerticalTabsManager._hasSetSingleToolbar) {
document.getElementById('nav-bar').style.visibility = 'collapse';
}
for (const element of ZenWorkspaceCreation.elementsToDisable) {
const el = document.getElementById(element);
if (el) {
el.setAttribute('disabled', 'true');
}
}
this.inputName = this.querySelector('.zen-workspace-creation-name');
this.inputIcon = this.querySelector('.zen-workspace-creation-icon-label');
this.inputProfile = this.querySelector('.zen-workspace-creation-profile');
this.createButton = this.querySelector('.zen-workspace-creation-create-button');
this.cancelButton = this.querySelector('.zen-workspace-creation-cancel-button');
this.createButton.addEventListener('command', this.onCreateButtonCommand.bind(this));
this.cancelButton.addEventListener('command', this.onCancelButtonCommand.bind(this));
this.inputName.addEventListener('input', () => {
this.createButton.disabled = !this.inputName.value.trim();
});
this.inputIcon.addEventListener('command', this.onIconCommand.bind(this));
this.profilesPopup = this.querySelector('.zen-workspace-creation-profiles-popup');
if (gZenWorkspaces.shouldShowContainers) {
this.inputProfile.addEventListener('command', this.onProfileCommand.bind(this));
this.profilesPopup.addEventListener('popupshown', this.onProfilePopupShown.bind(this));
this.profilesPopup.addEventListener('command', this.onProfilePopupCommand.bind(this));
this.currentProfile = {
id: 0,
name: 'Default',
};
} else {
this.inputProfile.parentNode.hidden = true;
}
this.resolveInitialized();
}
async onCreateButtonCommand() {
const workspace = await gZenWorkspaces.getActiveWorkspace();
workspace.name = this.inputName.value.trim();
workspace.icon = this.inputIcon.label || undefined;
workspace.containerTabId = this.currentProfile;
await gZenWorkspaces.saveWorkspace(workspace);
this.#cleanup();
await gZenWorkspaces._organizeWorkspaceStripLocations(workspace, true);
await gZenWorkspaces.updateTabsContainers();
this.tabContainer._invalidateCachedTabs();
if (gZenVerticalTabsManager._canReplaceNewTab) {
BrowserCommands.openTab();
}
}
async onCancelButtonCommand() {
const workspaces = await gZenWorkspaces._workspaces();
await gZenWorkspaces.changeWorkspace(workspaces.workspaces[workspaces.workspaces.length - 2]);
}
onIconCommand(event) {
gZenEmojiPicker
.open(event.target)
.then(async (emoji) => {
this.inputIcon.label = emoji || '';
})
.catch((error) => {
console.warn('Error changing workspace icon:', error);
});
}
set currentProfile(profile) {
this.inputProfile.label = profile.name;
this._profileId = profile.id;
}
get currentProfile() {
return this._profileId;
}
onProfileCommand(event) {
this.profilesPopup.openPopup(event.target, 'after_start');
}
onProfilePopupShown(event) {
return window.createUserContextMenu(event, {
isContextMenu: true,
showDefaultTab: true,
});
}
onProfilePopupCommand(event) {
let userContextId = parseInt(event.target.getAttribute('data-usercontextid'));
if (isNaN(userContextId)) {
return;
}
this.currentProfile = {
id: userContextId,
name: event.target.label,
};
}
finishSetup() {
gZenWorkspaces.addChangeListeners(this.handleZenWorkspacesChangeBind, { once: true });
}
async handleZenWorkspacesChange() {
await gZenWorkspaces.removeWorkspace(this.workspaceId);
this.#cleanup();
}
#cleanup() {
gZenWorkspaces.removeChangeListeners(this.handleZenWorkspacesChangeBind);
for (const element of this.constructor.elementsToDisable) {
const el = document.getElementById(element);
if (el) {
el.removeAttribute('disabled');
}
}
if (this.#wasInCollapsedMode) {
gNavToolbox.removeAttribute('zen-sidebar-expanded');
document.documentElement.removeAttribute('zen-sidebar-expanded');
}
document.documentElement.removeAttribute('zen-creating-workspace');
gBrowser.tabContainer.style.visibility = '';
if (gZenVerticalTabsManager._hasSetSingleToolbar) {
document.getElementById('nav-bar').style.visibility = '';
}
for (const element of this.#hiddenElements) {
element.hidden = false;
}
this.#hiddenElements = [];
this.remove();
}
}
customElements.define('zen-workspace-creation', ZenWorkspaceCreation);
}

View File

@@ -20,8 +20,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
_lastScrollTime = 0;
#workspaceCreationArgs = {};
bookmarkMenus = [
'PlacesToolbar',
'bookmarks-menu-button',
@@ -368,6 +366,13 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
return this.tabboxChildren.filter((child) => !child.hasAttribute('zen-empty-tab'));
}
get shouldAnimateEssentials() {
return (
this.containerSpecificEssentials ||
document.documentElement.hasAttribute('zen-creating-workspace')
);
}
workspaceElement(workspaceId) {
if (typeof workspaceId !== 'string') {
workspaceId = workspaceId?.uuid;
@@ -999,6 +1004,9 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
const hasNoIcon = anchor.hasAttribute('no-icon');
anchor.removeAttribute('no-icon');
if (hasNoIcon) {
anchor.textContent = '';
}
gZenEmojiPicker
.open(anchor)
.then(async (emoji) => {
@@ -1555,6 +1563,19 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
}).catch(console.error);
}
async openWorkspaceCreation(event) {
let createForm;
await this.createAndSaveWorkspace('Space', undefined, false, 0, {
beforeChangeCallback: async (workspace) => {
createForm = document.createXULElement('zen-workspace-creation');
createForm.setAttribute('workspace-id', workspace.uuid);
gBrowser.tabContainer.after(createForm);
await createForm.promiseInitialized;
},
});
createForm.finishSetup();
}
closeWorkspacesSubView() {
let parentPanel = document.getElementById('PanelUI-zen-workspaces-multiview');
parentPanel.goBack(parentPanel);
@@ -1627,11 +1648,23 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
}
addChangeListeners(func) {
addChangeListeners(
func,
opts = {
once: false,
}
) {
if (!this._changeListeners) {
this._changeListeners = [];
}
this._changeListeners.push(func);
this._changeListeners.push({ func, opts });
}
removeChangeListeners(func) {
if (!this._changeListeners) {
return;
}
this._changeListeners = this._changeListeners.filter((listener) => listener.func !== func);
}
async changeWorkspaceWithID(workspaceID, ...args) {
@@ -1780,7 +1813,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
// if it's not we do apply it
if (
container.getAttribute('container') != workspace.containerTabId &&
this.containerSpecificEssentials
this.shouldAnimateEssentials
) {
container.setAttribute('hidden', 'true');
} else {
@@ -1789,7 +1822,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (
nextWorkspaceContextId !== workspaceContextId &&
offsetPixels &&
this.containerSpecificEssentials &&
this.shouldAnimateEssentials &&
(container.getAttribute('container') == nextWorkspaceContextId ||
container.getAttribute('container') == workspaceContextId)
) {
@@ -1815,11 +1848,10 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (this.workspaceHasIcon(currentWorkspace)) {
indicatorIcon.removeAttribute('no-icon');
indicatorIcon.textContent = this.getWorkspaceIcon(currentWorkspace);
} else {
indicatorIcon.setAttribute('no-icon', 'true');
indicatorIcon.textContent = '';
}
indicatorIcon.textContent = this.getWorkspaceIcon(currentWorkspace);
indicatorName.textContent = currentWorkspace.name;
}
@@ -1844,7 +1876,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
const newWorkspaceIndex = workspaces.workspaces.findIndex((w) => w.uuid === newWorkspace.uuid);
const isGoingLeft = newWorkspaceIndex <= previousWorkspaceIndex;
const clonedEssentials = [];
if (shouldAnimate && this.containerSpecificEssentials && previousWorkspace) {
if (shouldAnimate && this.shouldAnimateEssentials && previousWorkspace) {
for (const workspace of workspaces.workspaces) {
const essentialsContainer = this.getEssentialsSection(workspace.containerTabId);
if (clonedEssentials[clonedEssentials.length - 1]?.contextId == workspace.containerTabId) {
@@ -1938,7 +1970,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
}
}
if (this.containerSpecificEssentials && previousWorkspace) {
if (this.shouldAnimateEssentials && previousWorkspace) {
// Animate essentials
const newWorkspaceEssentialsContainer = clonedEssentials.find((cloned) =>
cloned.workspaces.some((w) => w.uuid === newWorkspace.uuid)
@@ -2237,7 +2269,11 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
// Notify listeners
if (this._changeListeners?.length) {
for (const listener of this._changeListeners) {
await listener(workspace, onInit);
const { func, opts } = listener;
await func({ workspace, onInit });
if (opts.once) {
this.removeChangeListeners(func);
}
}
}
@@ -2332,7 +2368,8 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
name = 'Space',
icon = undefined,
dontChange = false,
containerTabId = 0
containerTabId = 0,
{ beforeChangeCallback } = { beforeChangeCallback: null } // Callback to run before changing workspace
) {
if (!this.workspaceEnabled) {
return;
@@ -2361,6 +2398,13 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
await this.saveWorkspace(workspaceData, dontChange);
}
if (!dontChange) {
if (beforeChangeCallback) {
try {
await beforeChangeCallback(workspaceData);
} catch (e) {
console.error('Error in beforeChangeCallback:', e);
}
}
this.registerPinnedResizeObserver();
let changed = extraTabs.length > 0;
if (changed) {
@@ -2545,10 +2589,13 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
let userContextId = parseInt(event.target.getAttribute('data-usercontextid'));
workspace.containerTabId = userContextId + 0; // +0 to convert to number
await this.saveWorkspace(workspace);
await this._organizeWorkspaceStripLocations(workspace, true);
await gZenWorkspaces.updateTabsContainers();
this.tabContainer._invalidateCachedTabs();
}
async contextDeleteWorkspace() {
await this.removeWorkspace(this.activeWorkspace, true);
await this.removeWorkspace(this.activeWorkspace);
}
findTabToBlur(tab) {
@@ -2592,6 +2639,10 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
menu.appendChild(menuPopup);
document.getElementById('context_closeDuplicateTabs').after(menu);
document
.getElementById('cmd_zenOpenWorkspaceCreation')
.setAttribute('disabled', this.privateWindowOrDisabled);
}
async changeTabWorkspace(workspaceID) {

View File

@@ -0,0 +1,140 @@
/*
* 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/.
*/
zen-workspace-creation {
flex: 1;
max-width: calc(var(--zen-sidebar-width) - var(--zen-toolbox-padding) * 2);
& .zen-workspace-creation {
justify-content: center;
& .zen-workspace-creation-title {
font-size: large;
}
& .zen-workspace-creation-label {
margin: 0;
opacity: 0.6;
}
& form {
--input-border-color: light-dark(rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.2));
--input-bgcolor: light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.15));
display: flex;
flex-direction: column;
width: calc(100% - 10px);
margin: auto;
gap: 1rem;
& .zen-workspace-creation-form {
gap: 0.6rem;
}
& xul|button {
border: none;
margin: 0;
}
& .zen-workspace-creation-name-wrapper {
padding: 9px 6px;
border-radius: var(--zen-button-border-radius);
margin: 0;
background-color: var(--input-bgcolor);
gap: 8px;
align-items: center;
padding-left: 8px;
& .zen-workspace-creation-icon-label {
position: relative;
width: 24px;
height: 20px;
justify-content: center;
align-items: center;
cursor: pointer;
background: transparent !important;
appearance: none;
align-content: center;
padding: 0;
& image {
display: none;
}
& label {
display: flex;
font-size: 12px;
justify-content: center;
}
&::before {
border: 1px dashed light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.5));
border-radius: 4px;
width: calc(100% + 2px);
height: calc(100% + 2px);
content: '';
position: absolute;
top: -2px;
left: -2px;
pointer-events: none;
}
}
& .zen-workspace-creation-name {
--input-border-color: transparent;
--input-bgcolor: transparent;
padding: 0 !important;
width: 100%;
}
}
& .zen-workspace-creation-profile-wrapper {
padding: 4px;
border-radius: var(--zen-button-border-radius);
margin: 0;
background-color: var(--input-bgcolor);
gap: 4px;
align-items: center;
flex-wrap: wrap;
& .zen-workspace-creation-profile-label {
cursor: help;
}
& .zen-workspace-creation-profile {
margin: 0;
padding: 6px !important;
border-radius: 99px;
padding-inline-end: 0;
appearance: none;
background: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1));
margin-left: auto;
min-width: unset !important;
}
}
& .zen-workspace-creation-edit-theme-button {
border-radius: var(--zen-button-border-radius);
margin: 0;
background-color: var(--input-bgcolor);
justify-content: center;
align-items: center;
appearance: none;
padding: 10px !important;
}
& .zen-workspace-creation-buttons {
gap: 0.5rem;
margin-top: 2rem;
& .zen-workspace-creation-create-button {
color: var(--button-text-color-primary) !important;
background: var(--color-accent-primary) !important;
}
}
}
}
}

View File

@@ -402,7 +402,7 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: text;
cursor: auto;
}
.zen-workspaces-actions {
@@ -506,3 +506,5 @@ zen-workspace {
#wrapper-zen-workspaces-button {
width: 100%;
}
%include create-workspace-form.css