mirror of
https://github.com/zen-browser/desktop.git
synced 2025-09-05 19:08:18 +00:00
Merge branch 'dev' into feature/import-export-mods
This commit is contained in:
@@ -58,7 +58,6 @@ pref('browser.newtabpage.activity-stream.feeds.section.topstories', false);
|
||||
pref("browser.topsites.contile.enabled", true);
|
||||
|
||||
// Pdf
|
||||
pref('browser.download.open_pdf_attachments_inline', true);
|
||||
pref('pdfjs.enableHighlightEditor', true);
|
||||
pref('pdfjs.enableHighlightFloatingButton', true);
|
||||
|
||||
@@ -121,7 +120,7 @@ pref('zen.theme.color-prefs.use-workspace-colors', true);
|
||||
|
||||
pref('zen.view.compact.hide-tabbar', true);
|
||||
pref('zen.view.compact.hide-toolbar', false);
|
||||
pref('zen.view.compact.toolbar-flash-popup', true);
|
||||
pref('zen.view.compact.toolbar-flash-popup', false);
|
||||
pref('zen.view.compact.toolbar-flash-popup.duration', 800);
|
||||
pref('zen.view.compact.toolbar-hide-after-hover.duration', 1000);
|
||||
pref('zen.view.compact.color-toolbar', true);
|
||||
@@ -194,11 +193,14 @@ pref('zen.splitView.enable-tab-drop', true);
|
||||
pref('zen.splitView.min-resize-width', 7);
|
||||
pref('zen.splitView.rearrange-hover-size', 24);
|
||||
|
||||
// Zen Download Animations
|
||||
pref('zen.downloads.download-animation', true);
|
||||
pref('zen.downloads.download-animation-duration', 1000); // ms
|
||||
|
||||
// Startup flags
|
||||
pref('zen.startup.smooth-scroll-in-tabs', true);
|
||||
|
||||
// Zen Workspaces
|
||||
pref('zen.workspaces.disabled_for_testing', false);
|
||||
pref('zen.workspaces.hide-default-container-indicator', true);
|
||||
pref('zen.workspaces.force-container-workspace', false);
|
||||
pref('zen.workspaces.open-new-tab-if-last-unpinned-tab-is-closed', false);
|
||||
@@ -272,8 +274,9 @@ pref("pdfjs.enableScripting", false);
|
||||
pref("extensions.postDownloadThirdPartyPrompt", false);
|
||||
|
||||
// Downloads
|
||||
pref("browser.download.always_ask_before_handling_new_types", true);
|
||||
pref("browser.download.manager.addToRecentDocs", false);
|
||||
pref('browser.download.open_pdf_attachments_inline', true);
|
||||
pref('browser.download.alwaysOpenPanel', false);
|
||||
|
||||
// Tracking protection
|
||||
pref("urlclassifier.trackingSkipURLs", "*.reddit.com, *.x.com, *.twimg.com, *.tiktok.com");
|
||||
@@ -335,10 +338,6 @@ pref("network.predictor.enable-hover-on-ssl", true);
|
||||
pref("network.http.speculative-parallel-limit", 10);
|
||||
pref("network.http.rcwn.enabled", false);
|
||||
|
||||
// Enable Browser Toolbox, Ctrl+Shift+Alt+I for debugging and modifying UI
|
||||
pref("devtools.debugger.remote-enabled", false);
|
||||
pref("devtools.chrome.enabled", true);
|
||||
|
||||
// Disable Firefox's revamp
|
||||
pref("sidebar.revamp", false, locked);
|
||||
pref("sidebar.verticalTabs", false, locked);
|
||||
@@ -454,10 +453,6 @@ pref("browser.ml.chat.sidebar", false);
|
||||
pref("browser.ml.enable", false);
|
||||
|
||||
// ---- Experimental settings to try make zen faster
|
||||
pref("gfx.canvas.accelerated.cache-items", 32768);
|
||||
pref("gfx.canvas.accelerated.cache-size", 256);
|
||||
pref("gfx.content.skia-font-cache-size", 80);
|
||||
|
||||
pref("media.memory_cache_max_size", 1048576);
|
||||
pref("media.cache_readahead_limit", 9000);
|
||||
pref("media.cache_resume_threshold", 3600);
|
||||
|
@@ -1,16 +1,11 @@
|
||||
diff --git a/browser/base/content/nsContextMenu.sys.mjs b/browser/base/content/nsContextMenu.sys.mjs
|
||||
index 3bd0ee8af8b696161d18fd2a978f9e25972ed3ad..2f0763dbde2250f625e9a87ab88910b4421c36ca 100644
|
||||
index 3bd0ee8af8b696161d18fd2a978f9e25972ed3ad..9e602a942271bd54231dc66363f8db51aea9e78a 100644
|
||||
--- a/browser/base/content/nsContextMenu.sys.mjs
|
||||
+++ b/browser/base/content/nsContextMenu.sys.mjs
|
||||
@@ -1111,6 +1111,13 @@ export class nsContextMenu {
|
||||
@@ -1111,6 +1111,8 @@ export class nsContextMenu {
|
||||
!this.isSecureAboutPage()
|
||||
);
|
||||
|
||||
+ this.showItem(
|
||||
+ "context-zenAddToWebPanel",
|
||||
+ this.onLink && !this.onMailtoLink && !this.onTelLink
|
||||
+ );
|
||||
+
|
||||
+ this.showItem("context-zenSplitLink", this.onLink && !this.onMailtoLink && !this.onTelLink);
|
||||
+
|
||||
let canNotStrip =
|
||||
|
@@ -25,15 +25,16 @@
|
||||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-branding.css" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-welcome.css" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-media-controls.css" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://browser/content/zen-styles/zen-download-box-animation.css" />
|
||||
</linkset>
|
||||
|
||||
# Scripts used all over the browser
|
||||
<script>
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/ZenUIManager.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenFolders.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenThemesCommon.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenThemesImporter.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenCompactMode.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/ZenUIManager.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenTabUnloader.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenPinnedTabsStorage.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenWorkspacesStorage.mjs", this);
|
||||
@@ -42,4 +43,5 @@ Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/Zen
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenViewSplitter.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenGlanceManager.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenMediaController.mjs", this);
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenDownloadAnimation.mjs", this);
|
||||
</script>
|
||||
|
@@ -68,6 +68,11 @@
|
||||
content/browser/zen-components/ZenMediaController.mjs (../../zen/media/ZenMediaController.mjs)
|
||||
content/browser/zen-styles/zen-media-controls.css (../../zen/media/zen-media-controls.css)
|
||||
|
||||
content/browser/zen-components/ZenDownloadAnimation.mjs (../../zen/downloads/ZenDownloadAnimation.mjs)
|
||||
content/browser/zen-styles/zen-download-arc-animation.css (../../zen/downloads/zen-download-arc-animation.css)
|
||||
content/browser/zen-styles/zen-download-box-animation.css (../../zen/downloads/zen-download-box-animation.css)
|
||||
|
||||
|
||||
# Images
|
||||
content/browser/zen-images/gradient.png (../../zen/images/gradient.png)
|
||||
content/browser/zen-images/brand-header.svg (../../zen/images/brand-header.svg)
|
||||
@@ -77,6 +82,9 @@
|
||||
content/browser/zen-images/grain-bg.png (../../zen/images/grain-bg.png)
|
||||
content/browser/zen-images/note-indicator.svg (../../zen/images/note-indicator.svg)
|
||||
|
||||
content/browser/zen-images/downloads/download.svg (../../zen/images/downloads/download.svg)
|
||||
content/browser/zen-images/downloads/archive.svg (../../zen/images/downloads/archive.svg)
|
||||
|
||||
# Fonts
|
||||
content/browser/zen-fonts/JunicodeVF-Italic.woff2 (../../zen/fonts/JunicodeVF-Italic.woff2)
|
||||
content/browser/zen-fonts/JunicodeVF-Roman.woff2 (../../zen/fonts/JunicodeVF-Roman.woff2)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
index 6dece2b9d0462d90a28e75350ce983d87816ef73..b1f6a5e05281cdc9707f4e82fe3df611d246cc6f 100644
|
||||
index 6dece2b9d0462d90a28e75350ce983d87816ef73..e80730ed2db404c0d47f2e29c3235c66f0137ad2 100644
|
||||
--- a/browser/components/tabbrowser/content/tabbrowser.js
|
||||
+++ b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
@@ -415,11 +415,58 @@
|
||||
@@ -67,7 +67,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..b1f6a5e05281cdc9707f4e82fe3df611
|
||||
this.tabpanels.appendChild(panel);
|
||||
|
||||
let tab = this.tabs[0];
|
||||
+ ZenWorkspaces.handleInitialTab(tab, (!remoteType || remoteType === E10SUtils.PRIVILEGEDABOUT_REMOTE_TYPE) && !Services.prefs.getBoolPref('zen.workspaces.disable_empty_state_for_testing', false));
|
||||
+ ZenWorkspaces.handleInitialTab(tab, (!remoteType || remoteType === E10SUtils.PRIVILEGEDABOUT_REMOTE_TYPE) && !gZenUIManager.testingEnabled);
|
||||
tab.linkedPanel = uniqueId;
|
||||
this._selectedTab = tab;
|
||||
this._selectedBrowser = browser;
|
||||
|
@@ -24,10 +24,6 @@
|
||||
list-style-image: url('move-tab.svg') !important;
|
||||
}
|
||||
|
||||
.zen-tab-unsplit-button {
|
||||
list-style-image: url('unpin.svg') !important;
|
||||
}
|
||||
|
||||
#forward-button,
|
||||
#zen-sidebar-web-panel-forward {
|
||||
list-style-image: url('forward.svg') !important;
|
||||
@@ -63,9 +59,7 @@
|
||||
list-style-image: url('sidebars-right.svg') !important;
|
||||
}
|
||||
|
||||
#context_zenSplitTabs,
|
||||
#context-zenAddToWebPanel {
|
||||
/* TODO: Add split view icon */
|
||||
#context_zenSplitTabs {
|
||||
--menu-image: url('sidebars-right.svg') !important;
|
||||
}
|
||||
|
||||
@@ -267,7 +261,8 @@
|
||||
#restore-button,
|
||||
#fullscreen-button,
|
||||
#zen-glance-sidebar-open,
|
||||
#appMenu-fullscreen-button2 {
|
||||
#appMenu-fullscreen-button2,
|
||||
.zen-tab-unsplit-button {
|
||||
list-style-image: url('fullscreen.svg') !important;
|
||||
}
|
||||
|
||||
|
@@ -1,16 +1,14 @@
|
||||
diff --git a/testing/profiles/mochitest/user.js b/testing/profiles/mochitest/user.js
|
||||
index a4068ac3f61161d014c49d54ae7a3bf886868f1b..84523e9e10d44269172aa6913699ec50def8166e 100644
|
||||
index a4068ac3f61161d014c49d54ae7a3bf886868f1b..b9861cfaae19a4a71b75ccc73095dc602df22b12 100644
|
||||
--- a/testing/profiles/mochitest/user.js
|
||||
+++ b/testing/profiles/mochitest/user.js
|
||||
@@ -41,3 +41,11 @@ user_pref("places.history.floodingPrevention.enabled", false);
|
||||
@@ -41,3 +41,9 @@ user_pref("places.history.floodingPrevention.enabled", false);
|
||||
// permission, and we can open it and wait for the user to give permission, then
|
||||
// don't do that.
|
||||
user_pref("geo.prompt.open_system_prefs", false);
|
||||
+
|
||||
+user_pref("zen.keyboard.shortcuts.enabled", false);
|
||||
+user_pref("zen.welcome-screen.seen", true);
|
||||
+user_pref("zen.tab-unloader.enabled", false);
|
||||
+user_pref("zen.workspaces.disable_empty_state_for_testing", true);
|
||||
+user_pref("zen.watermark.enabled", false);
|
||||
+user_pref("zen.urlbar.replace-newtab", false);
|
||||
+user_pref("zen.sidebar.use-google-favicons", false); // Crashes on some platforms
|
||||
+user_pref("zen.testing.enabled", true);
|
||||
|
@@ -1,17 +1,16 @@
|
||||
diff --git a/testing/profiles/profileserver/user.js b/testing/profiles/profileserver/user.js
|
||||
index 19ff7d474f6d22d2d386764e2e6942ce6a324470..a1ed4b51f26f458f965fbc29dfa7b8ad451faf7f 100644
|
||||
index 19ff7d474f6d22d2d386764e2e6942ce6a324470..a68a1f692e050c2a2a7e5e1390dec9556e71d7ed 100644
|
||||
--- a/testing/profiles/profileserver/user.js
|
||||
+++ b/testing/profiles/profileserver/user.js
|
||||
@@ -8,3 +8,12 @@
|
||||
@@ -8,3 +8,11 @@
|
||||
user_pref("dom.timeout.enable_budget_timer_throttling", false);
|
||||
// Turn off update
|
||||
user_pref("app.update.disabledForTesting", true);
|
||||
+
|
||||
+// zen:
|
||||
+// Disable some of zen's features to better match the default Firefox experience
|
||||
+user_pref("zen.workspaces.disabled_for_testing", true);
|
||||
+user_pref("zen.workspaces.disable_empty_state_for_testing", true);
|
||||
+user_pref("zen.welcome-screen.seen", true);
|
||||
+user_pref("zen.tab-unloader.enabled", false);
|
||||
+user_pref("zen.watermark.enabled", false);
|
||||
+user_pref("zen.glance.enabled", false);
|
||||
+user_pref("zen.urlbar.replace-newtab", false);
|
||||
+user_pref("zen.testing.enabled", true);
|
||||
|
@@ -2,6 +2,7 @@ var gZenUIManager = {
|
||||
_popupTrackingElements: [],
|
||||
_hoverPausedForExpand: false,
|
||||
_hasLoadedDOM: false,
|
||||
testingEnabled: Services.prefs.getBoolPref('zen.testing.enabled', false),
|
||||
|
||||
init() {
|
||||
document.addEventListener('popupshowing', this.onPopupShowing.bind(this));
|
||||
@@ -254,6 +255,10 @@ var gZenUIManager = {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.testingEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const shouldOpenURLBar = gZenVerticalTabsManager._canReplaceNewTab && !werePassedURL && !searchClipboard && where === 'tab';
|
||||
|
||||
if (!shouldOpenURLBar) {
|
||||
@@ -630,7 +635,7 @@ var gZenVerticalTabsManager = {
|
||||
},
|
||||
|
||||
_updateEvent({ forCustomizableMode = false, dontRebuildAreas = false } = {}) {
|
||||
if (this._isUpdating) {
|
||||
if (this._isUpdating || gZenUIManager.testingEnabled) {
|
||||
return;
|
||||
}
|
||||
this._isUpdating = true;
|
||||
|
459
src/zen/downloads/ZenDownloadAnimation.mjs
Normal file
459
src/zen/downloads/ZenDownloadAnimation.mjs
Normal file
@@ -0,0 +1,459 @@
|
||||
{
|
||||
const { Downloads } = ChromeUtils.importESModule('resource://gre/modules/Downloads.sys.mjs');
|
||||
|
||||
const CONFIG = Object.freeze({
|
||||
ANIMATION: {
|
||||
ARC_STEPS: 60,
|
||||
MAX_ARC_HEIGHT: 1200,
|
||||
ARC_HEIGHT_RATIO: 0.8, // Arc height = distance * ratio (capped at MAX_ARC_HEIGHT)
|
||||
SCALE_END: 0.45, // Final scale at destination
|
||||
},
|
||||
});
|
||||
|
||||
class ZenDownloadAnimation extends ZenDOMOperatedFeature {
|
||||
#lastClickPosition = null;
|
||||
|
||||
async init() {
|
||||
this.#setupClickListener();
|
||||
await this.#setupDownloadListeners();
|
||||
}
|
||||
|
||||
#setupClickListener() {
|
||||
document.addEventListener('mousedown', this.#handleClick.bind(this), true);
|
||||
}
|
||||
|
||||
#handleClick(event) {
|
||||
this.#lastClickPosition = {
|
||||
clientX: event.clientX,
|
||||
clientY: event.clientY,
|
||||
};
|
||||
}
|
||||
|
||||
async #setupDownloadListeners() {
|
||||
try {
|
||||
const list = await Downloads.getList(Downloads.ALL);
|
||||
list.addView({
|
||||
onDownloadAdded: this.#handleNewDownload.bind(this),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`[${ZenDownloadAnimation.name}] Failed to set up download animation listeners: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
#handleNewDownload() {
|
||||
if (!Services.prefs.getBoolPref('zen.downloads.download-animation')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.#lastClickPosition) {
|
||||
console.warn(`[${ZenDownloadAnimation.name}] No recent click position available for animation`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.#animateDownload(this.#lastClickPosition);
|
||||
}
|
||||
|
||||
#animateDownload(startPosition) {
|
||||
let animationElement = document.querySelector('zen-download-animation');
|
||||
|
||||
if (!animationElement) {
|
||||
animationElement = document.createElement('zen-download-animation');
|
||||
document.body.appendChild(animationElement);
|
||||
}
|
||||
|
||||
animationElement.initializeAnimation(startPosition);
|
||||
}
|
||||
}
|
||||
|
||||
class ZenDownloadAnimationElement extends HTMLElement {
|
||||
#boxAnimationElement = null;
|
||||
#boxAnimationTimeoutId = null;
|
||||
#isBoxAnimationRunning = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
this.#loadArcStyles();
|
||||
}
|
||||
|
||||
#loadArcStyles() {
|
||||
try {
|
||||
const link = document.createElement('link');
|
||||
link.setAttribute('rel', 'stylesheet');
|
||||
link.setAttribute('href', 'chrome://browser/content/zen-styles/zen-download-arc-animation.css');
|
||||
this.shadowRoot.appendChild(link);
|
||||
} catch (error) {
|
||||
console.error(`[${ZenDownloadAnimationElement.name}] Error loading arc styles: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
async initializeAnimation(startPosition) {
|
||||
if (!startPosition) {
|
||||
console.warn(`[${ZenDownloadAnimationElement.name}] No start position provided, skipping animation`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine animation target position
|
||||
const { endPosition, isDownloadButtonVisible } = this.#determineEndPosition();
|
||||
const areTabsPositionedRight = this.#areTabsOnRightSide();
|
||||
|
||||
// Create and prepare the arc animation element
|
||||
const arcAnimationElement = this.#createArcAnimationElement(startPosition);
|
||||
|
||||
// Calculate optimal arc parameters based on available space
|
||||
const distance = this.#calculateDistance(startPosition, endPosition);
|
||||
const { arcHeight, shouldArcDownward } = this.#calculateOptimalArc(startPosition, endPosition, distance);
|
||||
const distanceX = endPosition.clientX - startPosition.clientX;
|
||||
const distanceY = endPosition.clientY - startPosition.clientY;
|
||||
const arcSequence = this.#createArcAnimationSequence(distanceX, distanceY, arcHeight, shouldArcDownward);
|
||||
|
||||
// Start the download animation
|
||||
await this.#startDownloadAnimation(areTabsPositionedRight, isDownloadButtonVisible, arcAnimationElement, arcSequence);
|
||||
}
|
||||
|
||||
#areTabsOnRightSide() {
|
||||
return Services.prefs.getBoolPref('zen.tabs.vertical.right-side');
|
||||
}
|
||||
|
||||
#determineEndPosition() {
|
||||
const downloadsButton = document.getElementById('downloads-button');
|
||||
const isDownloadButtonVisible = downloadsButton && this.#isElementVisible(downloadsButton);
|
||||
|
||||
let endPosition = { clientX: 0, clientY: 0 };
|
||||
|
||||
if (isDownloadButtonVisible) {
|
||||
// Use download button as target
|
||||
const buttonRect = downloadsButton.getBoundingClientRect();
|
||||
endPosition = {
|
||||
clientX: buttonRect.left + buttonRect.width / 2,
|
||||
clientY: buttonRect.top + buttonRect.height / 2,
|
||||
};
|
||||
} else {
|
||||
// Use alternative position at bottom of wrapper
|
||||
const areTabsPositionedRight = this.#areTabsOnRightSide();
|
||||
const wrapper = document.getElementById('zen-main-app-wrapper');
|
||||
const wrapperRect = wrapper.getBoundingClientRect();
|
||||
|
||||
endPosition = {
|
||||
clientX: areTabsPositionedRight ? wrapperRect.right - 42 : wrapperRect.left + 42,
|
||||
clientY: wrapperRect.bottom - 40,
|
||||
};
|
||||
}
|
||||
|
||||
return { endPosition, isDownloadButtonVisible };
|
||||
}
|
||||
|
||||
#createArcAnimationElement(startPosition) {
|
||||
const arcAnimationHTML = `
|
||||
<box class="zen-download-arc-animation">
|
||||
<box class="zen-download-arc-animation-inner-circle">
|
||||
<html:div class="zen-download-arc-animation-icon"></html:div>
|
||||
</box>
|
||||
</box>
|
||||
`;
|
||||
|
||||
const fragment = window.MozXULElement.parseXULToFragment(arcAnimationHTML);
|
||||
const animationElement = fragment.querySelector('.zen-download-arc-animation');
|
||||
|
||||
Object.assign(animationElement.style, {
|
||||
left: `${startPosition.clientX}px`,
|
||||
top: `${startPosition.clientY}px`,
|
||||
transform: 'translate(-50%, -50%)',
|
||||
});
|
||||
|
||||
this.shadowRoot.appendChild(animationElement);
|
||||
|
||||
return animationElement;
|
||||
}
|
||||
|
||||
#calculateOptimalArc(startPosition, endPosition, distance) {
|
||||
// Calculate available space for the arc
|
||||
const availableTopSpace = Math.min(startPosition.clientY, endPosition.clientY);
|
||||
const viewportHeight = window.innerHeight;
|
||||
const availableBottomSpace = viewportHeight - Math.max(startPosition.clientY, endPosition.clientY);
|
||||
|
||||
// Determine if we should arc downward or upward based on available space
|
||||
const shouldArcDownward = availableBottomSpace > availableTopSpace;
|
||||
|
||||
// Use the space in the direction we're arcing
|
||||
const availableSpace = shouldArcDownward ? availableBottomSpace : availableTopSpace;
|
||||
|
||||
// Limit arc height to a percentage of the available space
|
||||
const arcHeight = Math.min(
|
||||
distance * CONFIG.ANIMATION.ARC_HEIGHT_RATIO,
|
||||
CONFIG.ANIMATION.MAX_ARC_HEIGHT,
|
||||
availableSpace * 0.8
|
||||
);
|
||||
|
||||
return { arcHeight, shouldArcDownward };
|
||||
}
|
||||
|
||||
#calculateDistance(start, end) {
|
||||
const distanceX = end.clientX - start.clientX;
|
||||
const distanceY = end.clientY - start.clientY;
|
||||
return Math.sqrt(distanceX * distanceX + distanceY * distanceY);
|
||||
}
|
||||
|
||||
async #startDownloadAnimation(areTabsPositionedRight, isDownloadButtonVisible, arcAnimationElement, sequence) {
|
||||
try {
|
||||
if (!isDownloadButtonVisible) {
|
||||
this.#startBoxAnimation(areTabsPositionedRight);
|
||||
}
|
||||
|
||||
await gZenUIManager.motion.animate(arcAnimationElement, sequence, {
|
||||
duration: Services.prefs.getIntPref('zen.downloads.download-animation-duration') / 1000,
|
||||
easing: 'cubic-bezier(0.37, 0, 0.63, 1)',
|
||||
fill: 'forwards',
|
||||
});
|
||||
|
||||
this.#cleanArcAnimation(arcAnimationElement);
|
||||
} catch (error) {
|
||||
console.error('[ZenDownloadAnimationElement] Error in animation sequence:', error);
|
||||
this.#cleanArcAnimation(arcAnimationElement);
|
||||
}
|
||||
}
|
||||
|
||||
#createArcAnimationSequence(distanceX, distanceY, arcHeight, shouldArcDownward) {
|
||||
const sequence = { offset: [], opacity: [], transform: [] };
|
||||
|
||||
const arcDirection = shouldArcDownward ? 1 : -1;
|
||||
const steps = CONFIG.ANIMATION.ARC_STEPS;
|
||||
const endScale = CONFIG.ANIMATION.SCALE_END;
|
||||
|
||||
function easeInOutQuad(t) {
|
||||
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
||||
}
|
||||
|
||||
let previousRotation = 0;
|
||||
for (let i = 0; i <= steps; i++) {
|
||||
const progress = i / steps;
|
||||
const eased = easeInOutQuad(progress);
|
||||
|
||||
// Calculate opacity changes
|
||||
let opacity;
|
||||
if (progress < 0.3) {
|
||||
// Fade in during first 30%
|
||||
opacity = 0.3 + (progress / 0.3) * 0.6;
|
||||
} else if (progress < 0.98) {
|
||||
// Slight increase to full opacity
|
||||
opacity = 0.9 + ((progress - 0.3) / 0.6) * 0.1;
|
||||
} else {
|
||||
// Decrease opacity in the final steps
|
||||
opacity = 1 - ((progress - 0.9) / 0.1) * 1;
|
||||
}
|
||||
|
||||
// Calculate scaling changes
|
||||
let scale;
|
||||
if (progress < 0.5) {
|
||||
scale = 0.5 + (progress / 0.5) * 1.3;
|
||||
} else {
|
||||
scale = 1.8 - ((progress - 0.5) / 0.5) * (1.8 - endScale);
|
||||
}
|
||||
|
||||
// Position on arc
|
||||
const x = distanceX * eased;
|
||||
const y = distanceY * eased + arcDirection * arcHeight * (1 - (2 * eased - 1) ** 2);
|
||||
|
||||
// Calculate rotation to point in the direction of movement
|
||||
let rotation = previousRotation;
|
||||
if (i > 0) {
|
||||
const prevEased = easeInOutQuad((i - 1) / steps);
|
||||
|
||||
const prevX = distanceX * prevEased;
|
||||
const prevAdjustedProgress = prevEased * 2 - 1;
|
||||
const prevVerticalOffset = arcDirection * arcHeight * (1 - prevAdjustedProgress * 2);
|
||||
const prevY = distanceY * prevEased + prevVerticalOffset;
|
||||
|
||||
const targetRotation = Math.atan2(y - prevY, x - prevX) * (180 / Math.PI);
|
||||
|
||||
rotation += (targetRotation - previousRotation) * 0.01;
|
||||
previousRotation = rotation;
|
||||
}
|
||||
|
||||
sequence.offset.push(progress);
|
||||
sequence.opacity.push(opacity);
|
||||
sequence.transform.push(`translate(calc(${x}px - 50%), calc(${y}px - 50%)) rotate(${rotation}deg) scale(${scale})`);
|
||||
}
|
||||
|
||||
// Last opacity should be 0
|
||||
sequence.opacity[steps] = 0;
|
||||
|
||||
return sequence;
|
||||
}
|
||||
|
||||
#cleanArcAnimation(element) {
|
||||
element.remove();
|
||||
}
|
||||
|
||||
async #startBoxAnimation(areTabsPositionedRight) {
|
||||
// If animation is already in progress, don't start a new one
|
||||
if (this.#isBoxAnimationRunning) {
|
||||
console.warn(`[${ZenDownloadAnimationElement.name}] Box animation already running, skipping new request.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.#boxAnimationElement) {
|
||||
clearTimeout(this.#boxAnimationTimeoutId);
|
||||
this.#boxAnimationTimeoutId = setTimeout(
|
||||
() => this.#finishBoxAnimation(areTabsPositionedRight),
|
||||
this.#getBoxAnimationDurationMs()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const wrapper = document.getElementById('zen-main-app-wrapper');
|
||||
if (!wrapper) {
|
||||
console.warn(`[${ZenDownloadAnimationElement.name}] Cannot start box animation, Wrapper element not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.#isBoxAnimationRunning = true;
|
||||
|
||||
try {
|
||||
const boxAnimationHTML = `
|
||||
<box class="zen-download-box-animation">
|
||||
<html:div class="zen-download-box-animation-icon"></html:div>
|
||||
</box>
|
||||
`;
|
||||
|
||||
const sideProp = areTabsPositionedRight ? 'right' : 'left';
|
||||
const startSideValue = areTabsPositionedRight ? '50px' : '-50px';
|
||||
|
||||
const fragment = window.MozXULElement.parseXULToFragment(boxAnimationHTML);
|
||||
this.#boxAnimationElement = fragment.querySelector('.zen-download-box-animation');
|
||||
|
||||
Object.assign(this.#boxAnimationElement.style, {
|
||||
bottom: '24px',
|
||||
transform: 'scale(0.8)',
|
||||
[sideProp]: startSideValue,
|
||||
});
|
||||
|
||||
wrapper.appendChild(this.#boxAnimationElement);
|
||||
|
||||
await gZenUIManager.motion.animate(
|
||||
this.#boxAnimationElement,
|
||||
{
|
||||
[sideProp]: '34px',
|
||||
opacity: 1,
|
||||
transform: 'scale(1.1)',
|
||||
},
|
||||
{
|
||||
duration: 0.35,
|
||||
easing: 'ease-out',
|
||||
}
|
||||
).finished;
|
||||
|
||||
await gZenUIManager.motion.animate(
|
||||
this.#boxAnimationElement,
|
||||
{
|
||||
[sideProp]: '24px',
|
||||
transform: 'scale(1)',
|
||||
},
|
||||
{
|
||||
duration: 0.2,
|
||||
easing: 'ease-in-out',
|
||||
}
|
||||
).finished;
|
||||
|
||||
clearTimeout(this.#boxAnimationTimeoutId);
|
||||
this.#boxAnimationTimeoutId = setTimeout(
|
||||
() => this.#finishBoxAnimation(areTabsPositionedRight),
|
||||
this.#getBoxAnimationDurationMs()
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`[${ZenDownloadAnimationElement.name}] Error during box entry animation: ${error}`);
|
||||
this.#cleanBoxAnimation();
|
||||
} finally {
|
||||
this.#isBoxAnimationRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
#getBoxAnimationDurationMs() {
|
||||
return Services.prefs.getIntPref('zen.downloads.download-animation-duration') + 200;
|
||||
}
|
||||
|
||||
async #finishBoxAnimation(areTabsPositionedRight) {
|
||||
clearTimeout(this.#boxAnimationTimeoutId);
|
||||
this.#boxAnimationTimeoutId = null;
|
||||
|
||||
if (!this.#boxAnimationElement || this.#isBoxAnimationRunning) {
|
||||
if (!this.#boxAnimationElement) this.#cleanBoxAnimationState();
|
||||
return;
|
||||
}
|
||||
|
||||
this.#isBoxAnimationRunning = true;
|
||||
|
||||
try {
|
||||
const sideProp = areTabsPositionedRight ? 'right' : 'left';
|
||||
|
||||
await gZenUIManager.motion.animate(
|
||||
this.#boxAnimationElement,
|
||||
{
|
||||
transform: 'scale(0.9)',
|
||||
},
|
||||
{
|
||||
duration: 0.15,
|
||||
easing: 'ease-in',
|
||||
}
|
||||
).finished;
|
||||
|
||||
await gZenUIManager.motion.animate(
|
||||
this.#boxAnimationElement,
|
||||
{
|
||||
[sideProp]: '-50px',
|
||||
opacity: 0,
|
||||
transform: 'scale(0.8)',
|
||||
},
|
||||
{
|
||||
duration: 0.3,
|
||||
easing: 'cubic-bezier(0.5, 0, 0.75, 0)',
|
||||
}
|
||||
).finished;
|
||||
} catch (error) {
|
||||
console.warn(`[${ZenDownloadAnimationElement.name}] Error during box exit animation: ${error}`);
|
||||
} finally {
|
||||
this.#cleanBoxAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
#cleanBoxAnimationState() {
|
||||
this.#boxAnimationElement = null;
|
||||
if (this.#boxAnimationTimeoutId) {
|
||||
clearTimeout(this.#boxAnimationTimeoutId);
|
||||
this.#boxAnimationTimeoutId = null;
|
||||
}
|
||||
this.#isBoxAnimationRunning = false;
|
||||
}
|
||||
|
||||
#cleanBoxAnimation() {
|
||||
if (this.#boxAnimationElement && this.#boxAnimationElement.isConnected) {
|
||||
try {
|
||||
this.#boxAnimationElement.remove();
|
||||
} catch (error) {
|
||||
console.error(`[${ZenDownloadAnimationElement.name}] Error removing box animation element: ${error}`, error);
|
||||
}
|
||||
}
|
||||
this.#cleanBoxAnimationState();
|
||||
}
|
||||
|
||||
#isElementVisible(element) {
|
||||
if (!element) return false;
|
||||
|
||||
const rect = element.getBoundingClientRect();
|
||||
|
||||
// Element must be in the viewport
|
||||
// Is 1 and no 0 because if you pin the download button in the overflow menu
|
||||
// the download button is in the viewport but in the position 0,0 so this
|
||||
// avoid this case
|
||||
if (rect.bottom < 1 || rect.right < 1 || rect.top > window.innerHeight || rect.left > window.innerWidth) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('zen-download-animation', ZenDownloadAnimationElement);
|
||||
|
||||
new ZenDownloadAnimation();
|
||||
}
|
41
src/zen/downloads/zen-download-arc-animation.css
Normal file
41
src/zen/downloads/zen-download-arc-animation.css
Normal file
@@ -0,0 +1,41 @@
|
||||
:host {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.zen-download-arc-animation {
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 2px;
|
||||
background-color: var(--zen-colors-hover-bg);
|
||||
box-shadow: var(--zen-big-shadow);
|
||||
}
|
||||
|
||||
.zen-download-arc-animation-inner-circle {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
background-color: var(--zen-colors-secondary);
|
||||
}
|
||||
|
||||
.zen-download-arc-animation-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--zen-primary-color);
|
||||
mask: url('chrome://browser/content/zen-images/downloads/download.svg') no-repeat center;
|
||||
mask-size: 70%;
|
||||
}
|
22
src/zen/downloads/zen-download-box-animation.css
Normal file
22
src/zen/downloads/zen-download-box-animation.css
Normal file
@@ -0,0 +1,22 @@
|
||||
.zen-download-box-animation {
|
||||
position: absolute;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--zen-colors-primary);
|
||||
border-radius: var(--zen-native-content-radius);
|
||||
box-shadow: var(--zen-big-shadow);
|
||||
pointer-events: none;
|
||||
z-index: 1100;
|
||||
}
|
||||
|
||||
.zen-download-box-animation-icon {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
background-color: var(--zen-primary-color);
|
||||
mask: url('chrome://browser/content/zen-images/downloads/archive.svg') no-repeat center;
|
||||
mask-size: contain;
|
||||
display: block;
|
||||
}
|
7
src/zen/images/downloads/archive.svg
Normal file
7
src/zen/images/downloads/archive.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-archive-icon lucide-archive">
|
||||
<rect width="20" height="5" x="2" y="3" rx="1" />
|
||||
<path d="M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8" />
|
||||
<path d="M10 12h4" />
|
||||
</svg>
|
After Width: | Height: | Size: 384 B |
6
src/zen/images/downloads/download.svg
Normal file
6
src/zen/images/downloads/download.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
stroke="#000000" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-arrow-down-icon lucide-arrow-down">
|
||||
<path d="M12 5v14" />
|
||||
<path d="m19 12-7 7-7-7" />
|
||||
</svg>
|
After Width: | Height: | Size: 305 B |
@@ -34,6 +34,11 @@
|
||||
margin-left: 0 !important;
|
||||
position: absolute !important;
|
||||
overflow: hidden;
|
||||
|
||||
&.deck-selected:has(.dialogStack:not([hidden='true'])) {
|
||||
/* Fix for issue https://github.com/zen-browser/desktop/issues/7564 */
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
#tabbrowser-tabpanels[zen-split-view='true']:not([zen-split-resizing]) > [zen-split-anim='true'] {
|
||||
@@ -125,7 +130,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
padding: 0.4rem 0.6rem;
|
||||
padding: 0.4rem 0.6rem 0.2rem 0.6rem;
|
||||
border-radius: 8px;
|
||||
background-color: light-dark(rgba(255, 255, 255, 1), rgba(0, 0, 0, 1));
|
||||
box-shadow: 0 0 0 1px var(--button-primary-border-color);
|
||||
@@ -144,7 +149,7 @@
|
||||
}
|
||||
|
||||
.zen-view-splitter-header-container toolbarbutton {
|
||||
display: block;
|
||||
display: flex;
|
||||
-moz-context-properties: fill, fill-opacity;
|
||||
border-radius: var(--tab-border-radius);
|
||||
color: inherit;
|
||||
@@ -163,6 +168,11 @@
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
&.zen-tab-unsplit-button image {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
&.zen-tab-rearrange-button {
|
||||
cursor: move;
|
||||
|
||||
|
@@ -6,10 +6,6 @@ if [ ! -f "package.json" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf engine/browser/base/zen-components/tests/
|
||||
|
||||
npm run import
|
||||
npm run build:ui
|
||||
cd ./engine
|
||||
./mach mochitest browser/base/zen-components/tests
|
||||
./mach mochitest zen/tests/ $@
|
||||
cd ..
|
||||
|
@@ -47,6 +47,7 @@
|
||||
for (const url of tabs) {
|
||||
const tab = window.gBrowser.addTrustedTab(url, {
|
||||
inBackground: true,
|
||||
skipAnimation: true,
|
||||
});
|
||||
_tabsToPin.push(tab);
|
||||
}
|
||||
|
@@ -266,7 +266,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
_initializeEmptyTab() {
|
||||
if (Services.prefs.getBoolPref('zen.workspaces.disable_empty_state_for_testing', false)) {
|
||||
if (gZenUIManager.testingEnabled) {
|
||||
return;
|
||||
}
|
||||
this._emptyTab = gBrowser.addTrustedTab('about:blank', { inBackground: true, userContextId: 0, _forZenEmptyTab: true });
|
||||
@@ -281,13 +281,13 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
if (element.classList.contains('tabbrowser-tab')) {
|
||||
continue;
|
||||
}
|
||||
this._pinnedTabsResizeObserver.observe(element);
|
||||
this._pinnedTabsResizeObserver.observe(element, { box: 'border-box' });
|
||||
}
|
||||
for (let element of document.getElementById('zen-essentials-wrapper').children) {
|
||||
if (element.classList.contains('tabbrowser-tab')) {
|
||||
continue;
|
||||
}
|
||||
this._pinnedTabsResizeObserver.observe(element);
|
||||
this._pinnedTabsResizeObserver.observe(element, { box: 'border-box' });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,8 +678,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
|
||||
get workspaceEnabled() {
|
||||
if (typeof this._workspaceEnabled === 'undefined') {
|
||||
this._workspaceEnabled =
|
||||
!Services.prefs.getBoolPref('zen.workspaces.disabled_for_testing', false) && this.shouldHaveWorkspaces;
|
||||
this._workspaceEnabled = !gZenUIManager.testingEnabled && this.shouldHaveWorkspaces;
|
||||
}
|
||||
return this._workspaceEnabled && !window.closed;
|
||||
}
|
||||
@@ -769,7 +768,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
async _selectStartPage() {
|
||||
if (Services.prefs.getBoolPref('zen.workspaces.disable_empty_state_for_testing', false)) {
|
||||
if (gZenUIManager.testingEnabled) {
|
||||
return;
|
||||
}
|
||||
if (this._initialTab) {
|
||||
@@ -1666,27 +1665,37 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
moveTabToWorkspace(tab, workspaceID) {
|
||||
const parent = tab.pinned ? '#vertical-pinned-tabs-container ' : '#tabbrowser-arrowscrollbox ';
|
||||
const container = document.querySelector(parent + `.zen-workspace-tabs-section[zen-workspace-id="${workspaceID}"]`);
|
||||
return this.moveTabsToWorkspace([tab], workspaceID);
|
||||
}
|
||||
|
||||
if (container?.contains(tab)) {
|
||||
return false;
|
||||
}
|
||||
moveTabsToWorkspace(tabs, workspaceID, justChangeId = false) {
|
||||
for (let tab of tabs) {
|
||||
const parent = tab.pinned ? '#vertical-pinned-tabs-container ' : '#tabbrowser-arrowscrollbox ';
|
||||
const container = document.querySelector(parent + `.zen-workspace-tabs-section[zen-workspace-id="${workspaceID}"]`);
|
||||
|
||||
tab.setAttribute('zen-workspace-id', workspaceID);
|
||||
if (tab.hasAttribute('zen-essential')) {
|
||||
return false;
|
||||
}
|
||||
if (container?.contains(tab)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (container) {
|
||||
container.insertBefore(tab, container.lastChild);
|
||||
}
|
||||
// also change glance tab if it's the same tab
|
||||
const glanceTab = tab.querySelector('.tabbrowser-tab[zen-glance-tab]');
|
||||
if (glanceTab) {
|
||||
glanceTab.setAttribute('zen-workspace-id', workspaceID);
|
||||
}
|
||||
tab.setAttribute('zen-workspace-id', workspaceID);
|
||||
if (tab.hasAttribute('zen-essential')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (container && !justChangeId) {
|
||||
if (tab.group?.hasAttribute('split-view-group')) {
|
||||
this.moveTabsToWorkspace(tab.group.tabs, workspaceID, true);
|
||||
container.insertBefore(tab.group, container.lastChild);
|
||||
continue;
|
||||
}
|
||||
container.insertBefore(tab, container.lastChild);
|
||||
}
|
||||
// also change glance tab if it's the same tab
|
||||
const glanceTab = tab.querySelector('.tabbrowser-tab[zen-glance-tab]');
|
||||
if (glanceTab) {
|
||||
glanceTab.setAttribute('zen-workspace-id', workspaceID);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1840,7 +1849,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
_updateMarginTopPinnedTabs(arrowscrollbox, pinnedContainer, essentialContainer, workspaceIndicator, forAnimation = false) {
|
||||
if (arrowscrollbox) {
|
||||
if (arrowscrollbox && !(this._inChangingWorkspace && !forAnimation && !this._alwaysAnimateMarginTop)) {
|
||||
delete this._alwaysAnimateMarginTop;
|
||||
const essentialsHeight = essentialContainer.getBoundingClientRect().height;
|
||||
workspaceIndicator.style.marginTop = essentialsHeight + 'px';
|
||||
let arrowMarginTop = pinnedContainer.getBoundingClientRect().height;
|
||||
@@ -1849,8 +1859,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
document.getElementById('zen-tabs-wrapper').style.marginTop = essentialsHeight + 'px';
|
||||
pinnedContainer.style.marginTop = '';
|
||||
} else {
|
||||
arrowMarginTop += essentialsHeight;
|
||||
arrowMarginTop += forAnimation ? 0 : essentialsHeight;
|
||||
pinnedContainer.style.marginTop = essentialsHeight + 'px';
|
||||
if (forAnimation) {
|
||||
document.getElementById('zen-tabs-wrapper').style.marginTop = '';
|
||||
}
|
||||
}
|
||||
if (!forAnimation && !this._inChangingWorkspace) {
|
||||
// TODO:
|
||||
@@ -2112,6 +2125,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
for (const cloned of clonedEssentials) {
|
||||
cloned.container.remove();
|
||||
}
|
||||
this._alwaysAnimateMarginTop = true;
|
||||
this.updateTabsContainers();
|
||||
}
|
||||
const essentialsContainer = this.getEssentialsSection(newWorkspace.containerTabId);
|
||||
@@ -2794,7 +2808,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
const containerTabId = parseInt(tab.parentNode.getAttribute('container'));
|
||||
workspaceToSwitch = this._workspaceCache.workspaces.find((workspace) => workspace.containerTabId === containerTabId);
|
||||
} else {
|
||||
workspaceToSwitch = this._workspaceCache.workspaces.find((workspace) => workspace.uuid === tab.getAttribute('zen-workspace-id'));
|
||||
workspaceToSwitch = this._workspaceCache.workspaces.find(
|
||||
(workspace) => workspace.uuid === tab.getAttribute('zen-workspace-id')
|
||||
);
|
||||
}
|
||||
if (!workspaceToSwitch) {
|
||||
console.error('No workspace found for tab, cannot switch');
|
||||
|
Reference in New Issue
Block a user