chore: Format with only a maximum of 10 columns, b=(no-bug), c=workflows, common, compact-mode, folders, glance, kbs, media, mods, split-view, tabs, tests, workspaces, welcome

This commit is contained in:
Mr. M 2025-05-10 21:22:16 +02:00
parent 1f68a45417
commit 7b99f227cd
No known key found for this signature in database
GPG key ID: 6292C4C8F8652B18
57 changed files with 5118 additions and 1336 deletions

View file

@ -475,7 +475,18 @@ jobs:
if: ${{ inputs.create_release || inputs.update_branch == 'twilight' }}
permissions: write-all
name: Release
needs: [build-data, linux, windows-step-3, check-release, mac-uni, appimage, source, lint, stop-self-hosted]
needs:
[
build-data,
linux,
windows-step-3,
check-release,
mac-uni,
appimage,
source,
lint,
stop-self-hosted,
]
runs-on: ubuntu-latest
environment:
name: ${{ inputs.update_branch == 'release' && 'Deploy-Release' || 'Deploy-Twilight' }}

View file

@ -7,6 +7,6 @@
"useTabs": false,
"jsxSingleQuote": false,
"semi": true,
"printWidth": 128,
"printWidth": 100,
"plugins": ["prettier-plugin-sh"]
}

View file

@ -8,7 +8,7 @@
"scripts": {
"build": "surfer build",
"build:ui": "surfer build --ui",
"start": "cd engine && ./mach run --noprofile",
"start": "cd engine && ./mach run --noprofile --marionette",
"import": "surfer import",
"export": "surfer export",
"init": "npm run download && npm run bootstrap && npm run import",

View file

@ -35,7 +35,9 @@ pref('browser.download.open_pdf_attachments_inline', true);
pref('browser.download.alwaysOpenPanel', false);
// Updates
#ifdef MOZILLA_OFFICIAL
pref("app.update.checkInstallTime.days", 6);
#endif
#include fullscreen.inc
#include ai.inc

View file

@ -8,6 +8,6 @@
skipintoolbarset="true"
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" cui-areatype="toolbar"></toolbarbutton>
<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 id="zen-workspaces-button" class="chromeclass-toolbar-additional" overflows="false" removable="false"></toolbarbutton>
</toolbar>

View file

@ -80,17 +80,24 @@ var gZenMarketplaceManager = {
const browser = ZenThemesCommon.currentBrowser;
const mozToggle = document.createElement('moz-toggle');
mozToggle.className = 'zenThemeMarketplaceItemPreferenceToggle zenThemeMarketplaceDisableAllToggle';
mozToggle.className =
'zenThemeMarketplaceItemPreferenceToggle zenThemeMarketplaceDisableAllToggle';
mozToggle.pressed = !areThemesDisabled;
browser.document.l10n.setAttributes(mozToggle, `zen-theme-disable-all-${!areThemesDisabled ? 'enabled' : 'disabled'}`);
browser.document.l10n.setAttributes(
mozToggle,
`zen-theme-disable-all-${!areThemesDisabled ? 'enabled' : 'disabled'}`
);
mozToggle.addEventListener('toggle', async (event) => {
const { pressed = false } = event.target || {};
this.themesList.style.display = pressed ? '' : 'none';
Services.prefs.setBoolPref('zen.themes.disable-all', !pressed);
browser.document.l10n.setAttributes(mozToggle, `zen-theme-disable-all-${pressed ? 'enabled' : 'disabled'}`);
browser.document.l10n.setAttributes(
mozToggle,
`zen-theme-disable-all-${pressed ? 'enabled' : 'disabled'}`
);
});
if (areThemesDisabled) {
@ -343,18 +350,28 @@ var gZenMarketplaceManager = {
if (!event.target.hasAttribute('pressed')) {
await this.disableTheme(themeId);
browser.document.l10n.setAttributes(mozToggle, 'zen-theme-marketplace-toggle-disabled-button');
browser.document.l10n.setAttributes(
mozToggle,
'zen-theme-marketplace-toggle-disabled-button'
);
if (theme.preferences) {
document.getElementById(`zenThemeMarketplaceItemConfigureButton-${sanitizedName}`).setAttribute('hidden', true);
document
.getElementById(`zenThemeMarketplaceItemConfigureButton-${sanitizedName}`)
.setAttribute('hidden', true);
}
} else {
await this.enableTheme(themeId);
browser.document.l10n.setAttributes(mozToggle, 'zen-theme-marketplace-toggle-enabled-button');
browser.document.l10n.setAttributes(
mozToggle,
'zen-theme-marketplace-toggle-enabled-button'
);
if (theme.preferences) {
document.getElementById(`zenThemeMarketplaceItemConfigureButton-${sanitizedName}`).removeAttribute('hidden');
document
.getElementById(`zenThemeMarketplaceItemConfigureButton-${sanitizedName}`)
.removeAttribute('hidden');
}
}
setTimeout(() => {
@ -365,15 +382,19 @@ var gZenMarketplaceManager = {
fragment.querySelector('.zenThemeMarketplaceItemTitle').textContent = themeName;
fragment.querySelector('.zenThemeMarketplaceItemDescription').textContent = theme.description;
fragment.querySelector('.zenThemeMarketplaceItemUninstallButton').addEventListener('click', async (event) => {
const [msg] = await document.l10n.formatValues([{ id: 'zen-theme-marketplace-remove-confirmation' }]);
fragment
.querySelector('.zenThemeMarketplaceItemUninstallButton')
.addEventListener('click', async (event) => {
const [msg] = await document.l10n.formatValues([
{ id: 'zen-theme-marketplace-remove-confirmation' },
]);
if (!confirm(msg)) {
return;
}
if (!confirm(msg)) {
return;
}
await this.removeTheme(event.target.getAttribute('zen-theme-id'));
});
await this.removeTheme(event.target.getAttribute('zen-theme-id'));
});
if (theme.homepage) {
const homepageButton = fragment.querySelector('.zenThemeMarketplaceItemHomepageButton');
@ -386,12 +407,16 @@ var gZenMarketplaceManager = {
}
if (theme.preferences) {
fragment.querySelector('.zenThemeMarketplaceItemConfigureButton').addEventListener('click', () => {
dialog.showModal();
});
fragment
.querySelector('.zenThemeMarketplaceItemConfigureButton')
.addEventListener('click', () => {
dialog.showModal();
});
if (isThemeEnabled) {
fragment.querySelector('.zenThemeMarketplaceItemConfigureButton').removeAttribute('hidden');
fragment
.querySelector('.zenThemeMarketplaceItemConfigureButton')
.removeAttribute('hidden');
}
}
@ -432,7 +457,10 @@ var gZenMarketplaceManager = {
if (placeholder) {
defaultItem.setAttribute('label', placeholder || '-');
} else {
browser.document.l10n.setAttributes(defaultItem, 'zen-theme-marketplace-dropdown-default-label');
browser.document.l10n.setAttributes(
defaultItem,
'zen-theme-marketplace-dropdown-default-label'
);
}
menupopup.appendChild(defaultItem);
@ -500,7 +528,9 @@ var gZenMarketplaceManager = {
</hbox>
`);
const checkboxElement = checkbox.querySelector('.zenThemeMarketplaceItemPreferenceCheckbox');
const checkboxElement = checkbox.querySelector(
'.zenThemeMarketplaceItemPreferenceCheckbox'
);
checkboxElement.setAttribute('label', label);
checkboxElement.setAttribute('tooltiptext', property);
checkboxElement.setAttribute('zen-pref', property);
@ -546,7 +576,10 @@ var gZenMarketplaceManager = {
if (placeholder) {
input.setAttribute('placeholder', placeholder || '-');
} else {
browser.document.l10n.setAttributes(input, 'zen-theme-marketplace-input-default-placeholder');
browser.document.l10n.setAttributes(
input,
'zen-theme-marketplace-input-default-placeholder'
);
}
input.addEventListener(
@ -558,9 +591,13 @@ var gZenMarketplaceManager = {
this._triggerBuildUpdateWithoutRebuild();
if (value === '') {
browser.document.querySelector(':root').style.removeProperty(`--${sanitizedProperty}`);
browser.document
.querySelector(':root')
.style.removeProperty(`--${sanitizedProperty}`);
} else {
browser.document.querySelector(':root').style.setProperty(`--${sanitizedProperty}`, value);
browser.document
.querySelector(':root')
.style.setProperty(`--${sanitizedProperty}`, value);
}
}, 500)
);
@ -630,7 +667,11 @@ var gZenLooksAndFeel = {
layout.classList.remove('selected');
if (layout.getAttribute('layout') == 'single' && isSingleToolbar) {
layout.classList.add('selected');
} else if (layout.getAttribute('layout') == 'multiple' && !isSingleToolbar && isExtendedSidebar) {
} else if (
layout.getAttribute('layout') == 'multiple' &&
!isSingleToolbar &&
isExtendedSidebar
) {
layout.classList.add('selected');
} else if (layout.getAttribute('layout') == 'collapsed' && !isExtendedSidebar) {
layout.classList.add('selected');
@ -650,7 +691,10 @@ var gZenLooksAndFeel = {
layout.classList.add('selected');
Services.prefs.setBoolPref(kZenExtendedSidebar, layout.getAttribute('layout') != 'collapsed');
Services.prefs.setBoolPref(
kZenExtendedSidebar,
layout.getAttribute('layout') != 'collapsed'
);
Services.prefs.setBoolPref(kZenSingleToolbar, layout.getAttribute('layout') == 'single');
});
}
@ -734,13 +778,19 @@ var gZenWorkspacesSettings = {
};
Services.prefs.addObserver('zen.tab-unloader.enabled', tabsUnloaderPrefListener);
Services.prefs.addObserver('zen.glance.enabled', tabsUnloaderPrefListener); // We can use the same listener for both prefs
Services.prefs.addObserver('zen.workspaces.container-specific-essentials-enabled', tabsUnloaderPrefListener);
Services.prefs.addObserver(
'zen.workspaces.container-specific-essentials-enabled',
tabsUnloaderPrefListener
);
Services.prefs.addObserver('zen.glance.activation-method', tabsUnloaderPrefListener);
window.addEventListener('unload', () => {
Services.prefs.removeObserver('zen.tab-unloader.enabled', tabsUnloaderPrefListener);
Services.prefs.removeObserver('zen.glance.enabled', tabsUnloaderPrefListener);
Services.prefs.removeObserver('zen.glance.activation-method', tabsUnloaderPrefListener);
Services.prefs.removeObserver('zen.workspaces.container-specific-essentials-enabled', tabsUnloaderPrefListener);
Services.prefs.removeObserver(
'zen.workspaces.container-specific-essentials-enabled',
tabsUnloaderPrefListener
);
});
},
};
@ -800,7 +850,10 @@ var zenMissingKeyboardShortcutL10n = {
key_accessibility: 'zen-devtools-toggle-accessibility-shortcut',
};
var zenIgnoreKeyboardShortcutL10n = ['zen-full-zoom-reduce-shortcut-alt-b', 'zen-full-zoom-reduce-shortcut-alt-a'];
var zenIgnoreKeyboardShortcutL10n = [
'zen-full-zoom-reduce-shortcut-alt-b',
'zen-full-zoom-reduce-shortcut-alt-a',
];
var gZenCKSSettings = {
async init() {
@ -964,8 +1017,16 @@ var gZenCKSSettings = {
event.preventDefault();
let input = document.querySelector(`.${ZEN_CKS_INPUT_FIELD_CLASS}[${KEYBIND_ATTRIBUTE_KEY}="${this._currentActionID}"]`);
const modifiers = new KeyShortcutModifiers(event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, false);
let input = document.querySelector(
`.${ZEN_CKS_INPUT_FIELD_CLASS}[${KEYBIND_ATTRIBUTE_KEY}="${this._currentActionID}"]`
);
const modifiers = new KeyShortcutModifiers(
event.ctrlKey,
event.altKey,
event.shiftKey,
event.metaKey,
false
);
const modifiersActive = modifiers.areAnyActive();
input.classList.remove(`${ZEN_CKS_INPUT_FIELD_CLASS}-not-set`);

View file

@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c2eb25c4c 100644
index 6dece2b9d0462d90a28e75350ce983d87816ef73..e54e815b04c311464ed53364007d99bb6c1a0cf3 100644
--- a/browser/components/tabbrowser/content/tabbrowser.js
+++ b/browser/components/tabbrowser/content/tabbrowser.js
@@ -415,11 +415,45 @@
@ -309,9 +309,11 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
let url = "about:blank";
if (tabData.entries?.length) {
@@ -3638,6 +3723,27 @@
@@ -3637,7 +3722,29 @@
skipLoad: true,
preferredRemoteType,
});
+ tab._originalUrl = url;
+ if (tabData.zenWorkspace) {
+ tab.setAttribute("zen-workspace-id", tabData.zenWorkspace);
@ -337,7 +339,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
if (select) {
tabToSelect = tab;
}
@@ -3661,7 +3767,8 @@
@@ -3661,7 +3768,8 @@
// needs calling:
shouldUpdateForPinnedTabs = true;
}
@ -347,7 +349,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
let { groupId } = tabData;
const tabGroup = tabGroupWorkingData.get(groupId);
// if a tab refers to a tab group we don't know, skip any group
@@ -3675,7 +3782,10 @@
@@ -3675,7 +3783,10 @@
tabGroup.stateData.id,
tabGroup.stateData.color,
tabGroup.stateData.collapsed,
@ -359,7 +361,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
);
tabsFragment.appendChild(tabGroup.node);
}
@@ -3723,8 +3833,16 @@
@@ -3723,8 +3834,16 @@
// to remove the old selected tab.
if (tabToSelect) {
let leftoverTab = this.selectedTab;
@ -378,7 +380,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
}
if (tabs.length > 1 || !tabs[0].selected) {
@@ -3912,7 +4030,7 @@
@@ -3912,7 +4031,7 @@
// Ensure we have an index if one was not provided.
if (typeof index != "number") {
// Move the new tab after another tab if needed, to the end otherwise.
@ -387,7 +389,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
if (
!bulkOrderedOpen &&
((openerTab &&
@@ -3935,7 +4053,7 @@
@@ -3935,7 +4054,7 @@
) {
index = Infinity;
} else if (previousTab.visible) {
@ -396,7 +398,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
} else if (previousTab == FirefoxViewHandler.tab) {
index = 0;
}
@@ -3958,18 +4076,18 @@
@@ -3958,18 +4077,18 @@
// Ensure index is within bounds.
if (tab.pinned) {
@ -420,7 +422,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
if (this.isTab(itemAfter) && itemAfter.group == tabGroup) {
// Place at the front of, or between tabs in, the same tab group
this.tabContainer.insertBefore(tab, itemAfter);
@@ -4290,6 +4408,9 @@
@@ -4290,6 +4409,9 @@
return;
}
@ -430,7 +432,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
this.removeTabs(selectedTabs, { telemetrySource });
}
@@ -4542,6 +4663,7 @@
@@ -4542,6 +4664,7 @@
telemetrySource,
} = {}
) {
@ -438,7 +440,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
// When 'closeWindowWithLastTab' pref is enabled, closing all tabs
// can be considered equivalent to closing the window.
if (
@@ -4626,6 +4748,7 @@
@@ -4626,6 +4749,7 @@
if (lastToClose) {
this.removeTab(lastToClose, aParams);
}
@ -446,7 +448,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
} catch (e) {
console.error(e);
}
@@ -4650,6 +4773,7 @@
@@ -4650,6 +4774,7 @@
telemetrySource,
} = {}
) {
@ -454,7 +456,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
if (UserInteraction.running("browser.tabs.opening", window)) {
UserInteraction.finish("browser.tabs.opening", window);
}
@@ -4663,6 +4787,12 @@
@@ -4663,6 +4788,12 @@
aTab._closeTimeNoAnimTimerId = Glean.browserTabclose.timeNoAnim.start();
}
@ -467,7 +469,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
// Handle requests for synchronously removing an already
// asynchronously closing tab.
if (!animate && aTab.closing) {
@@ -4677,7 +4807,9 @@
@@ -4677,7 +4808,9 @@
// frame created for it (for example, by updating the visually selected
// state).
let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width;
@ -478,7 +480,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
if (
!this._beginRemoveTab(aTab, {
closeWindowFastpath: true,
@@ -4840,7 +4972,7 @@
@@ -4840,7 +4973,7 @@
closeWindowWithLastTab != null
? closeWindowWithLastTab
: !window.toolbar.visible ||
@ -487,7 +489,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
if (closeWindow) {
// We've already called beforeunload on all the relevant tabs if we get here,
@@ -4864,6 +4996,7 @@
@@ -4864,6 +4997,7 @@
newTab = true;
}
@ -495,7 +497,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
aTab._endRemoveArgs = [closeWindow, newTab];
// swapBrowsersAndCloseOther will take care of closing the window without animation.
@@ -4903,9 +5036,7 @@
@@ -4903,9 +5037,7 @@
aTab._mouseleave();
if (newTab) {
@ -506,7 +508,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
} else {
TabBarVisibility.update();
}
@@ -5034,6 +5165,8 @@
@@ -5034,6 +5166,8 @@
this.tabs[i]._tPos = i;
}
@ -515,7 +517,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
if (!this._windowIsClosing) {
if (wasPinned) {
this.tabContainer._positionPinnedTabs();
@@ -5159,8 +5292,8 @@
@@ -5159,8 +5293,8 @@
return closedCount;
}
@ -526,7 +528,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
if (unloadBlocked) {
return;
}
@@ -5248,6 +5381,7 @@
@@ -5248,6 +5382,7 @@
}
let excludeTabs = new Set(aExcludeTabs);
@ -534,7 +536,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
// If this tab has a successor, it should be selectable, since
// hiding or closing a tab removes that tab as a successor.
@@ -5260,13 +5394,13 @@
@@ -5260,13 +5395,13 @@
!excludeTabs.has(aTab.owner) &&
Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")
) {
@ -550,7 +552,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
);
let tab = this.tabContainer.findNextTab(aTab, {
@@ -5282,7 +5416,7 @@
@@ -5282,7 +5417,7 @@
}
if (tab) {
@ -559,7 +561,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
}
// If no qualifying visible tab was found, see if there is a tab in
@@ -5303,7 +5437,7 @@
@@ -5303,7 +5438,7 @@
});
}
@ -568,7 +570,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
}
_blurTab(aTab) {
@@ -5704,10 +5838,10 @@
@@ -5704,10 +5839,10 @@
SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
}
@ -581,7 +583,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
aTab.selected ||
aTab.closing ||
// Tabs that are sharing the screen, microphone or camera cannot be hidden.
@@ -6001,7 +6135,7 @@
@@ -6001,7 +6136,7 @@
// Don't allow mixing pinned and unpinned tabs.
if (this.isTab(element) && element.pinned) {
@ -590,7 +592,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
} else {
tabIndex = Math.max(tabIndex, this.pinnedTabCount);
}
@@ -6028,9 +6162,16 @@
@@ -6028,9 +6163,16 @@
element,
() => {
let neighbor = this.tabs[tabIndex];
@ -608,7 +610,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
if (neighbor && this.isTab(element) && tabIndex > element._tPos) {
neighbor.after(element);
} else {
@@ -6099,7 +6240,9 @@
@@ -6099,7 +6241,9 @@
targetElement = targetElement.group;
}
}
@ -619,7 +621,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
// Don't allow mixing pinned and unpinned tabs.
if (element.pinned && !targetElement?.pinned) {
targetElement = this.tabs[this.pinnedTabCount - 1];
@@ -6109,7 +6252,13 @@
@@ -6109,7 +6253,13 @@
moveBefore = true;
}
@ -633,7 +635,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
if (element.pinned && this.tabContainer.verticalMode) {
return this.tabContainer.verticalPinnedTabsContainer;
}
@@ -6169,7 +6318,7 @@
@@ -6169,7 +6319,7 @@
if (!this.isTab(aTab)) {
throw new Error("Can only move a tab into a tab group");
}
@ -642,7 +644,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
return;
}
if (aTab.group && aTab.group.id === aGroup.id) {
@@ -6263,6 +6412,10 @@
@@ -6263,6 +6413,10 @@
moveActionCallback();
@ -653,7 +655,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
// Clear tabs cache after moving nodes because the order of tabs may have
// changed.
this.tabContainer._invalidateCachedTabs();
@@ -7080,7 +7233,7 @@
@@ -7080,7 +7234,7 @@
// preventDefault(). It will still raise the window if appropriate.
break;
}
@ -662,7 +664,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
window.focus();
aEvent.preventDefault();
break;
@@ -7981,6 +8134,7 @@
@@ -7981,6 +8135,7 @@
aWebProgress.isTopLevel
) {
this.mTab.setAttribute("busy", "true");
@ -670,7 +672,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
gBrowser._tabAttrModified(this.mTab, ["busy"]);
this.mTab._notselectedsinceload = !this.mTab.selected;
}
@@ -8954,7 +9108,7 @@ var TabContextMenu = {
@@ -8954,7 +9109,7 @@ var TabContextMenu = {
);
contextUnpinSelectedTabs.hidden =
!this.contextTab.pinned || !this.multiselected;
@ -679,7 +681,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..a2fd09d94746bbb8ba16c5e234c6e99c
// Move Tab items
let contextMoveTabOptions = document.getElementById(
"context_moveTabOptions"
@@ -9223,6 +9377,7 @@ var TabContextMenu = {
@@ -9223,6 +9378,7 @@ var TabContextMenu = {
telemetrySource: gBrowser.TabMetrics.METRIC_SOURCE.TAB_STRIP,
});
} else {

View file

@ -7,7 +7,10 @@
@namespace html 'http://www.w3.org/1999/xhtml';
:root {
--zen-settings-secondary-background: light-dark(#f2f4f4, color-mix(in srgb, var(--zen-colors-tertiary) 50%, #0f0f0f 50%));
--zen-settings-secondary-background: light-dark(
#f2f4f4,
color-mix(in srgb, var(--zen-colors-tertiary) 50%, #0f0f0f 50%)
);
--in-content-box-background: var(--zen-colors-tertiary) !important;
}

View file

@ -94,8 +94,16 @@
#appMenu-passwords-button,
#password-notification-icon,
#PopupAutoComplete > richlistbox > richlistitem[originaltype='generatedPassword'] > .two-line-wrapper > .ac-site-icon,
#PopupAutoComplete > richlistbox > richlistitem[originaltype='loginWithOrigin'] > .two-line-wrapper > .ac-site-icon,
#PopupAutoComplete
> richlistbox
> richlistitem[originaltype='generatedPassword']
> .two-line-wrapper
> .ac-site-icon,
#PopupAutoComplete
> richlistbox
> richlistitem[originaltype='loginWithOrigin']
> .two-line-wrapper
> .ac-site-icon,
#PopupAutoComplete > richlistbox > richlistitem[originaltype='login'] > .ac-site-icon {
list-style-image: url('passwords.svg') !important;
}
@ -125,13 +133,19 @@
}
#history-panelmenu,
.urlbarView-row[source='history'] > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-favicon,
.urlbarView-row[source='history']
> .urlbarView-row-inner
> .urlbarView-no-wrap
> .urlbarView-favicon,
#urlbar-engine-one-off-item-history,
#appMenu-history-button,
#appMenu-library-history-button,
#sidebar-switcher-history,
#zen-history-button,
#sidebar-box[sidebarcommand='viewHistorySidebar'] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon {
#sidebar-box[sidebarcommand='viewHistorySidebar']
> #sidebar-header
> #sidebar-switcher-target
> #sidebar-icon {
list-style-image: url('history.svg') !important;
}
@ -276,7 +290,10 @@
#appMenu-bookmarks-button,
#sidebar-switcher-bookmarks,
#appMenu-library-bookmarks-button,
#sidebar-box[sidebarcommand='viewBookmarksSidebar'] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon {
#sidebar-box[sidebarcommand='viewBookmarksSidebar']
> #sidebar-header
> #sidebar-switcher-target
> #sidebar-icon {
list-style-image: url('bookmark-star-on-tray.svg') !important;
}
@ -302,7 +319,10 @@
list-style-image: url('page-portrait.svg') !important;
}
#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate='invalid'] #identity-icon {
#urlbar:not(.searchButton)
> #urlbar-input-container
> #identity-box[pageproxystate='invalid']
#identity-icon {
list-style-image: url('search-glass.svg') !important;
}
@ -428,7 +448,10 @@
list-style-image: url('split.svg');
}
#sidebar-box[sidebarcommand='viewTabsSidebar'] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon,
#sidebar-box[sidebarcommand='viewTabsSidebar']
> #sidebar-header
> #sidebar-switcher-target
> #sidebar-icon,
#sidebar-switcher-tabs {
list-style-image: url('send-to-device.svg') !important;
}
@ -592,7 +615,10 @@
background-image: url('reload-to-stop.svg') !important;
}
#stop-reload-button[animate] > #reload-button > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image,
#stop-reload-button[animate]
> #reload-button
> .toolbarbutton-animatable-box
> .toolbarbutton-animatable-image,
#zen-sidebar-web-panel-reload[animate]
> #zen-sidebar-web-panel-reload-button
> .toolbarbutton-animatable-box
@ -630,7 +656,14 @@
),
:not(:not(menubar) > menu, #ContentSelectDropdown)
> menupopup
> menu:not(.menu-iconic, [type='checkbox'], [type='radio'], .in-menulist, .in-menulist menu, .unified-nav-current),
> menu:not(
.menu-iconic,
[type='checkbox'],
[type='radio'],
.in-menulist,
.in-menulist menu,
.unified-nav-current
),
#toggle_toolbar-menubar,
#PanelUI-history toolbarbutton,
#unified-extensions-context-menu menuitem {
@ -1112,10 +1145,18 @@ menuitem[id='placesContext_new:separator'] {
),
:not(:not(menubar) > menu, #ContentSelectDropdown)
> menupopup
> menu:not(.menu-iconic, [type='checkbox'], [type='radio'], .in-menulist, .in-menulist menu, .unified-nav-current),
> menu:not(
.menu-iconic,
[type='checkbox'],
[type='radio'],
.in-menulist,
.in-menulist menu,
.unified-nav-current
),
:not(:not(menubar) > menu, #ContentSelectDropdown) > menupopup > menucaption {
padding-inline-start: calc(
var(--fp-contextmenu-menuitem-padding-inline) + 16px + var(--fp-contextmenu-menuicon-margin-inline)
var(--fp-contextmenu-menuitem-padding-inline) + 16px +
var(--fp-contextmenu-menuicon-margin-inline)
) !important;
}

View file

@ -52,7 +52,11 @@ declare global {
setBadgeImage(aBadgeImage: imgIContainer, aPaintContext?: nsISVGPaintContext): void;
readonly isAppInDock: boolean;
ensureAppIsPinnedToDock(aAppPath?: string, aAppToReplacePath?: string): boolean;
launchAppBundle(aAppBundle: nsIFile, aArgs: string[], aLaunchOptions?: nsIAppBundleLaunchOptions): void;
launchAppBundle(
aAppBundle: nsIFile,
aArgs: string[],
aLaunchOptions?: nsIAppBundleLaunchOptions
): void;
}
// https://searchfox.org/mozilla-central/source/widget/nsIMacFinderProgress.idl

File diff suppressed because it is too large Load diff

View file

@ -27,7 +27,10 @@ declare global {
interface nsIApplicationChooser extends nsISupports {
init(parent: mozIDOMWindowProxy, title: string): void;
open(contentType: string, applicationChooserFinishedCallback: nsIApplicationChooserFinishedCallback): void;
open(
contentType: string,
applicationChooserFinishedCallback: nsIApplicationChooserFinishedCallback
): void;
}
// https://searchfox.org/mozilla-central/source/widget/nsIGtkTaskbarProgress.idl

View file

@ -30,8 +30,14 @@ type nsIGleanPingWithReason<T> = {
interface MessageListenerManagerMixin {
// Overloads that define `data` arg as required, since it's ~always expected.
addMessageListener(msg: string, listener: { receiveMessage(_: ReceiveMessageArgument & { data }) });
removeMessageListener(msg: string, listener: { receiveMessage(_: ReceiveMessageArgument & { data }) });
addMessageListener(
msg: string,
listener: { receiveMessage(_: ReceiveMessageArgument & { data }) }
);
removeMessageListener(
msg: string,
listener: { receiveMessage(_: ReceiveMessageArgument & { data }) }
);
}
interface MozQueryInterface {
@ -71,7 +77,12 @@ interface ComponentsExceptionOptions {
interface nsIException extends Exception {}
interface nsIXPCComponents_Exception {
(message?: string, resultOrOptions?: number | ComponentsExceptionOptions, stack?: nsIStackFrame, data?: object): nsIException;
(
message?: string,
resultOrOptions?: number | ComponentsExceptionOptions,
stack?: nsIStackFrame,
data?: object
): nsIException;
}
interface nsIXPCComponents_ID {

View file

@ -31,7 +31,11 @@ declare global {
// https://searchfox.org/mozilla-central/source/toolkit/components/aboutwindowsmessages/nsIAboutWindowsMessages.idl
interface nsIAboutWindowsMessages extends nsISupports {
getMessages(currentWindow: mozIDOMWindowProxy, messages: OutParam<string[][]>, windowTitles: OutParam<string[]>): void;
getMessages(
currentWindow: mozIDOMWindowProxy,
messages: OutParam<string[][]>,
windowTitles: OutParam<string[]>
): void;
}
// https://searchfox.org/mozilla-central/source/toolkit/components/alerts/nsIWindowsAlertsService.idl
@ -48,7 +52,9 @@ declare global {
type ImagePlacement = nsIWindowsAlertNotification_ImagePlacement;
}
interface nsIWindowsAlertNotification extends nsIAlertNotification, Enums<typeof nsIWindowsAlertNotification_ImagePlacement> {
interface nsIWindowsAlertNotification
extends nsIAlertNotification,
Enums<typeof nsIWindowsAlertNotification_ImagePlacement> {
imagePlacement: nsIWindowsAlertNotification.ImagePlacement;
}
@ -157,7 +163,12 @@ declare global {
// https://searchfox.org/mozilla-central/source/toolkit/components/taskscheduler/nsIWinTaskSchedulerService.idl
interface nsIWinTaskSchedulerService extends nsISupports {
registerTask(aFolderName: string, aTaskName: string, aDefinitionXML: string, aUpdateExisting?: boolean): void;
registerTask(
aFolderName: string,
aTaskName: string,
aDefinitionXML: string,
aUpdateExisting?: boolean
): void;
validateTaskDefinition(aDefinitionXML: string): i32;
getTaskXML(aFolderName: string, aTaskName: string): string;
getCurrentUserSid(): string;
@ -174,7 +185,11 @@ declare global {
obtainAndCacheFaviconAsync(faviconURL: nsIURI): Promise<any>;
isAvailable(): Promise<any>;
checkForRemovals(): Promise<any>;
populateJumpList(aTaskDescriptions: any, aCustomTitle: string, aCustomDescriptions: any): Promise<any>;
populateJumpList(
aTaskDescriptions: any,
aCustomTitle: string,
aCustomDescriptions: any
): Promise<any>;
clearJumpList(): Promise<any>;
}
@ -183,7 +198,11 @@ declare global {
// https://searchfox.org/mozilla-central/source/widget/nsITaskbarOverlayIconController.idl
interface nsITaskbarOverlayIconController extends nsISupports {
setOverlayIcon(statusIcon: imgIContainer, statusDescription: string, paintContext?: nsISVGPaintContext): void;
setOverlayIcon(
statusIcon: imgIContainer,
statusDescription: string,
paintContext?: nsISVGPaintContext
): void;
}
// https://searchfox.org/mozilla-central/source/widget/nsITaskbarPreview.idl
@ -259,7 +278,10 @@ declare global {
readonly available: boolean;
readonly defaultGroupId: string;
readonly defaultPrivateGroupId: string;
createTaskbarTabPreview(shell: nsIDocShell, controller: nsITaskbarPreviewController): nsITaskbarTabPreview;
createTaskbarTabPreview(
shell: nsIDocShell,
controller: nsITaskbarPreviewController
): nsITaskbarTabPreview;
getTaskbarWindowPreview(shell: nsIDocShell): nsITaskbarWindowPreview;
getTaskbarProgress(shell: nsIDocShell): nsITaskbarProgress;
getOverlayIconController(shell: nsIDocShell): nsITaskbarOverlayIconController;
@ -273,7 +295,11 @@ declare global {
interface nsIWindowsUIUtils extends nsISupports {
readonly systemSmallIconSize: i32;
readonly systemLargeIconSize: i32;
setWindowIcon(aWindow: mozIDOMWindowProxy, aSmallIcon: imgIContainer, aLargeIcon: imgIContainer): void;
setWindowIcon(
aWindow: mozIDOMWindowProxy,
aSmallIcon: imgIContainer,
aLargeIcon: imgIContainer
): void;
setWindowIconFromExe(aWindow: mozIDOMWindowProxy, aExe: string, aIndex: u16): void;
setWindowIconNoData(aWindow: mozIDOMWindowProxy): void;
readonly inWin10TabletMode: boolean;
@ -346,13 +372,19 @@ declare global {
nsIInstalledApplication: nsJSIID<nsIInstalledApplication>;
nsIAboutThirdParty: nsJSIID<nsIAboutThirdParty>;
nsIAboutWindowsMessages: nsJSIID<nsIAboutWindowsMessages>;
nsIWindowsAlertNotification: nsJSIID<nsIWindowsAlertNotification, typeof nsIWindowsAlertNotification_ImagePlacement>;
nsIWindowsAlertNotification: nsJSIID<
nsIWindowsAlertNotification,
typeof nsIWindowsAlertNotification_ImagePlacement
>;
nsIWindowsAlertsService: nsJSIID<nsIWindowsAlertsService>;
nsIDefaultAgent: nsJSIID<nsIDefaultAgent>;
nsIWindowsMutex: nsJSIID<nsIWindowsMutex>;
nsIWindowsMutexFactory: nsJSIID<nsIWindowsMutexFactory>;
nsIGeolocationUIUtilsWin: nsJSIID<nsIGeolocationUIUtilsWin>;
nsIWindowsShellService: nsJSIID<nsIWindowsShellService, typeof nsIWindowsShellService_LaunchOnLoginEnabledEnumerator>;
nsIWindowsShellService: nsJSIID<
nsIWindowsShellService,
typeof nsIWindowsShellService_LaunchOnLoginEnabledEnumerator
>;
nsIWinTaskSchedulerService: nsJSIID<nsIWinTaskSchedulerService>;
nsIJumpListBuilder: nsJSIID<nsIJumpListBuilder>;
nsITaskbarOverlayIconController: nsJSIID<nsITaskbarOverlayIconController>;

File diff suppressed because it is too large Load diff

View file

@ -164,7 +164,11 @@ declare namespace MockedExports {
removeObserver: (aDomain: string, aObserver: PrefObserver) => void;
};
type PrefObserverFunction = (aSubject: nsIPrefBranch, aTopic: 'nsPref:changed', aData: string) => unknown;
type PrefObserverFunction = (
aSubject: nsIPrefBranch,
aTopic: 'nsPref:changed',
aData: string
) => unknown;
type PrefObserver = PrefObserverFunction | { observe: PrefObserverFunction };
interface nsIURI {}
@ -216,7 +220,9 @@ declare namespace MockedExports {
GetFeatures: () => string[];
getProfileDataAsync: (sinceTime?: number) => Promise<object>;
getProfileDataAsArrayBuffer: (sinceTime?: number) => Promise<ArrayBuffer>;
getProfileDataAsGzippedArrayBuffer: (sinceTime?: number) => Promise<ProfileAndAdditionalInformation>;
getProfileDataAsGzippedArrayBuffer: (
sinceTime?: number
) => Promise<ProfileAndAdditionalInformation>;
IsActive: () => boolean;
sharedLibraries: SharedLibrary[];
};
@ -273,7 +279,10 @@ declare namespace MockedExports {
const PlaceUtilsSYSMJS: {
PlacesUtils: {
promiseFaviconData: (pageUrl: string | URL | nsIURI, preferredWidth?: number) => Promise<FaviconData>;
promiseFaviconData: (
pageUrl: string | URL | nsIURI,
preferredWidth?: number
) => Promise<FaviconData>;
// TS-TODO: Add the rest.
};
};
@ -429,8 +438,16 @@ declare interface XULCommandEvent extends Event {
}
declare interface XULElementWithCommandHandler {
addEventListener: (type: 'command', handler: (event: XULCommandEvent) => void, isCapture?: boolean) => void;
removeEventListener: (type: 'command', handler: (event: XULCommandEvent) => void, isCapture?: boolean) => void;
addEventListener: (
type: 'command',
handler: (event: XULCommandEvent) => void,
isCapture?: boolean
) => void;
removeEventListener: (
type: 'command',
handler: (event: XULCommandEvent) => void,
isCapture?: boolean
) => void;
}
declare type nsIPrefBranch = MockedExports.nsIPrefBranch;

View file

@ -65,7 +65,9 @@ var gZenCommonActions = {
if (currentUrl) {
let str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
str.data = currentUrl;
let transferable = Cc['@mozilla.org/widget/transferable;1'].createInstance(Ci.nsITransferable);
let transferable = Cc['@mozilla.org/widget/transferable;1'].createInstance(
Ci.nsITransferable
);
transferable.init(getLoadContext());
transferable.addDataFlavor('text/plain');
transferable.setTransferData('text/plain', str);
@ -80,7 +82,9 @@ var gZenCommonActions = {
const markdownLink = `[${tabTitle}](${currentUrl})`;
let str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
str.data = markdownLink;
let transferable = Cc['@mozilla.org/widget/transferable;1'].createInstance(Ci.nsITransferable);
let transferable = Cc['@mozilla.org/widget/transferable;1'].createInstance(
Ci.nsITransferable
);
transferable.init(getLoadContext());
transferable.addDataFlavor('text/plain');
transferable.setTransferData('text/plain', str);

View file

@ -103,8 +103,13 @@ export var ZenCustomizableUI = new (class {
_moveWindowButtons(window) {
const windowControls = window.document.getElementsByClassName('titlebar-buttonbox-container');
const toolboxIcons = window.document.getElementById('zen-sidebar-top-buttons-customization-target');
if (window.AppConstants.platform === 'macosx' || window.matchMedia('(-moz-gtk-csd-reversed-placement)').matches) {
const toolboxIcons = window.document.getElementById(
'zen-sidebar-top-buttons-customization-target'
);
if (
window.AppConstants.platform === 'macosx' ||
window.matchMedia('(-moz-gtk-csd-reversed-placement)').matches
) {
for (let i = 0; i < windowControls.length; i++) {
if (i === 0) {
toolboxIcons.prepend(windowControls[i]);
@ -131,7 +136,11 @@ export var ZenCustomizableUI = new (class {
}
registerToolbarNodes(window) {
window.CustomizableUI.registerToolbarNode(window.document.getElementById('zen-sidebar-top-buttons'));
window.CustomizableUI.registerToolbarNode(window.document.getElementById('zen-sidebar-bottom-buttons'));
window.CustomizableUI.registerToolbarNode(
window.document.getElementById('zen-sidebar-top-buttons')
);
window.CustomizableUI.registerToolbarNode(
window.document.getElementById('zen-sidebar-bottom-buttons')
);
}
})();

View file

@ -37,7 +37,10 @@
this._checkForWelcomePage();
document.l10n.setAttributes(document.getElementById('tabs-newtab-button'), 'tabs-toolbar-new-tab');
document.l10n.setAttributes(
document.getElementById('tabs-newtab-button'),
'tabs-toolbar-new-tab'
);
} catch (e) {
console.error('ZenThemeModifier: Error initializing browser layout', e);
}
@ -104,7 +107,9 @@
}
)
.then(() => {
for (let elem of document.querySelectorAll('#browser > *, #urlbar, #tabbrowser-tabbox > *')) {
for (let elem of document.querySelectorAll(
'#browser > *, #urlbar, #tabbrowser-tabbox > *'
)) {
elem.style.removeProperty('opacity');
}
});
@ -141,7 +146,10 @@
_initSidebarScrolling() {
// Disable smooth scroll
const canSmoothScroll = Services.prefs.getBoolPref('zen.startup.smooth-scroll-in-tabs', false);
const canSmoothScroll = Services.prefs.getBoolPref(
'zen.startup.smooth-scroll-in-tabs',
false
);
const tabsWrapper = document.getElementById('zen-tabs-wrapper');
gBrowser.tabContainer.addEventListener('wheel', (event) => {
if (canSmoothScroll) return;
@ -162,7 +170,9 @@
window.requestAnimationFrame(() => {
tabContainer.arrowScrollbox.toggleAttribute('overflowing', overflowing);
tabContainer.arrowScrollbox.dispatchEvent(new CustomEvent(overflowing ? 'overflow' : 'underflow'));
tabContainer.arrowScrollbox.dispatchEvent(
new CustomEvent(overflowing ? 'overflow' : 'underflow')
);
});
});
observer.observe(tabsWrapper);
@ -180,7 +190,10 @@
_checkForWelcomePage() {
if (!Services.prefs.getBoolPref('zen.welcome-screen.seen', false)) {
Services.prefs.setBoolPref('zen.welcome-screen.seen', true);
Services.scriptloader.loadSubScript('chrome://browser/content/zen-components/ZenWelcome.mjs', window);
Services.scriptloader.loadSubScript(
'chrome://browser/content/zen-components/ZenWelcome.mjs',
window
);
}
},
};

View file

@ -9,22 +9,41 @@ var gZenUIManager = {
init() {
document.addEventListener('popupshowing', this.onPopupShowing.bind(this));
document.addEventListener('popuphidden', this.onPopupHidden.bind(this));
XPCOMUtils.defineLazyPreferenceGetter(this, 'sidebarHeightThrottle', 'zen.view.sidebar-height-throttle', 500);
XPCOMUtils.defineLazyPreferenceGetter(this, 'contentElementSeparation', 'zen.theme.content-element-separation', 0);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'sidebarHeightThrottle',
'zen.view.sidebar-height-throttle',
500
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'contentElementSeparation',
'zen.theme.content-element-separation',
0
);
XPCOMUtils.defineLazyPreferenceGetter(this, 'urlbarWaitToClear', 'zen.urlbar.wait-to-clear', 0);
XPCOMUtils.defineLazyPreferenceGetter(this, 'urlbarShowDomainOnly', 'zen.urlbar.show-domain-only-in-sidebar', true);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'urlbarShowDomainOnly',
'zen.urlbar.show-domain-only-in-sidebar',
true
);
gURLBar._zenTrimURL = this.urlbarTrim.bind(this);
ChromeUtils.defineLazyGetter(this, 'motion', () => {
return ChromeUtils.importESModule('chrome://browser/content/zen-vendor/motion.min.mjs', { global: 'current' });
return ChromeUtils.importESModule('chrome://browser/content/zen-vendor/motion.min.mjs', {
global: 'current',
});
});
ChromeUtils.defineLazyGetter(this, '_toastContainer', () => {
return document.getElementById('zen-toast-container');
});
new ResizeObserver(this.updateTabsToolbar.bind(this)).observe(document.getElementById('TabsToolbar'));
new ResizeObserver(this.updateTabsToolbar.bind(this)).observe(
document.getElementById('TabsToolbar')
);
new ResizeObserver(
gZenCommonActions.throttle(
@ -132,7 +151,8 @@ var gZenUIManager = {
// we also ignore menus inside panels
if (
!el.contains(showEvent.explicitOriginalTarget) ||
(showEvent.explicitOriginalTarget instanceof Element && showEvent.explicitOriginalTarget?.closest('panel'))
(showEvent.explicitOriginalTarget instanceof Element &&
showEvent.explicitOriginalTarget?.closest('panel'))
) {
continue;
}
@ -202,7 +222,9 @@ var gZenUIManager = {
const timeSinceLastSwitch = now - this._tabSwitchState.lastSwitchTime;
if (timeSinceLastSwitch < this._tabSwitchState.debounceTime) {
await new Promise((resolve) => setTimeout(resolve, this._tabSwitchState.debounceTime - timeSinceLastSwitch));
await new Promise((resolve) =>
setTimeout(resolve, this._tabSwitchState.debounceTime - timeSinceLastSwitch)
);
}
// Execute operation
@ -247,7 +269,11 @@ var gZenUIManager = {
return false;
}
const shouldOpenURLBar = gZenVerticalTabsManager._canReplaceNewTab && !werePassedURL && !searchClipboard && where === 'tab';
const shouldOpenURLBar =
gZenVerticalTabsManager._canReplaceNewTab &&
!werePassedURL &&
!searchClipboard &&
where === 'tab';
if (!shouldOpenURLBar) {
return false;
@ -323,7 +349,12 @@ var gZenUIManager = {
gURLBar.removeAttribute('zen-newtab');
// Safely restore tab visual state with proper validation
if (this._lastTab && !this._lastTab.closing && this._lastTab.ownerGlobal && !this._lastTab.ownerGlobal.closed) {
if (
this._lastTab &&
!this._lastTab.closing &&
this._lastTab.ownerGlobal &&
!this._lastTab.ownerGlobal.closed
) {
this._lastTab._visuallySelected = true;
this._lastTab = null;
}
@ -421,12 +452,14 @@ var gZenUIManager = {
clearTimeout(this._toastTimeouts[messageId]);
}
this._toastTimeouts[messageId] = setTimeout(() => {
this.motion.animate(toast, { opacity: [1, 0], scale: [1, 0.5] }, { duration: 0.2, bounce: 0 }).then(() => {
toast.remove();
if (this._toastContainer.children.length === 0) {
this._toastContainer.setAttribute('hidden', true);
}
});
this.motion
.animate(toast, { opacity: [1, 0], scale: [1, 0.5] }, { duration: 0.2, bounce: 0 })
.then(() => {
toast.remove();
if (this._toastContainer.children.length === 0) {
this._toastContainer.setAttribute('hidden', true);
}
});
}, options.timeout || 3000);
},
@ -457,7 +490,12 @@ var gZenVerticalTabsManager = {
);
});
XPCOMUtils.defineLazyPreferenceGetter(this, '_canReplaceNewTab', 'zen.urlbar.replace-newtab', true);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_canReplaceNewTab',
'zen.urlbar.replace-newtab',
true
);
var updateEvent = this._updateEvent.bind(this);
var onPrefChange = this._onPrefChange.bind(this);
@ -506,7 +544,9 @@ var gZenVerticalTabsManager = {
if (this.__topButtonsSeparatorElement) {
return this.__topButtonsSeparatorElement;
}
this.__topButtonsSeparatorElement = document.getElementById('zen-sidebar-top-buttons-separator');
this.__topButtonsSeparatorElement = document.getElementById(
'zen-sidebar-top-buttons-separator'
);
return this.__topButtonsSeparatorElement;
},
@ -573,7 +613,10 @@ var gZenVerticalTabsManager = {
async _preCustomize() {
await this._multiWindowFeature.foreachWindowAsActive(async (browser) => {
browser.gZenVerticalTabsManager._updateEvent({ forCustomizableMode: true, dontRebuildAreas: true });
browser.gZenVerticalTabsManager._updateEvent({
forCustomizableMode: true,
dontRebuildAreas: true,
});
});
this.rebuildAreas();
this.navigatorToolbox.setAttribute('zen-sidebar-expanded', 'true');
@ -588,10 +631,34 @@ var gZenVerticalTabsManager = {
},
initializePreferences(updateEvent) {
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsVerticalTabs', 'zen.tabs.vertical', true, updateEvent);
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsRightSide', 'zen.tabs.vertical.right-side', false, updateEvent);
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsUseSingleToolbar', 'zen.view.use-single-toolbar', false, updateEvent);
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsSidebarExpanded', 'zen.view.sidebar-expanded', false, updateEvent);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_prefsVerticalTabs',
'zen.tabs.vertical',
true,
updateEvent
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_prefsRightSide',
'zen.tabs.vertical.right-side',
false,
updateEvent
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_prefsUseSingleToolbar',
'zen.view.use-single-toolbar',
false,
updateEvent
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_prefsSidebarExpanded',
'zen.view.sidebar-expanded',
false,
updateEvent
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_prefsSidebarExpandedMaxWidth',
@ -648,7 +715,10 @@ var gZenVerticalTabsManager = {
this._updateMaxWidth();
if (window.docShell) {
window.docShell.treeOwner.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIAppWindow).rollupAllPopups();
window.docShell.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIAppWindow)
.rollupAllPopups();
}
const topButtons = document.getElementById('zen-sidebar-top-buttons');
@ -663,7 +733,10 @@ var gZenVerticalTabsManager = {
const titlebar = document.getElementById('titlebar');
gBrowser.tabContainer.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal');
gBrowser.tabContainer.arrowScrollbox.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal');
gBrowser.tabContainer.arrowScrollbox.setAttribute(
'orient',
isVerticalTabs ? 'vertical' : 'horizontal'
);
// on purpose, we set the orient to horizontal, because the arrowScrollbox is vertical
gBrowser.tabContainer.arrowScrollbox.scrollbox.setAttribute(
'orient',
@ -775,7 +848,13 @@ var gZenVerticalTabsManager = {
}
// Case: single toolbar, not compact mode, not right side and macos styled buttons
if (!doNotChangeWindowButtons && isSingleToolbar && !isCompactMode && !isRightSide && !this.isWindowsStyledButtons) {
if (
!doNotChangeWindowButtons &&
isSingleToolbar &&
!isCompactMode &&
!isRightSide &&
!this.isWindowsStyledButtons
) {
topButtons.prepend(windowButtons);
}
// Case: single toolbar, compact mode, right side and windows styled buttons
@ -890,7 +969,11 @@ var gZenVerticalTabsManager = {
}
if (this._tabEdited.getAttribute('zen-pin-id')) {
// Update pin title in storage
await gZenPinnedTabManager.updatePinTitle(this._tabEdited, this._tabEdited.label, !!newName);
await gZenPinnedTabManager.updatePinTitle(
this._tabEdited,
this._tabEdited.label,
!!newName
);
}
document.documentElement.removeAttribute('zen-renaming-tab');
@ -923,7 +1006,11 @@ var gZenVerticalTabsManager = {
)
return;
this._tabEdited = event.target.closest('.tabbrowser-tab');
if (!this._tabEdited || !this._tabEdited.pinned || this._tabEdited.hasAttribute('zen-essential')) {
if (
!this._tabEdited ||
!this._tabEdited.pinned ||
this._tabEdited.hasAttribute('zen-essential')
) {
this._tabEdited = null;
return;
}

View file

@ -177,7 +177,11 @@
.titlebar-buttonbox-container {
/* Draw 3 dots as background to represent the window controls,
all with the same cololr as the titlebar */
background-image: radial-gradient(circle, var(--zen-toolbar-element-bg) 6px, transparent 0.5px);
background-image: radial-gradient(
circle,
var(--zen-toolbar-element-bg) 6px,
transparent 0.5px
);
background-size: 20px 22px;
background-position: 53% 50%;

View file

@ -11,7 +11,8 @@
:root {
--panel-subview-body-padding: 2px 0;
--arrowpanel-menuitem-border-radius: 5px;
--arrowpanel-menuitem-margin: var(--uc-arrowpanel-menuitem-margin-block) var(--uc-arrowpanel-menuitem-margin-inline);
--arrowpanel-menuitem-margin: var(--uc-arrowpanel-menuitem-margin-block)
var(--uc-arrowpanel-menuitem-margin-inline);
--arrowpanel-menuitem-padding-block: 8px;
--arrowpanel-menuitem-padding-inline: 14px;
--uc-arrowpanel-menuicon-margin-inline: 14px;
@ -22,7 +23,9 @@
--uc-panel-zoom-button-padding: 8px;
--uc-panel-zoom-button-inline-padding: 9px;
--uc-panel-zoom-padding-block: calc(var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block));
--uc-panel-zoom-padding-block: calc(
var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block)
);
--uc-autocomplete-panel-menuitem-margin: 4px;
--uc-autocomplete-panel-menuicon-padding-inline: 14px;
@ -62,7 +65,9 @@ panel {
}
.widget-overflow-list .toolbarbutton-1:not(.toolbarbutton-combined) > .toolbarbutton-text,
.subviewbutton:not(#appMenu-zoom-controls > .subviewbutton) > .toolbarbutton-icon + .toolbarbutton-text,
.subviewbutton:not(#appMenu-zoom-controls > .subviewbutton)
> .toolbarbutton-icon
+ .toolbarbutton-text,
#appMenu-fxa-label2 > vbox {
padding-inline-start: var(--uc-arrowpanel-menuicon-margin-inline);
}
@ -101,7 +106,9 @@ panel {
/* zoom controls */
#appMenu-zoom-controls {
border-top: 1px solid var(--panel-separator-color);
padding-inline: calc(var(--arrowpanel-menuitem-padding-inline) + var(--uc-arrowpanel-menuitem-margin-inline))
padding-inline: calc(
var(--arrowpanel-menuitem-padding-inline) + var(--uc-arrowpanel-menuitem-margin-inline)
)
var(--uc-arrowpanel-menuitem-margin-inline);
padding-block: var(--uc-panel-zoom-padding-block);
margin: var(--panel-separator-margin-vertical) 0 calc(var(--panel-separator-margin-vertical) * -1);
@ -118,7 +125,9 @@ panel {
/* #appMenu-zoomReduce-button2, */
#appMenu-zoom-controls > #appMenu-fullscreen-button2 {
margin-left: calc((var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block)) * 2 + 1px);
margin-left: calc(
(var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block)) * 2 + 1px
);
}
#appMenu-zoom-controls > #appMenu-fullscreen-button2::before {

View file

@ -35,9 +35,17 @@
--zen-colors-hover-bg: color-mix(in srgb, var(--zen-primary-color) 90%, white 10%);
--zen-colors-primary-foreground: var(--zen-branding-bg-reverse);
--zen-colors-border: color-mix(in srgb, var(--zen-colors-secondary) 97%, black 3%);
--zen-colors-border-contrast: color-mix(in srgb, var(--zen-colors-secondary) 10%, rgba(181, 181, 181, 0.11) 90%);
--zen-colors-border-contrast: color-mix(
in srgb,
var(--zen-colors-secondary) 10%,
rgba(181, 181, 181, 0.11) 90%
);
--zen-colors-input-bg: color-mix(in srgb, var(--zen-primary-color) 1%, var(--zen-colors-tertiary) 99%);
--zen-colors-input-bg: color-mix(
in srgb,
var(--zen-primary-color) 1%,
var(--zen-colors-tertiary) 99%
);
--zen-dialog-background: var(--zen-colors-tertiary);
--zen-urlbar-background: color-mix(in srgb, var(--zen-primary-color) 3%, #f4f4f4 97%);
@ -71,7 +79,11 @@
/* This is like the secondary button */
--in-content-button-background: transparent !important;
--in-content-button-text-color: var(--zen-secondary-btn-color) !important;
--in-content-button-background-hover: color-mix(in srgb, currentColor 3%, transparent 97%) !important;
--in-content-button-background-hover: color-mix(
in srgb,
currentColor 3%,
transparent 97%
) !important;
--button-bgcolor: var(--in-content-button-background) !important;
--button-hover-bgcolor: var(--in-content-button-background-hover) !important;
--button-hover-color: var(--in-content-button-text-color-hover) !important;
@ -95,7 +107,11 @@
--link-color: var(--zen-branding-bg-reverse) !important;
--link-color-hover: var(--zen-colors-primary-foreground) !important;
--link-color-active: color-mix(in srgb, var(--zen-colors-primary-foreground) 80%, transparent 20%) !important;
--link-color-active: color-mix(
in srgb,
var(--zen-colors-primary-foreground) 80%,
transparent 20%
) !important;
--in-content-page-background: var(--zen-colors-tertiary) !important;
--zen-in-content-dialog-background: var(--zen-colors-tertiary);
@ -110,7 +126,11 @@
--zen-toolbar-button-inner-padding: 6px;
--toolbarbutton-outer-padding: 4px;
--toolbarbutton-hover-background: color-mix(in srgb, var(--zen-branding-bg-reverse) 10%, transparent 90%);
--toolbarbutton-hover-background: color-mix(
in srgb,
var(--zen-branding-bg-reverse) 10%,
transparent 90%
);
/* Other colors */
--urlbar-box-bgcolor: var(--zen-urlbar-background) !important;
@ -143,7 +163,8 @@
--fp-contextmenu-menuicon-margin-inline: 12px;
--fp-contextmenu-menuitem-margin-inline: calc(4px - var(--fp-contextmenu-menuitem-border-width));
--fp-contextmenu-menuitem-margin-block: 0px;
--fp-contextmenu-menuitem-margin: var(--fp-contextmenu-menuitem-margin-block) var(--fp-contextmenu-menuitem-margin-inline);
--fp-contextmenu-menuitem-margin: var(--fp-contextmenu-menuitem-margin-block)
var(--fp-contextmenu-menuitem-margin-inline);
--fp-contextmenu-separator-vertical: calc(4px - var(--fp-contextmenu-menuitem-border-width));
--fp-contextmenu-separator-horizontal: 0;
--fp-contextmenu-bgcolor: light-dark(Menu, rgb(43 42 51 / 0.95));
@ -163,7 +184,11 @@
background: transparent;
--zen-themed-toolbar-bg-transparent: transparent;
@media -moz-pref('widget.windows.mica.toplevel-backdrop', 2) {
--zen-themed-toolbar-bg-transparent: color-mix(in srgb, var(--zen-themed-toolbar-bg) 35%, transparent 65%);
--zen-themed-toolbar-bg-transparent: color-mix(
in srgb,
var(--zen-themed-toolbar-bg) 35%,
transparent 65%
);
}
}
@ -179,7 +204,11 @@
--zen-active-tab-scale: 0.98;
/* Define tab hover background color */
--tab-hover-background-color: color-mix(in srgb, var(--toolbarbutton-hover-background) 50%, transparent 50%);
--tab-hover-background-color: color-mix(
in srgb,
var(--toolbarbutton-hover-background) 50%,
transparent 50%
);
/* Nativity */
--zen-native-content-radius: var(--zen-border-radius);
@ -218,20 +247,48 @@
:root {
--zen-in-content-dialog-background: var(--zen-branding-bg);
--zen-dark-color-mix-base: var(--zen-branding-bg);
--zen-colors-primary: color-mix(in srgb, var(--zen-primary-color) 20%, var(--zen-dark-color-mix-base) 80%);
--zen-colors-secondary: color-mix(in srgb, var(--zen-primary-color) 30%, var(--zen-dark-color-mix-base) 70%);
--zen-colors-tertiary: color-mix(in srgb, var(--zen-primary-color) 1%, var(--zen-dark-color-mix-base) 99%);
--zen-colors-primary: color-mix(
in srgb,
var(--zen-primary-color) 20%,
var(--zen-dark-color-mix-base) 80%
);
--zen-colors-secondary: color-mix(
in srgb,
var(--zen-primary-color) 30%,
var(--zen-dark-color-mix-base) 70%
);
--zen-colors-tertiary: color-mix(
in srgb,
var(--zen-primary-color) 1%,
var(--zen-dark-color-mix-base) 99%
);
--zen-colors-hover-bg: color-mix(in srgb, var(--zen-primary-color) 90%, var(--zen-dark-color-mix-base) 10%);
--zen-colors-hover-bg: color-mix(
in srgb,
var(--zen-primary-color) 90%,
var(--zen-dark-color-mix-base) 10%
);
--zen-colors-primary-foreground: color-mix(in srgb, var(--zen-primary-color) 80%, white 20%);
--zen-colors-input-bg: color-mix(in srgb, var(--zen-primary-color) 1%, var(--zen-dark-color-mix-base) 99%);
--zen-colors-input-bg: color-mix(
in srgb,
var(--zen-primary-color) 1%,
var(--zen-dark-color-mix-base) 99%
);
--zen-colors-border: color-mix(in srgb, var(--zen-colors-secondary) 20%, rgb(79, 79, 79) 80%);
--zen-colors-border-contrast: color-mix(in srgb, var(--zen-colors-secondary) 10%, rgba(255, 255, 255, 0.11) 90%);
--zen-colors-border-contrast: color-mix(
in srgb,
var(--zen-colors-secondary) 10%,
rgba(255, 255, 255, 0.11) 90%
);
--zen-dialog-background: var(--zen-dark-color-mix-base);
--zen-urlbar-background: color-mix(in srgb, var(--zen-primary-color) 4%, rgb(24, 24, 24) 96%);
--zen-browser-gradient-base: color-mix(in srgb, var(--zen-primary-color) 30%, var(--zen-dark-color-mix-base) 70%);
--zen-browser-gradient-base: color-mix(
in srgb,
var(--zen-primary-color) 30%,
var(--zen-dark-color-mix-base) 70%
);
}
}

View file

@ -137,7 +137,9 @@
margin-right: 0px !important;
}
#identity-box:has(#identity-permission-box:is([hasPermissions], [hasSharingIcon])):not([pageproxystate='invalid'])
#identity-box:has(#identity-permission-box:is([hasPermissions], [hasSharingIcon])):not(
[pageproxystate='invalid']
)
#identity-icon-box {
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
@ -208,9 +210,9 @@
}
#urlbar[open]
:is(#tracking-protection-icon-container, .urlbar-page-action, .identity-box-button):not([hidden='true']):not(
#identity-permission-box
),
:is(#tracking-protection-icon-container, .urlbar-page-action, .identity-box-button):not(
[hidden='true']
):not(#identity-permission-box),
#urlbar:hover #identity-icon-box {
opacity: 1 !important;
margin-inline-start: 0 !important;
@ -263,7 +265,9 @@
border-radius: 999px;
margin: 0 4px 0 0 !important;
padding: 0 4px;
min-width: calc(var(--urlbar-min-height) - 4px - 4 * var(--urlbar-container-padding)) !important;
min-width: calc(
var(--urlbar-min-height) - 4px - 4 * var(--urlbar-container-padding)
) !important;
height: calc(var(--urlbar-min-height) - 4px - 4 * var(--urlbar-container-padding)) !important;
justify-content: center;
gap: 8px;
@ -286,7 +290,8 @@ button.popup-notification-dropmarker {
border-bottom-left-radius: 0 !important;
}
.panel-footer:has(button.popup-notification-dropmarker:not([hidden='true'])) button.popup-notification-secondary-button {
.panel-footer:has(button.popup-notification-dropmarker:not([hidden='true']))
button.popup-notification-secondary-button {
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
@ -361,7 +366,9 @@ button.popup-notification-dropmarker {
/* Border radius on hover */
#urlbar .urlbar-page-action,
#urlbar #tracking-protection-icon-container,
#urlbar:not([breakout-extend='true']) #identity-box:is(:not(.chromeUI), [pageproxystate='invalid']) #identity-icon-box {
#urlbar:not([breakout-extend='true'])
#identity-box:is(:not(.chromeUI), [pageproxystate='invalid'])
#identity-icon-box {
border-radius: var(--urlbar-icon-border-radius) !important;
}
@ -598,7 +605,11 @@ button.popup-notification-dropmarker {
&:hover {
.urlbarView-favicon,
& {
background-color: color-mix(in srgb, var(--zen-branding-bg-reverse) 5%, transparent 95%) !important;
background-color: color-mix(
in srgb,
var(--zen-branding-bg-reverse) 5%,
transparent 95%
) !important;
}
}

View file

@ -69,7 +69,9 @@ document.addEventListener(
gZenThemePicker.openThemePicker(event);
break;
case 'cmd_zenChangeWorkspaceTab':
ZenWorkspaces.changeTabWorkspace(event.sourceEvent.target.getAttribute('zen-workspace-id'));
ZenWorkspaces.changeTabWorkspace(
event.sourceEvent.target.getAttribute('zen-workspace-id')
);
break;
case 'cmd_zenToggleTabsOnRight':
gZenVerticalTabsManager.toggleTabsOnRight();

View file

@ -10,7 +10,11 @@
* FOR ANY WEBSITE THAT WOULD NEED TO USE THE ACCENT COLOR, ETC
*/
const kZenThemePrefsList = ['zen.theme.accent-color', 'zen.theme.border-radius', 'zen.theme.content-element-separation'];
const kZenThemePrefsList = [
'zen.theme.accent-color',
'zen.theme.border-radius',
'zen.theme.content-element-separation',
];
const kZenMaxElementSeparation = 12;
/**
@ -79,7 +83,10 @@ var ZenThemeModifier = {
},
get elementSeparation() {
return Math.min(Services.prefs.getIntPref('zen.theme.content-element-separation'), kZenMaxElementSeparation);
return Math.min(
Services.prefs.getIntPref('zen.theme.content-element-separation'),
kZenMaxElementSeparation
);
},
/**

View file

@ -21,7 +21,9 @@ XPCOMUtils.defineLazyPreferenceGetter(
true
);
ChromeUtils.defineLazyGetter(lazyCompactMode, 'mainAppWrapper', () => document.getElementById('zen-main-app-wrapper'));
ChromeUtils.defineLazyGetter(lazyCompactMode, 'mainAppWrapper', () =>
document.getElementById('zen-main-app-wrapper')
);
var gZenCompactModeManager = {
_flashTimeouts: {},
@ -31,7 +33,8 @@ var gZenCompactModeManager = {
preInit() {
// Remove it before initializing so we can properly calculate the width
// of the sidebar at startup and avoid overflowing items not being hidden
const isCompactMode = lazyCompactMode.mainAppWrapper.getAttribute('zen-compact-mode') === 'true';
const isCompactMode =
lazyCompactMode.mainAppWrapper.getAttribute('zen-compact-mode') === 'true';
lazyCompactMode.mainAppWrapper.removeAttribute('zen-compact-mode');
this._wasInCompactMode = isCompactMode;
@ -41,15 +44,23 @@ var gZenCompactModeManager = {
init() {
this.addMouseActions();
Services.prefs.addObserver('zen.tabs.vertical.right-side', this._updateSidebarIsOnRight.bind(this));
Services.prefs.addObserver(
'zen.tabs.vertical.right-side',
this._updateSidebarIsOnRight.bind(this)
);
gZenUIManager.addPopupTrackingAttribute(this.sidebar);
gZenUIManager.addPopupTrackingAttribute(document.getElementById('zen-appcontent-navbar-container'));
gZenUIManager.addPopupTrackingAttribute(
document.getElementById('zen-appcontent-navbar-container')
);
// Clear hover states when window state changes (minimize, maximize, etc.)
window.addEventListener('sizemodechange', () => this._clearAllHoverStates());
this._canShowBackgroundTabToast = Services.prefs.getBoolPref('zen.view.compact.show-background-tab-toast', true);
this._canShowBackgroundTabToast = Services.prefs.getBoolPref(
'zen.view.compact.show-background-tab-toast',
true
);
if (AppConstants.platform == 'macosx') {
window.addEventListener('mouseover', (event) => {
@ -66,7 +77,10 @@ var gZenCompactModeManager = {
},
set preference(value) {
if (this.preference === value || document.documentElement.hasAttribute('zen-compact-animating')) {
if (
this.preference === value ||
document.documentElement.hasAttribute('zen-compact-animating')
) {
if (typeof this._wasInCompactMode !== 'undefined') {
// We wont do anything with it anyway, so we remove it
delete this._wasInCompactMode;
@ -101,7 +115,12 @@ var gZenCompactModeManager = {
if (aInstant) {
gZenVerticalTabsManager.recalculateURLBarHeight();
}
if (!aInstant && this.preference && lazyCompactMode.COMPACT_MODE_FLASH_ENABLED && !gZenGlanceManager._animating) {
if (
!aInstant &&
this.preference &&
lazyCompactMode.COMPACT_MODE_FLASH_ENABLED &&
!gZenGlanceManager._animating
) {
this.flashSidebar();
}
},
@ -192,11 +211,15 @@ var gZenCompactModeManager = {
// Get the splitter width before hiding it (we need to hide it before animating on right)
document.documentElement.setAttribute('zen-compact-animating', 'true');
// We need to set the splitter width before hiding it
let splitterWidth = document.getElementById('zen-sidebar-splitter').getBoundingClientRect().width;
let splitterWidth = document
.getElementById('zen-sidebar-splitter')
.getBoundingClientRect().width;
const isCompactMode = this.preference;
const canHideSidebar =
Services.prefs.getBoolPref('zen.view.compact.hide-tabbar') || gZenVerticalTabsManager._hasSetSingleToolbar;
let canAnimate = lazyCompactMode.COMPACT_MODE_CAN_ANIMATE_SIDEBAR && !this.isSidebarPotentiallyOpen();
Services.prefs.getBoolPref('zen.view.compact.hide-tabbar') ||
gZenVerticalTabsManager._hasSetSingleToolbar;
let canAnimate =
lazyCompactMode.COMPACT_MODE_CAN_ANIMATE_SIDEBAR && !this.isSidebarPotentiallyOpen();
if (typeof this._wasInCompactMode !== 'undefined') {
canAnimate = false;
delete this._wasInCompactMode;
@ -316,7 +339,9 @@ var gZenCompactModeManager = {
},
updateContextMenu() {
document.getElementById('zen-context-menu-compact-mode-toggle').setAttribute('checked', this.preference);
document
.getElementById('zen-context-menu-compact-mode-toggle')
.setAttribute('checked', this.preference);
const hideTabBar = Services.prefs.getBoolPref('zen.view.compact.hide-tabbar', false);
const hideToolbar = Services.prefs.getBoolPref('zen.view.compact.hide-toolbar', false);
@ -330,7 +355,9 @@ var gZenCompactModeManager = {
_removeOpenStateOnUnifiedExtensions() {
// Fix for bug https://github.com/zen-browser/desktop/issues/1925
const buttons = document.querySelectorAll('toolbarbutton:is(#unified-extensions-button, .webextension-browser-action)');
const buttons = document.querySelectorAll(
'toolbarbutton:is(#unified-extensions-button, .webextension-browser-action)'
);
for (let button of buttons) {
button.removeAttribute('open');
}
@ -434,7 +461,10 @@ var gZenCompactModeManager = {
if (event.type === 'mouseenter' && !event.target.matches(':hover')) return;
// Dont register the hover if the urlbar is floating and we are hovering over it
this.clearFlashTimeout('has-hover' + target.id);
if (document.documentElement.getAttribute('supress-primary-adjustment') === 'true' || this._hasHoveredUrlbar) {
if (
document.documentElement.getAttribute('supress-primary-adjustment') === 'true' ||
this._hasHoveredUrlbar
) {
return;
}
window.requestAnimationFrame(() => target.setAttribute('zen-has-hover', 'true'));
@ -457,7 +487,10 @@ var gZenCompactModeManager = {
}
// If it's a child element but not the target, ignore the event
if (target.contains(event.explicitOriginalTarget) && event.explicitOriginalTarget !== target) {
if (
target.contains(event.explicitOriginalTarget) &&
event.explicitOriginalTarget !== target
) {
return;
}
@ -474,9 +507,16 @@ var gZenCompactModeManager = {
}
if (this.hoverableElements[i].keepHoverDuration) {
this.flashElement(target, this.hoverableElements[i].keepHoverDuration, 'has-hover' + target.id, 'zen-has-hover');
this.flashElement(
target,
this.hoverableElements[i].keepHoverDuration,
'has-hover' + target.id,
'zen-has-hover'
);
} else {
this._removeHoverFrames[target.id] = window.requestAnimationFrame(() => target.removeAttribute('zen-has-hover'));
this._removeHoverFrames[target.id] = window.requestAnimationFrame(() =>
target.removeAttribute('zen-has-hover')
);
}
};
@ -499,7 +539,12 @@ var gZenCompactModeManager = {
}
window.cancelAnimationFrame(this._removeHoverFrames[target.id]);
this.flashElement(target, this.hideAfterHoverDuration, 'has-hover' + target.id, 'zen-has-hover');
this.flashElement(
target,
this.hideAfterHoverDuration,
'has-hover' + target.id,
'zen-has-hover'
);
document.addEventListener(
'mousemove',
() => {

View file

@ -36,7 +36,9 @@
onDownloadAdded: this.#handleNewDownload.bind(this),
});
} catch (error) {
console.error(`[${ZenDownloadAnimation.name}] Failed to set up download animation listeners: ${error}`);
console.error(
`[${ZenDownloadAnimation.name}] Failed to set up download animation listeners: ${error}`
);
}
}
@ -46,7 +48,9 @@
}
if (!this.#lastClickPosition) {
console.warn(`[${ZenDownloadAnimation.name}] No recent click position available for animation`);
console.warn(
`[${ZenDownloadAnimation.name}] No recent click position available for animation`
);
return;
}
@ -80,7 +84,10 @@
try {
const link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', 'chrome://browser/content/zen-styles/zen-download-arc-animation.css');
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}`);
@ -89,7 +96,9 @@
async initializeAnimation(startPosition) {
if (!startPosition) {
console.warn(`[${ZenDownloadAnimationElement.name}] No start position provided, skipping animation`);
console.warn(
`[${ZenDownloadAnimationElement.name}] No start position provided, skipping animation`
);
return;
}
@ -102,13 +111,27 @@
// Calculate optimal arc parameters based on available space
const distance = this.#calculateDistance(startPosition, endPosition);
const { arcHeight, shouldArcDownward } = this.#calculateOptimalArc(startPosition, endPosition, distance);
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);
const arcSequence = this.#createArcAnimationSequence(
distanceX,
distanceY,
arcHeight,
shouldArcDownward
);
// Start the download animation
await this.#startDownloadAnimation(areTabsPositionedRight, isDownloadButtonVisible, arcAnimationElement, arcSequence);
await this.#startDownloadAnimation(
areTabsPositionedRight,
isDownloadButtonVisible,
arcAnimationElement,
arcSequence
);
}
#areTabsOnRightSide() {
@ -170,7 +193,8 @@
// 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);
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;
@ -194,7 +218,12 @@
return Math.sqrt(distanceX * distanceX + distanceY * distanceY);
}
async #startDownloadAnimation(areTabsPositionedRight, isDownloadButtonVisible, arcAnimationElement, sequence) {
async #startDownloadAnimation(
areTabsPositionedRight,
isDownloadButtonVisible,
arcAnimationElement,
sequence
) {
try {
if (!isDownloadButtonVisible) {
this.#startBoxAnimation(areTabsPositionedRight);
@ -272,7 +301,9 @@
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})`);
sequence.transform.push(
`translate(calc(${x}px - 50%), calc(${y}px - 50%)) rotate(${rotation}deg) scale(${scale})`
);
}
return sequence;
@ -285,7 +316,9 @@
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.`);
console.warn(
`[${ZenDownloadAnimationElement.name}] Box animation already running, skipping new request.`
);
return;
}
@ -300,7 +333,9 @@
const wrapper = document.getElementById('zen-main-app-wrapper');
if (!wrapper) {
console.warn(`[${ZenDownloadAnimationElement.name}] Cannot start box animation, Wrapper element not found`);
console.warn(
`[${ZenDownloadAnimationElement.name}] Cannot start box animation, Wrapper element not found`
);
return;
}
@ -357,7 +392,9 @@
this.#getBoxAnimationDurationMs()
);
} catch (error) {
console.error(`[${ZenDownloadAnimationElement.name}] Error during box entry animation: ${error}`);
console.error(
`[${ZenDownloadAnimationElement.name}] Error during box entry animation: ${error}`
);
this.#cleanBoxAnimation();
} finally {
this.#isBoxAnimationRunning = false;
@ -406,7 +443,9 @@
}
).finished;
} catch (error) {
console.warn(`[${ZenDownloadAnimationElement.name}] Error during box exit animation: ${error}`);
console.warn(
`[${ZenDownloadAnimationElement.name}] Error during box exit animation: ${error}`
);
} finally {
this.#cleanBoxAnimation();
}
@ -426,7 +465,10 @@
try {
this.#boxAnimationElement.remove();
} catch (error) {
console.error(`[${ZenDownloadAnimationElement.name}] Error removing box animation element: ${error}`, error);
console.error(
`[${ZenDownloadAnimationElement.name}] Error removing box animation element: ${error}`,
error
);
}
}
this.#cleanBoxAnimationState();
@ -441,7 +483,12 @@
// 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) {
if (
rect.bottom < 1 ||
rect.right < 1 ||
rect.top > window.innerHeight ||
rect.left > window.innerWidth
) {
return false;
}

View file

@ -87,7 +87,10 @@
gBrowser.pinTab(otherTab);
}
this._piningFolder = false;
gBrowser.verticalPinnedTabsContainer.insertBefore(group, gBrowser.verticalPinnedTabsContainer.lastChild);
gBrowser.verticalPinnedTabsContainer.insertBefore(
group,
gBrowser.verticalPinnedTabsContainer.lastChild
);
gBrowser.tabContainer._invalidateCachedTabs();
return true;
}

View file

@ -23,7 +23,11 @@ tab-group[split-view-group] {
outline-color: var(--tab-selected-outline-color);
transition: scale 0.1s ease;
align-items: center;
--zen-split-view-active-tab-bg: color-mix(in srgb, var(--zen-toolbar-element-bg), transparent 40%);
--zen-split-view-active-tab-bg: color-mix(
in srgb,
var(--zen-toolbar-element-bg),
transparent 40%
);
:root:not([zen-sidebar-expanded='true']) & {
padding: 0 2px;

View file

@ -19,8 +19,12 @@
false
);
ChromeUtils.defineLazyGetter(this, 'sidebarButtons', () => document.getElementById('zen-glance-sidebar-container'));
document.getElementById('tabbrowser-tabpanels').addEventListener('click', this.onOverlayClick.bind(this));
ChromeUtils.defineLazyGetter(this, 'sidebarButtons', () =>
document.getElementById('zen-glance-sidebar-container')
);
document
.getElementById('tabbrowser-tabpanels')
.addEventListener('click', this.onOverlayClick.bind(this));
Services.obs.addObserver(this, 'quit-application-requested');
this.#addSidebarButtonListeners();
@ -93,7 +97,8 @@
};
currentTab._selected = true;
const newUUID = gZenUIManager.generateUuidv4();
const newTab = existingTab ?? gBrowser.addTrustedTab(Services.io.newURI(url).spec, newTabOptions);
const newTab =
existingTab ?? gBrowser.addTrustedTab(Services.io.newURI(url).spec, newTabOptions);
if (currentTab.hasAttribute('zenDefaultUserContextId')) {
newTab.setAttribute('zenDefaultUserContextId', true);
}
@ -266,7 +271,9 @@
this.browserWrapper.removeAttribute('has-finished-animation');
if (noAnimation) {
this._clearContainerStyles(this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer'));
this._clearContainerStyles(
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer')
);
this.quickCloseGlance({ closeCurrentTab: false });
return;
}
@ -308,7 +315,9 @@
}
)
.then(() => {
this._clearContainerStyles(this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer'));
this._clearContainerStyles(
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer')
);
});
this.browserWrapper.style.opacity = 1;
gZenUIManager.motion
@ -336,7 +345,9 @@
this.lastCurrentTab = this.#currentTab;
this.overlay.classList.remove('zen-glance-overlay');
gBrowser._getSwitcher().setTabStateNoAction(this.lastCurrentTab, gBrowser.AsyncTabSwitcher.STATE_UNLOADED);
gBrowser
._getSwitcher()
.setTabStateNoAction(this.lastCurrentTab, gBrowser.AsyncTabSwitcher.STATE_UNLOADED);
if (!onTabClose) {
this.#currentParentTab._visuallySelected = false;
@ -383,7 +394,9 @@
this.showSidebarButtons();
}
const parentBrowserContainer = this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer');
const parentBrowserContainer = this.#currentParentTab.linkedBrowser.closest(
'.browserSidebarContainer'
);
parentBrowserContainer.classList.add('zen-glance-background');
parentBrowserContainer.classList.remove('zen-glance-overlay');
parentBrowserContainer.classList.add('deck-selected');
@ -401,16 +414,25 @@
this._duringOpening = false;
}
quickCloseGlance({ closeCurrentTab = true, closeParentTab = true, justAnimateParent = false, clearID = true } = {}) {
quickCloseGlance({
closeCurrentTab = true,
closeParentTab = true,
justAnimateParent = false,
clearID = true,
} = {}) {
const parentHasBrowser = !!this.#currentParentTab.linkedBrowser;
this.hideSidebarButtons();
if (parentHasBrowser) {
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('zen-glance-background');
this.#currentParentTab.linkedBrowser
.closest('.browserSidebarContainer')
.classList.remove('zen-glance-background');
}
if (!justAnimateParent && this.overlay) {
if (parentHasBrowser) {
if (closeParentTab) {
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('deck-selected');
this.#currentParentTab.linkedBrowser
.closest('.browserSidebarContainer')
.classList.remove('deck-selected');
}
this.#currentParentTab.linkedBrowser.zenModeActive = false;
}
@ -471,7 +493,9 @@
setTimeout(() => {
gBrowser.selectedTab = curTab;
if (prevTab?.linkedBrowser) {
prevTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('deck-selected');
prevTab.linkedBrowser
.closest('.browserSidebarContainer')
.classList.remove('deck-selected');
}
}, 0);
} else if (gBrowser.selectedTab === this.#currentTab) {
@ -495,7 +519,11 @@
this._ignoreClose = false;
return false;
}
this.closeGlance({ onTabClose: true, setNewID: isDifferent ? oldGlanceID : null, isDifferent });
this.closeGlance({
onTabClose: true,
setNewID: isDifferent ? oldGlanceID : null,
isDifferent,
});
// only keep continueing tab close if we are not on the currently selected tab
return !isDifferent;
}
@ -513,7 +541,11 @@
}
// https://github.com/zen-browser/desktop/issues/7173: Only glance up links that are http(s) or file
const url2Spec = url2.spec;
if (!url2Spec.startsWith('http') && !url2Spec.startsWith('https') && !url2Spec.startsWith('file')) {
if (
!url2Spec.startsWith('http') &&
!url2Spec.startsWith('https') &&
!url2Spec.startsWith('file')
) {
return false;
}
return Services.io.newURI(url1).host !== url2.host;
@ -543,7 +575,13 @@
if (this.shouldOpenTabInGlance(tab, uri)) {
const browserRect = gBrowser.tabbox.getBoundingClientRect();
this.openGlance(
{ url: undefined, x: browserRect.width / 2, y: browserRect.height / 2, width: 0, height: 0 },
{
url: undefined,
x: browserRect.width / 2,
y: browserRect.height / 2,
width: 0,
height: 0,
},
tab,
tab.owner
);
@ -578,7 +616,9 @@
this.#currentTab.removeAttribute('glance-id');
this.#currentParentTab.removeAttribute('glance-id');
gBrowser.selectedTab = this.#currentTab;
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('zen-glance-background');
this.#currentParentTab.linkedBrowser
.closest('.browserSidebarContainer')
.classList.remove('zen-glance-background');
this.#currentParentTab._visuallySelected = false;
this.hideSidebarButtons();
if (gReduceMotion || forSplit) {

View file

@ -46,7 +46,11 @@ export class ZenGlanceChild extends JSWindowActorChild {
this.contentWindow.addEventListener('mouseup', this.mouseUpListener);
this.contentWindow.document.removeEventListener('click', this.clickListener);
} else if (activationMethod === 'ctrl' || activationMethod === 'alt' || activationMethod === 'shift') {
} else if (
activationMethod === 'ctrl' ||
activationMethod === 'alt' ||
activationMethod === 'shift'
) {
this.contentWindow.document.addEventListener('click', this.clickListener, { capture: true });
this.contentWindow.removeEventListener('mousedown', this.mouseDownListener);

View file

@ -222,9 +222,11 @@ class KeyShortcutModifiers {
this.#shift == other.#shift &&
this.#control == other.#control &&
(AppConstants.platform == 'macosx'
? (this.#meta || this.#accel) == (other.#meta || other.#accel) && this.#control == other.#control
? (this.#meta || this.#accel) == (other.#meta || other.#accel) &&
this.#control == other.#control
: // In other platforms, we can have control and accel counting as the same thing
this.#meta == other.#meta && (this.#control || this.#accel) == (other.#control || other.#accel))
this.#meta == other.#meta &&
(this.#control || this.#accel) == (other.#control || other.#accel))
);
}
@ -295,7 +297,18 @@ class KeyShortcut {
#reserved = false;
#internal = false;
constructor(id, key, keycode, group, modifiers, action, l10nId, disabled = false, reserved = false, internal = false) {
constructor(
id,
key,
keycode,
group,
modifiers,
action,
l10nId,
disabled = false,
reserved = false,
internal = false
) {
this.#id = id;
this.#key = key?.toLowerCase();
this.#keycode = keycode;
@ -359,7 +372,10 @@ class KeyShortcut {
key.getAttribute('key'),
key.getAttribute('keycode'),
group ??
KeyShortcut.getGroupFromL10nId(KeyShortcut.sanitizeL10nId(key.getAttribute('data-l10n-id')), key.getAttribute('id')),
KeyShortcut.getGroupFromL10nId(
KeyShortcut.sanitizeL10nId(key.getAttribute('data-l10n-id')),
key.getAttribute('id')
),
KeyShortcutModifiers.parseFromXHTMLAttribute(key.getAttribute('modifiers')),
key.getAttribute('command'),
key.getAttribute('data-l10n-id'),
@ -986,7 +1002,10 @@ var gZenKeyboardShortcutsManager = {
// handled wont wait for the async function to finish.
void this.getZenKeyset();
this._hasCleared = Services.prefs.getBoolPref('zen.keyboard.shortcuts.disable-mainkeyset-clear', false);
this._hasCleared = Services.prefs.getBoolPref(
'zen.keyboard.shortcuts.disable-mainkeyset-clear',
false
);
window.addEventListener('zen-devtools-keyset-added', this._hasAddedDevtoolShortcuts.bind(this));
this.init();
@ -1225,7 +1244,10 @@ var gZenKeyboardShortcutsManager = {
continue;
}
if (targetShortcut.getModifiers().equals(modifiers) && targetShortcut.getKeyNameOrCode()?.toLowerCase() == realShortcut) {
if (
targetShortcut.getModifiers().equals(modifiers) &&
targetShortcut.getKeyNameOrCode()?.toLowerCase() == realShortcut
) {
return true;
}
}

View file

@ -152,11 +152,21 @@
}
if (linkedBrowser?.browsingContext?.mediaController) {
this.deinitMediaController(linkedBrowser.browsingContext.mediaController, true, isCurrentBrowser, true);
this.deinitMediaController(
linkedBrowser.browsingContext.mediaController,
true,
isCurrentBrowser,
true
);
}
}
async deinitMediaController(mediaController, shouldForget = true, shouldOverride = true, shouldHide = true) {
async deinitMediaController(
mediaController,
shouldForget = true,
shouldOverride = true,
shouldHide = true
) {
if (shouldForget && mediaController) {
mediaController.removeEventListener('pictureinpicturemodechange', this.onPipModeChange);
mediaController.removeEventListener('positionstatechange', this.onPositionstateChange);
@ -230,7 +240,8 @@
if (!this.isSharing) {
if (!this._currentMediaController) return;
if (this._currentMediaController.isBeingUsedInPIPModeOrFullscreen) return this.hideMediaControls();
if (this._currentMediaController.isBeingUsedInPIPModeOrFullscreen)
return this.hideMediaControls();
this.updatePipButton();
}
@ -280,11 +291,15 @@
setupMediaControlUI(metadata, positionState) {
this.updatePipButton();
if (!this.mediaControlBar.classList.contains('playing') && this._currentMediaController.isPlaying) {
if (
!this.mediaControlBar.classList.contains('playing') &&
this._currentMediaController.isPlaying
) {
this.mediaControlBar.classList.add('playing');
}
const iconURL = this._currentBrowser.mIconURL || `page-icon:${this._currentBrowser.currentURI.spec}`;
const iconURL =
this._currentBrowser.mIconURL || `page-icon:${this._currentBrowser.currentURI.spec}`;
this.mediaFocusButton.style.listStyleImage = `url(${iconURL})`;
this.mediaTitle.textContent = metadata.title || '';
@ -309,7 +324,8 @@
this.updateMuteState();
this.switchController();
if (!mediaController.isActive || this._currentBrowser?.browserId === browser.browserId) return;
if (!mediaController.isActive || this._currentBrowser?.browserId === browser.browserId)
return;
const metadata = mediaController.getMetadata();
const positionState = mediaController.getPositionState();
@ -385,7 +401,12 @@
}
_onDeactivated(event) {
this.deinitMediaController(event.target, true, event.target.id === this._currentMediaController.id, true);
this.deinitMediaController(
event.target,
true,
event.target.id === this._currentMediaController.id,
true
);
this.switchController();
}
@ -455,7 +476,8 @@
const elapsedTime = Math.floor((Date.now() - nextController.lastUpdated) / 1000);
this.setupMediaControlUI(nextController.controller.getMetadata(), {
position: nextController.position + (nextController.controller.isPlaying ? elapsedTime : 0),
position:
nextController.position + (nextController.controller.isPlaying ? elapsedTime : 0),
duration: nextController.duration,
playbackRate: nextController.playbackRate,
});
@ -475,7 +497,8 @@
this._mediaUpdateInterval = null;
}
if (this._currentDuration >= 900_000) return this.mediaControlBar.setAttribute('media-position-hidden', 'true');
if (this._currentDuration >= 900_000)
return this.mediaControlBar.setAttribute('media-position-hidden', 'true');
else this.mediaControlBar.removeAttribute('media-position-hidden');
if (!this._currentDuration) return;
@ -619,18 +642,26 @@
onMicrophoneMuteToggle() {
if (this._currentBrowser) {
const shouldMute = this.mediaControlBar.hasAttribute('mic-muted') ? 'webrtc:UnmuteMicrophone' : 'webrtc:MuteMicrophone';
const shouldMute = this.mediaControlBar.hasAttribute('mic-muted')
? 'webrtc:UnmuteMicrophone'
: 'webrtc:MuteMicrophone';
this._currentBrowser.browsingContext.currentWindowGlobal.getActor('WebRTC').sendAsyncMessage(shouldMute);
this._currentBrowser.browsingContext.currentWindowGlobal
.getActor('WebRTC')
.sendAsyncMessage(shouldMute);
this.mediaControlBar.toggleAttribute('mic-muted');
}
}
onCameraMuteToggle() {
if (this._currentBrowser) {
const shouldMute = this.mediaControlBar.hasAttribute('camera-muted') ? 'webrtc:UnmuteCamera' : 'webrtc:MuteCamera';
const shouldMute = this.mediaControlBar.hasAttribute('camera-muted')
? 'webrtc:UnmuteCamera'
: 'webrtc:MuteCamera';
this._currentBrowser.browsingContext.currentWindowGlobal.getActor('WebRTC').sendAsyncMessage(shouldMute);
this._currentBrowser.browsingContext.currentWindowGlobal
.getActor('WebRTC')
.sendAsyncMessage(shouldMute);
this.mediaControlBar.toggleAttribute('camera-muted');
}
}
@ -644,7 +675,9 @@
if (!this._currentBrowser) return;
if (this.isSharing) return;
const { totalPipCount, totalPipDisabled } = PictureInPicture.getEligiblePipVideoCount(this._currentBrowser);
const { totalPipCount, totalPipDisabled } = PictureInPicture.getEligiblePipVideoCount(
this._currentBrowser
);
const canPip = totalPipCount === 1 || (totalPipDisabled > 0 && lazy.RESPECT_PIP_DISABLED);
this.mediaControlBar.toggleAttribute('can-pip', canPip);

View file

@ -3,7 +3,18 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
var ZenThemesCommon = {
kZenColors: ['#aac7ff', '#74d7cb', '#a0d490', '#dec663', '#ffb787', '#dec1b1', '#ffb1c0', '#ddbfc3', '#f6b0ea', '#d4bbff'],
kZenColors: [
'#aac7ff',
'#74d7cb',
'#a0d490',
'#dec663',
'#ffb787',
'#dec1b1',
'#ffb1c0',
'#ddbfc3',
'#f6b0ea',
'#d4bbff',
],
get browsers() {
return Services.wm.getEnumerator('navigator:browser');
@ -72,7 +83,8 @@ var ZenThemesCommon = {
const newThemePreferences = [];
for (let [entry, label] of Object.entries(preferences)) {
const [_, negation = '', os = '', property] = /(!?)(?:(macos|windows|linux):)?([A-z0-9-_.]+)/g.exec(entry);
const [_, negation = '', os = '', property] =
/(!?)(?:(macos|windows|linux):)?([A-z0-9-_.]+)/g.exec(entry);
const isNegation = negation === '!';
if (
@ -94,7 +106,8 @@ var ZenThemesCommon = {
}
return preferences.filter(
({ disabledOn = [] }) => !disabledOn.includes(gZenOperatingSystemCommonUtils.currentOperatingSystem)
({ disabledOn = [] }) =>
!disabledOn.includes(gZenOperatingSystemCommonUtils.currentOperatingSystem)
);
},

View file

@ -55,7 +55,10 @@ var gZenThemesImporter = new (class {
constructor() {
try {
window.SessionStore.promiseInitialized.then(async () => {
if (Services.prefs.getBoolPref('zen.themes.disable-all', false) || Services.appinfo.inSafeMode) {
if (
Services.prefs.getBoolPref('zen.themes.disable-all', false) ||
Services.appinfo.inSafeMode
) {
console.log('[ZenThemesImporter]: Disabling all themes.');
return;
}
@ -83,13 +86,23 @@ var gZenThemesImporter = new (class {
console.error('[ZenThemesImporter]: Error importing Zen Themes: ', e);
}
Services.prefs.addObserver('zen.themes.updated-value-observer', this.rebuildThemeStylesheet.bind(this), false);
Services.prefs.addObserver('zen.themes.disable-all', this.handleDisableThemes.bind(this), false);
Services.prefs.addObserver(
'zen.themes.updated-value-observer',
this.rebuildThemeStylesheet.bind(this),
false
);
Services.prefs.addObserver(
'zen.themes.disable-all',
this.handleDisableThemes.bind(this),
false
);
}
get sss() {
if (!this._sss) {
this._sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
this._sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(
Ci.nsIStyleSheetService
);
}
return this._sss;
}
@ -118,7 +131,9 @@ var gZenThemesImporter = new (class {
}
getStylesheetURIForTheme(theme) {
return Services.io.newFileURI(new FileUtils.File(PathUtils.join(ZenThemesCommon.getThemeFolder(theme.id), 'chrome.css')));
return Services.io.newFileURI(
new FileUtils.File(PathUtils.join(ZenThemesCommon.getThemeFolder(theme.id), 'chrome.css'))
);
}
async insertStylesheet() {
@ -135,7 +150,10 @@ var gZenThemesImporter = new (class {
await this.sss.unregisterSheet(this.styleSheetURI, this.sss.AGENT_SHEET);
await IOUtils.remove(this.styleSheetPath, { ignoreAbsent: true });
if (!this.sss.sheetRegistered(this.styleSheetURI, this.sss.AGENT_SHEET) && !(await IOUtils.exists(this.styleSheetPath))) {
if (
!this.sss.sheetRegistered(this.styleSheetURI, this.sss.AGENT_SHEET) &&
!(await IOUtils.exists(this.styleSheetPath))
) {
console.debug('[ZenThemesImporter]: Sheet successfully unregistered');
}
}
@ -169,7 +187,9 @@ var gZenThemesImporter = new (class {
async getEnabledThemes() {
const themeObject = await ZenThemesCommon.getThemes();
const themes = Object.values(themeObject).filter((theme) => theme.enabled === undefined || theme.enabled);
const themes = Object.values(themeObject).filter(
(theme) => theme.enabled === undefined || theme.enabled
);
const themeList = themes.map(({ name }) => name).join(', ');
@ -198,7 +218,9 @@ var gZenThemesImporter = new (class {
case 'checkbox': {
const value = Services.prefs.getBoolPref(property, false);
if (typeof defaultValue !== 'boolean') {
console.log(`[ZenThemesImporter]: Warning, invalid data type received for expected type boolean, skipping.`);
console.log(
`[ZenThemesImporter]: Warning, invalid data type received for expected type boolean, skipping.`
);
continue;
}
@ -212,7 +234,9 @@ var gZenThemesImporter = new (class {
const value = Services.prefs.getStringPref(property, 'zen-property-no-saved');
if (typeof defaultValue !== 'string' && typeof defaultValue !== 'number') {
console.log(`[ZenThemesImporter]: Warning, invalid data type received (${typeof defaultValue}), skipping.`);
console.log(
`[ZenThemesImporter]: Warning, invalid data type received (${typeof defaultValue}), skipping.`
);
continue;
}
@ -271,9 +295,13 @@ var gZenThemesImporter = new (class {
case 'string': {
if (value === '') {
browser.document.querySelector(':root').style.removeProperty(`--${sanitizedProperty}`);
browser.document
.querySelector(':root')
.style.removeProperty(`--${sanitizedProperty}`);
} else {
browser.document.querySelector(':root').style.setProperty(`--${sanitizedProperty}`, value);
browser.document
.querySelector(':root')
.style.setProperty(`--${sanitizedProperty}`, value);
}
break;
}
@ -309,5 +337,8 @@ gZenActorsManager.addJSWindowActor('ZenThemeMarketplace', {
DOMContentLoaded: {},
},
},
matches: [...Services.prefs.getStringPref('zen.injections.match-urls').split(','), 'about:preferences'],
matches: [
...Services.prefs.getStringPref('zen.injections.match-urls').split(','),
'about:preferences',
],
});

View file

@ -31,7 +31,10 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
}
this.initiateThemeMarketplace();
this.contentWindow.document.addEventListener('ZenCheckForThemeUpdates', this.checkForThemeUpdates.bind(this));
this.contentWindow.document.addEventListener(
'ZenCheckForThemeUpdates',
this.checkForThemeUpdates.bind(this)
);
}
collectRiceMetadata() {

View file

@ -79,14 +79,24 @@ export class ZenThemeMarketplaceParent extends JSWindowActorParent {
for (const theme of Object.values(await this.getThemes())) {
try {
const themeInfo = await this.sendQuery('ZenThemeMarketplace:GetThemeInfo', { themeId: theme.id });
const themeInfo = await this.sendQuery('ZenThemeMarketplace:GetThemeInfo', {
themeId: theme.id,
});
if (!themeInfo) {
continue;
}
if (!this.compareVersions(themeInfo.version, theme.version || '0.0.0') && themeInfo.version != theme.version) {
console.info('ZenThemeMarketplaceParent: Theme update found', theme.id, theme.version, themeInfo.version);
if (
!this.compareVersions(themeInfo.version, theme.version || '0.0.0') &&
themeInfo.version != theme.version
) {
console.info(
'ZenThemeMarketplaceParent: Theme update found',
theme.id,
theme.version,
themeInfo.version
);
themeInfo.enabled = theme.enabled;
updates.push(themeInfo);
@ -156,7 +166,10 @@ export class ZenThemeMarketplaceParent extends JSWindowActorParent {
await this.downloadUrlToFile(theme.style, PathUtils.join(themePath, 'chrome.css'), true);
await this.downloadUrlToFile(theme.readme, PathUtils.join(themePath, 'readme.md'));
if (theme.preferences) {
await this.downloadUrlToFile(theme.preferences, PathUtils.join(themePath, 'preferences.json'));
await this.downloadUrlToFile(
theme.preferences,
PathUtils.join(themePath, 'preferences.json')
);
}
}

View file

@ -82,21 +82,39 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
init() {
this.handleTabEvent = this._handleTabEvent.bind(this);
XPCOMUtils.defineLazyPreferenceGetter(this, 'minResizeWidth', 'zen.splitView.min-resize-width', 7);
XPCOMUtils.defineLazyPreferenceGetter(this, '_edgeHoverSize', 'zen.splitView.rearrange-edge-hover-size', 24);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'minResizeWidth',
'zen.splitView.min-resize-width',
7
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_edgeHoverSize',
'zen.splitView.rearrange-edge-hover-size',
24
);
ChromeUtils.defineLazyGetter(this, 'overlay', () => document.getElementById('zen-splitview-overlay'));
ChromeUtils.defineLazyGetter(this, 'overlay', () =>
document.getElementById('zen-splitview-overlay')
);
ChromeUtils.defineLazyGetter(this, 'dropZone', () => document.getElementById('zen-splitview-dropzone'));
ChromeUtils.defineLazyGetter(this, 'dropZone', () =>
document.getElementById('zen-splitview-dropzone')
);
window.addEventListener('TabClose', this.handleTabClose.bind(this));
window.addEventListener('TabSelect', this.onTabSelect.bind(this));
this.initializeContextMenu();
this.insertIntoContextMenu();
window.addEventListener('AfterWorkspacesSessionRestore', this.onAfterWorkspaceSessionRestore.bind(this), {
once: true,
});
window.addEventListener(
'AfterWorkspacesSessionRestore',
this.onAfterWorkspaceSessionRestore.bind(this),
{
once: true,
}
);
// Add drag over listener to the browser view
if (Services.prefs.getBoolPref('zen.splitView.enable-tab-drop')) {
@ -200,7 +218,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
this.fakeBrowser ||
!this._lastOpenedTab ||
(this._lastOpenedTab &&
this._lastOpenedTab.getAttribute('zen-workspace-id') !== draggedTab.getAttribute('zen-workspace-id') &&
this._lastOpenedTab.getAttribute('zen-workspace-id') !==
draggedTab.getAttribute('zen-workspace-id') &&
!this._lastOpenedTab.hasAttribute('zen-essential')) ||
draggedTab === this._lastOpenedTab
) {
@ -224,7 +243,12 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
return;
}
// first quarter or last quarter of the screen, but not the middle
if (!(event.clientX < panelsRect.left + panelsWidth / 4 || event.clientX > panelsRect.left + (panelsWidth / 4) * 3)) {
if (
!(
event.clientX < panelsRect.left + panelsWidth / 4 ||
event.clientX > panelsRect.left + (panelsWidth / 4) * 3
)
) {
return;
}
dt.mozCursor = 'default';
@ -244,7 +268,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
// Add a min width to all the browser elements to prevent them from resizing
const panelsWidth = gBrowser.tabbox.getBoundingClientRect().width;
const halfWidth = panelsWidth / 2;
let threshold = gNavToolbox.getBoundingClientRect().width * (gZenVerticalTabsManager._prefsRightSide ? 0 : 1);
let threshold =
gNavToolbox.getBoundingClientRect().width *
(gZenVerticalTabsManager._prefsRightSide ? 0 : 1);
if (gZenCompactModeManager.preference) {
threshold = 0;
}
@ -267,7 +293,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
this.fakeBrowser.setAttribute('has-split-view', 'true');
}
gBrowser.tabbox.appendChild(this.fakeBrowser);
this.fakeBrowser.style.setProperty('--zen-split-view-fake-icon', `url(${draggedTab.getAttribute('image')})`);
this.fakeBrowser.style.setProperty(
'--zen-split-view-fake-icon',
`url(${draggedTab.getAttribute('image')})`
);
draggedTab._visuallySelected = true;
this.fakeBrowser.setAttribute('side', side);
this._finishAllAnimatingPromise = Promise.all([
@ -497,12 +526,18 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
if (!this.rearrangeViewEnabled) return;
if (event) {
// Click or "ESC" key
if ((event.type === 'click' && event.button !== 0) || (event.type === 'keydown' && event.key !== 'Escape')) {
if (
(event.type === 'click' && event.button !== 0) ||
(event.type === 'keydown' && event.key !== 'Escape')
) {
return;
}
}
if (!this.rearrangeViewEnabled || (event && event.target.classList.contains('zen-split-view-splitter'))) {
if (
!this.rearrangeViewEnabled ||
(event && event.target.classList.contains('zen-split-view-splitter'))
) {
return;
}
@ -650,7 +685,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
if (hoverSide !== 'center') {
const isVertical = hoverSide === 'top' || hoverSide === 'bottom';
const browserSize = 100 - (isVertical ? posToRoot.top + posToRoot.bottom : posToRoot.right + posToRoot.left);
const browserSize =
100 - (isVertical ? posToRoot.top + posToRoot.bottom : posToRoot.right + posToRoot.left);
const reduce = browserSize * 0.5;
posToRoot[this._oppositeSide(hoverSide)] += reduce;
@ -712,7 +748,11 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
const droppedOnTab = gBrowser.getTabForBrowser(event.target.querySelector('browser'));
if (droppedTab === droppedOnTab) return;
const hoverSide = this.calculateHoverSide(event.clientX, event.clientY, browserDroppedOn.getBoundingClientRect());
const hoverSide = this.calculateHoverSide(
event.clientX,
event.clientY,
browserDroppedOn.getBoundingClientRect()
);
const droppedSplitNode = this.getSplitNodeFromTab(droppedTab);
const droppedOnSplitNode = this.getSplitNodeFromTab(droppedOnTab);
if (hoverSide === 'center') {
@ -902,7 +942,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
* @returns {boolean} True if the tabs can be split, false otherwise.
*/
contextCanSplitTabs() {
if (window.gBrowser.selectedTabs.length < 2 || window.gBrowser.selectedTabs.length > this.MAX_TABS) {
if (
window.gBrowser.selectedTabs.length < 2 ||
window.gBrowser.selectedTabs.length > this.MAX_TABS
) {
return false;
}
for (const tab of window.gBrowser.selectedTabs) {
@ -979,7 +1022,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
if (gridTypeChange || !newTabsAdded) {
// reset layout
group.gridType = gridType;
group.layoutTree = this.calculateLayoutTree([...new Set(group.tabs.concat(tabs))], gridType);
group.layoutTree = this.calculateLayoutTree(
[...new Set(group.tabs.concat(tabs))],
gridType
);
} else {
// Add any tabs that are not already in the group
for (let i = 0; i < tabs.length; i++) {
@ -1266,7 +1312,13 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
let currentSplitters = this._splitNodeToSplitters.get(parentNode) || [];
if (!splittersNeeded || currentSplitters.length === splittersNeeded) return currentSplitters;
for (let i = currentSplitters?.length || 0; i < splittersNeeded; i++) {
currentSplitters.push(this.createSplitter(parentNode.direction === 'column' ? 'horizontal' : 'vertical', parentNode, i));
currentSplitters.push(
this.createSplitter(
parentNode.direction === 'column' ? 'horizontal' : 'vertical',
parentNode,
i
)
);
currentSplitters[i].parentSplitNode = parentNode;
}
if (currentSplitters.length > splittersNeeded) {
@ -1278,7 +1330,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
}
removeSplitters() {
[...this.overlay.children].filter((c) => c.classList.contains('zen-split-view-splitter')).forEach((s) => s.remove());
[...this.overlay.children]
.filter((c) => c.classList.contains('zen-split-view-splitter'))
.forEach((s) => s.remove());
this._splitNodeToSplitters.clear();
}
@ -1309,7 +1363,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
return;
}
const container = event.currentTarget.closest('.browserSidebarContainer');
const tab = window.gBrowser.tabs.find((t) => t.linkedBrowser.closest('.browserSidebarContainer') === container);
const tab = window.gBrowser.tabs.find(
(t) => t.linkedBrowser.closest('.browserSidebarContainer') === container
);
if (tab) {
window.gBrowser.selectedTab = tab;
}
@ -1325,8 +1381,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
const startPosition = event[clientAxis];
const splitNode = event.target.parentSplitNode;
let rootToNodeSize;
if (isVertical) rootToNodeSize = 100 / (100 - splitNode.positionToRoot.right - splitNode.positionToRoot.left);
else rootToNodeSize = 100 / (100 - splitNode.positionToRoot.bottom - splitNode.positionToRoot.top);
if (isVertical)
rootToNodeSize = 100 / (100 - splitNode.positionToRoot.right - splitNode.positionToRoot.left);
else
rootToNodeSize = 100 / (100 - splitNode.positionToRoot.bottom - splitNode.positionToRoot.top);
const originalSizes = splitNode.children.map((c) => c.sizeInParent);
const dragFunc = (dEvent) => {
@ -1334,7 +1392,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
originalSizes.forEach((s, i) => (splitNode.children[i].sizeInParent = s)); // reset changes
const movement = dEvent[clientAxis] - startPosition;
let movementPercent = (movement / this.tabBrowserPanel.getBoundingClientRect()[dimension]) * rootToNodeSize * 100;
let movementPercent =
(movement / this.tabBrowserPanel.getBoundingClientRect()[dimension]) *
rootToNodeSize *
100;
let reducingMovement = Math.max(movementPercent, -movementPercent);
for (
@ -1351,7 +1412,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
}
const increasingMovement = Math.max(movementPercent, -movementPercent) - reducingMovement;
const increaseIndex = gridIdx + (movementPercent < 0 ? 1 : 0);
splitNode.children[increaseIndex].sizeInParent = originalSizes[increaseIndex] + increasingMovement;
splitNode.children[increaseIndex].sizeInParent =
originalSizes[increaseIndex] + increasingMovement;
this.applyGridLayout(splitNode);
});
};
@ -1562,7 +1624,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
const containerRect = this.fakeBrowser.getBoundingClientRect();
const padding = ZenThemeModifier.elementSeparation;
const dropTarget = document.elementFromPoint(
dropSide === 'left' ? containerRect.left + containerRect.width + padding + 5 : containerRect.left - padding - 5,
dropSide === 'left'
? containerRect.left + containerRect.width + padding + 5
: containerRect.left - padding - 5,
event.clientY
);
const browser = dropTarget?.closest('browser');
@ -1609,9 +1673,18 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
if (hoverSide !== 'center') {
const splitDirection = hoverSide === 'left' || hoverSide === 'right' ? 'row' : 'column';
if (parentNode.direction !== splitDirection) {
this.splitIntoNode(droppedOnSplitNode, new SplitLeafNode(draggedTab, 50), hoverSide, 0.5);
this.splitIntoNode(
droppedOnSplitNode,
new SplitLeafNode(draggedTab, 50),
hoverSide,
0.5
);
} else {
this.addTabToSplit(draggedTab, parentNode, /* prepend = */ hoverSide === 'left' || hoverSide === 'top');
this.addTabToSplit(
draggedTab,
parentNode,
/* prepend = */ hoverSide === 'left' || hoverSide === 'top'
);
}
} else {
this.addTabToSplit(draggedTab, group.layoutTree);
@ -1636,7 +1709,11 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
//}
// Put tabs always as if it was dropped from the left
this.splitTabs(dropSide == 'left' ? [draggedTab, droppedOnTab] : [droppedOnTab, draggedTab], gridType, 1);
this.splitTabs(
dropSide == 'left' ? [draggedTab, droppedOnTab] : [droppedOnTab, draggedTab],
gridType,
1
);
}
}
if (this._finishAllAnimatingPromise) {
@ -1711,7 +1788,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
// Try to find an existing split view group
let splitGroup = gBrowser.tabGroups.find(
(group) => group.getAttribute('split-view-group') && group.tabs.some((tab) => tabs.includes(tab) && tab.splitView)
(group) =>
group.getAttribute('split-view-group') &&
group.tabs.some((tab) => tabs.includes(tab) && tab.splitView)
);
if (splitGroup) {
@ -1762,7 +1841,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
}
onAfterWorkspaceSessionRestore() {
if (gBrowser.selectedTab.group?.hasAttribute('split-view-group') && !gBrowser.selectedTab.pinned) {
if (
gBrowser.selectedTab.group?.hasAttribute('split-view-group') &&
!gBrowser.selectedTab.pinned
) {
// Activate all browsers in the split view
this.currentView = -1;
this.onLocationChange(gBrowser.selectedTab.linkedBrowser);

View file

@ -141,7 +141,9 @@
border-top-right-radius: 0;
}
:root:not([inDOMFullscreen='true']) .browserSidebarContainer:hover .zen-view-splitter-header-container,
:root:not([inDOMFullscreen='true'])
.browserSidebarContainer:hover
.zen-view-splitter-header-container,
.zen-view-splitter-header-container:hover {
pointer-events: all;
opacity: 1;

View file

@ -19,7 +19,9 @@
'zen.pinned-tab-manager.close-shortcut-behavior',
'switch'
);
ChromeUtils.defineESModuleGetters(lazy, { E10SUtils: 'resource://gre/modules/E10SUtils.sys.mjs' });
ChromeUtils.defineESModuleGetters(lazy, {
E10SUtils: 'resource://gre/modules/E10SUtils.sys.mjs',
});
this.#listenPinnedTabEvents();
}
@ -100,7 +102,9 @@
} catch {}
} else {
if (tab.hasAttribute('zen-essential')) {
tab.querySelector('.tab-background').style.setProperty('--zen-tab-icon', `url(${iconUrl})`);
tab
.querySelector('.tab-background')
.style.setProperty('--zen-tab-icon', `url(${iconUrl})`);
}
}
// TODO: work on this
@ -354,8 +358,13 @@
tab.position = tab._tPos;
for (let otherTab of gBrowser.tabs) {
if (otherTab.pinned && otherTab.getAttribute('zen-pin-id') !== tab.getAttribute('zen-pin-id')) {
const actualPin = this._pinsCache.find((pin) => pin.uuid === otherTab.getAttribute('zen-pin-id'));
if (
otherTab.pinned &&
otherTab.getAttribute('zen-pin-id') !== tab.getAttribute('zen-pin-id')
) {
const actualPin = this._pinsCache.find(
(pin) => pin.uuid === otherTab.getAttribute('zen-pin-id')
);
if (!actualPin) {
continue;
}
@ -507,7 +516,11 @@
}
}
_onCloseTabShortcut(event, selectedTab = gBrowser.selectedTab, behavior = lazy.zenPinnedTabCloseShortcutBehavior) {
_onCloseTabShortcut(
event,
selectedTab = gBrowser.selectedTab,
behavior = lazy.zenPinnedTabCloseShortcutBehavior
) {
if (!selectedTab?.pinned) {
return;
}
@ -687,7 +700,11 @@
}
removeEssentials(tab, unpin = true) {
const tabs = tab ? [tab] : TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
const tabs = tab
? [tab]
: TabContextMenu.contextTab.multiselected
? gBrowser.selectedTabs
: [TabContextMenu.contextTab];
for (let i = 0; i < tabs.length; i++) {
const tab = tabs[i];
tab.removeAttribute('zen-essential');
@ -742,7 +759,11 @@
// TODO: remove this as it's not possible to know the base pinned url any more as it's now stored in tab state
resetPinnedTabData(tabData) {
if (lazy.zenPinnedTabRestorePinnedTabsToPinnedUrl && tabData.pinned && tabData.zenPinnedEntry) {
if (
lazy.zenPinnedTabRestorePinnedTabsToPinnedUrl &&
tabData.pinned &&
tabData.zenPinnedEntry
) {
tabData.entries = [JSON.parse(tabData.zenPinnedEntry)];
tabData.image = tabData.zenPinnedIcon;
tabData.index = 0;
@ -754,22 +775,27 @@
return;
}
const isVisible = contextTab.pinned && !contextTab.multiselected;
document.getElementById('context_zen-reset-pinned-tab').hidden = !isVisible || !contextTab.getAttribute('zen-pin-id');
document.getElementById('context_zen-reset-pinned-tab').hidden =
!isVisible || !contextTab.getAttribute('zen-pin-id');
document.getElementById('context_zen-replace-pinned-url-with-current').hidden = !isVisible;
document.getElementById('context_zen-add-essential').hidden =
contextTab.getAttribute('zen-essential') || !!contextTab.group;
document.getElementById('context_zen-remove-essential').hidden = !contextTab.getAttribute('zen-essential');
document.getElementById('context_zen-remove-essential').hidden =
!contextTab.getAttribute('zen-essential');
document.getElementById('context_unpinTab').hidden =
document.getElementById('context_unpinTab').hidden || contextTab.getAttribute('zen-essential');
document.getElementById('context_unpinTab').hidden ||
contextTab.getAttribute('zen-essential');
document.getElementById('context_unpinSelectedTabs').hidden =
document.getElementById('context_unpinSelectedTabs').hidden || contextTab.getAttribute('zen-essential');
document.getElementById('context_unpinSelectedTabs').hidden ||
contextTab.getAttribute('zen-essential');
document.getElementById('context_zen-pinned-tab-separator').hidden = !isVisible;
}
moveToAnotherTabContainerIfNecessary(event, movingTabs) {
try {
const pinnedTabsTarget =
event.target.closest('#vertical-pinned-tabs-container') || event.target.closest('.zen-current-workspace-indicator');
event.target.closest('#vertical-pinned-tabs-container') ||
event.target.closest('.zen-current-workspace-indicator');
const essentialTabsTarget = event.target.closest('.zen-essentials-container');
const tabsTarget = event.target.closest('#tabbrowser-arrowscrollbox');
// Remove group labels from the moving tabs and replace it
@ -801,7 +827,10 @@
}
// Check for essentials container
else if (essentialTabsTarget) {
if (!draggedTab.hasAttribute('zen-essential') && !draggedTab?.group?.hasAttribute('split-view-group')) {
if (
!draggedTab.hasAttribute('zen-essential') &&
!draggedTab?.group?.hasAttribute('split-view-group')
) {
this.addToEssentials(draggedTab);
moved = true;
isVertical = false;
@ -958,7 +987,9 @@
const tabsTarget = event.target.closest('#tabbrowser-arrowscrollbox');
let targetTab = event.target.closest('.tabbrowser-tab');
targetTab = targetTab?.group || targetTab;
draggedTab = draggedTab?.group?.hasAttribute('split-view-group') ? draggedTab.group : draggedTab;
draggedTab = draggedTab?.group?.hasAttribute('split-view-group')
? draggedTab.group
: draggedTab;
if (event.target.closest('.zen-current-workspace-indicator')) {
this.removeTabContainersDragoverClass();
ZenWorkspaces.activeWorkspaceIndicator?.setAttribute('open', true);

View file

@ -202,7 +202,9 @@ var ZenPinnedTabsStorage = {
await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.removePin', async (db) => {
await db.executeTransaction(async () => {
// Get all child UUIDs first for change tracking
const children = await db.execute(`SELECT uuid FROM zen_pins WHERE parent_uuid = :uuid`, { uuid });
const children = await db.execute(`SELECT uuid FROM zen_pins WHERE parent_uuid = :uuid`, {
uuid,
});
// Add child UUIDs to changedUUIDs array
for (const child of children) {
@ -283,7 +285,9 @@ var ZenPinnedTabsStorage = {
shouldReorderPins(before, current, after) {
const minGap = 1; // Minimum allowed gap between positions
return (before !== null && current - before < minGap) || (after !== null && after - current < minGap);
return (
(before !== null && current - before < minGap) || (after !== null && after - current < minGap)
);
},
async reorderAllPins(db, changedUUIDs) {
@ -329,41 +333,44 @@ var ZenPinnedTabsStorage = {
async updatePinPositions(pins) {
const changedUUIDs = new Set();
await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.updatePinPositions', async (db) => {
await db.executeTransaction(async () => {
const now = Date.now();
await PlacesUtils.withConnectionWrapper(
'ZenPinnedTabsStorage.updatePinPositions',
async (db) => {
await db.executeTransaction(async () => {
const now = Date.now();
for (let i = 0; i < pins.length; i++) {
const pin = pins[i];
const newPosition = (i + 1) * 1000;
for (let i = 0; i < pins.length; i++) {
const pin = pins[i];
const newPosition = (i + 1) * 1000;
await db.execute(
`
await db.execute(
`
UPDATE zen_pins
SET position = :newPosition
WHERE uuid = :uuid
`,
{ newPosition, uuid: pin.uuid }
);
{ newPosition, uuid: pin.uuid }
);
changedUUIDs.add(pin.uuid);
changedUUIDs.add(pin.uuid);
// Record the change
await db.execute(
`
// Record the change
await db.execute(
`
INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`,
{
uuid: pin.uuid,
timestamp: Math.floor(now / 1000),
}
);
}
{
uuid: pin.uuid,
timestamp: Math.floor(now / 1000),
}
);
}
await this.updateLastChangeTimestamp(db);
});
});
await this.updateLastChangeTimestamp(db);
});
}
);
this._notifyPinsChanged('zen-pin-updated', Array.from(changedUUIDs));
},

View file

@ -1,11 +1,26 @@
{
const lazy = {};
XPCOMUtils.defineLazyPreferenceGetter(lazy, 'zenTabUnloaderEnabled', 'zen.tab-unloader.enabled', false);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
'zenTabUnloaderEnabled',
'zen.tab-unloader.enabled',
false
);
XPCOMUtils.defineLazyPreferenceGetter(lazy, 'zenTabUnloaderTimeout', 'zen.tab-unloader.timeout-minutes', 20);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
'zenTabUnloaderTimeout',
'zen.tab-unloader.timeout-minutes',
20
);
XPCOMUtils.defineLazyPreferenceGetter(lazy, 'zenTabUnloaderExcludedUrls', 'zen.tab-unloader.excluded-urls', '');
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
'zenTabUnloaderExcludedUrls',
'zen.tab-unloader.excluded-urls',
''
);
const ZEN_TAB_UNLOADER_DEFAULT_EXCLUDED_URLS = [
'^about:',
@ -68,7 +83,10 @@
constructor(unloader) {
this.unloader = unloader;
this.interval = setInterval(this.intervalListener.bind(this), ZenTabsIntervalUnloader.INTERVAL);
this.interval = setInterval(
this.intervalListener.bind(this),
ZenTabsIntervalUnloader.INTERVAL
);
}
intervalListener() {
@ -218,7 +236,10 @@
get excludedUrls() {
// Check if excludedrls is the same as the pref value
const excludedUrls = this.lazyExcludeUrls;
if (!this.arraysEqual(this.#excludedUrls, excludedUrls) || !this.#compiledExcludedUrls.length) {
if (
!this.arraysEqual(this.#excludedUrls, excludedUrls) ||
!this.#compiledExcludedUrls.length
) {
this.#excludedUrls = excludedUrls;
this.#compiledExcludedUrls = excludedUrls.map((url) => new RegExp(url));
}
@ -231,7 +252,9 @@
}
unloadTab() {
const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
const tabs = TabContextMenu.contextTab.multiselected
? gBrowser.selectedTabs
: [TabContextMenu.contextTab];
this.explicitUnloadTabs(tabs);
}
@ -244,7 +267,9 @@
}
preventUnloadTab() {
const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
const tabs = TabContextMenu.contextTab.multiselected
? gBrowser.selectedTabs
: [TabContextMenu.contextTab];
for (let i = 0; i < tabs.length; i++) {
const tab = tabs[i];
tab.zenIgnoreUnload = true;
@ -252,7 +277,9 @@
}
ignoreUnloadTab() {
const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
const tabs = TabContextMenu.contextTab.multiselected
? gBrowser.selectedTabs
: [TabContextMenu.contextTab];
for (let i = 0; i < tabs.length; i++) {
const tab = tabs[i];
tab.zenIgnoreUnload = false;
@ -288,7 +315,9 @@
}
const diff = currentTimestamp - lastActivity;
// Check if the tab has been inactive for more than the timeout
return diff > lazy.zenTabUnloaderTimeout * 60 * 1000 && this._tabPermitsUnload(tab, extraArgs);
return (
diff > lazy.zenTabUnloaderTimeout * 60 * 1000 && this._tabPermitsUnload(tab, extraArgs)
);
}
_tabPermitsUnload(tab, extraArgs) {

View file

@ -14,7 +14,9 @@ z-index: 1;
}
}
&:not([zen-has-hover='true']):not([has-popup-menu]):not(:focus-within):not(:has(*:is([panelopen='true'], [open='true']))) {
&:not([zen-has-hover='true']):not([has-popup-menu]):not(:focus-within):not(
:has(*:is([panelopen='true'], [open='true']))
) {
transition-delay: 0.2s;
/* In order to still use it on fullscreen, even if it's 0px, add .1px (almost invisible) */
height: calc(var(--zen-element-separation) + 0.1px);

View file

@ -103,7 +103,10 @@
--zen-min-toolbox-padding: 0.35rem;
}
/* Actual padding used, ensuring it's at least min padding or based on element separation */
--zen-toolbox-padding: max(var(--zen-min-toolbox-padding), calc(var(--zen-element-separation) / 1.5));
--zen-toolbox-padding: max(
var(--zen-min-toolbox-padding),
calc(var(--zen-element-separation) / 1.5)
);
}
/* ==========================================================================
@ -290,7 +293,9 @@
/* Scale down tab slightly on active press (but not when dragging or clicking images) */
#tabbrowser-tabs:not([movingtab]) &:active:not(:has(.tab-content > image:active)) {
scale: var(--zen-active-tab-scale); /* Requires --zen-active-tab-scale to be defined elsewhere */
scale: var(
--zen-active-tab-scale
); /* Requires --zen-active-tab-scale to be defined elsewhere */
}
/* Scale down icon/image specifically on active press */
@ -535,7 +540,9 @@
/* Specific padding for URL bar input in single toolbar mode */
:root[zen-single-toolbar='true'] & {
& #urlbar:not([breakout-extend='true']):not([pageproxystate='invalid']) .urlbar-input-container {
&
#urlbar:not([breakout-extend='true']):not([pageproxystate='invalid'])
.urlbar-input-container {
padding-left: 8px;
padding-right: 4px;
}
@ -660,7 +667,10 @@
/* --- Pinned Tab Icon Repositioning & Reset Button --- */
/* Reposition icon stack absolutely when tab is pinned (and not essential) */
&[zen-pinned-changed='true']:not([zen-essential]) > .tab-stack > .tab-content > .tab-icon-stack {
&[zen-pinned-changed='true']:not([zen-essential])
> .tab-stack
> .tab-content
> .tab-icon-stack {
position: absolute;
top: 50%;
transform: translateY(-50%);
@ -889,7 +899,9 @@
:is(
:root[uidensity='compact'],
#tabbrowser-tabs[secondarytext-unsupported],
:root:not([uidensity='compact']) #tabbrowser-tabs:not([secondarytext-unsupported]) .tabbrowser-tab:hover
:root:not([uidensity='compact'])
#tabbrowser-tabs:not([secondarytext-unsupported])
.tabbrowser-tab:hover
)
.tab-icon-stack[indicator-replaces-favicon]
> :not(&),
@ -1024,7 +1036,9 @@
display: flex; /* Use flex for alignment */
position: relative; /* For pseudo-element positioning */
height: calc(100% - var(--tab-block-margin) * 2); /* Adjust height based on margins */
margin-left: calc(-1 * var(--tab-inline-padding) + var(--tab-block-margin)); /* Overlap slightly */
margin-left: calc(
-1 * var(--tab-inline-padding) + var(--tab-block-margin)
); /* Overlap slightly */
margin-right: 8px;
padding: 0 calc(var(--toolbarbutton-inner-padding) - 2px) 0
calc(var(--toolbarbutton-inner-padding) / 4 + var(--tab-inline-padding) - 2px); /* Custom padding */
@ -1118,7 +1132,9 @@
/* Adjust inner padding based on sidebar state */
:root[zen-sidebar-expanded='true'] & {
--toolbarbutton-inner-padding: var(--zen-toolbar-button-inner-padding) !important; /* Use theme variable */
--toolbarbutton-inner-padding: var(
--zen-toolbar-button-inner-padding
) !important; /* Use theme variable */
}
:root[zen-single-toolbar='true'] & {
--toolbarbutton-inner-padding: calc(
@ -1153,7 +1169,9 @@
/* Standardize height and padding for toolbar buttons (excluding titlebar buttons) */
& toolbarbutton:not(.titlebar-button) {
height: calc(2 * var(--toolbarbutton-inner-padding) + 16px); /* Calculate height based on padding + icon */
height: calc(
2 * var(--toolbarbutton-inner-padding) + 16px
); /* Calculate height based on padding + icon */
padding: 0 var(--toolbarbutton-outer-padding) !important; /* Apply outer padding */
}
@ -1231,7 +1249,10 @@
content: '';
display: block;
height: 1px;
background: light-dark(rgba(1, 1, 1, 0.075), rgba(255, 255, 255, 0.1)); /* Separator color */
background: light-dark(
rgba(1, 1, 1, 0.075),
rgba(255, 255, 255, 0.1)
); /* Separator color */
width: 98%; /* Near full width */
position: absolute;
top: -8px; /* Position above the button */
@ -1269,7 +1290,10 @@
grid-template-columns: repeat(auto-fit, minmax(max(30%, 48px), auto));
}
&[data-hack-type='2'] {
grid-template-columns: repeat(auto-fit, minmax(max(23%, 48px), 1fr) minmax(max(23%, 48px), 1fr));
grid-template-columns: repeat(
auto-fit,
minmax(max(23%, 48px), 1fr) minmax(max(23%, 48px), 1fr)
);
}
&[data-hack-type='3'] {
grid-template-columns: repeat(auto-fit, minmax(max(25%, 48px), 1fr));
@ -1282,7 +1306,9 @@
&[hidden='true'] {
--hidden-essentials-width: var(--zen-sidebar-width);
max-width: var(--hidden-essentials-width) !important; /* To still allow essentials to grid the tabs */
max-width: var(
--hidden-essentials-width
) !important; /* To still allow essentials to grid the tabs */
min-width: var(--hidden-essentials-width) !important;
}
}
@ -1351,7 +1377,9 @@
&::before {
background: light-dark(rgba(255, 255, 255, 0.85), rgba(68, 64, 64, 0.85));
margin: var(--zen-essential-bg-margin); /* Apply margin */
border-radius: calc(var(--border-radius-medium) - var(--zen-essential-bg-margin)); /* Adjust radius */
border-radius: calc(
var(--border-radius-medium) - var(--zen-essential-bg-margin)
); /* Adjust radius */
position: absolute;
inset: 0;
z-index: 0; /* Position above ::after, below content */

View file

@ -19,7 +19,9 @@ add_task(async function test_Check_Creation() {
'New tab should be marked as essential.'
);
ok(
gBrowser.tabs.find((t) => t.hasAttribute('zen-essential') && t.getAttribute('usercontextid') == 1),
gBrowser.tabs.find(
(t) => t.hasAttribute('zen-essential') && t.getAttribute('usercontextid') == 1
),
'New tab should be marked as essential.'
);
const newWorkspaceUUID = ZenWorkspaces.activeWorkspace;
@ -27,7 +29,9 @@ add_task(async function test_Check_Creation() {
// Change to the original workspace, there should be no essential tabs
await ZenWorkspaces.changeWorkspace(workspaces.workspaces[0]);
ok(
!gBrowser.tabs.find((t) => t.hasAttribute('zen-essential') && t.getAttribute('usercontextid') == 1),
!gBrowser.tabs.find(
(t) => t.hasAttribute('zen-essential') && t.getAttribute('usercontextid') == 1
),
'No essential tabs should be found in the original workspace.'
);

View file

@ -32,7 +32,10 @@ add_task(async function test_Click_Shoudnt_FLoat_Urlbar() {
value: 'http://example.com/',
});
ok(!gURLBar.textbox.hasAttribute('zen-floating-urlbar'), 'URL bar should not be in floating mode');
ok(
!gURLBar.textbox.hasAttribute('zen-floating-urlbar'),
'URL bar should not be in floating mode'
);
});
add_task(async function test_Floating_Highlight_Everything() {
@ -44,5 +47,8 @@ add_task(async function test_Floating_Highlight_Everything() {
// Selection range
ok(gURLBar.selectionStart == 0, 'Selection start should be 0');
ok(gURLBar.selectionEnd == gURLBar.value.length, 'Selection end should be the length of the value');
ok(
gURLBar.selectionEnd == gURLBar.value.length,
'Selection end should be the length of the value'
);
});

View file

@ -14,9 +14,27 @@ function selectWithMouseDrag(fromX, toX, win = window) {
let target = win.gURLBar.inputField;
let rect = target.getBoundingClientRect();
let promise = BrowserTestUtils.waitForEvent(target, 'mouseup');
EventUtils.synthesizeMouse(target, fromX, rect.height / 2, { type: 'mousemove' }, target.ownerGlobal);
EventUtils.synthesizeMouse(target, fromX, rect.height / 2, { type: 'mousedown' }, target.ownerGlobal);
EventUtils.synthesizeMouse(target, toX, rect.height / 2, { type: 'mousemove' }, target.ownerGlobal);
EventUtils.synthesizeMouse(
target,
fromX,
rect.height / 2,
{ type: 'mousemove' },
target.ownerGlobal
);
EventUtils.synthesizeMouse(
target,
fromX,
rect.height / 2,
{ type: 'mousedown' },
target.ownerGlobal
);
EventUtils.synthesizeMouse(
target,
toX,
rect.height / 2,
{ type: 'mousemove' },
target.ownerGlobal
);
EventUtils.synthesizeMouse(target, toX, rect.height / 2, { type: 'mouseup' }, target.ownerGlobal);
return promise;
}

View file

@ -10,7 +10,10 @@ add_task(async function test_Check_Creation() {
await ZenWorkspaces.createAndSaveWorkspace('Test Workspace 2');
const workspaces = await ZenWorkspaces._workspaces();
ok(workspaces.workspaces.length === 2, 'Two workspaces should exist.');
ok(currentWorkspaceUUID !== workspaces.workspaces[1].uuid, 'The new workspace should be different from the current one.');
ok(
currentWorkspaceUUID !== workspaces.workspaces[1].uuid,
'The new workspace should be different from the current one.'
);
let newTab = BrowserTestUtils.addTab(gBrowser, 'about:blank', {
skipAnimation: true,
@ -22,6 +25,9 @@ add_task(async function test_Check_Creation() {
await ZenWorkspaces.removeWorkspace(ZenWorkspaces.activeWorkspace);
const workspacesAfterRemove = await ZenWorkspaces._workspaces();
ok(workspacesAfterRemove.workspaces.length === 1, 'One workspace should exist.');
ok(workspacesAfterRemove.workspaces[0].uuid === currentWorkspaceUUID, 'The workspace should be the one we started with.');
ok(
workspacesAfterRemove.workspaces[0].uuid === currentWorkspaceUUID,
'The workspace should be the one we started with.'
);
ok(gBrowser.tabs.length === 2, 'There should be one tab.');
});

View file

@ -11,13 +11,25 @@ const ROOT = getRootDirectory(gTestPath);
const HTTPROOT = ROOT.replace('chrome://mochitests/content/', 'http://example.com/');
const HTTPSROOT = ROOT.replace('chrome://mochitests/content/', 'https://example.com/');
const { SessionSaver } = ChromeUtils.importESModule('resource:///modules/sessionstore/SessionSaver.sys.mjs');
const { SessionFile } = ChromeUtils.importESModule('resource:///modules/sessionstore/SessionFile.sys.mjs');
const { TabState } = ChromeUtils.importESModule('resource:///modules/sessionstore/TabState.sys.mjs');
const { TabStateFlusher } = ChromeUtils.importESModule('resource:///modules/sessionstore/TabStateFlusher.sys.mjs');
const { SessionStoreTestUtils } = ChromeUtils.importESModule('resource://testing-common/SessionStoreTestUtils.sys.mjs');
const { SessionSaver } = ChromeUtils.importESModule(
'resource:///modules/sessionstore/SessionSaver.sys.mjs'
);
const { SessionFile } = ChromeUtils.importESModule(
'resource:///modules/sessionstore/SessionFile.sys.mjs'
);
const { TabState } = ChromeUtils.importESModule(
'resource:///modules/sessionstore/TabState.sys.mjs'
);
const { TabStateFlusher } = ChromeUtils.importESModule(
'resource:///modules/sessionstore/TabStateFlusher.sys.mjs'
);
const { SessionStoreTestUtils } = ChromeUtils.importESModule(
'resource://testing-common/SessionStoreTestUtils.sys.mjs'
);
const { PageWireframes } = ChromeUtils.importESModule('resource:///modules/sessionstore/PageWireframes.sys.mjs');
const { PageWireframes } = ChromeUtils.importESModule(
'resource:///modules/sessionstore/PageWireframes.sys.mjs'
);
const ss = SessionStore;
SessionStoreTestUtils.init(this, window);
@ -47,7 +59,12 @@ function provideWindow(aCallback, aURL, aFeatures) {
});
}
let win = openDialog(AppConstants.BROWSER_CHROME_URL, '', aFeatures || 'chrome,all,dialog=no', aURL || 'about:blank');
let win = openDialog(
AppConstants.BROWSER_CHROME_URL,
'',
aFeatures || 'chrome,all,dialog=no',
aURL || 'about:blank'
);
whenWindowLoaded(win, function onWindowLoaded(aWin) {
if (!aURL) {
info('Loaded a blank window.');
@ -85,11 +102,15 @@ function promiseTabState(tab, state) {
}
function promiseWindowRestoring(win) {
return new Promise((resolve) => win.addEventListener('SSWindowRestoring', resolve, { once: true }));
return new Promise((resolve) =>
win.addEventListener('SSWindowRestoring', resolve, { once: true })
);
}
function promiseWindowRestored(win) {
return new Promise((resolve) => win.addEventListener('SSWindowRestored', resolve, { once: true }));
return new Promise((resolve) =>
win.addEventListener('SSWindowRestored', resolve, { once: true })
);
}
async function setBrowserState(state, win = window) {
@ -426,37 +447,45 @@ function modifySessionStorage(browser, storageData, storageOptions = {}) {
browsingContext = browsingContext.children[storageOptions.frameIndex];
}
return SpecialPowers.spawn(browsingContext, [[storageData, storageOptions]], async function ([data]) {
let frame = content;
let keys = new Set(Object.keys(data));
let isClearing = !keys.size;
let storage = frame.sessionStorage;
return SpecialPowers.spawn(
browsingContext,
[[storageData, storageOptions]],
async function ([data]) {
let frame = content;
let keys = new Set(Object.keys(data));
let isClearing = !keys.size;
let storage = frame.sessionStorage;
return new Promise((resolve) => {
docShell.chromeEventHandler.addEventListener(
'MozSessionStorageChanged',
function onStorageChanged(event) {
if (event.storageArea == storage) {
keys.delete(event.key);
return new Promise((resolve) => {
docShell.chromeEventHandler.addEventListener(
'MozSessionStorageChanged',
function onStorageChanged(event) {
if (event.storageArea == storage) {
keys.delete(event.key);
}
if (keys.size == 0) {
docShell.chromeEventHandler.removeEventListener(
'MozSessionStorageChanged',
onStorageChanged,
true
);
resolve();
}
},
true
);
if (isClearing) {
storage.clear();
} else {
for (let key of keys) {
frame.sessionStorage[key] = data[key];
}
if (keys.size == 0) {
docShell.chromeEventHandler.removeEventListener('MozSessionStorageChanged', onStorageChanged, true);
resolve();
}
},
true
);
if (isClearing) {
storage.clear();
} else {
for (let key of keys) {
frame.sessionStorage[key] = data[key];
}
}
});
});
});
}
);
}
function pushPrefs(...aPrefs) {
@ -503,20 +532,28 @@ function whenDomWindowClosedHandled(aCallback) {
}
function getPropertyOfFormField(browserContext, selector, propName) {
return SpecialPowers.spawn(browserContext, [selector, propName], (selectorChild, propNameChild) => {
return content.document.querySelector(selectorChild)[propNameChild];
});
return SpecialPowers.spawn(
browserContext,
[selector, propName],
(selectorChild, propNameChild) => {
return content.document.querySelector(selectorChild)[propNameChild];
}
);
}
function setPropertyOfFormField(browserContext, selector, propName, newValue) {
return SpecialPowers.spawn(browserContext, [selector, propName, newValue], (selectorChild, propNameChild, newValueChild) => {
let node = content.document.querySelector(selectorChild);
node[propNameChild] = newValueChild;
return SpecialPowers.spawn(
browserContext,
[selector, propName, newValue],
(selectorChild, propNameChild, newValueChild) => {
let node = content.document.querySelector(selectorChild);
node[propNameChild] = newValueChild;
let event = node.ownerDocument.createEvent('UIEvents');
event.initUIEvent('input', true, true, node.ownerGlobal, 0);
node.dispatchEvent(event);
});
let event = node.ownerDocument.createEvent('UIEvents');
event.initUIEvent('input', true, true, node.ownerGlobal, 0);
node.dispatchEvent(event);
}
);
}
function promiseOnHistoryReplaceEntry(browser) {

View file

@ -84,8 +84,16 @@
async function openInitialPinTab() {
const tabs = [
['https://reddit.com/r/zen_browser', 'Zen on Reddit', 'chrome://browser/content/zen-images/favicons/reddit.ico'],
['https://x.com/zen_browser', 'Zen on Twitter', 'chrome://browser/content/zen-images/favicons/x.ico'],
[
'https://reddit.com/r/zen_browser',
'Zen on Reddit',
'chrome://browser/content/zen-images/favicons/reddit.ico',
],
[
'https://x.com/zen_browser',
'Zen on Twitter',
'chrome://browser/content/zen-images/favicons/x.ico',
],
];
await PlacesUtils.history.insertMany(
@ -307,7 +315,11 @@
getEngines() {
return this._engines.filter(
(engine) => !(engine.name.toLowerCase().includes('wikipedia') || engine.name.toLowerCase().includes('ebay'))
(engine) =>
!(
engine.name.toLowerCase().includes('wikipedia') ||
engine.name.toLowerCase().includes('ebay')
)
);
}
@ -344,7 +356,10 @@
}
async setDefaultEngine(engine) {
await Services.search.setDefault(engine.originalEngine, Ci.nsISearchService.CHANGE_REASON_USER);
await Services.search.setDefault(
engine.originalEngine,
Ci.nsISearchService.CHANGE_REASON_USER
);
}
}
@ -398,7 +413,9 @@
document.getElementById('zen-welcome-page-content').appendChild(fragment);
},
async fadeOut() {
const shouldSetDefault = document.getElementById('zen-welcome-set-default-browser').checked;
const shouldSetDefault = document.getElementById(
'zen-welcome-set-default-browser'
).checked;
if (AppConstants.HAVE_SHELL_SERVICE && shouldSetDefault) {
let shellSvc = getShellService();
if (!shellSvc) {
@ -728,7 +745,9 @@
function () {
window.resizeTo(875, 560);
window.focus();
const appWin = window.docShell.treeOwner.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIAppWindow);
const appWin = window.docShell.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIAppWindow);
appWin.rollupAllPopups();
window.moveTo(
screen.availLeft + (screen.availWidth - outerWidth) / 2,

View file

@ -13,12 +13,17 @@
useAlgo = '';
constructor() {
super();
if (!Services.prefs.getBoolPref('zen.theme.gradient', true) || !ZenWorkspaces.shouldHaveWorkspaces) {
if (
!Services.prefs.getBoolPref('zen.theme.gradient', true) ||
!ZenWorkspaces.shouldHaveWorkspaces
) {
return;
}
this.dragStartPosition = null;
ChromeUtils.defineLazyGetter(this, 'panel', () => document.getElementById('PanelUI-zen-gradient-generator'));
ChromeUtils.defineLazyGetter(this, 'panel', () =>
document.getElementById('PanelUI-zen-gradient-generator')
);
ChromeUtils.defineLazyGetter(this, 'toolbox', () => document.getElementById('TabsToolbar'));
ChromeUtils.defineLazyGetter(this, 'customColorInput', () =>
document.getElementById('PanelUI-zen-gradient-generator-custom-input')
@ -48,7 +53,9 @@
this.initTextureInput();
this.initRotationInput();
window.matchMedia('(prefers-color-scheme: dark)').addListener(this.onDarkModeChange.bind(this));
window
.matchMedia('(prefers-color-scheme: dark)')
.addListener(this.onDarkModeChange.bind(this));
}
get isDarkMode() {
@ -110,50 +117,52 @@
}
initPredefinedColors() {
document.getElementById('PanelUI-zen-gradient-generator-predefined').addEventListener('click', async (event) => {
const target = event.target;
const rawPosition = target.getAttribute('data-position');
if (!rawPosition) {
return;
}
const algo = target.getAttribute('data-algo');
const numDots = parseInt(target.getAttribute('data-num-dots'));
if (algo == 'float') {
for (const dot of this.dots) {
dot.element.remove();
document
.getElementById('PanelUI-zen-gradient-generator-predefined')
.addEventListener('click', async (event) => {
const target = event.target;
const rawPosition = target.getAttribute('data-position');
if (!rawPosition) {
return;
}
this.dots = [];
} else if (numDots < this.dots.length) {
for (let i = numDots; i < this.dots.length; i++) {
this.dots[i].element.remove();
const algo = target.getAttribute('data-algo');
const numDots = parseInt(target.getAttribute('data-num-dots'));
if (algo == 'float') {
for (const dot of this.dots) {
dot.element.remove();
}
this.dots = [];
} else if (numDots < this.dots.length) {
for (let i = numDots; i < this.dots.length; i++) {
this.dots[i].element.remove();
}
this.dots = this.dots.slice(0, numDots);
}
this.dots = this.dots.slice(0, numDots);
}
// Generate new gradient from the single color given
const [x, y] = rawPosition.split(',').map((pos) => parseInt(pos));
let dots = [
{
ID: 0,
position: { x, y },
},
];
for (let i = 1; i < numDots; i++) {
dots.push({
ID: i,
position: { x: 0, y: 0 },
});
}
this.useAlgo = algo;
dots = this.calculateCompliments(dots, 'update', this.useAlgo);
if (algo == 'float') {
for (const dot of dots) {
this.spawnDot(dot.position);
// Generate new gradient from the single color given
const [x, y] = rawPosition.split(',').map((pos) => parseInt(pos));
let dots = [
{
ID: 0,
position: { x, y },
},
];
for (let i = 1; i < numDots; i++) {
dots.push({
ID: i,
position: { x: 0, y: 0 },
});
}
this.dots[0].element.classList.add('primary');
}
this.handleColorPositions(dots);
this.updateCurrentWorkspace();
});
this.useAlgo = algo;
dots = this.calculateCompliments(dots, 'update', this.useAlgo);
if (algo == 'float') {
for (const dot of dots) {
this.spawnDot(dot.position);
}
this.dots[0].element.classList.add('primary');
}
this.handleColorPositions(dots);
this.updateCurrentWorkspace();
});
}
initCustomColorInput() {
@ -383,8 +392,12 @@
<toolbarbutton class="zen-theme-picker-custom-list-item-remove toolbarbutton-1"></toolbarbutton>
</hbox>
`);
listItems.querySelector('.zen-theme-picker-custom-list-item').setAttribute('data-color', color);
listItems.querySelector('.zen-theme-picker-dot').style.setProperty('--zen-theme-picker-dot-color', color);
listItems
.querySelector('.zen-theme-picker-custom-list-item')
.setAttribute('data-color', color);
listItems
.querySelector('.zen-theme-picker-dot')
.style.setProperty('--zen-theme-picker-dot-color', color);
listItems.querySelector('.zen-theme-picker-custom-list-item-label').textContent = color;
listItems
.querySelector('.zen-theme-picker-custom-list-item-remove')
@ -452,7 +465,10 @@
}
const colorFromPos = this.getColorFromPosition(relativePosition.x, relativePosition.y);
dot.style.setProperty('--zen-theme-picker-dot-color', `rgb(${colorFromPos[0]}, ${colorFromPos[1]}, ${colorFromPos[2]})`);
dot.style.setProperty(
'--zen-theme-picker-dot-color',
`rgb(${colorFromPos[0]}, ${colorFromPos[1]}, ${colorFromPos[2]})`
);
this.dots.push({
ID: id,
@ -481,13 +497,17 @@
if (selectedHarmony) {
if (action === 'remove') {
if (dots.length !== 0) {
return colorHarmonies.find((harmony) => harmony.angles.length === selectedHarmony.angles.length - 1);
return colorHarmonies.find(
(harmony) => harmony.angles.length === selectedHarmony.angles.length - 1
);
} else {
return { type: 'floating', angles: [] };
}
}
if (action === 'add') {
return colorHarmonies.find((harmony) => harmony.angles.length === selectedHarmony.angles.length + 1);
return colorHarmonies.find(
(harmony) => harmony.angles.length === selectedHarmony.angles.length + 1
);
}
if (action === 'update') {
return selectedHarmony;
@ -526,7 +546,10 @@
let updatedDots = [...dots];
const centerPosition = { x: rect.width / 2, y: rect.height / 2 };
const harmonyAngles = getColorHarmonyType(dots.length + (action === 'add' ? 1 : action === 'remove' ? -1 : 0), this.dots);
const harmonyAngles = getColorHarmonyType(
dots.length + (action === 'add' ? 1 : action === 'remove' ? -1 : 0),
this.dots
);
this.useAlgo = harmonyAngles.type;
if (!harmonyAngles || harmonyAngles.angles.length === 0) return dots;
@ -594,7 +617,10 @@
if (existingPrimaryDot) {
existingPrimaryDot.element.style.zIndex = 999;
const colorFromPos = this.getColorFromPosition(existingPrimaryDot.position.x, existingPrimaryDot.position.y);
const colorFromPos = this.getColorFromPosition(
existingPrimaryDot.position.x,
existingPrimaryDot.position.y
);
existingPrimaryDot.element.style.setProperty(
'--zen-theme-picker-dot-color',
`rgb(${colorFromPos[0]}, ${colorFromPos[1]}, ${colorFromPos[2]})`
@ -606,7 +632,10 @@
if (existingDot) {
existingDot.position = dotPosition.position;
const colorFromPos = this.getColorFromPosition(dotPosition.position.x, dotPosition.position.y);
const colorFromPos = this.getColorFromPosition(
dotPosition.position.x,
dotPosition.position.y
);
existingDot.element.style.setProperty(
'--zen-theme-picker-dot-color',
`rgb(${colorFromPos[0]}, ${colorFromPos[1]}, ${colorFromPos[2]})`
@ -681,7 +710,9 @@
(harmony) => harmony.angles.length + 1 === this.dots.length || harmony.type === 'floating'
);
let currentIndex = applicableHarmonies.findIndex((harmony) => harmony.type === this.useAlgo);
let currentIndex = applicableHarmonies.findIndex(
(harmony) => harmony.type === this.useAlgo
);
let nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % applicableHarmonies.length;
this.useAlgo = applicableHarmonies[nextIndex].type;
@ -875,7 +906,11 @@
return colors.map((color) => ({
c: color.isCustom
? color.c
: [Math.min(255, color.c[0] * factor), Math.min(255, color.c[1] * factor), Math.min(255, color.c[2] * factor)],
: [
Math.min(255, color.c[0] * factor),
Math.min(255, color.c[1] * factor),
Math.min(255, color.c[2] * factor),
],
isCustom: color.isCustom,
algorithm: color.algorithm,
}));
@ -908,7 +943,9 @@
this.useAlgo = themedColors[0]?.algorithm ?? '';
if (themedColors.length === 0) {
return forToolbar ? 'var(--zen-themed-toolbar-bg)' : 'var(--zen-themed-toolbar-bg-transparent)';
return forToolbar
? 'var(--zen-themed-toolbar-bg)'
: 'var(--zen-themed-toolbar-bg-transparent)';
} else if (themedColors.length === 1) {
return this.getSingleRGBColor(themedColors[0], forToolbar);
} else if (themedColors.length !== 3) {
@ -945,7 +982,11 @@
.map((char) => char + char)
.join('');
}
return [parseInt(hex.substring(0, 2), 16), parseInt(hex.substring(2, 4), 16), parseInt(hex.substring(4, 6), 16)];
return [
parseInt(hex.substring(0, 2), 16),
parseInt(hex.substring(2, 4), 16),
parseInt(hex.substring(4, 6), 16),
];
}
pSBC = (p, c0, c1, l) => {
@ -959,7 +1000,14 @@
i = parseInt,
m = Math.round,
a = typeof c1 == 'string';
if (typeof p != 'number' || p < -1 || p > 1 || typeof c0 != 'string' || (c0[0] != 'r' && c0[0] != '#') || (c1 && !a))
if (
typeof p != 'number' ||
p < -1 ||
p > 1 ||
typeof c0 != 'string' ||
(c0[0] != 'r' && c0[0] != '#') ||
(c1 && !a)
)
return null;
if (!this.pSBCr)
this.pSBCr = (d) => {
@ -968,13 +1016,20 @@
if (n > 9) {
([r, g, b, a] = d = d.split(',')), (n = d.length);
if (n < 3 || n > 4) return null;
(x.r = i(r[3] == 'a' ? r.slice(5) : r.slice(4))), (x.g = i(g)), (x.b = i(b)), (x.a = a ? parseFloat(a) : -1);
(x.r = i(r[3] == 'a' ? r.slice(5) : r.slice(4))),
(x.g = i(g)),
(x.b = i(b)),
(x.a = a ? parseFloat(a) : -1);
} else {
if (n == 8 || n == 6 || n < 4) return null;
if (n < 6) d = '#' + d[1] + d[1] + d[2] + d[2] + d[3] + d[3] + (n > 4 ? d[4] + d[4] : '');
if (n < 6)
d = '#' + d[1] + d[1] + d[2] + d[2] + d[3] + d[3] + (n > 4 ? d[4] + d[4] : '');
d = i(d.slice(1), 16);
if (n == 9 || n == 5)
(x.r = (d >> 24) & 255), (x.g = (d >> 16) & 255), (x.b = (d >> 8) & 255), (x.a = m((d & 255) / 0.255) / 1000);
(x.r = (d >> 24) & 255),
(x.g = (d >> 16) & 255),
(x.b = (d >> 8) & 255),
(x.a = m((d & 255) / 0.255) / 1000);
else (x.r = d >> 16), (x.g = (d >> 8) & 255), (x.b = d & 255), (x.a = -1);
}
return x;
@ -983,7 +1038,12 @@
(h = a ? (c1.length > 9 ? true : c1 == 'c' ? !h : false) : h),
(f = this.pSBCr(c0)),
(P = p < 0),
(t = c1 && c1 != 'c' ? this.pSBCr(c1) : P ? { r: 0, g: 0, b: 0, a: -1 } : { r: 255, g: 255, b: 255, a: -1 }),
(t =
c1 && c1 != 'c'
? this.pSBCr(c1)
: P
? { r: 0, g: 0, b: 0, a: -1 }
: { r: 255, g: 255, b: 255, a: -1 }),
(p = P ? p * -1 : p),
(P = 1 - p);
if (!f || !t) return null;
@ -992,12 +1052,28 @@
(r = m((P * f.r ** 2 + p * t.r ** 2) ** 0.5)),
(g = m((P * f.g ** 2 + p * t.g ** 2) ** 0.5)),
(b = m((P * f.b ** 2 + p * t.b ** 2) ** 0.5));
(a = f.a), (t = t.a), (f = a >= 0 || t >= 0), (a = f ? (a < 0 ? t : t < 0 ? a : a * P + t * p) : 0);
if (h) return 'rgb' + (f ? 'a(' : '(') + r + ',' + g + ',' + b + (f ? ',' + m(a * 1000) / 1000 : '') + ')';
(a = f.a),
(t = t.a),
(f = a >= 0 || t >= 0),
(a = f ? (a < 0 ? t : t < 0 ? a : a * P + t * p) : 0);
if (h)
return (
'rgb' +
(f ? 'a(' : '(') +
r +
',' +
g +
',' +
b +
(f ? ',' + m(a * 1000) / 1000 : '') +
')'
);
else
return (
'#' +
(4294967296 + r * 16777216 + g * 65536 + b * 256 + (f ? m(a * 255) : 0)).toString(16).slice(1, f ? undefined : -2)
(4294967296 + r * 16777216 + g * 65536 + b * 256 + (f ? m(a * 255) : 0))
.toString(16)
.slice(1, f ? undefined : -2)
);
};
@ -1033,7 +1109,9 @@
workspaceTheme = this.fixTheme(theme || windowWorkspace.theme);
if (!skipUpdate) {
for (const dot of browser.gZenThemePicker.panel.querySelectorAll('.zen-theme-picker-dot')) {
for (const dot of browser.gZenThemePicker.panel.querySelectorAll(
'.zen-theme-picker-dot'
)) {
dot.remove();
}
}
@ -1052,7 +1130,9 @@
this._animatingBackground = false;
appWrapper.removeAttribute('animating');
appWrapper.setAttribute('post-animating', 'true');
browser.document.documentElement.style.removeProperty('--zen-main-browser-background-old');
browser.document.documentElement.style.removeProperty(
'--zen-main-browser-background-old'
);
setTimeout(() => {
// Reactivate the transition after the animation
appWrapper.removeAttribute('post-animating');
@ -1061,9 +1141,14 @@
});
}
const button = browser.document.getElementById('PanelUI-zen-gradient-generator-color-toggle-algo');
const button = browser.document.getElementById(
'PanelUI-zen-gradient-generator-color-toggle-algo'
);
if (browser.gZenThemePicker.useAlgo) {
document.l10n.setAttributes(button, `zen-panel-ui-gradient-generator-algo-${browser.gZenThemePicker.useAlgo}`);
document.l10n.setAttributes(
button,
`zen-panel-ui-gradient-generator-algo-${browser.gZenThemePicker.useAlgo}`
);
} else {
button.removeAttribute('data-l10n-id');
}
@ -1072,10 +1157,19 @@
if (!workspaceTheme || workspaceTheme.type !== 'gradient') {
const gradient = browser.gZenThemePicker.getGradient([]);
const gradientToolbar = browser.gZenThemePicker.getGradient([], true);
browser.document.documentElement.style.setProperty('--zen-main-browser-background', gradient);
browser.document.documentElement.style.setProperty('--zen-main-browser-background-toolbar', gradientToolbar);
browser.document.documentElement.style.setProperty(
'--zen-main-browser-background',
gradient
);
browser.document.documentElement.style.setProperty(
'--zen-main-browser-background-toolbar',
gradientToolbar
);
browser.gZenThemePicker.updateNoise(0);
browser.document.documentElement.style.setProperty('--zen-primary-color', this.getNativeAccentColor());
browser.document.documentElement.style.setProperty(
'--zen-primary-color',
this.getNativeAccentColor()
);
return;
}
@ -1083,7 +1177,9 @@
browser.gZenThemePicker.currentRotation = workspaceTheme.rotation ?? -45;
browser.gZenThemePicker.currentTexture = workspaceTheme.texture ?? 0;
for (const button of browser.document.querySelectorAll('#PanelUI-zen-gradient-generator-color-actions button')) {
for (const button of browser.document.querySelectorAll(
'#PanelUI-zen-gradient-generator-color-actions button'
)) {
// disable if there are no buttons
button.disabled =
workspaceTheme.gradientColors.length === 0 ||
@ -1097,7 +1193,9 @@
browser.document.getElementById('PanelUI-zen-gradient-generator-opacity').value =
browser.gZenThemePicker.currentOpacity;
const textureSelectWrapper = browser.document.getElementById('PanelUI-zen-gradient-generator-texture-wrapper');
const textureSelectWrapper = browser.document.getElementById(
'PanelUI-zen-gradient-generator-texture-wrapper'
);
const textureWrapperWidth = textureSelectWrapper.getBoundingClientRect().width;
// Dont show when hidden
if (textureWrapperWidth) {
@ -1125,8 +1223,12 @@
}
const numberOfColors = workspaceTheme.gradientColors?.length;
const rotationDot = browser.document.getElementById('PanelUI-zen-gradient-generator-rotation-dot');
const rotationLine = browser.document.getElementById('PanelUI-zen-gradient-generator-rotation-line');
const rotationDot = browser.document.getElementById(
'PanelUI-zen-gradient-generator-rotation-dot'
);
const rotationLine = browser.document.getElementById(
'PanelUI-zen-gradient-generator-rotation-line'
);
if (numberOfColors > 1) {
rotationDot.style.opacity = 1;
rotationLine.style.opacity = 1;
@ -1136,9 +1238,11 @@
const rotationDotPosition = this.currentRotation;
const rotationDotWidth = 30;
const rotationDotX =
Math.cos((rotationDotPosition * Math.PI) / 180) * (rotationParentWidth / 2 - rotationDotWidth / 2);
Math.cos((rotationDotPosition * Math.PI) / 180) *
(rotationParentWidth / 2 - rotationDotWidth / 2);
const rotationDotY =
Math.sin((rotationDotPosition * Math.PI) / 180) * (rotationParentWidth / 2 - rotationDotWidth / 2);
Math.sin((rotationDotPosition * Math.PI) / 180) *
(rotationParentWidth / 2 - rotationDotWidth / 2);
rotationDot.style.left = `${rotationParentWidth / 2 + rotationDotX - rotationPadding + rotationDotWidth / 4}px`;
rotationDot.style.top = `${rotationParentWidth / 2 + rotationDotY - rotationPadding + rotationDotWidth / 4}px`;
} else {
@ -1149,7 +1253,10 @@
}
const gradient = browser.gZenThemePicker.getGradient(workspaceTheme.gradientColors);
const gradientToolbar = browser.gZenThemePicker.getGradient(workspaceTheme.gradientColors, true);
const gradientToolbar = browser.gZenThemePicker.getGradient(
workspaceTheme.gradientColors,
true
);
browser.gZenThemePicker.updateNoise(workspaceTheme.texture);
for (const dot of workspaceTheme.gradientColors) {
@ -1158,8 +1265,14 @@
}
}
browser.document.documentElement.style.setProperty('--zen-main-browser-background-toolbar', gradientToolbar);
browser.document.documentElement.style.setProperty('--zen-main-browser-background', gradient);
browser.document.documentElement.style.setProperty(
'--zen-main-browser-background-toolbar',
gradientToolbar
);
browser.document.documentElement.style.setProperty(
'--zen-main-browser-background',
gradient
);
const dominantColor = this.getMostDominantColor(workspaceTheme.gradientColors);
if (dominantColor) {
@ -1180,7 +1293,10 @@
fixTheme(theme) {
// add a primary color if there isn't one
if (!theme.gradientColors.find((color) => color.isPrimary) && theme.gradientColors.length > 0) {
if (
!theme.gradientColors.find((color) => color.isPrimary) &&
theme.gradientColors.length > 0
) {
theme.gradientColors[(theme.gradientColors.length / 2) | 0].isPrimary = true;
}
return theme;
@ -1252,9 +1368,19 @@
}
const isCustom = dot.classList.contains('custom');
const algorithm = this.useAlgo;
return { c: isCustom ? color : color.match(/\d+/g).map(Number), isCustom, algorithm, isPrimary };
return {
c: isCustom ? color : color.match(/\d+/g).map(Number),
isCustom,
algorithm,
isPrimary,
};
});
const gradient = ZenThemePicker.getTheme(colors, this.currentOpacity, this.currentRotation, this.currentTexture);
const gradient = ZenThemePicker.getTheme(
colors,
this.currentOpacity,
this.currentRotation,
this.currentTexture
);
let currentWorkspace = await ZenWorkspaces.getActiveWorkspace();
if (!skipSave) {

View file

@ -48,7 +48,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
`;
async waitForPromises() {
await Promise.all([this.promiseDBInitialized, this.promisePinnedInitialized, SessionStore.promiseAllWindowsRestored]);
await Promise.all([
this.promiseDBInitialized,
this.promisePinnedInitialized,
SessionStore.promiseAllWindowsRestored,
]);
}
async init() {
@ -64,15 +68,32 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (!this.shouldHaveWorkspaces) {
this._resolveInitialized();
document.getElementById('zen-current-workspace-indicator-container').setAttribute('hidden', 'true');
document
.getElementById('zen-current-workspace-indicator-container')
.setAttribute('hidden', 'true');
console.warn('ZenWorkspaces: !!! ZenWorkspaces is disabled in hidden windows !!!');
return; // We are in a hidden window, don't initialize ZenWorkspaces
}
this.ownerWindow = window;
XPCOMUtils.defineLazyPreferenceGetter(this, 'activationMethod', 'zen.workspaces.scroll-modifier-key', 'ctrl');
XPCOMUtils.defineLazyPreferenceGetter(this, 'naturalScroll', 'zen.workspaces.natural-scroll', true);
XPCOMUtils.defineLazyPreferenceGetter(this, 'shouldWrapAroundNavigation', 'zen.workspaces.wrap-around-navigation', true);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'activationMethod',
'zen.workspaces.scroll-modifier-key',
'ctrl'
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'naturalScroll',
'zen.workspaces.natural-scroll',
true
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'shouldWrapAroundNavigation',
'zen.workspaces.wrap-around-navigation',
true
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'shouldForceContainerTabsToWorkspace',
@ -89,7 +110,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
'zen.workspaces.container-specific-essentials-enabled',
false
);
ChromeUtils.defineLazyGetter(this, 'tabContainer', () => document.getElementById('tabbrowser-tabs'));
ChromeUtils.defineLazyGetter(this, 'tabContainer', () =>
document.getElementById('tabbrowser-tabs')
);
this._activeWorkspace = Services.prefs.getStringPref('zen.workspaces.active', '');
window.addEventListener('resize', this.onWindowResize.bind(this));
@ -111,7 +134,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
this.log('ZenWorkspaces initialized');
await this.initializeWorkspaces();
if (Services.prefs.getBoolPref('zen.workspaces.swipe-actions', false) && this.workspaceEnabled) {
if (
Services.prefs.getBoolPref('zen.workspaces.swipe-actions', false) &&
this.workspaceEnabled
) {
this.initializeGestureHandlers();
this.initializeWorkspaceNavigation();
}
@ -158,7 +184,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
const timeSinceLastSelection = now - this._tabSelectionState.lastSelectionTime;
if (timeSinceLastSelection < this._tabSelectionState.debounceTime) {
await new Promise((resolve) => setTimeout(resolve, this._tabSelectionState.debounceTime - timeSinceLastSelection));
await new Promise((resolve) =>
setTimeout(resolve, this._tabSelectionState.debounceTime - timeSinceLastSelection)
);
}
// Mark selection as in progress
@ -278,7 +306,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
_initializeEmptyTab() {
this._emptyTab = gBrowser.addTrustedTab('about:blank', { inBackground: true, userContextId: 0, _forZenEmptyTab: true });
this._emptyTab = gBrowser.addTrustedTab('about:blank', {
inBackground: true,
userContextId: 0,
_forZenEmptyTab: true,
});
}
registerPinnedResizeObserver() {
@ -377,7 +409,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (!this.containerSpecificEssentials) {
container = 0;
}
let essentialsContainer = document.querySelector(`.zen-essentials-container[container="${container}"]:not([cloned])`);
let essentialsContainer = document.querySelector(
`.zen-essentials-container[container="${container}"]:not([cloned])`
);
if (!essentialsContainer) {
essentialsContainer = document.createXULElement('hbox');
essentialsContainer.className = 'zen-essentials-container zen-workspace-tabs-section';
@ -421,13 +455,19 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
const workspaceIndicator = this.#createWorkspaceSection(workspace);
workspaceIndicator.classList.add('zen-current-workspace-indicator');
workspaceIndicator.appendChild(window.MozXULElement.parseXULToFragment(this.workspaceIndicatorXUL));
document.getElementById('zen-current-workspace-indicator-container').appendChild(workspaceIndicator);
workspaceIndicator.appendChild(
window.MozXULElement.parseXULToFragment(this.workspaceIndicatorXUL)
);
document
.getElementById('zen-current-workspace-indicator-container')
.appendChild(workspaceIndicator);
this.initIndicatorContextMenu(workspaceIndicator);
}
_organizeTabsToWorkspaceSections(workspace, section, pinnedSection, tabs) {
const workspaceTabs = Array.from(tabs).filter((tab) => tab.getAttribute('zen-workspace-id') === workspace.uuid);
const workspaceTabs = Array.from(tabs).filter(
(tab) => tab.getAttribute('zen-workspace-id') === workspace.uuid
);
let firstNormalTab = null;
for (let tab of workspaceTabs) {
if (tab.hasAttribute('zen-essential')) {
@ -521,7 +561,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
meta: event.metaKey,
};
if (this.activationMethod in activationKeyMap && !activationKeyMap[this.activationMethod]) {
if (
this.activationMethod in activationKeyMap &&
!activationKeyMap[this.activationMethod]
) {
return;
}
}
@ -699,7 +742,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
get workspaceEnabled() {
if (typeof this._workspaceEnabled === 'undefined') {
this._workspaceEnabled = this.shouldHaveWorkspaces && !Services.prefs.getBoolPref('zen.testing.profiling.enabled', false);
this._workspaceEnabled =
this.shouldHaveWorkspaces &&
!Services.prefs.getBoolPref('zen.testing.profiling.enabled', false);
}
return this._workspaceEnabled && !window.closed;
}
@ -741,7 +786,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
this.activeWorkspace = this._workspaceCache.workspaces[0]?.uuid;
}
// sort by position
this._workspaceCache.workspaces.sort((a, b) => (a.position ?? Infinity) - (b.position ?? Infinity));
this._workspaceCache.workspaces.sort(
(a, b) => (a.position ?? Infinity) - (b.position ?? Infinity)
);
return this._workspaceCache;
}
@ -811,7 +858,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
};
let removedEmptyTab = false;
if (this._initialTab && !(this._initialTab._shouldRemove && this._initialTab._veryPossiblyEmpty)) {
if (
this._initialTab &&
!(this._initialTab._shouldRemove && this._initialTab._veryPossiblyEmpty)
) {
gBrowser.selectedTab = this._initialTab;
this.moveTabToWorkspace(this._initialTab, this.activeWorkspace);
gBrowser.moveTabTo(this._initialTab, { forceUngrouped: true, tabIndex: 0 });
@ -820,7 +870,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
if (this._tabToRemoveForEmpty && !removedEmptyTab) {
const tabs = gBrowser.tabs.filter((tab) => !tab.collapsed && !tab.hasAttribute('zen-empty-tab'));
const tabs = gBrowser.tabs.filter(
(tab) => !tab.collapsed && !tab.hasAttribute('zen-empty-tab')
);
if (
typeof this._tabToSelect === 'number' &&
this._tabToSelect >= 0 &&
@ -866,6 +918,26 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (gZenVerticalTabsManager._canReplaceNewTab && showed) {
BrowserCommands.openTab();
}
if (
!gZenVerticalTabsManager._canReplaceNewTab &&
!Services.prefs.getBoolPref('zen.workspaces.continue-where-left-off')
) {
// Go through each tab and see if there's another tab with the same startup URL.
// If we do find one, remove it.
const newTabUrl = Services.prefs.getStringPref('browser.startup.homepage');
const tabs = gBrowser.tabs.filter(
(tab) => !tab.collapsed && !tab.hasAttribute('zen-empty-tab') && !tab.pinned
);
for (const tab of tabs) {
if (tab._originalUrl === newTabUrl && tab !== gBrowser.selectedTab) {
gBrowser.removeTab(tab, {
skipSessionStore: true,
});
}
}
}
window.dispatchEvent(new CustomEvent('AfterWorkspacesSessionRestore', { bubbles: true }));
}
@ -893,7 +965,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
shouldCloseWindow() {
return !window.toolbar.visible || Services.prefs.getBoolPref('browser.tabs.closeWindowWithLastTab');
return (
!window.toolbar.visible || Services.prefs.getBoolPref('browser.tabs.closeWindowWithLastTab')
);
}
async _clearAnyZombieTabs() {
@ -927,7 +1001,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
let tabs = gBrowser.visibleTabs;
let tabsPinned = tabs.filter((t) => !this.shouldOpenNewTabIfLastUnpinnedTabIsClosed || !t.pinned);
let tabsPinned = tabs.filter(
(t) => !this.shouldOpenNewTabIfLastUnpinnedTabIsClosed || !t.pinned
);
const shouldCloseWindow = this.shouldCloseWindow() && closeWindowWithLastTab;
if (tabs.length === 1 && tabs[0] === tab) {
if (shouldCloseWindow) {
@ -1172,15 +1248,21 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
async removeWorkspace(windowID) {
let workspacesData = await this._workspaces();
this._deleteAllTabsInWorkspace(windowID);
await this.changeWorkspace(workspacesData.workspaces.find((workspace) => workspace.uuid !== windowID));
await this.changeWorkspace(
workspacesData.workspaces.find((workspace) => workspace.uuid !== windowID)
);
delete this._lastSelectedWorkspaceTabs[windowID];
await ZenWorkspacesStorage.removeWorkspace(windowID);
// Remove the workspace from the cache
this._workspaceCache.workspaces = this._workspaceCache.workspaces.filter((workspace) => workspace.uuid !== windowID);
this._workspaceCache.workspaces = this._workspaceCache.workspaces.filter(
(workspace) => workspace.uuid !== windowID
);
await this._propagateWorkspaceData();
await this._updateWorkspacesChangeContextMenu();
this.onWindowResize();
for (let container of document.querySelectorAll(`.zen-workspace-tabs-section[zen-workspace-id="${windowID}"]`)) {
for (let container of document.querySelectorAll(
`.zen-workspace-tabs-section[zen-workspace-id="${windowID}"]`
)) {
container.remove();
}
this.registerPinnedResizeObserver();
@ -1192,7 +1274,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
async getActiveWorkspace() {
const workspaces = await this._workspaces();
return workspaces.workspaces.find((workspace) => workspace.uuid === this.activeWorkspace) ?? workspaces.workspaces[0];
return (
workspaces.workspaces.find((workspace) => workspace.uuid === this.activeWorkspace) ??
workspaces.workspaces[0]
);
}
// Workspaces dialog UI management
@ -1204,13 +1289,15 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
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
.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);
@ -1229,14 +1316,17 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
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);
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);
}
@ -1283,7 +1373,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
get shouldShowContainers() {
return (
Services.prefs.getBoolPref('privacy.userContext.ui.enabled') && ContextualIdentityService.getPublicIdentities().length > 0
Services.prefs.getBoolPref('privacy.userContext.ui.enabled') &&
ContextualIdentityService.getPublicIdentities().length > 0
);
}
@ -1420,19 +1511,21 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
`);
// use text content instead of innerHTML to avoid XSS
childs.querySelector('.zen-workspace-icon').textContent = browser.ZenWorkspaces.getWorkspaceIcon(workspace);
childs.querySelector('.zen-workspace-icon').textContent =
browser.ZenWorkspaces.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-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');
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.ZenWorkspaces)
@ -1562,7 +1655,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
isReorderModeOn(browser) {
return browser.document.getElementById('PanelUI-zen-workspaces-list').getAttribute('reorder-mode') === 'true';
return (
browser.document
.getElementById('PanelUI-zen-workspaces-list')
.getAttribute('reorder-mode') === 'true'
);
}
toggleReorderMode() {
@ -1605,7 +1702,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (!this.workspaceEnabled) {
return;
}
let target = event.target.closest('.zen-current-workspace-indicator') || document.getElementById('zen-workspaces-button');
let target =
event.target.closest('.zen-current-workspace-indicator') ||
document.getElementById('zen-workspaces-button');
let panel = document.getElementById('PanelUI-zen-workspaces');
await this._propagateWorkspaceData({
ignoreStrip: true,
@ -1692,7 +1791,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
event.stopPropagation();
this.openWorkspacesDialog(event);
};
button.addEventListener('contextmenu', this._workspaceButtonContextMenuListener.bind(browser.ZenWorkspaces));
button.addEventListener(
'contextmenu',
this._workspaceButtonContextMenuListener.bind(browser.ZenWorkspaces)
);
}
closeWorkspacesSubView() {
@ -1721,7 +1823,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
_deleteAllTabsInWorkspace(workspaceID) {
gBrowser.removeTabs(
Array.from(this.allStoredTabs).filter(
(tab) => tab.getAttribute('zen-workspace-id') === workspaceID && !tab.hasAttribute('zen-empty-tab')
(tab) =>
tab.getAttribute('zen-workspace-id') === workspaceID && !tab.hasAttribute('zen-empty-tab')
),
{
animate: false,
@ -1737,8 +1840,12 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
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}"]`);
const parent = tab.pinned
? '#vertical-pinned-tabs-container '
: '#tabbrowser-arrowscrollbox ';
const container = document.querySelector(
parent + `.zen-workspace-tabs-section[zen-workspace-id="${workspaceID}"]`
);
if (container?.contains(tab)) {
continue;
@ -1857,7 +1964,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
this._animateTabs(this.getActiveWorkspaceFromCache(), true);
}
async _performWorkspaceChange(workspace, { onInit = false, alwaysChange = false, whileScrolling = false } = {}) {
async _performWorkspaceChange(
workspace,
{ onInit = false, alwaysChange = false, whileScrolling = false } = {}
) {
const previousWorkspace = await this.getActiveWorkspace();
alwaysChange = alwaysChange || onInit;
this.activeWorkspace = workspace.uuid;
@ -1869,7 +1979,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
const workspaces = await this._workspaces();
// Refresh tab cache
gBrowser.verticalPinnedTabsContainer = this.pinnedTabsContainer || gBrowser.verticalPinnedTabsContainer;
gBrowser.verticalPinnedTabsContainer =
this.pinnedTabsContainer || gBrowser.verticalPinnedTabsContainer;
gBrowser.tabContainer.verticalPinnedTabsContainer =
this.pinnedTabsContainer || gBrowser.tabContainer.verticalPinnedTabsContainer;
// Move empty tab to the new workspace
@ -1886,8 +1997,13 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
gBrowser.warmupTab(tabToSelect);
// Update UI and state
const previousWorkspaceIndex = workspaces.workspaces.findIndex((w) => w.uuid === previousWorkspace.uuid);
await this._updateWorkspaceState(workspace, onInit, tabToSelect, { previousWorkspaceIndex, previousWorkspace });
const previousWorkspaceIndex = workspaces.workspaces.findIndex(
(w) => w.uuid === previousWorkspace.uuid
);
await this._updateWorkspaceState(workspace, onInit, tabToSelect, {
previousWorkspaceIndex,
previousWorkspace,
});
}
_moveEmptyTabToWorkspace(workspaceUuid) {
@ -1921,7 +2037,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
forAnimation = false,
animateContainer = false
) {
if (arrowscrollbox && !(this._inChangingWorkspace && !forAnimation && !this._alwaysAnimateMarginTop)) {
if (
arrowscrollbox &&
!(this._inChangingWorkspace && !forAnimation && !this._alwaysAnimateMarginTop)
) {
delete this._alwaysAnimateMarginTop;
const essentialsHeight = essentialContainer.getBoundingClientRect().height;
workspaceIndicator.style.marginTop = essentialsHeight + 'px';
@ -1963,12 +2082,17 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (!justMove) {
this._fixIndicatorsNames(workspaces);
}
const otherContainersEssentials = document.querySelectorAll(`#zen-essentials-wrapper .zen-workspace-tabs-section`);
const otherContainersEssentials = document.querySelectorAll(
`#zen-essentials-wrapper .zen-workspace-tabs-section`
);
const workspaceContextId = workspace.containerTabId;
const nextWorkspaceContextId = workspaces.workspaces[workspaceIndex + (offsetPixels > 0 ? -1 : 1)]?.containerTabId;
const nextWorkspaceContextId =
workspaces.workspaces[workspaceIndex + (offsetPixels > 0 ? -1 : 1)]?.containerTabId;
if (this.containerSpecificEssentials && justMove) {
const waitForContainers = [];
for (const element of document.querySelectorAll('.zen-workspace-tabs-section.zen-workspace-pinned-tabs-section')) {
for (const element of document.querySelectorAll(
'.zen-workspace-tabs-section.zen-workspace-pinned-tabs-section'
)) {
waitForContainers.push(this.updateTabsContainers(element, true));
}
await Promise.all(waitForContainers);
@ -1989,7 +2113,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
for (const container of otherContainersEssentials) {
// Get the next workspace contextId, if it's the same, dont apply offsetPixels
// if it's not we do apply it
if (container.getAttribute('container') != workspace.containerTabId && this.containerSpecificEssentials) {
if (
container.getAttribute('container') != workspace.containerTabId &&
this.containerSpecificEssentials
) {
container.setAttribute('hidden', 'true');
} else {
container.removeAttribute('hidden');
@ -2077,7 +2204,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
if (shouldAnimate && this.containerSpecificEssentials) {
const waitForContainers = [];
for (const element of document.querySelectorAll('.zen-workspace-tabs-section.zen-workspace-pinned-tabs-section')) {
for (const element of document.querySelectorAll(
'.zen-workspace-tabs-section.zen-workspace-pinned-tabs-section'
)) {
waitForContainers.push(this.updateTabsContainers(element, true));
}
await Promise.all(waitForContainers);
@ -2089,7 +2218,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
const existingTransform = element.style.transform;
const elementWorkspaceId = element.getAttribute('zen-workspace-id');
const elementWorkspaceIndex = workspaces.workspaces.findIndex((w) => w.uuid === elementWorkspaceId);
const elementWorkspaceIndex = workspaces.workspaces.findIndex(
(w) => w.uuid === elementWorkspaceId
);
const offset = -(newWorkspaceIndex - elementWorkspaceIndex) * 100;
const newTransform = `translateX(${offset}%)`;
if (shouldAnimate) {
@ -2143,7 +2274,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
// will slide in from the right
// Get the index from first and last workspace
const firstWorkspaceIndex = workspaces.workspaces.findIndex((w) => w.uuid === essentialsWorkspaces[0].uuid);
const firstWorkspaceIndex = workspaces.workspaces.findIndex(
(w) => w.uuid === essentialsWorkspaces[0].uuid
);
const lastWorkspaceIndex = workspaces.workspaces.findIndex(
(w) => w.uuid === essentialsWorkspaces[essentialsWorkspaces.length - 1].uuid
);
@ -2156,7 +2289,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
container.remove();
continue;
}
let stepsInBetween = Math.abs(newWorkspaceIndex - (isGoingLeft ? firstWorkspaceIndex : lastWorkspaceIndex)) + 1;
let stepsInBetween =
Math.abs(newWorkspaceIndex - (isGoingLeft ? firstWorkspaceIndex : lastWorkspaceIndex)) +
1;
const usingSameContainer =
newWorkspaceEssentialsContainer.workspaces.some((w) => w.uuid === newWorkspace.uuid) &&
newWorkspaceEssentialsContainer.workspaces.some((w) => w.uuid === previousWorkspace.uuid);
@ -2185,7 +2320,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
existingOffset = 0;
}
const needsOffsetAdjustment = stepsInBetween > essentialsWorkspaces.length || usingSameContainer;
const needsOffsetAdjustment =
stepsInBetween > essentialsWorkspaces.length || usingSameContainer;
if (repeats > 0 && needsOffsetAdjustment) {
if (!isGoingLeft) {
@ -2211,7 +2347,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (
!usingSameContainer &&
isGoingLeft &&
(firstWorkspaceIndex === newWorkspaceIndex - 1 || firstWorkspaceIndex === newWorkspaceIndex)
(firstWorkspaceIndex === newWorkspaceIndex - 1 ||
firstWorkspaceIndex === newWorkspaceIndex)
) {
existingOffset = -100;
newOffset = 0;
@ -2234,7 +2371,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
gZenUIManager.motion.animate(
container,
{
transform: [existingTransform, new Array(stepsInBetween).fill(newTransform).join(',')],
transform: [
existingTransform,
new Array(stepsInBetween).fill(newTransform).join(','),
],
},
{
type: 'spring',
@ -2267,12 +2407,20 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
_shouldChangeToTab(aTab) {
return !(aTab?.hasAttribute('zen-essential') || (aTab?.pinned && aTab?.hasAttribute('pending')));
return !(
aTab?.hasAttribute('zen-essential') ||
(aTab?.pinned && aTab?.hasAttribute('pending'))
);
}
async #shouldShowTabInCurrentWorkspace(tab) {
const currentWorkspace = this.getActiveWorkspaceFromCache();
return this._shouldShowTab(tab, currentWorkspace.uuid, currentWorkspace.containerTabId, await this._workspaces());
return this._shouldShowTab(
tab,
currentWorkspace.uuid,
currentWorkspace.containerTabId,
await this._workspaces()
);
}
_shouldShowTab(tab, workspaceUuid, containerId, workspaces) {
@ -2299,7 +2447,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
return (
!tabContextId ||
tabContextId === '0' ||
!workspaces.workspaces.some((workspace) => workspace.containerTabId === parseInt(tabContextId, 10))
!workspaces.workspaces.some(
(workspace) => workspace.containerTabId === parseInt(tabContextId, 10)
)
);
}
}
@ -2325,12 +2475,16 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
// Save current tab as last selected for old workspace if it shouldn't be visible in new workspace
if (oldWorkspaceId && oldWorkspaceId !== workspace.uuid) {
this._lastSelectedWorkspaceTabs[oldWorkspaceId] = gZenGlanceManager.getTabOrGlanceParent(currentSelectedTab);
this._lastSelectedWorkspaceTabs[oldWorkspaceId] =
gZenGlanceManager.getTabOrGlanceParent(currentSelectedTab);
}
let tabToSelect = null;
// Try last selected tab if it is visible
if (lastSelectedTab && this._shouldShowTab(lastSelectedTab, workspace.uuid, containerId, workspaces)) {
if (
lastSelectedTab &&
this._shouldShowTab(lastSelectedTab, workspace.uuid, containerId, workspaces)
) {
tabToSelect = lastSelectedTab;
}
// Find first suitable tab
@ -2362,7 +2516,12 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
return tabToSelect;
}
async _updateWorkspaceState(workspace, onInit, tabToSelect, { previousWorkspaceIndex, previousWorkspace } = {}) {
async _updateWorkspaceState(
workspace,
onInit,
tabToSelect,
{ previousWorkspaceIndex, previousWorkspace } = {}
) {
// Update document state
document.documentElement.setAttribute('zen-workspace-id', workspace.uuid);
@ -2476,7 +2635,12 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
return window;
}
async createAndSaveWorkspace(name = 'Space', icon = undefined, dontChange = false, containerTabId = 0) {
async createAndSaveWorkspace(
name = 'Space',
icon = undefined,
dontChange = false,
containerTabId = 0
) {
if (!this.workspaceEnabled) {
return;
}
@ -2488,7 +2652,13 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
!child.hasAttribute('zen-empty-tab') &&
!child.hasAttribute('zen-essential')
);
let workspaceData = this._createWorkspaceData(name, icon, extraTabs, !dontChange, containerTabId);
let workspaceData = this._createWorkspaceData(
name,
icon,
extraTabs,
!dontChange,
containerTabId
);
await this.saveWorkspace(workspaceData, dontChange);
if (!dontChange) {
this.registerPinnedResizeObserver();
@ -2509,7 +2679,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
// Only animate if it's from an event
const animateContainer = target && target instanceof EventTarget;
await this.onPinnedTabsResize([{ target: target ?? this.pinnedTabsContainer }], forAnimation, animateContainer);
await this.onPinnedTabsResize(
[{ target: target ?? this.pinnedTabsContainer }],
forAnimation,
animateContainer
);
}
updateShouldHideSeparator(arrowScrollbox, pinnedContainer) {
@ -2614,7 +2788,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
async onLocationChange(browser) {
gZenCompactModeManager.sidebar.toggleAttribute('zen-has-empty-tab', gBrowser.selectedTab.hasAttribute('zen-empty-tab'));
gZenCompactModeManager.sidebar.toggleAttribute(
'zen-has-empty-tab',
gBrowser.selectedTab.hasAttribute('zen-empty-tab')
);
if (!this.workspaceEnabled || this._inChangingWorkspace || this._isClosingWindow) {
return;
}
@ -2686,8 +2863,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
gBrowser.tabContainer._invalidateCachedTabs();
}
// Return the number of essentials INSIDE the pinned tabs container so we can correctly change their parent
return Array.from(this.pinnedTabsContainer.children).filter((child) => child.getAttribute('zen-essential') === 'true')
.length;
return Array.from(this.pinnedTabsContainer.children).filter(
(child) => child.getAttribute('zen-essential') === 'true'
).length;
}
// Context menu management
@ -2696,7 +2874,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
async updateContextMenu(_) {
console.assert(this._contextMenuId, 'No context menu ID set');
document
.querySelector(`#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`)
.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');
@ -2707,13 +2887,17 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
let openMenuItem = document.getElementById('context_zenOpenWorkspace');
if (
workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId && this.isWorkspaceActive(workspace))
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');
const openInContainerMenuItem = document.getElementById(
'context_zenWorkspacesOpenInContainerTab'
);
if (this.shouldShowContainers) {
openInContainerMenuItem.removeAttribute('hidden');
} else {
@ -2724,7 +2908,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
async contextChangeContainerTab(event) {
this._organizingWorkspaceStrip = true;
let workspaces = await this._workspaces();
let workspace = workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId);
let workspace = workspaces.workspaces.find(
(workspace) => workspace.uuid === this._contextMenuId
);
let userContextId = parseInt(event.target.getAttribute('data-usercontextid'));
workspace.containerTabId = userContextId + 0; // +0 to convert to number
await this.saveWorkspace(workspace);
@ -2756,7 +2942,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
async openWorkspace() {
let workspaces = await this._workspaces();
let workspace = workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId);
let workspace = workspaces.workspaces.find(
(workspace) => workspace.uuid === this._contextMenuId
);
await this.changeWorkspace(workspace);
}
@ -2777,7 +2965,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
return this._emojis;
}
const lazy = {};
Services.scriptloader.loadSubScript('chrome://browser/content/zen-components/ZenEmojies.mjs', lazy);
Services.scriptloader.loadSubScript(
'chrome://browser/content/zen-components/ZenEmojies.mjs',
lazy
);
this._emojis = lazy.zenGlobalEmojis();
return this._emojis;
}
@ -2821,7 +3012,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
async changeTabWorkspace(workspaceID) {
const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
const tabs = TabContextMenu.contextTab.multiselected
? gBrowser.selectedTabs
: [TabContextMenu.contextTab];
document.getElementById('tabContextMenu').hidePopup();
const previousWorkspaceID = document.documentElement.getAttribute('zen-workspace-id');
for (let tab of tabs) {
@ -2833,9 +3026,13 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
}
// Make sure we select the last tab in the new workspace
this._lastSelectedWorkspaceTabs[workspaceID] = gZenGlanceManager.getTabOrGlanceParent(tabs[tabs.length - 1]);
this._lastSelectedWorkspaceTabs[workspaceID] = gZenGlanceManager.getTabOrGlanceParent(
tabs[tabs.length - 1]
);
const workspaces = await this._workspaces();
await this.changeWorkspace(workspaces.workspaces.find((workspace) => workspace.uuid === workspaceID));
await this.changeWorkspace(
workspaces.workspaces.find((workspace) => workspace.uuid === workspaceID)
);
}
// Tab browser utilities
@ -2878,7 +3075,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
const activeWorkspace = this.getActiveWorkspaceFromCache();
const activeWorkspaceUserContextId = activeWorkspace?.containerTabId;
if (fromExternal !== true && typeof userContextId !== 'undefined' && userContextId !== activeWorkspaceUserContextId) {
if (
fromExternal !== true &&
typeof userContextId !== 'undefined' &&
userContextId !== activeWorkspaceUserContextId
) {
return [userContextId, false, undefined];
}
return [activeWorkspaceUserContextId, true, undefined];
@ -2890,7 +3091,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
return this.allStoredTabs.filter(
(tab) =>
tab.getAttribute('zen-workspace-id') !== tabWorkspaceId &&
!(this.containerSpecificEssentials && tab.getAttribute('container') !== aTab.getAttribute('container')) &&
!(
this.containerSpecificEssentials &&
tab.getAttribute('container') !== aTab.getAttribute('container')
) &&
!tab.hasAttribute('zen-empty-tab')
);
}
@ -2912,7 +3116,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
let isInActiveWorkspace = false;
let isInOtherWorkspace = false;
for (const [workspaceUuid, bookmarkGuids] of Object.entries(this._workspaceBookmarksCache.bookmarks)) {
for (const [workspaceUuid, bookmarkGuids] of Object.entries(
this._workspaceBookmarksCache.bookmarks
)) {
if (bookmarkGuids.includes(bookmarkGuid)) {
if (workspaceUuid === activeWorkspaceUuid) {
isInActiveWorkspace = true;
@ -2934,9 +3140,15 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
const tabs = [];
// we need to go through each tab in each container
const essentialsContainer = document.querySelectorAll('#zen-essentials-wrapper .zen-workspace-tabs-section');
let pinnedContainers = document.querySelectorAll('#vertical-pinned-tabs-container .zen-workspace-tabs-section');
let normalContainers = document.querySelectorAll('#tabbrowser-arrowscrollbox .zen-workspace-tabs-section');
const essentialsContainer = document.querySelectorAll(
'#zen-essentials-wrapper .zen-workspace-tabs-section'
);
let pinnedContainers = document.querySelectorAll(
'#vertical-pinned-tabs-container .zen-workspace-tabs-section'
);
let normalContainers = document.querySelectorAll(
'#tabbrowser-arrowscrollbox .zen-workspace-tabs-section'
);
if (!this._hasInitializedTabsStrip) {
pinnedContainers = [document.getElementById('vertical-pinned-tabs-container')];
normalContainers = [this.activeWorkspaceStrip];
@ -2973,8 +3185,12 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
let children = this.tabboxChildren;
return children.filter((node) => node.tagName == 'tab-group');
}
const pinnedContainers = document.querySelectorAll('#vertical-pinned-tabs-container .zen-workspace-tabs-section');
const normalContainers = document.querySelectorAll('#tabbrowser-arrowscrollbox .zen-workspace-tabs-section');
const pinnedContainers = document.querySelectorAll(
'#vertical-pinned-tabs-container .zen-workspace-tabs-section'
);
const normalContainers = document.querySelectorAll(
'#tabbrowser-arrowscrollbox .zen-workspace-tabs-section'
);
const containers = [...pinnedContainers, ...normalContainers];
const tabGroups = [];
for (const container of containers) {
@ -2999,7 +3215,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
get allWorkspaceTabs() {
const currentWorkspace = this.activeWorkspace;
return this.allStoredTabs.filter(
(tab) => tab.hasAttribute('zen-essential') || tab.getAttribute('zen-workspace-id') === currentWorkspace
(tab) =>
tab.hasAttribute('zen-essential') ||
tab.getAttribute('zen-workspace-id') === currentWorkspace
);
}
@ -3038,7 +3256,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
const currentWorkspace = this.getActiveWorkspaceFromCache();
// Check if we need to change workspace
if (
(tab.getAttribute('zen-workspace-id') !== this.activeWorkspace && !tab.hasAttribute('zen-essential')) ||
(tab.getAttribute('zen-workspace-id') !== this.activeWorkspace &&
!tab.hasAttribute('zen-essential')) ||
(currentWorkspace.containerTabId !== parseInt(tab.parentNode.getAttribute('container')) &&
this.containerSpecificEssentials)
) {

View file

@ -17,9 +17,11 @@ var ZenWorkspacesStorage = {
},
async _ensureTable() {
await this.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage._ensureTable', async (db) => {
// Create the main workspaces table if it doesn't exist
await db.execute(`
await this.lazy.PlacesUtils.withConnectionWrapper(
'ZenWorkspacesStorage._ensureTable',
async (db) => {
// Create the main workspaces table if it doesn't exist
await db.execute(`
CREATE TABLE IF NOT EXISTS zen_workspaces (
id INTEGER PRIMARY KEY,
uuid TEXT UNIQUE NOT NULL,
@ -32,55 +34,60 @@ var ZenWorkspacesStorage = {
)
`);
// Add new columns if they don't exist
// SQLite doesn't have a direct "ADD COLUMN IF NOT EXISTS" syntax,
// so we need to check if the columns exist first
const columns = await db.execute(`PRAGMA table_info(zen_workspaces)`);
const columnNames = columns.map((row) => row.getResultByName('name'));
// Add new columns if they don't exist
// SQLite doesn't have a direct "ADD COLUMN IF NOT EXISTS" syntax,
// so we need to check if the columns exist first
const columns = await db.execute(`PRAGMA table_info(zen_workspaces)`);
const columnNames = columns.map((row) => row.getResultByName('name'));
// Helper function to add column if it doesn't exist
const addColumnIfNotExists = async (columnName, definition) => {
if (!columnNames.includes(columnName)) {
await db.execute(`ALTER TABLE zen_workspaces ADD COLUMN ${columnName} ${definition}`);
}
};
// Helper function to add column if it doesn't exist
const addColumnIfNotExists = async (columnName, definition) => {
if (!columnNames.includes(columnName)) {
await db.execute(`ALTER TABLE zen_workspaces ADD COLUMN ${columnName} ${definition}`);
}
};
// Add each new column if it doesn't exist
await addColumnIfNotExists('theme_type', 'TEXT');
await addColumnIfNotExists('theme_colors', 'TEXT');
await addColumnIfNotExists('theme_opacity', 'REAL');
await addColumnIfNotExists('theme_rotation', 'INTEGER');
await addColumnIfNotExists('theme_texture', 'REAL');
// Add each new column if it doesn't exist
await addColumnIfNotExists('theme_type', 'TEXT');
await addColumnIfNotExists('theme_colors', 'TEXT');
await addColumnIfNotExists('theme_opacity', 'REAL');
await addColumnIfNotExists('theme_rotation', 'INTEGER');
await addColumnIfNotExists('theme_texture', 'REAL');
// Create an index on the uuid column
await db.execute(`
// Create an index on the uuid column
await db.execute(`
CREATE INDEX IF NOT EXISTS idx_zen_workspaces_uuid ON zen_workspaces(uuid)
`);
// Create the changes tracking table if it doesn't exist
await db.execute(`
// Create the changes tracking table if it doesn't exist
await db.execute(`
CREATE TABLE IF NOT EXISTS zen_workspaces_changes (
uuid TEXT PRIMARY KEY,
timestamp INTEGER NOT NULL
)
`);
// Create an index on the uuid column for changes tracking table
await db.execute(`
// Create an index on the uuid column for changes tracking table
await db.execute(`
CREATE INDEX IF NOT EXISTS idx_zen_workspaces_changes_uuid ON zen_workspaces_changes(uuid)
`);
if (!this.lazy.Weave.Service.engineManager.get('workspaces')) {
this.lazy.Weave.Service.engineManager.register(ZenWorkspacesEngine);
await ZenWorkspacesStorage.migrateWorkspacesFromJSON();
}
if (!this.lazy.Weave.Service.engineManager.get('workspaces')) {
this.lazy.Weave.Service.engineManager.register(ZenWorkspacesEngine);
await ZenWorkspacesStorage.migrateWorkspacesFromJSON();
}
ZenWorkspaces._resolveDBInitialized();
});
ZenWorkspaces._resolveDBInitialized();
}
);
},
async migrateWorkspacesFromJSON() {
const oldWorkspacesPath = PathUtils.join(PathUtils.profileDir, 'zen-workspaces', 'Workspaces.json');
const oldWorkspacesPath = PathUtils.join(
PathUtils.profileDir,
'zen-workspaces',
'Workspaces.json'
);
if (await IOUtils.exists(oldWorkspacesPath)) {
console.info('ZenWorkspacesStorage: Migrating workspaces from JSON...');
const oldWorkspaces = await IOUtils.readJSON(oldWorkspacesPath);
@ -110,23 +117,27 @@ var ZenWorkspacesStorage = {
async saveWorkspace(workspace, notifyObservers = true) {
const changedUUIDs = new Set();
await this.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.saveWorkspace', async (db) => {
await db.executeTransaction(async () => {
const now = Date.now();
await this.lazy.PlacesUtils.withConnectionWrapper(
'ZenWorkspacesStorage.saveWorkspace',
async (db) => {
await db.executeTransaction(async () => {
const now = Date.now();
let newPosition;
if ('position' in workspace && Number.isFinite(workspace.position)) {
newPosition = workspace.position;
} else {
// Get the maximum position
const maxPositionResult = await db.execute(`SELECT MAX("position") as max_position FROM zen_workspaces`);
const maxPosition = maxPositionResult[0].getResultByName('max_position') || 0;
newPosition = maxPosition + 1000; // Add a large increment to avoid frequent reordering
}
let newPosition;
if ('position' in workspace && Number.isFinite(workspace.position)) {
newPosition = workspace.position;
} else {
// Get the maximum position
const maxPositionResult = await db.execute(
`SELECT MAX("position") as max_position FROM zen_workspaces`
);
const maxPosition = maxPositionResult[0].getResultByName('max_position') || 0;
newPosition = maxPosition + 1000; // Add a large increment to avoid frequent reordering
}
// Insert or replace the workspace
await db.executeCached(
`
// Insert or replace the workspace
await db.executeCached(
`
INSERT OR REPLACE INTO zen_workspaces (
uuid, name, icon, container_id, created_at, updated_at, "position",
theme_type, theme_colors, theme_opacity, theme_rotation, theme_texture
@ -138,38 +149,39 @@ var ZenWorkspacesStorage = {
:theme_type, :theme_colors, :theme_opacity, :theme_rotation, :theme_texture
)
`,
{
uuid: workspace.uuid,
name: workspace.name,
icon: workspace.icon || null,
container_id: workspace.containerTabId || null,
now,
position: newPosition,
theme_type: workspace.theme?.type || null,
theme_colors: workspace.theme ? JSON.stringify(workspace.theme.gradientColors) : null,
theme_opacity: workspace.theme?.opacity || null,
theme_rotation: workspace.theme?.rotation || null,
theme_texture: workspace.theme?.texture || null,
}
);
{
uuid: workspace.uuid,
name: workspace.name,
icon: workspace.icon || null,
container_id: workspace.containerTabId || null,
now,
position: newPosition,
theme_type: workspace.theme?.type || null,
theme_colors: workspace.theme ? JSON.stringify(workspace.theme.gradientColors) : null,
theme_opacity: workspace.theme?.opacity || null,
theme_rotation: workspace.theme?.rotation || null,
theme_texture: workspace.theme?.texture || null,
}
);
// Record the change
await db.execute(
`
// Record the change
await db.execute(
`
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`,
{
uuid: workspace.uuid,
timestamp: Math.floor(now / 1000),
}
);
{
uuid: workspace.uuid,
timestamp: Math.floor(now / 1000),
}
);
changedUUIDs.add(workspace.uuid);
changedUUIDs.add(workspace.uuid);
await this.updateLastChangeTimestamp(db);
});
});
await this.updateLastChangeTimestamp(db);
});
}
);
if (notifyObservers) {
this._notifyWorkspacesChanged('zen-workspace-updated', Array.from(changedUUIDs));
@ -202,29 +214,32 @@ var ZenWorkspacesStorage = {
async removeWorkspace(uuid, notifyObservers = true) {
const changedUUIDs = [uuid];
await this.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.removeWorkspace', async (db) => {
await db.execute(
`
await this.lazy.PlacesUtils.withConnectionWrapper(
'ZenWorkspacesStorage.removeWorkspace',
async (db) => {
await db.execute(
`
DELETE FROM zen_workspaces WHERE uuid = :uuid
`,
{ uuid }
);
{ uuid }
);
// Record the removal as a change
const now = Date.now();
await db.execute(
`
// Record the removal as a change
const now = Date.now();
await db.execute(
`
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`,
{
uuid,
timestamp: Math.floor(now / 1000),
}
);
{
uuid,
timestamp: Math.floor(now / 1000),
}
);
await this.updateLastChangeTimestamp(db);
});
await this.updateLastChangeTimestamp(db);
}
);
if (notifyObservers) {
this._notifyWorkspacesChanged('zen-workspace-removed', changedUUIDs);
@ -232,27 +247,33 @@ var ZenWorkspacesStorage = {
},
async wipeAllWorkspaces() {
await this.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.wipeAllWorkspaces', async (db) => {
await db.execute(`DELETE FROM zen_workspaces`);
await db.execute(`DELETE FROM zen_workspaces_changes`);
await this.updateLastChangeTimestamp(db);
});
await this.lazy.PlacesUtils.withConnectionWrapper(
'ZenWorkspacesStorage.wipeAllWorkspaces',
async (db) => {
await db.execute(`DELETE FROM zen_workspaces`);
await db.execute(`DELETE FROM zen_workspaces_changes`);
await this.updateLastChangeTimestamp(db);
}
);
},
async markChanged(uuid) {
await this.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.markChanged', async (db) => {
const now = Date.now();
await db.execute(
`
await this.lazy.PlacesUtils.withConnectionWrapper(
'ZenWorkspacesStorage.markChanged',
async (db) => {
const now = Date.now();
await db.execute(
`
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`,
{
uuid,
timestamp: Math.floor(now / 1000),
}
);
});
{
uuid,
timestamp: Math.floor(now / 1000),
}
);
}
);
},
async saveWorkspaceTheme(uuid, theme, notifyObservers = true) {
@ -303,14 +324,19 @@ var ZenWorkspacesStorage = {
},
async clearChangedIDs() {
await this.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.clearChangedIDs', async (db) => {
await db.execute(`DELETE FROM zen_workspaces_changes`);
});
await this.lazy.PlacesUtils.withConnectionWrapper(
'ZenWorkspacesStorage.clearChangedIDs',
async (db) => {
await db.execute(`DELETE FROM zen_workspaces_changes`);
}
);
},
shouldReorderWorkspaces(before, current, after) {
const minGap = 1; // Minimum allowed gap between positions
return (before !== null && current - before < minGap) || (after !== null && after - current < minGap);
return (
(before !== null && current - before < minGap) || (after !== null && after - current < minGap)
);
},
async reorderAllWorkspaces(db, changedUUIDs) {
@ -356,41 +382,44 @@ var ZenWorkspacesStorage = {
async updateWorkspacePositions(workspaces) {
const changedUUIDs = new Set();
await this.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.updateWorkspacePositions', async (db) => {
await db.executeTransaction(async () => {
const now = Date.now();
await this.lazy.PlacesUtils.withConnectionWrapper(
'ZenWorkspacesStorage.updateWorkspacePositions',
async (db) => {
await db.executeTransaction(async () => {
const now = Date.now();
for (let i = 0; i < workspaces.length; i++) {
const workspace = workspaces[i];
const newPosition = (i + 1) * 1000;
for (let i = 0; i < workspaces.length; i++) {
const workspace = workspaces[i];
const newPosition = (i + 1) * 1000;
await db.execute(
`
await db.execute(
`
UPDATE zen_workspaces
SET "position" = :newPosition
WHERE uuid = :uuid
`,
{ newPosition, uuid: workspace.uuid }
);
{ newPosition, uuid: workspace.uuid }
);
changedUUIDs.add(workspace.uuid);
changedUUIDs.add(workspace.uuid);
// Record the change
await db.execute(
`
// Record the change
await db.execute(
`
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`,
{
uuid: workspace.uuid,
timestamp: Math.floor(now / 1000),
}
);
}
{
uuid: workspace.uuid,
timestamp: Math.floor(now / 1000),
}
);
}
await this.updateLastChangeTimestamp(db);
});
});
await this.updateLastChangeTimestamp(db);
});
}
);
this._notifyWorkspacesChanged('zen-workspace-updated', Array.from(changedUUIDs));
},
@ -403,9 +432,11 @@ var ZenWorkspaceBookmarksStorage = {
},
async _ensureTable() {
await ZenWorkspacesStorage.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspaceBookmarksStorage.init', async (db) => {
// Create table using GUIDs instead of IDs
await db.execute(`
await ZenWorkspacesStorage.lazy.PlacesUtils.withConnectionWrapper(
'ZenWorkspaceBookmarksStorage.init',
async (db) => {
// Create table using GUIDs instead of IDs
await db.execute(`
CREATE TABLE IF NOT EXISTS zen_bookmarks_workspaces (
id INTEGER PRIMARY KEY,
bookmark_guid TEXT NOT NULL,
@ -418,14 +449,14 @@ var ZenWorkspaceBookmarksStorage = {
)
`);
// Create index for fast lookups
await db.execute(`
// Create index for fast lookups
await db.execute(`
CREATE INDEX IF NOT EXISTS idx_bookmarks_workspaces_lookup
ON zen_bookmarks_workspaces(workspace_uuid, bookmark_guid)
`);
// Add changes tracking table
await db.execute(`
// Add changes tracking table
await db.execute(`
CREATE TABLE IF NOT EXISTS zen_bookmarks_workspaces_changes (
id INTEGER PRIMARY KEY,
bookmark_guid TEXT NOT NULL,
@ -438,12 +469,13 @@ var ZenWorkspaceBookmarksStorage = {
)
`);
// Create index for changes tracking
await db.execute(`
// Create index for changes tracking
await db.execute(`
CREATE INDEX IF NOT EXISTS idx_bookmarks_workspaces_changes
ON zen_bookmarks_workspaces_changes(bookmark_guid, workspace_uuid)
`);
});
}
);
},
/**

View file

@ -2,10 +2,14 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
var { Tracker, Store, SyncEngine } = ChromeUtils.importESModule('resource://services-sync/engines.sys.mjs');
var { Tracker, Store, SyncEngine } = ChromeUtils.importESModule(
'resource://services-sync/engines.sys.mjs'
);
var { CryptoWrapper } = ChromeUtils.importESModule('resource://services-sync/record.sys.mjs');
var { Utils } = ChromeUtils.importESModule('resource://services-sync/util.sys.mjs');
var { SCORE_INCREMENT_XLARGE } = ChromeUtils.importESModule('resource://services-sync/constants.sys.mjs');
var { SCORE_INCREMENT_XLARGE } = ChromeUtils.importESModule(
'resource://services-sync/constants.sys.mjs'
);
// Define ZenWorkspaceRecord
function ZenWorkspaceRecord(collection, id) {

View file

@ -202,7 +202,10 @@
margin-bottom: 20px;
background: var(--zen-toolbar-element-bg);
background-image: radial-gradient(light-dark(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.4)) 1px, transparent 0);
background-image: radial-gradient(
light-dark(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.4)) 1px,
transparent 0
);
background-position: -19px -19px;
background-size: 5px 5px;
@ -321,7 +324,11 @@
border: 1px solid color-mix(in srgb, var(--zen-colors-border) 50%, transparent 50%);
border-radius: 50%;
/* 3d effect */
background: linear-gradient(-45deg, transparent -10%, light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1)) 110%);
background: linear-gradient(
-45deg,
transparent -10%,
light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1)) 110%
);
z-index: 2;
top: 50%;
left: 50%;

View file

@ -460,7 +460,8 @@
}
.zen-current-workspace-indicator {
padding: calc(15px + var(--zen-toolbox-padding)) calc(4px + var(--tab-inline-padding) + var(--zen-toolbox-padding));
padding: calc(15px + var(--zen-toolbox-padding))
calc(4px + var(--tab-inline-padding) + var(--zen-toolbox-padding));
font-weight: 600;
position: absolute;
max-height: var(--zen-workspace-indicator-height);