mirror of
https://github.com/zen-browser/desktop.git
synced 2025-10-15 06:16:14 +00:00
feat: Added new workspace creation form, b=no-bug, c=tabs, common, compact-mode, workspaces
This commit is contained in:
@@ -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
2
l10n
Submodule l10n updated: 751793cd1f...a98bf79797
@@ -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>
|
||||
|
@@ -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)
|
||||
|
@@ -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" />
|
||||
|
@@ -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"
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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(
|
||||
|
@@ -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();
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
) {
|
||||
|
@@ -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 */
|
||||
|
@@ -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 {
|
||||
|
@@ -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,
|
||||
});
|
||||
}
|
||||
|
@@ -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');
|
||||
const handlePopupHidden = (event) => {
|
||||
if (event.target !== popup) return;
|
||||
target.removeAttribute('open');
|
||||
this.indicator.removeAttribute('open');
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
popup.removeEventListener('popuphidden', handlePopupHidden);
|
||||
};
|
||||
popup.addEventListener('popuphidden', handlePopupHidden);
|
||||
popup.openPopup(event.target, 'after_start');
|
||||
}
|
||||
}
|
||||
|
246
src/zen/workspaces/ZenWorkspaceCreation.mjs
Normal file
246
src/zen/workspaces/ZenWorkspaceCreation.mjs
Normal 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);
|
||||
}
|
@@ -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) {
|
||||
|
140
src/zen/workspaces/create-workspace-form.css
Normal file
140
src/zen/workspaces/create-workspace-form.css
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
Reference in New Issue
Block a user