Merge branch 'dev' into dev

Signed-off-by: mr. m  <91018726+mr-cheff@users.noreply.github.com>
This commit is contained in:
mr. m
2024-11-28 18:57:22 +01:00
committed by GitHub
73 changed files with 1837 additions and 442 deletions

12
.editorconfig Normal file
View File

@@ -0,0 +1,12 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

View File

@@ -1,4 +1,4 @@
blank_issues_enabled: false
blank_issues_enabled: false
contact_links:
- name: Feature Request
url: https://github.com/zen-browser/desktop/discussions

View File

@@ -153,7 +153,7 @@ jobs:
with:
commit_message: 🔖 Update version to ${{ steps.data.outputs.version }}
commit_user_name: Zen Browser Robot
commit_user_email: zen-browser-bot@users.noreply.github.com
commit_user_email: zen-browser-auto@users.noreply.github.com
check-release:
runs-on: ubuntu-latest
@@ -209,7 +209,7 @@ jobs:
contents: write
runs-on: ubuntu-latest
needs: [build-data, check-release]
steps:
- name: Checkout repository
uses: actions/checkout@v4
@@ -345,7 +345,7 @@ jobs:
run: |
npm install -g pnpm
sudo apt-get update
sudo apt-get -y install libfuse2 desktop-file-utils appstream
sudo apt-get -y install libfuse2 desktop-file-utils appstream
- name: Download Linux build
uses: actions/download-artifact@v4
@@ -437,7 +437,7 @@ jobs:
mkdir -p updates
cp -a ../linux_update_manifest_generic/. updates/
cp -a ../linux_update_manifest_specific/. updates/
cp -a ../linux_update_manifest_aarch64/. updates/
cp -a ../linux_update_manifest_aarch64/. updates/
if [[ $RELEASE_BRANCH == 'alpha' ]]; then
cp -a ../.github/workflows/object/windows-x64-signed-generic/update_manifest/. updates/
@@ -457,7 +457,7 @@ jobs:
with:
commit_message: 🚀 Update update manifests
commit_user_name: Zen Browser Robot
commit_user_email: zen-browser-bot@users.noreply.github.com
commit_user_email: zen-browser-auto@users.noreply.github.com
repository: ./updates-server
# If we are on Twilight, we want to just update the Twilight tag's release
@@ -566,7 +566,7 @@ jobs:
with:
commit_message: 🚀 Update releases for Flatpak
commit_user_name: Zen Browser Robot
commit_user_email: zen-browser-bot@users.noreply.github.com
commit_user_email: zen-browser-auto@users.noreply.github.com
- name: Checkout Flatpak repository
uses: actions/checkout@v4
@@ -589,7 +589,7 @@ jobs:
with:
commit_message: '[release]: Update Flatpak manifest'
commit_user_name: Zen Browser Robot
commit_user_email: zen-browser-bot@users.noreply.github.com
commit_user_email: zen-browser-auto@users.noreply.github.com
repository: ./flatpak
- name: Wait 4 minutes for the Flatpak repo to update
@@ -673,10 +673,10 @@ jobs:
git-token: ${{ secrets.DEPLOY_KEY }}
delete-branch: true
release-homebrew:
release-homebrew-alpha:
if: ${{ inputs.create_release && inputs.update_branch == 'alpha' }}
permissions: write-all
name: Homebrew release
name: Homebrew release for alpha build
needs: [release, mac, build-data]
runs-on: macos-latest
@@ -690,10 +690,35 @@ jobs:
- name: Setup Git
uses: Homebrew/actions/git-user-config@master
with:
username: zen-browser-bot
username: zen-browser-auto
- name: Bump zen-browser
- name: Bump cask
uses: Homebrew/actions/bump-packages@master
with:
token: ${{ secrets.DEPLOY_KEY }}
casks: zen-browser
release-homebrew-twilight:
if: ${{ inputs.create_release && inputs.update_branch == 'twilight' }}
permissions: write-all
name: Homebrew release for twilight build
needs: [release, mac, build-data]
runs-on: macos-latest
steps:
- name: Set up Homebrew
uses: Homebrew/actions/setup-homebrew@master
with:
cask: true
test-bot: false
- name: Setup git
uses: Homebrew/actions/git-user-config@master
with:
username: zen-browser-auto
- name: Bump cask
uses: Homebrew/actions/bump-packages@master
with:
token: ${{ secrets.DEPLOY_KEY }}
casks: zen-browser@twilight

View File

@@ -88,9 +88,10 @@ jobs:
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Install dependencies
run: pnpm install
run: |
pnpm install
- name: Load Surfer CI setup
- name: Load surfer CI setup
run: pnpm surfer ci --brand ${{ inputs.release-branch }} --display-version ${{ inputs.build-version }}
- name: Download Firefox source and dependencies

View File

@@ -28,4 +28,4 @@ jobs:
with:
commit_message: "[skip ci] 📦 Update submodules"
commit_user_name: Zen Browser Robot
commit_user_email: zen-browser-bot@users.noreply.github.com
commit_user_email: zen-browser-auto@users.noreply.github.com

View File

@@ -71,7 +71,7 @@ jobs:
- name: Download Firefox and dependencies
run: |
git config --global core.safecrlf false
git config --global core.safecrlf false
pnpm surfer download
- name: Import patches

View File

@@ -28,7 +28,7 @@ jobs:
fail-fast: false
matrix:
arch: [x86_64, x86_64-v3, aarch64]
steps:
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
@@ -213,7 +213,7 @@ jobs:
find engine/obj-x86_64-pc-windows-msvc/ -mindepth 1 -maxdepth 1 -type f -not -name 'dist' -exec rm -f {} \;
fi
- name: Upload artifact (dist object)
- name: Upload dist object
if: ${{ !inputs.generate-gpo }}
uses: actions/upload-artifact@v4
with:

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
20

1
.python-version Normal file
View File

@@ -0,0 +1 @@
3.11

View File

@@ -28,7 +28,7 @@
## 🖥️ Compatibility
Zen is currently built using firefox version `132.0.1`! 🚀
Zen is currently built using firefox version `133.0`! 🚀
- Check out the latest [release notes](https://zen-browser.app/release-notes)!
- Part of our mission is to keep Zen up-to-date with the latest version of Firefox, so you can enjoy the latest features and security updates!

View File

@@ -12,19 +12,22 @@ mkdir windsign-temp -ErrorAction SilentlyContinue
# Download in parallel
#show output too
Start-Job -Name "DownloadGitObjectsRepo" -ScriptBlock {
param($PWD)
echo "Downloading git objects repo to $PWD\windsign-temp\windows-binaries"
git clone https://github.com/zen-browser/windows-binaries.git $PWD\windsign-temp\windows-binaries
echo "Downloaded git objects repo to"
} -Verbose -ArgumentList $PWD -Debug
#Start-Job -Name "DownloadGitObjectsRepo" -ScriptBlock {
# param($PWD)
# echo "Downloading git objects repo to $PWD\windsign-temp\windows-binaries"
# git clone https://github.com/zen-browser/windows-binaries.git $PWD\windsign-temp\windows-binaries
# echo "Downloaded git objects repo to"
#} -Verbose -ArgumentList $PWD -Debug
gh run download $GithubRunId --name windows-x64-obj-arm64 -D windsign-temp\windows-x64-obj-arm64
echo "Downloaded arm64 artifacts"
gh run download $GithubRunId --name windows-x64-obj-specific -D windsign-temp\windows-x64-obj-specific
echo "Downloaded specific artifacts"
gh run download $GithubRunId --name windows-x64-obj-generic -D windsign-temp\windows-x64-obj-generic
echo "Downloaded generic artifacts"
Wait-Job -Name "DownloadGitObjectsRepo"
#Wait-Job -Name "DownloadGitObjectsRepo"
mkdir engine\obj-x86_64-pc-windows-msvc\ -ErrorAction SilentlyContinue
@@ -46,9 +49,13 @@ function SignAndPackage($name) {
$env:SURFER_SIGNING_MODE="sign"
$env:MAR="$PWD\\build\\winsign\\mar.exe"
if ($name -eq "generic") {
$env:SURFER_COMPAT="true"
$env:SURFER_COMPAT="x86_64"
} else {
rm env:SURFER_COMPAT -ErrorAction SilentlyContinue
if ($name -eq "arm64") {
$env:SURFER_COMPAT="aarch64"
} else {
$env:SURFER_COMPAT="x86_64-v3"
}
}
echo "Compat Mode? $env:SURFER_COMPAT"
@@ -67,21 +74,28 @@ function SignAndPackage($name) {
mkdir windsign-temp\windows-x64-signed-$name
# Move the MAR, add the `-generic` suffix if needed
if ($name -eq "generic") {
mv .\dist\output.mar windsign-temp\windows-x64-signed-$name\windows-generic.mar
echo "Moving MAR for $name"
if ($name -eq "generic" -or $name -eq "arm64") {
mv .\dist\output.mar windsign-temp\windows-x64-signed-$name\windows-$name.mar
} else {
mv .\dist\output.mar windsign-temp\windows-x64-signed-$name\windows.mar
}
# Move the installer
if ($name -eq "generic") {
mv .\dist\zen.installer.exe windsign-temp\windows-x64-signed-$name\zen.installer-generic.exe
echo "Moving installer for $name"
if ($name -eq "generic" -or $name -eq "arm64") {
mv .\dist\zen.installer.exe windsign-temp\windows-x64-signed-$name\zen.installer-$name.exe
} else {
mv .\dist\zen.installer.exe windsign-temp\windows-x64-signed-$name\zen.installer.exe
}
# Move the zip
mv (Get-Item .\dist\*.en-US.win64.zip) windsign-temp\windows-x64-signed-$name\zen.win-$name.zip
echo "Moving zip for $name"
if ($name -eq "arm64") {
mv (Get-Item .\dist\*.en-US.win64-aarch64.zip) windsign-temp\windows-x64-signed-$name\zen.win-arm64.zip
} else {
mv (Get-Item .\dist\*.en-US.win64.zip) windsign-temp\windows-x64-signed-$name\zen.win-$name.zip
}
# Extract the zip, sign everything inside, and repackage it
Expand-Archive -Path windsign-temp\windows-x64-signed-$name\zen.win-$name.zip -DestinationPath windsign-temp\windows-x64-signed-$name\zen.win-$name
@@ -103,6 +117,7 @@ function SignAndPackage($name) {
echo "Finished $name"
}
SignAndPackage arm64
SignAndPackage specific
SignAndPackage generic
@@ -121,7 +136,9 @@ echo "All the artifacts (Generic and Specific) are signed and packaged, get a re
Read-Host "Press Enter to continue"
echo "Cleaning up"
rmdir windsign-temp -Recurse -ErrorAction SilentlyContinue
rmdir windsign-temp\windows-x64-obj-specific -Recurse -ErrorAction SilentlyContinue
rmdir windsign-temp\windows-x64-obj-generic -Recurse -ErrorAction SilentlyContinue
rmdir windsign-temp\windows-x64-obj-arm64 -Recurse -ErrorAction SilentlyContinue
echo "Opening visual studio code"
code .

View File

@@ -35,7 +35,6 @@ if test "$ZEN_RELEASE"; then
ac_add_options --disable-debug-js-modules
ac_add_options --disable-tests
ac_add_options --disable-jprof
ac_add_options --disable-vtune
ac_add_options --enable-rust-simd

View File

@@ -6,9 +6,10 @@ ac_add_options --enable-eme=widevine
export MOZ_MACBUNDLE_ID=${appId}
export MOZ_MACBUNDLE_NAME="Zen Browser.app"
export MOZ_PGO=1
ac_add_options MOZ_PGO=1
if test "$SURFER_COMPAT" = "x86_64"; then
export MOZ_PGO=1
ac_add_options MOZ_PGO=1
ac_add_options --target=x86_64-apple-darwin
ac_add_options --enable-wasm-avx

View File

@@ -33,7 +33,7 @@
},
"homepage": "https://github.com/zen-browser/core#readme",
"dependencies": {
"@zen-browser/surfer": "^1.6.2"
"@zen-browser/surfer": "^1.6.4"
},
"devDependencies": {
"husky": "^9.1.5",

10
pnpm-lock.yaml generated
View File

@@ -9,8 +9,8 @@ importers:
.:
dependencies:
'@zen-browser/surfer':
specifier: ^1.6.2
version: 1.6.2
specifier: ^1.6.4
version: 1.6.4
devDependencies:
husky:
specifier: ^9.1.5
@@ -119,8 +119,8 @@ packages:
'@types/node@17.0.45':
resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
'@zen-browser/surfer@1.6.2':
resolution: {integrity: sha512-Go8RYGgHQLSffltLIhaYaKLDUW1Z7qyMUiC8SRTtSqmC7OPacdngX1uCYVMyaNpGkpV0xuZiAkToFYVMQY7Z7w==}
'@zen-browser/surfer@1.6.4':
resolution: {integrity: sha512-JmTHLHTbTLPgrakdU/m1KQgetPMQNGjYgGGVoi2AenvVDlJf3j+L2it0XehAqRFIQhXmbEuF1nSDV4Vla/vUUg==}
hasBin: true
ansi-escapes@7.0.0:
@@ -1003,7 +1003,7 @@ snapshots:
'@types/node@17.0.45': {}
'@zen-browser/surfer@1.6.2':
'@zen-browser/surfer@1.6.4':
dependencies:
'@resvg/resvg-js': 1.4.0
async-icns: 1.0.2

View File

@@ -76,7 +76,7 @@ pref('zen.welcomeScreen.seen', false);
pref('zen.tabs.vertical', true);
pref('zen.tabs.vertical.right-side', false);
pref('zen.theme.accent-color', "#aac7ff");
pref('zen.theme.accent-color', "#ffb787");
pref('zen.theme.content-element-separation', 6); // In pixels
pref('zen.theme.pill-button', false);
pref('zen.theme.gradient', true);
@@ -111,17 +111,15 @@ pref('zen.view.compact.color-sidebar', true);
pref('zen.glance.enabled', true);
pref('zen.glance.hold-duration', 300); // in ms
#ifdef XP_MACOSX
pref('zen.glance.activation-method', 'alt'); // ctrl, alt, shift, none, hold
#else
pref('zen.glance.activation-method', 'ctrl'); // ctrl, alt, shift, none, hold
#endif
pref('zen.view.sidebar-height-throttle', 200); // in ms
pref('zen.view.sidebar-expanded.max-width', 400);
pref('zen.view.show-bottom-border', false);
pref('zen.view.use-single-toolbar', false, locked);
pref('zen.view.use-single-toolbar', true);
pref('zen.view.sidebar-expanded', true);
pref('zen.view.sidebar-collapsed.hide-mute-button', true);
#ifndef XP_MACOSX
pref('zen.view.hide-window-controls', true);

View File

@@ -34,7 +34,7 @@ export var ZenCustomizableUI = new (class {
_addSidebarButtons(window) {
const sidebarBox = window.MozXULElement.parseXULToFragment(`
<toolbar id="zen-sidebar-top-buttons"
fullscreentoolbar="true"
fullscreentoolbar="true"
class="browser-toolbar customization-target zen-dont-hide-on-fullscreen"
brighttext="true"
data-l10n-id="tabs-toolbar"
@@ -45,6 +45,7 @@ export var ZenCustomizableUI = new (class {
customizationtarget="zen-sidebar-top-buttons-customization-target"
mode="icons">
<hbox id="zen-sidebar-top-buttons-customization-target" class="customization-target" flex="1">
<toolbarbutton removable="true" class="chromeclass-toolbar-additional toolbarbutton-1 zen-sidebar-action-button" id="zen-expand-sidebar-button" data-l10n-id="sidebar-zen-expand" cui-areatype="toolbar" oncommand="gZenVerticalTabsManager.toggleExpand();"></toolbarbutton>
<toolbarbutton removable="true" class="toolbarbutton-1 zen-sidebar-action-button zen-compact-mode-ignore" id="zen-sidepanel-button" data-l10n-id="sidebar-zen-sidepanel" onclick="gZenBrowserManagerSidebar.toggle();"></toolbarbutton>
</hbox>
</toolbar>

View File

@@ -12,7 +12,7 @@ var gZenUIManager = {
'zen.theme.content-element-separation',
0
);
function throttle(f, delay) {
let timer = 0;
return function (...args) {
@@ -126,6 +126,7 @@ var gZenVerticalTabsManager = {
Services.prefs.addObserver('zen.tabs.vertical.right-side', updateEvent);
Services.prefs.addObserver('zen.view.sidebar-expanded.max-width', updateEvent);
Services.prefs.addObserver('zen.view.use-single-toolbar', updateEvent);
Services.prefs.addObserver('zen.view.sidebar-expanded', updateEvent);
this._toolbarOriginalParent = document.getElementById('nav-bar').parentElement;
@@ -154,6 +155,11 @@ var gZenVerticalTabsManager = {
}
},
toggleExpand() {
const newVal = !Services.prefs.getBoolPref('zen.view.sidebar-expanded');
Services.prefs.setBoolPref('zen.view.sidebar-expanded', newVal);
},
get navigatorToolbox() {
if (this._navigatorToolbox) {
return this._navigatorToolbox;
@@ -202,15 +208,16 @@ var gZenVerticalTabsManager = {
const topButtons = document.getElementById('zen-sidebar-top-buttons');
const isCompactMode = Services.prefs.getBoolPref('zen.view.compact');
const isVerticalTabs = Services.prefs.getBoolPref('zen.tabs.vertical');
const isSidebarExpanded = Services.prefs.getBoolPref('zen.view.sidebar-expanded') || !isVerticalTabs;
const isRightSide = Services.prefs.getBoolPref('zen.tabs.vertical.right-side') && isVerticalTabs;
const isSingleToolbar = Services.prefs.getBoolPref('zen.view.use-single-toolbar') && isVerticalTabs;
const isSingleToolbar = Services.prefs.getBoolPref('zen.view.use-single-toolbar') && (isVerticalTabs && isSidebarExpanded) || !isVerticalTabs;
const titlebar = document.getElementById('titlebar');
gBrowser.tabContainer.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal');
gBrowser.tabContainer.arrowScrollbox.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal');
const buttonsTarget = document.getElementById('zen-sidebar-top-buttons-customization-target');
if (isRightSide && isVerticalTabs) {
if (isRightSide) {
this.navigatorToolbox.setAttribute('zen-right-side', 'true');
document.documentElement.setAttribute('zen-right-side', 'true');
} else {
@@ -218,8 +225,14 @@ var gZenVerticalTabsManager = {
document.documentElement.removeAttribute('zen-right-side');
}
if (isSidebarExpanded) {
this.navigatorToolbox.setAttribute('zen-sidebar-expanded', 'true');
} else {
this.navigatorToolbox.removeAttribute('zen-sidebar-expanded');
}
const appContentNavbarContaienr = document.getElementById('zen-appcontent-navbar-container');
if ((!isRightSide && this.isWindowsStyledButtons) || (isRightSide && !this.isWindowsStyledButtons)) {
if ((!isRightSide && this.isWindowsStyledButtons) || (isRightSide && !this.isWindowsStyledButtons) || isCompactMode) {
appContentNavbarContaienr.setAttribute('should-hide', 'true');
} else {
appContentNavbarContaienr.removeAttribute('should-hide');
@@ -237,9 +250,9 @@ var gZenVerticalTabsManager = {
// tabboxWrapper.prepend(this.navigatorToolbox);
}
if (!isVerticalTabs) {
document.getElementById("urlbar-container").after(document.getElementById('navigator-toolbox'));
}
//if (!isVerticalTabs) {
// document.getElementById("urlbar-container").after(document.getElementById('navigator-toolbox'));
//}
let windowButtons = this.actualWindowButtons;
let doNotChangeWindowButtons = !isCompactMode && isRightSide && this.isWindowsStyledButtons;
@@ -305,9 +318,9 @@ var gZenVerticalTabsManager = {
}
} else {
if (isRightSide) {
document.getElementById('zen-appcontent-navbar-container').prepend(windowButtons);
document.getElementById('zen-appcontent-navbar-container').appendChild(windowButtons);
} else {
navBar.prepend(windowButtons);
topButtons.prepend(windowButtons);
}
}
} else if (!isSingleToolbar && isCompactMode) {

View File

@@ -3,9 +3,9 @@ index 9df41bb3c82919839ee1408aa4d177ea7ee40a56..e37c64fa2c2ea39762be4285a1a70554
--- a/browser/base/content/browser-init.js
+++ b/browser/base/content/browser-init.js
@@ -152,13 +152,15 @@ var gBrowserInit = {
// tell CUI to ignore this element when it builds the toolbar areas
elem.setAttribute("skipintoolbarset", "true");
}
elem.setAttribute("skipintoolbarset", "true");
}
}
+ ZenCustomizableUI.init(window);
for (let area of CustomizableUI.areas) {
let type = CustomizableUI.getAreaType(area);
@@ -16,9 +16,9 @@ index 9df41bb3c82919839ee1408aa4d177ea7ee40a56..e37c64fa2c2ea39762be4285a1a70554
}
}
+ ZenCustomizableUI.registerToolbarNodes(window);
for (let elem of nonRemovables) {
elem.setAttribute("removable", "false");
elem.removeAttribute("skipintoolbarset");
if (isVerticalTabs) {
// Show the vertical tabs toolbar
setToolbarVisibility(
@@ -253,6 +255,10 @@ var gBrowserInit = {
gPrivateBrowsingUI.init();
BrowserSearch.init();

View File

@@ -1,5 +1,5 @@
diff --git a/browser/base/content/browser-sets.js b/browser/base/content/browser-sets.js
index 50da6424691ca230aa1a3a419cb69e66cf47b2c4..1f63f4bb7b75c940d5482dd4f13cebf452dddb74 100644
index 3031278749317d153624c6ccfbcc9d47aaf4089f..e67a8c3b56c01334627350c494b0139638ebf19a 100644
--- a/browser/base/content/browser-sets.js
+++ b/browser/base/content/browser-sets.js
@@ -245,7 +245,7 @@ document.addEventListener(
@@ -7,7 +7,7 @@ index 50da6424691ca230aa1a3a419cb69e66cf47b2c4..1f63f4bb7b75c940d5482dd4f13cebf4
});
- document.getElementById("mainKeyset").addEventListener("command", event => {
+ document.getElementById(ZEN_KEYSET_ID).addEventListener("command", event => {
+ document.getElementById("zenKeyset").addEventListener("command", event => {
switch (event.target.id) {
case "goHome":
BrowserCommands.home();

View File

@@ -1,5 +1,5 @@
diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml
index 12fa0cf79aade28581016adf96df85386dabdcef..85859842c85f5c131900ce49d69b117237ffc592 100644
index eb2d8670874bd5bcaf9253caafb98444cb8cfcd9..51e6c01c279e0105ec8ac08df0763027179c0616 100644
--- a/browser/base/content/navigator-toolbox.inc.xhtml
+++ b/browser/base/content/navigator-toolbox.inc.xhtml
@@ -2,7 +2,7 @@
@@ -8,59 +8,78 @@ index 12fa0cf79aade28581016adf96df85386dabdcef..85859842c85f5c131900ce49d69b1172
-<toolbox id="navigator-toolbox">
+<toolbox id="navigator-toolbox" persist="width style">
<script src="chrome://browser/content/navigator-toolbox.js" />
<vbox id="titlebar">
<!-- Menu -->
@@ -32,13 +32,14 @@
<!-- Menu -->
@@ -19,7 +19,7 @@
<spacer flex="1" skipintoolbarset="true" style="order: 1000;"/>
#include titlebar-items.inc.xhtml
</toolbar>
-
+<hbox id="titlebar">
<toolbar id="TabsToolbar"
class="browser-toolbar browser-titlebar"
fullscreentoolbar="true"
@@ -32,7 +32,7 @@
<hbox class="titlebar-spacer" type="pre-tabs"/>
<hbox class="titlebar-spacer" type="pre-tabs"/>
- <hbox flex="1" align="end" class="toolbar-items">
+ <hbox flex="1" align="start" class="toolbar-items">
<toolbartabstop/>
<hbox id="TabsToolbar-customization-target" flex="1">
<toolbarbutton id="firefox-view-button"
class="toolbarbutton-1 chromeclass-toolbar-additional"
data-l10n-id="toolbar-button-firefox-view-2"
role="button"
+ hidden="true"
aria-pressed="false"
oncommand="FirefoxViewHandler.openTab();"
onmousedown="FirefoxViewHandler.openToolbarMouseEvent(event);"
@@ -57,9 +58,14 @@
- <hbox flex="1" align="end" class="toolbar-items">
+ <hbox flex="1" align="start" class="toolbar-items">
<toolbartabstop/>
<hbox id="TabsToolbar-customization-target" flex="1">
<toolbarbutton id="firefox-view-button"
@@ -40,6 +40,7 @@
data-l10n-id="toolbar-button-firefox-view-2"
role="button"
aria-pressed="false"
+ hidden="true"
cui-areatype="toolbar"
removable="true"/>
@@ -55,9 +56,14 @@
# significantly, there is an optimization in
# DisplayPortUtils::MaybeCreateDisplayPortInFirstScrollFrameEncountered based
# the current structure that we may want to revisit.
+ <html:div id="zen-essentials-container"></html:div>
+ <hbox id="zen-current-workspace-indicator">
+ <hbox id="zen-current-workspace-indicator-icon"></hbox>
+ <hbox id="zen-current-workspace-indicator-name"></hbox>
+ </hbox>
<html:div id="vertical-pinned-tabs-container"></html:div>
<html:div id="vertical-pinned-tabs-container-separator"></html:div>
- <arrowscrollbox id="tabbrowser-arrowscrollbox" orient="horizontal" flex="1" clicktoscroll="" scrolledtostart="" scrolledtoend="">
+ <arrowscrollbox id="tabbrowser-arrowscrollbox" orient="vertical" flex="1" clicktoscroll="" scrolledtostart="" scrolledtoend="">
<tab is="tabbrowser-tab" class="tabbrowser-tab" selected="true" visuallyselected="" fadein=""/>
<hbox id="tabbrowser-arrowscrollbox-periphery">
<toolbartabstop/>
@@ -113,9 +119,10 @@
<toolbarbutton id="content-analysis-indicator"
oncommand="ContentAnalysis.showPanel(this, PanelUI);"
class="toolbarbutton-1 content-analysis-indicator-icon"/>
+ <html:div id="zen-essentials-container"></html:div>
+ <hbox id="zen-current-workspace-indicator">
+ <hbox id="zen-current-workspace-indicator-icon"></hbox>
+ <hbox id="zen-current-workspace-indicator-name"></hbox>
+ </hbox>
<html:div id="vertical-pinned-tabs-container" tabindex="-1"></html:div>
<html:div id="vertical-pinned-tabs-container-separator"></html:div>
- <arrowscrollbox id="tabbrowser-arrowscrollbox" orient="horizontal" flex="1" clicktoscroll="" scrolledtostart="" scrolledtoend="">
+ <arrowscrollbox id="tabbrowser-arrowscrollbox" orient="vertical" flex="1" clicktoscroll="" scrolledtostart="" scrolledtoend="">
<tab is="tabbrowser-tab" class="tabbrowser-tab" selected="true" visuallyselected="" fadein=""/>
<hbox id="tabbrowser-arrowscrollbox-periphery">
<toolbartabstop/>
@@ -100,11 +106,12 @@
#include private-browsing-indicator.inc.xhtml
<toolbarbutton id="content-analysis-indicator"
class="toolbarbutton-1 content-analysis-indicator-icon"/>
-
+ #if 0
+ #if 0
#include titlebar-items.inc.xhtml
-
+#endif
+#include zen-sidebar-icons.inc.xhtml
</toolbar>
</vbox>
@@ -531,6 +538,7 @@
</toolbar>
-
+</hbox>
<toolbar id="nav-bar"
class="browser-toolbar chromeclass-location"
data-l10n-id="navbar-accessible"
@@ -487,10 +494,12 @@
consumeanchor="PanelUI-button"
data-l10n-id="appmenu-menu-button-closed2"/>
</toolbaritem>
+#include titlebar-items.inc.xhtml
<hbox class="titlebar-spacer" type="post-tabs"/>
#include private-browsing-indicator.inc.xhtml
-
+#if 0
#include titlebar-items.inc.xhtml
+#endif
</toolbar>
<toolbar id="PersonalToolbar"

View File

@@ -0,0 +1,13 @@
diff --git a/browser/base/content/navigator-toolbox.js b/browser/base/content/navigator-toolbox.js
index 64ded8fb2c08f1dbfec8fe08ab427a24b53f1169..69009d53d7242c26f777ac2e0bb1897ff27ad916 100644
--- a/browser/base/content/navigator-toolbox.js
+++ b/browser/base/content/navigator-toolbox.js
@@ -8,7 +8,7 @@
document.addEventListener(
"DOMContentLoaded",
() => {
- const navigatorToolbox = document.getElementById("navigator-toolbox");
+ const navigatorToolbox = document.getElementById("browser");
const widgetOverflow = document.getElementById("widget-overflow");
function onPopupShowing(event) {

View File

@@ -35,7 +35,7 @@
role="document"
mainview-with-header="true"
has-custom-header="true">
<box id="zenSplitViewModifierHeader"
<box id="zenSplitViewModifierHeader"
class="panel-header panel-header-with-additional-element panel-header-with-info-button">
<html:h1>
<html:span data-l10n-id="zen-split-view-modifier-header"></html:span>
@@ -96,7 +96,7 @@
<toolbarbutton id="PanelUI-zen-profiles-privateWin" command="Tools:PrivateBrowsing" data-l10n-id="appmenuitem-new-private-window" class="subviewbutton"></toolbarbutton>
<toolbarbutton id="PanelUI-zen-profiles-newProfile" oncommand="ZenProfileDialogUI.createProfileWizard();" data-l10n-id="appmenu-create-profile" class="subviewbutton"></toolbarbutton>
</hbox>
<vbox id="PanelUI-zen-profiles-list">
<vbox id="PanelUI-zen-profiles-list">
</vbox>
</vbox>
</panelview>

View File

@@ -1,13 +1,13 @@
<toolbar brighttext="true"
id="zen-sidebar-icons-wrapper"
fullscreentoolbar="true"
<toolbar brighttext="true"
id="zen-sidebar-icons-wrapper"
fullscreentoolbar="true"
class="browser-toolbar customization-target zen-dont-hide-on-fullscreen"
data-l10n-id="tabs-toolbar"
customizable="true"
skipintoolbarset="true"
context="toolbar-context-menu"
mode="icons">
<toolbarbutton id="zen-profile-button"
<toolbarbutton id="zen-profile-button"
class="zen-sidebar-action-button toolbarbutton-1 chromeclass-toolbar-additional"
delegatesanchor="true"
onmousedown="ZenProfileDialogUI.showSubView(this, event)"

View File

@@ -22,7 +22,7 @@
</vbox>
<toolbar mode="icons" flex="1" id="zen-sidebar-panels-wrapper" fullscreentoolbar="true">
<toolbar mode="icons" flex="1" id="zen-sidebar-panels-sites" fullscreentoolbar="true">
</toolbar>
<toolbarbutton id="zen-sidebar-add-panel-button" class="zen-sidebar-panel-button toolbarbutton-1 chromeclass-toolbar-additional" onclick="gZenBrowserManagerSidebar._openAddPanelDialog();"/>
</toolbar>

View File

@@ -56,7 +56,18 @@
@keyframes zen-slide-in {
from {
transform: translateX(-30px);
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes zen-slide-in-reverse {
from {
transform: translateX(100%);
opacity: 0;
}
to {
@@ -228,9 +239,9 @@
height: 0%;
}
70% {
80% {
/* make the box grow to full width/height */
opacity: .5;
opacity: 1;
transform: translate(-50%, -50%) translateZ(0);
top: 50%;
left: 50%;
@@ -253,31 +264,22 @@
0% {
/* make the box shrink to final width/height and x/y coordinates */
transform: translate(-50%, -50%) translateZ(0);
opacity: 1;
width: 85%;
height: 100%;
top: 50%;
left: 50%;
}
50% {
/* make the box grow to full width/height */
opacity: 1;
transform: translate(-50%, -50%) translateZ(0);
top: 50%;
left: 50%;
width: 87%;
height: 102%;
}
100% {
/* make the box appear from initial width/height and x/y coordinates */
transform: translate(-50%, -50%) translateZ(0);
opacity: 0;
width: 47%;
height: 53%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) translateZ(0);
width: 0%;
height: 0%;
opacity: 0;
}
}
@@ -293,10 +295,10 @@
to {
width: 100%;
height: 100%;
top: 0;
left: 0;
top: 50%;
left: 50%;
opacity: 1;
transform: none;
transform: translate(-50%, -50%);
}
}
@@ -307,7 +309,7 @@
}
90% {
width: 100%;
width: 100%;
}
100% {

View File

@@ -4,11 +4,13 @@
border-radius: var(--zen-webview-border-radius, var(--zen-border-radius));
position: relative;
/* For glance */
transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out;
box-shadow: 0 0 1px 1px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.5));
border-radius: var(--zen-border-radius);
overflow: hidden;
margin: 1px;
:root[zen-right-side='true'] & {
margin-right: 0;
margin-left: var(--zen-element-separation);

View File

@@ -51,7 +51,7 @@
#zen-main-app-wrapper {
background: transparent;
overflow: hidden;
& > * {
z-index: 1;
}
@@ -75,16 +75,17 @@
#zen-appcontent-wrapper {
max-width: 100%;
overflow-x: hidden;
z-index: 1;
}
:root:not([inDOMFullscreen='true']):not([chromehidden~='location']):not([chromehidden~='toolbar']) {
& #zen-appcontent-wrapper {
& #zen-tabbox-wrapper {
margin: var(--zen-element-separation);
margin-left: 0;
margin-top: 0;
}
&[zen-right-side='true'] #zen-appcontent-wrapper {
&[zen-right-side='true'] #zen-tabbox-wrapper {
margin-right: 0;
}
}
@@ -100,6 +101,10 @@
& .titlebar-buttonbox {
align-items: center;
& .titlebar-button {
height: 100%;
}
}
}

View File

@@ -23,7 +23,7 @@
--zen-toolbox-max-width: 54px !important;
--zen-compact-float: calc(var(--zen-element-separation) - 1px);
position: absolute;
z-index: 9;
z-index: 10;
transition: transform 0.2s ease-in-out, opacity 0.2s ease-in-out;
right: calc(100% - var(--zen-element-separation));
top: 0;
@@ -121,8 +121,7 @@
& #zen-appcontent-navbar-container {
--zen-compact-toolbar-offset: 5px;
position: absolute;
top: 0;
transform: translateY(calc(-100% + var(--zen-element-separation) + 1px));
top: calc((-1 * var(--zen-toolbar-height)) + var(--zen-element-separation) + 1px);
left: 0;
z-index: 10;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.3) !important;
@@ -159,7 +158,7 @@
opacity: 1;
border-top-width: 1px;
transform: translateY(-1px);
top: -1px;
}
}
}

View File

@@ -27,7 +27,8 @@
#tabbrowser-tabpanels[zen-split-view='true'] > [zen-split='true'], #zen-splitview-dropzone {
flex: 1;
margin: calc(var(--zen-split-column-gap) / 2) calc(var(--zen-split-row-gap) / 2 + 1px);
margin: calc(var(--zen-split-column-gap) / 2) calc(var(--zen-split-row-gap) / 2 + 1px) !important;
margin-bottom: 0 !important;
position: absolute !important;
overflow: hidden;
}
@@ -48,9 +49,15 @@
outline-offset: -1px;
}
#tabbrowser-tabbox {
#tabbrowser-tabbox:has(#tabbrowser-tabpanels[zen-split-view='true']) {
--zen-split-row-gap: calc(var(--zen-element-separation) + 1px);
--zen-split-column-gap: calc(var(--zen-element-separation) + 1px);
margin-right: calc(-1 * var(--zen-split-column-gap));
:root[zen-right-side='true'] & {
margin-right: 0;
margin-left: calc(-1 * var(--zen-split-column-gap));
}
}
#tabbrowser-tabpanels:has(> [zen-split='true']), #zen-splitview-overlay {

View File

@@ -5,7 +5,6 @@
}
.zen-glance-background {
transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out;
transform: scale(0.98);
backdrop-filter: blur(5px);
opacity: 0.6;
@@ -28,11 +27,10 @@
& .browserContainer {
opacity: 1;
animation: zen-glance-content-animation-out .5s ease-in-out forwards !important;
animation: zen-glance-content-animation-out .3s ease-in-out forwards !important;
& browser {
opacity: 0;
transition: opacity .3s ease-in-out;
opacity: 1 !important;
}
& #zen-glance-sidebar-container {

View File

@@ -70,7 +70,7 @@
z-index: 1;
width: calc(100% - var(--zen-sidebar-web-panel-spacing) * 3);
margin: var(--zen-sidebar-web-panel-spacing);
/* Why times 3?
/* Why times 3?
* + 1 for the top margin, making the element overflow the view.
* + 1 for the margin we want to add at the bottom
* + 1 so that the panel can be correctly spaced from the border of the webview
@@ -80,7 +80,7 @@
#zen-sidebar-web-panel {
border-radius: var(--zen-panel-radius);
overflow: hidden;
z-index: 2;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
border: 1px solid var(--zen-colors-border);
background: var(--zen-colors-tertiary);
@@ -105,21 +105,47 @@
top: 0;
left: 0;
height: 100%;
width: 4px;
width: calc(var(--zen-element-separation) * 2 - 3px);
background: transparent;
border: none;
cursor: ew-resize;
&::before {
height: 30px;
width: 3px;
background: var(--zen-colors-border);
border-radius: 2px;
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0;
transition: opacity 0.1s ease-in-out;
pointer-events: none;
}
&:hover::before {
opacity: 1;
}
}
.zen-sidebar-web-panel-splitter[side='right'] {
left: initial;
right: 0;
left: 100%;
}
.zen-sidebar-web-panel-splitter[side='left'] {
right: 100%;
}
.zen-sidebar-web-panel-splitter[orient='horizontal'] {
width: 100%;
height: 7px;
cursor: ns-resize;
&::before {
display: none;
}
}
.zen-sidebar-web-panel-splitter[side='bottom'] {
@@ -251,8 +277,9 @@
}
:root:not([zen-right-side='true']) {
#zen-sidebar-web-panel-wrapper:not(:has(#zen-sidebar-web-panel[pinned='true'])) {
#zen-sidebar-web-panel-wrapper:not(:has(#zen-sidebar-web-panel:is([hidden='true'], [pinned='true']))) {
margin-left: 0 !important;
margin-right: calc(var(--zen-element-separation) * 2 - 3px) !important;
}
}

View File

@@ -1,6 +1,6 @@
/* Styles for both vertical and horizontal tabs */
@import url('chrome://browser/content/zen-styles/zen-tabs/horizontal-tabs.css');
@import url('chrome://browser/content/zen-styles/zen-tabs/vertical-tabs.css');
@import url('chrome://browser/content/zen-styles/zen-tabs/horizontal-tabs.css');
#zen-tabbox-wrapper {
position: relative;

View File

@@ -1,20 +1,332 @@
@media not (-moz-bool-pref: 'zen.tabs.vertical') {
#browser,
#navigator-toolbox {
flex-direction: row;
max-width: unset !important;
width: 100% !important;
:root #browser {
display: flex !important;
flex-direction: column !important;
}
#zen-sidebar-splitter {
display: none !important;
& #navigator-toolbox {
display: flex !important;
flex-direction: row !important;
max-width: unset !important;
min-width: unset !important;
width: 100% !important;
padding: var(--zen-toolbox-padding) !important;
}
#tabbrowser-tabs {
display: -webkit-box !important;
-webkit-box-orient: horizontal;
-webkit-box-pack: start;
max-width: 10000px !important;
}
#vertical-pinned-tabs-container-separator {
display: none !important;
}
#zen-essentials-container,
#vertical-pinned-tabs-container,
#tabbrowser-arrowscrollbox {
max-height: unset !important;
-webkit-box-flex: 1;
}
#vertical-pinned-tabs-container:empty {
-webkit-box-flex: 0 !important;
width: 0 !important;
padding: 0 !important;
margin: 0 !important;
border: none !important;
visibility: collapse !important;
}
#navigator-toolbox {
flex-direction: row !important;
}
#titlebar {
flex-direction: row !important;
width: 100%;
height: 40px !important;
}
#zen-essentials-container {
--tab-min-height: 36px !important;
display: flex !important;
flex-direction: row !important;
padding-inline-end: 0 !important;
}
#vertical-pinned-tabs-container {
display: flex !important;
flex-direction: row !important;
padding-inline-end: 0 !important;
}
#zen-essentials-container .tabbrowser-tab {
width: 0% !important;
}
#vertical-pinned-tabs-container .tabbrowser-tab {
width: 0% !important;
}
.tabbrowser-tab[zen-glance-tab="true"] {
.tab-content {
}
.tab-label-container {
display: none !important;
width: 0px !important;
max-width: 0px !important;
}
}
#tabbrowser-arrowscrollbox {
display: flex !important;
max-width: -moz-available;
overflow: hidden !important;
}
#TabsToolbar {
flex-direction: row !important;
gap: 8px;
overflow: hidden !important;
display: flex !important;
}
#TabsToolbar-customization-target {
flex-direction: row !important;
}
#tabbrowser-tabs[orient="vertical"] {
flex-direction: row !important;
}
tabs {
flex-direction: row !important;
}
#zen-essentials-container {
container-name: tab-container;
container-type: normal;
max-width: 36px !important;
flex: 1 1 36px !important;
}
#vertical-pinned-tabs-container {
container-name: tab-container;
container-type: normal;
max-width: 36px !important;
min-width: 36px !important;
flex: 1 1 36px !important;
}
#vertical-pinned-tabs-container .tab-close-button {
display: none !important;
}
#vertical-pinned-tabs-container .tab-label-container {
display: none !important;
}
#vertical-pinned-tabs-container .tab-icon-image {
margin: 0 !important;
}
.tabbrowser-tab {
container-name: tab-container;
container-type: normal;
max-width: 200px !important;
min-width: 36px !important;
flex: 1 1 150px !important;
}
.tabbrowser-tab[selected] {
flex: 2 1 150px !important;
min-width: 32px !important;
}
@container tab-container (max-width: 80px) {
.tab-close-button {
margin-right: 0px !important;
}
.tab-icon-image {
padding: 0 !important;
margin-left: min(2.5px, 5%) !important;
margin-right: min(10px, 5%) !important;
}
.tab-label-container,
.tab-content {
margin: 0 !important;
padding-left: min(8px, 5%) !important;
padding-right: min(8px, 5%) !important;
}
}
@container tab-container (max-width: 44px) {
.tab-label-container {
display: none !important;
}
.tab-content {
justify-content: space-around !important;
}
.tab-close-button {
display: none !important;
}
.tabbrowser-tab[selected] {
& .tab-icon-image,
.tab-icon-stack {
display: none !important;
}
& .tab-content {
justify-content: space-around !important;
padding: 0 !important;
}
.tab-close-button {
display: block !important;
}
}
}
#vertical-pinned-tabs-container::after {
z-index: -1;
content: "";
position: absolute;
right: 0;
width: 1px;
height: 45%;
top: 50%;
transform: translateY(-50%);
background: hsl(255, 10%, 100%);
}
slot {
flex-direction: row !important;
}
box.scrollbox-clip scrollbox slot {
display: flex !important;
width: 100% !important;
overflow: hidden !important;
}
.menupopup-arrowscrollbox > slot:nth-child(1) {
display: flex;
flex-direction: column !important;
}
/* Other UI Elements */
#zen-current-workspace-indicator {
display: none !important;
}
#zen-sidebar-splitter {
display: none !important;
}
#tabbrowser-tabpanels {
padding-left: var(--zen-element-separation) !important;
}
#appcontent * {
overflow: visible !important;
}
#TabsToolbar-customization-target::after {
display: none !important;
}
#zen-sidebar-icons-wrapper {
width: auto !important;
padding: 0 !important;
}
/* Height Adjustments */
#vertical-pinned-tabs-container,
#zen-essentials-container,
#tabbrowser-arrowscrollbox {
max-height: none !important;
}
#PanelUI-zen-gradient-generator {
min-width: 390px !important;
}
#zen-essentials-container:not(:empty),
#vertical-pinned-tabs-container:not(:empty),
#tabbrowser-arrowscrollbox {
-webkit-box-flex: 1;
min-width: min-content;
width: auto !important;
}
#vertical-pinned-tabs-container:not(:empty) {
display: -webkit-box !important;
-webkit-box-orient: horizontal;
min-width: fit-content !important;
width: fit-content !important;
position: relative;
margin-right: -1px !important;
}
#vertical-pinned-tabs-container:not(:empty) .tabbrowser-tab {
position: relative;
display: -webkit-box !important;
}
#tabbrowser-arrowscrollbox {
margin-left: 0 !important;
}
#vertical-pinned-tabs-container:empty,
#zen-essentials-container:empty {
-webkit-box-flex: 0 !important;
width: 0 !important;
min-width: 0 !important;
padding: 0 !important;
margin: 0 !important;
border: none !important;
visibility: collapse !important;
}
#tabbrowser-arrowscrollbox-periphery {
margin: 0 !important;
}
hbox#nav-bar-customization-target toolbarbutton.chromeclass-toolbar-additional:nth-of-type(1) {
padding-inline-start: var(--toolbar-start-end-padding) !important;
}
toolbar#PersonalToolbar {
padding-left: 6px !important;
}
.tab-context-line {
width: 100% !important;
height: 3px !important;
}
.tabbrowser-tab[zen-glance-tab="true"] {
flex-basis: fit-content !important;
max-width: 36px !important;
}
#zen-essentials-container .tabbrowser-tab[zen-glance-tab="true"] {
left: 2px;
}
#vertical-pinned-tabs-container .tabbrowser-tab[zen-glance-tab="true"] {
position: absolute !important;
}
#TabsToolbar-customization-target toolbarbutton,
#TabsToolbar-customization-target toolbarpaletteitem {
-webkit-box-flex: 0 !important;
min-width: min-content;
width: auto !important;
.toolbarbutton-text {
display: none !important;
}
}
}

View File

@@ -1,6 +1,6 @@
height: var(--zen-toolbar-height);
@media (-moz-bool-pref: 'zen.view.hide-window-controls') {
@media (-moz-bool-pref: 'zen.view.hide-window-controls') {
& {
transition: height 0.2s ease-out, opacity 0.2s ease-out;
transition-delay: 0.05s;

View File

@@ -1,4 +1,3 @@
@media (-moz-bool-pref: 'zen.tabs.vertical') {
#tabbrowser-tabs,
#TabsToolbar,
#titlebar,
@@ -12,8 +11,8 @@
& #zen-sidebar-top-buttons {
--zen-toolbar-height: 32px;
height: var(--zen-toolbar-height);
}
}
& #zen-sidebar-top-buttons .toolbarbutton-1 {
& > .toolbarbutton-icon {
padding: 5px;
@@ -28,7 +27,11 @@
:root:not([zen-window-buttons-reversed='true']) .titlebar-buttonbox-container {
margin-left: auto;
width: fit-content;
margin-right: var(--zen-element-separation);
}
:root[zen-window-buttons-reversed='true'] .titlebar-buttonbox-container {
margin-right: auto;
width: fit-content;
}
#TabsToolbar > * {
@@ -135,8 +138,8 @@
& #PersonalToolbar {
width: -moz-available;
}
/* We enable this trick IF we follow any of theses conditions:
/* We enable this trick IF we follow any of theses conditions:
* - We are on a Mac
* - We are on a Linux with reversed CSD
* - If we are not in any of the above, we can still enable it if the user has bookmarks toolbar enabled
@@ -212,7 +215,21 @@
}
& .tabbrowser-tab {
animation: zen-slide-in 0.2s ease-in-out;
animation: none;
transition: none;
&[fadein='true']:not([zen-essential='true']) {
#tabbrowser-tabs[zen-workspace-animation='previous'] & {
animation: zen-slide-in-reverse 0.2s ease-in-out;
}
#tabbrowser-tabs[zen-workspace-animation='next'] & {
animation: zen-slide-in 0.2s ease-in-out;
}
&[pinned] {
animation-delay: .03s !important;
}
}
max-width: unset;
padding: 0 !important;
@@ -252,8 +269,8 @@
}
& label { display: none !important; }
& .tab-close-button,
& .tab-reset-button {
display: none !important;
& .tab-reset-button {
display: none !important;
}
& .tab-icon-image {
@@ -295,6 +312,11 @@
&::part(scrollbox) {
gap: 0px !important;
}
&::part(overflow-start-indicator),
&::part(overflow-end-indicator) {
display: none !important;
}
}
#vertical-pinned-tabs-container {
@@ -318,12 +340,13 @@
}
/* Mark: toolbox as expanded */
#navigator-toolbox {
#navigator-toolbox[zen-sidebar-expanded='true'] {
--zen-toolbox-min-width: fit-content;
--tab-icon-end-margin: 8.5px;
padding: var(--zen-toolbox-padding);
padding-left: 0;
padding-top: 0;
z-index: 1;
& #titlebar {
min-width: 150px;
@@ -340,16 +363,13 @@
margin-left: var(--zen-toolbox-padding);
width: calc(100% - var(--zen-toolbox-padding));
& .urlbar-input-container {
padding-left: 2px;
padding-left: 4px;
padding-right: 4px;
}
:root[zen-right-side='true'] & {
margin-left: 0;
margin-right: var(--zen-toolbox-padding);
& .urlbar-input-container {
padding-right: 2px;
}
}
}
}
@@ -475,6 +495,7 @@
&:is(:hover, [visuallyselected]) .tab-close-button {
display: block;
--tab-inline-padding: 0; /* Avoid weird padding */
margin-inline-end: 0 !important;
}
.tab-throbber,
@@ -489,6 +510,146 @@
}
}
/* Mark: toolbox as collapsed */
#navigator-toolbox:not([zen-sidebar-expanded='true']) {
--tab-min-width: 36px !important;
/* Important: When changin this value, make sure expand on hover doesn't break! */
--zen-toolbox-padding: calc(var(--zen-element-separation) / 2 + 1px);
--zen-toolbox-max-width: calc(var(--tab-min-width) + var(--zen-toolbox-padding) * 2);
max-width: var(--zen-toolbox-max-width) !important;
min-width: var(--zen-toolbox-max-width) !important;
& #zen-current-workspace-indicator-name,
& .toolbarbutton-text {
display: none !important;
}
& #zen-current-workspace-indicator {
padding-left: 0;
padding-right: 0;
display: flex;
align-items: center;
justify-content: center;
opacity: .4;
}
& #zen-essentials-container {
justify-content: center;
}
& #vertical-tabs-newtab-button {
padding: 0 !important;
background: transparent !important;
}
:root[customizing] & #zen-sidebar-icons-wrapper {
min-width: unset !important;
}
& #zen-sidebar-icons-wrapper {
display: flex;
flex-direction: column;
padding-top: var(--zen-element-separation);
align-items: center;
}
:root:has(&) #zen-sidebar-splitter {
display: none !important;
}
& #tabbrowser-arrowscrollbox-periphery {
& > toolbarbutton {
margin: 0 auto !important;
padding: 0 !important;
}
&::before {
width: 90% !important;
}
}
& #EssentialsToolbar {
display: none !important;
}
& #essentials-accordion-header {
display: none !important;
}
& #vertical-pinned-tabs-container:has(tab:not([hidden])) {
position: relative;
& .tabbrowser-tab {
max-width: var(--tab-min-width);
}
}
& #TabsToolbar-customization-target {
padding-bottom: var(--zen-toolbox-padding);
&::after {
bottom: -1px !important;
}
}
& #tabbrowser-tabs {
margin-top: -2px;
& .tabbrowser-tab {
margin: 0 auto;
& .tab-background {
margin-inline: auto !important;
&:is([selected], [multiselected]) {
box-shadow: 0 0 1px 1px rgba(0,0,0,.1);
@media not (prefers-color-scheme: dark) {
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.12) !important;
}
}
}
& .tab-reset-button {
display: none !important;
}
& .tab-content {
display: flex;
align-content: center;
justify-content: center;
padding: 0 !important;
& .tab-label-container {
display: none !important;
}
& .tab-icon-image,
& .tab-icon-pending {
margin-inline-end: 0 !important;
}
/* Hide glances */
& .tabbrowser-tab {
display: none !important;
}
}
}
@media (-moz-bool-pref: 'zen.view.sidebar-collapsed.hide-mute-button') {
& .tab-icon-overlay:is([soundplaying], [muted]):not([selected]) {
display: none !important;
:is(
:root[uidensity='compact'],
#tabbrowser-tabs[secondarytext-unsupported],
:root:not([uidensity='compact']) #tabbrowser-tabs:not([secondarytext-unsupported]) .tabbrowser-tab:hover
)
.tab-icon-stack[indicator-replaces-favicon]
> :not(&),
:root:not([uidensity='compact'])
#tabbrowser-tabs:not([secondarytext-unsupported])
.tabbrowser-tab:not(:hover)
&[indicator-replaces-favicon] {
opacity: 1 !important;
}
}
}
& .tab-throbber,
& .tab-icon-pending,
& .tab-icon-image,
& .tab-sharing-icon-overlay,
& .tab-icon-overlay {
margin-inline-end: 0 !important;
}
}
& #zen-workspaces-button {
flex-direction: column;
&:not([as-button='true']) {
& toolbarbutton {
&[active='true']::after {
bottom: 50% !important;
transform: translateY(50%) !important;
}
}
}
}
}
/* Mark: Separator styling */
#zen-sidebar-splitter {
opacity: 0;
@@ -645,6 +806,10 @@
@media (-moz-bool-pref: 'zen.tabs.show-newtab-vertical') {
#tabs-newtab-button {
display: flex !important;
& .toolbarbutton-text {
align-items: center;
padding-top: 0;
}
}
#tabbrowser-arrowscrollbox-periphery {
@@ -675,7 +840,7 @@
}
}
}
}
/* Mark: Essentials Toolbar */
#zen-essentials-container {
@@ -703,8 +868,8 @@
border-radius: var(--border-radius-medium);
&:not([selected]) .tab-background {
background: light-dark(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1));
box-shadow: none;
background: light-dark(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.1));
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
}
backdrop-filter: blur(10px);

View File

@@ -1,4 +1,4 @@
/* Here, we contain all the theme related variables, for example theme
/* Here, we contain all the theme related variables, for example theme
* colors, border radius, etc.
* We have `--zen-border-radius` and `--zen-primary-color` as variables.
*/
@@ -12,7 +12,11 @@
/* Default values */
--zen-border-radius: 7px;
--zen-primary-color: #4a90e2;
--zen-primary-color: #ffb787;
--zen-branding-bg-dark: #202020;
--zen-branding-bg: light-dark(#F2F0E3, var(--zen-branding-bg-dark));
--zen-branding-bg-reverse: light-dark(var(--zen-branding-bg-dark), #F2F0E3);
/** Zen colors are generated automatically from the primary color */
--zen-colors-primary: color-mix(in srgb, var(--zen-primary-color) 50%, black 50%);
@@ -20,7 +24,7 @@
--zen-colors-tertiary: color-mix(in srgb, var(--zen-primary-color) 2%, white 98%);
--zen-colors-hover-bg: color-mix(in srgb, var(--zen-primary-color) 90%, white 10%);
--zen-colors-primary-foreground: color-mix(in srgb, var(--zen-primary-color) 80%, black 20%);
--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-input-bg: color-mix(in srgb, var(--zen-primary-color) 1%, var(--zen-colors-tertiary) 99%);
@@ -30,19 +34,10 @@
--zen-secondary-btn-color: var(--zen-colors-primary-foreground);
--in-content-primary-button-background: light-dark(
color-mix(in srgb, var(--zen-primary-color) 35%, black 65%),
color-mix(in srgb, var(--zen-primary-color) 85%, black 15%)
) !important;
--in-content-primary-button-background-hover: light-dark(
color-mix(in srgb, var(--zen-primary-color) 40%, black 60%),
color-mix(in srgb, var(--zen-primary-color) 40%, white 60%)
) !important;
--in-content-primary-button-background-active: light-dark(
color-mix(in srgb, var(--zen-primary-color) 50%, black 50%),
color-mix(in srgb, var(--zen-primary-color) 80%, rgba(255,255,255,.2) 20%)
) !important;
--in-content-primary-button-text-color: light-dark(white, black) !important;
--in-content-primary-button-background: color-mix(in srgb, var(--zen-primary-color) 10%, var(--zen-branding-bg-reverse) 90%) !important;
--in-content-primary-button-background-hover: color-mix(in srgb, var(--zen-primary-color) 5%, var(--zen-branding-bg-reverse) 60%) !important;
--in-content-primary-button-background-active: color-mix(in srgb, var(--zen-primary-color) 7%, var(--zen-branding-bg-reverse) 50%) !important;
--in-content-primary-button-text-color: var(--zen-colors-primary-foreground) !important;
--in-content-primary-button-border-color: transparent !important;
--in-content-primary-button-border-hover: transparent !important;
--in-content-primary-button-border-active: var(--zen-colors-border) !important;
@@ -51,18 +46,14 @@
--in-content-accent-color: var(--zen-colors-primary) !important;
/* This is like the secondary button */
--in-content-button-background: light-dark(
color-mix(in srgb, var(--zen-primary-color) 20%, transparent 80%),
color-mix(in srgb, var(--zen-primary-color) 10%, transparent 90%)
) !important;
--in-content-button-background-hover: light-dark(
color-mix(in srgb, var(--zen-primary-color) 10%, rgb(255, 255, 255) 90%),
color-mix(in srgb, var(--zen-primary-color) 15%, transparent 85%)
) !important;
--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, var(--zen-primary-color) 5%, var(--zen-branding-bg-reverse) 60%) !important;
--in-content-button-text-color-hover: var(--zen-branding-bg) !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;
--focus-outline-color: var(--button-bgcolor) !important;
--in-content-button-text-color: var(--zen-secondary-btn-color) !important;
--toolbarbutton-icon-fill-attention: var(--zen-primary-color) !important;
--toolbarbutton-icon-fill: light-dark(rgb(57, 57, 58), rgb(251, 251, 254)) !important;
@@ -74,6 +65,7 @@
--button-background-color: var(--in-content-button-background) !important;
--button-background-color-hover: var(--in-content-button-background-hover) !important;
--button-text-color-hover: var(--in-content-button-text-color-hover) !important;
--button-background-color-active: var(--in-content-primary-button-background-active) !important;
--color-accent-primary: var(--button-primary-bgcolor) !important;
@@ -91,16 +83,18 @@
--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%);
/* Other colors */
--urlbar-box-bgcolor: var(--zen-urlbar-background) !important;
--urlbar-box-active-bgcolor: var(--toolbarbutton-hover-background) !important;
--toolbar-field-focus-background-color: var(--urlbar-box-bgcolor) !important;
--zen-input-border-color: light-dark(rgb(204, 204, 204), rgb(66, 65, 77));
--urlbar-box-hover-bgcolor: var(--toolbarbutton-hover-background) !important;
/* XUL */
--zen-main-browser-background: light-dark(rgb(235, 235, 235), #1b1b1b);
--zen-main-browser-background-toolbar: var(--zen-main-browser-background);
--zen-browser-gradient-base: color-mix(in srgb, var(--zen-primary-color) 50%, white 50%);
--zen-appcontent-border: 1px solid var(--zen-colors-border);
--zen-panel-radius: var(--zen-border-radius);
@@ -127,8 +121,8 @@
--input-bgcolor: var(--zen-colors-tertiary) !important;
--input-border-color: var(--zen-input-border-color) !important;
--zen-themed-toolbar-bg: light-dark(#f7f7f7, var(--zen-colors-tertiary));
--zen-themed-toolbar-bg-transparent: light-dark(#f7f7f7, var(--zen-colors-tertiary));
--zen-themed-toolbar-bg: light-dark(var(--zen-branding-bg), var(--zen-colors-tertiary));
--zen-themed-toolbar-bg-transparent: light-dark(var(--zen-branding-bg), var(--zen-colors-tertiary));
@supports (-moz-osx-font-smoothing: auto) {
--zen-themed-toolbar-bg-transparency: 0.05;
@@ -142,8 +136,8 @@
@media (prefers-color-scheme: dark) {
:host(:is(.anonymous-content-host, notification-message)),
:root {
--zen-in-content-dialog-background: rgb(23, 23, 23);
--zen-dark-color-mix-base: rgb(21, 21, 21);
--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%);

View File

@@ -28,6 +28,7 @@
#urlbar-background {
background: var(--zen-dialog-background);
outline: none !important;
}
#urlbar[focused='true'] > #urlbar-background {
@@ -42,7 +43,7 @@
#urlbar-background {
border: transparent !important;
margin: 1px;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1) !important;
}
#urlbar[focused='true']:not([suppress-focus-border]) > #urlbar-background,
@@ -52,7 +53,7 @@
outline-color: none !important;
}
#identity-box.chromeUI:not([pageproxystate="invalid"]) {
#identity-box.chromeUI:not([pageproxystate="invalid"]) {
& #identity-icon-box {
background: light-dark(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1)) !important;
}
@@ -64,7 +65,7 @@
#identity-permission-box:not(:hover):not(:focus-within) {
background: transparent !important;
}
}
#urlbar:is([focused], [open]) > #urlbar-background,
#searchbar:focus-within {
@@ -101,8 +102,8 @@
.urlbar-page-action,
#tracking-protection-icon-container {
width: calc(var(--urlbar-min-height) - 4 * var(--urlbar-container-padding)) !important;
height: calc(var(--urlbar-min-height) - 4 * var(--urlbar-container-padding)) !important;
width: calc(var(--urlbar-min-height) - 6 * var(--urlbar-container-padding)) !important;
height: calc(var(--urlbar-min-height) - 6 * var(--urlbar-container-padding)) !important;
margin-top: auto !important;
margin-bottom: auto !important;
}
@@ -125,6 +126,11 @@
}
:root[zen-single-toolbar='true'] {
#urlbar[breakout-extend='true'] {
top: 0px !important;
width: calc(var(--urlbar-width) + 2 * var(--urlbar-margin-inline) * 4);
}
#notification-popup-box {
align-items: center;
justify-content: center;
@@ -160,7 +166,7 @@
padding: 0;
margin-top: auto;
margin-bottom: auto;
}
}
}
}
@@ -278,6 +284,10 @@ button.popup-notification-dropmarker {
align-items: center;
}
:root:not([zen-single-toolbar='true']) #nav-bar {
margin-bottom: -1px;
}
/* Other small tweaks */
#nav-bar-customization-target {
/* Don't grow if potentially-user-sized elements (like the searchbar or the

View File

@@ -60,7 +60,7 @@
filter: grayscale(1);
transition: opacity 0.2s;
}
&[active='true'] {
filter: none;
opacity: 1;
@@ -401,7 +401,7 @@
font-weight: 600;
align-items: center;
position: relative;
& #zen-current-workspace-indicator-icon {
font-size: 14px;
}

View File

@@ -192,7 +192,7 @@
this.lastCurrentTab.removeAttribute("zen-glance-tab");
this.lastCurrentTab._closingGlance = true;
gBrowser.tabContainer._invalidateCachedTabs();
gBrowser.removeTab(this.lastCurrentTab, { animate: true });
@@ -200,10 +200,10 @@
this.#currentBrowser = null;
this.lastCurrentTab = null;
this._duringOpening = false;
this._duringOpening = false;
}, 400);
});
});
});
}
quickOpenGlance() {
@@ -231,7 +231,7 @@
quickCloseGlance({ closeCurrentTab = true, closeParentTab = true, justAnimateParent = false } = {}) {
const parentHasBrowser = !!(this.currentParentTab.linkedBrowser);
if (!justAnimateParent) {
if (!justAnimateParent) {
if (parentHasBrowser) {
if (closeParentTab) {
this.currentParentTab.linkedBrowser.closest(".browserSidebarContainer").classList.remove("deck-selected");
@@ -277,7 +277,7 @@
}
}
fullyOpenGlance() {
fullyOpenGlance() {
gBrowser._insertTabAtIndex(this.#currentTab, {
index: this.#currentTab._tPos + 1,
});

View File

@@ -19,7 +19,7 @@
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'));
ChromeUtils.defineLazyGetter(this, 'customColorList', () => document.getElementById('PanelUI-zen-gradient-generator-custom-list'));
ChromeUtils.defineLazyGetter(this, 'customColorList', () => document.getElementById('PanelUI-zen-gradient-generator-custom-list'));
XPCOMUtils.defineLazyPreferenceGetter(
this,
@@ -74,7 +74,7 @@
this.image.onload = this.onImageLoad.bind(this);
}
onImageLoad() {
// resize the image to fit the panel
const imageSize = 300 - 20; // 20 is the padding (10px)
@@ -164,11 +164,11 @@
this.rotationInputDot.style.transform = `rotate(${degrees - 20}deg)`;
this.rotationInputText.textContent = `${fixedRotation}°`;
}
initCustomColorInput() {
this.customColorInput.addEventListener('keydown', this.onCustomColorKeydown.bind(this));
}
onCustomColorKeydown(event) {
//checks for enter key for custom colors
if (event.key === 'Enter') {
@@ -246,19 +246,19 @@
onThemePickerClick(event) {
event.preventDefault();
if (event.button !== 0 || this.dragging ) return;
const gradient = this.panel.querySelector('.zen-theme-picker-gradient');
const rect = gradient.getBoundingClientRect();
const padding = 90; // each side
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
const radius = (rect.width - padding) / 2;
let pixelX = event.clientX;
let pixelY = event.clientY;
// Check if the click is within the circle
const distance = Math.sqrt((pixelX - centerX) ** 2 + (pixelY - centerY) ** 2);
if (distance > radius) {
@@ -268,33 +268,33 @@
// Check if we clicked on an existing dot
const clickedElement = event.target;
const isExistingDot = clickedElement.classList.contains('zen-theme-picker-dot');
// Only proceed if not clicking on an existing dot
if (!isExistingDot) {
const relativeX = event.clientX - rect.left;
const relativeY = event.clientY - rect.top;
const color = this.getColorFromPosition(relativeX, relativeY);
// Create new dot
const dot = document.createElement('div');
dot.classList.add('zen-theme-picker-dot');
dot.addEventListener('mousedown', this.onDotMouseDown.bind(this));
dot.style.left = `${relativeX}px`;
dot.style.top = `${relativeY}px`;
dot.style.setProperty('--zen-theme-picker-dot-color', `rgb(${color[0]}, ${color[1]}, ${color[2]})`);
gradient.appendChild(dot);
this.updateCurrentWorkspace(true);
}
}
onDotMouseDown(event) {
event.preventDefault();
@@ -305,7 +305,7 @@
this.draggedDot = event.target;
this.draggedDot.style.zIndex = 1;
this.draggedDot.classList.add('dragging');
// Store the starting position of the drag
this.dragStartPosition = {
x: event.clientX,
@@ -320,9 +320,9 @@
const rect = this.panel.querySelector('.zen-theme-picker-gradient').getBoundingClientRect();
const padding = 90; // each side
// do NOT let the ball be draged outside of an imaginary circle. You can drag it anywhere inside the circle
// if the distance between the center of the circle and the dragged ball is bigger than the radius, then the ball
// if the distance between the center of the circle and the dragged ball is bigger than the radius, then the ball
// should be placed on the edge of the circle. If it's inside the circle, then the ball just follows the mouse
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
const radius = (rect.width - padding) / 2;
@@ -358,18 +358,18 @@
listItems.querySelector('.zen-theme-picker-dot-custom').style.setProperty('--zen-theme-picker-dot-color', color);
listItems.querySelector('.zen-theme-picker-custom-list-item-label').textContent = color;
this.customColorList.appendChild(listItems);
}
async addCustomColor() {
const color = this.customColorInput.value;
if (!color) {
return;
}
// can be any color format, we just add it to the list as a dot, but hidden
const dot = document.createElement('div');
@@ -385,46 +385,46 @@
onThemePickerClick(event) {
event.preventDefault();
if (event.button !== 0 || this.dragging) return;
const gradient = this.panel.querySelector('.zen-theme-picker-gradient');
const rect = gradient.getBoundingClientRect();
const padding = 90; // each side
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
const radius = (rect.width - padding) / 2;
let pixelX = event.clientX;
let pixelY = event.clientY;
// Check if the click is within the circle
const distance = Math.sqrt((pixelX - centerX) ** 2 + (pixelY - centerY) ** 2);
if (distance > radius) {
return;
return;
}
const clickedElement = event.target;
const isExistingDot = clickedElement.classList.contains('zen-theme-picker-dot');
if (!isExistingDot && this.numberOfDots < ZenThemePicker.MAX_DOTS) {
const relativeX = event.clientX - rect.left;
const relativeY = event.clientY - rect.top;
const color = this.getColorFromPosition(relativeX, relativeY);
const dot = document.createElement('div');
dot.classList.add('zen-theme-picker-dot');
dot.addEventListener('mousedown', this.onDotMouseDown.bind(this));
dot.style.left = `${relativeX}px`;
dot.style.top = `${relativeY}px`;
dot.style.setProperty('--zen-theme-picker-dot-color', `rgb(${color[0]}, ${color[1]}, ${color[2]})`);
gradient.appendChild(dot);
this.updateCurrentWorkspace(true);
}
}
@@ -438,7 +438,7 @@
this.draggedDot = event.target;
this.draggedDot.style.zIndex = 1;
this.draggedDot.classList.add('dragging');
// Store the starting position of the drag
this.dragStartPosition = {
x: event.clientX,
@@ -459,7 +459,7 @@
if (this.dragging) {
event.preventDefault();
event.stopPropagation();
event.stopPropagation();
this.dragging = false;
this.draggedDot.style.zIndex = 1;
this.draggedDot.classList.remove('dragging');
@@ -586,13 +586,13 @@
}
}
const result = this.pSBC(
this.isDarkMode ? 0.2 : -0.5,
this.isDarkMode ? 0.2 : -0.5,
`rgb(${dominantColor[0]}, ${dominantColor[1]}, ${dominantColor[2]})`);
return result?.match(/\d+/g).map(Number);
}
async onWorkspaceChange(workspace, skipUpdate = false, theme = null) {
const uuid = workspace.uuid;
// Use theme from workspace object or passed theme
let workspaceTheme = theme || workspace.theme;
@@ -615,7 +615,7 @@
dot.remove();
}
}
const appWrapper = browser.document.getElementById('zen-main-app-wrapper');
if (!skipUpdate) {
@@ -655,7 +655,7 @@
const gradient = browser.gZenThemePicker.getGradient(workspaceTheme.gradientColors);
const gradientToolbar = browser.gZenThemePicker.getGradient(workspaceTheme.gradientColors, true);
browser.gZenThemePicker.updateNoise(workspaceTheme.texture);
for (const dot of workspaceTheme.gradientColors) {
if (dot.isCustom) {
browser.gZenThemePicker.addColorToCustomList(dot.c);

View File

@@ -651,17 +651,6 @@ function zenGetDefaultShortcuts() {
'zen-web-panel-shortcut-toggle'
)
);
newShortcutList.push(
new KeyShortcut(
'zen-toggle-sidebar',
'B',
'',
ZEN_OTHER_SHORTCUTS_GROUP,
KeyShortcutModifiers.fromObject({ alt: true }),
'code:gZenVerticalTabsManager.toggleExpand()',
'zen-sidebar-shortcut-toggle'
)
);
// Split view
newShortcutList.push(
@@ -713,7 +702,7 @@ function zenGetDefaultShortcuts() {
}
class ZenKeyboardShortcutsVersioner {
static LATEST_KBS_VERSION = 3;
static LATEST_KBS_VERSION = 4;
constructor() {}
@@ -812,6 +801,12 @@ class ZenKeyboardShortcutsVersioner {
}
}
}
if (version < 4) {
// Migrate from 3 to 4
// In this new version, we are just removing the 'zen-toggle-sidebar' shortcut
// since it's not used anymore.
data = data.filter((shortcut) => shortcut.getID() != 'zen-toggle-sidebar');
}
return data;
}
}
@@ -879,7 +874,7 @@ var gZenKeyboardShortcutsManager = {
browser.gZenKeyboardShortcutsManager._zenKeyset = browser.document.createXULElement('keyset');
browser.gZenKeyboardShortcutsManager._zenKeyset.id = ZEN_KEYSET_ID;
const mainKeyset = browser.document.getElementById(ZEN_MAIN_KEYSET_ID);
mainKeyset.after(browser.gZenKeyboardShortcutsManager._zenKeyset);
}

View File

@@ -149,8 +149,8 @@ var ZenPinnedTabsStorage = {
async getGroupChildren(groupUuid) {
const db = await PlacesUtils.promiseDBConnection();
const rows = await db.executeCached(`
SELECT * FROM zen_pins
WHERE parent_uuid = :groupUuid
SELECT * FROM zen_pins
WHERE parent_uuid = :groupUuid
ORDER BY position ASC
`, { groupUuid });

View File

@@ -49,7 +49,11 @@ var ZenProfileDialogUI = {
},
_openProfile(profile) {
Services.startup.createInstanceWithProfile(profile);
SelectableProfileService.getProfile(
aEvent.target.getAttribute("profileid")
).then(profile => {
SelectableProfileService.launchInstance(profile);
});
},
_getProfilesSize(profiles) {

View File

@@ -17,7 +17,7 @@ class ZenBrowserManagerSidebar extends ZenDOMOperatedFeature {
DEFAULT_MOBILE_USER_AGENT = `Mozilla/5.0 (Android 12; Mobile; rv:129.0) Gecko/20100101 Firefox/${AppConstants.ZEN_FIREFOX_VERSION}`;
MAX_SIDEBAR_PANELS = Services.prefs.getIntPref('zen.sidebar.max-webpanels');
init() {
ChromeUtils.defineLazyGetter(this, 'sidebar', () => document.getElementById('zen-sidebar-web-panel'));
ChromeUtils.defineLazyGetter(this, 'forwardButton', () => document.getElementById('zen-sidebar-web-panel-forward'));
@@ -615,7 +615,7 @@ class ZenBrowserManagerSidebar extends ZenDOMOperatedFeature {
this._setPinnedToElements();
this.moveToTabBox();
}
this.update();
this.update();
}
get sidebarElement() {

View File

@@ -120,7 +120,7 @@ var gZenThemeBuilder = {
//ctx.fillRect(0, 0, size, size);
// Add the thumb.
const accentColor = Services.prefs.getStringPref(kZenAccentColorConfigKey, '#aac7ff');
const accentColor = Services.prefs.getStringPref(kZenAccentColorConfigKey, '#ffb787');
const pos = this._getPositionFromColor(ctx, this._hexToRgb(accentColor));
let x = pos ? pos[0] : center;

View File

@@ -13,6 +13,13 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
};
_hoveringSidebar = false;
_lastScrollTime = 0;
bookmarkMenus = [
"PlacesToolbar",
"bookmarks-menu-button",
"BMB_bookmarksToolbar",
"BMB_unsortedBookmarks",
"BMB_mobileBookmarks"
];
async init() {
if (!this.shouldHaveWorkspaces) {
@@ -61,6 +68,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
Services.obs.addObserver(this, 'weave:engine:sync:finish');
Services.obs.addObserver(async function observe(subject) {
this._workspaceBookmarksCache = null;
await this.workspaceBookmarks();
this._invalidateBookmarkContainers();
}.bind(this), "workspace-bookmarks-updated");
}
initializeWorkspaceNavigation() {
@@ -128,7 +140,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
// Change workspace based on scroll direction
const direction = event.deltaX > 0 ? -1 : 1;
const direction = event.deltaX > 0 ? 1 : -1;
await this.changeWorkspaceShortcut(direction);
this._lastScrollTime = currentTime;
}, { passive: true });
@@ -320,6 +332,21 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
return this._workspaceCache;
}
async workspaceBookmarks() {
if (this._workspaceBookmarksCache) {
return this._workspaceBookmarksCache;
}
const [bookmarks, lastChangeTimestamp] = await Promise.all([
ZenWorkspaceBookmarksStorage.getBookmarkGuidsByWorkspace(),
ZenWorkspaceBookmarksStorage.getLastChangeTimestamp(),
]);
this._workspaceBookmarksCache = { bookmarks, lastChangeTimestamp };
return this._workspaceCache;
}
async onWorkspacesEnabledChanged() {
if (this.workspaceEnabled) {
throw Error("Shoud've had reloaded the window");
@@ -339,6 +366,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (this.workspaceEnabled) {
this._initializeWorkspaceCreationIcons();
this._initializeWorkspaceTabContextMenus();
await this.workspaceBookmarks();
window.addEventListener('TabBrowserInserted', this.onTabBrowserInserted.bind(this));
await SessionStore.promiseInitialized;
let workspaces = await this._workspaces();
@@ -658,7 +686,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
<div class="zen-workspace-container" ${containerGroup ? '' : 'hidden="true"'}>
</div>
</vbox>
<image class="toolbarbutton-icon zen-workspace-actions-reorder-icon" ></image>
<image class="toolbarbutton-icon zen-workspace-actions-reorder-icon" ></image>
<toolbarbutton closemenu="none" class="toolbarbutton-1 zen-workspace-actions">
<image class="toolbarbutton-icon" id="zen-workspace-actions-menu-icon"></image>
</toolbarbutton>
@@ -754,8 +782,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if(clearCache) {
browser.ZenWorkspaces._workspaceCache = null;
browser.ZenWorkspaces._workspaceBookmarksCache = null;
}
let workspaces = await browser.ZenWorkspaces._workspaces();
await browser.ZenWorkspaces.workspaceBookmarks();
workspaceList.innerHTML = '';
workspaceList.parentNode.style.display = 'flex';
if (workspaces.workspaces.length <= 0) {
@@ -1106,6 +1136,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
async _performWorkspaceChange(window, onInit) {
const previousWorkspace = await this.getActiveWorkspace();
this.activeWorkspace = window.uuid;
const containerId = window.containerTabId?.toString();
const workspaces = await this._workspaces();
@@ -1121,6 +1153,20 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
// Update UI and state
await this._updateWorkspaceState(window, onInit);
// Animate acordingly
if (previousWorkspace && !this._animatingChange) {
// we want to know if we are moving forward or backward in sense of animation
let isNextWorkspace = onInit ||
(workspaces.workspaces.findIndex((w) => w.uuid === previousWorkspace.uuid)
< workspaces.workspaces.findIndex((w) => w.uuid === window.uuid));
gBrowser.tabContainer.setAttribute('zen-workspace-animation', isNextWorkspace ? 'next' : 'previous');
this._animatingChange = true;
setTimeout(() => {
this._animatingChange = false;
gBrowser.tabContainer.removeAttribute('zen-workspace-animation');
}, 300);
}
}
@@ -1252,16 +1298,23 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
}
// Reset bookmarks toolbar
const placesToolbar = document.getElementById("PlacesToolbar");
if (placesToolbar?._placesView) {
placesToolbar._placesView.invalidateContainer(placesToolbar._placesView._resultNode);
}
// Reset bookmarks
this._invalidateBookmarkContainers();
// Update workspace indicator
await this.updateWorkspaceIndicator();
}
_invalidateBookmarkContainers() {
for (let i = 0, len = this.bookmarkMenus.length; i < len; i++) {
const element = document.getElementById(this.bookmarkMenus[i]);
if (element && element._placesView) {
const placesView = element._placesView;
placesView.invalidateContainer(placesView._resultNode);
}
}
}
async updateWorkspaceIndicator() {
// Update current workspace indicator
const currentWorkspace = await this.getActiveWorkspace();
@@ -1534,12 +1587,24 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
isBookmarkInAnotherWorkspace(bookmark) {
let tags = bookmark.tags;
// if any tag starts with "_workspace_id" and the workspace id doesnt match the active workspace id, return null
if (tags) {
for (let tag of tags.split(",")) {
return !!(tag.startsWith("zen_workspace_") && this.getActiveWorkspaceFromCache()?.uuid !== tag.split("_")[2]);
if (!this._workspaceBookmarksCache?.bookmarks) return false;
const bookmarkGuid = bookmark.bookmarkGuid;
const activeWorkspaceUuid = this.activeWorkspace;
let isInActiveWorkspace = false;
let isInOtherWorkspace = false;
for (const [workspaceUuid, bookmarkGuids] of Object.entries(this._workspaceBookmarksCache.bookmarks)) {
if (bookmarkGuids.includes(bookmarkGuid)) {
if (workspaceUuid === activeWorkspaceUuid) {
isInActiveWorkspace = true;
} else {
isInOtherWorkspace = true;
}
}
}
// Return true only if the bookmark is in another workspace and not in the active one
return isInOtherWorkspace && !isInActiveWorkspace;
}
})();

View File

@@ -2,6 +2,8 @@ var ZenWorkspacesStorage = {
async init() {
console.log('ZenWorkspacesStorage: Initializing...');
await this._ensureTable();
await ZenWorkspaceBookmarksStorage.init();
ZenWorkspaces._delayedStartup();
},
async _ensureTable() {
@@ -64,7 +66,6 @@ var ZenWorkspacesStorage = {
await ZenWorkspacesStorage.migrateWorkspacesFromJSON();
}
ZenWorkspaces._delayedStartup();
});
},
@@ -128,7 +129,7 @@ var ZenWorkspacesStorage = {
uuid, name, icon, is_default, container_id, created_at, updated_at, "position",
theme_type, theme_colors, theme_opacity, theme_rotation, theme_texture
) VALUES (
:uuid, :name, :icon, :is_default, :container_id,
:uuid, :name, :icon, :is_default, :container_id,
COALESCE((SELECT created_at FROM zen_workspaces WHERE uuid = :uuid), :now),
:now,
:position,
@@ -405,3 +406,152 @@ var ZenWorkspacesStorage = {
this._notifyWorkspacesChanged("zen-workspace-updated", Array.from(changedUUIDs));
},
};
// Integration of workspace-specific bookmarks into Places
var ZenWorkspaceBookmarksStorage = {
async init() {
await this._ensureTable();
},
async _ensureTable() {
await 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,
workspace_uuid TEXT NOT NULL,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE(bookmark_guid, workspace_uuid),
FOREIGN KEY(workspace_uuid) REFERENCES zen_workspaces(uuid) ON DELETE CASCADE,
FOREIGN KEY(bookmark_guid) REFERENCES moz_bookmarks(guid) ON DELETE CASCADE
)
`);
// 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(`
CREATE TABLE IF NOT EXISTS zen_bookmarks_workspaces_changes (
id INTEGER PRIMARY KEY,
bookmark_guid TEXT NOT NULL,
workspace_uuid TEXT NOT NULL,
change_type TEXT NOT NULL,
timestamp INTEGER NOT NULL,
UNIQUE(bookmark_guid, workspace_uuid),
FOREIGN KEY(workspace_uuid) REFERENCES zen_workspaces(uuid) ON DELETE CASCADE,
FOREIGN KEY(bookmark_guid) REFERENCES moz_bookmarks(guid) ON DELETE CASCADE
)
`);
// 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)
`);
});
},
/**
* Updates the last change timestamp in the metadata table.
* @param {Object} db - The database connection.
*/
async updateLastChangeTimestamp(db) {
const now = Date.now();
await db.execute(`
INSERT OR REPLACE INTO moz_meta (key, value)
VALUES ('zen_bookmarks_workspaces_last_change', :now)
`, { now });
},
/**
* Gets the timestamp of the last change.
* @returns {Promise<number>} The timestamp of the last change.
*/
async getLastChangeTimestamp() {
const db = await PlacesUtils.promiseDBConnection();
const result = await db.executeCached(`
SELECT value FROM moz_meta WHERE key = 'zen_bookmarks_workspaces_last_change'
`);
return result.length ? parseInt(result[0].getResultByName('value'), 10) : 0;
},
async getBookmarkWorkspaces(bookmarkGuid) {
const db = await PlacesUtils.promiseDBConnection();
const rows = await db.execute(`
SELECT workspace_uuid
FROM zen_bookmarks_workspaces
WHERE bookmark_guid = :bookmark_guid
`, { bookmark_guid: bookmarkGuid });
return rows.map(row => row.getResultByName("workspace_uuid"));
},
/**
* Get all bookmark GUIDs organized by workspace UUID.
* @returns {Promise<Object>} A dictionary with workspace UUIDs as keys and arrays of bookmark GUIDs as values.
* @example
* // Returns:
* {
* "workspace-uuid-1": ["bookmark-guid-1", "bookmark-guid-2"],
* "workspace-uuid-2": ["bookmark-guid-3"]
* }
*/
async getBookmarkGuidsByWorkspace() {
const db = await PlacesUtils.promiseDBConnection();
const rows = await db.execute(`
SELECT workspace_uuid, GROUP_CONCAT(bookmark_guid) as bookmark_guids
FROM zen_bookmarks_workspaces
GROUP BY workspace_uuid
`);
const result = {};
for (const row of rows) {
const workspaceUuid = row.getResultByName("workspace_uuid");
const bookmarkGuids = row.getResultByName("bookmark_guids");
result[workspaceUuid] = bookmarkGuids ? bookmarkGuids.split(',') : [];
}
return result;
},
/**
* Get all changed bookmarks with their change types.
* @returns {Promise<Object>} An object mapping bookmark+workspace pairs to their change data.
*/
async getChangedIDs() {
const db = await PlacesUtils.promiseDBConnection();
const rows = await db.execute(`
SELECT bookmark_guid, workspace_uuid, change_type, timestamp
FROM zen_bookmarks_workspaces_changes
`);
const changes = {};
for (const row of rows) {
const key = `${row.getResultByName('bookmark_guid')}:${row.getResultByName('workspace_uuid')}`;
changes[key] = {
type: row.getResultByName('change_type'),
timestamp: row.getResultByName('timestamp')
};
}
return changes;
},
/**
* Clear all recorded changes.
*/
async clearChangedIDs() {
await PlacesUtils.withConnectionWrapper('ZenWorkspaceBookmarksStorage.clearChangedIDs', async (db) => {
await db.execute(`DELETE FROM zen_bookmarks_workspaces_changes`);
});
},
};

View File

@@ -62,7 +62,7 @@ export class ZenGlanceChild extends JSWindowActorChild {
url = this.contentWindow.location.origin + url;
}
const rect = target.getBoundingClientRect();
this.sendAsyncMessage('ZenGlance:OpenGlance', {
this.sendAsyncMessage('ZenGlance:OpenGlance', {
url,
x: rect.left,
y: rect.top,
@@ -117,7 +117,7 @@ export class ZenGlanceChild extends JSWindowActorChild {
if (target) {
event.preventDefault();
event.stopPropagation();
this.openGlance(target);
}
}

View File

@@ -8,7 +8,7 @@ index bc8e72a3cd07e8746c6fbf190bdd2bf70f4000d4..07031dfdfadf393db5fd848948e33510
:host {
- border-inline-end: 1px solid var(--in-content-border-color);
+ border: 1px solid var(--in-content-border-color);
background-color: var(--in-content-box-background);
background-color: var(--background-color-box);
display: flex;
flex-direction: column;
@@ -161,3 +161,8 @@ ol {

View File

@@ -0,0 +1,159 @@
diff --git a/browser/components/places/PlacesUIUtils.sys.mjs b/browser/components/places/PlacesUIUtils.sys.mjs
index 0f79ba5dd42116d626445b86f6b24731d2fa8aad..76d692db1731e84b28d9035b03e34c176c12bd23 100644
--- a/browser/components/places/PlacesUIUtils.sys.mjs
+++ b/browser/components/places/PlacesUIUtils.sys.mjs
@@ -58,6 +58,7 @@ class BookmarkState {
info,
tags = "",
keyword = "",
+ workspaces = [],
isFolder = false,
children = [],
autosave = false,
@@ -82,12 +83,18 @@ class BookmarkState {
keyword,
parentGuid: info.parentGuid,
index,
+ workspaces,
};
// Edited bookmark
this._newState = {};
}
+ async _workspacesChanged(workspaces) {
+ this._newState.workspaces = workspaces;
+ await this._maybeSave();
+ }
+
/**
* Save edited title for the bookmark
*
@@ -181,6 +188,14 @@ class BookmarkState {
"BookmarkState::createBookmark"
);
this._guid = results?.[0];
+
+ if ('workspaces' in this._newState) {
+ try {
+ await this.updateBookmarkWorkspaces(this._guid, this._newState.workspaces);
+ } catch (ex) {
+ console.error("Failed to update workspace assignments:", ex);
+ }
+ }
return this._guid;
}
@@ -214,6 +229,14 @@ class BookmarkState {
"BookmarkState::save::createFolder"
);
this._guid = results[0];
+
+ if ('workspaces' in this._newState) {
+ try {
+ await this.updateBookmarkWorkspaces(this._guid, this._newState.workspaces);
+ } catch (ex) {
+ console.error("Failed to update workspace assignments:", ex);
+ }
+ }
return this._guid;
}
@@ -300,11 +323,97 @@ class BookmarkState {
await lazy.PlacesTransactions.batch(transactions, "BookmarkState::save");
}
+ if ('workspaces' in this._newState) {
+ try {
+ await this.updateBookmarkWorkspaces(this._guid, this._newState.workspaces);
+ } catch (ex) {
+ console.error("Failed to update workspace assignments:", ex);
+ }
+ }
this._originalState = { ...this._originalState, ...this._newState };
this._newState = {};
return this._guid;
}
+ async updateBookmarkWorkspaces(bookmarkGuid, workspaces) {
+ await lazy.PlacesUtils.withConnectionWrapper('ZenWorkspaceBookmarksStorage.updateBookmarkWorkspaces', async (db) => {
+ const now = Date.now();
+
+ await db.executeTransaction(async () => {
+ const rows = await db.execute(`
+ SELECT workspace_uuid
+ FROM zen_bookmarks_workspaces
+ WHERE bookmark_guid = :bookmark_guid
+ `, { bookmark_guid: bookmarkGuid });
+
+ const currentWorkspaces = rows.map(row => row.getResultByName("workspace_uuid"));
+ const workspacesToRemove = currentWorkspaces.filter(w => !workspaces.includes(w));
+ const workspacesToAdd = workspaces.filter(w => !currentWorkspaces.includes(w));
+
+ // If there are workspaces to remove, delete only those specific associations
+ if (workspacesToRemove.length > 0) {
+ const placeholders = workspacesToRemove.map(() => '?').join(',');
+ await db.execute(`
+ DELETE FROM zen_bookmarks_workspaces
+ WHERE bookmark_guid = :bookmark_guid
+ AND workspace_uuid IN (${placeholders})
+ `, [bookmarkGuid, ...workspacesToRemove]);
+
+ // Record removals
+ for (const workspace of workspacesToRemove) {
+ await this._recordChange(db, bookmarkGuid, workspace, 'removed');
+ }
+ }
+
+ // Add only new associations
+ for (const workspaceUuid of workspacesToAdd) {
+ await db.execute(`
+ INSERT INTO zen_bookmarks_workspaces (
+ bookmark_guid, workspace_uuid, created_at, updated_at
+ ) VALUES (
+ :bookmark_guid, :workspace_uuid, :now, :now
+ )
+ `, {
+ bookmark_guid: bookmarkGuid,
+ workspace_uuid: workspaceUuid,
+ now
+ });
+
+ await this._recordChange(db, bookmarkGuid, workspaceUuid, 'added');
+ }
+ });
+ });
+
+ const changes = { bookmarkGuid, workspaces };
+ Services.obs.notifyObservers(null, "workspace-bookmarks-updated", JSON.stringify(changes));
+ }
+
+ async _recordChange(db, bookmarkGuid, workspaceUuid, changeType) {
+ const now = Date.now();
+ await db.execute(`
+ INSERT OR REPLACE INTO zen_bookmarks_workspaces_changes (
+ bookmark_guid, workspace_uuid, change_type, timestamp
+ ) VALUES (
+ :bookmark_guid, :workspace_uuid, :change_type, :timestamp
+ )
+ `, {
+ bookmark_guid: bookmarkGuid,
+ workspace_uuid: workspaceUuid,
+ change_type: changeType,
+ timestamp: Math.floor(now / 1000)
+ });
+
+ await this._updateLastChangeTimestamp(db);
+ }
+
+ async _updateLastChangeTimestamp(db) {
+ const now = Date.now();
+ await db.execute(`
+ INSERT OR REPLACE INTO moz_meta (key, value)
+ VALUES ('zen_bookmarks_workspaces_last_change', :now)
+ `, { now });
+ }
+
/**
* Append transactions to update tags by given information.
*

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/places/content/bookmarkProperties.xhtml b/browser/components/places/content/bookmarkProperties.xhtml
index 047652a52e705d49f870399992873fce536c07b9..2932eb94e8c16eb05f172322a6ce3ea201ecd0b1 100644
index 047652a52e705d49f870399992873fce536c07b9..8bc7d1c5e44c33d90f82fdc6f66d9e2e80c60bae 100644
--- a/browser/components/places/content/bookmarkProperties.xhtml
+++ b/browser/components/places/content/bookmarkProperties.xhtml
@@ -37,6 +37,7 @@
@@ -10,3 +10,11 @@ index 047652a52e705d49f870399992873fce536c07b9..2932eb94e8c16eb05f172322a6ce3ea2
</linkset>
<stringbundleset id="stringbundleset">
@@ -44,6 +45,7 @@
src="chrome://browser/locale/places/bookmarkProperties.properties"/>
</stringbundleset>
+ <script src="chrome://browser/content/zen-components/ZenWorkspacesStorage.mjs" />
<script src="chrome://browser/content/places/editBookmark.js"/>
<script src="chrome://browser/content/places/bookmarkProperties.js"/>
<script src="chrome://global/content/globalOverlay.js"/>

View File

@@ -1,8 +1,35 @@
diff --git a/browser/components/places/content/browserPlacesViews.js b/browser/components/places/content/browserPlacesViews.js
index 1bfa0af16178c9b42172bc1b1e0249d28ff8e9e6..e7e76a6d548b32887c1d39053e42c5e3dafbb839 100644
index 1bfa0af16178c9b42172bc1b1e0249d28ff8e9e6..417a9dc4e55208bdc9c1422a3bae14361a4964c5 100644
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -393,6 +393,7 @@ class PlacesViewBase {
@@ -330,12 +330,23 @@ class PlacesViewBase {
this._cleanPopup(aPopup);
+ let children = [];
let cc = resultNode.childCount;
- if (cc > 0) {
+ for (let i = 0; i < cc; ++i) {
+ let child = resultNode.getChild(i);
+ // Skip nodes that don't belong in current workspace
+ if (PlacesUtils.nodeIsURI(child) || PlacesUtils.containerTypes.includes(child.type)) {
+ if (ZenWorkspaces.isBookmarkInAnotherWorkspace(child)) {
+ continue;
+ }
+ }
+ children.push(child);
+ }
+
+ if (children.length > 0) {
this._setEmptyPopupStatus(aPopup, false);
let fragment = document.createDocumentFragment();
- for (let i = 0; i < cc; ++i) {
- let child = resultNode.getChild(i);
+ for (let child of children) {
this._insertNewItemToPopup(child, fragment);
}
aPopup.insertBefore(fragment, aPopup._endMarker);
@@ -393,6 +404,7 @@ class PlacesViewBase {
"scheme",
PlacesUIUtils.guessUrlSchemeForUI(aPlacesNode.uri)
);
@@ -10,16 +37,89 @@ index 1bfa0af16178c9b42172bc1b1e0249d28ff8e9e6..e7e76a6d548b32887c1d39053e42c5e3
} else if (PlacesUtils.containerTypes.includes(type)) {
element = document.createXULElement("menu");
element.setAttribute("container", "true");
@@ -1087,6 +1088,8 @@ class PlacesToolbar extends PlacesViewBase {
@@ -981,25 +993,33 @@ class PlacesToolbar extends PlacesViewBase {
this._rootElt.firstChild.remove();
}
+ let visibleNodes = [];
let cc = this._resultNode.childCount;
- if (cc > 0) {
- // There could be a lot of nodes, but we only want to build the ones that
- // are more likely to be shown, not all of them.
- // We also don't want to wait for reflows at every node insertion, to
- // calculate a precise number of visible items, thus we guess a size from
- // the first non-separator node (because separators have flexible size).
+ for (let i = 0; i < cc; i++) {
+ let child = this._resultNode.getChild(i);
+ if (PlacesUtils.nodeIsURI(child) || PlacesUtils.containerTypes.includes(child.type)) {
+ if (!ZenWorkspaces.isBookmarkInAnotherWorkspace(child)) {
+ visibleNodes.push(child);
+ }
+ } else {
+ // Always include separators
+ visibleNodes.push(child);
+ }
+ }
+
+ if (visibleNodes.length > 0) {
+ // Look for the first non-separator node.
let startIndex = 0;
let limit = await this._runBeforeFrameRender(() => {
if (!this._isAlive) {
- return cc;
+ return visibleNodes.length;
}
- // Look for the first non-separator node.
let elt;
- while (startIndex < cc) {
+ while (startIndex < visibleNodes.length) {
elt = this._insertNewItem(
- this._resultNode.getChild(startIndex),
- this._rootElt
+ visibleNodes[startIndex],
+ this._rootElt
);
++startIndex;
if (elt.localName != "toolbarseparator") {
@@ -1007,15 +1027,12 @@ class PlacesToolbar extends PlacesViewBase {
}
}
if (!elt) {
- return cc;
+ return visibleNodes.length;
}
return window.promiseDocumentFlushed(() => {
- // We assume a button with just the icon will be more or less a square,
- // then compensate the measurement error by considering a larger screen
- // width. Moreover the window could be bigger than the screen.
- let size = elt.clientHeight || 1; // Sanity fallback.
- return Math.min(cc, parseInt((window.screen.width * 1.5) / size));
+ let size = elt.clientHeight || 1;
+ return Math.min(visibleNodes.length, parseInt((window.screen.width * 1.5) / size));
});
});
@@ -1025,7 +1042,7 @@ class PlacesToolbar extends PlacesViewBase {
let fragment = document.createDocumentFragment();
for (let i = startIndex; i < limit; ++i) {
- this._insertNewItem(this._resultNode.getChild(i), fragment);
+ this._insertNewItem(visibleNodes[i], fragment);
}
await new Promise(resolve => window.requestAnimationFrame(resolve));
if (!this._isAlive) {
@@ -1087,6 +1104,8 @@ class PlacesToolbar extends PlacesViewBase {
"scheme",
PlacesUIUtils.guessUrlSchemeForUI(aChild.uri)
);
+ button.hidden = ZenWorkspaces.isBookmarkInAnotherWorkspace(aChild);
+
+ button.addEventListener("command", gZenGlanceManager.openGlanceForBookmark.bind(gZenGlanceManager));
}
}
@@ -2235,7 +2238,7 @@ this.PlacesPanelview = class PlacesPanelview extends PlacesViewBase {
@@ -2235,7 +2254,7 @@ this.PlacesPanelview = class PlacesPanelview extends PlacesViewBase {
PlacesUIUtils.guessUrlSchemeForUI(placesNode.uri)
);
element.setAttribute("label", PlacesUIUtils.getBestTitle(placesNode));

View File

@@ -0,0 +1,182 @@
diff --git a/browser/components/places/content/editBookmark.js b/browser/components/places/content/editBookmark.js
index 9f17174fdd9cc1eaefb4330da1e10f40eeda2f31..e2c38872ee3a5c45d2e288e67d33f9ce24cab2b9 100644
--- a/browser/components/places/content/editBookmark.js
+++ b/browser/components/places/content/editBookmark.js
@@ -370,6 +370,10 @@ var gEditItemOverlay = {
this._keywordField.readOnly = this.readOnly;
}
+ if (showOrCollapse("workspaceRow", true, "workspace")) {
+ await this._initWorkspaceDropdown(aInfo);
+ }
+
// Collapse the tag selector if the item does not accept tags.
if (showOrCollapse("tagsRow", isBookmark || bulkTagging, "tags")) {
this._initTagsField();
@@ -682,6 +686,7 @@ var gEditItemOverlay = {
if (this._paneInfo.isBookmark) {
options.tags = this._element("tagsField").value;
options.keyword = this._keyword;
+ options.workspaces = this._selectedWorkspaces;
}
if (this._paneInfo.bulkTagging) {
@@ -1232,6 +1237,148 @@ var gEditItemOverlay = {
get bookmarkState() {
return this._bookmarkState;
},
+
+ async _initWorkspaceSelector() {
+ if(document.documentElement.getAttribute("windowtype") === "Places:Organizer") {
+ return;
+ }
+ this._workspaces = await ZenWorkspacesStorage.getWorkspaces();
+
+ const selectElement = this._workspaceSelect;
+
+ // Clear any existing options
+ while (selectElement.firstChild) {
+ selectElement.removeChild(selectElement.firstChild);
+ }
+
+ // For each workspace, create an option element
+ for (let workspace of this._workspaces) {
+ const option = document.createElementNS("http://www.w3.org/1999/xhtml", "option");
+ option.textContent = workspace.name;
+ option.value = workspace.uuid;
+ selectElement.appendChild(option);
+ }
+
+ selectElement.disabled = this.readOnly;
+ },
+ async onWorkspaceSelectionChange(event) {
+ if(document.documentElement.getAttribute("windowtype") === "Places:Organizer") {
+ return;
+ }
+ event.stopPropagation();
+
+ // Add new workspaces uuids
+ const checkboxes = this._workspaceList.querySelectorAll("input[type='checkbox']");
+ const newWorkspaces = [];
+ const selectedNames = [];
+
+ checkboxes.forEach(checkbox => {
+ if (checkbox.checked) {
+ newWorkspaces.push(checkbox.value);
+
+ const label = checkbox.parentNode.textContent.trim();
+ selectedNames.push(label);
+ }
+ });
+
+ this._selectedWorkspaces = [ ...newWorkspaces];
+
+ // Update the bookmark state
+ if (this._bookmarkState) {
+ await this._bookmarkState._workspacesChanged(this._selectedWorkspaces);
+ }
+
+ // Update summary text
+ this._workspaceSummary.textContent = selectedNames.length
+ ? selectedNames.join(", ")
+ : "-";
+ },
+
+ onWorkspaceDropdownToggle() {
+ if(document.documentElement.getAttribute("windowtype") === "Places:Organizer") {
+ return;
+ }
+
+ // Toggle active class on the container
+ const dropdown = this._workspaceList;
+ const button = this._workspaceSummary;
+
+ dropdown.hidden = !dropdown.hidden;
+
+ var expander = this._element("workspacesSelectorExpander");
+ expander.classList.toggle("expander-up", !dropdown.hidden);
+ expander.classList.toggle("expander-down", dropdown.hidden);
+
+ // Only update summary text when closing the dropdown
+ if (dropdown.hidden) {
+ const checkboxes = this._workspaceList.querySelectorAll("input[type='checkbox']");
+ const selectedLabels = [];
+
+ checkboxes.forEach(checkbox => {
+ if (checkbox.checked) {
+ const label = checkbox.parentNode.textContent.trim();
+ selectedLabels.push(label);
+ }
+ });
+
+ button.textContent = selectedLabels.length
+ ? selectedLabels.join(", ")
+ : "-";
+ }
+ },
+
+ async _initWorkspaceDropdown(aInfo) {
+ if(document.documentElement.getAttribute("windowtype") === "Places:Organizer") {
+ return;
+ }
+ this._workspaces = await ZenWorkspacesStorage.getWorkspaces();
+ const workspaceList = this._workspaceList;
+ if(aInfo.node?.bookmarkGuid) {
+ this._selectedWorkspaces = await ZenWorkspaceBookmarksStorage.getBookmarkWorkspaces(aInfo.node.bookmarkGuid);
+ }
+
+ // Clear existing items
+ workspaceList.innerHTML = "";
+
+ // Create checkbox items for each workspace
+ for (let workspace of this._workspaces) {
+ const li = document.createElementNS("http://www.w3.org/1999/xhtml", "li");
+ const label = document.createElementNS("http://www.w3.org/1999/xhtml", "label");
+ const input = document.createElementNS("http://www.w3.org/1999/xhtml", "input");
+
+ input.setAttribute("type", "checkbox");
+ input.setAttribute("name", "workspace");
+ input.setAttribute("value", workspace.uuid);
+
+ // Check if this workspace is selected
+ input.checked = this._selectedWorkspaces?.includes(workspace.uuid) ?? false;
+
+ input.addEventListener("click", this.onWorkspaceSelectionChange.bind(this));
+
+ label.appendChild(input);
+ label.appendChild(document.createTextNode(workspace.name));
+ li.appendChild(label);
+ workspaceList.appendChild(li);
+ }
+
+ // Get the names of selected workspaces for initial summary
+ const selectedNames = this._workspaces
+ .filter(ws => this._selectedWorkspaces?.includes(ws.uuid))
+ .map(ws => ws.name);
+
+ // Update summary text with comma-separated list
+ this._workspaceSummary.textContent = selectedNames.length
+ ? selectedNames.join(", ")
+ : "-";
+
+ // Handle read-only state
+ if (this.readOnly) {
+ this._workspaceDropdown.setAttribute("disabled", "true");
+ } else {
+ this._workspaceDropdown.removeAttribute("disabled");
+ }
+ },
+ _selectedWorkspaces : [],
};
ChromeUtils.defineLazyGetter(gEditItemOverlay, "_folderTree", () => {
@@ -1267,6 +1414,9 @@ for (let elt of [
"locationField",
"keywordField",
"tagsField",
+ "workspaceDropdown",
+ "workspaceSummary",
+ "workspaceList",
]) {
let eltScoped = elt;
ChromeUtils.defineLazyGetter(gEditItemOverlay, `_${eltScoped}`, () =>

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/places/content/editBookmarkPanel.inc.xhtml b/browser/components/places/content/editBookmarkPanel.inc.xhtml
index 3ec3f094831c2143a818b43d1761a571f0ffa63d..309dfa8ed628f4cc124fe16d20b7411065c09f23 100644
index 3ec3f094831c2143a818b43d1761a571f0ffa63d..c4dd904604ee10a909bbcc7c03dd0dd3536020b1 100644
--- a/browser/components/places/content/editBookmarkPanel.inc.xhtml
+++ b/browser/components/places/content/editBookmarkPanel.inc.xhtml
@@ -5,7 +5,7 @@
@@ -29,11 +29,30 @@ index 3ec3f094831c2143a818b43d1761a571f0ffa63d..309dfa8ed628f4cc124fe16d20b74110
<label data-l10n-id="bookmark-overlay-location-2"
class="editBMPanel_folderRow hideable"
control="editBMPanel_folderMenuList"/>
@@ -51,6 +51,7 @@
@@ -51,6 +51,26 @@
data-l10n-id="bookmark-overlay-folders-expander2"
oncommand="gEditItemOverlay.toggleFolderTreeVisibility();"/>
</hbox>
+</hbox>
+ <vbox>
+ <label data-l10n-id="zen-bookmark-edit-panel-workspace-selector"
+ class="hideable"
+ control="editBMPanel_workspacesSelectorExpander"/>
+ <div id="editBMPanel_workspaceDropdown"
+ class="editBMPanel_workspaceRow hideable workspace-dropdown">
+ <div
+ id="editBMPanel_workspaceSummary"
+ class="workspace-trigger">-</div>
+ <button id="editBMPanel_workspacesSelectorExpander"
+ class="expander-down panel-button"
+ data-l10n-id="bookmark-overlay-tags-expander2"
+ oncommand="gEditItemOverlay.onWorkspaceDropdownToggle();"/>
+
+ </div>
+ </vbox>
+
+ <ul id="editBMPanel_workspaceList" class="workspace-list hideable" hidden="true">
+ </ul>
<vbox id="editBMPanel_folderTreeRow"
class="hideable"

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/preferences/preferences.js b/browser/components/preferences/preferences.js
index 7e21bab426b6eb52fe84876d817fddbdb1a35ffc..445940903fb28d332e5436634fa9546ec812a130 100644
index 78b70a99b00198402c357ead363dec7e534be456..90e10509fdff67144f5cbcf42c743e617df604e0 100644
--- a/browser/components/preferences/preferences.js
+++ b/browser/components/preferences/preferences.js
@@ -122,6 +122,7 @@ ChromeUtils.defineLazyGetter(this, "gSubDialog", function () {
@@ -118,6 +118,7 @@ ChromeUtils.defineLazyGetter(this, "gSubDialog", function () {
styleSheets: [
"chrome://browser/skin/preferences/dialog.css",
"chrome://browser/skin/preferences/preferences.css",
@@ -10,14 +10,14 @@ index 7e21bab426b6eb52fe84876d817fddbdb1a35ffc..445940903fb28d332e5436634fa9546e
],
resizeCallback: async ({ title, frame }) => {
// Search within main document and highlight matched keyword.
@@ -196,6 +197,10 @@ function init_all() {
// the entire document.
Preferences.queueUpdateOfAllElements();
Services.telemetry.setEventRecordingEnabled("aboutpreferences", true);
@@ -197,6 +198,10 @@ function init_all() {
register_module("paneSearch", gSearchPane);
register_module("panePrivacy", gPrivacyPane);
register_module("paneContainers", gContainersPane);
+ register_module("paneZenLooks", gZenLooksAndFeel);
+ register_module("paneZenTabManagement", gZenWorkspacesSettings);
+ register_module("paneZenCKS", gZenCKSSettings);
+ register_module("paneZenMarketplace", gZenMarketplaceManager);
register_module("paneGeneral", gMainPane);
register_module("paneHome", gHomePane);
if (Services.prefs.getBoolPref("browser.translations.newSettingsUI.enable")) {
register_module("paneTranslations", gTranslationsPane);

View File

@@ -1024,7 +1024,7 @@ Preferences.addAll([
{
id: "zen.glance.activation-method",
type: "string",
default: "ctrl",
default: "ctrl",
},
{
id: "zen.glance.enabled",

View File

@@ -11,7 +11,7 @@
<label><html:h2 data-l10n-id="zen-settings-CKS-header"/></label>
<description class="description-deemphasized" data-l10n-id="zen-settings-CKS-description" />
<hbox>
<button id="zenCKSResetButton" data-l10n-id="zen-settings-CKS-reset-shortcuts" class="reset-button"/>
<button id="zenCKSResetButton" data-l10n-id="zen-settings-CKS-reset-shortcuts" class="reset-button"/>
</hbox>
<vbox id="zenCKSOption-wrapper"></vbox>
</groupbox>

View File

@@ -67,7 +67,7 @@
</g>
</g>
</g>
</svg>
</svg>
</div>
<div class="web-appearance-choice-footer">
<input type="radio" name="web-appearance" value="amoled" data-l10n-id="preferences-web-appearance-choice-input-auto"
@@ -112,7 +112,7 @@
</g>
</g>
</g>
</svg>
</svg>
</div>
<div class="web-appearance-choice-footer">
<input type="radio" name="web-appearance" value="default" data-l10n-id="preferences-web-appearance-choice-input-light"
@@ -157,7 +157,7 @@
</g>
</g>
</g>
</svg>
</svg>
</div>
<div class="web-appearance-choice-footer">
<input type="radio" name="web-appearance" value="colorful" data-l10n-id="preferences-web-appearance-choice-input-dark"

View File

@@ -36,7 +36,7 @@
<checkbox id="zenWorkspaceHideDeactivatedWorkspaces"
data-l10n-id="zen-settings-workspaces-hide-deactivated-workspaces"
preference="zen.workspaces.hide-deactivated-workspaces"/>
</vbox>
</groupbox>
@@ -81,6 +81,9 @@
<checkbox id="zenPinnedTabRestorePinnedTabsToPinnedUrl"
data-l10n-id="zen-pinned-tab-manager-restore-pinned-tabs-to-pinned-url"
preference="zen.pinned-tab-manager.restore-pinned-tabs-to-pinned-url"/>
<checkbox id="zenPinnedTabContainerSpecificEssentials"
data-l10n-id="zen-pinned-tab-manager-container-specific-essentials-enabled"
preference="zen.workspaces.container-specific-essentials-enabled"/>
<hbox align="center">
<label id="zenPinnedTabCloseShortcutBehaviorLabel" data-l10n-id="zen-pinned-tab-manager-close-shortcut-behavior-label"/>

View File

@@ -1,9 +1,9 @@
diff --git a/browser/components/sessionstore/TabState.sys.mjs b/browser/components/sessionstore/TabState.sys.mjs
index 26f5671c849d9b0a126d79b07bc7d3d7870826ec..36b535321f17a4e3dfdfdbb677a4e4b869038154 100644
index 8f7ed557e6aa61e7e16ed4a8d785ad5fe651b3d8..83bf443ca158c07e05075777da02b7f228d83dff 100644
--- a/browser/components/sessionstore/TabState.sys.mjs
+++ b/browser/components/sessionstore/TabState.sys.mjs
@@ -98,6 +98,13 @@ var TabStateInternal = {
tabData.muteReason = tab.muteReason;
@@ -84,6 +84,13 @@ class _TabState {
tabData.groupId = tab.group.id;
}
+ tabData.zenWorkspace = tab.getAttribute("zen-workspace-id");

View File

@@ -22,15 +22,15 @@ index 4a124003976684e014435854aef69ce29da541d2..61ce44751c36eea3e5ae2ddcc62e42c0
+ this._splitter.style.order = browser.children.length + 1;
+ this._splitter.style.marginRight = 0;
// Indicate we've switched ordering to the box
this._box.setAttribute("positionend", true);
sidebarMain.setAttribute("positionend", true);
this._box.toggleAttribute("positionend", true);
sidebarMain.toggleAttribute("positionend", true);
@@ -603,6 +604,9 @@ var SidebarController = {
this._box.removeAttribute("positionend");
sidebarMain.removeAttribute("positionend");
sidebarContainer.removeAttribute("positionend");
this._box.toggleAttribute("positionend", false);
sidebarMain.toggleAttribute("positionend", false);
sidebarContainer.toggleAttribute("positionend", false);
+ this._box.style.order = 1;
+ this._splitter.style.order = 2;
+ this._splitter.style.removeProperty("margin-right");
this.toolbarButton &&
this.toolbarButton.toggleAttribute("positionend", false);
}
this.hideSwitcherPanel();

View File

@@ -1,9 +1,9 @@
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338e14216df 100644
index fec3dc8129a4d235fdd05e0390145a02064ebaa5..636b56754f48c1ec931152cf34bab8414a75cebc 100644
--- a/browser/components/tabbrowser/content/tabbrowser.js
+++ b/browser/components/tabbrowser/content/tabbrowser.js
@@ -462,11 +462,26 @@
return duplicateTabs;
@@ -402,11 +402,26 @@
return count;
},
+ get _numVisiblePinTabs() {
@@ -19,7 +19,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
+ return i;
+ },
+
get _numPinnedTabs() {
get pinnedTabCount() {
- for (var i = 0; i < this.tabs.length; i++) {
- if (!this.tabs[i].pinned) {
+ let i = 0;
@@ -31,7 +31,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
}
return i;
},
@@ -860,7 +875,7 @@
@@ -800,7 +815,7 @@
if (this.tabContainer.verticalMode) {
let wasFocused = document.activeElement == this.selectedTab;
let oldPosition = aTab._tPos;
@@ -39,8 +39,8 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
+ aTab.hasAttribute("zen-essential") ? document.getElementById("zen-essentials-container").appendChild(aTab) : this.verticalPinnedTabsContainer.appendChild(aTab);
this._updateAfterMoveTabTo(aTab, oldPosition, wasFocused);
} else {
this.moveTabTo(aTab, this._numPinnedTabs);
@@ -1107,6 +1122,7 @@
this.moveTabTo(aTab, this.pinnedTabCount);
@@ -1047,6 +1062,7 @@
let LOCAL_PROTOCOLS = ["chrome:", "about:", "resource:", "data:"];
@@ -48,7 +48,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
if (
aIconURL &&
!aLoadingPrincipal &&
@@ -1117,6 +1133,9 @@
@@ -1057,6 +1073,9 @@
);
return;
}
@@ -58,7 +58,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
let browser = this.getBrowserForTab(aTab);
browser.mIconURL = aIconURL;
@@ -1346,6 +1365,7 @@
@@ -1286,6 +1305,7 @@
if (!this._previewMode) {
newTab.recordTimeFromUnloadToReload();
newTab.updateLastAccessed();
@@ -66,7 +66,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
oldTab.updateLastAccessed();
// if this is the foreground window, update the last-seen timestamps.
if (this.ownerGlobal == BrowserWindowTracker.getTopWindow()) {
@@ -2431,7 +2451,7 @@
@@ -2371,7 +2391,7 @@
let panel = this.getPanel(browser);
let uniqueId = this._generateUniquePanelID();
@@ -75,7 +75,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
aTab.linkedPanel = uniqueId;
// Inject the <browser> into the DOM if necessary.
@@ -2491,7 +2511,7 @@
@@ -2431,7 +2451,7 @@
// hasSiblings=false on both the existing browser and the new browser.
if (this.tabs.length == 2) {
this.tabs[0].linkedBrowser.browsingContext.hasSiblings = true;
@@ -84,7 +84,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
} else {
aTab.linkedBrowser.browsingContext.hasSiblings = this.tabs.length > 1;
}
@@ -2711,6 +2731,11 @@
@@ -2651,6 +2671,11 @@
);
}
@@ -96,7 +96,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
if (!UserInteraction.running("browser.tabs.opening", window)) {
UserInteraction.start("browser.tabs.opening", "initting", window);
}
@@ -2780,6 +2805,9 @@
@@ -2720,6 +2745,9 @@
noInitialLabel,
skipBackgroundNotify,
});
@@ -106,7 +106,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
if (insertTab) {
// insert the tab into the tab container in the correct position
this._insertTabAtIndex(t, {
@@ -3291,6 +3319,23 @@
@@ -3342,6 +3370,23 @@
) {
tabWasReused = true;
tab = this.selectedTab;
@@ -130,7 +130,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
if (!tabData.pinned) {
this.unpinTab(tab);
} else {
@@ -3304,6 +3349,9 @@
@@ -3355,6 +3400,9 @@
restoreTabsLazily && !select && !tabData.pinned;
let url = "about:blank";
@@ -140,7 +140,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
if (tabData.entries?.length) {
let activeIndex = (tabData.index || tabData.entries.length) - 1;
// Ensure the index is in bounds.
@@ -3340,6 +3388,21 @@
@@ -3391,6 +3439,21 @@
preferredRemoteType,
});
@@ -162,7 +162,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
if (select) {
tabToSelect = tab;
}
@@ -3374,7 +3437,6 @@
@@ -3444,7 +3507,6 @@
this.tabContainer._invalidateCachedTabs();
}
}
@@ -170,7 +170,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
tab.initialize();
}
@@ -3831,6 +3893,10 @@
@@ -3992,6 +4054,10 @@
return;
}
@@ -181,7 +181,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
this.removeTabs(selectedTabs);
},
@@ -4148,6 +4214,13 @@
@@ -4309,6 +4375,13 @@
TelemetryStopwatch.start("FX_TAB_CLOSE_TIME_NO_ANIM_MS", aTab);
}
@@ -195,7 +195,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
// Handle requests for synchronously removing an already
// asynchronously closing tab.
if (!animate && aTab.closing) {
@@ -4163,6 +4236,10 @@
@@ -4324,6 +4397,10 @@
// state).
let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width;
@@ -206,7 +206,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
if (
!this._beginRemoveTab(aTab, {
closeWindowFastpath: true,
@@ -4311,7 +4388,7 @@
@@ -4472,7 +4549,7 @@
var closeWindow = false;
var newTab = false;
@@ -215,7 +215,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
closeWindow =
closeWindowWithLastTab != null
? closeWindowWithLastTab
@@ -5123,10 +5200,10 @@
@@ -5265,10 +5342,10 @@
SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
},
@@ -228,7 +228,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
aTab.selected ||
aTab.closing ||
// Tabs that are sharing the screen, microphone or camera cannot be hidden.
@@ -7042,6 +7119,7 @@
@@ -7181,6 +7258,7 @@
aWebProgress.isTopLevel
) {
this.mTab.setAttribute("busy", "true");
@@ -236,7 +236,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
gBrowser._tabAttrModified(this.mTab, ["busy"]);
this.mTab._notselectedsinceload = !this.mTab.selected;
gBrowser.syncThrobberAnimations(this.mTab);
@@ -7874,7 +7952,7 @@ var TabContextMenu = {
@@ -8114,7 +8192,7 @@ var TabContextMenu = {
);
contextUnpinSelectedTabs.hidden =
!this.contextTab.pinned || !multiselectionContext;
@@ -245,7 +245,16 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338
// Move Tab items
let contextMoveTabOptions = document.getElementById(
"context_moveTabOptions"
@@ -8136,6 +8214,7 @@ var TabContextMenu = {
@@ -8148,7 +8226,7 @@ var TabContextMenu = {
let contextMoveTabToStart = document.getElementById("context_moveToStart");
let isFirstTab =
tabsToMove[0] == visibleTabs[0] ||
- tabsToMove[0] == visibleTabs[gBrowser.pinnedTabCount];
+ tabsToMove[0] == visibleTabs[gBrowser._numVisiblePinTabs];
contextMoveTabToStart.disabled = isFirstTab && allSelectedTabsAdjacent;
document.getElementById("context_openTabInWindow").disabled =
@@ -8376,6 +8454,7 @@ var TabContextMenu = {
if (this.contextTab.multiselected) {
gBrowser.removeMultiSelectedTabs();
} else {

View File

@@ -1,8 +1,17 @@
diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js
index f3a2f226a9056c5a75023281fdeb704cec49b4a6..ae808f0f16466edc3d5f70271cc40c80deb7ab07 100644
index f9e256b143786c18ba85859ca1b11182ab23f1aa..f60a8850305f1d7c2eadb6ac6996302f42a08a8a 100644
--- a/browser/components/tabbrowser/content/tabs.js
+++ b/browser/components/tabbrowser/content/tabs.js
@@ -894,7 +894,7 @@
@@ -541,7 +541,7 @@
if (this.#isContainerVerticalPinnedExpanded(tab)) {
// In expanded vertical mode, the max number of pinned tabs per row is dynamic
// Set this before adjusting dragged tab's position
- let pinnedTabs = this.visibleTabs.slice(0, gBrowser.pinnedTabCount);
+ let pinnedTabs = this.visibleTabs.slice(0, gBrowser._numVisiblePinTabs);
let tabsPerRow = 0;
let position = 0;
for (let pinnedTab of pinnedTabs) {
@@ -918,7 +918,7 @@
let postTransitionCleanup = () => {
tab.removeAttribute("tabdrop-samewindow");
@@ -11,7 +20,7 @@ index f3a2f226a9056c5a75023281fdeb704cec49b4a6..ae808f0f16466edc3d5f70271cc40c80
if (dropIndex !== false) {
gBrowser.moveTabTo(tab, dropIndex);
if (incrementDropIndex) {
@@ -904,7 +904,7 @@
@@ -928,7 +928,7 @@
gBrowser.syncThrobberAnimations(tab);
};
@@ -20,7 +29,7 @@ index f3a2f226a9056c5a75023281fdeb704cec49b4a6..ae808f0f16466edc3d5f70271cc40c80
postTransitionCleanup();
} else {
let onTransitionEnd = transitionendEvent => {
@@ -1044,7 +1044,8 @@
@@ -1077,7 +1077,8 @@
if (
dt.mozUserCancelled ||
dt.dropEffect != "none" ||
@@ -30,25 +39,16 @@ index f3a2f226a9056c5a75023281fdeb704cec49b4a6..ae808f0f16466edc3d5f70271cc40c80
) {
delete draggedTab._dragData;
return;
@@ -1284,7 +1285,7 @@
@@ -1328,7 +1329,7 @@
}
}
- let allChildren = [...verticalPinnedTabsContainer.children, ...children];
+ let allChildren = [...document.getElementById("zen-essentials-container").children, ...verticalPinnedTabsContainer.children, ...children];
this._allTabs = allChildren;
return allChildren;
- this.#allTabs = [...verticalPinnedTabsContainer.children, ...children];
+ this.#allTabs = [...document.getElementById("zen-essentials-container").children, ...verticalPinnedTabsContainer.children, ...children];
return this.#allTabs;
}
@@ -1480,7 +1481,7 @@
let rect = ele => {
return window.windowUtils.getBoundsWithoutFlushing(ele);
};
- let tab = this._getVisibleTabs()[gBrowser._numPinnedTabs];
+ let tab = this._getVisibleTabs()[gBrowser._numVisiblePinTabs];
if (tab && rect(tab).width <= this._tabClipWidth) {
this.setAttribute("closebuttons", "activetab");
} else {
@@ -1499,10 +1500,12 @@
@@ -1520,10 +1521,12 @@
_handleTabSelect(aInstant) {
let selectedTab = this.selectedItem;
@@ -64,16 +64,16 @@ index f3a2f226a9056c5a75023281fdeb704cec49b4a6..ae808f0f16466edc3d5f70271cc40c80
selectedTab._notselectedsinceload = false;
}
@@ -1550,7 +1553,7 @@
@@ -1571,7 +1574,7 @@
if (isEndTab && !this._hasTabTempMaxWidth) {
return;
}
- let numPinned = gBrowser._numPinnedTabs;
- let numPinned = gBrowser.pinnedTabCount;
+ let numPinned = gBrowser._numVisiblePinTabs;
// Force tabs to stay the same width, unless we're closing the last tab,
// which case we need to let them expand just enough so that the overall
// tabbar width is the same.
@@ -1565,7 +1568,7 @@
@@ -1586,7 +1589,7 @@
let tabsToReset = [];
for (let i = numPinned; i < tabs.length; i++) {
let tab = tabs[i];
@@ -82,16 +82,15 @@ index f3a2f226a9056c5a75023281fdeb704cec49b4a6..ae808f0f16466edc3d5f70271cc40c80
if (!isEndTab) {
// keep tabs the same width
tab.style.transition = "none";
@@ -1630,13 +1633,13 @@
@@ -1651,13 +1654,13 @@
let verticalTabsContainer = document.getElementById(
"vertical-pinned-tabs-container"
);
- let numPinned = gBrowser._numPinnedTabs;
- let numPinned = gBrowser.pinnedTabCount;
+ let numPinned = gBrowser._numVisiblePinTabs;
- if (gBrowser._numPinnedTabs !== verticalTabsContainer.children.length) {
+ if (gBrowser._numVisiblePinTabs !== verticalTabsContainer.children.length) {
let tabs = this._getVisibleTabs();
if (gBrowser.pinnedTabCount !== verticalTabsContainer.children.length) {
let tabs = this.visibleTabs;
for (let i = 0; i < numPinned; i++) {
tabs[i].style.marginInlineStart = "";
- verticalTabsContainer.appendChild(tabs[i]);
@@ -99,26 +98,35 @@ index f3a2f226a9056c5a75023281fdeb704cec49b4a6..ae808f0f16466edc3d5f70271cc40c80
}
}
@@ -1660,7 +1663,7 @@
@@ -1681,7 +1684,7 @@
_positionPinnedTabs() {
let tabs = this._getVisibleTabs();
- let numPinned = gBrowser._numPinnedTabs;
let tabs = this.visibleTabs;
- let numPinned = gBrowser.pinnedTabCount;
+ let numPinned = gBrowser._numVisiblePinTabs;
let absPositionHorizontalTabs =
this.overflowing && tabs.length > numPinned && numPinned > 0;
@@ -1934,7 +1937,7 @@
@@ -1762,7 +1765,7 @@
return;
}
- let tabs = this.visibleTabs.slice(0, gBrowser.pinnedTabCount);
+ let tabs = this.visibleTabs.slice(0, gBrowser._numVisiblePinTabs);
let directionX = screenX > dragData.animLastScreenX;
let directionY = screenY > dragData.animLastScreenY;
@@ -1948,7 +1951,7 @@
}
let pinned = draggedTab.pinned;
- let numPinned = gBrowser._numPinnedTabs;
- let numPinned = gBrowser.pinnedTabCount;
+ let numPinned = gBrowser._numVisiblePinTabs;
let tabs = this._getVisibleTabs().slice(
let tabs = this.visibleTabs.slice(
pinned ? 0 : numPinned,
pinned ? numPinned : undefined
@@ -2059,8 +2062,8 @@
}
@@ -2140,8 +2143,8 @@
);
}
- _finishAnimateTabMove() {
@@ -128,15 +136,3 @@ index f3a2f226a9056c5a75023281fdeb704cec49b4a6..ae808f0f16466edc3d5f70271cc40c80
return;
}
@@ -2218,9 +2221,9 @@
function newIndex(aTab, index) {
// Don't allow mixing pinned and unpinned tabs.
if (aTab.pinned) {
- return Math.min(index, gBrowser._numPinnedTabs - 1);
+ return Math.min(index, gBrowser._numVisiblePinTabs - 1);
}
- return Math.max(index, gBrowser._numPinnedTabs);
+ return Math.max(index, gBrowser._numVisiblePinTabs);
}
}

View File

@@ -31,11 +31,11 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<div class="page" id="welcome">
<img class="icon" src="chrome://branding/content/about-logo.png" />
<h1 data-l10n-id="welcome-dialog-welcome"></h1>
<p data-l10n-id="welcome-dialog-welcome-subtext"></p>
</div>
<div class="page page-split" id="import">
<div>
<h1 data-l10n-id="welcome-dialog-import"></h1>
@@ -51,7 +51,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
</hbox>
</div>
</div>
<div class="page page-split" id="theme">
<div>
<h1 data-l10n-id="welcome-dialog-theme"></h1>
@@ -120,11 +120,11 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<rect width="700" height="700" fill="white"/>
</clipPath>
</defs>
</svg>
</svg>
</div>
</div>
</div>
<div class="page page-split" id="search">
<div>
<h1 data-l10n-id="welcome-dialog-search"></h1>
@@ -134,7 +134,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<div id="searchList" class="cardGroup"></div>
</div>
</div>
<div class="page" id="thanks">
<h1 data-l10n-id="welcome-dialog-thanks"></h1>
<p data-l10n-id="welcome-dialog-thanks-subtext"></p>

View File

@@ -1,8 +1,8 @@
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
index da760e143740a166df14d055cf3ec7b095b93d10..093dacee4356d4084432d53639873e3da006dd94 100644
index 861ba1c484a4688857a3025455532ea9551b616a..570ac5122f50275d40e4deeeda0caeb577ee1bfd 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -377,17 +377,17 @@ bin/libfreebl_64int_3.so
@@ -384,17 +384,17 @@ bin/libfreebl_64int_3.so
; [MaintenanceService]
;
#ifdef MOZ_MAINTENANCE_SERVICE
@@ -24,12 +24,3 @@ index da760e143740a166df14d055cf3ec7b095b93d10..093dacee4356d4084432d53639873e3d
#if defined(XP_WIN)
@BINPATH@/@DLL_PREFIX@mozwer@DLL_SUFFIX@
#endif
@@ -397,7 +397,7 @@ bin/libfreebl_64int_3.so
; [ minidump-analyzer ]
;
#ifdef MOZ_CRASHREPORTER
-@BINPATH@/minidump-analyzer@BIN_SUFFIX@
+;@BINPATH@/minidump-analyzer@BIN_SUFFIX@
#endif
; [ Ping Sender ]

View File

@@ -0,0 +1,15 @@
diff --git a/browser/locales/en-US/browser/editBookmarkOverlay.ftl b/browser/locales/en-US/browser/editBookmarkOverlay.ftl
index da74660e48620fe9097d05a51ba4be34f21246e6..d70b98c71ca3a70732c633d939079f9fb589726f 100644
--- a/browser/locales/en-US/browser/editBookmarkOverlay.ftl
+++ b/browser/locales/en-US/browser/editBookmarkOverlay.ftl
@@ -37,6 +37,10 @@ bookmark-overlay-tags-2 =
.value = Tags
.accesskey = T
+zen-bookmark-edit-panel-workspace-selector =
+ .value = Workspaces
+ .accesskey = W
+
bookmark-overlay-tags-empty-description =
.placeholder = Separate tags with commas

View File

@@ -11,7 +11,7 @@ index f2171eb033a1143870f4708c63f565fabb535c4b..4280bc4b0f7cdbd94179fa2111f8001a
}
@@ -196,6 +194,31 @@ body {
transition: 0.8s margin-top ease-out;
border-bottom-color: var(--chrome-content-separator-color);
}
+

View File

@@ -0,0 +1,10 @@
diff --git a/browser/themes/shared/light-dark-overrides.css b/browser/themes/shared/light-dark-overrides.css
index 8b10da7c3ccbbfca30f77e2b7602794dccbf306d..f9188accee0e02d3ef6944b155da613fa6bd335d 100644
--- a/browser/themes/shared/light-dark-overrides.css
+++ b/browser/themes/shared/light-dark-overrides.css
@@ -5,5 +5,4 @@
#urlbar {
--urlbar-box-bgcolor: var(--toolbar-field-focus-background-color);
--urlbar-box-focus-bgcolor: var(--button-background-color);
- --urlbar-box-hover-bgcolor: var(--button-background-color-hover);
}

View File

@@ -0,0 +1,59 @@
diff --git a/browser/themes/shared/places/editBookmark.css b/browser/themes/shared/places/editBookmark.css
index 4c00982e620f4cfd5aa1d97d45a276f5d41d0d74..58018015d6046895c996f808785ab7282e5fed81 100644
--- a/browser/themes/shared/places/editBookmark.css
+++ b/browser/themes/shared/places/editBookmark.css
@@ -158,3 +158,53 @@
font-size: 0.9em;
margin: 2px 4px;
}
+
+/*Bookmark workspace selector styles*/
+.workspace-dropdown {
+ position: relative;
+ width: 100%;
+ display: flex;
+ gap: 16px;
+}
+
+.workspace-trigger {
+ width: 100%;
+ text-align: left;
+ padding: 8px 12px;
+ border: 1px solid var(--card-outline-color);
+ border-radius: 4px;
+ background-color: var(--zen-colors-tertiary);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.workspace-list {
+ flex-direction: column;
+ width: 100%;
+ max-height: 200px;
+ overflow-y: auto;
+ margin-top: 4px;
+ border: 1px solid var(--card-outline-color);
+ border-radius: 4px;
+ background-color: var(--zen-colors-tertiary);
+ box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
+ padding: 4px 0;
+}
+
+.workspace-list li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.workspace-list li > label {
+ display: flex;
+ align-items: center;
+ padding: 4px 12px;
+ cursor: pointer;
+}
+
+.workspace-list input[type="checkbox"] {
+ margin-right: 8px;
+}
\ No newline at end of file

View File

@@ -3,9 +3,9 @@ index d48aad3a397909056ee43be4e65797875e80b772..d9728867a69a935caf2176d492a7aa78
--- a/browser/themes/shared/tabbrowser/tabs.css
+++ b/browser/themes/shared/tabbrowser/tabs.css
@@ -26,7 +26,7 @@
--tab-icon-end-margin: 5.5px;
--tab-icon-overlay-fill: light-dark(black, white);
--tab-icon-overlay-stroke: light-dark(white, black);
--tab-icon-overlay-fill: light-dark(white, black);
--tab-icon-overlay-stroke: light-dark(black, white);
--tab-label-line-height: 1.7;
- --tab-loading-fill: #0A84FF;
+ --tab-loading-fill: var(--zen-primary-color);
--tab-hover-background-color: color-mix(in srgb, currentColor 11%, transparent);
@@ -20,7 +20,7 @@ index d48aad3a397909056ee43be4e65797875e80b772..d9728867a69a935caf2176d492a7aa78
+
}
#tabbrowser-tabs[movingtab] > #tabbrowser-arrowscrollbox > &:is([selected], [multiselected]) {
#tabbrowser-tabs[movingtab] &:is([selected], [multiselected]) {
@@ -498,14 +497,14 @@
}

View File

@@ -1,5 +1,5 @@
diff --git a/toolkit/themes/shared/in-content/common-shared.css b/toolkit/themes/shared/in-content/common-shared.css
index 2b59a0604b4bfefd3bdcfdb9a3964937e9699114..d9f5f81158790336c7fa5ad366fd815abfe67087 100644
index 646a11b699a0b34204cd766836678bfc17e8548e..14ebf803000ccea0de7c4f09ed2a9528bb017778 100644
--- a/toolkit/themes/shared/in-content/common-shared.css
+++ b/toolkit/themes/shared/in-content/common-shared.css
@@ -5,6 +5,8 @@
@@ -11,7 +11,7 @@ index 2b59a0604b4bfefd3bdcfdb9a3964937e9699114..d9f5f81158790336c7fa5ad366fd815a
@namespace html "http://www.w3.org/1999/xhtml";
@namespace xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@@ -63,7 +65,7 @@
@@ -54,7 +56,7 @@
--in-content-table-border-color: var(--in-content-box-border-color);
--in-content-table-header-background: var(--in-content-primary-button-background);
--in-content-table-header-color: var(--in-content-primary-button-text-color);
@@ -20,12 +20,20 @@ index 2b59a0604b4bfefd3bdcfdb9a3964937e9699114..d9f5f81158790336c7fa5ad366fd815a
--dialog-warning-text-color: var(--red-60);
@@ -791,7 +793,8 @@ html|*#categories > html|*.category:dir(rtl) {
@@ -740,7 +742,6 @@ html|*#categories {
color: inherit;
margin-inline-start: 34px;
padding-inline: 10px;
- transition: background-color 150ms;
}
html|*#categories > html|*.category {
@@ -777,7 +778,8 @@ html|*#categories > html|*.category:dir(rtl) {
@media not (forced-colors) {
#categories > .category[selected],
#categories > .category.selected {
- color: var(--in-content-accent-color);
+ /*color: var(--in-content-accent-color);*/
- color: var(--color-accent-primary);
+ /*color: var(--color-accent-primary);*/
+ opacity: .7;
}

View File

@@ -5,7 +5,7 @@
"binaryName": "zen",
"version": {
"product": "firefox",
"version": "132.0.2"
"version": "133.0"
},
"buildOptions": {
"generateBranding": true
@@ -18,7 +18,7 @@
"brandShortName": "Zen Browser",
"brandFullName": "Zen Browser",
"release": {
"displayVersion": "1.0.1-a.20",
"displayVersion": "1.0.1-a.22",
"github": {
"repo": "zen-browser/desktop"
},
@@ -40,7 +40,7 @@
"brandShortName": "Zen Twilight",
"brandFullName": "Zen Twilight",
"release": {
"displayVersion": "1.0.1-t.20",
"displayVersion": "1.0.1-t.22",
"github": {
"repo": "zen-browser/desktop"
}
@@ -54,4 +54,4 @@
"licenseType": "MPL-2.0"
},
"updateHostname": "updates.zen-browser.app"
}
}