mirror of
https://github.com/zen-browser/desktop.git
synced 2025-07-07 17:15:30 +02:00
feat: Added library, b=(no-bug), c=common, tabs, workspaces
This commit is contained in:
parent
a3de3e221c
commit
3724f2a759
17 changed files with 611 additions and 1118 deletions
|
@ -1,8 +1,16 @@
|
|||
diff --git a/browser/base/content/browser-box.inc.xhtml b/browser/base/content/browser-box.inc.xhtml
|
||||
index 7d7e8697f02f90d4f336c9ab0a73a89848e0c21c..64e950106dd05b443ce72107613ac9cc405d56ea 100644
|
||||
index 7d7e8697f02f90d4f336c9ab0a73a89848e0c21c..3819ae72f97900b6d212f8a54550ae569d497741 100644
|
||||
--- a/browser/base/content/browser-box.inc.xhtml
|
||||
+++ b/browser/base/content/browser-box.inc.xhtml
|
||||
@@ -23,7 +23,15 @@
|
||||
@@ -3,6 +3,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
<hbox flex="1" id="browser">
|
||||
+ <zen-library/>
|
||||
<box context="sidebar-context-menu" id="sidebar-main" hidden="true">
|
||||
<html:sidebar-main flex="1">
|
||||
<box id="vertical-tabs" slot="tabstrip" customizable="true" contextmenu="toolbar-context-menu"></box>
|
||||
@@ -23,7 +24,15 @@
|
||||
<browser id="sidebar" autoscroll="false" disablehistory="true" disablefullscreen="true" tooltip="aHTMLTooltip"/>
|
||||
</vbox>
|
||||
<splitter id="sidebar-splitter" class="chromeclass-extrachrome sidebar-splitter" resizebefore="sibling" resizeafter="none" hidden="true"/>
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-urlbar.css" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-workspaces.css" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-decks.css" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-library.css" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-folders.css" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-glance.css" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-popup.css" />
|
||||
|
@ -42,3 +43,4 @@
|
|||
<script src="chrome://browser/content/zen-components/ZenGlanceManager.mjs"></script>
|
||||
<script src="chrome://browser/content/zen-components/ZenMediaController.mjs"></script>
|
||||
<script src="chrome://browser/content/zen-components/ZenDownloadAnimation.mjs"></script>
|
||||
<script src="chrome://browser/content/zen-components/ZenLibrary.mjs"></script>
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
content/browser/zen-components/actors/ZenThemeMarketplaceParent.sys.mjs (../../zen/mods/actors/ZenThemeMarketplaceParent.sys.mjs)
|
||||
content/browser/zen-components/actors/ZenThemeMarketplaceChild.sys.mjs (../../zen/mods/actors/ZenThemeMarketplaceChild.sys.mjs)
|
||||
|
||||
content/browser/zen-components/ZenLibrary.mjs (../../zen/library/ZenLibrary.mjs)
|
||||
content/browser/zen-styles/zen-library.css (../../zen/library/zen-library.css)
|
||||
|
||||
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)
|
||||
|
|
|
@ -43,6 +43,11 @@
|
|||
|
||||
<command id="cmd_zenCopyCurrentURL" />
|
||||
<command id="cmd_zenCopyCurrentURLMarkdown" />
|
||||
|
||||
<command id="cmd_zenCtxDeleteWorkspace" />
|
||||
<command id="cmd_zenChangeWorkspaceName" />
|
||||
|
||||
<command id="cmd_zenToggleLibrary" />
|
||||
</commandset>
|
||||
|
||||
<keyset id="zenKeyset"></keyset>
|
||||
|
|
|
@ -57,67 +57,11 @@
|
|||
</panelmultiview>
|
||||
</panel>
|
||||
|
||||
<panel flip="slide" type="arrow" orient="vertical" id="PanelUI-zen-workspaces" position="bottomright topright" mainview="true" side="left">
|
||||
<panelmultiview id="PanelUI-zen-workspaces-multiview" mainViewId="PanelUI-zen-workspaces-view">
|
||||
<panelview id="PanelUI-zen-workspaces-view" class="PanelUI-subView" role="document" mainview-with-header="true" has-custom-header="true" closemenu="none">
|
||||
<vbox>
|
||||
<hbox>
|
||||
<h3 data-l10n-id="zen-panel-ui-workspaces-text" id="PanelUI-zen-workspaces-header"></h3>
|
||||
<toolbarbutton id="PanelUI-zen-workspaces-reorder-mode" class="subviewbutton">
|
||||
<image></image>
|
||||
</toolbarbutton>
|
||||
<toolbarbutton id="PanelUI-zen-workspaces-new" class="subviewbutton">
|
||||
<image></image>
|
||||
</toolbarbutton>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<html:div id="PanelUI-zen-workspaces-list">
|
||||
</html:div>
|
||||
</panelview>
|
||||
<panelview id="PanelUI-zen-workspaces-create" class="PanelUI-subView" role="document" mainview-with-header="true" has-custom-header="true">
|
||||
<vbox class="PanelUI-zen-workspaces-user-create">
|
||||
<h1 data-l10n-id="zen-panel-ui-workspaces-create-text"></h1>
|
||||
<hbox class="PanelUI-zen-workspaces-creation-wraper">
|
||||
<hbox class="PanelUI-zen-workspaces-icons-container create"></hbox>
|
||||
<html:input autofocus="true" id="PanelUI-zen-workspaces-create-input" type="text" placeholder="Enter workspace name" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
<html:moz-button-group class="panel-footer" id="PanelUI-zen-workspaces-create-footer">
|
||||
<button disabled="true" default="true" slot="primary" id="PanelUI-zen-workspaces-create-save" class="footer-button" data-l10n-id="zen-panel-ui-workspaces-create-save">
|
||||
</button>
|
||||
<button id="PanelUI-zen-workspaces-create-cancel" class="footer-button" data-l10n-id="zen-panel-ui-workspaces-create-cancel">
|
||||
</button>
|
||||
</html:moz-button-group>
|
||||
</panelview>
|
||||
<panelview id="PanelUI-zen-workspaces-edit" class="PanelUI-subView" role="document" mainview-with-header="true" has-custom-header="true">
|
||||
<vbox class="PanelUI-zen-workspaces-user-create">
|
||||
<h1 data-l10n-id="zen-panel-ui-workspaces-edit-text"></h1>
|
||||
<hbox class="PanelUI-zen-workspaces-creation-wraper">
|
||||
<hbox class="PanelUI-zen-workspaces-icons-container edit"></hbox>
|
||||
<html:input autofocus="true" id="PanelUI-zen-workspaces-edit-input" type="text" placeholder="Enter workspace name" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
<html:moz-button-group class="panel-footer" id="PanelUI-zen-workspaces-edit-footer">
|
||||
<button disabled="true" default="true" slot="primary" id="PanelUI-zen-workspaces-edit-save" class="footer-button" data-l10n-id="zen-panel-ui-workspaces-edit-save">
|
||||
</button>
|
||||
<button id="PanelUI-zen-workspaces-edit-cancel" class="footer-button" data-l10n-id="zen-panel-ui-workspaces-edit-cancel">
|
||||
</button>
|
||||
</html:moz-button-group>
|
||||
</panelview>
|
||||
<panelview id="PanelUI-zen-workspaces-icon-picker" class="PanelUI-subView" role="document" mainview-with-header="true" has-custom-header="true">
|
||||
<vbox id="PanelUI-zen-workspaces-icon-picker-wrapper">
|
||||
<html:div id="PanelUI-zen-workspaces-icon-search-bar">
|
||||
<html:input autofocus="true" type="text" id="PanelUI-zen-workspaces-icon-search-input"/>
|
||||
</html:div>
|
||||
</vbox>
|
||||
</panelview>
|
||||
</panelmultiview>
|
||||
</panel>
|
||||
|
||||
<menupopup id="zenWorkspaceActionsMenu">
|
||||
<menuitem id="context_zenOpenWorkspace" data-l10n-id="zen-workspaces-panel-context-open"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="context_zenEditWorkspace" data-l10n-id="zen-workspaces-panel-context-edit"/>
|
||||
<menupopup id="zenWorkspaceMoreActions">
|
||||
<menuitem id="context_zenEditWorkspace" data-l10n-id="zen-workspaces-panel-change-name" command="cmd_zenChangeWorkspaceName"/>
|
||||
<menuitem class="zenToolbarThemePicker"
|
||||
data-l10n-id="zen-workspaces-change-gradient"
|
||||
command="cmd_zenOpenZenThemePicker"/>
|
||||
<menu id="context_zenWorkspacesOpenInContainerTab"
|
||||
data-l10n-id="zen-workspaces-panel-context-open-in-container-tab"
|
||||
selection-type="single"
|
||||
|
@ -127,5 +71,5 @@
|
|||
<menupopup />
|
||||
</menu>
|
||||
<menuseparator/>
|
||||
<menuitem id="context_zenDeleteWorkspace" data-l10n-id="zen-workspaces-panel-context-delete"/>
|
||||
<menuitem id="context_zenDeleteWorkspace" data-l10n-id="zen-workspaces-panel-context-delete" command="cmd_zenCtxDeleteWorkspace"/>
|
||||
</menupopup>
|
||||
|
|
|
@ -9,5 +9,6 @@
|
|||
context="toolbar-context-menu"
|
||||
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>
|
||||
<toolbarbutton removable="true" class="chromeclass-toolbar-additional toolbarbutton-1 zen-sidebar-action-button" id="zen-open-library" command="cmd_zenToggleLibrary"></toolbarbutton>
|
||||
<zen-workspace-icons id="zen-workspaces-button" overflows="false" removable="false"></zen-workspace-icons>
|
||||
</toolbar>
|
||||
|
|
|
@ -60,6 +60,14 @@
|
|||
list-style-image: url('sidebars-right.svg') !important;
|
||||
}
|
||||
|
||||
#zen-library-sidebar-workspaces {
|
||||
list-style-image: url('duplicate-tab.svg');
|
||||
}
|
||||
|
||||
#zen-library-sidebar-mods {
|
||||
list-style-image: url('edit.svg');
|
||||
}
|
||||
|
||||
#context_zenSplitTabs {
|
||||
--menu-image: url('sidebars-right.svg') !important;
|
||||
}
|
||||
|
@ -119,6 +127,7 @@
|
|||
|
||||
#PanelUI-menu-button,
|
||||
#appMenu-more-button2,
|
||||
.zen-workspaces-actions,
|
||||
#zen-workspace-actions-menu-icon {
|
||||
list-style-image: url('menu.svg') !important;
|
||||
}
|
||||
|
@ -173,12 +182,7 @@
|
|||
list-style-image: url('open.svg') !important;
|
||||
}
|
||||
|
||||
#context_zenOpenWorkspace {
|
||||
--menu-image: url('open.svg') !important;
|
||||
}
|
||||
|
||||
#context_zenEditWorkspace,
|
||||
#zenToolbarThemePicker {
|
||||
.zenToolbarThemePicker {
|
||||
--menu-image: url('edit-theme.svg') !important;
|
||||
}
|
||||
|
||||
|
@ -199,16 +203,10 @@
|
|||
#appMenu-zoomEnlarge-button2,
|
||||
#PanelUI-zen-profiles-newProfile,
|
||||
#zen-sidebar-add-panel-button,
|
||||
#PanelUI-zen-workspaces-new image,
|
||||
#PanelUI-zen-gradient-generator-color-custom-add image {
|
||||
list-style-image: url('plus.svg') !important;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-reorder-mode image {
|
||||
list-style-image: url('move-tab.svg') !important;
|
||||
rotate: 90deg;
|
||||
}
|
||||
|
||||
#cut-button {
|
||||
list-style-image: url('edit-cut.svg') !important;
|
||||
}
|
||||
|
@ -303,7 +301,8 @@
|
|||
list-style-image: url('home.svg') !important;
|
||||
}
|
||||
|
||||
#library-button {
|
||||
#library-button,
|
||||
#zen-open-library {
|
||||
list-style-image: url('library.svg') !important;
|
||||
}
|
||||
|
||||
|
@ -980,7 +979,8 @@ menuitem[contexttype='fullscreen'][label*='Exit'] {
|
|||
|
||||
menuitem[id='placesContext_show_bookmark:info'],
|
||||
menuitem[id='placesContext_show_folder:info'],
|
||||
menuitem[id='placesContext_show:info'] {
|
||||
menuitem[id='placesContext_show:info'],
|
||||
#context_zenEditWorkspace {
|
||||
--menu-image: url('edit.svg');
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ export var ZenCustomizableUI = new (class {
|
|||
constructor() {}
|
||||
|
||||
TYPE_TOOLBAR = 'toolbar';
|
||||
defaultSidebarIcons = ['preferences-button', 'zen-workspaces-button', 'downloads-button'];
|
||||
defaultSidebarIcons = ['zen-open-library', 'zen-workspaces-button', 'downloads-button'];
|
||||
|
||||
startup(CustomizableUIInternal) {
|
||||
CustomizableUIInternal.registerArea(
|
||||
|
|
|
@ -989,43 +989,54 @@ var gZenVerticalTabsManager = {
|
|||
async renameTabKeydown(event) {
|
||||
event.stopPropagation();
|
||||
if (event.key === 'Enter') {
|
||||
let label = this._tabEdited.querySelector('.tab-label-container-editing');
|
||||
let input = this._tabEdited.querySelector('#tab-label-input');
|
||||
const isTab = !!event.target.closest('.tabbrowser-tab');
|
||||
let label = isTab
|
||||
? this._tabEdited.querySelector('.tab-label-container-editing')
|
||||
: this._tabEdited;
|
||||
let input = document.getElementById('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');
|
||||
gZenUIManager.showToast('zen-tabs-renamed');
|
||||
document.documentElement.removeAttribute('zen-renaming-tab');
|
||||
input.remove();
|
||||
if (!isTab) {
|
||||
await this._tabEdited.onRenameFinished(newName);
|
||||
} else {
|
||||
gBrowser.setTabTitle(this._tabEdited);
|
||||
}
|
||||
if (this._tabEdited.getAttribute('zen-pin-id')) {
|
||||
// Update pin title in storage
|
||||
await gZenPinnedTabManager.updatePinTitle(
|
||||
// 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');
|
||||
gZenUIManager.showToast('zen-tabs-renamed');
|
||||
} else {
|
||||
gBrowser.setTabTitle(this._tabEdited);
|
||||
}
|
||||
if (this._tabEdited.getAttribute('zen-pin-id')) {
|
||||
// Update pin title in storage
|
||||
await gZenPinnedTabManager.updatePinTitle(
|
||||
this._tabEdited,
|
||||
this._tabEdited.label,
|
||||
!!newName
|
||||
);
|
||||
}
|
||||
|
||||
// Maybe add some confetti here?!?
|
||||
gZenUIManager.motion.animate(
|
||||
this._tabEdited,
|
||||
this._tabEdited.label,
|
||||
!!newName
|
||||
{
|
||||
scale: [1, 0.98, 1],
|
||||
},
|
||||
{
|
||||
duration: 0.25,
|
||||
}
|
||||
);
|
||||
}
|
||||
document.documentElement.removeAttribute('zen-renaming-tab');
|
||||
|
||||
// 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();
|
||||
const editorContainer = this._tabEdited.querySelector('.tab-editor-container');
|
||||
if (editorContainer) {
|
||||
editorContainer.remove();
|
||||
}
|
||||
label.classList.remove('tab-label-container-editing');
|
||||
|
||||
this._tabEdited = null;
|
||||
|
@ -1035,34 +1046,45 @@ var gZenVerticalTabsManager = {
|
|||
},
|
||||
|
||||
renameTabStart(event) {
|
||||
const isTab = !!event.target.closest('.tabbrowser-tab');
|
||||
if (
|
||||
this._tabEdited ||
|
||||
!Services.prefs.getBoolPref('zen.tabs.rename-tabs') ||
|
||||
Services.prefs.getBoolPref('browser.tabs.closeTabByDblclick') ||
|
||||
((!Services.prefs.getBoolPref('zen.tabs.rename-tabs') ||
|
||||
Services.prefs.getBoolPref('browser.tabs.closeTabByDblclick')) &&
|
||||
isTab) ||
|
||||
!gZenVerticalTabsManager._prefsSidebarExpanded
|
||||
)
|
||||
return;
|
||||
this._tabEdited = event.target.closest('.tabbrowser-tab');
|
||||
this._tabEdited =
|
||||
event.target.closest('.tabbrowser-tab') ||
|
||||
event.target.closest('.zen-current-workspace-indicator-name') ||
|
||||
gZenWorkspaces.activeWorkspaceIndicator.querySelector(
|
||||
'.zen-current-workspace-indicator-name'
|
||||
);
|
||||
if (
|
||||
!this._tabEdited ||
|
||||
!this._tabEdited.pinned ||
|
||||
this._tabEdited.hasAttribute('zen-essential')
|
||||
((!this._tabEdited.pinned || this._tabEdited.hasAttribute('zen-essential')) && isTab)
|
||||
) {
|
||||
this._tabEdited = null;
|
||||
return;
|
||||
}
|
||||
event.stopPropagation();
|
||||
document.documentElement.setAttribute('zen-renaming-tab', 'true');
|
||||
const label = this._tabEdited.querySelector('.tab-label-container');
|
||||
const label = isTab ? this._tabEdited.querySelector('.tab-label-container') : this._tabEdited;
|
||||
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');
|
||||
if (isTab) {
|
||||
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 = isTab
|
||||
? this._tabEdited.querySelector('.tab-editor-container')
|
||||
: this._tabEdited.parentNode;
|
||||
const input = document.createElement('input');
|
||||
input.id = 'tab-label-input';
|
||||
input.value = this._tabEdited.label;
|
||||
input.value = isTab ? this._tabEdited.label : this._tabEdited.textContent;
|
||||
input.addEventListener('keydown', this.renameTabKeydown.bind(this));
|
||||
|
||||
containerHtml.appendChild(input);
|
||||
|
@ -1077,8 +1099,16 @@ var gZenVerticalTabsManager = {
|
|||
return;
|
||||
}
|
||||
document.documentElement.removeAttribute('zen-renaming-tab');
|
||||
this._tabEdited.querySelector('.tab-editor-container').remove();
|
||||
const label = this._tabEdited.querySelector('.tab-label-container-editing');
|
||||
const editorContainer = this._tabEdited.querySelector('.tab-editor-container');
|
||||
let input = document.getElementById('tab-label-input');
|
||||
input.remove();
|
||||
if (editorContainer) {
|
||||
editorContainer.remove();
|
||||
}
|
||||
const isTab = !!this._tabEdited.closest('.tabbrowser-tab');
|
||||
const label = isTab
|
||||
? this._tabEdited.querySelector('.tab-label-container-editing')
|
||||
: this._tabEdited;
|
||||
label.classList.remove('tab-label-container-editing');
|
||||
|
||||
this._tabEdited = null;
|
||||
|
|
|
@ -73,6 +73,9 @@ document.addEventListener(
|
|||
event.sourceEvent.target.getAttribute('zen-workspace-id')
|
||||
);
|
||||
break;
|
||||
case 'cmd_zenToggleLibrary':
|
||||
gZenLibrary.toggle();
|
||||
break;
|
||||
case 'cmd_zenToggleTabsOnRight':
|
||||
gZenVerticalTabsManager.toggleTabsOnRight();
|
||||
break;
|
||||
|
@ -88,6 +91,12 @@ document.addEventListener(
|
|||
case 'cmd_zenRemoveFromEssentials':
|
||||
gZenPinnedTabManager.removeEssentials();
|
||||
break;
|
||||
case 'cmd_zenCtxDeleteWorkspace':
|
||||
gZenWorkspaces.contextDeleteWorkspace(event);
|
||||
break;
|
||||
case 'cmd_zenChangeWorkspaceName':
|
||||
gZenVerticalTabsManager.renameTabStart(event);
|
||||
break;
|
||||
default:
|
||||
if (event.target.id.startsWith('cmd_zenWorkspaceSwitch')) {
|
||||
const index = parseInt(event.target.id.replace('cmd_zenWorkspaceSwitch', ''), 10) - 1;
|
||||
|
|
270
src/zen/library/ZenLibrary.mjs
Normal file
270
src/zen/library/ZenLibrary.mjs
Normal file
|
@ -0,0 +1,270 @@
|
|||
{
|
||||
class ZenLibraryElement extends MozXULElement {
|
||||
#currentTab = null;
|
||||
#availableTabs = ['workspaces', 'mods'];
|
||||
|
||||
static get markup() {
|
||||
return `
|
||||
<vbox id="zen-library-sidebar">
|
||||
<vbox id="zen-library-sidebar-buttons" flex="1">
|
||||
<toolbarbutton class="toolbarbutton-1 zen-library-sidebar-button" id="zen-library-sidebar-workspaces" data-l10n-id="zen-library-sidebar-workspaces"/>
|
||||
<toolbarbutton class="toolbarbutton-1 zen-library-sidebar-button" id="zen-library-sidebar-mods" data-l10n-id="zen-library-sidebar-mods"/>
|
||||
</vbox>
|
||||
<hbox id="zen-library-sidebar-footer">
|
||||
<toolbarbutton removable="true" class="chromeclass-toolbar-additional toolbarbutton-1 zen-sidebar-action-button" id="zen-open-library" command="cmd_zenToggleLibrary"></toolbarbutton>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox id="zen-library-content">
|
||||
<hbox content="workspaces" size="big">
|
||||
</hbox>
|
||||
<hbox content="mods" size="small"></hbox>
|
||||
</vbox>
|
||||
`;
|
||||
}
|
||||
|
||||
static get inheritedAttributes() {
|
||||
return {
|
||||
'#zen-library-content': 'content,size=content-size',
|
||||
'#zen-library-sidebar': 'content',
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
set currentTab(tab) {
|
||||
if (!this.#availableTabs.includes(tab)) {
|
||||
throw new Error(`Tab "${tab}" is not available in Zen Library.`);
|
||||
}
|
||||
this.#currentTab = tab;
|
||||
this.setAttribute('content', tab);
|
||||
// Also set if the size is big or small based on the tab.
|
||||
const element = this.querySelector(`#zen-library-content hbox[content="${tab}"]`);
|
||||
this.setAttribute('content-size', element.getAttribute('size') || 'small');
|
||||
for (const availableTab of this.#availableTabs) {
|
||||
const button = this.querySelector(`#zen-library-sidebar-${availableTab}`);
|
||||
if (availableTab === tab) {
|
||||
button.setAttribute('active', 'true');
|
||||
} else {
|
||||
button.removeAttribute('active');
|
||||
}
|
||||
const contentContainer = this.#getContentContainer(availableTab);
|
||||
if (availableTab === tab) {
|
||||
contentContainer.removeAttribute('hidden');
|
||||
} else {
|
||||
contentContainer.setAttribute('hidden', 'true');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get currentTab() {
|
||||
return this.#currentTab;
|
||||
}
|
||||
|
||||
set open(value) {
|
||||
if (value) {
|
||||
this.setAttribute('open', 'true');
|
||||
this.onOpen(); // Trigger the onOpen method to populate the content
|
||||
} else {
|
||||
this.removeAttribute('open');
|
||||
this.onClose(); // Trigger the onClose method if needed
|
||||
}
|
||||
}
|
||||
|
||||
get open() {
|
||||
return this.getAttribute('open') === 'true';
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (this.delayConnectedCallback()) {
|
||||
// If we are not ready yet, or if we have already connected, we
|
||||
// don't need to do anything.
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = 'zen-library';
|
||||
this.appendChild(this.constructor.fragment);
|
||||
this.initializeAttributeInheritance();
|
||||
|
||||
for (const availableTab of this.#availableTabs) {
|
||||
const button = this.querySelector(`#zen-library-sidebar-${availableTab}`);
|
||||
button.addEventListener('command', () => {
|
||||
this.currentTab = availableTab;
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('TabSelect', this);
|
||||
|
||||
this.currentTab = 'workspaces'; // Default tab
|
||||
}
|
||||
|
||||
#getContentContainer(tab) {
|
||||
return this.querySelector(`#zen-library-content hbox[content="${tab}"]`);
|
||||
}
|
||||
|
||||
#createWorkspaceElement(workspace) {
|
||||
const fragment = window.MozXULElement.parseXULToFragment(`
|
||||
<vbox class="zen-workspace-item" zen-workspace-id="${workspace.uuid}">
|
||||
<hbox class="zen-workspace-item-header">
|
||||
<label class="zen-workspace-item-name"></label>
|
||||
</hbox>
|
||||
<vbox class="zen-workspace-item-content">
|
||||
</vbox>
|
||||
</vbox>
|
||||
`);
|
||||
|
||||
const workspaceLabel = fragment.querySelector('.zen-workspace-item-name');
|
||||
workspaceLabel.textContent = workspace.name;
|
||||
workspaceLabel.addEventListener(
|
||||
'click',
|
||||
gZenVerticalTabsManager.renameTabStart.bind(gZenVerticalTabsManager)
|
||||
);
|
||||
|
||||
const workspaceItem = fragment.querySelector('.zen-workspace-item');
|
||||
workspaceItem.style.setProperty(
|
||||
'--zen-workspace-gradient',
|
||||
gZenThemePicker.getGradient(workspace.theme.gradientColors, true, workspace.theme.rotation)
|
||||
);
|
||||
|
||||
// TODO: Not jet! Figure this out
|
||||
//const workspaceElement = gZenWorkspaces.workspaceElement(workspace.uuid);
|
||||
//fragment.querySelector('.zen-workspace-item-content').appendChild(workspaceElement);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
async onOpen(event) {
|
||||
const conatainer = this.#getContentContainer('workspaces');
|
||||
conatainer.innerHTML = ''; // Clear the container
|
||||
|
||||
const workspaces = await gZenWorkspaces._workspaces();
|
||||
for (const workspace of workspaces.workspaces) {
|
||||
const workspaceElement = this.#createWorkspaceElement(workspace);
|
||||
conatainer.appendChild(workspaceElement);
|
||||
}
|
||||
}
|
||||
|
||||
async onClose(event) {}
|
||||
|
||||
on_TabSelect(event) {
|
||||
if (!this.open) return;
|
||||
gZenLibrary.close();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('zen-library', ZenLibraryElement);
|
||||
|
||||
class ZenLibrary {
|
||||
#animating = false;
|
||||
|
||||
constructor() {
|
||||
ChromeUtils.defineLazyGetter(this, 'wrapper', () => document.getElementById('zen-library'));
|
||||
}
|
||||
|
||||
get isOpen() {
|
||||
return this.wrapper.hasAttribute('open');
|
||||
}
|
||||
|
||||
set isOpen(value) {
|
||||
if (this.#animating) {
|
||||
return; // Prevent multiple animations from running at the same time
|
||||
}
|
||||
this.#animating = true;
|
||||
if (value) {
|
||||
this.wrapper.open = value;
|
||||
this.animateLibrary(false).then(() => {
|
||||
this.#animating = false;
|
||||
});
|
||||
} else {
|
||||
this.animateLibrary(true).then(() => {
|
||||
this.wrapper.open = value;
|
||||
this.#animating = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
open() {
|
||||
this.isOpen = true;
|
||||
}
|
||||
|
||||
close() {
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.isOpen = !this.isOpen;
|
||||
}
|
||||
|
||||
async animateLibrary(open) {
|
||||
window.docShell.treeOwner
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIAppWindow)
|
||||
.rollupAllPopups();
|
||||
|
||||
let elementsToAnimate = [gNavToolbox];
|
||||
if (gZenVerticalTabsManager._hasSetSingleToolbar) {
|
||||
elementsToAnimate.push(gURLBar.textbox);
|
||||
}
|
||||
const wrapperWidth = this.wrapper.getBoundingClientRect().width;
|
||||
const appContentWrapper = document.getElementById('zen-appcontent-wrapper');
|
||||
if (open) {
|
||||
await Promise.all([
|
||||
gZenUIManager.motion.animate(
|
||||
elementsToAnimate,
|
||||
{
|
||||
transform: ['translateX(100%)', 'translateX(0)'],
|
||||
opacity: [0, 1],
|
||||
},
|
||||
{
|
||||
duration: 0.2,
|
||||
easing: 'ease-in-out',
|
||||
}
|
||||
),
|
||||
gZenUIManager.motion.animate(
|
||||
this.wrapper,
|
||||
{
|
||||
marginLeft: ['0px', `${-wrapperWidth}px`],
|
||||
transform: ['translateX(0)', 'translateX(100%)'],
|
||||
},
|
||||
{
|
||||
duration: 0.2,
|
||||
easing: 'ease-in-out',
|
||||
}
|
||||
),
|
||||
]);
|
||||
appContentWrapper.style.minWidth = ''; // Reset the min-width after the animation
|
||||
gNavToolbox.style.display = ''; // Hide the toolbox during the animation
|
||||
} else {
|
||||
appContentWrapper.style.minWidth = `${appContentWrapper.getBoundingClientRect().width}px`;
|
||||
await Promise.all([
|
||||
gZenUIManager.motion.animate(
|
||||
elementsToAnimate,
|
||||
{
|
||||
transform: ['translateX(0)', 'translateX(100%)'],
|
||||
opacity: [1, 0],
|
||||
},
|
||||
{
|
||||
duration: 0.2,
|
||||
easing: 'ease-in-out',
|
||||
}
|
||||
),
|
||||
gZenUIManager.motion.animate(
|
||||
this.wrapper,
|
||||
{
|
||||
marginLeft: [`${-wrapperWidth}px`, '0px'],
|
||||
transform: ['translateX(-100%)', 'translateX(0%)'],
|
||||
},
|
||||
{
|
||||
duration: 0.2,
|
||||
easing: 'ease-in-out',
|
||||
}
|
||||
),
|
||||
]);
|
||||
gNavToolbox.style.display = 'none'; // Show the toolbox after the animation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.gZenLibrary = new ZenLibrary();
|
||||
}
|
103
src/zen/library/zen-library.css
Normal file
103
src/zen/library/zen-library.css
Normal file
|
@ -0,0 +1,103 @@
|
|||
#zen-library {
|
||||
order: -1;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
position: fixed;
|
||||
left: -200%;
|
||||
|
||||
&[open='true'] {
|
||||
display: flex;
|
||||
pointer-events: all;
|
||||
position: relative;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#zen-library-sidebar {
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
padding: 0.6rem;
|
||||
box-shadow: var(--zen-big-shadow);
|
||||
-moz-window-dragging: drag;
|
||||
border-right: 1px solid var(--zen-colors-border);
|
||||
|
||||
#zen-library-sidebar-buttons {
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
& .zen-library-sidebar-button {
|
||||
transition: background-color 0.1s;
|
||||
padding: 0.8rem 0.7rem;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
appearance: none;
|
||||
gap: 0.5rem;
|
||||
border-radius: 6px !important;
|
||||
&:hover,
|
||||
&[active='true'] {
|
||||
background: light-dark(rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
}
|
||||
|
||||
#zen-library-sidebar-footer {
|
||||
justify-content: space-between;
|
||||
|
||||
& toolbarbutton {
|
||||
appearance: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#zen-library-content {
|
||||
transition: width 0.15s;
|
||||
width: 20vw;
|
||||
overflow-x: auto;
|
||||
|
||||
&[size='big'] {
|
||||
width: 60vw;
|
||||
}
|
||||
|
||||
& > * {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
& > [content='workspaces'] {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
padding: 6rem;
|
||||
|
||||
& .zen-workspace-item {
|
||||
width: 16rem;
|
||||
padding: 0.7rem;
|
||||
border-radius: var(--zen-border-radius);
|
||||
box-shadow: var(--zen-big-shadow);
|
||||
background: var(--zen-workspace-gradient);
|
||||
border: 1px solid light-dark(
|
||||
rgba(255, 255, 255, 0.2),
|
||||
rgba(0, 0, 0, 0.2)
|
||||
);
|
||||
height: 100%;
|
||||
|
||||
&::before {
|
||||
background-image: url(chrome://browser/content/zen-images/grain-bg.png);
|
||||
opacity: var(--zen-grainy-background-opacity, 0);
|
||||
mix-blend-mode: hard-light;
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
pointer-events: none;
|
||||
top: 50%;
|
||||
border-radius: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 1;
|
||||
content: '';
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -709,6 +709,7 @@
|
|||
|
||||
/* Hide text labels */
|
||||
& .zen-current-workspace-indicator-name,
|
||||
& .zen-workspace-actions,
|
||||
& zen-workspace .toolbarbutton-text {
|
||||
display: none !important;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
|
||||
initContextMenu() {
|
||||
const menu = window.MozXULElement.parseXULToFragment(`
|
||||
<menuitem id="zenToolbarThemePicker"
|
||||
<menuitem class="zenToolbarThemePicker"
|
||||
data-lazy-l10n-id="zen-workspaces-change-gradient"
|
||||
command="cmd_zenOpenZenThemePicker"/>
|
||||
`);
|
||||
|
@ -944,7 +944,10 @@
|
|||
return `rgba(${color.c[0]}, ${color.c[1]}, ${color.c[2]}, ${this.currentOpacity})`;
|
||||
}
|
||||
|
||||
getGradient(colors, forToolbar = false) {
|
||||
getGradient(colors, forToolbar = false, rotation = undefined) {
|
||||
if (typeof rotation === 'undefined') {
|
||||
rotation = this.currentRotation;
|
||||
}
|
||||
const themedColors = this.themedColors(colors);
|
||||
this.useAlgo = themedColors[0]?.algorithm ?? '';
|
||||
|
||||
|
@ -955,12 +958,12 @@
|
|||
} else if (themedColors.length === 1) {
|
||||
return this.getSingleRGBColor(themedColors[0], forToolbar);
|
||||
} else if (themedColors.length !== 3) {
|
||||
return `linear-gradient(${this.currentRotation}deg, ${themedColors.map((color) => this.getSingleRGBColor(color, forToolbar)).join(', ')})`;
|
||||
return `linear-gradient(${rotation}deg, ${themedColors.map((color) => this.getSingleRGBColor(color, forToolbar)).join(', ')})`;
|
||||
} else {
|
||||
let color1 = this.getSingleRGBColor(themedColors[2], forToolbar);
|
||||
let color2 = this.getSingleRGBColor(themedColors[0], forToolbar);
|
||||
let color3 = this.getSingleRGBColor(themedColors[1], forToolbar);
|
||||
return `linear-gradient(${this.currentRotation}deg, ${color1}, ${color2}, ${color3})`;
|
||||
return `linear-gradient(${rotation}deg, ${color1}, ${color2}, ${color3})`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1122,7 +1125,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
const appBackground = browser.document.getElementById('zen-browser-background');
|
||||
if (!skipUpdate) {
|
||||
browser.document.documentElement.style.setProperty(
|
||||
'--zen-main-browser-background-old',
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<vbox class="zen-workspace-tabs-section zen-current-workspace-indicator" flex="1">
|
||||
<hbox class="zen-current-workspace-indicator-icon"></hbox>
|
||||
<hbox class="zen-current-workspace-indicator-name"></hbox>
|
||||
<toolbarbutton class="toolbarbutton-1 chromeclass-toolbar-additional zen-workspaces-actions" context="zenWorkspaceMoreActions"></toolbarbutton>
|
||||
</vbox>
|
||||
<arrowscrollbox orient="vertical" tabindex="-1" class="workspace-arrowscrollbox">
|
||||
<vbox class="zen-workspace-tabs-section zen-workspace-pinned-tabs-section">
|
||||
|
@ -57,6 +58,13 @@
|
|||
false
|
||||
);
|
||||
|
||||
this.indicator.querySelector('.zen-current-workspace-indicator-name').onRenameFinished =
|
||||
this.onIndicatorRenameFinished.bind(this);
|
||||
|
||||
this.indicator
|
||||
.querySelector('.zen-workspaces-actions')
|
||||
.addEventListener('click', this.onActionsCommand.bind(this));
|
||||
|
||||
this.scrollbox.addEventListener('wheel', this, true);
|
||||
this.scrollbox.addEventListener('underflow', this);
|
||||
this.scrollbox.addEventListener('overflow', this);
|
||||
|
@ -168,6 +176,38 @@
|
|||
gBrowser.tabContainer.handleEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
get workspaceUuid() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
async onIndicatorRenameFinished(newName) {
|
||||
if (newName === '') {
|
||||
return;
|
||||
}
|
||||
let workspaces = (await gZenWorkspaces._workspaces()).workspaces;
|
||||
let workspaceData = workspaces.find((workspace) => workspace.uuid === this.workspaceUuid);
|
||||
workspaceData.name = newName;
|
||||
await gZenWorkspaces.saveWorkspace(workspaceData);
|
||||
this.indicator.querySelector('.zen-current-workspace-indicator-name').textContent = newName;
|
||||
gZenUIManager.showToast('zen-workspace-renamed-toast');
|
||||
}
|
||||
|
||||
onActionsCommand(event) {
|
||||
event.stopPropagation();
|
||||
const popup = document.getElementById('zenWorkspaceMoreActions');
|
||||
event.target.setAttribute('open', 'true');
|
||||
this.indicator.setAttribute('open', 'true');
|
||||
popup.addEventListener(
|
||||
'popuphidden',
|
||||
() => {
|
||||
event.target.removeAttribute('open');
|
||||
this.indicator.removeAttribute('open');
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
popup.openPopup(event.target, 'after_start');
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('zen-workspace', ZenWorkspace);
|
||||
|
|
|
@ -42,11 +42,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
this._resolveInitialized = resolve;
|
||||
});
|
||||
|
||||
workspaceIndicatorXUL = `
|
||||
<hbox class="zen-current-workspace-indicator-icon"></hbox>
|
||||
<hbox class="zen-current-workspace-indicator-name"></hbox>
|
||||
`;
|
||||
|
||||
async waitForPromises() {
|
||||
if (this.privateWindowOrDisabled) {
|
||||
return;
|
||||
|
@ -842,7 +837,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
|
||||
async initializeWorkspaces() {
|
||||
if (this.workspaceEnabled) {
|
||||
this._initializeWorkspaceCreationIcons();
|
||||
this._initializeWorkspaceTabContextMenus();
|
||||
await this.workspaceBookmarks();
|
||||
window.addEventListener('TabBrowserInserted', this.onTabBrowserInserted.bind(this));
|
||||
|
@ -1066,84 +1060,48 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
}
|
||||
|
||||
addPopupListeners() {
|
||||
const popup = document.getElementById('PanelUI-zen-workspaces');
|
||||
const contextMenu = document.getElementById('zenWorkspaceActionsMenu');
|
||||
const workspaceActions = document.getElementById('zenWorkspaceMoreActions');
|
||||
workspaceActions.addEventListener('popupshowing', this.updateWorkspaceActionsMenu.bind(this));
|
||||
|
||||
popup.addEventListener('popuphidden', this.handlePanelHidden.bind(this));
|
||||
popup.addEventListener('command', this.handlePanelCommand.bind(this));
|
||||
const contextChangeContainerTabMenu = document.getElementById(
|
||||
'context_zenWorkspacesOpenInContainerTab'
|
||||
);
|
||||
contextChangeContainerTabMenu.addEventListener(
|
||||
'popupshowing',
|
||||
this.updateWorkspaceActionsMenuContainer.bind(this)
|
||||
);
|
||||
contextChangeContainerTabMenu.addEventListener(
|
||||
'command',
|
||||
this.contextChangeContainerTab.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
contextMenu.addEventListener('popuphidden', (event) => {
|
||||
if (event.target === contextMenu) {
|
||||
this.onContextMenuClose(event);
|
||||
}
|
||||
updateWorkspaceActionsMenu(event) {
|
||||
if (event.target.id !== 'zenWorkspaceMoreActions') {
|
||||
return;
|
||||
}
|
||||
const openInContainerMenuItem = document.getElementById(
|
||||
'context_zenWorkspacesOpenInContainerTab'
|
||||
);
|
||||
if (this.shouldShowContainers) {
|
||||
openInContainerMenuItem.removeAttribute('hidden');
|
||||
} else {
|
||||
openInContainerMenuItem.setAttribute('hidden', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
updateWorkspaceActionsMenuContainer(event) {
|
||||
const workspace = this.getActiveWorkspaceFromCache();
|
||||
let containerTabId = workspace.containerTabId;
|
||||
return window.createUserContextMenu(event, {
|
||||
isContextMenu: true,
|
||||
excludeUserContextId: containerTabId,
|
||||
showDefaultTab: true,
|
||||
});
|
||||
contextMenu.addEventListener('popupshowing', this.updateContextMenu.bind(this));
|
||||
contextMenu.addEventListener('command', this.handleContextMenuCommand.bind(this));
|
||||
|
||||
const submenu = document.querySelector('#context_zenWorkspacesOpenInContainerTab > menupopup');
|
||||
if (submenu) {
|
||||
submenu.addEventListener('popupshowing', this.createContainerTabMenu.bind(this));
|
||||
submenu.addEventListener('command', this.contextChangeContainerTab.bind(this));
|
||||
}
|
||||
|
||||
const onWorkspaceIconContainerClick = this.onWorkspaceIconContainerClick.bind(this);
|
||||
for (const element of document.querySelectorAll('.PanelUI-zen-workspaces-icons-container')) {
|
||||
element.addEventListener('click', onWorkspaceIconContainerClick);
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById('PanelUI-zen-workspaces-create-input')
|
||||
.addEventListener('input', this.onWorkspaceCreationNameChange.bind(this));
|
||||
document
|
||||
.getElementById('PanelUI-zen-workspaces-edit-input')
|
||||
.addEventListener('input', this.onWorkspaceEditChange.bind(this));
|
||||
document
|
||||
.getElementById('PanelUI-zen-workspaces-icon-search-input')
|
||||
.addEventListener('input', this.conductSearch.bind(this));
|
||||
}
|
||||
|
||||
handlePanelCommand(event) {
|
||||
let target = event.target.closest('toolbarbutton');
|
||||
target ??= event.target.closest('button');
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
switch (target.id) {
|
||||
case 'PanelUI-zen-workspaces-reorder-mode':
|
||||
this.toggleReorderMode();
|
||||
break;
|
||||
case 'PanelUI-zen-workspaces-new':
|
||||
this.openSaveDialog();
|
||||
break;
|
||||
case 'PanelUI-zen-workspaces-create-save':
|
||||
this.saveWorkspaceFromCreate();
|
||||
break;
|
||||
case 'PanelUI-zen-workspaces-edit-cancel':
|
||||
case 'PanelUI-zen-workspaces-create-cancel':
|
||||
this.closeWorkspacesSubView();
|
||||
break;
|
||||
case 'PanelUI-zen-workspaces-edit-save':
|
||||
this.saveWorkspaceFromEdit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handleContextMenuCommand(event) {
|
||||
const target = event.target.closest('menuitem');
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
switch (target.id) {
|
||||
case 'context_zenOpenWorkspace':
|
||||
this.openWorkspace();
|
||||
break;
|
||||
case 'context_zenEditWorkspace':
|
||||
this.contextEdit(event);
|
||||
break;
|
||||
case 'context_zenDeleteWorkspace':
|
||||
this.contextDelete(event);
|
||||
break;
|
||||
}
|
||||
async contextDeleteWorkspace() {
|
||||
await this.removeWorkspace(this.activeWorkspace, true);
|
||||
}
|
||||
|
||||
searchIcons(input, icons) {
|
||||
|
@ -1207,69 +1165,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
return filteredEmojiScores.map((score) => score.emoji);
|
||||
}
|
||||
|
||||
resetWorkspaceIconSearch() {
|
||||
let container = document.getElementById('PanelUI-zen-workspaces-icon-picker-wrapper');
|
||||
let searchInput = document.getElementById('PanelUI-zen-workspaces-icon-search-input');
|
||||
|
||||
// Clear the search input field
|
||||
searchInput.value = '';
|
||||
for (let button of container.querySelectorAll('.toolbarbutton-1')) {
|
||||
button.style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
_initializeWorkspaceCreationIcons() {
|
||||
let container = document.getElementById('PanelUI-zen-workspaces-icon-picker-wrapper');
|
||||
let searchInput = document.getElementById('PanelUI-zen-workspaces-icon-search-input');
|
||||
searchInput.value = '';
|
||||
for (let iconData of this.emojis) {
|
||||
const icon = iconData[0];
|
||||
let button = document.createXULElement('toolbarbutton');
|
||||
button.className = 'toolbarbutton-1 workspace-icon-button';
|
||||
button.setAttribute('label', icon);
|
||||
button.onclick = (event) => {
|
||||
const button = event.target;
|
||||
let wasSelected = button.hasAttribute('selected');
|
||||
for (let button of container.children) {
|
||||
button.removeAttribute('selected');
|
||||
}
|
||||
if (!wasSelected) {
|
||||
button.setAttribute('selected', 'true');
|
||||
}
|
||||
if (this.onIconChangeConnectedCallback) {
|
||||
this.onIconChangeConnectedCallback(icon);
|
||||
} else {
|
||||
this.onWorkspaceIconChangeInner('create', icon);
|
||||
}
|
||||
};
|
||||
container.appendChild(button);
|
||||
}
|
||||
}
|
||||
|
||||
conductSearch() {
|
||||
const container = document.getElementById('PanelUI-zen-workspaces-icon-picker-wrapper');
|
||||
const searchInput = document.getElementById('PanelUI-zen-workspaces-icon-search-input');
|
||||
const query = searchInput.value.toLowerCase();
|
||||
|
||||
if (query === '') {
|
||||
this.resetWorkspaceIconSearch();
|
||||
return;
|
||||
}
|
||||
|
||||
const buttons = Array.from(container.querySelectorAll('.toolbarbutton-1'));
|
||||
buttons.forEach((button) => (button.style.display = 'none'));
|
||||
|
||||
const filteredIcons = this.searchIcons(query, this.emojis);
|
||||
|
||||
filteredIcons.forEach((emoji) => {
|
||||
const matchingButton = buttons.find((button) => button.getAttribute('label') === emoji);
|
||||
if (matchingButton) {
|
||||
matchingButton.style.display = '';
|
||||
container.appendChild(matchingButton);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async saveWorkspace(workspaceData, preventPropagation = false) {
|
||||
if (this.privateWindowOrDisabled) {
|
||||
return;
|
||||
|
@ -1316,83 +1211,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
);
|
||||
}
|
||||
// Workspaces dialog UI management
|
||||
|
||||
openSaveDialog() {
|
||||
let parentPanel = document.getElementById('PanelUI-zen-workspaces-multiview');
|
||||
|
||||
// randomly select an icon
|
||||
let icon = this.emojis[Math.floor(Math.random() * (this.emojis.length - 257))][0];
|
||||
this._workspaceCreateInput.textContent = '';
|
||||
this._workspaceCreateInput.value = '';
|
||||
this._workspaceCreateInput.setAttribute('data-initial-value', '');
|
||||
document
|
||||
.querySelectorAll('#PanelUI-zen-workspaces-icon-picker-wrapper toolbarbutton')
|
||||
.forEach((button) => {
|
||||
if (button.label === icon) {
|
||||
button.setAttribute('selected', 'true');
|
||||
} else {
|
||||
button.removeAttribute('selected');
|
||||
}
|
||||
});
|
||||
document.querySelector('.PanelUI-zen-workspaces-icons-container.create').textContent = icon;
|
||||
|
||||
PanelUI.showSubView('PanelUI-zen-workspaces-create', parentPanel);
|
||||
}
|
||||
|
||||
async openEditDialog(workspaceUuid) {
|
||||
this._workspaceEditDialog.setAttribute('data-workspace-uuid', workspaceUuid);
|
||||
document.getElementById('PanelUI-zen-workspaces-edit-save').setAttribute('disabled', 'true');
|
||||
let workspaces = (await this._workspaces()).workspaces;
|
||||
let workspaceData = workspaces.find((workspace) => workspace.uuid === workspaceUuid);
|
||||
this._workspaceEditInput.textContent = workspaceData.name;
|
||||
this._workspaceEditInput.value = workspaceData.name;
|
||||
this._workspaceEditInput.setAttribute('data-initial-value', workspaceData.name);
|
||||
this._workspaceEditIconsContainer.setAttribute('data-initial-value', workspaceData.icon);
|
||||
this.onIconChangeConnectedCallback = (...args) => {
|
||||
this.onWorkspaceIconChangeInner('edit', ...args);
|
||||
this.onWorkspaceEditChange(...args);
|
||||
};
|
||||
document
|
||||
.querySelectorAll('#PanelUI-zen-workspaces-icon-picker-wrapper toolbarbutton')
|
||||
.forEach((button) => {
|
||||
if (button.label === workspaceData.icon) {
|
||||
button.setAttribute('selected', 'true');
|
||||
} else {
|
||||
button.removeAttribute('selected');
|
||||
}
|
||||
});
|
||||
document.querySelector('.PanelUI-zen-workspaces-icons-container.edit').textContent =
|
||||
this.getWorkspaceIcon(workspaceData);
|
||||
let parentPanel = document.getElementById('PanelUI-zen-workspaces-multiview');
|
||||
PanelUI.showSubView('PanelUI-zen-workspaces-edit', parentPanel);
|
||||
}
|
||||
|
||||
onWorkspaceIconChangeInner(type = 'create', icon) {
|
||||
const container = document.querySelector(`.PanelUI-zen-workspaces-icons-container.${type}`);
|
||||
if (container.textContent !== icon) {
|
||||
container.textContent = icon;
|
||||
}
|
||||
this.goToPreviousSubView();
|
||||
}
|
||||
|
||||
onWorkspaceIconContainerClick(event) {
|
||||
event.preventDefault();
|
||||
const parentPanel = document.getElementById('PanelUI-zen-workspaces-edit');
|
||||
PanelUI.showSubView('PanelUI-zen-workspaces-icon-picker', parentPanel);
|
||||
|
||||
const container = parentPanel.parentNode.querySelector('.panel-viewcontainer');
|
||||
setTimeout(() => {
|
||||
if (container) {
|
||||
container.style.minHeight = 'unset';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
goToPreviousSubView() {
|
||||
const parentPanel = document.getElementById('PanelUI-zen-workspaces-multiview');
|
||||
parentPanel.goBack();
|
||||
}
|
||||
|
||||
workspaceHasIcon(workspace) {
|
||||
return workspace.icon && workspace.icon !== '';
|
||||
}
|
||||
|
@ -1426,230 +1244,15 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
return;
|
||||
}
|
||||
|
||||
let workspaceList = browser.document.getElementById('PanelUI-zen-workspaces-list');
|
||||
const createWorkspaceElement = (workspace) => {
|
||||
let element = browser.document.createXULElement('toolbarbutton');
|
||||
element.className = 'subviewbutton zen-workspace-button';
|
||||
element.setAttribute('tooltiptext', workspace.name);
|
||||
element.setAttribute('zen-workspace-id', workspace.uuid);
|
||||
if (this.isWorkspaceActive(workspace)) {
|
||||
element.setAttribute('active', 'true');
|
||||
}
|
||||
let containerGroup = undefined;
|
||||
try {
|
||||
containerGroup = browser.ContextualIdentityService.getPublicIdentities().find(
|
||||
(container) => container.userContextId === workspace.containerTabId
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn('gZenWorkspaces: Error setting container color', e);
|
||||
}
|
||||
if (containerGroup) {
|
||||
element.classList.add('identity-color-' + containerGroup.color);
|
||||
element.setAttribute('data-usercontextid', containerGroup.userContextId);
|
||||
}
|
||||
// Set draggable attribute based on reorder mode
|
||||
if (this.isReorderModeOn(browser)) {
|
||||
element.setAttribute('draggable', 'true');
|
||||
}
|
||||
element.addEventListener(
|
||||
'dragstart',
|
||||
function (event) {
|
||||
if (this.isReorderModeOn(browser)) {
|
||||
this.draggedElement = element;
|
||||
event.dataTransfer.effectAllowed = 'move';
|
||||
event.dataTransfer.setData('text/plain', element.getAttribute('zen-workspace-id'));
|
||||
|
||||
// Create a transparent drag image for Linux
|
||||
if (AppConstants.platform === 'linux') {
|
||||
const dragImage = document.createElement('canvas');
|
||||
dragImage.width = 1;
|
||||
dragImage.height = 1;
|
||||
event.dataTransfer.setDragImage(dragImage, 0, 0);
|
||||
}
|
||||
|
||||
element.classList.add('dragging');
|
||||
} else {
|
||||
event.preventDefault();
|
||||
}
|
||||
}.bind(browser.gZenWorkspaces)
|
||||
);
|
||||
|
||||
element.addEventListener(
|
||||
'dragover',
|
||||
function (event) {
|
||||
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
|
||||
// Ensure the dragover effect is visible on Linux
|
||||
if (AppConstants.platform === 'linux') {
|
||||
const targetId = element.getAttribute('zen-workspace-id');
|
||||
const draggedId = this.draggedElement.getAttribute('zen-workspace-id');
|
||||
if (targetId !== draggedId) {
|
||||
element.classList.add('dragover');
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bind(browser.gZenWorkspaces)
|
||||
);
|
||||
|
||||
element.addEventListener('dragenter', function (event) {
|
||||
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
||||
element.classList.add('dragover');
|
||||
}
|
||||
});
|
||||
|
||||
element.addEventListener('dragleave', function (event) {
|
||||
element.classList.remove('dragover');
|
||||
});
|
||||
|
||||
element.addEventListener(
|
||||
'drop',
|
||||
async function (event) {
|
||||
event.preventDefault();
|
||||
element.classList.remove('dragover');
|
||||
if (this.isReorderModeOn(browser)) {
|
||||
const draggedWorkspaceId = event.dataTransfer.getData('text/plain');
|
||||
const targetWorkspaceId = element.getAttribute('zen-workspace-id');
|
||||
if (draggedWorkspaceId !== targetWorkspaceId) {
|
||||
await this.moveWorkspace(draggedWorkspaceId, targetWorkspaceId);
|
||||
}
|
||||
if (this.draggedElement) {
|
||||
this.draggedElement.classList.remove('dragging');
|
||||
this.draggedElement = null;
|
||||
}
|
||||
}
|
||||
}.bind(browser.gZenWorkspaces)
|
||||
);
|
||||
|
||||
element.addEventListener(
|
||||
'dragend',
|
||||
function (event) {
|
||||
if (this.draggedElement) {
|
||||
this.draggedElement.classList.remove('dragging');
|
||||
this.draggedElement = null;
|
||||
}
|
||||
const workspaceElements = browser.document.querySelectorAll('.zen-workspace-button');
|
||||
for (const elem of workspaceElements) {
|
||||
elem.classList.remove('dragover');
|
||||
}
|
||||
}.bind(browser.gZenWorkspaces)
|
||||
);
|
||||
|
||||
let childs = browser.MozXULElement.parseXULToFragment(`
|
||||
<div class="zen-workspace-icon">
|
||||
</div>
|
||||
<vbox>
|
||||
<div class="zen-workspace-name">
|
||||
</div>
|
||||
<div class="zen-workspace-container" ${containerGroup ? '' : 'hidden="true"'}>
|
||||
</div>
|
||||
</vbox>
|
||||
<image class="toolbarbutton-icon zen-workspace-actions-reorder-icon" ></image>
|
||||
<toolbarbutton closemenu="none" class="toolbarbutton-1 zen-workspace-actions">
|
||||
<image class="toolbarbutton-icon" id="zen-workspace-actions-menu-icon"></image>
|
||||
</toolbarbutton>
|
||||
`);
|
||||
|
||||
// use text content instead of innerHTML to avoid XSS
|
||||
childs.querySelector('.zen-workspace-icon').textContent =
|
||||
browser.gZenWorkspaces.getWorkspaceIcon(workspace);
|
||||
childs.querySelector('.zen-workspace-name').textContent = workspace.name;
|
||||
if (containerGroup) {
|
||||
childs.querySelector('.zen-workspace-container').textContent =
|
||||
ContextualIdentityService.getUserContextLabel(containerGroup.userContextId);
|
||||
}
|
||||
|
||||
childs.querySelector('.zen-workspace-actions').addEventListener(
|
||||
'command',
|
||||
((event) => {
|
||||
let button = event.target;
|
||||
this._contextMenuId = button
|
||||
.closest('toolbarbutton[zen-workspace-id]')
|
||||
.getAttribute('zen-workspace-id');
|
||||
const popup = button.ownerDocument.getElementById('zenWorkspaceActionsMenu');
|
||||
popup.openPopup(button, 'after_end');
|
||||
}).bind(browser.gZenWorkspaces)
|
||||
);
|
||||
element.appendChild(childs);
|
||||
element.onclick = (async () => {
|
||||
if (this.isReorderModeOn(browser)) {
|
||||
return; // Return early if reorder mode is on
|
||||
}
|
||||
if (event.target.closest('.zen-workspace-actions')) {
|
||||
return; // Ignore clicks on the actions button
|
||||
}
|
||||
const workspaceId = element.getAttribute('zen-workspace-id');
|
||||
const workspaces = await this._workspaces();
|
||||
const workspace = workspaces.workspaces.find((w) => w.uuid === workspaceId);
|
||||
await this.changeWorkspace(workspace);
|
||||
let panel = this.ownerWindow.document.getElementById('PanelUI-zen-workspaces');
|
||||
PanelMultiView.hidePopup(panel);
|
||||
}).bind(browser.gZenWorkspaces);
|
||||
return element;
|
||||
};
|
||||
|
||||
const createLastPositionDropTarget = () => {
|
||||
const element = browser.document.createXULElement('div');
|
||||
element.className = 'zen-workspace-last-place-drop-target';
|
||||
|
||||
element.addEventListener(
|
||||
'dragover',
|
||||
function (event) {
|
||||
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
|
||||
// Ensure the dragover effect is visible on Linux
|
||||
if (AppConstants.platform === 'linux') {
|
||||
element.classList.add('dragover');
|
||||
}
|
||||
}
|
||||
}.bind(browser.gZenWorkspaces)
|
||||
);
|
||||
|
||||
element.addEventListener(
|
||||
'dragenter',
|
||||
function (event) {
|
||||
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
||||
element.classList.add('dragover');
|
||||
}
|
||||
}.bind(browser.gZenWorkspaces)
|
||||
);
|
||||
|
||||
element.addEventListener(
|
||||
'dragleave',
|
||||
function (event) {
|
||||
element.classList.remove('dragover');
|
||||
}.bind(browser.gZenWorkspaces)
|
||||
);
|
||||
|
||||
element.addEventListener(
|
||||
'drop',
|
||||
async function (event) {
|
||||
event.preventDefault();
|
||||
element.classList.remove('dragover');
|
||||
|
||||
if (this.isReorderModeOn(browser)) {
|
||||
const draggedWorkspaceId = event.dataTransfer.getData('text/plain');
|
||||
await this.moveWorkspaceToEnd(draggedWorkspaceId);
|
||||
|
||||
if (this.draggedElement) {
|
||||
this.draggedElement.classList.remove('dragging');
|
||||
this.draggedElement = null;
|
||||
}
|
||||
}
|
||||
}.bind(browser.gZenWorkspaces)
|
||||
);
|
||||
|
||||
return element;
|
||||
};
|
||||
|
||||
if (clearCache) {
|
||||
browser.gZenWorkspaces._workspaceCache = null;
|
||||
browser.gZenWorkspaces._workspaceBookmarksCache = null;
|
||||
await browser.gZenWorkspaces.workspaceBookmarks();
|
||||
}
|
||||
let workspaces = await browser.gZenWorkspaces._workspaces();
|
||||
browser.document
|
||||
.getElementById('cmd_zenCtxDeleteWorkspace')
|
||||
.setAttribute('disabled', workspaces.workspaces.length <= 1);
|
||||
if (clearCache) {
|
||||
browser.dispatchEvent(
|
||||
new CustomEvent('ZenWorkspacesUIUpdate', {
|
||||
|
@ -1658,39 +1261,12 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
})
|
||||
);
|
||||
}
|
||||
await browser.gZenWorkspaces.workspaceBookmarks();
|
||||
workspaceList.innerHTML = '';
|
||||
workspaceList.parentNode.style.display = 'flex';
|
||||
if (workspaces.workspaces.length <= 0) {
|
||||
workspaceList.innerHTML = 'No workspaces available';
|
||||
workspaceList.setAttribute('empty', 'true');
|
||||
} else {
|
||||
workspaceList.removeAttribute('empty');
|
||||
}
|
||||
|
||||
for (let workspace of workspaces.workspaces) {
|
||||
let workspaceElement = createWorkspaceElement(workspace);
|
||||
workspaceList.appendChild(workspaceElement);
|
||||
}
|
||||
|
||||
workspaceList.appendChild(createLastPositionDropTarget());
|
||||
|
||||
if (!ignoreStrip) {
|
||||
browser.gZenWorkspaces._fixIndicatorsNames(workspaces);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
handlePanelHidden() {
|
||||
const workspacesList = document.getElementById('PanelUI-zen-workspaces-list');
|
||||
const reorderModeButton = document.getElementById('PanelUI-zen-workspaces-reorder-mode');
|
||||
|
||||
workspacesList?.removeAttribute('reorder-mode');
|
||||
reorderModeButton?.removeAttribute('active');
|
||||
this.resetWorkspaceIconSearch();
|
||||
this.clearEmojis();
|
||||
}
|
||||
|
||||
async moveWorkspaceToEnd(draggedWorkspaceId) {
|
||||
const workspaces = (await this._workspaces()).workspaces;
|
||||
const draggedIndex = workspaces.findIndex((w) => w.uuid === draggedWorkspaceId);
|
||||
|
@ -1701,39 +1277,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
await this._propagateWorkspaceData();
|
||||
}
|
||||
|
||||
isReorderModeOn(browser) {
|
||||
return (
|
||||
browser.document
|
||||
.getElementById('PanelUI-zen-workspaces-list')
|
||||
.getAttribute('reorder-mode') === 'true'
|
||||
);
|
||||
}
|
||||
|
||||
toggleReorderMode() {
|
||||
const workspacesList = document.getElementById('PanelUI-zen-workspaces-list');
|
||||
const reorderModeButton = document.getElementById('PanelUI-zen-workspaces-reorder-mode');
|
||||
const isActive = workspacesList.getAttribute('reorder-mode') === 'true';
|
||||
if (isActive) {
|
||||
workspacesList.removeAttribute('reorder-mode');
|
||||
reorderModeButton.removeAttribute('active');
|
||||
} else {
|
||||
workspacesList.setAttribute('reorder-mode', 'true');
|
||||
reorderModeButton.setAttribute('active', 'true');
|
||||
}
|
||||
|
||||
// Update draggable attribute
|
||||
const workspaceElements = document.querySelectorAll('.zen-workspace-button');
|
||||
workspaceElements.forEach((elem) => {
|
||||
// When reorder mode is toggled off, remove draggable attribute
|
||||
// When reorder mode is toggled on, set draggable attribute
|
||||
if (isActive) {
|
||||
elem.removeAttribute('draggable');
|
||||
} else {
|
||||
elem.setAttribute('draggable', 'true');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async moveWorkspace(draggedWorkspaceId, targetWorkspaceId) {
|
||||
const workspaces = (await this._workspaces()).workspaces;
|
||||
const draggedIndex = workspaces.findIndex((w) => w.uuid === draggedWorkspaceId);
|
||||
|
@ -1745,45 +1288,8 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
await this._propagateWorkspaceData();
|
||||
}
|
||||
|
||||
async openWorkspacesDialog(event) {
|
||||
if (!this.workspaceEnabled || this.isPrivateWindow) {
|
||||
return;
|
||||
}
|
||||
let target = event.target.closest('.zen-current-workspace-indicator');
|
||||
let panel = document.getElementById('PanelUI-zen-workspaces');
|
||||
await this._propagateWorkspaceData({
|
||||
ignoreStrip: true,
|
||||
clearCache: false,
|
||||
});
|
||||
PanelMultiView.openPopup(panel, target, {
|
||||
position: 'bottomright topright',
|
||||
triggerEvent: event,
|
||||
}).catch(console.error);
|
||||
}
|
||||
|
||||
closeWorkspacesSubView() {
|
||||
let parentPanel = document.getElementById('PanelUI-zen-workspaces-multiview');
|
||||
parentPanel.goBack(parentPanel);
|
||||
}
|
||||
|
||||
// Workspaces management
|
||||
|
||||
get _workspaceCreateInput() {
|
||||
return document.getElementById('PanelUI-zen-workspaces-create-input');
|
||||
}
|
||||
|
||||
get _workspaceEditDialog() {
|
||||
return document.getElementById('PanelUI-zen-workspaces-edit');
|
||||
}
|
||||
|
||||
get _workspaceEditInput() {
|
||||
return document.getElementById('PanelUI-zen-workspaces-edit-input');
|
||||
}
|
||||
|
||||
get _workspaceEditIconsContainer() {
|
||||
return document.getElementById('PanelUI-zen-workspaces-icon-picker');
|
||||
}
|
||||
|
||||
_deleteAllTabsInWorkspace(workspaceID) {
|
||||
gBrowser.removeTabs(
|
||||
Array.from(this.allStoredTabs).filter(
|
||||
|
@ -1849,57 +1355,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
}
|
||||
}
|
||||
|
||||
async saveWorkspaceFromCreate() {
|
||||
let workspaceName = this._workspaceCreateInput.value;
|
||||
if (!workspaceName) {
|
||||
return;
|
||||
}
|
||||
this._workspaceCreateInput.value = '';
|
||||
let icon = document.querySelector('#PanelUI-zen-workspaces-icon-picker-wrapper [selected]');
|
||||
icon?.removeAttribute('selected');
|
||||
await this.createAndSaveWorkspace(workspaceName, icon?.label);
|
||||
this.goToPreviousSubView();
|
||||
}
|
||||
|
||||
async saveWorkspaceFromEdit() {
|
||||
let workspaceUuid = this._workspaceEditDialog.getAttribute('data-workspace-uuid');
|
||||
let workspaceName = this._workspaceEditInput.value;
|
||||
if (!workspaceName) {
|
||||
return;
|
||||
}
|
||||
this._workspaceEditInput.value = '';
|
||||
let icon = document.querySelector('#PanelUI-zen-workspaces-icon-picker-wrapper [selected]');
|
||||
icon?.removeAttribute('selected');
|
||||
let workspaces = (await this._workspaces()).workspaces;
|
||||
let workspaceData = workspaces.find((workspace) => workspace.uuid === workspaceUuid);
|
||||
workspaceData.name = workspaceName;
|
||||
workspaceData.icon = icon?.label;
|
||||
await this.saveWorkspace(workspaceData);
|
||||
this.goToPreviousSubView();
|
||||
}
|
||||
|
||||
onWorkspaceCreationNameChange() {
|
||||
let button = document.getElementById('PanelUI-zen-workspaces-create-save');
|
||||
if (this._workspaceCreateInput.value === '') {
|
||||
button.setAttribute('disabled', 'true');
|
||||
return;
|
||||
}
|
||||
button.removeAttribute('disabled');
|
||||
}
|
||||
|
||||
onWorkspaceEditChange(icon) {
|
||||
let button = document.getElementById('PanelUI-zen-workspaces-edit-save');
|
||||
let name = this._workspaceEditInput.value;
|
||||
if (
|
||||
name === this._workspaceEditInput.getAttribute('data-initial-value') &&
|
||||
icon === this._workspaceEditIconsContainer.getAttribute('data-initial-value')
|
||||
) {
|
||||
button.setAttribute('disabled', 'true');
|
||||
return;
|
||||
}
|
||||
button.removeAttribute('disabled');
|
||||
}
|
||||
|
||||
addChangeListeners(func) {
|
||||
if (!this._changeListeners) {
|
||||
this._changeListeners = [];
|
||||
|
@ -2810,49 +2265,9 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
}
|
||||
}
|
||||
|
||||
// Context menu management
|
||||
|
||||
_contextMenuId = null;
|
||||
async updateContextMenu(_) {
|
||||
console.assert(this._contextMenuId, 'No context menu ID set');
|
||||
document
|
||||
.querySelector(
|
||||
`#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`
|
||||
)
|
||||
.setAttribute('active', 'true');
|
||||
const workspaces = await this._workspaces();
|
||||
let deleteMenuItem = document.getElementById('context_zenDeleteWorkspace');
|
||||
if (workspaces.workspaces.length <= 1) {
|
||||
deleteMenuItem.setAttribute('disabled', 'true');
|
||||
} else {
|
||||
deleteMenuItem.removeAttribute('disabled');
|
||||
}
|
||||
let openMenuItem = document.getElementById('context_zenOpenWorkspace');
|
||||
if (
|
||||
workspaces.workspaces.find(
|
||||
(workspace) => workspace.uuid === this._contextMenuId && this.isWorkspaceActive(workspace)
|
||||
)
|
||||
) {
|
||||
openMenuItem.setAttribute('disabled', 'true');
|
||||
} else {
|
||||
openMenuItem.removeAttribute('disabled');
|
||||
}
|
||||
const openInContainerMenuItem = document.getElementById(
|
||||
'context_zenWorkspacesOpenInContainerTab'
|
||||
);
|
||||
if (this.shouldShowContainers) {
|
||||
openInContainerMenuItem.removeAttribute('hidden');
|
||||
} else {
|
||||
openInContainerMenuItem.setAttribute('hidden', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
async contextChangeContainerTab(event) {
|
||||
this._organizingWorkspaceStrip = true;
|
||||
let workspaces = await this._workspaces();
|
||||
let workspace = workspaces.workspaces.find(
|
||||
(workspace) => workspace.uuid === this._contextMenuId
|
||||
);
|
||||
let workspace = await this.getActiveWorkspace();
|
||||
let userContextId = parseInt(event.target.getAttribute('data-usercontextid'));
|
||||
workspace.containerTabId = userContextId + 0; // +0 to convert to number
|
||||
await this.saveWorkspace(workspace);
|
||||
|
@ -2865,16 +2280,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
}, 0);
|
||||
}
|
||||
|
||||
onContextMenuClose() {
|
||||
let target = document.querySelector(
|
||||
`#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`
|
||||
);
|
||||
if (target) {
|
||||
target.removeAttribute('active');
|
||||
}
|
||||
this._contextMenuId = null;
|
||||
}
|
||||
|
||||
findTabToBlur(tab) {
|
||||
if ((!this._shouldChangeToTab(tab) || !tab) && this._emptyTab) {
|
||||
return this._emptyTab;
|
||||
|
@ -2882,26 +2287,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
return tab;
|
||||
}
|
||||
|
||||
async openWorkspace() {
|
||||
let workspaces = await this._workspaces();
|
||||
let workspace = workspaces.workspaces.find(
|
||||
(workspace) => workspace.uuid === this._contextMenuId
|
||||
);
|
||||
await this.changeWorkspace(workspace);
|
||||
}
|
||||
|
||||
async contextDelete(event) {
|
||||
this.__contextIsDelete = true;
|
||||
event.stopPropagation();
|
||||
await this.removeWorkspace(this._contextMenuId);
|
||||
this.__contextIsDelete = false;
|
||||
}
|
||||
|
||||
async contextEdit(event) {
|
||||
event.stopPropagation();
|
||||
await this.openEditDialog(this._contextMenuId);
|
||||
}
|
||||
|
||||
get emojis() {
|
||||
if (this._emojis) {
|
||||
return this._emojis;
|
||||
|
@ -2941,6 +2326,9 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
}
|
||||
|
||||
_initializeWorkspaceTabContextMenus() {
|
||||
if (this.privateWindowOrDisabled) {
|
||||
return;
|
||||
}
|
||||
const menu = document.createXULElement('menu');
|
||||
menu.setAttribute('id', 'context-zen-change-workspace-tab');
|
||||
menu.setAttribute('data-l10n-id', 'context-zen-change-workspace-tab');
|
||||
|
@ -2977,18 +2365,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
);
|
||||
}
|
||||
|
||||
// Tab browser utilities
|
||||
createContainerTabMenu(event) {
|
||||
let window = event.target.ownerGlobal;
|
||||
const workspace = this.getWorkspaceFromId(this._contextMenuId);
|
||||
let containerTabId = workspace.containerTabId;
|
||||
return window.createUserContextMenu(event, {
|
||||
isContextMenu: true,
|
||||
excludeUserContextId: containerTabId,
|
||||
showDefaultTab: true,
|
||||
});
|
||||
}
|
||||
|
||||
getContextIdIfNeeded(userContextId, fromExternal, allowInheritPrincipal) {
|
||||
if (!this.workspaceEnabled) {
|
||||
return [userContextId, false, undefined];
|
||||
|
|
|
@ -122,327 +122,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* Workspaces Panel UI */
|
||||
|
||||
#PanelUI-zen-workspaces {
|
||||
--panel-width: 320px;
|
||||
--panel-padding: 0;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces > panelmultiview {
|
||||
align-items: flex-start;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces panelmultiview panelview {
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
width: var(--panel-width);
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-icon-picker toolbarbutton {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-icon-picker toolbarbutton[selected='true'] {
|
||||
border-color: var(--zen-colors-secondary);
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-icon-picker toolbarbutton .toolbarbutton-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-icon-picker toolbarbutton .toolbarbutton-text {
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-icon-picker {
|
||||
padding: 5px !important;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-icon-picker-wrapper {
|
||||
overflow-x: hidden;
|
||||
justify-items: center;
|
||||
overflow-y: auto;
|
||||
|
||||
display: flex;
|
||||
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
justify-content: space-between;
|
||||
align-content: space-between;
|
||||
max-height: 250px;
|
||||
|
||||
.workspace-icon-button {
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
font-size: 16px;
|
||||
margin: 2px;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-list[empty='true'] {
|
||||
font-weight: 600;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
text-align: start;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.PanelUI-zen-workspaces-user-create {
|
||||
height: 100%;
|
||||
|
||||
.PanelUI-zen-workspaces-creation-wraper {
|
||||
border-radius: 5px;
|
||||
border: 1px solid var(--zen-colors-border);
|
||||
|
||||
margin-top: 10px;
|
||||
|
||||
& .PanelUI-zen-workspaces-icons-container {
|
||||
padding: 10px 0;
|
||||
min-width: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-right: 1px solid var(--zen-colors-border);
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
& html|input {
|
||||
border: none;
|
||||
outline: none !important;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Workspace icon picker styles */
|
||||
#PanelUI-zen-workspaces-icon-picker-wrapper {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-icon-search-bar {
|
||||
display: flex;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: inherit;
|
||||
z-index: 1000;
|
||||
padding: 8px;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-icon-search-input {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
font-size: 14px;
|
||||
border: 1px solid var(--panel-separator-color, #ccc);
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-list toolbarbutton {
|
||||
padding: 5px;
|
||||
border-radius: var(--zen-button-border-radius);
|
||||
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
& .zen-workspace-icon {
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: var(--zen-button-border-radius);
|
||||
margin-right: 10px;
|
||||
border: 1px solid var(--zen-colors-border);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&[data-usercontextid] .zen-workspace-icon {
|
||||
border-color: color-mix(in srgb, var(--identity-tab-color) 40%, transparent 60%);
|
||||
}
|
||||
|
||||
& > vbox:has(> .zen-workspace-name) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
& .zen-workspace-name {
|
||||
font-weight: 600;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
& .zen-workspace-container {
|
||||
font-size: 12px;
|
||||
opacity: 0.5;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
& .zen-workspace-actions,
|
||||
.zen-workspace-actions-reorder-icon {
|
||||
display: none;
|
||||
margin: 0;
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
&.zen-workspace-button[active='true'] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&.zen-workspace-button[active='true'] .zen-workspace-icon::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
left: -2px;
|
||||
width: 2px;
|
||||
height: 16px;
|
||||
background-color: var(--toolbarbutton-icon-fill-attention);
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.zen-workspace-button.dragging {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.zen-workspace-button.dragover::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background-color: var(--toolbarbutton-icon-fill-attention);
|
||||
}
|
||||
|
||||
/* Enhanced visual feedback for Linux platform */
|
||||
@supports (-moz-gtk-csd-available) {
|
||||
.zen-workspace-button.dragover {
|
||||
background-color: color-mix(in srgb, var(--toolbarbutton-icon-fill-attention) 15%, transparent);
|
||||
}
|
||||
|
||||
.zen-workspace-button.dragover::after {
|
||||
height: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.zen-workspace-last-place-drop-target.dragover {
|
||||
background-color: var(--toolbarbutton-icon-fill-attention);
|
||||
}
|
||||
|
||||
/* Enhanced visual feedback for Linux platform */
|
||||
@supports (-moz-gtk-csd-available) {
|
||||
.zen-workspace-last-place-drop-target {
|
||||
height: 6px;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.zen-workspace-last-place-drop-target.dragover {
|
||||
background-color: var(--toolbarbutton-icon-fill-attention);
|
||||
box-shadow: 0 0 4px var(--toolbarbutton-icon-fill-attention);
|
||||
}
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-reorder-mode[active='true'] {
|
||||
color: var(--toolbarbutton-icon-fill-attention) !important;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-list:not([reorder-mode='true']) toolbarbutton {
|
||||
&:hover .zen-workspace-actions,
|
||||
& .zen-workspace-actions[active='true'] {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-list[reorder-mode='true'] toolbarbutton {
|
||||
.zen-workspace-actions-reorder-icon {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-list[reorder-mode='true'] .zen-workspace-last-place-drop-target {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.zen-workspace-last-place-drop-target {
|
||||
display: none;
|
||||
height: 4px;
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-view > vbox:nth-child(2) {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-new,
|
||||
#PanelUI-zen-workspaces-reorder-mode,
|
||||
#PanelUI-zen-gradient-generator-color-custom-add {
|
||||
min-height: 1px !important;
|
||||
padding: 3px;
|
||||
border-radius: 4px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-create-footer,
|
||||
#PanelUI-zen-workspaces-edit-footer {
|
||||
padding-bottom: 0 !important;
|
||||
margin-top: 10px;
|
||||
margin-left: 0;
|
||||
margin-bottom: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-create-footer button[default='true'],
|
||||
#PanelUI-zen-workspaces-edit-footer button[default='true'] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#PanelUI-zen-workspaces-header {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* Mark workspaces indicator */
|
||||
.zen-current-workspace-indicator {
|
||||
padding: calc(15px + var(--zen-toolbox-padding))
|
||||
calc(4px + var(--tab-inline-padding) + var(--zen-toolbox-padding));
|
||||
padding: calc(4px + var(--tab-inline-padding) + var(--zen-toolbox-padding));
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
max-height: var(--zen-workspace-indicator-height);
|
||||
|
@ -452,6 +134,8 @@
|
|||
flex-direction: row !important;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
font-size: small;
|
||||
padding-right: 10px;
|
||||
|
||||
&::before {
|
||||
border-radius: var(--border-radius-medium);
|
||||
|
@ -486,8 +170,23 @@
|
|||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
pointer-events: none;
|
||||
font-size: small;
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.zen-workspaces-actions {
|
||||
--toolbarbutton-inner-padding: 4px;
|
||||
margin-left: auto !important;
|
||||
opacity: 0;
|
||||
visibility: collapse;
|
||||
transition: opacity 0.1s;
|
||||
order: 5;
|
||||
}
|
||||
|
||||
:root:not([zen-private-window]) &:hover .zen-workspaces-actions,
|
||||
& .zen-workspaces-actions[open='true'] {
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue