Compare commits

..

35 Commits

Author SHA1 Message Date
mr. m
3655afbe13 gh-15089: Prevent folder expansion on sync (gh-15197) 2026-09-02 02:29:59 +02:00
mr. m
bb023ac5b1 gh-15191: Fixed collapse indicator still showing when deleting a folder (gh-15192) 2026-09-01 13:51:06 +02:00
mr. m
faafff667e gh-15144: Fixed installing updates does not updating registries (gh-15181) 2026-09-01 02:07:53 +02:00
Nikola Hristov
8b632c9b05 gh-15182: Fix tab changing when handling tab close when group collapses (gh-15183) 2026-08-31 20:52:19 +02:00
mr. m
67b6daaa0e gh-15177: Improve on-boarding experience and new space form UX (gh-15178) 2026-08-31 02:52:10 +02:00
mr. m
e89bd7796e gh-15154: Fixed stale containers trying to sync across devices (gh-15166) 2026-08-30 00:42:45 +02:00
mr. m
66c5931a29 gh-15163: Sync upstream Firefox to version 155.0 RC (gh-15164) 2026-08-30 00:26:45 +02:00
Fernando Omori
a5585c5619 gh-14380: Fix sidebar width getting stuck when toggling layout on the right side (gh-15092) 2026-08-29 12:35:31 +02:00
mr. m
2326d2b56b gh-15157: Add support for squircles on the Chrome UI (gh-14009) 2026-08-29 12:35:17 +02:00
mr. m
9ef1d96c00 Revert "gh-15144: Update windows registry on update" (gh-15153) 2026-08-29 01:34:29 +02:00
Nikola Hristov
432f93770f gh-15146: Fix bad current view index after removing a group (gh-15147) 2026-08-28 19:58:05 +02:00
mr. m
f28e0688fb gh-15144: Update windows registry on update (gh-15145) 2026-08-28 11:55:40 +02:00
Nikola Hristov
8df6fef1ac gh-15115: Tests for urlbar close and split view (gh-15118)
Co-authored-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
2026-08-27 23:45:37 +02:00
mr. m
4746d36699 gh-15088: Prevent sync if engine is already applying (gh-15137) 2026-08-27 23:38:47 +02:00
Nikola Hristov
9e0c790602 gh-15134: Fixes tab removed from group getting focused (gh-15135)
Closes https://github.com/zen-browser/desktop/issues/15134

Fix video:

https://github.com/user-attachments/assets/1c06ea7f-d482-4d4a-8bbe-df41daa27616
2026-08-27 22:40:43 +02:00
mr. m
3d53b37e8b gh-15119: Update windows registry with old certificates (gh-15120) 2026-08-26 17:51:09 +02:00
Nikola Hristov
e7ddfb52db gh-15115: Fix creating empty split view with url bar open (gh-15116) 2026-08-26 13:16:13 +02:00
mr. m
ba70449bdd gh-15088: Add debug log for space sync (gh-15117) 2026-08-26 12:23:52 +02:00
mr. m
bf40c31149 gh-14710: Fixed minimizing PiP window failing to collapse into the sidebar (gh-15111) 2026-08-26 08:30:00 +02:00
mr. m
7a093beae4 gh-15084: Fixed incoming tab icons applying to active tabs (gh-15107) 2026-08-25 22:31:50 +02:00
mr. m
03b4e934fe gh-15091: Fixed race condition when syncing new space and container (gh-15106) 2026-08-25 22:21:19 +02:00
mr. m
b93d19b873 gh-15088: Fixed syncing essentials with different containers (gh-15105) 2026-08-25 22:05:54 +02:00
mr. m
b9c4000fe2 gh-15101: Sync upstream Firefox to version 154.0.1 (gh-15100) 2026-08-25 19:37:07 +02:00
mr. m
0b7687ec6d gh-14990: Prevent policyContainer from bloating the session file (gh-15098) 2026-08-25 13:41:10 +02:00
mr. m
d70b3d902c gh-15085: Import mochitests for remote settings (gh-15086) 2026-08-24 22:52:33 +02:00
mr. m
f9f8f2f372 gh-15075: Fixed syncing new tabs not using static labels (gh-15079)
Fixes https://github.com/zen-browser/desktop/issues/15075
2026-08-24 18:27:50 +02:00
mr. m
99dca42723 gh-14470: Prevent state override if url changed (gh-15070) 2026-08-23 16:40:30 +02:00
Henrik Nyh
ed0a6fd447 gh-15039: Use Title Case for split view labels (gh-15059) 2026-08-23 12:21:34 +02:00
CocoLng
88c6611f1e gh-15039: Fix New Blank Window menu entry not in Title Case (gh-15056) 2026-08-22 10:08:37 +02:00
mr. m
e66e763e63 gh-14470: Fixed wrong data image being used for sync (gh-15048) 2026-08-21 09:44:49 +02:00
mr. m
721135f576 gh-14470: Fixed moz-remote-urls not being synced correctly (gh-15043) 2026-08-21 01:24:25 +02:00
mr. m
d8a934d2ec gh-15029: Fixed urlbar suggestion context not working (gh-15037) 2026-08-20 21:57:35 +02:00
mr. m
91a1d4d2ca gh-14470: Run sweep animation on first sync (gh-15036) 2026-08-20 21:38:09 +02:00
mr. m
97577dac26 gh-15031: Fixed duplicate separator on tab context menu (gh-15035) 2026-08-20 21:18:13 +02:00
Kristijan Ribarić
5723a89bcd gh-14470: Add tab and folder sync support (gh-13984)
Co-authored-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
2026-08-20 19:16:13 +02:00
649 changed files with 88889 additions and 2563 deletions

2
.gitattributes vendored
View File

@@ -5,4 +5,4 @@
*.patch linguist-language=C++ *.patch linguist-language=C++
*.d.ts linguist-language=TypeScript *.d.ts linguist-language=TypeScript
src/zen/tests/*.js linguist-language=Test src/zen/tests/** linguist-language=C++

View File

@@ -26,6 +26,11 @@ on:
required: true required: true
type: "boolean" type: "boolean"
default: false default: false
disable-pgo:
description: "Build without PGO (skips the profile generation stages)"
required: false
type: "boolean"
default: false
workflow_call: workflow_call:
inputs: inputs:
create_release: create_release:
@@ -48,6 +53,11 @@ on:
required: true required: true
type: "boolean" type: "boolean"
default: false default: false
disable-pgo:
description: "Build without PGO (skips the profile generation stages)"
required: false
type: "boolean"
default: false
jobs: jobs:
buildid: buildid:
@@ -73,6 +83,7 @@ jobs:
echo "create_release: ${{ inputs.create_release }}" echo "create_release: ${{ inputs.create_release }}"
echo "update_version: ${{ inputs.update_version }}" echo "update_version: ${{ inputs.update_version }}"
echo "use sccache: ${{ inputs.use-sccache }}" echo "use sccache: ${{ inputs.use-sccache }}"
echo "disable-pgo: ${{ inputs.disable-pgo }}"
echo "update_branch: ${{ inputs.update_branch }}" echo "update_branch: ${{ inputs.update_branch }}"
echo "GITHUB_REPOSITORY: ${{ github.repository }}" echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}" echo "GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}"
@@ -102,14 +113,14 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Download aws-cli - name: Download aws-cli
if: ${{ inputs.create_release && inputs.update_branch == 'release' }} if: ${{ inputs.update_branch == 'release' }}
run: | run: |
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip unzip awscliv2.zip
sudo ./aws/install --update sudo ./aws/install --update
- name: Start self-hosted runner - name: Start self-hosted runner
if: ${{ inputs.create_release && inputs.update_branch == 'release' }} if: ${{ inputs.update_branch == 'release' }}
run: | run: |
echo "Starting self-hosted runner" echo "Starting self-hosted runner"
echo "${{ secrets.SELF_HOSTED_RUNNER_START_SCRIPT }}" | base64 -d > start.sh echo "${{ secrets.SELF_HOSTED_RUNNER_START_SCRIPT }}" | base64 -d > start.sh
@@ -117,7 +128,7 @@ jobs:
bash ./start.sh bash ./start.sh
- name: Remove self-hosted runner script - name: Remove self-hosted runner script
if: always() && ${{ inputs.create_release && inputs.update_branch == 'release' }} if: always() && ${{ inputs.update_branch == 'release' }}
run: | run: |
echo "Removing self-hosted runner script" echo "Removing self-hosted runner script"
rm start.sh || true rm start.sh || true
@@ -280,12 +291,14 @@ jobs:
windows-step-1: windows-step-1:
name: Windows build step 1 (PGO build) name: Windows build step 1 (PGO build)
uses: ./.github/workflows/windows-release-build.yml uses: ./.github/workflows/windows-release-build.yml
if: ${{ !inputs.disable-pgo }}
needs: [build-data, buildid] needs: [build-data, buildid]
permissions: permissions:
contents: write contents: write
secrets: inherit secrets: inherit
with: with:
use-sccache: ${{ inputs.use-sccache }} use-sccache: ${{ inputs.use-sccache }}
force-candidate: ${{ !inputs.create_release }}
build-version: ${{ needs.build-data.outputs.version }} build-version: ${{ needs.build-data.outputs.version }}
generate-pgo: true generate-pgo: true
profile-data-path-archive: zen-windows-profile-data-and-jarlog.zip profile-data-path-archive: zen-windows-profile-data-and-jarlog.zip
@@ -295,11 +308,13 @@ jobs:
windows-step-2: windows-step-2:
name: Windows build step 2 (Generate profile data) name: Windows build step 2 (Generate profile data)
uses: ./.github/workflows/windows-profile-build.yml uses: ./.github/workflows/windows-profile-build.yml
if: ${{ !inputs.disable-pgo }}
permissions: permissions:
contents: write contents: write
secrets: inherit secrets: inherit
needs: [windows-step-1, build-data] needs: [windows-step-1, build-data]
with: with:
force-candidate: ${{ !inputs.create_release }}
build-version: ${{ needs.build-data.outputs.version }} build-version: ${{ needs.build-data.outputs.version }}
profile-data-path-archive: zen.win64-pgo-stage-1.zip profile-data-path-archive: zen.win64-pgo-stage-1.zip
release-branch: ${{ inputs.update_branch }} release-branch: ${{ inputs.update_branch }}
@@ -310,10 +325,14 @@ jobs:
permissions: permissions:
contents: write contents: write
secrets: inherit secrets: inherit
# windows-step-2 is skipped when PGO is disabled, so don't inherit its skip
if: ${{ !failure() && !cancelled() }}
needs: [build-data, windows-step-2, start-self-host, buildid] needs: [build-data, windows-step-2, start-self-host, buildid]
with: with:
force-candidate: ${{ !inputs.create_release }}
build-version: ${{ needs.build-data.outputs.version }} build-version: ${{ needs.build-data.outputs.version }}
generate-pgo: false generate-pgo: false
disable-pgo: ${{ inputs.disable-pgo }}
release-branch: ${{ inputs.update_branch }} release-branch: ${{ inputs.update_branch }}
MOZ_BUILD_DATE: ${{needs.buildid.outputs.buildids}} MOZ_BUILD_DATE: ${{needs.buildid.outputs.buildids}}
use-sccache: ${{ inputs.use-sccache }} use-sccache: ${{ inputs.use-sccache }}
@@ -326,20 +345,24 @@ jobs:
secrets: inherit secrets: inherit
needs: [build-data, start-self-host, buildid] needs: [build-data, start-self-host, buildid]
with: with:
force-candidate: ${{ !inputs.create_release }}
build-version: ${{ needs.build-data.outputs.version }} build-version: ${{ needs.build-data.outputs.version }}
release-branch: ${{ inputs.update_branch }} release-branch: ${{ inputs.update_branch }}
MOZ_BUILD_DATE: ${{needs.buildid.outputs.buildids}} MOZ_BUILD_DATE: ${{needs.buildid.outputs.buildids}}
use-sccache: ${{ inputs.use-sccache }} use-sccache: ${{ inputs.use-sccache }}
disable-pgo: ${{ inputs.disable-pgo }}
mac-step-1: mac-step-1:
name: macOS build step 1 (PGO build) name: macOS build step 1 (PGO build)
uses: ./.github/workflows/macos-release-build.yml uses: ./.github/workflows/macos-release-build.yml
if: ${{ !inputs.disable-pgo }}
needs: [build-data, buildid] needs: [build-data, buildid]
permissions: permissions:
contents: write contents: write
secrets: inherit secrets: inherit
with: with:
use-sccache: ${{ inputs.use-sccache }} use-sccache: ${{ inputs.use-sccache }}
force-candidate: ${{ !inputs.create_release }}
build-version: ${{ needs.build-data.outputs.version }} build-version: ${{ needs.build-data.outputs.version }}
generate-pgo: true generate-pgo: true
release-branch: ${{ inputs.update_branch }} release-branch: ${{ inputs.update_branch }}
@@ -348,11 +371,13 @@ jobs:
mac-step-2: mac-step-2:
name: macOS build step 2 (Generate profile data) name: macOS build step 2 (Generate profile data)
uses: ./.github/workflows/macos-profile-build.yml uses: ./.github/workflows/macos-profile-build.yml
if: ${{ !inputs.disable-pgo }}
permissions: permissions:
contents: write contents: write
secrets: inherit secrets: inherit
needs: [mac-step-1, build-data] needs: [mac-step-1, build-data]
with: with:
force-candidate: ${{ !inputs.create_release }}
build-version: ${{ needs.build-data.outputs.version }} build-version: ${{ needs.build-data.outputs.version }}
release-branch: ${{ inputs.update_branch }} release-branch: ${{ inputs.update_branch }}
@@ -362,10 +387,14 @@ jobs:
permissions: permissions:
contents: write contents: write
secrets: inherit secrets: inherit
# mac-step-2 is skipped when PGO is disabled, so don't inherit its skip
if: ${{ !failure() && !cancelled() }}
needs: [build-data, mac-step-2, start-self-host, buildid] needs: [build-data, mac-step-2, start-self-host, buildid]
with: with:
force-candidate: ${{ !inputs.create_release }}
build-version: ${{ needs.build-data.outputs.version }} build-version: ${{ needs.build-data.outputs.version }}
generate-pgo: false generate-pgo: false
disable-pgo: ${{ inputs.disable-pgo }}
release-branch: ${{ inputs.update_branch }} release-branch: ${{ inputs.update_branch }}
MOZ_BUILD_DATE: ${{needs.buildid.outputs.buildids}} MOZ_BUILD_DATE: ${{needs.buildid.outputs.buildids}}
use-sccache: ${{ inputs.use-sccache }} use-sccache: ${{ inputs.use-sccache }}
@@ -378,6 +407,7 @@ jobs:
secrets: inherit secrets: inherit
needs: [build-data, mac-step-3] needs: [build-data, mac-step-3]
with: with:
force-candidate: ${{ !inputs.create_release }}
build-version: ${{ needs.build-data.outputs.version }} build-version: ${{ needs.build-data.outputs.version }}
release-branch: ${{ inputs.update_branch }} release-branch: ${{ inputs.update_branch }}
@@ -470,14 +500,14 @@ jobs:
if: always() if: always()
steps: steps:
- name: Download aws-cli - name: Download aws-cli
if: ${{ inputs.create_release && inputs.update_branch == 'release' }} if: ${{ inputs.update_branch == 'release' }}
run: | run: |
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip unzip awscliv2.zip
sudo ./aws/install --update sudo ./aws/install --update
- name: Stop self-hosted runner - name: Stop self-hosted runner
if: ${{ inputs.create_release && inputs.update_branch == 'release' }} if: ${{ inputs.update_branch == 'release' }}
run: | run: |
echo "Stopping self-hosted runner" echo "Stopping self-hosted runner"
echo "${{ secrets.SELF_HOSTED_RUNNER_STOP_SCRIPT }}" | base64 -d > stop.sh echo "${{ secrets.SELF_HOSTED_RUNNER_STOP_SCRIPT }}" | base64 -d > stop.sh
@@ -485,13 +515,12 @@ jobs:
bash ./stop.sh > /dev/null bash ./stop.sh > /dev/null
- name: Remove self-hosted runner script - name: Remove self-hosted runner script
if: always() && ${{ inputs.create_release && inputs.update_branch == 'release' }} if: always() && ${{ inputs.update_branch == 'release' }}
run: | run: |
echo "Removing self-hosted runner script" echo "Removing self-hosted runner script"
rm stop.sh || true rm stop.sh || true
release: release:
if: ${{ inputs.create_release || inputs.update_branch == 'twilight' }}
permissions: write-all permissions: write-all
name: Release name: Release
needs: needs:
@@ -585,6 +614,7 @@ jobs:
- name: Commit - name: Commit
uses: stefanzweifel/git-auto-commit-action@v5 uses: stefanzweifel/git-auto-commit-action@v5
if: ${{ inputs.create_release || inputs.update_branch == 'twilight' }}
with: with:
commit_message: 🚀 Update update manifests commit_message: 🚀 Update update manifests
commit_user_name: Zen Browser Robot commit_user_name: Zen Browser Robot
@@ -628,9 +658,22 @@ jobs:
env: env:
GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_REPOSITORY: ${{ github.repository }}
- name: Upload signed MAR files to workflow artifacts
if: ${{ inputs.update_branch == 'release' && !inputs.create_release }}
uses: actions/upload-artifact@v4
with:
retention-days: 5
name: signed-mar-files
path: |
./linux.mar/*
./linux-aarch64.mar/*
./.github/workflows/object/windows-x64-signed-x86_64/windows.mar
./.github/workflows/object/windows-x64-signed-arm64/windows-arm64.mar
./macos.mar/*
- name: Release - name: Release
uses: softprops/action-gh-release@v2.2.2 uses: softprops/action-gh-release@v2.2.2
if: ${{ inputs.update_branch == 'release' }} if: ${{ inputs.update_branch == 'release' && inputs.create_release }}
with: with:
token: ${{ secrets.DEPLOY_KEY }} token: ${{ secrets.DEPLOY_KEY }}
tag_name: ${{ needs.build-data.outputs.version }} tag_name: ${{ needs.build-data.outputs.version }}

View File

@@ -20,6 +20,19 @@ on:
required: true required: true
type: boolean type: boolean
default: false default: false
disable-pgo:
description: "Build without PGO at all"
required: false
type: boolean
default: false
force-candidate:
description: "Force building against the Firefox release candidate"
required: false
type: boolean
default: false
env:
SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }}
jobs: jobs:
build-linux: build-linux:
@@ -105,6 +118,8 @@ jobs:
SURFER_COMPAT: ${{ matrix.arch }} SURFER_COMPAT: ${{ matrix.arch }}
SURFER_CERT_PATCH_ISSUER: ${{ secrets.SURFER_CERT_PATCH_ISSUER }} SURFER_CERT_PATCH_ISSUER: ${{ secrets.SURFER_CERT_PATCH_ISSUER }}
SURFER_CERT_PATCH_NAME: ${{ secrets.SURFER_CERT_PATCH_NAME }} SURFER_CERT_PATCH_NAME: ${{ secrets.SURFER_CERT_PATCH_NAME }}
SURFER_CERT_PATCH_NAME_PREV: ${{ secrets.SURFER_CERT_PATCH_NAME_PREV }}
SURFER_CERT_PATCH_ISSUER_PREV: ${{ secrets.SURFER_CERT_PATCH_ISSUER_PREV }}
run: | run: |
. "$HOME/.cargo/env" . "$HOME/.cargo/env"
npm run import npm run import
@@ -120,7 +135,7 @@ jobs:
cd .. cd ..
- name: Build (PGO stage 1 - generate) - name: Build (PGO stage 1 - generate)
if: ${{ matrix.arch == 'x86_64' }} if: ${{ matrix.arch == 'x86_64' && !inputs.disable-pgo }}
env: env:
SURFER_COMPAT: ${{ matrix.arch }} SURFER_COMPAT: ${{ matrix.arch }}
ZEN_RELEASE_BRANCH: ${{ inputs.release-branch }} ZEN_RELEASE_BRANCH: ${{ inputs.release-branch }}
@@ -137,7 +152,7 @@ jobs:
bash .github/workflows/src/release-build.sh bash .github/workflows/src/release-build.sh
- name: Generate PGO profile data - name: Generate PGO profile data
if: ${{ matrix.arch == 'x86_64' }} if: ${{ matrix.arch == 'x86_64' && !inputs.disable-pgo }}
run: | run: |
set -x set -x
export DISPLAY=:2 export DISPLAY=:2
@@ -155,6 +170,7 @@ jobs:
env: env:
SURFER_COMPAT: ${{ matrix.arch }} SURFER_COMPAT: ${{ matrix.arch }}
ZEN_RELEASE_BRANCH: ${{ inputs.release-branch }} ZEN_RELEASE_BRANCH: ${{ inputs.release-branch }}
ZEN_GA_DISABLE_PGO: ${{ inputs.disable-pgo && '1' || '' }}
ZEN_SAFEBROWSING_API_KEY: ${{ secrets.ZEN_SAFEBROWSING_API_KEY }} ZEN_SAFEBROWSING_API_KEY: ${{ secrets.ZEN_SAFEBROWSING_API_KEY }}
ZEN_MOZILLA_API_KEY: ${{ secrets.ZEN_MOZILLA_API_KEY }} ZEN_MOZILLA_API_KEY: ${{ secrets.ZEN_MOZILLA_API_KEY }}
ZEN_GOOGLE_LOCATION_SERVICE_API_KEY: ${{ secrets.ZEN_GOOGLE_LOCATION_SERVICE_API_KEY }} ZEN_GOOGLE_LOCATION_SERVICE_API_KEY: ${{ secrets.ZEN_GOOGLE_LOCATION_SERVICE_API_KEY }}

View File

@@ -14,6 +14,14 @@ on:
description: "The branch to build" description: "The branch to build"
required: true required: true
type: string type: string
force-candidate:
description: "Force building against the Firefox release candidate"
required: false
type: boolean
default: false
env:
SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }}
jobs: jobs:
macos-profile-build: macos-profile-build:

View File

@@ -10,6 +10,11 @@ on:
required: true required: true
type: boolean type: boolean
default: false default: false
disable-pgo:
description: "Build without PGO at all"
required: false
type: boolean
default: false
build-version: build-version:
description: "The version to build" description: "The version to build"
required: true required: true
@@ -27,6 +32,14 @@ on:
required: true required: true
type: boolean type: boolean
default: false default: false
force-candidate:
description: "Force building against the Firefox release candidate"
required: false
type: boolean
default: false
env:
SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }}
jobs: jobs:
mac-build: mac-build:
@@ -122,6 +135,8 @@ jobs:
SURFER_COMPAT: ${{ matrix.arch }} SURFER_COMPAT: ${{ matrix.arch }}
SURFER_CERT_PATCH_ISSUER: ${{ secrets.SURFER_CERT_PATCH_ISSUER }} SURFER_CERT_PATCH_ISSUER: ${{ secrets.SURFER_CERT_PATCH_ISSUER }}
SURFER_CERT_PATCH_NAME: ${{ secrets.SURFER_CERT_PATCH_NAME }} SURFER_CERT_PATCH_NAME: ${{ secrets.SURFER_CERT_PATCH_NAME }}
SURFER_CERT_PATCH_NAME_PREV: ${{ secrets.SURFER_CERT_PATCH_NAME_PREV }}
SURFER_CERT_PATCH_ISSUER_PREV: ${{ secrets.SURFER_CERT_PATCH_ISSUER_PREV }}
SURFER_PLATFORM: darwin SURFER_PLATFORM: darwin
run: | run: |
. "$HOME/.cargo/env" . "$HOME/.cargo/env"
@@ -138,13 +153,13 @@ jobs:
- name: Download artifact (if use profdata) - name: Download artifact (if use profdata)
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
if: ${{ !inputs.generate-pgo }} if: ${{ !inputs.generate-pgo && !inputs.disable-pgo }}
with: with:
path: ~/artifact path: ~/artifact
name: macos-profdata-${{ matrix.arch }} name: macos-profdata-${{ matrix.arch }}
- name: Show artifact info - name: Show artifact info
if: ${{ !inputs.generate-pgo }} if: ${{ !inputs.generate-pgo && !inputs.disable-pgo }}
run: | run: |
ls ~/artifact ls ~/artifact
ls ~/artifact/en-US.log ls ~/artifact/en-US.log
@@ -164,6 +179,9 @@ jobs:
if test ${{ inputs.generate-pgo }} = true; then if test ${{ inputs.generate-pgo }} = true; then
export ZEN_GA_GENERATE_PROFILE=1 export ZEN_GA_GENERATE_PROFILE=1
fi fi
if test ${{ inputs.disable-pgo }} = true; then
export ZEN_GA_DISABLE_PGO=1
fi
if [[ -n ${{ inputs.MOZ_BUILD_DATE }} ]];then if [[ -n ${{ inputs.MOZ_BUILD_DATE }} ]];then
export MOZ_BUILD_DATE=${{ inputs.MOZ_BUILD_DATE }} export MOZ_BUILD_DATE=${{ inputs.MOZ_BUILD_DATE }}
fi fi

View File

@@ -11,6 +11,14 @@ on:
description: "The branch to build" description: "The branch to build"
required: true required: true
type: string type: string
force-candidate:
description: "Force building against the Firefox release candidate"
required: false
type: boolean
default: false
env:
SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }}
jobs: jobs:
mac-build: mac-build:

View File

@@ -18,6 +18,14 @@ on:
description: "The branch to build" description: "The branch to build"
required: true required: true
type: string type: string
force-candidate:
description: "Force building against the Firefox release candidate"
required: false
type: boolean
default: false
env:
SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }}
jobs: jobs:
windows-profile-build: windows-profile-build:

View File

@@ -10,6 +10,11 @@ on:
required: true required: true
type: boolean type: boolean
default: false default: false
disable-pgo:
description: "Build without PGO at all"
required: false
type: boolean
default: false
build-version: build-version:
description: "The version to build" description: "The version to build"
required: true required: true
@@ -30,6 +35,13 @@ on:
required: true required: true
type: boolean type: boolean
default: false default: false
force-candidate:
description: "Force building against the Firefox release candidate"
required: false
type: boolean
default: false
env:
SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }}
jobs: jobs:
windows-build: windows-build:
@@ -166,6 +178,8 @@ jobs:
SURFER_COMPAT: ${{ matrix.arch }} SURFER_COMPAT: ${{ matrix.arch }}
SURFER_CERT_PATCH_ISSUER: ${{ secrets.SURFER_CERT_PATCH_ISSUER }} SURFER_CERT_PATCH_ISSUER: ${{ secrets.SURFER_CERT_PATCH_ISSUER }}
SURFER_CERT_PATCH_NAME: ${{ secrets.SURFER_CERT_PATCH_NAME }} SURFER_CERT_PATCH_NAME: ${{ secrets.SURFER_CERT_PATCH_NAME }}
SURFER_CERT_PATCH_NAME_PREV: ${{ secrets.SURFER_CERT_PATCH_NAME_PREV }}
SURFER_CERT_PATCH_ISSUER_PREV: ${{ secrets.SURFER_CERT_PATCH_ISSUER_PREV }}
run: | run: |
. "$HOME/.cargo/env" . "$HOME/.cargo/env"
npm run import -- --verbose npm run import -- --verbose
@@ -213,13 +227,13 @@ jobs:
- name: Download artifact (if use profdata) - name: Download artifact (if use profdata)
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
if: ${{ !inputs.generate-pgo && matrix.arch == 'x86_64' }} if: ${{ !inputs.generate-pgo && !inputs.disable-pgo && matrix.arch == 'x86_64' }}
with: with:
path: ~/artifact path: ~/artifact
name: windows-profdata-${{ matrix.arch == 'aarch64' && 'arm64' || matrix.arch }} name: windows-profdata-${{ matrix.arch == 'aarch64' && 'arm64' || matrix.arch }}
- name: Show artifact info - name: Show artifact info
if: ${{ !inputs.generate-pgo && matrix.arch == 'x86_64' }} if: ${{ !inputs.generate-pgo && !inputs.disable-pgo && matrix.arch == 'x86_64' }}
run: | run: |
ls ~/artifact ls ~/artifact
ls ~/artifact/en-US.log ls ~/artifact/en-US.log
@@ -244,6 +258,9 @@ jobs:
if test ${{ inputs.generate-pgo }} = true; then if test ${{ inputs.generate-pgo }} = true; then
export ZEN_GA_GENERATE_PROFILE=1 export ZEN_GA_GENERATE_PROFILE=1
fi fi
if test ${{ inputs.disable-pgo }} = true; then
export ZEN_GA_DISABLE_PGO=1
fi
if [[ -n ${{ inputs.MOZ_BUILD_DATE }} ]];then if [[ -n ${{ inputs.MOZ_BUILD_DATE }} ]];then
export MOZ_BUILD_DATE=${{ inputs.MOZ_BUILD_DATE }} export MOZ_BUILD_DATE=${{ inputs.MOZ_BUILD_DATE }}
fi fi

View File

@@ -34,8 +34,8 @@ Zen is a firefox-based browser with the aim of pushing your productivity to a ne
### Firefox Versions ### Firefox Versions
- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `154.0`! 🚀 - [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `154.0.1`!
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 154.0`! - [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 155.0`!
### Contributing ### Contributing

View File

@@ -1 +1 @@
1fb0703fa9723fd9c400ad60d18e64ee4f9bf125 6b4abe0093721c1be89eb41b3fb060dd6336923d

View File

@@ -3,8 +3,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
param( param(
[string][Parameter(Mandatory=$true)]$SignIdentity,
[string][Parameter(Mandatory=$true)]$SignIdentityIssuer,
[string][Parameter(Mandatory=$true)]$GithubRunId [string][Parameter(Mandatory=$true)]$GithubRunId
) )
@@ -24,11 +22,15 @@ mkdir windsign-temp -ErrorAction SilentlyContinue
# echo "Downloaded git objects repo to" # echo "Downloaded git objects repo to"
#} -Verbose -ArgumentList $PWD -Debug #} -Verbose -ArgumentList $PWD -Debug
$token = gh auth token
$env:SURFER_MOZCONFIG_ONLY="1" $env:SURFER_MOZCONFIG_ONLY="1"
$env:SURFER_SIGNING_MODE="" $env:SURFER_SIGNING_MODE=""
$env:SURFER_CERT_PATCH_ISSUER=$SignIdentityIssuer get-content "$PSScriptRoot/../.env" | foreach {
$env:SURFER_CERT_PATCH_NAME=$SignIdentity $name, $value = $_.split('=')
set-content env:\$name $value
}
Start-Job -Name "DownloadGitl10n" -ScriptBlock { Start-Job -Name "DownloadGitl10n" -ScriptBlock {
param($PWD) param($PWD)
@@ -46,7 +48,6 @@ npm run build
echo "Downloading artifacts info" echo "Downloading artifacts info"
$artifactsInfo=gh api repos/zen-browser/desktop/actions/runs/$GithubRunId/artifacts $artifactsInfo=gh api repos/zen-browser/desktop/actions/runs/$GithubRunId/artifacts
$token = gh auth token
function New-TemporaryDirectory { function New-TemporaryDirectory {
$tmp = [System.IO.Path]::GetTempPath() # Not $env:TEMP, see https://stackoverflow.com/a/946017 $tmp = [System.IO.Path]::GetTempPath() # Not $env:TEMP, see https://stackoverflow.com/a/946017

View File

@@ -64,6 +64,10 @@ zen-tabs-select-recently-used-on-close =
zen-tabs-close-on-back-with-no-history = zen-tabs-close-on-back-with-no-history =
.label = Close tab and switch to its owner tab (or most recently used tab) when going back with no history .label = Close tab and switch to its owner tab (or most recently used tab) when going back with no history
zen-settings-workspaces-sync =
.label = Sync your sidebar across devices
.description = Keep your workspaces, pinned tabs and folders in sync on all your devices through your Mozilla account.
zen-settings-workspaces-sync-unpinned-tabs = zen-settings-workspaces-sync-unpinned-tabs =
.label = Sync only pinned tabs in workspaces .label = Sync only pinned tabs in workspaces

View File

@@ -164,5 +164,5 @@ zen-window-sync-migration-dialog-learn-more = Learn More
zen-window-sync-migration-dialog-accept = Got It zen-window-sync-migration-dialog-accept = Got It
zen-appmenu-new-blank-window = zen-appmenu-new-blank-window =
.label = New blank window .label = New Blank Window

View File

@@ -5,14 +5,14 @@
tab-zen-split-tabs = tab-zen-split-tabs =
.label = .label =
{ $tabCount -> { $tabCount ->
[-1] Split out tab [-1] Split Out Tab
[1] Add split view... [1] Add Split View...
*[other] Join { $tabCount } Tabs *[other] Join { $tabCount } Tabs
} }
.accesskey = S .accesskey = S
zen-split-link = zen-split-link =
.label = Split link to new tab .label = Split Link to New Tab
.accesskey = S .accesskey = S
zen-split-view-modifier-header = Split View zen-split-view-modifier-header = Split View

View File

@@ -5,29 +5,28 @@
zen-welcome-title-line1 = Welcome to zen-welcome-title-line1 = Welcome to
zen-welcome-title-line2 = a calmer internet zen-welcome-title-line2 = a calmer internet
zen-welcome-import-title = A Fresh Start, Same Bookmarks zen-welcome-back = Back
zen-welcome-import-description-1 = Your bookmarks, history, and passwords are like a trail of breadcrumbs through the internet—dont leave them behind! zen-welcome-skip = Skip for now
zen-welcome-import-description-2 = Easily bring them over from another browser and pick up right where you left off.
zen-welcome-import-button = Import now
zen-welcome-set-default-browser = Set { -brand-short-name } as your default browser zen-welcome-import-title = Bring your stuff along.
zen-welcome-dont-set-default-browser = DONT set { -brand-short-name } as your default browser zen-welcome-import-description = Import your bookmarks, history and passwords from another browser and pick up right where you left off.
zen-welcome-import-yes = <strong>YES</strong>, import from another browser.
zen-welcome-import-no = <strong>NO</strong>, start fresh.
zen-welcome-initial-essentials-title = Your Key Tabs, Always Within Reach zen-welcome-default-browser-title = Make { -brand-short-name } your default?
zen-welcome-initial-essentials-description-1 = Keep your most important tabs easily accessible and always at hand, no matter how many you open. zen-welcome-default-browser-description = Links from other apps will open in { -brand-short-name }. You can always change this later.
zen-welcome-initial-essentials-description-2 = Essential tabs are always visible, no matter what workspace you are in. zen-welcome-set-default-browser = <strong>YES</strong>, make { -brand-short-name } default.
zen-welcome-dont-set-default-browser = <strong>NO</strong>, still exploring my options.
zen-welcome-workspace-colors-title = Your Workspaces, Your Colors zen-welcome-default-search-title = Pick your search engine.
zen-welcome-workspace-colors-description = Personalize your browser by giving each workspace its own unique color identity.
zen-welcome-start-browsing-title = All set?<br/>
Lets get rolling!
zen-welcome-start-browsing-description-1 = Youre all set up and ready to go. Click the button below to start browsing with { -brand-short-name }.
zen-welcome-start-browsing = Dive in!
zen-welcome-default-search-title = Your Default Search Engine
zen-welcome-default-search-description = Choose your default search engine. You can always change it later! zen-welcome-default-search-description = Choose your default search engine. You can always change it later!
zen-welcome-skip-button = Skip zen-welcome-essentials-title = Choose the apps you use most.
zen-welcome-essentials-description = Select your favorite apps to keep them handy in your sidebar.
zen-welcome-finished = Your Zen has been set up correctly! zen-welcome-workspace-colors-title = Your space, your colors.
zen-welcome-workspace-colors-description = Personalize your browser by giving each space its own unique color identity.
zen-welcome-start-browsing-title = All set? Lets get rolling!
zen-welcome-start-browsing-description-1 = Youre all set up and ready to go. Click the button below to start browsing with { -brand-short-name }.
zen-welcome-start-browsing = Dive in!

View File

@@ -86,6 +86,8 @@ zen-workspace-default-profile = Default
zen-workspaces-delete-workspace-title = Delete Space? zen-workspaces-delete-workspace-title = Delete Space?
zen-workspaces-delete-workspace-body = Are you sure you want to delete { $name }? This action cannot be undone. zen-workspaces-delete-workspace-body = Are you sure you want to delete { $name }? This action cannot be undone.
zen-workspaces-remote-delete-title = Delete Synced Space?
zen-workspaces-remote-delete-body = { $name } was deleted on another device. Delete it here too? Keeping it will restore it on your other devices.
# Note that the html tag MUST not be changed or removed, as it is used to better # Note that the html tag MUST not be changed or removed, as it is used to better
# display the shortcut in the toast notification. # display the shortcut in the toast notification.

8
package-lock.json generated
View File

@@ -11,7 +11,7 @@
"devDependencies": { "devDependencies": {
"@babel/preset-typescript": "^7.27.0", "@babel/preset-typescript": "^7.27.0",
"@zen-browser/prettier": "^3.9.3", "@zen-browser/prettier": "^3.9.3",
"@zen-browser/surfer": "^1.14.7", "@zen-browser/surfer": "^1.14.9",
"formal-git": "^1.2.9", "formal-git": "^1.2.9",
"globals": "^16.3.0", "globals": "^16.3.0",
"husky": "^9.1.7", "husky": "^9.1.7",
@@ -860,9 +860,9 @@
} }
}, },
"node_modules/@zen-browser/surfer": { "node_modules/@zen-browser/surfer": {
"version": "1.14.7", "version": "1.14.9",
"resolved": "https://registry.npmjs.org/@zen-browser/surfer/-/surfer-1.14.7.tgz", "resolved": "https://registry.npmjs.org/@zen-browser/surfer/-/surfer-1.14.9.tgz",
"integrity": "sha512-Ui2Chqvr4/+FmHM54eKOv7cQu8DRAK/uCX9o1GNi81hszxo/RSQwaw71eNW43Qcj7giK4U4x0IdCMht98iQ0rA==", "integrity": "sha512-XbMzG4GHSRoGzKR/DkpyywcbTYemieDRD1A6qgJ8CaVDixenj/uzMhp6HXAUksRTeh1u9j3lzNcVrI99axcZLw==",
"dev": true, "dev": true,
"license": "MPL-2.0", "license": "MPL-2.0",
"dependencies": { "dependencies": {

View File

@@ -49,7 +49,7 @@
"devDependencies": { "devDependencies": {
"@babel/preset-typescript": "^7.27.0", "@babel/preset-typescript": "^7.27.0",
"@zen-browser/prettier": "^3.9.3", "@zen-browser/prettier": "^3.9.3",
"@zen-browser/surfer": "^1.14.7", "@zen-browser/surfer": "^1.14.9",
"formal-git": "^1.2.9", "formal-git": "^1.2.9",
"globals": "^16.3.0", "globals": "^16.3.0",
"husky": "^9.1.7", "husky": "^9.1.7",

View File

@@ -95,6 +95,9 @@
- name: browser.search.widget.new - name: browser.search.widget.new
value: true value: true
- name: layout.css.corner-shape.enabled
value: true
# Disabled from https://searchfox.org/firefox-main/rev/d6bfff43852356ca98af848b4705d37f8d41856f/modules/libpref/init/StaticPrefList.yaml#2008 # Disabled from https://searchfox.org/firefox-main/rev/d6bfff43852356ca98af848b4705d37f8d41856f/modules/libpref/init/StaticPrefList.yaml#2008
# Only enabled for windows, doesn't really fit inside Zen. # Only enabled for windows, doesn't really fit inside Zen.
- name: browser.startup.preXulSkeletonUI - name: browser.startup.preXulSkeletonUI

View File

@@ -10,3 +10,6 @@
value: false value: false
locked: true locked: true
condition: "!@IS_TWILIGHT@" condition: "!@IS_TWILIGHT@"
- name: zen.spaces-sync.debug
value: false

View File

@@ -8,4 +8,4 @@ packaging==24.2
pathspec==0.12.1 pathspec==0.12.1
platformdirs==4.3.6 platformdirs==4.3.6
pycodestyle==2.12.1 pycodestyle==2.12.1
requests==2.33.0 requests==2.34.2

View File

@@ -1,8 +1,8 @@
diff --git a/.prettierignore b/.prettierignore diff --git a/.prettierignore b/.prettierignore
index 949896ff064ae0b54b6a657ea074bc88e12820f7..5249f420972667bece4d85fe8d35073afaebeb8a 100644 index bd8ab46ff7175f5039b69b04c1afe53ab8efe746..7ae12a1ff3724e99aeec2e93518640a2fa9611e6 100644
--- a/.prettierignore --- a/.prettierignore
+++ b/.prettierignore +++ b/.prettierignore
@@ -1803,3 +1803,12 @@ tools/ts/test/baselines/ @@ -1807,3 +1807,12 @@ tools/ts/test/baselines/
try_task_config.json try_task_config.json
xpcom/idl-parser/xpidl/fixtures/xpctest.d.json xpcom/idl-parser/xpidl/fixtures/xpctest.d.json
**/package-lock.json **/package-lock.json
@@ -12,6 +12,6 @@ index 949896ff064ae0b54b6a657ea074bc88e12820f7..5249f420972667bece4d85fe8d35073a
+*.min.js +*.min.js
+*.min.mjs +*.min.mjs
+*.inc +*.inc
+*/mochitests/* +**/mochitests/**
+*.svg +*.svg
+ +

View File

@@ -1,5 +1,5 @@
diff --git a/.stylelintrc.js b/.stylelintrc.js diff --git a/.stylelintrc.js b/.stylelintrc.js
index b484bf6600a7e1b8ad2aed8c8b7fe5e84cc3d023..f89712e2c13dfa0bcb48e55cd3872c67f5c98dad 100644 index b5f8245fa04ffb8fc82240261d63f893f4629f19..1b6ead24adbe69fcb5aeb95cfd3e7fa9662d89d8 100644
--- a/.stylelintrc.js --- a/.stylelintrc.js
+++ b/.stylelintrc.js +++ b/.stylelintrc.js
@@ -67,7 +67,7 @@ module.exports = { @@ -67,7 +67,7 @@ module.exports = {
@@ -11,10 +11,10 @@ index b484bf6600a7e1b8ad2aed8c8b7fe5e84cc3d023..f89712e2c13dfa0bcb48e55cd3872c67
{ {
ignore: ["blockless-at-rules"], ignore: ["blockless-at-rules"],
}, },
@@ -280,7 +280,7 @@ module.exports = { @@ -281,7 +281,7 @@ module.exports = {
"media-query-no-invalid": null,
"stylelint-plugin-mozilla/media-query-no-invalid": true, "stylelint-plugin-mozilla/media-query-no-invalid": true,
"stylelint-plugin-mozilla/no-base-design-tokens": true, "stylelint-plugin-mozilla/no-base-design-tokens": true,
"stylelint-plugin-mozilla/no-has-selector": true,
- "stylelint-plugin-mozilla/use-design-tokens": true, - "stylelint-plugin-mozilla/use-design-tokens": true,
+ "stylelint-plugin-mozilla/use-design-tokens": false, + "stylelint-plugin-mozilla/use-design-tokens": false,
}, },

View File

@@ -1,5 +1,5 @@
diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml
index dd2f391096968564086911c532f696dc7ffb8ae1..3de617bf4fb7fa35f7d4d7b618e4673b72b953ee 100644 index dd2f391096968564086911c532f696dc7ffb8ae1..c968e5f0ebb5f0151fb124bafe10d8d5361e060f 100644
--- a/browser/base/content/navigator-toolbox.inc.xhtml --- a/browser/base/content/navigator-toolbox.inc.xhtml
+++ b/browser/base/content/navigator-toolbox.inc.xhtml +++ b/browser/base/content/navigator-toolbox.inc.xhtml
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
@@ -19,7 +19,7 @@ index dd2f391096968564086911c532f696dc7ffb8ae1..3de617bf4fb7fa35f7d4d7b618e4673b
</toolbar> </toolbar>
+<hbox id="titlebar"> +<hbox id="titlebar">
+ <html:div id="zen-toolbar-background" class="zen-toolbar-background zen-browser-generic-background"> + <html:div id="zen-toolbar-background" class="zen-toolbar-background zen-squircle-before zen-squircle-after zen-browser-generic-background">
+ <html:div class="zen-browser-grain" /> + <html:div class="zen-browser-grain" />
+ </html:div> + </html:div>
+ <box id="zen-overflow-extensions-list" skipintoolbarset="true" contextmenu="toolbar-context-menu" /> + <box id="zen-overflow-extensions-list" skipintoolbarset="true" contextmenu="toolbar-context-menu" />

View File

@@ -15,19 +15,23 @@
mainview-with-header="true"> mainview-with-header="true">
<hbox id="zen-site-data-header"> <hbox id="zen-site-data-header">
<toolbarbutton id="zen-site-data-header-share" <toolbarbutton id="zen-site-data-header-share"
class="zen-squircle-before"
data-l10n-id="zen-site-data-header-share" data-l10n-id="zen-site-data-header-share"
flex="1" flex="1"
closemenu="none" /> closemenu="none" />
<toolbarbutton id="zen-site-data-header-reader-mode" <toolbarbutton id="zen-site-data-header-reader-mode"
class="zen-squircle-before"
data-l10n-id="zen-site-data-header-reader-mode" data-l10n-id="zen-site-data-header-reader-mode"
command="View:ReaderView" command="View:ReaderView"
tooltip="dynamic-shortcut-tooltip" tooltip="dynamic-shortcut-tooltip"
flex="1" /> flex="1" />
<toolbarbutton id="zen-site-data-header-screenshot" <toolbarbutton id="zen-site-data-header-screenshot"
class="zen-squircle-before"
data-l10n-id="zen-site-data-header-screenshot" data-l10n-id="zen-site-data-header-screenshot"
command="Browser:Screenshot" command="Browser:Screenshot"
flex="1" /> flex="1" />
<toolbarbutton id="zen-site-data-header-bookmark" <toolbarbutton id="zen-site-data-header-bookmark"
class="zen-squircle-before"
data-l10n-id="zen-site-data-header-bookmark" data-l10n-id="zen-site-data-header-bookmark"
command="Browser:AddBookmarkAs" command="Browser:AddBookmarkAs"
flex="1" /> flex="1" />

View File

@@ -14,14 +14,14 @@
<panelview id="PanelUI-zen-gradient-generator-view" class="PanelUI-subView zen-theme-picker" role="document" mainview-with-header="true" has-custom-header="true"> <panelview id="PanelUI-zen-gradient-generator-view" class="PanelUI-subView zen-theme-picker" role="document" mainview-with-header="true" has-custom-header="true">
<hbox class="zen-theme-picker-gradient"> <hbox class="zen-theme-picker-gradient">
<hbox id="PanelUI-zen-gradient-generator-scheme"> <hbox id="PanelUI-zen-gradient-generator-scheme">
<button id="PanelUI-zen-gradient-generator-scheme-auto" class="subviewbutton"/> <button id="PanelUI-zen-gradient-generator-scheme-auto" class="no-squircles subviewbutton"/>
<button id="PanelUI-zen-gradient-generator-scheme-light" class="subviewbutton"/> <button id="PanelUI-zen-gradient-generator-scheme-light" class="no-squircles subviewbutton"/>
<button id="PanelUI-zen-gradient-generator-scheme-dark" class="subviewbutton"/> <button id="PanelUI-zen-gradient-generator-scheme-dark" class="no-squircles subviewbutton"/>
</hbox> </hbox>
<hbox id="PanelUI-zen-gradient-generator-color-actions"> <hbox id="PanelUI-zen-gradient-generator-color-actions">
<button id="PanelUI-zen-gradient-generator-color-add" class="subviewbutton" /> <button id="PanelUI-zen-gradient-generator-color-add" class="no-squircles subviewbutton" />
<button id="PanelUI-zen-gradient-generator-color-remove" class="subviewbutton" /> <button id="PanelUI-zen-gradient-generator-color-remove" class="no-squircles subviewbutton" />
<button id="PanelUI-zen-gradient-generator-color-toggle-algo" class="subviewbutton" /> <button id="PanelUI-zen-gradient-generator-color-toggle-algo" class="no-squircles subviewbutton" />
</hbox> </hbox>
<label data-l10n-id="zen-panel-ui-gradient-click-to-add" id="PanelUI-zen-gradient-generator-color-click-to-add"></label> <label data-l10n-id="zen-panel-ui-gradient-click-to-add" id="PanelUI-zen-gradient-generator-color-click-to-add"></label>
</hbox> </hbox>
@@ -29,82 +29,82 @@
<toolbarbutton id="PanelUI-zen-gradient-generator-color-page-left" class="toolbarbutton-1" disabled="true" /> <toolbarbutton id="PanelUI-zen-gradient-generator-color-page-left" class="toolbarbutton-1" disabled="true" />
<hbox id="PanelUI-zen-gradient-generator-color-pages"> <hbox id="PanelUI-zen-gradient-generator-color-pages">
<hbox> <hbox>
<box data-lightness="90" data-algo="float" data-num-dots="1" data-position="240,240" style="background: #f4efdf;"></box> <box class="no-squircles" data-lightness="90" data-algo="float" data-num-dots="1" data-position="240,240" style="background: #f4efdf;"></box>
<box data-lightness="80" data-algo="float" data-num-dots="1" data-position="233,157" style="background: #f0b8cd;"></box> <box class="no-squircles" data-lightness="80" data-algo="float" data-num-dots="1" data-position="233,157" style="background: #f0b8cd;"></box>
<box data-lightness="80" data-algo="float" data-num-dots="1" data-position="236,111" style="background: #e9c3e3;"></box> <box class="no-squircles" data-lightness="80" data-algo="float" data-num-dots="1" data-position="236,111" style="background: #e9c3e3;"></box>
<box data-lightness="70" data-algo="float" data-num-dots="1" data-position="234,173" style="background: #da7682;"></box> <box class="no-squircles" data-lightness="70" data-algo="float" data-num-dots="1" data-position="234,173" style="background: #da7682;"></box>
<box data-lightness="70" data-algo="float" data-num-dots="1" data-position="220,187" style="background: #eb8570;"></box> <box class="no-squircles" data-lightness="70" data-algo="float" data-num-dots="1" data-position="220,187" style="background: #eb8570;"></box>
<box data-lightness="60" data-algo="float" data-num-dots="1" data-position="225,237" style="background: #dcce7f;"></box> <box class="no-squircles" data-lightness="60" data-algo="float" data-num-dots="1" data-position="225,237" style="background: #dcce7f;"></box>
<box data-lightness="60" data-algo="float" data-num-dots="1" data-position="147,195" style="background: #5becad;"></box> <box class="no-squircles" data-lightness="60" data-algo="float" data-num-dots="1" data-position="147,195" style="background: #5becad;"></box>
<box data-lightness="50" data-algo="float" data-num-dots="1" data-position="81,84" style="background: #919bb5;"></box> <box class="no-squircles" data-lightness="50" data-algo="float" data-num-dots="1" data-position="81,84" style="background: #919bb5;"></box>
</hbox> </hbox>
<hbox> <hbox>
<box data-lightness="90" data-algo="analogous" data-num-dots="3" data-position="240,240" <box class="no-squircles" data-lightness="90" data-algo="analogous" data-num-dots="3" data-position="240,240"
style="--c1: rgb(245, 237, 214); --c2: rgb(221, 243, 216); --c3: rgb(243, 216, 225);" /> style="--c1: rgb(245, 237, 214); --c2: rgb(221, 243, 216); --c3: rgb(243, 216, 225);" />
<box data-lightness="85" data-algo="analogous" data-num-dots="3" data-position="233,157" <box class="no-squircles" data-lightness="85" data-algo="analogous" data-num-dots="3" data-position="233,157"
style="--c1: rgb(243, 190, 222); --c2: rgb(247, 222, 186); --c3: rgb(223, 195, 238);" /> style="--c1: rgb(243, 190, 222); --c2: rgb(247, 222, 186); --c3: rgb(223, 195, 238);" />
<box data-lightness="80" data-algo="analogous" data-num-dots="3" data-position="236,111" <box class="no-squircles" data-lightness="80" data-algo="analogous" data-num-dots="3" data-position="236,111"
style="--c1: rgb(229, 179, 228); --c2: rgb(236, 172, 178); --c3: rgb(197, 185, 223);" /> style="--c1: rgb(229, 179, 228); --c2: rgb(236, 172, 178); --c3: rgb(197, 185, 223);" />
<box data-lightness="70" data-algo="analogous" data-num-dots="3" data-position="234,173" <box class="no-squircles" data-lightness="70" data-algo="analogous" data-num-dots="3" data-position="234,173"
style="--c1: rgb(235, 122, 159); --c2: rgb(239, 239, 118); --c3: rgb(210, 133, 224);" /> style="--c1: rgb(235, 122, 159); --c2: rgb(239, 239, 118); --c3: rgb(210, 133, 224);" />
<box data-lightness="70" data-algo="analogous" data-num-dots="3" data-position="220,187" <box class="no-squircles" data-lightness="70" data-algo="analogous" data-num-dots="3" data-position="220,187"
style="--c1: rgb(242, 115, 123); --c2: rgb(175, 242, 115); --c3: rgb(230, 125, 232);" /> style="--c1: rgb(242, 115, 123); --c2: rgb(175, 242, 115); --c3: rgb(230, 125, 232);" />
<box data-lightness="60" data-algo="analogous" data-num-dots="3" data-position="225,237" <box class="no-squircles" data-lightness="60" data-algo="analogous" data-num-dots="3" data-position="225,237"
style="--c1: rgb(221, 205, 85); --c2: rgb(97, 212, 94); --c3: rgb(215, 91, 124);" /> style="--c1: rgb(221, 205, 85); --c2: rgb(97, 212, 94); --c3: rgb(215, 91, 124);" />
<box data-lightness="60" data-algo="analogous" data-num-dots="3" data-position="147,195" <box class="no-squircles" data-lightness="60" data-algo="analogous" data-num-dots="3" data-position="147,195"
style="--c1: rgb(75, 231, 210); --c2: rgb(84, 175, 222); --c3: rgb(62, 244, 112);" /> style="--c1: rgb(75, 231, 210); --c2: rgb(84, 175, 222); --c3: rgb(62, 244, 112);" />
<box data-lightness="55" data-algo="analogous" data-num-dots="3" data-position="81,84" <box class="no-squircles" data-lightness="55" data-algo="analogous" data-num-dots="3" data-position="81,84"
style="--c1: rgb(122, 132, 158); --c2: rgb(137, 117, 164); --c3: rgb(116, 162, 164);" /> style="--c1: rgb(122, 132, 158); --c2: rgb(137, 117, 164); --c3: rgb(116, 162, 164);" />
</hbox> </hbox>
<hbox> <hbox>
<box data-lightness="10" data-algo="float" data-num-dots="1" data-position="171,72" style="background:rgb(93, 86, 106);"></box> <box class="no-squircles" data-lightness="10" data-algo="float" data-num-dots="1" data-position="171,72" style="background:rgb(93, 86, 106);"></box>
<box data-lightness="40" data-algo="float" data-num-dots="1" data-position="265,79" style="background: #997096;"></box> <box class="no-squircles" data-lightness="40" data-algo="float" data-num-dots="1" data-position="265,79" style="background: #997096;"></box>
<box data-lightness="35" data-algo="float" data-num-dots="1" data-position="301,176" style="background: #956066;"></box> <box class="no-squircles" data-lightness="35" data-algo="float" data-num-dots="1" data-position="301,176" style="background: #956066;"></box>
<box data-lightness="30" data-algo="float" data-num-dots="1" data-position="237,210" style="background: #9c6645;"></box> <box class="no-squircles" data-lightness="30" data-algo="float" data-num-dots="1" data-position="237,210" style="background: #9c6645;"></box>
<box data-lightness="30" data-algo="float" data-num-dots="1" data-position="91,228" style="background: #517b6c;"></box> <box class="no-squircles" data-lightness="30" data-algo="float" data-num-dots="1" data-position="91,228" style="background: #517b6c;"></box>
<box data-lightness="25" data-algo="float" data-num-dots="1" data-position="67,159" style="background: #576e75;"></box> <box class="no-squircles" data-lightness="25" data-algo="float" data-num-dots="1" data-position="67,159" style="background: #576e75;"></box>
<box data-lightness="20" data-algo="float" data-num-dots="1" data-position="314,235" style="background:rgb(131, 109, 95);"></box> <box class="no-squircles" data-lightness="20" data-algo="float" data-num-dots="1" data-position="314,235" style="background:rgb(131, 109, 95);"></box>
<box data-lightness="20" data-algo="float" data-num-dots="1" data-position="118,215" style="background: #447464;"></box> <box class="no-squircles" data-lightness="20" data-algo="float" data-num-dots="1" data-position="118,215" style="background: #447464;"></box>
</hbox> </hbox>
<hbox> <hbox>
<box data-lightness="10" data-algo="analogous" data-num-dots="3" data-position="171,72" <box class="no-squircles" data-lightness="10" data-algo="analogous" data-num-dots="3" data-position="171,72"
style="--c1: rgb(23, 17, 34); --c2: rgb(37, 14, 35); --c3: rgb(18, 22, 33);" /> style="--c1: rgb(23, 17, 34); --c2: rgb(37, 14, 35); --c3: rgb(18, 22, 33);" />
<box data-lightness="40" data-algo="analogous" data-num-dots="3" data-position="265,79" <box class="no-squircles" data-lightness="40" data-algo="analogous" data-num-dots="3" data-position="265,79"
style="--c1: rgb(128, 76, 124); --c2: rgb(141, 63, 66); --c3: rgb(97, 88, 116);" /> style="--c1: rgb(128, 76, 124); --c2: rgb(141, 63, 66); --c3: rgb(97, 88, 116);" />
<box data-lightness="35" data-algo="analogous" data-num-dots="3" data-position="301,176" <box class="no-squircles" data-lightness="35" data-algo="analogous" data-num-dots="3" data-position="301,176"
style="--c1: rgb(122, 56, 64); --c2: rgb(126, 121, 52); --c3: rgb(111, 68, 110);" /> style="--c1: rgb(122, 56, 64); --c2: rgb(126, 121, 52); --c3: rgb(111, 68, 110);" />
<box data-lightness="30" data-algo="analogous" data-num-dots="3" data-position="237,210" <box class="no-squircles" data-lightness="30" data-algo="analogous" data-num-dots="3" data-position="237,210"
style="--c1: rgb(131, 65, 22); --c2: rgb(64, 128, 25); --c3: rgb(122, 31, 91);" /> style="--c1: rgb(131, 65, 22); --c2: rgb(64, 128, 25); --c3: rgb(122, 31, 91);" />
<box data-lightness="30" data-algo="analogous" data-num-dots="3" data-position="91,228" <box class="no-squircles" data-lightness="30" data-algo="analogous" data-num-dots="3" data-position="91,228"
style="--c1: rgb(45, 108, 85); --c2: rgb(52, 85, 101); --c3: rgb(52, 118, 35);" /> style="--c1: rgb(45, 108, 85); --c2: rgb(52, 85, 101); --c3: rgb(52, 118, 35);" />
<box data-lightness="25" data-algo="analogous" data-num-dots="3" data-position="67,159" <box class="no-squircles" data-lightness="25" data-algo="analogous" data-num-dots="3" data-position="67,159"
style="--c1: rgb(45, 74, 83); --c2: rgb(46, 50, 81); --c3: rgb(38, 90, 65);" /> style="--c1: rgb(45, 74, 83); --c2: rgb(46, 50, 81); --c3: rgb(38, 90, 65);" />
<box data-lightness="20" data-algo="analogous" data-num-dots="3" data-position="314,235" <box class="no-squircles" data-lightness="20" data-algo="analogous" data-num-dots="3" data-position="314,235"
style="--c1: rgb(64, 47, 38); --c2: rgb(55, 64, 38); --c3: rgb(59, 43, 52);" /> style="--c1: rgb(64, 47, 38); --c2: rgb(55, 64, 38); --c3: rgb(59, 43, 52);" />
<box data-lightness="20" data-algo="analogous" data-num-dots="3" data-position="118,215" <box class="no-squircles" data-lightness="20" data-algo="analogous" data-num-dots="3" data-position="118,215"
style="--c1: rgb(22, 80, 61); --c2: rgb(26, 60, 76); --c3: rgb(27, 87, 15);" /> style="--c1: rgb(22, 80, 61); --c2: rgb(26, 60, 76); --c3: rgb(27, 87, 15);" />
</hbox> </hbox>
<hbox> <hbox>
# Start from black to white in a span on 8 steps and. # Start from black to white in a span on 8 steps and.
# They must all go from the middle to the right side. They must always stay verically centered. # They must all go from the middle to the right side. They must always stay verically centered.
# And reach to 180 on the right side, meaning we must divide the width in 16 segments. # And reach to 180 on the right side, meaning we must divide the width in 16 segments.
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1" <box class="no-squircles" data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="340,180" style="background: rgb(224, 224, 224);"></box> data-position="340,180" style="background: rgb(224, 224, 224);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1" <box class="no-squircles" data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="337.5,180" style="background: rgb(224, 224, 224);"></box> data-position="337.5,180" style="background: rgb(224, 224, 224);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1" <box class="no-squircles" data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="315,180" style="background: rgb(192, 192, 192);"></box> data-position="315,180" style="background: rgb(192, 192, 192);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1" <box class="no-squircles" data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="292.5,180" style="background: rgb(160, 160, 160);"></box> data-position="292.5,180" style="background: rgb(160, 160, 160);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1" <box class="no-squircles" data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="270,180" style="background: rgb(128, 128, 128);"></box> data-position="270,180" style="background: rgb(128, 128, 128);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1" <box class="no-squircles" data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="247.5,180" style="background: rgb(96, 96, 96);"></box> data-position="247.5,180" style="background: rgb(96, 96, 96);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1" <box class="no-squircles" data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="225,180" style="background: rgb(64, 64, 64);"></box> data-position="225,180" style="background: rgb(64, 64, 64);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1" <box class="no-squircles" data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="202.5,180" style="background: rgb(32, 32, 32);"></box> data-position="202.5,180" style="background: rgb(32, 32, 32);"></box>
<box data-type="explicit-black-white" data-algo="float" data-num-dots="1" <box class="no-squircles" data-type="explicit-black-white" data-algo="float" data-num-dots="1"
data-position="180,180" style="background: rgb(0, 0, 0);"></box> data-position="180,180" style="background: rgb(0, 0, 0);"></box>
</hbox> </hbox>
</hbox> </hbox>
@@ -131,10 +131,10 @@
</box> </box>
<html:input type="range" value="0.4" step="0.001" id="PanelUI-zen-gradient-generator-opacity" <html:input type="range" value="0.4" step="0.001" id="PanelUI-zen-gradient-generator-opacity"
#ifdef XP_MACOSX #ifdef XP_MACOSX
max="0.9" max="0.8"
min="0.30" min="0.30"
#else #else
max="0.9" max="0.8"
min="0.25" min="0.25"
#endif #endif
/> />

View File

@@ -0,0 +1,21 @@
diff --git a/browser/components/contextualidentity/content/ContainerCreationPanel.mjs b/browser/components/contextualidentity/content/ContainerCreationPanel.mjs
index e04d7a4738192703e8f7f8555f50aaf0a619a5bd..b86e4853c421856f84ad8e017062f0d611b88aad 100644
--- a/browser/components/contextualidentity/content/ContainerCreationPanel.mjs
+++ b/browser/components/contextualidentity/content/ContainerCreationPanel.mjs
@@ -4,7 +4,7 @@
import { ContainerEditor } from "chrome://browser/content/usercontext/ContainerEditor.mjs";
-const ANCHOR_ID = "userContext-icons";
+const ANCHOR_ID = "navigator-toolbox";
const ANCHOR_PINNED_CLASS = "container-anchor-pinned";
const lazy = {};
@@ -95,6 +95,6 @@ export const ContainerCreationPanel = {
anchor.hidden = false;
}
- panel.openPopup(anchor, "bottomright topright");
+ panel.openPopup(anchor, win.gZenUIManager.panelUIPosition());
},
};

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/customizableui/CustomizableUI.sys.mjs b/browser/components/customizableui/CustomizableUI.sys.mjs diff --git a/browser/components/customizableui/CustomizableUI.sys.mjs b/browser/components/customizableui/CustomizableUI.sys.mjs
index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2681652e5 100644 index 6d1885a54815d10b3a4e79f7e5acd61ab3abb159..3d6e092e7ed126cdee8c32229df2cfa13303d3a3 100644
--- a/browser/components/customizableui/CustomizableUI.sys.mjs --- a/browser/components/customizableui/CustomizableUI.sys.mjs
+++ b/browser/components/customizableui/CustomizableUI.sys.mjs +++ b/browser/components/customizableui/CustomizableUI.sys.mjs
@@ -13,6 +13,7 @@ ChromeUtils.defineESModuleGetters(lazy, { @@ -13,6 +13,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
@@ -10,7 +10,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
HomePage: "resource:///modules/HomePage.sys.mjs", HomePage: "resource:///modules/HomePage.sys.mjs",
PanelMultiView: PanelMultiView:
"moz-src:///browser/components/customizableui/PanelMultiView.sys.mjs", "moz-src:///browser/components/customizableui/PanelMultiView.sys.mjs",
@@ -348,7 +349,7 @@ var CustomizableUIInternal = { @@ -352,7 +353,7 @@ var CustomizableUIInternal = {
{ {
type: CustomizableUI.TYPE_PANEL, type: CustomizableUI.TYPE_PANEL,
defaultPlacements: [], defaultPlacements: [],
@@ -19,7 +19,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
}, },
false false
); );
@@ -358,27 +359,23 @@ var CustomizableUIInternal = { @@ -362,27 +363,23 @@ var CustomizableUIInternal = {
"back-button", "back-button",
"forward-button", "forward-button",
"stop-reload-button", "stop-reload-button",
@@ -50,17 +50,18 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
defaultCollapsed: false, defaultCollapsed: false,
}, },
true true
@@ -402,9 +399,6 @@ var CustomizableUIInternal = { @@ -406,10 +403,6 @@ var CustomizableUIInternal = {
type: CustomizableUI.TYPE_TOOLBAR, type: CustomizableUI.TYPE_TOOLBAR,
defaultPlacements: [ defaultPlacements: [
"tabbrowser-tabs", "tabbrowser-tabs",
- "new-tab-button", - "new-tab-button",
- "spring",
- "alltabs-button", - "alltabs-button",
- "ai-window-toggle", - "ai-window-toggle",
], ],
verticalTabsDefaultPlacements: [], verticalTabsDefaultPlacements: [],
defaultCollapsed: null, defaultCollapsed: null,
@@ -484,6 +478,7 @@ var CustomizableUIInternal = { @@ -502,6 +495,7 @@ var CustomizableUIInternal = {
CustomizableUI.AREA_NAVBAR, CustomizableUI.AREA_NAVBAR,
CustomizableUI.AREA_BOOKMARKS, CustomizableUI.AREA_BOOKMARKS,
CustomizableUI.AREA_TABSTRIP, CustomizableUI.AREA_TABSTRIP,
@@ -68,7 +69,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
]); ]);
if (AppConstants.platform != "macosx") { if (AppConstants.platform != "macosx") {
toolbars.add(CustomizableUI.AREA_MENUBAR); toolbars.add(CustomizableUI.AREA_MENUBAR);
@@ -1285,6 +1280,9 @@ var CustomizableUIInternal = { @@ -1334,6 +1328,9 @@ var CustomizableUIInternal = {
placements = gPlacements.get(area); placements = gPlacements.get(area);
} }
@@ -78,7 +79,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
// For toolbars that need it, mark as dirty. // For toolbars that need it, mark as dirty.
let defaultPlacements = areaProperties.get("defaultPlacements"); let defaultPlacements = areaProperties.get("defaultPlacements");
if ( if (
@@ -1793,7 +1791,6 @@ var CustomizableUIInternal = { @@ -1842,7 +1839,6 @@ var CustomizableUIInternal = {
lazy.log.info( lazy.log.info(
"Widget " + aWidgetId + " not found, unable to remove from " + aArea "Widget " + aWidgetId + " not found, unable to remove from " + aArea
); );
@@ -86,7 +87,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
} }
this.notifyDOMChange(widgetNode, null, container, true, () => { this.notifyDOMChange(widgetNode, null, container, true, () => {
@@ -1803,7 +1800,7 @@ var CustomizableUIInternal = { @@ -1852,7 +1848,7 @@ var CustomizableUIInternal = {
// We also need to remove the panel context menu if it's there: // We also need to remove the panel context menu if it's there:
this.ensureButtonContextMenu(widgetNode); this.ensureButtonContextMenu(widgetNode);
if (gPalette.has(aWidgetId) || this.isSpecialWidget(aWidgetId)) { if (gPalette.has(aWidgetId) || this.isSpecialWidget(aWidgetId)) {
@@ -95,7 +96,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
} else { } else {
window.gNavToolbox.palette.appendChild(widgetNode); window.gNavToolbox.palette.appendChild(widgetNode);
} }
@@ -1971,16 +1968,16 @@ var CustomizableUIInternal = { @@ -2020,16 +2016,16 @@ var CustomizableUIInternal = {
elem.setAttribute("skipintoolbarset", "true"); elem.setAttribute("skipintoolbarset", "true");
} }
} }
@@ -115,7 +116,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
// Handle initial state of vertical tabs. // Handle initial state of vertical tabs.
if (isVerticalTabs) { if (isVerticalTabs) {
// Show the vertical tabs toolbar // Show the vertical tabs toolbar
@@ -2222,6 +2219,10 @@ var CustomizableUIInternal = { @@ -2271,6 +2267,10 @@ var CustomizableUIInternal = {
* The identifier string of the area that aNode is being inserted into. * The identifier string of the area that aNode is being inserted into.
*/ */
insertWidgetBefore(aNode, aNextNode, aContainer, aAreaId) { insertWidgetBefore(aNode, aNextNode, aContainer, aAreaId) {
@@ -126,7 +127,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
this.notifyDOMChange(aNode, aNextNode, aContainer, false, () => { this.notifyDOMChange(aNode, aNextNode, aContainer, false, () => {
this.setLocationAttributes(aNode, aAreaId); this.setLocationAttributes(aNode, aAreaId);
aContainer.insertBefore(aNode, aNextNode); aContainer.insertBefore(aNode, aNextNode);
@@ -4592,7 +4593,7 @@ var CustomizableUIInternal = { @@ -4647,7 +4647,7 @@ var CustomizableUIInternal = {
* For all registered areas, builds those areas to reflect the current * For all registered areas, builds those areas to reflect the current
* placement state of all widgets. * placement state of all widgets.
*/ */
@@ -135,7 +136,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
for (let [areaId, areaNodes] of gBuildAreas) { for (let [areaId, areaNodes] of gBuildAreas) {
let placements = gPlacements.get(areaId); let placements = gPlacements.get(areaId);
let isFirstChangedToolbar = true; let isFirstChangedToolbar = true;
@@ -4603,7 +4604,7 @@ var CustomizableUIInternal = { @@ -4658,7 +4658,7 @@ var CustomizableUIInternal = {
if (area.get("type") == CustomizableUI.TYPE_TOOLBAR) { if (area.get("type") == CustomizableUI.TYPE_TOOLBAR) {
let defaultCollapsed = area.get("defaultCollapsed"); let defaultCollapsed = area.get("defaultCollapsed");
let win = areaNode.documentGlobal; let win = areaNode.documentGlobal;
@@ -144,7 +145,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
win.setToolbarVisibility( win.setToolbarVisibility(
areaNode, areaNode,
typeof defaultCollapsed == "string" typeof defaultCollapsed == "string"
@@ -5899,6 +5900,7 @@ export var CustomizableUI = { @@ -5971,6 +5971,7 @@ export var CustomizableUI = {
unregisterArea(aName, aDestroyPlacements) { unregisterArea(aName, aDestroyPlacements) {
CustomizableUIInternal.unregisterArea(aName, aDestroyPlacements); CustomizableUIInternal.unregisterArea(aName, aDestroyPlacements);
}, },
@@ -152,7 +153,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
/** /**
* Add a widget to an area. * Add a widget to an area.
* If the area to which you try to add is not known to CustomizableUI, * If the area to which you try to add is not known to CustomizableUI,
@@ -7869,7 +7871,9 @@ class OverflowableToolbar { @@ -7946,7 +7947,9 @@ class OverflowableToolbar {
); );
if (webExtList && CustomizableUI.isWebExtensionWidget(child.id)) { if (webExtList && CustomizableUI.isWebExtensionWidget(child.id)) {
@@ -162,16 +163,27 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
webExtList.insertBefore(child, webExtList.firstElementChild); webExtList.insertBefore(child, webExtList.firstElementChild);
} else { } else {
child.setAttribute("cui-anchorid", this.#defaultListButton.id); child.setAttribute("cui-anchorid", this.#defaultListButton.id);
@@ -7929,7 +7933,7 @@ class OverflowableToolbar { @@ -7995,6 +7998,7 @@ class OverflowableToolbar {
return aElement.getBoundingClientRect().width;
}
+ let toolbar = this.#toolbar;
function sumChildrenInlineSize(aParent, aExceptChild = null) {
let sum = 0;
for (let child of aParent.children) {
@@ -8006,7 +8010,10 @@ class OverflowableToolbar {
) { ) {
continue; continue;
} }
- sum += parseFloat(style.marginLeft) + parseFloat(style.marginRight); - sum += parseFloat(style.marginLeft) + parseFloat(style.marginRight);
+ sum += parseFloat(style.marginLeft) + (win.gZenVerticalTabsManager._hasSetSingleToolbar ? Math.max(0, parseFloat(style.marginRight)) : parseFloat(style.marginRight)); + sum += parseFloat(style.marginLeft) + (win.gZenVerticalTabsManager._hasSetSingleToolbar ? Math.max(0, parseFloat(style.marginRight)) : parseFloat(style.marginRight));
+ if (toolbar.id == 'zen-sidebar-top-buttons' && toolbar.hasAttribute("overflowing")) {
+ sum += 2; // Add extra padding that we remove from the CSS
+ }
if (child != aExceptChild) { if (child != aExceptChild) {
sum += getInlineSize(child); sum += getInlineSize(child);
} }
@@ -7953,11 +7957,11 @@ class OverflowableToolbar { @@ -8030,11 +8037,11 @@ class OverflowableToolbar {
parseFloat(style.paddingLeft) - parseFloat(style.paddingLeft) -
parseFloat(style.paddingRight) - parseFloat(style.paddingRight) -
toolbarChildrenWidth; toolbarChildrenWidth;
@@ -185,7 +197,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
}); });
lazy.log.debug( lazy.log.debug(
@@ -7972,7 +7976,39 @@ class OverflowableToolbar { @@ -8049,7 +8056,39 @@ class OverflowableToolbar {
Math.max(targetWidth, targetChildrenWidth) Math.max(targetWidth, targetChildrenWidth)
); );
totalAvailWidth = Math.ceil(totalAvailWidth); totalAvailWidth = Math.ceil(totalAvailWidth);
@@ -226,7 +238,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
return { isOverflowing, targetContentWidth, totalAvailWidth }; return { isOverflowing, targetContentWidth, totalAvailWidth };
} }
@@ -8033,7 +8069,11 @@ class OverflowableToolbar { @@ -8110,7 +8149,11 @@ class OverflowableToolbar {
return; return;
} }
} }
@@ -239,7 +251,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
lazy.log.debug( lazy.log.debug(
`Need ${minSize} but width is ${totalAvailWidth} so bailing` `Need ${minSize} but width is ${totalAvailWidth} so bailing`
); );
@@ -8066,7 +8106,7 @@ class OverflowableToolbar { @@ -8143,7 +8186,7 @@ class OverflowableToolbar {
} }
} }
if (!inserted) { if (!inserted) {
@@ -248,7 +260,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
} }
child.removeAttribute("cui-anchorid"); child.removeAttribute("cui-anchorid");
child.removeAttribute("overflowedItem"); child.removeAttribute("overflowedItem");
@@ -8192,6 +8232,9 @@ class OverflowableToolbar { @@ -8269,6 +8312,9 @@ class OverflowableToolbar {
* if no such list exists. * if no such list exists.
*/ */
get #webExtList() { get #webExtList() {
@@ -258,7 +270,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
if (!this.#webExtListRef) { if (!this.#webExtListRef) {
let targetID = this.#toolbar.getAttribute("addon-webext-overflowtarget"); let targetID = this.#toolbar.getAttribute("addon-webext-overflowtarget");
if (!targetID) { if (!targetID) {
@@ -8203,6 +8246,9 @@ class OverflowableToolbar { @@ -8280,6 +8326,9 @@ class OverflowableToolbar {
let win = this.#toolbar.documentGlobal; let win = this.#toolbar.documentGlobal;
let { panel } = win.gUnifiedExtensions; let { panel } = win.gUnifiedExtensions;
this.#webExtListRef = panel.querySelector(`#${targetID}`); this.#webExtListRef = panel.querySelector(`#${targetID}`);
@@ -268,7 +280,7 @@ index 491161e48044f75167a8e8a0348779cfa22fc40e..867d51b8a6b74f841afc6d84dcdfd8f2
} }
return this.#webExtListRef; return this.#webExtListRef;
} }
@@ -8411,7 +8457,7 @@ class OverflowableToolbar { @@ -8488,7 +8537,7 @@ class OverflowableToolbar {
break; break;
} }
case "mousedown": { case "mousedown": {

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/preferences/config/account-sync.mjs b/browser/components/preferences/config/account-sync.mjs diff --git a/browser/components/preferences/config/account-sync.mjs b/browser/components/preferences/config/account-sync.mjs
index b503987a08e2ce64bfc01c4e3a21e5e19ef834f0..b1c03a0b219fd3eddd93c1deaeb18ab79c85f168 100644 index b01fd4bb163ad53139fcbd8e79e12ef994d1fa13..dd60be4fe268618d6596cd5cfac3342975bd241a 100644
--- a/browser/components/preferences/config/account-sync.mjs --- a/browser/components/preferences/config/account-sync.mjs
+++ b/browser/components/preferences/config/account-sync.mjs +++ b/browser/components/preferences/config/account-sync.mjs
@@ -42,6 +42,7 @@ Preferences.addAll([ @@ -46,6 +46,7 @@ Preferences.addAll([
{ id: "services.sync.engine.creditcards", type: "bool" }, { id: "services.sync.engine.creditcards", type: "bool" },
{ id: "services.sync.engine.addons", type: "bool" }, { id: "services.sync.engine.addons", type: "bool" },
{ id: "services.sync.engine.prefs", type: "bool" }, { id: "services.sync.engine.prefs", type: "bool" },
@@ -10,7 +10,7 @@ index b503987a08e2ce64bfc01c4e3a21e5e19ef834f0..b1c03a0b219fd3eddd93c1deaeb18ab7
]); ]);
/** /**
@@ -546,6 +547,7 @@ const SYNC_ENGINE_SETTINGS = [ @@ -557,6 +558,7 @@ const SYNC_ENGINE_SETTINGS = [
type: "payments", type: "payments",
}, },
{ id: "syncAddons", pref: "services.sync.engine.addons", type: "addons" }, { id: "syncAddons", pref: "services.sync.engine.addons", type: "addons" },
@@ -18,3 +18,37 @@ index b503987a08e2ce64bfc01c4e3a21e5e19ef834f0..b1c03a0b219fd3eddd93c1deaeb18ab7
{ id: "syncSettings", pref: "services.sync.engine.prefs", type: "settings" }, { id: "syncSettings", pref: "services.sync.engine.prefs", type: "settings" },
]; ];
@@ -564,6 +566,12 @@ SYNC_ENGINE_SETTINGS.forEach(({ id, pref }) => {
Preferences.addSetting({ id, pref });
});
+Preferences.addSetting({ id: "zenSyncWorkspacesGroup" });
+Preferences.addSetting({
+ id: "zenSyncWorkspaces",
+ pref: "services.sync.engine.spaces",
+});
+
Preferences.addSetting({
id: "syncEngines",
deps: SYNC_ENGINE_SETTINGS.map(({ id }) => id),
@@ -995,6 +1003,20 @@ SettingGroupManager.registerGroups({
id: "syncEnginesList",
control: "sync-engines-list",
},
+ {
+ id: "zenSyncWorkspacesGroup",
+ control: "moz-box-item",
+ items: [
+ {
+ id: "zenSyncWorkspaces",
+ l10nId: "zen-settings-workspaces-sync",
+ control: "moz-toggle",
+ controlAttrs: {
+ inputlayout: "inline-end",
+ },
+ },
+ ],
+ },
{
id: "syncChangeOptions",
control: "moz-box-button",

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/preferences/preferences.js b/browser/components/preferences/preferences.js diff --git a/browser/components/preferences/preferences.js b/browser/components/preferences/preferences.js
index c76a0647e14bac806d9428483bb565b3e10c31e7..2188f7808aca090f92574c7f5c55a28a9c5bb3f8 100644 index 94612d8e28af58fcb04914440348b899a0a1e08f..da3b1ffd09745d09589283356d1001dbfb76a468 100644
--- a/browser/components/preferences/preferences.js --- a/browser/components/preferences/preferences.js
+++ b/browser/components/preferences/preferences.js +++ b/browser/components/preferences/preferences.js
@@ -131,6 +131,7 @@ ChromeUtils.defineLazyGetter(this, "gSubDialog", function () { @@ -132,6 +132,7 @@ ChromeUtils.defineLazyGetter(this, "gSubDialog", function () {
styleSheets: [ styleSheets: [
"chrome://browser/skin/preferences/dialog.css", "chrome://browser/skin/preferences/dialog.css",
"chrome://browser/skin/preferences/preferences.css", "chrome://browser/skin/preferences/preferences.css",
@@ -10,7 +10,7 @@ index c76a0647e14bac806d9428483bb565b3e10c31e7..2188f7808aca090f92574c7f5c55a28a
], ],
resizeCallback: async ({ title, frame }) => { resizeCallback: async ({ title, frame }) => {
// Search within main document and highlight matched keyword. // Search within main document and highlight matched keyword.
@@ -437,6 +438,8 @@ const CONFIG_PANES = Object.freeze({ @@ -471,6 +472,8 @@ const CONFIG_PANES = Object.freeze({
tabsBrowsing: { tabsBrowsing: {
l10nId: "tabs-browsing-section", l10nId: "tabs-browsing-section",
groupIds: [ groupIds: [
@@ -19,7 +19,7 @@ index c76a0647e14bac806d9428483bb565b3e10c31e7..2188f7808aca090f92574c7f5c55a28a
"browserLayout", "browserLayout",
"tabs", "tabs",
"pageNavigation", "pageNavigation",
@@ -483,7 +486,7 @@ function register_module(categoryName, categoryObject) { @@ -518,7 +521,7 @@ function register_module(categoryName, categoryObject) {
} }
this._initted = true; this._initted = true;
let template = document.getElementById("template-" + categoryName); let template = document.getElementById("template-" + categoryName);
@@ -28,7 +28,7 @@ index c76a0647e14bac806d9428483bb565b3e10c31e7..2188f7808aca090f92574c7f5c55a28a
// Replace the template element with the nodes inside of it. // Replace the template element with the nodes inside of it.
template.replaceWith(template.content); template.replaceWith(template.content);
@@ -527,6 +530,10 @@ function init_all() { @@ -562,6 +565,10 @@ function init_all() {
register_module("paneHome", gHomePane); register_module("paneHome", gHomePane);
register_module("paneSearch", gSearchPane); register_module("paneSearch", gSearchPane);
register_module("panePrivacy", gPrivacyPane); register_module("panePrivacy", gPrivacyPane);
@@ -39,15 +39,3 @@ index c76a0647e14bac806d9428483bb565b3e10c31e7..2188f7808aca090f92574c7f5c55a28a
// Restore the cached Firefox Labs nav button visibility so it shows // Restore the cached Firefox Labs nav button visibility so it shows
// immediately when recipes are expected to be available, before // immediately when recipes are expected to be available, before
@@ -656,9 +663,9 @@ async function gotoPref(
let redesignEnabled = srdSectionPrefs.all;
let categories = document.getElementById("categories");
const kDefaultCategoryInternalName = redesignEnabled
- ? "paneSync"
+ ? "paneTabsBrowsing"
: "paneGeneral";
- const kDefaultCategory = redesignEnabled ? "sync" : "general";
+ const kDefaultCategory = redesignEnabled ? "tabsBrowsing" : "general";
let hash = document.location.hash;
let category = aCategory || hash.substring(1) || kDefaultCategoryInternalName;

View File

@@ -27,7 +27,7 @@ index 1b8c38159314b6edee9e6f455beb2b63db1ad3f0..1308345db640dba6b2848b49ef7c1181
+ </html:moz-page-nav-button> + </html:moz-page-nav-button>
+ <html:moz-page-nav-button id="category-zen-CKS" + <html:moz-page-nav-button id="category-zen-CKS"
+ view="paneZenCKS" + view="paneZenCKS"
+ iconsrc="chrome://browser/skin/quickactions.svg" + iconsrc="chrome://browser/skin/preferences/category-accessibility.svg"
+ data-l10n-id="pane-zen-CKS-title"> + data-l10n-id="pane-zen-CKS-title">
+ </html:moz-page-nav-button> + </html:moz-page-nav-button>
+ <html:moz-page-nav-button id="category-zen-marketplace" + <html:moz-page-nav-button id="category-zen-marketplace"

View File

@@ -0,0 +1,15 @@
diff --git a/browser/components/preferences/widgets/sync-engine-list/sync-engines-list.mjs b/browser/components/preferences/widgets/sync-engine-list/sync-engines-list.mjs
index 9359a485ed6212c7df49a8d4b1e4a8febbc1c9b6..132fea440cfa535e78b35f706e7ef2d6881f9ba6 100644
--- a/browser/components/preferences/widgets/sync-engine-list/sync-engines-list.mjs
+++ b/browser/components/preferences/widgets/sync-engine-list/sync-engines-list.mjs
@@ -50,6 +50,10 @@ const engineTypeToMetadata = {
iconSrc: "chrome://global/skin/icons/settings.svg",
l10nId: "sync-currently-syncing-settings",
},
+ workspaces: {
+ iconSrc: "chrome://devtools/skin/images/tool-storage.svg",
+ l10nId: "sync-currently-syncing-workspaces",
+ },
};
/**

View File

@@ -1,18 +1,20 @@
diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs
index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee4aa3be28 100644 index 536e06eec9f35bad3b8366733b23b5a8697df9c8..631a16bc7518108641993836f0c52e2ab6e6c967 100644
--- a/browser/components/sessionstore/SessionStore.sys.mjs --- a/browser/components/sessionstore/SessionStore.sys.mjs
+++ b/browser/components/sessionstore/SessionStore.sys.mjs +++ b/browser/components/sessionstore/SessionStore.sys.mjs
@@ -129,6 +129,9 @@ const TAB_EVENTS = [ @@ -129,6 +129,11 @@ const TAB_EVENTS = [
"TabSplitViewActivate", "TabSplitViewActivate",
"SplitViewRemoved", "SplitViewRemoved",
"SplitViewCreated", "SplitViewCreated",
+ "TabAddedToEssentials", + "TabAddedToEssentials",
+ "TabRemovedFromEssentials", + "TabRemovedFromEssentials",
+ "TabMove",
+ "TabGroupMoved",
+ "ZenWorkspaceDataChanged", + "ZenWorkspaceDataChanged",
]; ];
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@@ -201,6 +204,8 @@ ChromeUtils.defineESModuleGetters(lazy, { @@ -201,6 +206,8 @@ ChromeUtils.defineESModuleGetters(lazy, {
TabStateCache: "resource:///modules/sessionstore/TabStateCache.sys.mjs", TabStateCache: "resource:///modules/sessionstore/TabStateCache.sys.mjs",
TabStateFlusher: "resource:///modules/sessionstore/TabStateFlusher.sys.mjs", TabStateFlusher: "resource:///modules/sessionstore/TabStateFlusher.sys.mjs",
setTimeout: "resource://gre/modules/Timer.sys.mjs", setTimeout: "resource://gre/modules/Timer.sys.mjs",
@@ -21,7 +23,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
}); });
ChromeUtils.defineLazyGetter(lazy, "blankURI", () => { ChromeUtils.defineLazyGetter(lazy, "blankURI", () => {
@@ -1300,10 +1305,7 @@ var SessionStoreInternal = { @@ -1317,10 +1324,7 @@ var SessionStoreInternal = {
*/ */
get willAutoRestore() { get willAutoRestore() {
return ( return (
@@ -33,17 +35,19 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
); );
}, },
@@ -1990,6 +1992,9 @@ var SessionStoreInternal = { @@ -2008,6 +2012,11 @@ var SessionStoreInternal = {
case "TabPinned": case "TabPinned":
case "TabUnpinned": case "TabUnpinned":
case "SwapDocShells": case "SwapDocShells":
+ case "TabRemovedFromEssentials": + case "TabRemovedFromEssentials":
+ case "TabAddedToEssentials": + case "TabAddedToEssentials":
+ case "TabMove":
+ case "TabGroupMoved":
+ case "ZenWorkspaceDataChanged": + case "ZenWorkspaceDataChanged":
this.saveStateDelayed(win); this.saveStateDelayed(win);
break; break;
case "TabGroupCreate": case "TabGroupCreate":
@@ -2099,6 +2104,10 @@ var SessionStoreInternal = { @@ -2117,6 +2126,10 @@ var SessionStoreInternal = {
this._windows[aWindow.__SSi].isTaskbarTab = true; this._windows[aWindow.__SSi].isTaskbarTab = true;
} }
@@ -54,7 +58,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
if (lazy.AIWindow.isAIWindowActiveAndEnabled(aWindow)) { if (lazy.AIWindow.isAIWindowActiveAndEnabled(aWindow)) {
this._windows[aWindow.__SSi].isAIWindow = true; this._windows[aWindow.__SSi].isAIWindow = true;
} }
@@ -2135,7 +2144,7 @@ var SessionStoreInternal = { @@ -2153,7 +2166,7 @@ var SessionStoreInternal = {
let isTaskbarTab = this._windows[aWindow.__SSi].isTaskbarTab; let isTaskbarTab = this._windows[aWindow.__SSi].isTaskbarTab;
// A regular window is not a private window, taskbar tab window, or popup window // A regular window is not a private window, taskbar tab window, or popup window
let isRegularWindow = let isRegularWindow =
@@ -63,7 +67,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
// perform additional initialization when the first window is loading // perform additional initialization when the first window is loading
if (lazy.RunState.isStopped) { if (lazy.RunState.isStopped) {
@@ -2147,7 +2156,7 @@ var SessionStoreInternal = { @@ -2165,7 +2178,7 @@ var SessionStoreInternal = {
// to disk to NOW() to enforce a full interval before the next write. // to disk to NOW() to enforce a full interval before the next write.
lazy.SessionSaver.updateLastSaveTime(); lazy.SessionSaver.updateLastSaveTime();
@@ -72,7 +76,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
this._log.debug( this._log.debug(
"initializeWindow, the window is private or a web app. Saving SessionStartup.state for possibly restoring later" "initializeWindow, the window is private or a web app. Saving SessionStartup.state for possibly restoring later"
); );
@@ -2191,6 +2200,7 @@ var SessionStoreInternal = { @@ -2209,6 +2222,7 @@ var SessionStoreInternal = {
null, null,
"sessionstore-one-or-no-tab-restored" "sessionstore-one-or-no-tab-restored"
); );
@@ -80,7 +84,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
this._deferredAllWindowsRestored.resolve(); this._deferredAllWindowsRestored.resolve();
} }
// this window was opened by _openWindowWithState // this window was opened by _openWindowWithState
@@ -2240,7 +2250,6 @@ var SessionStoreInternal = { @@ -2258,7 +2272,6 @@ var SessionStoreInternal = {
if (closedWindowState) { if (closedWindowState) {
let newWindowState; let newWindowState;
if ( if (
@@ -88,7 +92,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
!lazy.SessionStartup.willRestore() !lazy.SessionStartup.willRestore()
) { ) {
// We want to split the window up into pinned tabs and unpinned tabs. // We want to split the window up into pinned tabs and unpinned tabs.
@@ -2276,6 +2285,7 @@ var SessionStoreInternal = { @@ -2294,6 +2307,7 @@ var SessionStoreInternal = {
} }
if (newWindowState) { if (newWindowState) {
@@ -96,7 +100,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
// Ensure that the window state isn't hidden // Ensure that the window state isn't hidden
this._restoreCount = 1; this._restoreCount = 1;
let state = { windows: [newWindowState] }; let state = { windows: [newWindowState] };
@@ -2312,6 +2322,9 @@ var SessionStoreInternal = { @@ -2330,6 +2344,9 @@ var SessionStoreInternal = {
}); });
this._shouldRestoreLastSession = false; this._shouldRestoreLastSession = false;
} }
@@ -106,7 +110,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
if (this._restoreLastWindow && aWindow.toolbar.visible) { if (this._restoreLastWindow && aWindow.toolbar.visible) {
// always reset (if not a popup window) // always reset (if not a popup window)
@@ -2462,7 +2475,7 @@ var SessionStoreInternal = { @@ -2480,7 +2497,7 @@ var SessionStoreInternal = {
var tabbrowser = aWindow.gBrowser; var tabbrowser = aWindow.gBrowser;
@@ -115,7 +119,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
TAB_EVENTS.forEach(function (aEvent) { TAB_EVENTS.forEach(function (aEvent) {
tabbrowser.tabContainer.removeEventListener(aEvent, this, true); tabbrowser.tabContainer.removeEventListener(aEvent, this, true);
@@ -2513,7 +2526,7 @@ var SessionStoreInternal = { @@ -2531,7 +2548,7 @@ var SessionStoreInternal = {
let isLastRegularWindow = let isLastRegularWindow =
Object.values(this._windows).filter( Object.values(this._windows).filter(
@@ -124,7 +128,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
).length == 1; ).length == 1;
this._log.debug( this._log.debug(
`onClose, closing window isLastRegularWindow? ${isLastRegularWindow}` `onClose, closing window isLastRegularWindow? ${isLastRegularWindow}`
@@ -2570,8 +2583,8 @@ var SessionStoreInternal = { @@ -2588,8 +2605,8 @@ var SessionStoreInternal = {
// 2) Flush the window. // 2) Flush the window.
// 3) When the flush is complete, revisit our decision to store the window // 3) When the flush is complete, revisit our decision to store the window
// in _closedWindows, and add/remove as necessary. // in _closedWindows, and add/remove as necessary.
@@ -135,7 +139,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
} }
completionPromise = lazy.TabStateFlusher.flushWindow(aWindow).then(() => { completionPromise = lazy.TabStateFlusher.flushWindow(aWindow).then(() => {
@@ -2591,8 +2604,9 @@ var SessionStoreInternal = { @@ -2609,8 +2626,9 @@ var SessionStoreInternal = {
// Save non-private windows if they have at // Save non-private windows if they have at
// least one saveable tab or are the last window. // least one saveable tab or are the last window.
@@ -147,7 +151,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
if (!isLastWindow && winData.closedId > -1) { if (!isLastWindow && winData.closedId > -1) {
this._addClosedAction( this._addClosedAction(
@@ -2668,7 +2682,7 @@ var SessionStoreInternal = { @@ -2686,7 +2704,7 @@ var SessionStoreInternal = {
* to call this method again asynchronously (for example, after * to call this method again asynchronously (for example, after
* a window flush). * a window flush).
*/ */
@@ -156,7 +160,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
// Make sure SessionStore is still running, and make sure that we // Make sure SessionStore is still running, and make sure that we
// haven't chosen to forget this window. // haven't chosen to forget this window.
if ( if (
@@ -2685,6 +2699,7 @@ var SessionStoreInternal = { @@ -2703,6 +2721,7 @@ var SessionStoreInternal = {
// _closedWindows from a previous call to this function. // _closedWindows from a previous call to this function.
let winIndex = this._closedWindows.indexOf(winData); let winIndex = this._closedWindows.indexOf(winData);
let alreadyStored = winIndex != -1; let alreadyStored = winIndex != -1;
@@ -164,7 +168,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
// If sidebar command is truthy, i.e. sidebar is open, store sidebar settings // If sidebar command is truthy, i.e. sidebar is open, store sidebar settings
let shouldStore = hasSaveableTabs || isLastWindow; let shouldStore = hasSaveableTabs || isLastWindow;
@@ -3507,7 +3522,7 @@ var SessionStoreInternal = { @@ -3525,7 +3544,7 @@ var SessionStoreInternal = {
if (!isPrivateWindow && tabState.isPrivate) { if (!isPrivateWindow && tabState.isPrivate) {
return; return;
} }
@@ -173,7 +177,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
return; return;
} }
@@ -4246,6 +4261,12 @@ var SessionStoreInternal = { @@ -4264,6 +4283,12 @@ var SessionStoreInternal = {
Math.min(tabState.index, tabState.entries.length) Math.min(tabState.index, tabState.entries.length)
); );
tabState.pinned = false; tabState.pinned = false;
@@ -186,7 +190,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
if (inBackground === false) { if (inBackground === false) {
aWindow.gBrowser.selectedTab = newTab; aWindow.gBrowser.selectedTab = newTab;
@@ -4679,6 +4700,8 @@ var SessionStoreInternal = { @@ -4697,6 +4722,8 @@ var SessionStoreInternal = {
// Append the tab if we're opening into a different window, // Append the tab if we're opening into a different window,
tabIndex: aSource == aTargetWindow ? pos : Infinity, tabIndex: aSource == aTargetWindow ? pos : Infinity,
pinned: state.pinned, pinned: state.pinned,
@@ -195,7 +199,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
userContextId: state.userContextId, userContextId: state.userContextId,
skipLoad: true, skipLoad: true,
preferredRemoteType, preferredRemoteType,
@@ -5176,9 +5199,10 @@ var SessionStoreInternal = { @@ -5194,9 +5221,10 @@ var SessionStoreInternal = {
if (activePageData.title && activePageData.title != activePageData.url) { if (activePageData.title && activePageData.title != activePageData.url) {
win.gBrowser.setInitialTabTitle(tab, activePageData.title, { win.gBrowser.setInitialTabTitle(tab, activePageData.title, {
isContentTitle: true, isContentTitle: true,
@@ -207,7 +211,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
} }
} }
@@ -5543,7 +5567,7 @@ var SessionStoreInternal = { @@ -5561,7 +5589,7 @@ var SessionStoreInternal = {
for (let i = tabbrowser.pinnedTabCount; i < tabbrowser.tabs.length; i++) { for (let i = tabbrowser.pinnedTabCount; i < tabbrowser.tabs.length; i++) {
let tab = tabbrowser.tabs[i]; let tab = tabbrowser.tabs[i];
@@ -216,7 +220,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
removableTabs.push(tab); removableTabs.push(tab);
} }
} }
@@ -5656,7 +5680,7 @@ var SessionStoreInternal = { @@ -5674,7 +5702,7 @@ var SessionStoreInternal = {
// collect the data for all windows // collect the data for all windows
for (ix in this._windows) { for (ix in this._windows) {
@@ -225,7 +229,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
// window data is still in _statesToRestore // window data is still in _statesToRestore
continue; continue;
} }
@@ -5800,11 +5824,12 @@ var SessionStoreInternal = { @@ -5818,11 +5846,12 @@ var SessionStoreInternal = {
} }
let tabbrowser = aWindow.gBrowser; let tabbrowser = aWindow.gBrowser;
@@ -239,7 +243,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
// update the internal state data for this window // update the internal state data for this window
for (let tab of tabs) { for (let tab of tabs) {
if (tab == aWindow.FirefoxViewHandler.tab) { if (tab == aWindow.FirefoxViewHandler.tab) {
@@ -5815,6 +5840,9 @@ var SessionStoreInternal = { @@ -5833,6 +5862,9 @@ var SessionStoreInternal = {
tabsData.push(tabData); tabsData.push(tabData);
} }
@@ -249,7 +253,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
// update tab group state for this window // update tab group state for this window
winData.groups = []; winData.groups = [];
for (let tabGroup of aWindow.gBrowser.tabGroups) { for (let tabGroup of aWindow.gBrowser.tabGroups) {
@@ -5831,7 +5859,7 @@ var SessionStoreInternal = { @@ -5849,7 +5881,7 @@ var SessionStoreInternal = {
// a window is closed, point to the first item in the tab strip instead (it will never be the Firefox View tab, // a window is closed, point to the first item in the tab strip instead (it will never be the Firefox View tab,
// since it's only inserted into the tab strip after it's selected). // since it's only inserted into the tab strip after it's selected).
if (aWindow.FirefoxViewHandler.tab?.selected) { if (aWindow.FirefoxViewHandler.tab?.selected) {
@@ -258,7 +262,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
winData.title = tabbrowser.tabs[0].label; winData.title = tabbrowser.tabs[0].label;
} }
winData.selected = selectedIndex; winData.selected = selectedIndex;
@@ -6033,8 +6061,8 @@ var SessionStoreInternal = { @@ -6051,8 +6083,8 @@ var SessionStoreInternal = {
// selectTab represents. // selectTab represents.
let selectTab = 0; let selectTab = 0;
if (overwriteTabs) { if (overwriteTabs) {
@@ -269,7 +273,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
selectTab = Math.min(selectTab, winData.tabs.length); selectTab = Math.min(selectTab, winData.tabs.length);
} }
@@ -6056,6 +6084,7 @@ var SessionStoreInternal = { @@ -6074,6 +6106,7 @@ var SessionStoreInternal = {
if (overwriteTabs) { if (overwriteTabs) {
for (let i = tabbrowser.browsers.length - 1; i >= 0; i--) { for (let i = tabbrowser.browsers.length - 1; i >= 0; i--) {
if (!tabbrowser.tabs[i].selected) { if (!tabbrowser.tabs[i].selected) {
@@ -277,7 +281,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
tabbrowser.removeTab(tabbrowser.tabs[i]); tabbrowser.removeTab(tabbrowser.tabs[i]);
} }
} }
@@ -6090,6 +6119,12 @@ var SessionStoreInternal = { @@ -6108,6 +6141,12 @@ var SessionStoreInternal = {
savedTabGroup => !openTabGroupIdsInWindow.has(savedTabGroup.id) savedTabGroup => !openTabGroupIdsInWindow.has(savedTabGroup.id)
); );
} }
@@ -290,7 +294,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
// Move the originally open tabs to the end. // Move the originally open tabs to the end.
if (initialTabs) { if (initialTabs) {
@@ -6656,6 +6691,25 @@ var SessionStoreInternal = { @@ -6674,6 +6713,25 @@ var SessionStoreInternal = {
// Most of tabData has been restored, now continue with restoring // Most of tabData has been restored, now continue with restoring
// attributes that may trigger external events. // attributes that may trigger external events.
@@ -316,7 +320,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
if (tabData.pinned) { if (tabData.pinned) {
tabbrowser.pinTab(tab); tabbrowser.pinTab(tab);
@@ -6838,6 +6892,9 @@ var SessionStoreInternal = { @@ -6859,6 +6917,9 @@ var SessionStoreInternal = {
aWindow.gURLBar.readOnly = false; aWindow.gURLBar.readOnly = false;
} }
} }
@@ -326,7 +330,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
let promiseParts = Promise.withResolvers(); let promiseParts = Promise.withResolvers();
aWindow.setTimeout(() => { aWindow.setTimeout(() => {
@@ -7633,7 +7690,7 @@ var SessionStoreInternal = { @@ -7654,7 +7715,7 @@ var SessionStoreInternal = {
let groupsToSave = new Map(); let groupsToSave = new Map();
for (let tIndex = 0; tIndex < window.tabs.length; ) { for (let tIndex = 0; tIndex < window.tabs.length; ) {
@@ -335,7 +339,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
// Adjust window.selected // Adjust window.selected
if (tIndex + 1 < window.selected) { if (tIndex + 1 < window.selected) {
window.selected -= 1; window.selected -= 1;
@@ -7648,7 +7705,7 @@ var SessionStoreInternal = { @@ -7669,7 +7730,7 @@ var SessionStoreInternal = {
); );
// We don't want to increment tIndex here. // We don't want to increment tIndex here.
continue; continue;
@@ -344,7 +348,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
// Convert any open groups into saved groups. // Convert any open groups into saved groups.
let groupStateToSave = window.groups.find( let groupStateToSave = window.groups.find(
groupState => groupState.id == window.tabs[tIndex].groupId groupState => groupState.id == window.tabs[tIndex].groupId
@@ -8193,7 +8250,6 @@ var SessionStoreInternal = { @@ -8233,7 +8294,6 @@ var SessionStoreInternal = {
timer.initWithCallback( timer.initWithCallback(
function () { function () {
if (beats <= 0) { if (beats <= 0) {
@@ -352,7 +356,7 @@ index 11191a82a0f0dc6eee60f9de52a63bc6085c3981..f995c3b297c53aa6ee2219bfc09515ee
Glean.sessionRestore.shutdownFlushAllOutcomes.timed_out.add(1); Glean.sessionRestore.shutdownFlushAllOutcomes.timed_out.add(1);
deferred.resolve(); deferred.resolve();
} }
@@ -8671,6 +8727,7 @@ var SessionStoreInternal = { @@ -8711,6 +8771,7 @@ var SessionStoreInternal = {
if ( if (
!savedTabGroupState.tabs.length || !savedTabGroupState.tabs.length ||
this.getSavedTabGroup(savedTabGroupState.id) this.getSavedTabGroup(savedTabGroupState.id)

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/drag-and-drop.js b/browser/components/tabbrowser/content/drag-and-drop.js diff --git a/browser/components/tabbrowser/content/drag-and-drop.js b/browser/components/tabbrowser/content/drag-and-drop.js
index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b15a030046 100644 index 70b37f93c4e8ff4ad9a2452681e468d23914c1b5..dbf2d9c83dafbe0e0b4e6caf3835edc8edf9bcf4 100644
--- a/browser/components/tabbrowser/content/drag-and-drop.js --- a/browser/components/tabbrowser/content/drag-and-drop.js
+++ b/browser/components/tabbrowser/content/drag-and-drop.js +++ b/browser/components/tabbrowser/content/drag-and-drop.js
@@ -35,6 +35,9 @@ @@ -35,6 +35,9 @@
@@ -12,7 +12,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
if (isTab(element) || isSplitViewWrapper(element)) { if (isTab(element) || isSplitViewWrapper(element)) {
return element; return element;
} }
@@ -118,6 +121,9 @@ @@ -128,6 +131,9 @@
} }
let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0); let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
@@ -22,7 +22,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
if ( if (
(dropEffect == "move" || dropEffect == "copy") && (dropEffect == "move" || dropEffect == "copy") &&
document == draggedTab.ownerDocument && document == draggedTab.ownerDocument &&
@@ -138,6 +144,7 @@ @@ -148,6 +154,7 @@
!draggedTab.group.collapsed !draggedTab.group.collapsed
) { ) {
draggedTab.group.collapsed = true; draggedTab.group.collapsed = true;
@@ -30,7 +30,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
} }
if (dropEffect == "move") { if (dropEffect == "move") {
@@ -145,10 +152,6 @@ @@ -155,10 +162,6 @@
// Pinned tabs in expanded vertical mode are on a grid format and require // Pinned tabs in expanded vertical mode are on a grid format and require
// different logic to drag and drop. // different logic to drag and drop.
@@ -41,7 +41,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
this._animateTabMove(event); this._animateTabMove(event);
return; return;
} }
@@ -287,6 +290,10 @@ @@ -297,6 +300,10 @@
this._tabDropIndicator.hidden = true; this._tabDropIndicator.hidden = true;
event.stopPropagation(); event.stopPropagation();
@@ -52,7 +52,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
if (draggedTab && dropEffect == "copy") { if (draggedTab && dropEffect == "copy") {
let duplicatedDraggedTab; let duplicatedDraggedTab;
let duplicatedTabs = []; let duplicatedTabs = [];
@@ -312,12 +319,16 @@ @@ -324,12 +331,16 @@
let translateOffsetY = oldTranslateY % tabHeight; let translateOffsetY = oldTranslateY % tabHeight;
let newTranslateX = oldTranslateX - translateOffsetX; let newTranslateX = oldTranslateX - translateOffsetX;
let newTranslateY = oldTranslateY - translateOffsetY; let newTranslateY = oldTranslateY - translateOffsetY;
@@ -73,7 +73,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
if (this._tabbrowserTabs.isContainerVerticalPinnedGrid(draggedTab)) { if (this._tabbrowserTabs.isContainerVerticalPinnedGrid(draggedTab)) {
// Update both translate axis for pinned vertical expanded tabs // Update both translate axis for pinned vertical expanded tabs
@@ -392,11 +403,13 @@ @@ -404,11 +415,13 @@
this._dragToPinPromoCard, this._dragToPinPromoCard,
]; ];
let shouldPin = let shouldPin =
@@ -87,15 +87,15 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
isTab(draggedTab) && isTab(draggedTab) &&
draggedTab.pinned && draggedTab.pinned &&
this._tabbrowserTabs.arrowScrollbox.contains(event.target); this._tabbrowserTabs.arrowScrollbox.contains(event.target);
@@ -466,6 +479,7 @@ @@ -484,6 +497,7 @@
} }
} }
+ shouldTranslate = false; + shouldTranslate = false;
if (shouldTranslate) { if (shouldTranslate) {
this.#dropAnimationEndTime = Date.now() + DROP_ANIMATION_GRACE_MS;
let translationPromises = []; let translationPromises = [];
for (let item of movingTabs) { @@ -496,7 +510,7 @@
@@ -477,7 +491,7 @@
item.removeAttribute("tabdrop-samewindow"); item.removeAttribute("tabdrop-samewindow");
resolve(); resolve();
}; };
@@ -104,7 +104,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
postTransitionCleanup(); postTransitionCleanup();
} else { } else {
let onTransitionEnd = transitionendEvent => { let onTransitionEnd = transitionendEvent => {
@@ -552,7 +566,7 @@ @@ -580,7 +594,7 @@
if (tab.selected) { if (tab.selected) {
selectedTab = tab; selectedTab = tab;
indexForSelectedTab = newIndex; indexForSelectedTab = newIndex;
@@ -113,7 +113,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
const droppedIntoPinnedArea = dropIndex < gBrowser.pinnedTabCount; const droppedIntoPinnedArea = dropIndex < gBrowser.pinnedTabCount;
const newSplitView = gBrowser.adoptSplitView(tab, { const newSplitView = gBrowser.adoptSplitView(tab, {
elementIndex: droppedIntoPinnedArea elementIndex: droppedIntoPinnedArea
@@ -577,7 +591,7 @@ @@ -605,7 +619,7 @@
} }
} }
} }
@@ -122,7 +122,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
const newTab = gBrowser.adoptTab(selectedTab, { const newTab = gBrowser.adoptTab(selectedTab, {
elementIndex: indexForSelectedTab, elementIndex: indexForSelectedTab,
selectTab: selectedTab == draggedTab, selectTab: selectedTab == draggedTab,
@@ -611,10 +625,6 @@ @@ -639,10 +653,6 @@
this._tabbrowserTabs.dragAndDropElements[ this._tabbrowserTabs.dragAndDropElements[
gBrowser.pinnedTabCount + unpinnedSplitViews.length - 1 gBrowser.pinnedTabCount + unpinnedSplitViews.length - 1
]; ];
@@ -133,7 +133,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
} }
} }
} else { } else {
@@ -664,6 +674,7 @@ @@ -703,6 +713,7 @@
let nextItem = this._tabbrowserTabs.dragAndDropElements[newIndex]; let nextItem = this._tabbrowserTabs.dragAndDropElements[newIndex];
let tabGroup = isTab(nextItem) && nextItem.group; let tabGroup = isTab(nextItem) && nextItem.group;
@@ -141,12 +141,15 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
gBrowser.loadTabs(urls, { gBrowser.loadTabs(urls, {
inBackground, inBackground,
replace, replace,
@@ -705,7 +716,16 @@ @@ -744,6 +755,22 @@
this._expandGroupOnDrop(draggedTab); this._expandGroupOnDrop(draggedTab);
} }
this._resetTabsAfterDrop(draggedTab.ownerDocument); this._resetTabsAfterDrop(draggedTab);
- + if (
+ if (!dt.mozUserCancelled && dt.dropEffect == "none" && !this._isCustomizing) { + !dt.mozUserCancelled &&
+ dt.dropEffect == "none" &&
+ !this._tabbrowserTabs._isCustomizing
+ ) {
+ const moved = gZenViewSplitter.moveTabToSplitView(event, draggedTab); + const moved = gZenViewSplitter.moveTabToSplitView(event, draggedTab);
+ if (moved) { + if (moved) {
+ delete draggedTab._dragData; + delete draggedTab._dragData;
@@ -154,12 +157,14 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
+ } + }
+ } else if (dt.mozUserCancelled) { + } else if (dt.mozUserCancelled) {
+ gZenViewSplitter.onBrowserDragEndToSplit(event, true); + gZenViewSplitter.onBrowserDragEndToSplit(event, true);
+ if (gZenViewSplitter._lastOpenedTab) gZenViewSplitter._lastOpenedTab._visuallySelected = false; + if (gZenViewSplitter._lastOpenedTab) {
+ gZenViewSplitter._lastOpenedTab._visuallySelected = false;
+ } + }
+ }
if ( if (
dt.mozUserCancelled || dt.mozUserCancelled ||
dt.dropEffect != "none" || @@ -1074,11 +1101,10 @@
@@ -927,11 +947,10 @@
return this.#getHorizontalScrollboxDragTarget(event, ignoreSides); return this.#getHorizontalScrollboxDragTarget(event, ignoreSides);
} }
while (target) { while (target) {
@@ -175,7 +180,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
break; break;
} }
target = target.parentNode; target = target.parentNode;
@@ -961,6 +980,9 @@ @@ -1108,6 +1134,9 @@
return null; return null;
} }
} }
@@ -185,17 +190,36 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
return target; return target;
} }
@@ -1014,7 +1036,8 @@ @@ -1170,14 +1199,20 @@
isTabGroupLabel(draggedTab) && let releaseReservedSpace = () =>
draggedTab._dragData?.expandGroupOnDrop this.#releaseSpaceInScrolledContent(periphery);
) { if (group.collapsed) {
- draggedTab.group.collapsed = false; - // The group's tabs animate back to their full size, so hold on to the
+ draggedTab.group.collapsed = draggedTab.group.hasAttribute("has-active"); - // space reserved for them until they get there.
+ gZenFolders.animateGroupMove(draggedTab.group, true); - group.addEventListener(
- "TabGroupAnimationComplete",
- releaseReservedSpace,
- { once: true }
- );
- group.collapsed = false;
+ const expand = !group.hasAttribute("has-active");
+ if (expand) {
+ // The group's tabs animate back to their full size, so hold on to the
+ // space reserved for them until they get there.
+ group.addEventListener(
+ "TabGroupAnimationComplete",
+ releaseReservedSpace,
+ { once: true }
+ );
+ } else {
+ releaseReservedSpace();
+ }
+ group.collapsed = !expand;
+ gZenFolders.animateGroupMove(group, true);
} else {
releaseReservedSpace();
} }
} @@ -1362,7 +1397,6 @@
@@ -1206,7 +1229,6 @@
// using updateDragImage. On Linux, we can use a panel. // using updateDragImage. On Linux, we can use a panel.
if (platform == "win" || platform == "macosx") { if (platform == "win" || platform == "macosx") {
captureListener = function () { captureListener = function () {
@@ -203,7 +227,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
}; };
} else { } else {
// Create a panel to use it in setDragImage // Create a panel to use it in setDragImage
@@ -1244,7 +1266,6 @@ @@ -1400,7 +1434,6 @@
); );
dragImageOffset = dragImageOffset * scale; dragImageOffset = dragImageOffset * scale;
} }
@@ -211,7 +235,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
// _dragData.offsetX/Y give the coordinates that the mouse should be // _dragData.offsetX/Y give the coordinates that the mouse should be
// positioned relative to the corner of the new window created upon // positioned relative to the corner of the new window created upon
@@ -1263,7 +1284,7 @@ @@ -1419,7 +1452,7 @@
let dropEffect = this.getDropEffectForTabDrag(event); let dropEffect = this.getDropEffectForTabDrag(event);
let isMovingInTabStrip = !fromTabList && dropEffect == "move"; let isMovingInTabStrip = !fromTabList && dropEffect == "move";
let collapseTabGroupDuringDrag = let collapseTabGroupDuringDrag =
@@ -220,7 +244,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
tab._dragData = { tab._dragData = {
offsetX: this._tabbrowserTabs.verticalMode offsetX: this._tabbrowserTabs.verticalMode
@@ -1273,7 +1294,7 @@ @@ -1429,7 +1462,7 @@
? event.screenY - window.screenY - tabOffset ? event.screenY - window.screenY - tabOffset
: event.screenY - window.screenY, : event.screenY - window.screenY,
scrollPos: scrollPos:
@@ -229,7 +253,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
? this._tabbrowserTabs.pinnedTabsContainer.scrollPosition ? this._tabbrowserTabs.pinnedTabsContainer.scrollPosition
: this._tabbrowserTabs.arrowScrollbox.scrollPosition, : this._tabbrowserTabs.arrowScrollbox.scrollPosition,
screenX: event.screenX, screenX: event.screenX,
@@ -1320,6 +1341,7 @@ @@ -1522,6 +1555,7 @@
if (tabStripItemElement.hasAttribute("dragtarget")) { if (tabStripItemElement.hasAttribute("dragtarget")) {
return; return;
} }
@@ -237,7 +261,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
let isPinned = tab.pinned; let isPinned = tab.pinned;
let dragAndDropElements = this._tabbrowserTabs.dragAndDropElements; let dragAndDropElements = this._tabbrowserTabs.dragAndDropElements;
let isGrid = this._tabbrowserTabs.isContainerVerticalPinnedGrid(tab); let isGrid = this._tabbrowserTabs.isContainerVerticalPinnedGrid(tab);
@@ -1686,23 +1708,6 @@ @@ -1895,23 +1929,6 @@
// Slide the relevant tabs to their new position. // Slide the relevant tabs to their new position.
// non-moving tabs adjust for RTL // non-moving tabs adjust for RTL
@@ -261,7 +285,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
// moving tabs don't adjust for RTL // moving tabs don't adjust for RTL
for (let item of selectedElements) { for (let item of selectedElements) {
if ( if (
@@ -1751,7 +1756,6 @@ @@ -1960,7 +1977,6 @@
for (let item of this._tabbrowserTabs.dragAndDropElements) { for (let item of this._tabbrowserTabs.dragAndDropElements) {
delete item._moveTogetherSelectedTabsData; delete item._moveTogetherSelectedTabsData;
item = elementToMove(item); item = elementToMove(item);
@@ -269,7 +293,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
item.removeAttribute("multiselected-move-together"); item.removeAttribute("multiselected-move-together");
} }
} }
@@ -2598,7 +2602,6 @@ @@ -2812,7 +2828,6 @@
tab.style.top = ""; tab.style.top = "";
tab.style.maxWidth = ""; tab.style.maxWidth = "";
tab.style.pointerEvents = ""; tab.style.pointerEvents = "";
@@ -277,7 +301,7 @@ index 8bb1219962a1368f50b53c61041f135c68e35f31..8e72441d26883cbef7a352b00c0fe2b1
tab.removeAttribute("small-stack"); tab.removeAttribute("small-stack");
tab.removeAttribute("big-stack"); tab.removeAttribute("big-stack");
} }
@@ -2607,11 +2610,9 @@ @@ -2821,11 +2836,9 @@
)) { )) {
label.style.width = ""; label.style.width = "";
label.style.maxWidth = ""; label.style.maxWidth = "";

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/tabbrowser/content/tab-context-menu.js b/browser/components/tabbrowser/content/tab-context-menu.js diff --git a/browser/components/tabbrowser/content/tab-context-menu.js b/browser/components/tabbrowser/content/tab-context-menu.js
index 4a7cb33a4d9067d469bbe09d4cd8844581642f7a..2e2404b78deb428e57d01b8b929231f675a21323 100644 index 4a7cb33a4d9067d469bbe09d4cd8844581642f7a..d7f75471a207cccac6ca3dec49037ac30dd76163 100644
--- a/browser/components/tabbrowser/content/tab-context-menu.js --- a/browser/components/tabbrowser/content/tab-context-menu.js
+++ b/browser/components/tabbrowser/content/tab-context-menu.js +++ b/browser/components/tabbrowser/content/tab-context-menu.js
@@ -839,7 +839,8 @@ var TabContextMenu = { @@ -839,13 +839,15 @@ var TabContextMenu = {
); );
contextUnpinSelectedTabs.hidden = contextUnpinSelectedTabs.hidden =
!this.contextTab.pinned || !this.multiselected; !this.contextTab.pinned || !this.multiselected;
@@ -12,3 +12,10 @@ index 4a7cb33a4d9067d469bbe09d4cd8844581642f7a..2e2404b78deb428e57d01b8b929231f6
// Build Ask Chat items. The classic layout shows the full ask-chat submenu // Build Ask Chat items. The classic layout shows the full ask-chat submenu
// (#context_askChat); the alt layout shows only a flat "Summarize Page" item // (#context_askChat); the alt layout shows only a flat "Summarize Page" item
// (#context_askChatSummarize). Hide whichever one this layout doesn't use so // (#context_askChatSummarize). Hide whichever one this layout doesn't use so
// a pref toggle reverses cleanly.
if (!this._altTabContextMenu) {
document.getElementById("context_askChatSummarize").hidden = true;
+ document.getElementById("context_aiSeparator").hidden = true;
TabContextMenu.GenAI.buildTabMenu(
document.getElementById("context_askChat"),
this

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da5504f9d8 100644 index 43180487a2fac15b7a65fac94f233eeed9094990..ae1288974cae29da929f27b78ff8db542566eba2 100644
--- a/browser/components/tabbrowser/content/tabbrowser.js --- a/browser/components/tabbrowser/content/tabbrowser.js
+++ b/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js
@@ -513,6 +513,7 @@ @@ -514,6 +514,7 @@
* @type {MozBrowser[]} * @type {MozBrowser[]}
*/ */
get splitViewBrowsers() { get splitViewBrowsers() {
@@ -10,7 +10,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
const browsers = []; const browsers = [];
if (this.#activeSplitView) { if (this.#activeSplitView) {
for (const tab of this.#activeSplitView.tabs) { for (const tab of this.#activeSplitView.tabs) {
@@ -611,15 +612,66 @@ @@ -612,15 +613,66 @@
return this.tabContainer.visibleTabs; return this.tabContainer.visibleTabs;
} }
@@ -79,7 +79,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
setSelectedTab(val, metricsContext = null) { setSelectedTab(val, metricsContext = null) {
if (this.selectedTab === val) { if (this.selectedTab === val) {
return; return;
@@ -632,6 +684,9 @@ @@ -633,6 +685,9 @@
) { ) {
return; return;
} }
@@ -89,7 +89,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// Update the tab // Update the tab
this.tabbox.selectedTab = val; this.tabbox.selectedTab = val;
@@ -708,6 +763,10 @@ @@ -709,6 +764,10 @@
userContextId = parseInt(tabArgument.getAttribute("usercontextid"), 10); userContextId = parseInt(tabArgument.getAttribute("usercontextid"), 10);
} }
@@ -100,7 +100,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (openWindowInfo) { if (openWindowInfo) {
userContextId = openWindowInfo.originAttributes.userContextId; userContextId = openWindowInfo.originAttributes.userContextId;
} }
@@ -809,6 +868,8 @@ @@ -810,6 +869,8 @@
this.tabpanels.appendChild(panel); this.tabpanels.appendChild(panel);
let tab = this.tabs[0]; let tab = this.tabs[0];
@@ -109,7 +109,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
tab.linkedPanel = uniqueId; tab.linkedPanel = uniqueId;
this._selectedTab = tab; this._selectedTab = tab;
this._selectedBrowser = browser; this._selectedBrowser = browser;
@@ -1178,18 +1239,24 @@ @@ -1179,18 +1240,24 @@
* The context for the operation for telemetry purposes, defaults to an unknown context. * The context for the operation for telemetry purposes, defaults to an unknown context.
*/ */
pinTab(aTab, { metricsContext = this.TabMetrics.UNKNOWN_CONTEXT } = {}) { pinTab(aTab, { metricsContext = this.TabMetrics.UNKNOWN_CONTEXT } = {}) {
@@ -135,7 +135,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
aTab.setAttribute("pinned", "true"); aTab.setAttribute("pinned", "true");
this._updateTabBarForPinnedTabs(); this._updateTabBarForPinnedTabs();
@@ -1206,16 +1273,25 @@ @@ -1207,16 +1274,25 @@
* The context for the operation for telemetry purposes, defaults to an unknown context. * The context for the operation for telemetry purposes, defaults to an unknown context.
*/ */
unpinTab(aTab, { metricsContext = this.TabMetrics.UNKNOWN_CONTEXT } = {}) { unpinTab(aTab, { metricsContext = this.TabMetrics.UNKNOWN_CONTEXT } = {}) {
@@ -162,7 +162,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
}); });
aTab.style.marginInlineStart = ""; aTab.style.marginInlineStart = "";
@@ -1430,6 +1506,9 @@ @@ -1432,6 +1508,9 @@
let LOCAL_PROTOCOLS = ["chrome:", "about:", "resource:", "data:"]; let LOCAL_PROTOCOLS = ["chrome:", "about:", "resource:", "data:"];
@@ -172,7 +172,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if ( if (
aIconURL && aIconURL &&
!LOCAL_PROTOCOLS.some(protocol => aIconURL.startsWith(protocol)) !LOCAL_PROTOCOLS.some(protocol => aIconURL.startsWith(protocol))
@@ -1439,6 +1518,9 @@ @@ -1441,6 +1520,9 @@
); );
return; return;
} }
@@ -182,7 +182,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
let browser = this.getBrowserForTab(aTab); let browser = this.getBrowserForTab(aTab);
browser.mIconURL = aIconURL; browser.mIconURL = aIconURL;
@@ -1761,7 +1843,6 @@ @@ -1763,7 +1845,6 @@
// Preview mode should not reset the owner // Preview mode should not reset the owner
if (!this.#previewMode && !oldTab.selected) { if (!this.#previewMode && !oldTab.selected) {
@@ -190,7 +190,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
let lastRelatedTab = this.#lastRelatedTabMap.get(oldTab); let lastRelatedTab = this.#lastRelatedTabMap.get(oldTab);
@@ -1852,6 +1933,7 @@ @@ -1854,6 +1935,7 @@
if (!this.#previewMode) { if (!this.#previewMode) {
newTab.recordTimeFromUnloadToReload(); newTab.recordTimeFromUnloadToReload();
newTab.updateLastAccessed(); newTab.updateLastAccessed();
@@ -198,7 +198,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
oldTab.updateLastAccessed(); oldTab.updateLastAccessed();
// if this is the foreground window, update the last-seen timestamps. // if this is the foreground window, update the last-seen timestamps.
if (this.documentGlobal == BrowserWindowTracker.getTopWindow()) { if (this.documentGlobal == BrowserWindowTracker.getTopWindow()) {
@@ -2066,6 +2148,9 @@ @@ -2068,6 +2150,9 @@
} }
let activeEl = document.activeElement; let activeEl = document.activeElement;
@@ -208,7 +208,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// If focus is on the old tab, move it to the new tab. // If focus is on the old tab, move it to the new tab.
if (activeEl == oldTab) { if (activeEl == oldTab) {
newTab.focus(); newTab.focus();
@@ -2104,7 +2189,7 @@ @@ -2106,7 +2191,7 @@
// Focus the location bar if it was previously focused for that tab. // Focus the location bar if it was previously focused for that tab.
// In full screen mode, only bother making the location bar visible // In full screen mode, only bother making the location bar visible
// if the tab is a blank one. // if the tab is a blank one.
@@ -217,7 +217,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
let selectURL = () => { let selectURL = () => {
if (this._asyncTabSwitching) { if (this._asyncTabSwitching) {
// Set _awaitingSetURI flag to suppress popup notification // Set _awaitingSetURI flag to suppress popup notification
@@ -2392,7 +2477,12 @@ @@ -2394,7 +2479,12 @@
return this._setTabLabel(aTab, aLabel); return this._setTabLabel(aTab, aLabel);
} }
@@ -231,7 +231,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (!aLabel || (isURL && /^about:reader\?url=/.test(aLabel))) { if (!aLabel || (isURL && /^about:reader\?url=/.test(aLabel))) {
return false; return false;
} }
@@ -2518,7 +2608,7 @@ @@ -2520,7 +2610,7 @@
newIndex = this.selectedTab._tPos + 1; newIndex = this.selectedTab._tPos + 1;
} }
@@ -240,7 +240,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (this.isTabGroupLabel(targetTab)) { if (this.isTabGroupLabel(targetTab)) {
throw new Error( throw new Error(
"Replacing a tab group label with a tab is not supported" "Replacing a tab group label with a tab is not supported"
@@ -2793,6 +2883,7 @@ @@ -2795,6 +2885,7 @@
uriIsAboutBlank, uriIsAboutBlank,
userContextId, userContextId,
skipLoad, skipLoad,
@@ -248,7 +248,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} = {}) { } = {}) {
let b = document.createXULElement("browser"); let b = document.createXULElement("browser");
// Use the JSM global to create the permanentKey, so that if the // Use the JSM global to create the permanentKey, so that if the
@@ -2866,8 +2957,7 @@ @@ -2868,8 +2959,7 @@
// we use a different attribute name for this? // we use a different attribute name for this?
b.setAttribute("name", name); b.setAttribute("name", name);
} }
@@ -258,7 +258,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
b.setAttribute("transparent", "true"); b.setAttribute("transparent", "true");
} }
@@ -3022,7 +3112,7 @@ @@ -3024,7 +3114,7 @@
let panel = this.getPanel(browser); let panel = this.getPanel(browser);
let uniqueId = this._generateUniquePanelID(); let uniqueId = this._generateUniquePanelID();
@@ -267,7 +267,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
aTab.linkedPanel = uniqueId; aTab.linkedPanel = uniqueId;
// Inject the <browser> into the DOM if necessary. // Inject the <browser> into the DOM if necessary.
@@ -3082,8 +3172,8 @@ @@ -3084,8 +3174,8 @@
// If we transitioned from one browser to two browsers, we need to set // If we transitioned from one browser to two browsers, we need to set
// hasSiblings=false on both the existing browser and the new browser. // hasSiblings=false on both the existing browser and the new browser.
if (this.tabs.length == 2) { if (this.tabs.length == 2) {
@@ -278,7 +278,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} else { } else {
aTab.linkedBrowser.browsingContext.hasSiblings = this.tabs.length > 1; aTab.linkedBrowser.browsingContext.hasSiblings = this.tabs.length > 1;
} }
@@ -3268,7 +3358,6 @@ @@ -3270,7 +3360,6 @@
this.selectedTab = this.addTrustedTab(BROWSER_NEW_TAB_URL, { this.selectedTab = this.addTrustedTab(BROWSER_NEW_TAB_URL, {
tabIndex: tab._tPos + 1, tabIndex: tab._tPos + 1,
userContextId: tab.userContextId, userContextId: tab.userContextId,
@@ -286,7 +286,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
focusUrlBar: true, focusUrlBar: true,
}); });
resolve(this.selectedBrowser); resolve(this.selectedBrowser);
@@ -3378,6 +3467,10 @@ @@ -3380,6 +3469,10 @@
schemelessInput, schemelessInput,
hasValidUserGestureActivation = false, hasValidUserGestureActivation = false,
textDirectiveUserActivation = false, textDirectiveUserActivation = false,
@@ -297,7 +297,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} = {} } = {}
) { ) {
// all callers of addTab that pass a params object need to pass // all callers of addTab that pass a params object need to pass
@@ -3388,10 +3481,25 @@ @@ -3390,10 +3483,25 @@
); );
} }
@@ -323,7 +323,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// If we're opening a foreground tab, set the owner by default. // If we're opening a foreground tab, set the owner by default.
ownerTab ??= inBackground ? null : this.selectedTab; ownerTab ??= inBackground ? null : this.selectedTab;
@@ -3399,6 +3507,7 @@ @@ -3401,6 +3509,7 @@
if (this.selectedTab.owner) { if (this.selectedTab.owner) {
this.selectedTab.owner = null; this.selectedTab.owner = null;
} }
@@ -331,7 +331,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// Find the tab that opened this one, if any. This is used for // Find the tab that opened this one, if any. This is used for
// determining positioning, and inherited attributes such as the // determining positioning, and inherited attributes such as the
@@ -3451,6 +3560,22 @@ @@ -3453,6 +3562,22 @@
noInitialLabel, noInitialLabel,
skipBackgroundNotify, skipBackgroundNotify,
}); });
@@ -354,7 +354,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (insertTab) { if (insertTab) {
// Insert the tab into the tab container in the correct position. // Insert the tab into the tab container in the correct position.
this.#insertTabAtIndex(t, { this.#insertTabAtIndex(t, {
@@ -3459,6 +3584,7 @@ @@ -3461,6 +3586,7 @@
ownerTab, ownerTab,
openerTab, openerTab,
pinned, pinned,
@@ -362,7 +362,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
bulkOrderedOpen, bulkOrderedOpen,
tabGroup: tabGroup ?? openerTab?.group, tabGroup: tabGroup ?? openerTab?.group,
}); });
@@ -3477,6 +3603,7 @@ @@ -3479,6 +3605,7 @@
openWindowInfo, openWindowInfo,
skipLoad, skipLoad,
triggeringRemoteType, triggeringRemoteType,
@@ -370,7 +370,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
})); }));
if (focusUrlBar) { if (focusUrlBar) {
@@ -3601,6 +3728,12 @@ @@ -3603,6 +3730,12 @@
} }
} }
@@ -383,7 +383,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// Additionally send pinned tab events // Additionally send pinned tab events
if (pinned) { if (pinned) {
this.#notifyPinnedStatus(t); this.#notifyPinnedStatus(t);
@@ -3611,6 +3744,15 @@ @@ -3613,6 +3746,15 @@
if (!inBackground) { if (!inBackground) {
this.selectedTab = t; this.selectedTab = t;
} }
@@ -399,7 +399,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
return t; return t;
} }
@@ -3834,6 +3976,7 @@ @@ -3836,6 +3978,7 @@
insertBefore = null, insertBefore = null,
isAdoptingGroup = false, isAdoptingGroup = false,
metricsContext = this.TabMetrics.UNKNOWN_CONTEXT, metricsContext = this.TabMetrics.UNKNOWN_CONTEXT,
@@ -407,7 +407,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} = {} } = {}
) { ) {
if ( if (
@@ -3844,9 +3987,6 @@ @@ -3846,9 +3989,6 @@
!this.isSplitViewWrapper(tabOrSplitView) !this.isSplitViewWrapper(tabOrSplitView)
) )
) { ) {
@@ -417,7 +417,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
if (!color) { if (!color) {
@@ -3867,9 +4007,14 @@ @@ -3869,9 +4009,14 @@
label, label,
isAdoptingGroup isAdoptingGroup
); );
@@ -434,7 +434,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
); );
group.addTabs(tabsAndSplitViews, metricsContext); group.addTabs(tabsAndSplitViews, metricsContext);
@@ -3973,7 +4118,7 @@ @@ -3975,7 +4120,7 @@
} }
this.#handleTabMove(tab, () => this.#handleTabMove(tab, () =>
@@ -443,7 +443,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
); );
} }
@@ -4059,6 +4204,7 @@ @@ -4061,6 +4206,7 @@
color: group.color, color: group.color,
insertBefore: newTabs[0], insertBefore: newTabs[0],
isAdoptingGroup: true, isAdoptingGroup: true,
@@ -451,7 +451,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
}); });
} }
@@ -4269,6 +4415,7 @@ @@ -4271,6 +4417,7 @@
openWindowInfo, openWindowInfo,
skipLoad, skipLoad,
triggeringRemoteType, triggeringRemoteType,
@@ -459,7 +459,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
) { ) {
// If we don't have a preferred remote type (or it is `NOT_REMOTE`), and // If we don't have a preferred remote type (or it is `NOT_REMOTE`), and
@@ -4329,6 +4476,7 @@ @@ -4331,6 +4478,7 @@
openWindowInfo, openWindowInfo,
name, name,
skipLoad, skipLoad,
@@ -467,7 +467,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
}); });
} }
@@ -4542,9 +4690,9 @@ @@ -4544,9 +4692,9 @@
} }
// Add a new tab if needed. // Add a new tab if needed.
@@ -479,7 +479,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
let url = "about:blank"; let url = "about:blank";
if (tabData.entries?.length) { if (tabData.entries?.length) {
@@ -4577,8 +4725,10 @@ @@ -4579,8 +4727,10 @@
insertTab: false, insertTab: false,
skipLoad: true, skipLoad: true,
preferredRemoteType, preferredRemoteType,
@@ -491,7 +491,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (select) { if (select) {
tabToSelect = tab; tabToSelect = tab;
} }
@@ -4600,7 +4750,8 @@ @@ -4602,7 +4752,8 @@
this.pinTab(tab); this.pinTab(tab);
// Then ensure all the tab open/pinning information is sent. // Then ensure all the tab open/pinning information is sent.
this._fireTabOpen(tab, {}); this._fireTabOpen(tab, {});
@@ -501,7 +501,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
let { groupId } = tabData; let { groupId } = tabData;
const tabGroup = tabGroupWorkingData.get(groupId); const tabGroup = tabGroupWorkingData.get(groupId);
// if a tab refers to a tab group we don't know, skip any group // if a tab refers to a tab group we don't know, skip any group
@@ -4620,7 +4771,10 @@ @@ -4622,7 +4773,10 @@
tabGroup.stateData.id, tabGroup.stateData.id,
tabGroup.stateData.color, tabGroup.stateData.color,
tabGroup.stateData.collapsed, tabGroup.stateData.collapsed,
@@ -513,7 +513,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
); );
tabsFragment.appendChild(tabGroup.node); tabsFragment.appendChild(tabGroup.node);
} }
@@ -4675,9 +4829,21 @@ @@ -4677,9 +4831,21 @@
// to remove the old selected tab. // to remove the old selected tab.
if (tabToSelect) { if (tabToSelect) {
let leftoverTab = this.selectedTab; let leftoverTab = this.selectedTab;
@@ -535,7 +535,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (tabs.length > 1 || !tabs[0].selected) { if (tabs.length > 1 || !tabs[0].selected) {
this._updateTabsAfterInsert(); this._updateTabsAfterInsert();
@@ -4882,11 +5048,17 @@ @@ -4884,11 +5050,17 @@
if (ownerTab) { if (ownerTab) {
tab.owner = ownerTab; tab.owner = ownerTab;
} }
@@ -554,7 +554,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if ( if (
!bulkOrderedOpen && !bulkOrderedOpen &&
((openerTab && ((openerTab &&
@@ -4898,7 +5070,7 @@ @@ -4900,7 +5072,7 @@
let lastRelatedTab = let lastRelatedTab =
openerTab && this.#lastRelatedTabMap.get(openerTab); openerTab && this.#lastRelatedTabMap.get(openerTab);
let previousTab = lastRelatedTab || openerTab || this.selectedTab; let previousTab = lastRelatedTab || openerTab || this.selectedTab;
@@ -563,7 +563,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
tabGroup = previousTab.group; tabGroup = previousTab.group;
} }
if ( if (
@@ -4914,7 +5086,7 @@ @@ -4916,7 +5088,7 @@
previousTab.splitview previousTab.splitview
) + 1; ) + 1;
} else if (previousTab.visible) { } else if (previousTab.visible) {
@@ -572,7 +572,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} else if (previousTab == FirefoxViewHandler.tab) { } else if (previousTab == FirefoxViewHandler.tab) {
elementIndex = 0; elementIndex = 0;
} }
@@ -4942,14 +5114,14 @@ @@ -4944,14 +5116,14 @@
} }
// Ensure index is within bounds. // Ensure index is within bounds.
if (tab.pinned) { if (tab.pinned) {
@@ -591,7 +591,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (pinned && !itemAfter?.pinned) { if (pinned && !itemAfter?.pinned) {
itemAfter = null; itemAfter = null;
@@ -4966,7 +5138,7 @@ @@ -4968,7 +5140,7 @@
this.tabContainer._invalidateCachedTabs(); this.tabContainer._invalidateCachedTabs();
@@ -600,7 +600,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if ( if (
(this.isTab(itemAfter) && itemAfter.group == tabGroup) || (this.isTab(itemAfter) && itemAfter.group == tabGroup) ||
this.isSplitViewWrapper(itemAfter) this.isSplitViewWrapper(itemAfter)
@@ -4997,7 +5169,11 @@ @@ -4999,7 +5171,11 @@
const tabContainer = pinned const tabContainer = pinned
? this.tabContainer.pinnedTabsContainer ? this.tabContainer.pinnedTabsContainer
: this.tabContainer; : this.tabContainer;
@@ -612,7 +612,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
if (tab.group?.collapsed) { if (tab.group?.collapsed) {
@@ -5012,6 +5188,7 @@ @@ -5014,6 +5190,7 @@
if (pinned) { if (pinned) {
this._updateTabBarForPinnedTabs(); this._updateTabBarForPinnedTabs();
} }
@@ -620,7 +620,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
TabBarVisibility.update(); TabBarVisibility.update();
} }
@@ -5568,6 +5745,7 @@ @@ -5577,6 +5754,7 @@
metricsContext, metricsContext,
} = {} } = {}
) { ) {
@@ -628,7 +628,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// When 'closeWindowWithLastTab' pref is enabled, closing all tabs // When 'closeWindowWithLastTab' pref is enabled, closing all tabs
// can be considered equivalent to closing the window. // can be considered equivalent to closing the window.
if ( if (
@@ -5678,6 +5856,7 @@ @@ -5687,6 +5865,7 @@
closedTabCount -= 1; closedTabCount -= 1;
} }
} }
@@ -636,7 +636,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (closedTabCount > 0) { if (closedTabCount > 0) {
this.recordTabMetrics( this.recordTabMetrics(
@@ -5730,6 +5909,14 @@ @@ -5761,6 +5940,14 @@
return; return;
} }
@@ -651,7 +651,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
let isVisibleTab = aTab.visible; let isVisibleTab = aTab.visible;
// We have to sample the tab width now, since _beginRemoveTab might // We have to sample the tab width now, since _beginRemoveTab might
// end up modifying the DOM in such a way that aTab gets a new // end up modifying the DOM in such a way that aTab gets a new
@@ -5737,6 +5924,9 @@ @@ -5768,6 +5955,9 @@
// state). // state).
let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width; let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width;
let isLastTab = this.#isLastTabInWindow(aTab); let isLastTab = this.#isLastTabInWindow(aTab);
@@ -661,7 +661,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if ( if (
!this._beginRemoveTab(aTab, { !this._beginRemoveTab(aTab, {
closeWindowFastpath: true, closeWindowFastpath: true,
@@ -5747,13 +5937,14 @@ @@ -5778,13 +5968,14 @@
metricsContext, metricsContext,
}) })
) { ) {
@@ -677,7 +677,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
let lockTabSizing = let lockTabSizing =
!this.tabContainer.verticalMode && !this.tabContainer.verticalMode &&
!aTab.pinned && !aTab.pinned &&
@@ -5784,7 +5975,13 @@ @@ -5815,7 +6006,13 @@
// We're not animating, so we can cancel the animation stopwatch. // We're not animating, so we can cancel the animation stopwatch.
Glean.browserTabclose.timeAnim.cancel(aTab._closeTimeAnimTimerId); Glean.browserTabclose.timeAnim.cancel(aTab._closeTimeAnimTimerId);
aTab._closeTimeAnimTimerId = null; aTab._closeTimeAnimTimerId = null;
@@ -692,7 +692,18 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
return; return;
} }
@@ -5827,7 +6024,7 @@ @@ -5855,7 +6052,9 @@
get #shouldCloseWindowWithLastTab() {
return (
!window.toolbar.visible ||
- Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab")
+ (Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab") &&
+ !gZenWorkspaces._isClosingWindow &&
+ !gZenWorkspaces._removedByStartupPage)
);
}
@@ -5871,7 +6070,7 @@
*/ */
#isLastTabInWindow(tab) { #isLastTabInWindow(tab) {
for (const otherTab of this.tabs) { for (const otherTab of this.tabs) {
@@ -701,16 +712,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
return false; return false;
} }
} }
@@ -5917,7 +6114,7 @@ @@ -5982,6 +6181,7 @@
closeWindowWithLastTab != null
? closeWindowWithLastTab
: !window.toolbar.visible ||
- Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab");
+ Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab") && !gZenWorkspaces._isClosingWindow && !gZenWorkspaces._removedByStartupPage;
if (closeWindow) {
// We've already called beforeunload on all the relevant tabs if we get here,
@@ -5941,6 +6138,7 @@
newTab = true; newTab = true;
} }
@@ -718,8 +720,8 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
aTab._endRemoveArgs = [closeWindow, newTab]; aTab._endRemoveArgs = [closeWindow, newTab];
// swapBrowsersAndCloseOther will take care of closing the window without animation. // swapBrowsersAndCloseOther will take care of closing the window without animation.
@@ -5982,13 +6180,7 @@ @@ -6029,13 +6229,7 @@
aTab._mouseleave(); }
if (newTab) { if (newTab) {
- this.addTrustedTab(BROWSER_NEW_TAB_URL, { - this.addTrustedTab(BROWSER_NEW_TAB_URL, {
@@ -733,7 +735,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} else { } else {
TabBarVisibility.update(); TabBarVisibility.update();
} }
@@ -6128,6 +6320,7 @@ @@ -6192,6 +6386,7 @@
this.tabs[i]._tPos = i; this.tabs[i]._tPos = i;
} }
@@ -741,7 +743,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (!this.#windowIsClosing) { if (!this.#windowIsClosing) {
// update tab close buttons state // update tab close buttons state
this.tabContainer._updateCloseButtons(); this.tabContainer._updateCloseButtons();
@@ -6313,6 +6506,7 @@ @@ -6377,6 +6572,7 @@
memory_after: await getTotalMemoryUsage(), memory_after: await getTotalMemoryUsage(),
time_to_unload_in_ms: timeElapsed, time_to_unload_in_ms: timeElapsed,
}); });
@@ -749,7 +751,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
/** /**
@@ -6358,6 +6552,7 @@ @@ -6422,6 +6618,7 @@
} }
let excludeTabs = new Set(aExcludeTabs); let excludeTabs = new Set(aExcludeTabs);
@@ -757,7 +759,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// If this tab has a successor, it should be selectable, since // If this tab has a successor, it should be selectable, since
// hiding or closing a tab removes that tab as a successor. // hiding or closing a tab removes that tab as a successor.
@@ -6370,13 +6565,13 @@ @@ -6434,13 +6631,13 @@
!excludeTabs.has(aTab.owner) && !excludeTabs.has(aTab.owner) &&
Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose") Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")
) { ) {
@@ -773,7 +775,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
); );
if (Services.prefs.getBoolPref("browser.tabs.selectMRUOnClose", false)) { if (Services.prefs.getBoolPref("browser.tabs.selectMRUOnClose", false)) {
@@ -6392,6 +6587,13 @@ @@ -6456,6 +6653,13 @@
} }
} }
@@ -787,7 +789,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
let tab = this.tabContainer.findNextTab(aTab, { let tab = this.tabContainer.findNextTab(aTab, {
direction: 1, direction: 1,
filter: _tab => remainingTabs.includes(_tab), filter: _tab => remainingTabs.includes(_tab),
@@ -6405,7 +6607,7 @@ @@ -6469,7 +6673,7 @@
} }
if (tab) { if (tab) {
@@ -796,7 +798,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
// If no qualifying visible tab was found, see if there is a tab in // If no qualifying visible tab was found, see if there is a tab in
@@ -6426,7 +6628,7 @@ @@ -6490,7 +6694,7 @@
}); });
} }
@@ -805,7 +807,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
_blurTab(aTab) { _blurTab(aTab) {
@@ -6437,7 +6639,7 @@ @@ -6501,7 +6705,7 @@
* @returns {boolean} * @returns {boolean}
* False if swapping isn't permitted, true otherwise. * False if swapping isn't permitted, true otherwise.
*/ */
@@ -814,7 +816,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// Do not allow transfering a private tab to a non-private window // Do not allow transfering a private tab to a non-private window
// and vice versa. // and vice versa.
if ( if (
@@ -6491,6 +6693,7 @@ @@ -6555,6 +6759,7 @@
// fire the beforeunload event in the process. Close the other // fire the beforeunload event in the process. Close the other
// window if this was its last tab. // window if this was its last tab.
if ( if (
@@ -822,7 +824,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
!remoteBrowser._beginRemoveTab(aOtherTab, { !remoteBrowser._beginRemoveTab(aOtherTab, {
adoptedByTab: aOurTab, adoptedByTab: aOurTab,
closeWindowWithLastTab: true, closeWindowWithLastTab: true,
@@ -6502,7 +6705,7 @@ @@ -6566,7 +6771,7 @@
// If this is the last tab of the window, hide the window // If this is the last tab of the window, hide the window
// immediately without animation before the docshell swap, to avoid // immediately without animation before the docshell swap, to avoid
// about:blank being painted. // about:blank being painted.
@@ -831,7 +833,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (closeWindow) { if (closeWindow) {
let win = aOtherTab.documentGlobal; let win = aOtherTab.documentGlobal;
win.windowUtils.suppressAnimation(true); win.windowUtils.suppressAnimation(true);
@@ -6636,11 +6839,13 @@ @@ -6700,11 +6905,13 @@
} }
// Finish tearing down the tab that's going away. // Finish tearing down the tab that's going away.
@@ -845,7 +847,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
this.setTabTitle(aOurTab); this.setTabTitle(aOurTab);
@@ -6860,10 +7065,10 @@ @@ -6928,10 +7135,10 @@
SessionStore.deleteCustomTabValue(aTab, "hiddenBy"); SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
} }
@@ -858,7 +860,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
aTab.selected || aTab.selected ||
aTab.closing || aTab.closing ||
// Tabs that are sharing the screen, microphone or camera cannot be hidden. // Tabs that are sharing the screen, microphone or camera cannot be hidden.
@@ -6923,7 +7128,8 @@ @@ -6991,7 +7198,8 @@
* @param {object} [aOptions={}] * @param {object} [aOptions={}]
* Key-value pairs that will be serialized into the features string. * Key-value pairs that will be serialized into the features string.
*/ */
@@ -868,7 +870,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (this.tabs.length == 1) { if (this.tabs.length == 1) {
return null; return null;
} }
@@ -6940,7 +7146,7 @@ @@ -7008,7 +7216,7 @@
// tell a new window to take the "dropped" tab // tell a new window to take the "dropped" tab
let args = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); let args = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
args.appendElement(aTab.splitview ?? aTab); args.appendElement(aTab.splitview ?? aTab);
@@ -877,7 +879,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
private: PrivateBrowsingUtils.isWindowPrivate(window), private: PrivateBrowsingUtils.isWindowPrivate(window),
features: Object.entries(aOptions) features: Object.entries(aOptions)
.map(([key, value]) => `${key}=${value}`) .map(([key, value]) => `${key}=${value}`)
@@ -6948,6 +7154,8 @@ @@ -7016,6 +7224,8 @@
openerWindow: window, openerWindow: window,
args, args,
}); });
@@ -886,7 +888,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
/** /**
@@ -7074,7 +7282,7 @@ @@ -7142,7 +7352,7 @@
* `true` if element is a `<tab-group>` * `true` if element is a `<tab-group>`
*/ */
isTabGroup(element) { isTabGroup(element) {
@@ -895,7 +897,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
/** /**
@@ -7146,8 +7354,8 @@ @@ -7214,8 +7424,8 @@
} }
// Don't allow mixing pinned and unpinned tabs. // Don't allow mixing pinned and unpinned tabs.
@@ -906,7 +908,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} else { } else {
tabIndex = Math.max(tabIndex, this.pinnedTabCount); tabIndex = Math.max(tabIndex, this.pinnedTabCount);
} }
@@ -7193,8 +7401,8 @@ @@ -7261,8 +7471,8 @@
this.#handleTabMove( this.#handleTabMove(
element, element,
() => { () => {
@@ -917,7 +919,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
neighbor = neighbor.group; neighbor = neighbor.group;
} }
if (neighbor?.splitview) { if (neighbor?.splitview) {
@@ -7205,6 +7413,12 @@ @@ -7273,6 +7483,12 @@
return; return;
} }
} }
@@ -930,7 +932,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
if (movingForwards && neighbor) { if (movingForwards && neighbor) {
neighbor.after(element); neighbor.after(element);
@@ -7278,23 +7492,31 @@ @@ -7346,23 +7562,31 @@
) { ) {
if (this.isTabGroupLabel(targetElement)) { if (this.isTabGroupLabel(targetElement)) {
targetElement = targetElement.group; targetElement = targetElement.group;
@@ -968,7 +970,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} else if (!element.pinned && targetElement && targetElement.pinned) { } else if (!element.pinned && targetElement && targetElement.pinned) {
// If the caller asks to move an unpinned element next to a pinned // If the caller asks to move an unpinned element next to a pinned
// tab, move the unpinned element to be the first unpinned element // tab, move the unpinned element to be the first unpinned element
@@ -7307,12 +7529,35 @@ @@ -7375,12 +7599,35 @@
// move the tab group right before the first unpinned tab. // move the tab group right before the first unpinned tab.
// 4. Moving a tab group and the first unpinned tab is grouped: // 4. Moving a tab group and the first unpinned tab is grouped:
// move the tab group right before the first unpinned tab's tab group. // move the tab group right before the first unpinned tab's tab group.
@@ -1005,7 +1007,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// We want to include the splitview wrapper if it's the targetElement, but // We want to include the splitview wrapper if it's the targetElement, but
// not in the case where we want to reverse tabs within the same splitview. // not in the case where we want to reverse tabs within the same splitview.
@@ -7321,6 +7566,7 @@ @@ -7389,6 +7636,7 @@
} }
let getContainer = () => let getContainer = () =>
@@ -1013,7 +1015,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
element.pinned element.pinned
? this.tabContainer.pinnedTabsContainer ? this.tabContainer.pinnedTabsContainer
: this.tabContainer; : this.tabContainer;
@@ -7329,11 +7575,15 @@ @@ -7397,11 +7645,15 @@
element, element,
() => { () => {
if (moveBefore) { if (moveBefore) {
@@ -1030,7 +1032,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
}, },
{ metricsContext } { metricsContext }
@@ -7411,11 +7661,15 @@ @@ -7479,11 +7731,15 @@
* The context for the operation for telemetry purposes. * The context for the operation for telemetry purposes.
*/ */
moveTabToExistingGroup(aTab, aGroup, { metricsContext } = {}) { moveTabToExistingGroup(aTab, aGroup, { metricsContext } = {}) {
@@ -1049,7 +1051,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
} }
if (aTab.group && aTab.group.id === aGroup.id) { if (aTab.group && aTab.group.id === aGroup.id) {
return; return;
@@ -7489,6 +7743,7 @@ @@ -7557,6 +7813,7 @@
let state = { let state = {
tabIndex: tab._tPos, tabIndex: tab._tPos,
@@ -1057,7 +1059,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
}; };
if (tab.visible) { if (tab.visible) {
state.elementIndex = tab.elementIndex; state.elementIndex = tab.elementIndex;
@@ -7527,7 +7782,7 @@ @@ -7595,7 +7852,7 @@
let changedSplitView = let changedSplitView =
previousTabState.splitViewId != currentTabState.splitViewId; previousTabState.splitViewId != currentTabState.splitViewId;
@@ -1066,7 +1068,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
tab.dispatchEvent( tab.dispatchEvent(
new CustomEvent("TabMove", { new CustomEvent("TabMove", {
bubbles: true, bubbles: true,
@@ -7579,6 +7834,10 @@ @@ -7647,6 +7904,10 @@
moveActionCallback(); moveActionCallback();
@@ -1077,7 +1079,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// Clear tabs cache after moving nodes because the order of tabs may have // Clear tabs cache after moving nodes because the order of tabs may have
// changed. // changed.
this.tabContainer._invalidateCachedTabs(); this.tabContainer._invalidateCachedTabs();
@@ -7626,7 +7885,22 @@ @@ -7694,7 +7955,22 @@
* @returns {object} * @returns {object}
* The new tab in the current window, null if the tab couldn't be adopted. * The new tab in the current window, null if the tab couldn't be adopted.
*/ */
@@ -1101,7 +1103,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
// Swap the dropped tab with a new one we create and then close // Swap the dropped tab with a new one we create and then close
// it in the other window (making it seem to have moved between // it in the other window (making it seem to have moved between
// windows). We also ensure that the tab we create to swap into has // windows). We also ensure that the tab we create to swap into has
@@ -7669,6 +7943,8 @@ @@ -7737,6 +8013,8 @@
} }
params.skipLoad = true; params.skipLoad = true;
let newTab = this.addWebTab("about:blank", params); let newTab = this.addWebTab("about:blank", params);
@@ -1110,7 +1112,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
aTab.container.tabDragAndDrop.finishAnimateTabMove(); aTab.container.tabDragAndDrop.finishAnimateTabMove();
@@ -8448,7 +8724,7 @@ @@ -8516,7 +8794,7 @@
// preventDefault(). It will still raise the window if appropriate. // preventDefault(). It will still raise the window if appropriate.
return; return;
} }
@@ -1119,7 +1121,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
window.focus(); window.focus();
aEvent.preventDefault(); aEvent.preventDefault();
} }
@@ -8465,7 +8741,6 @@ @@ -8533,7 +8811,6 @@
on_TabGroupCollapse(aEvent) { on_TabGroupCollapse(aEvent) {
aEvent.target.tabs.forEach(tab => { aEvent.target.tabs.forEach(tab => {
@@ -1127,7 +1129,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
}); });
} }
@@ -8819,7 +9094,9 @@ @@ -8887,7 +9164,9 @@
let filter = this.#tabFilters.get(tab); let filter = this.#tabFilters.get(tab);
if (filter) { if (filter) {
@@ -1137,7 +1139,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
let listener = this.#tabListeners.get(tab); let listener = this.#tabListeners.get(tab);
if (listener) { if (listener) {
@@ -9604,6 +9881,7 @@ @@ -9676,6 +9955,7 @@
aWebProgress.isTopLevel aWebProgress.isTopLevel
) { ) {
this._tab.setAttribute("busy", "true"); this._tab.setAttribute("busy", "true");
@@ -1145,7 +1147,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
gBrowser._tabAttrModified(this._tab, ["busy"]); gBrowser._tabAttrModified(this._tab, ["busy"]);
this._tab._notselectedsinceload = !this._tab.selected; this._tab._notselectedsinceload = !this._tab.selected;
} }
@@ -9684,6 +9962,7 @@ @@ -9756,6 +10036,7 @@
// known defaults. Note we use the original URL since about:newtab // known defaults. Note we use the original URL since about:newtab
// redirects to a prerendered page. // redirects to a prerendered page.
const shouldRemoveFavicon = const shouldRemoveFavicon =
@@ -1153,7 +1155,7 @@ index 39b5babee5942427a82a7a64ad69e1b16efebcc1..32beac13dd4215a16de3a783db6c32da
!this._browser.mIconURL && !this._browser.mIconURL &&
!ignoreBlank && !ignoreBlank &&
!(originalLocation.spec in FAVICON_DEFAULTS); !(originalLocation.spec in FAVICON_DEFAULTS);
@@ -9858,13 +10137,6 @@ @@ -9930,13 +10211,6 @@
this._browser.originalURI = aRequest.originalURI; this._browser.originalURI = aRequest.originalURI;
} }

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js
index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e356c9f8c6f 100644 index 237950fb2c449ce088c204d33a70b1d95dae549b..635f9dbc5c79b6bb869b4ab4ec2d4b4e226b4672 100644
--- a/browser/components/tabbrowser/content/tabgroup.js --- a/browser/components/tabbrowser/content/tabgroup.js
+++ b/browser/components/tabbrowser/content/tabgroup.js +++ b/browser/components/tabbrowser/content/tabgroup.js
@@ -14,11 +14,11 @@ @@ -14,11 +14,11 @@
@@ -101,7 +101,7 @@ index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e35
resetDefaultGroupName = () => { resetDefaultGroupName = () => {
this.#defaultGroupName = ""; this.#defaultGroupName = "";
@@ -175,10 +198,15 @@ @@ -175,10 +198,18 @@
if (!this.#tabChangeObserver) { if (!this.#tabChangeObserver) {
this.#tabChangeObserver = new window.MutationObserver(mutations => { this.#tabChangeObserver = new window.MutationObserver(mutations => {
if (!this.tabs.length) { if (!this.tabs.length) {
@@ -112,12 +112,15 @@ index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e35
new CustomEvent("TabGroupRemoved", { bubbles: true }) new CustomEvent("TabGroupRemoved", { bubbles: true })
); );
+ gZenVerticalTabsManager.animateItemClose(this).then(() => { + gZenVerticalTabsManager.animateItemClose(this).then(() => {
+ this.dispatchEvent(
+ new CustomEvent("TabGroupRemovedFromDOM", { bubbles: true })
+ );
this.remove(); this.remove();
+ }); + });
Services.obs.notifyObservers( Services.obs.notifyObservers(
this, this,
"browser-tabgroup-removed-from-dom" "browser-tabgroup-removed-from-dom"
@@ -223,7 +251,10 @@ @@ -223,7 +254,10 @@
} }
}); });
} }
@@ -129,7 +132,7 @@ index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e35
} }
get color() { get color() {
@@ -330,6 +361,9 @@ @@ -330,6 +364,9 @@
} }
set collapsed(val) { set collapsed(val) {
@@ -139,7 +142,7 @@ index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e35
if (!!val == this.collapsed) { if (!!val == this.collapsed) {
return; return;
} }
@@ -416,7 +450,6 @@ @@ -416,7 +453,6 @@
tabGroupName, tabGroupName,
}) })
.then(result => { .then(result => {
@@ -147,7 +150,7 @@ index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e35
}); });
} }
@@ -491,13 +524,68 @@ @@ -491,13 +527,68 @@
* @returns {MozTabbrowserTab[]} * @returns {MozTabbrowserTab[]}
*/ */
get tabs() { get tabs() {
@@ -162,9 +165,8 @@ index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e35
+ tabsCollect.push(item); + tabsCollect.push(item);
+ if (gBrowser.isTabGroup(item)) { + if (gBrowser.isTabGroup(item)) {
+ tabsCollect.push(...item.tabs); + tabsCollect.push(...item.tabs);
} + }
} + }
- return childrenArray.filter(node => node.matches("tab"));
+ return tabsCollect.filter(node => node.matches("tab")); + return tabsCollect.filter(node => node.matches("tab"));
+ } + }
+ +
@@ -208,8 +210,9 @@ index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e35
+ currentGroup = currentGroup?.group; + currentGroup = currentGroup?.group;
+ if (currentGroup.collapsed) { + if (currentGroup.collapsed) {
+ return false; + return false;
+ } }
+ } }
- return childrenArray.filter(node => node.matches("tab"));
+ if (this.pinned && gZenWorkspaces.activeWorkspaceElement?.hasCollapsedPinnedTabs) { + if (this.pinned && gZenWorkspaces.activeWorkspaceElement?.hasCollapsedPinnedTabs) {
+ return false; + return false;
+ } + }
@@ -221,7 +224,7 @@ index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e35
} }
/** /**
@@ -617,9 +705,6 @@ @@ -617,9 +708,6 @@
}); });
} else { } else {
if (tabOrSplitView.pinned) { if (tabOrSplitView.pinned) {
@@ -231,7 +234,7 @@ index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e35
} }
let tabToMove = let tabToMove =
this.documentGlobal === tabOrSplitView.documentGlobal this.documentGlobal === tabOrSplitView.documentGlobal
@@ -682,7 +767,7 @@ @@ -682,7 +770,7 @@
*/ */
on_click(event) { on_click(event) {
let isToggleElement = let isToggleElement =
@@ -240,7 +243,7 @@ index 237950fb2c449ce088c204d33a70b1d95dae549b..af200a043dcd2e24393fcefe32493e35
event.target === this.#overflowCountLabel; event.target === this.#overflowCountLabel;
if (isToggleElement && event.button === 0) { if (isToggleElement && event.button === 0) {
event.preventDefault(); event.preventDefault();
@@ -761,5 +846,6 @@ @@ -761,5 +849,6 @@
} }
} }

View File

@@ -1,8 +1,18 @@
diff --git a/browser/components/urlbar/UrlbarPrefs.sys.mjs b/browser/components/urlbar/UrlbarPrefs.sys.mjs diff --git a/browser/components/urlbar/UrlbarPrefs.sys.mjs b/browser/components/urlbar/UrlbarPrefs.sys.mjs
index 2d21248256c6c2bfb8dac958133c10e3251ef564..f788bd10ec2c08e4b27b77cd3bb0489fb04e8b7a 100644 index e48f0295d803ba9eac5ab9d01ebb3b3dacbc9d4b..cb78b74230f63a47479404767b5ab5883278dfba 100644
--- a/browser/components/urlbar/UrlbarPrefs.sys.mjs --- a/browser/components/urlbar/UrlbarPrefs.sys.mjs
+++ b/browser/components/urlbar/UrlbarPrefs.sys.mjs +++ b/browser/components/urlbar/UrlbarPrefs.sys.mjs
@@ -462,6 +462,7 @@ const PREF_URLBAR_DEFAULTS = /** @type {PreferenceDefinition[]} */ ([ @@ -161,6 +161,9 @@ const PREF_URLBAR_DEFAULTS = /** @type {PreferenceDefinition[]} */ ([
// Feature gate pref for flight status suggestions in the urlbar.
["flightStatus.featureGate", false],
+ // Whether to close the urlbar when blurring the window while the urlbar is focused.
+ ["closeOnWindowBlur", true],
+
// The minimum prefix length of a flight status keyword the user must type to
// trigger the suggestion. 0 means the min length should be taken from Nimbus
// or remote settings.
@@ -486,6 +489,7 @@ const PREF_URLBAR_DEFAULTS = /** @type {PreferenceDefinition[]} */ ([
["shortcuts.tabs", true], ["shortcuts.tabs", true],
["shortcuts.history", true], ["shortcuts.history", true],
["shortcuts.actions", true], ["shortcuts.actions", true],
@@ -10,12 +20,12 @@ index 2d21248256c6c2bfb8dac958133c10e3251ef564..f788bd10ec2c08e4b27b77cd3bb0489f
// Boolean to determine if the providers defined in `exposureResults` // Boolean to determine if the providers defined in `exposureResults`
// should be displayed in search results. This can be set by a // should be displayed in search results. This can be set by a
@@ -799,6 +800,8 @@ function makeDefaultResultGroups({ showSearchSuggestionsFirst }) { @@ -854,6 +858,8 @@ function makeDefaultResultGroups({
*/ */
let rootGroup = { let rootGroup = {
children: [ children: [
+ { children: [{ group: lazy.UrlbarUtils.RESULT_GROUP.ZEN_ACTION }] }, + { children: [{ group: lazy.UrlbarShared.RESULT_GROUP.ZEN_ACTION }] },
+ { children: [{ group: lazy.UrlbarUtils.RESULT_GROUP.ZEN_WORKSPACE }] }, + { children: [{ group: lazy.UrlbarShared.RESULT_GROUP.ZEN_WORKSPACE }] },
// heuristic // heuristic
{ {
maxResultCount: 1, maxResultCount: 1,

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/urlbar/UrlbarProviderHeuristicFallback.sys.mjs b/browser/components/urlbar/UrlbarProviderHeuristicFallback.sys.mjs diff --git a/browser/components/urlbar/UrlbarProviderHeuristicFallback.sys.mjs b/browser/components/urlbar/UrlbarProviderHeuristicFallback.sys.mjs
index f611d8e44af518aa1adc7505c5021235f55b49de..0eca20cb869626dfa6ace02acc00cad84462d54f 100644 index cfc232f038cd491db32e0c0ca35622360dd9dec5..4806a725ddefa9d0709020d537eae5464249a294 100644
--- a/browser/components/urlbar/UrlbarProviderHeuristicFallback.sys.mjs --- a/browser/components/urlbar/UrlbarProviderHeuristicFallback.sys.mjs
+++ b/browser/components/urlbar/UrlbarProviderHeuristicFallback.sys.mjs +++ b/browser/components/urlbar/UrlbarProviderHeuristicFallback.sys.mjs
@@ -78,22 +78,26 @@ export class UrlbarProviderHeuristicFallback extends UrlbarProvider { @@ -77,22 +77,26 @@ export class UrlbarProviderHeuristicFallback extends UrlbarProvider {
// Since we can't tell if this is a real URL and whether the user wants // Since we can't tell if this is a real URL and whether the user wants
// to visit or search for it, we provide an alternative searchengine // to visit or search for it, we provide an alternative searchengine
// match if the string looks like an alphanumeric origin or an e-mail. // match if the string looks like an alphanumeric origin or an e-mail.
@@ -17,7 +17,7 @@ index f611d8e44af518aa1adc7505c5021235f55b49de..0eca20cb869626dfa6ace02acc00cad8
- lazy.UrlUtils.REGEXP_COMMON_EMAIL.test(str)) - lazy.UrlUtils.REGEXP_COMMON_EMAIL.test(str))
- ) { - ) {
+ let trimmedSearchString = queryContext.trimmedSearchString; + let trimmedSearchString = queryContext.trimmedSearchString;
+ let [searchCandidate] = UrlbarUtils.stripPrefixAndTrim( + let [searchCandidate] = lazy.UrlbarShared.stripPrefixAndTrim(
+ trimmedSearchString, + trimmedSearchString,
+ { + {
+ trimSlash: true, + trimSlash: true,

View File

@@ -1,41 +1,16 @@
diff --git a/browser/components/urlbar/UrlbarUtils.sys.mjs b/browser/components/urlbar/UrlbarUtils.sys.mjs diff --git a/browser/components/urlbar/UrlbarUtils.sys.mjs b/browser/components/urlbar/UrlbarUtils.sys.mjs
index 78c76bde00b6b581184cee1cd0e1756e5f2da6a4..94c713470b1240729ef2350d090b0449f3801af4 100644 index 178cd5e84fda74a28b2de59b671b3399cc28fac4..b03c6e06de4ee9a95dcb4d33d7ac9f0b053be4e1 100644
--- a/browser/components/urlbar/UrlbarUtils.sys.mjs --- a/browser/components/urlbar/UrlbarUtils.sys.mjs
+++ b/browser/components/urlbar/UrlbarUtils.sys.mjs +++ b/browser/components/urlbar/UrlbarUtils.sys.mjs
@@ -126,6 +126,8 @@ export var UrlbarUtils = { @@ -214,6 +214,11 @@ export var UrlbarUtils = {
SEMANTIC_HISTORY: "semanticHistory", return UrlbarShared.RESULT_GROUP.HEURISTIC_FALLBACK;
SUGGESTED_INDEX: "suggestedIndex",
TAIL_SUGGESTION: "tailSuggestion",
+ ZEN_ACTION: "zenAction",
+ ZEN_WORKSPACE: "zenWorkspace",
}),
// Defines provider types.
@@ -274,6 +276,14 @@ export var UrlbarUtils = {
telemetryLabel: "actions",
uiLabel: "urlbar-searchmode-actions3",
},
+ {
+ source: UrlbarShared.RESULT_SOURCE.WORKSPACES,
+ restrict: UrlbarShared.RESTRICT_TOKENS.WORKSPACE,
+ icon: "chrome://browser/skin/zen-icons/selectable/layers.svg",
+ pref: "shortcuts.workspaces",
+ telemetryLabel: "workspaces",
+ uiLabel: "urlbar-search-mode-workspaces",
+ },
]);
},
@@ -566,6 +576,12 @@ export var UrlbarUtils = {
return this.RESULT_GROUP.HEURISTIC_FALLBACK;
case "UrlbarProviderHistoryUrlHeuristic": case "UrlbarProviderHistoryUrlHeuristic":
return this.RESULT_GROUP.HEURISTIC_HISTORY_URL; return UrlbarShared.RESULT_GROUP.HEURISTIC_HISTORY_URL;
+ case "ZenUrlbarProviderGlobalActions": + case "ZenUrlbarProviderGlobalActions":
+ if (result.source == UrlbarShared.RESULT_SOURCE.WORKSPACES) { + if (result.source == UrlbarShared.RESULT_SOURCE.WORKSPACES) {
+ return this.RESULT_GROUP.ZEN_WORKSPACE; + return UrlbarShared.RESULT_GROUP.ZEN_WORKSPACE;
+ } else {
+ return this.RESULT_GROUP.ZEN_ACTION;
+ } + }
+ return UrlbarShared.RESULT_GROUP.ZEN_ACTION;
case "UrlbarProviderOmnibox": case "UrlbarProviderOmnibox":
return this.RESULT_GROUP.HEURISTIC_OMNIBOX; return UrlbarShared.RESULT_GROUP.HEURISTIC_OMNIBOX;
case "UrlbarProviderRestrictKeywordsAutofill": case "UrlbarProviderRestrictKeywordsAutofill":

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/urlbar/content/UrlbarChildController.mjs b/browser/components/urlbar/content/UrlbarChildController.mjs diff --git a/browser/components/urlbar/content/UrlbarChildController.mjs b/browser/components/urlbar/content/UrlbarChildController.mjs
index a8e9d3093d046612650a17970330a8279f55833f..063a3e8adf009d6c0ddc60430bc0e7485e812b8a 100644 index a17a4de079b69d2818388b33a2c1746cc6148c73..4fee63a22919972af08716db2d2de1c7549ff100 100644
--- a/browser/components/urlbar/content/UrlbarChildController.mjs --- a/browser/components/urlbar/content/UrlbarChildController.mjs
+++ b/browser/components/urlbar/content/UrlbarChildController.mjs +++ b/browser/components/urlbar/content/UrlbarChildController.mjs
@@ -258,7 +258,6 @@ export class UrlbarChildController { @@ -438,7 +438,6 @@ export class UrlbarChildController {
const isMac = AppConstants.platform == "macosx"; const isMac = AppConstants.platform == "macosx";
// Handle readline/emacs-style navigation bindings on Mac. // Handle readline/emacs-style navigation bindings on Mac.
if ( if (
@@ -10,7 +10,7 @@ index a8e9d3093d046612650a17970330a8279f55833f..063a3e8adf009d6c0ddc60430bc0e748
this.view.isOpen && this.view.isOpen &&
event.ctrlKey && event.ctrlKey &&
(event.key == "n" || event.key == "p") (event.key == "n" || event.key == "p")
@@ -450,6 +449,8 @@ export class UrlbarChildController { @@ -630,6 +629,8 @@ export class UrlbarChildController {
}); });
} }
event.preventDefault(); event.preventDefault();
@@ -19,3 +19,25 @@ index a8e9d3093d046612650a17970330a8279f55833f..063a3e8adf009d6c0ddc60430bc0e748
} }
break; break;
} }
@@ -934,6 +935,10 @@ export class UrlbarChildController {
}
reuseEmpty = true;
}
+ if (this.#input.hasAttribute?.("zen-newtab")) {
+ where = "tab";
+ reuseEmpty = true;
+ }
// The browser window exists only in chrome; a content-process input has no
// tab to reuse, so `gBrowser` is absent and the reuse is skipped.
if (
@@ -943,6 +948,10 @@ export class UrlbarChildController {
) {
where = "current";
}
+ if (this.window.gBrowser?.selectedTab.hasAttribute("zen-empty-tab")) {
+ // Always open in a new tab if the current tab is our empty tab.
+ return "tab";
+ }
return where;
}

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/urlbar/content/UrlbarInput.mjs b/browser/components/urlbar/content/UrlbarInput.mjs diff --git a/browser/components/urlbar/content/UrlbarInput.mjs b/browser/components/urlbar/content/UrlbarInput.mjs
index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a6182579cbaf4d 100644 index 319fb6870ec18d87b9f1263bd960edaa39b0447c..554cc90fb2307450ddc68033968cefd1a95e28b8 100644
--- a/browser/components/urlbar/content/UrlbarInput.mjs --- a/browser/components/urlbar/content/UrlbarInput.mjs
+++ b/browser/components/urlbar/content/UrlbarInput.mjs +++ b/browser/components/urlbar/content/UrlbarInput.mjs
@@ -101,6 +101,13 @@ const lazy = XPCOMUtils.declareLazy({ @@ -88,6 +88,13 @@ const lazy = XPCOMUtils.declareLazy({
logger: () => UrlbarShared.getLogger({ prefix: "Input" }), logger: () => UrlbarShared.getLogger({ prefix: "Input" }),
}); });
@@ -16,7 +16,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
const UNLIMITED_MAX_RESULTS = 99; const UNLIMITED_MAX_RESULTS = 99;
let getBoundsWithoutFlushing = element => let getBoundsWithoutFlushing = element =>
@@ -769,7 +776,16 @@ ${ @@ -771,7 +778,16 @@ ${
// See _on_select(). HTMLInputElement.select() dispatches a "select" // See _on_select(). HTMLInputElement.select() dispatches a "select"
// event but does not set the primary selection. // event but does not set the primary selection.
this._suppressPrimaryAdjustment = true; this._suppressPrimaryAdjustment = true;
@@ -33,7 +33,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
this._suppressPrimaryAdjustment = false; this._suppressPrimaryAdjustment = false;
} }
@@ -843,6 +859,10 @@ ${ @@ -846,6 +862,10 @@ ${
hideSearchTerms = false, hideSearchTerms = false,
isSameDocument = false, isSameDocument = false,
} = {}) { } = {}) {
@@ -44,7 +44,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
if (!this.#isAddressbar) { if (!this.#isAddressbar) {
throw new Error( throw new Error(
"Cannot set URI for UrlbarInput that is not an address bar" "Cannot set URI for UrlbarInput that is not an address bar"
@@ -1137,7 +1157,16 @@ ${ @@ -1143,7 +1163,16 @@ ${
this.searchModeSwitcher?.updateSearchIcon(); this.searchModeSwitcher?.updateSearchIcon();
} }
@@ -61,7 +61,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
} }
/** /**
@@ -1626,7 +1655,11 @@ ${ @@ -1726,7 +1755,11 @@ ${
openParams.avoidBrowserFocus = keepViewOpen; openParams.avoidBrowserFocus = keepViewOpen;
if (!this.#providesSearchMode(result) && !keepViewOpen) { if (!this.#providesSearchMode(result) && !keepViewOpen) {
@@ -74,7 +74,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
} }
if (isCanonized) { if (isCanonized) {
@@ -2974,6 +3007,42 @@ ${ @@ -3016,6 +3049,42 @@ ${
await this.#updateLayoutBreakoutDimensions(); await this.#updateLayoutBreakoutDimensions();
} }
@@ -117,7 +117,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
startLayoutExtend() { startLayoutExtend() {
if (!this.#allowBreakout || this.hasAttribute("breakout-extend")) { if (!this.#allowBreakout || this.hasAttribute("breakout-extend")) {
// Do not expand if the Urlbar does not support being expanded or it is // Do not expand if the Urlbar does not support being expanded or it is
@@ -2988,6 +3057,13 @@ ${ @@ -3030,6 +3099,13 @@ ${
this.toggleAttribute("breakout-extend", true); this.toggleAttribute("breakout-extend", true);
this.#updateTextboxPosition(); this.#updateTextboxPosition();
@@ -131,7 +131,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
// Enable the animation only after the first extend call to ensure it // Enable the animation only after the first extend call to ensure it
// doesn't run when opening a new window. // doesn't run when opening a new window.
if (!this.hasAttribute("breakout-extend-animate")) { if (!this.hasAttribute("breakout-extend-animate")) {
@@ -3011,6 +3087,29 @@ ${ @@ -3053,6 +3129,29 @@ ${
return; return;
} }
@@ -161,7 +161,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
this.toggleAttribute("breakout-extend", false); this.toggleAttribute("breakout-extend", false);
this.#updateTextboxPosition(); this.#updateTextboxPosition();
} }
@@ -3049,7 +3148,7 @@ ${ @@ -3091,7 +3190,7 @@ ${
forceUnifiedSearchButtonAvailable = false forceUnifiedSearchButtonAvailable = false
) { ) {
let prevState = this.getAttribute("pageproxystate"); let prevState = this.getAttribute("pageproxystate");
@@ -170,7 +170,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
this.setAttribute("pageproxystate", state); this.setAttribute("pageproxystate", state);
this._inputContainer.setAttribute("pageproxystate", state); this._inputContainer.setAttribute("pageproxystate", state);
this._identityBox?.setAttribute("pageproxystate", state); this._identityBox?.setAttribute("pageproxystate", state);
@@ -3332,10 +3431,12 @@ ${ @@ -3355,10 +3454,12 @@ ${
} }
this.style.top = px( this.style.top = px(
@@ -183,7 +183,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
); );
} }
@@ -3394,9 +3495,10 @@ ${ @@ -3417,9 +3518,10 @@ ${
return; return;
} }
@@ -193,9 +193,9 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
- px(getBoundsWithoutFlushing(this.parentNode).height) - px(getBoundsWithoutFlushing(this.parentNode).height)
+ px(getBoundsWithoutFlushing(this.parentNode).height + 8) + px(getBoundsWithoutFlushing(this.parentNode).height + 8)
); );
this.style.setProperty(
"--urlbar-height", if (this.#breakoutBlockerCount) {
@@ -3902,6 +4004,7 @@ ${ @@ -3929,6 +4031,7 @@ ${
} }
_toggleActionOverride(event) { _toggleActionOverride(event) {
@@ -203,47 +203,33 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
if ( if (
event.keyCode == KeyEvent.DOM_VK_SHIFT || event.keyCode == KeyEvent.DOM_VK_SHIFT ||
event.keyCode == KeyEvent.DOM_VK_ALT || event.keyCode == KeyEvent.DOM_VK_ALT ||
@@ -4014,8 +4117,8 @@ ${ @@ -4027,9 +4130,10 @@ ${
if (!this.#isAddressbar) { if (!this.#isAddressbar) {
return val; return val;
} }
- let trimmedValue = lazy.UrlbarPrefs.get("trimURLs") - let trimmedValue = UrlbarPrefs.get("trimURLs")
- ? lazy.BrowserUIUtils.trimURL(val) - ? lazy.BrowserUIUtils.trimURL(val)
+ let trimmedValue = lazy.UrlbarPrefs.get("trimURLs") && this._zenTrimURL - : val;
+ let trimmedValue =
+ UrlbarPrefs.get("trimURLs") && this._zenTrimURL
+ ? this._zenTrimURL(val) + ? this._zenTrimURL(val)
: val; + : val;
// Only trim value if the directionality doesn't change to RTL and we're not // Only trim value if the directionality doesn't change to RTL and we're not
// showing a strikeout https protocol. // showing a strikeout https protocol.
@@ -4317,6 +4420,7 @@ ${ return this.controller.isTextDirectionRTL(trimmedValue) ||
browser = this.window.gBrowser.selectedBrowser, @@ -4235,6 +4339,11 @@ ${
keepViewOpen = false keepViewOpen = false,
) { browserId = null,
+ openUILinkWhere = this.window.gZenUIManager.getOpenUILinkWhere(url, browser, openUILinkWhere); }) {
if (this.#isAddressbar) { + where = this.window.gZenUIManager.getOpenUILinkWhere(
this.#prepareAddressbarLoad( + url,
url, + this.window.gBrowser.selectedBrowser,
@@ -4430,6 +4534,10 @@ ${ + where
} + );
reuseEmpty = true; let userTypedValue;
} if (this.#isAddressbar && where == "current") {
+ if (this.hasAttribute("zen-newtab")) { // Make sure URL is formatted properly (don't show punycode).
+ where = "tab"; @@ -4576,6 +4685,7 @@ ${
+ reuseEmpty = true;
+ }
if (
where == "tab" &&
reuseEmpty &&
@@ -4437,6 +4545,9 @@ ${
) {
where = "current";
}
+ if (this.window.gBrowser.selectedTab.hasAttribute("zen-empty-tab")) {
+ return "tab"; // Always open in a new tab if the current tab is "our empty tab".
+ }
return where;
}
@@ -4691,6 +4802,7 @@ ${
this.setResultForCurrentValue(null); this.setResultForCurrentValue(null);
this.handleCommand(); this.handleCommand();
this.controller.clearLastQueryContextCache(); this.controller.clearLastQueryContextCache();
@@ -251,7 +237,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
this._suppressStartQuery = false; this._suppressStartQuery = false;
}); });
@@ -4698,7 +4810,6 @@ ${ @@ -4583,7 +4693,6 @@ ${
contextMenu.addEventListener("popupshowing", () => { contextMenu.addEventListener("popupshowing", () => {
// Close the results pane when the input field contextual menu is open, // Close the results pane when the input field contextual menu is open,
// because paste and go doesn't want a result selection. // because paste and go doesn't want a result selection.
@@ -259,7 +245,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
let controller = let controller =
this.document.commandDispatcher.getControllerForCommand("cmd_paste"); this.document.commandDispatcher.getControllerForCommand("cmd_paste");
@@ -4979,7 +5090,11 @@ ${ @@ -4850,7 +4959,11 @@ ${
if (!engineName && !source && !this.hasAttribute("searchmode")) { if (!engineName && !source && !this.hasAttribute("searchmode")) {
return; return;
} }
@@ -272,7 +258,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
if (this._searchModeIndicatorTitle) { if (this._searchModeIndicatorTitle) {
this._searchModeIndicatorTitle.textContent = ""; this._searchModeIndicatorTitle.textContent = "";
this._searchModeIndicatorTitle.removeAttribute("data-l10n-id"); this._searchModeIndicatorTitle.removeAttribute("data-l10n-id");
@@ -5297,6 +5412,7 @@ ${ @@ -5149,6 +5262,7 @@ ${
this.document.l10n.setAttributes( this.document.l10n.setAttributes(
this.inputField, this.inputField,
@@ -280,7 +266,20 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
l10nId, l10nId,
l10nId == "urlbar-placeholder-with-name" l10nId == "urlbar-placeholder-with-name"
? { name: engineName } ? { name: engineName }
@@ -5424,6 +5540,11 @@ ${ @@ -5199,6 +5313,12 @@ ${
}
lazy.logger.debug("Blur Event");
+ if (
+ this.document.commandDispatcher.focusedElement == this.inputField &&
+ !UrlbarPrefs.get("closeOnWindowBlur")
+ ) {
+ return;
+ }
// We cannot count every blur events after a missed engagement as abandoment
// because the user may have clicked on some view element that executes
// a command causing a focus change. For example opening preferences from
@@ -5276,6 +5396,11 @@ ${
} }
_on_click(event) { _on_click(event) {
@@ -292,7 +291,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
switch (event.target) { switch (event.target) {
case this.inputField: case this.inputField:
case this._inputContainer: case this._inputContainer:
@@ -5513,10 +5634,11 @@ ${ @@ -5371,10 +5496,11 @@ ${
} }
if (untrim) { if (untrim) {
this.setValue(this._untrimmedValue); this.setValue(this._untrimmedValue);
@@ -305,7 +304,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
this.view.autoOpen({ event }); this.view.autoOpen({ event });
} else { } else {
if (this._untrimOnFocusAfterKeydown) { if (this._untrimOnFocusAfterKeydown) {
@@ -5556,9 +5678,16 @@ ${ @@ -5414,9 +5540,16 @@ ${
} }
_on_mousedown(event) { _on_mousedown(event) {
@@ -323,7 +322,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
if ( if (
event.composedTarget != this.inputField && event.composedTarget != this.inputField &&
event.composedTarget != this._inputContainer event.composedTarget != this._inputContainer
@@ -5568,6 +5697,10 @@ ${ @@ -5426,6 +5559,10 @@ ${
this.focusedViaMousedown = !this.focused; this.focusedViaMousedown = !this.focused;
this.#preventClickSelectsAll = this.focused; this.#preventClickSelectsAll = this.focused;
@@ -334,7 +333,7 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
// Keep the focus status, since the attribute may be changed // Keep the focus status, since the attribute may be changed
// upon calling this.focus(). // upon calling this.focus().
@@ -5605,7 +5738,7 @@ ${ @@ -5463,7 +5600,7 @@ ${
// view open on tab switch, and the TabSelect event arrived earlier. // view open on tab switch, and the TabSelect event arrived earlier.
// Also ignore mousedown on the urlbarView context menu: opening/closing the // Also ignore mousedown on the urlbarView context menu: opening/closing the
// view is already handled by the result opening flow. // view is already handled by the result opening flow.
@@ -343,12 +342,12 @@ index e7e9495e56076cd112beafb8297dece4ae4cea58..330104d245ddd0956b95377082a61825
break; break;
} }
@@ -5894,7 +6027,7 @@ ${ @@ -5754,7 +5891,7 @@ ${
// When we are in actions search mode we can show more results so // When we are in actions search mode we can show more results so
// increase the limit. // increase the limit.
let maxResults = let maxResults =
- this.searchMode?.source != UrlbarShared.RESULT_SOURCE.ACTIONS - this.searchMode?.source != UrlbarShared.RESULT_SOURCE.ACTIONS
+ this.searchMode?.source != UrlbarShared.RESULT_SOURCE.ZEN_ACTIONS + this.searchMode?.source != UrlbarShared.RESULT_SOURCE.ZEN_ACTIONS
? lazy.UrlbarPrefs.get("maxRichResults") ? UrlbarPrefs.get("maxRichResults")
: UNLIMITED_MAX_RESULTS; : UNLIMITED_MAX_RESULTS;
let options = { let options = {

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/urlbar/content/UrlbarShared.mjs b/browser/components/urlbar/content/UrlbarShared.mjs diff --git a/browser/components/urlbar/content/UrlbarShared.mjs b/browser/components/urlbar/content/UrlbarShared.mjs
index 5b45afb747bfcdbd06782186737669aa2c4c634d..f68bd009f70415b5fb513abdfe19b4427ceefbfc 100644 index 4e67dad66ae006842abc6eed547e4a244320d57a..393b61b4d2543c73e60afd334a353f36119ae73e 100644
--- a/browser/components/urlbar/content/UrlbarShared.mjs --- a/browser/components/urlbar/content/UrlbarShared.mjs
+++ b/browser/components/urlbar/content/UrlbarShared.mjs +++ b/browser/components/urlbar/content/UrlbarShared.mjs
@@ -47,6 +47,7 @@ export const UrlbarShared = { @@ -100,6 +100,7 @@ export const UrlbarShared = {
// `looksLikeOrigin()` returned `LOOKS_LIKE_ORIGIN.OTHER` for this token. // `looksLikeOrigin()` returned `LOOKS_LIKE_ORIGIN.OTHER` for this token.
// It may or may not be an origin. // It may or may not be an origin.
POSSIBLE_ORIGIN_BUT_SEARCH_ALLOWED: 12, POSSIBLE_ORIGIN_BUT_SEARCH_ALLOWED: 12,
@@ -10,7 +10,7 @@ index 5b45afb747bfcdbd06782186737669aa2c4c634d..f68bd009f70415b5fb513abdfe19b442
}), }),
/** /**
@@ -67,6 +68,7 @@ export const UrlbarShared = { @@ -120,6 +121,7 @@ export const UrlbarShared = {
TITLE: "#", TITLE: "#",
URL: "$", URL: "$",
ACTION: ">", ACTION: ">",
@@ -18,7 +18,7 @@ index 5b45afb747bfcdbd06782186737669aa2c4c634d..f68bd009f70415b5fb513abdfe19b442
}), }),
// Defines UrlbarResult types. // Defines UrlbarResult types.
@@ -112,6 +114,8 @@ export const UrlbarShared = { @@ -165,6 +167,8 @@ export const UrlbarShared = {
OTHER_NETWORK: 6, OTHER_NETWORK: 6,
ADDON: 7, ADDON: 7,
ACTIONS: 8, ACTIONS: 8,
@@ -26,9 +26,33 @@ index 5b45afb747bfcdbd06782186737669aa2c4c634d..f68bd009f70415b5fb513abdfe19b442
+ WORKSPACES: 10, + WORKSPACES: 10,
}), }),
/** // Results are categorized into groups to help the muxer compose them. See
@@ -128,6 +132,7 @@ export const UrlbarShared = { @@ -200,6 +204,8 @@ export const UrlbarShared = {
if (lazy.UrlbarPrefs.get("scotchBonnet.enableOverride")) { SEMANTIC_HISTORY: "semanticHistory",
SUGGESTED_INDEX: "suggestedIndex",
TAIL_SUGGESTION: "tailSuggestion",
+ ZEN_ACTION: "zenAction",
+ ZEN_WORKSPACE: "zenWorkspace",
}),
// Defines provider types.
@@ -385,6 +391,14 @@ export const UrlbarShared = {
telemetryLabel: "actions",
uiLabel: "urlbar-searchmode-actions3",
},
+ {
+ source: this.RESULT_SOURCE.WORKSPACES,
+ restrict: this.RESTRICT_TOKENS.WORKSPACE,
+ icon: "chrome://browser/skin/zen-icons/selectable/layers.svg",
+ pref: "shortcuts.workspaces",
+ telemetryLabel: "workspaces",
+ uiLabel: "urlbar-search-mode-workspaces",
+ },
]);
},
@@ -402,6 +416,7 @@ export const UrlbarShared = {
if (UrlbarPrefs.get("scotchBonnet.enableOverride")) {
keys.push(this.RESTRICT_TOKENS.ACTION); keys.push(this.RESTRICT_TOKENS.ACTION);
} }
+ keys.push(this.RESTRICT_TOKENS.WORKSPACE); + keys.push(this.RESTRICT_TOKENS.WORKSPACE);

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/urlbar/content/UrlbarView.mjs b/browser/components/urlbar/content/UrlbarView.mjs diff --git a/browser/components/urlbar/content/UrlbarView.mjs b/browser/components/urlbar/content/UrlbarView.mjs
index 8afb2bf4a757b3ef7902f5a6e6eed6b70ca2845e..440dea1e66540ca1998cb7464b6695ac823fedcb 100644 index 9a2c787cfa4d70bd587d49e017075f905c90f626..1c3b341e5d520ec9541c4021aaedce98751b6993 100644
--- a/browser/components/urlbar/content/UrlbarView.mjs --- a/browser/components/urlbar/content/UrlbarView.mjs
+++ b/browser/components/urlbar/content/UrlbarView.mjs +++ b/browser/components/urlbar/content/UrlbarView.mjs
@@ -674,7 +674,7 @@ export class UrlbarView { @@ -822,7 +822,7 @@ export class UrlbarView {
!this.input.value || !this.input.value ||
this.input.getAttribute("pageproxystate") == "valid" this.input.getAttribute("pageproxystate") == "valid"
) { ) {
@@ -11,7 +11,7 @@ index 8afb2bf4a757b3ef7902f5a6e6eed6b70ca2845e..440dea1e66540ca1998cb7464b6695ac
// Try to reuse the cached top-sites context. If it's not cached, then // Try to reuse the cached top-sites context. If it's not cached, then
// there will be a gap of time between when the input is focused and // there will be a gap of time between when the input is focused and
// when the view opens that can be perceived as flicker. // when the view opens that can be perceived as flicker.
@@ -812,10 +812,6 @@ export class UrlbarView { @@ -963,10 +963,6 @@ export class UrlbarView {
} }
// If search mode isn't active, close the view. // If search mode isn't active, close the view.
@@ -22,7 +22,7 @@ index 8afb2bf4a757b3ef7902f5a6e6eed6b70ca2845e..440dea1e66540ca1998cb7464b6695ac
// Search mode is active. If the one-offs should be shown, make sure they // Search mode is active. If the one-offs should be shown, make sure they
// are enabled and show the view. // are enabled and show the view.
@@ -3031,6 +3027,8 @@ export class UrlbarView { @@ -3306,6 +3302,8 @@ export class UrlbarView {
if (row?.hasAttribute("row-selectable")) { if (row?.hasAttribute("row-selectable")) {
row?.toggleAttribute("selected", true); row?.toggleAttribute("selected", true);
} }
@@ -31,7 +31,7 @@ index 8afb2bf4a757b3ef7902f5a6e6eed6b70ca2845e..440dea1e66540ca1998cb7464b6695ac
if (element != row) { if (element != row) {
row?.toggleAttribute("descendant-selected", true); row?.toggleAttribute("descendant-selected", true);
} }
@@ -3544,7 +3542,7 @@ export class UrlbarView { @@ -3972,7 +3970,7 @@ export class UrlbarView {
} }
#enableOrDisableRowWrap() { #enableOrDisableRowWrap() {
@@ -40,3 +40,16 @@ index 8afb2bf4a757b3ef7902f5a6e6eed6b70ca2845e..440dea1e66540ca1998cb7464b6695ac
this.#rows.toggleAttribute("wrap", wrap); this.#rows.toggleAttribute("wrap", wrap);
this.oneOffSearchButtons?.container.toggleAttribute("wrap", wrap); this.oneOffSearchButtons?.container.toggleAttribute("wrap", wrap);
} }
@@ -4387,6 +4385,12 @@ export class UrlbarView {
}
on_blur() {
+ if (
+ this.document.commandDispatcher.focusedElement == this.input.inputField &&
+ !UrlbarPrefs.get("closeOnWindowBlur")
+ ) {
+ return;
+ }
// If the view is open without the input being focused, it will not close
// automatically when the window loses focus. We might be in this state
// after a Search Tip is shown on an engine homepage.

View File

@@ -0,0 +1,124 @@
diff --git a/browser/installer/windows/nsis/shared.nsh b/browser/installer/windows/nsis/shared.nsh
index b81c7ef59be0d25f67668215028008a451860df2..fa0ab8947e011289d25158cab17ff9388b5cab0d 100755
--- a/browser/installer/windows/nsis/shared.nsh
+++ b/browser/installer/windows/nsis/shared.nsh
@@ -873,50 +873,87 @@ FunctionEnd
!ifdef MOZ_MAINTENANCE_SERVICE
; Adds maintenance service certificate keys for the install dir.
; For the cert to work, it must also be signed by a trusted cert for the user.
+; Writes this application's allowed certificate values into _KEY, which must be
+; a maintenance service registry path such as the one returned by
+; ServicesHelper::PathToUniqueRegistryPath.
+!macro AddMaintCertKeyValues _KEY
+ ; PrefetchProcessName was originally used to experiment with deleting
+ ; Windows prefetch as a speed optimization. It is no longer used though.
+ DeleteRegValue HKLM "${_KEY}" "prefetchProcessName"
+
+ ; Setting the Attempted value will ensure that a new Maintenance Service
+ ; install will never be attempted again after this from updates. The value
+ ; is used only to see if updates should attempt new service installs.
+ WriteRegDWORD HKLM "Software\Mozilla\MaintenanceService" "Attempted" 1
+
+ ; More than one certificate can be specified in a different subfolder
+ ; for example: ${_KEY}\1, but each individual binary can be signed
+ ; with at most one certificate. A fallback certificate can only be used
+ ; if the binary is replaced with a different certificate.
+ WriteRegStr HKLM "${_KEY}\0" "name" "${CERTIFICATE_NAME}"
+ WriteRegStr HKLM "${_KEY}\0" "issuer" "${CERTIFICATE_ISSUER}"
+ ; These values associate the allowed certificates for the previous
+ ; installation, so that we can update from it cleanly using the
+ ; old updater.exe (which will still have this signature).
+ WriteRegStr HKLM "${_KEY}\1" "name" "${CERTIFICATE_NAME_PREVIOUS}"
+ WriteRegStr HKLM "${_KEY}\1" "issuer" "${CERTIFICATE_ISSUER_PREVIOUS}"
+ ClearErrors
+!macroend
+
!macro AddMaintCertKeys
Push $R0
; Allow main Mozilla cert information for updates
; This call will push the needed key on the stack
ServicesHelper::PathToUniqueRegistryPath "$INSTDIR"
Pop $R0
+ Push $R1
+ Push $R2
+ Push $R3
+ ; We always use the 64bit registry for certs.
+ ${If} ${RunningX64}
+ ${OrIf} ${IsNativeARM64}
+ SetRegView 64
+ ${EndIf}
+
${If} $R0 != ""
- ; More than one certificate can be specified in a different subfolder
- ; for example: $R0\1, but each individual binary can be signed
- ; with at most one certificate. A fallback certificate can only be used
- ; if the binary is replaced with a different certificate.
- ; We always use the 64bit registry for certs.
- ${If} ${RunningX64}
- ${OrIf} ${IsNativeARM64}
- SetRegView 64
- ${EndIf}
+ !insertmacro AddMaintCertKeyValues "$R0"
+ ${Else}
+ ; ServicesHelper could not be loaded. This happens when PostUpdate is run
+ ; by the updater, which launches it with an environment too minimal for
+ ; NSIS to load its plugins, leaving the unique registry path uncomputable.
+ ; Fall back to refreshing every key that already records one of our own
+ ; certificate names, so that any installation of this application is kept
+ ; current rather than only the first one found. Keys belonging to other
+ ; applications record a different name and are left alone.
+ StrCpy $R1 0
+ ${Do}
+ EnumRegKey $R2 HKLM "Software\Mozilla\MaintenanceService" $R1
+ ${If} $R2 == ""
+ ${ExitDo}
+ ${EndIf}
+ ReadRegStr $R3 HKLM "Software\Mozilla\MaintenanceService\$R2\0" "name"
+ ${If} $R3 == "${CERTIFICATE_NAME}"
+ ${OrIf} $R3 == "${CERTIFICATE_NAME_PREVIOUS}"
+ StrCpy $R0 "Software\Mozilla\MaintenanceService\$R2"
+ !insertmacro AddMaintCertKeyValues "$R0"
+ ${EndIf}
+ IntOp $R1 $R1 + 1
+ ${Loop}
+ StrCpy $R0 ""
+ ${EndIf}
- ; PrefetchProcessName was originally used to experiment with deleting
- ; Windows prefetch as a speed optimization. It is no longer used though.
- DeleteRegValue HKLM "$R0" "prefetchProcessName"
-
- ; Setting the Attempted value will ensure that a new Maintenance Service
- ; install will never be attempted again after this from updates. The value
- ; is used only to see if updates should attempt new service installs.
- WriteRegDWORD HKLM "Software\Mozilla\MaintenanceService" "Attempted" 1
-
- ; These values associate the allowed certificates for the current
- ; installation.
- WriteRegStr HKLM "$R0\0" "name" "${CERTIFICATE_NAME}"
- WriteRegStr HKLM "$R0\0" "issuer" "${CERTIFICATE_ISSUER}"
- ; These values associate the allowed certificates for the previous
- ; installation, so that we can update from it cleanly using the
- ; old updater.exe (which will still have this signature).
- WriteRegStr HKLM "$R0\1" "name" "${CERTIFICATE_NAME_PREVIOUS}"
- WriteRegStr HKLM "$R0\1" "issuer" "${CERTIFICATE_ISSUER_PREVIOUS}"
- ${If} ${RunningX64}
- ${OrIf} ${IsNativeARM64}
- SetRegView lastused
- ${EndIf}
- ClearErrors
+ ${If} ${RunningX64}
+ ${OrIf} ${IsNativeARM64}
+ SetRegView lastused
${EndIf}
+
+ Pop $R3
+ Pop $R2
+ Pop $R1
; Restore the previously used value back
Pop $R0
!macroend
+
!define AddMaintCertKeys "!insertmacro AddMaintCertKeys"
!endif

View File

@@ -1,9 +1,18 @@
diff --git a/browser/installer/windows/nsis/uninstaller.nsi b/browser/installer/windows/nsis/uninstaller.nsi diff --git a/browser/installer/windows/nsis/uninstaller.nsi b/browser/installer/windows/nsis/uninstaller.nsi
old mode 100755 old mode 100755
new mode 100644 new mode 100644
index becbb0f70c84eb7f2d9bff5a3aedcbb7a78a61cf..05835d2088ab631316a25a9f0728898bd7998d8d index becbb0f70c84eb7f2d9bff5a3aedcbb7a78a61cf..a23a8a1b160932368377fc841b501df9355918db
--- a/browser/installer/windows/nsis/uninstaller.nsi --- a/browser/installer/windows/nsis/uninstaller.nsi
+++ b/browser/installer/windows/nsis/uninstaller.nsi +++ b/browser/installer/windows/nsis/uninstaller.nsi
@@ -150,7 +150,7 @@ OutFile "helper.exe"
!endif
ShowUnInstDetails nevershow
-!define URLUninstallSurvey "https://qsurvey.mozilla.com/s3/FF-Desktop-Post-Uninstall?channel=${UpdateChannel}&version=${AppVersion}&osversion="
+!define URLUninstallSurvey "https://links.zen-browser.app/uninstall-feedback?osversion="
; Support for the profile refresh feature
!define URLProfileRefreshHelp "https://support.mozilla.org/kb/refresh-firefox-reset-add-ons-and-settings"
@@ -516,6 +516,7 @@ Section "Uninstall" @@ -516,6 +516,7 @@ Section "Uninstall"
${un.RegCleanFileHandler} ".svg" "FirefoxHTML-$AppUserModelID" ${un.RegCleanFileHandler} ".svg" "FirefoxHTML-$AppUserModelID"
${un.RegCleanFileHandler} ".webp" "FirefoxHTML-$AppUserModelID" ${un.RegCleanFileHandler} ".webp" "FirefoxHTML-$AppUserModelID"

View File

@@ -1,11 +1,11 @@
diff --git a/browser/themes/linux/browser.css b/browser/themes/linux/browser.css diff --git a/browser/themes/linux/browser.css b/browser/themes/linux/browser.css
index e735ec80b56e1a2da4bc5bec29136ce60353277b..330ea62d220d9acd96a95a605888839388e97452 100644 index f276db1d456703493ee713370691352985021708..619ee6724eec1e6a25adcb257af0d02eb7a29d34 100644
--- a/browser/themes/linux/browser.css --- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css +++ b/browser/themes/linux/browser.css
@@ -14,7 +14,6 @@ @@ -14,7 +14,6 @@
@media (-moz-gtk-theme-family) { @media (-moz-gtk-theme-family) {
--tabs-navbar-separator-style: none; --tabs-navbar-separator-style: none;
@media (prefers-color-scheme: light) and (not -moz-pref("browser.nova.enabled")) { @media (prefers-color-scheme: light) {
- --urlbar-box-background-color: #fafafa; - --urlbar-box-background-color: #fafafa;
} }
} }

View File

@@ -40,7 +40,7 @@ html|dialog {
} }
groupbox button { groupbox button {
border-radius: 5px !important; border-radius: calc(5px * var(--zen-squircle-value)) !important;
} }
groupbox button, groupbox button,

View File

@@ -1,16 +1,16 @@
diff --git a/browser/themes/shared/tabbrowser/content-area.css b/browser/themes/shared/tabbrowser/content-area.css diff --git a/browser/themes/shared/tabbrowser/content-area.css b/browser/themes/shared/tabbrowser/content-area.css
index 3acdec2b8e043fe27919cfa54e73f4d3c491bfc8..267a1087134464a8193a824a2d7f8ac15ff8ad60 100644 index 2374ed38bd9361d6c7e1886117099c6761e403b8..72f1f52a13096f19ca4009037ad0cdc880775ff7 100644
--- a/browser/themes/shared/tabbrowser/content-area.css --- a/browser/themes/shared/tabbrowser/content-area.css
+++ b/browser/themes/shared/tabbrowser/content-area.css +++ b/browser/themes/shared/tabbrowser/content-area.css
@@ -157,7 +157,6 @@ @@ -239,7 +239,6 @@
min-height: 0; min-width: 0;
/* We want to be able to show the frame color behind the clipped radiused corner */ /* We want to be able to show the frame color behind the clipped radiused corner */
- background: var(--tabpanel-background-color); - background: var(--tabpanel-background-color);
@media -moz-pref("sidebar.revamp") { display: grid;
outline: 0.01px solid var(--chrome-content-separator-color); /**
@@ -216,7 +215,6 @@ @@ -425,7 +424,6 @@
} }
browser:is([blank], [pendingpaint]) { browser:is([blank], [pendingpaint]) {
@@ -18,7 +18,7 @@ index 3acdec2b8e043fe27919cfa54e73f4d3c491bfc8..267a1087134464a8193a824a2d7f8ac1
} }
/* Exclude browsers with smartwindow-content attribute which inherit /* Exclude browsers with smartwindow-content attribute which inherit
@@ -553,7 +551,7 @@ split-view-footer { @@ -865,7 +863,7 @@ split-view-footer {
.dialogStack { .dialogStack {
z-index: var(--browser-stack-z-index-dialog-stack); z-index: var(--browser-stack-z-index-dialog-stack);
@@ -27,12 +27,12 @@ index 3acdec2b8e043fe27919cfa54e73f4d3c491bfc8..267a1087134464a8193a824a2d7f8ac1
inset: 0; inset: 0;
/* --browser-with-dialog set on browser[tabDialogShowing], we want to position the overlay /* --browser-with-dialog set on browser[tabDialogShowing], we want to position the overlay
only on the top of the <browser> element so it doesn't overlap the DevTools toolbox */ only on the top of the <browser> element so it doesn't overlap the DevTools toolbox */
@@ -718,7 +716,7 @@ split-view-footer { @@ -1034,7 +1032,7 @@ split-view-footer {
.dialogOverlay[topmost="true"], .dialogOverlay[topmost="true"],
#window-modal-dialog::backdrop { #window-modal-dialog::backdrop {
- background-color: var(--background-color-overlay); - background-color: var(--background-color-overlay);
+ background-color: light-dark(rgba(255, 255, 255, .3), rgba(0, 0, 0, .3)); + background-color: light-dark(rgba(255, 255, 255, .3), rgba(0, 0, 0, .3));
} border-radius: var(--chrome-block-radius);
.dialogOverlay[hideContent="true"][topmost="true"] { .browserSidebarContainer.responsive-mode & {

View File

@@ -1,17 +1,17 @@
diff --git a/browser/themes/shared/tabbrowser/tabs.css b/browser/themes/shared/tabbrowser/tabs.css diff --git a/browser/themes/shared/tabbrowser/tabs.css b/browser/themes/shared/tabbrowser/tabs.css
index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f253804576e 100644 index 61c0b8382c78f63ad9113af55a6236c4a29bc45b..0ab463c768d4fb3f45d22e753f408c46b61c0480 100644
--- a/browser/themes/shared/tabbrowser/tabs.css --- a/browser/themes/shared/tabbrowser/tabs.css
+++ b/browser/themes/shared/tabbrowser/tabs.css +++ b/browser/themes/shared/tabbrowser/tabs.css
@@ -45,7 +45,7 @@ @@ -46,7 +46,7 @@
--tab-group-line-thickness: 2px; --tab-group-line-thickness: 2px;
--tab-group-line-toolbar-border-distance: 1px; --tab-group-line-toolbar-border-distance: 1px;
/* Collapsed tabs should be square, so set width to match the min height */ /* Collapsed tabs should be square, so set width to match the min height */
- --tab-collapsed-background-width: var(--tab-min-height); - --tab-collapsed-background-width: var(--tab-min-height);
+ --tab-collapsed-background-width: 48px; + --tab-collapsed-background-width: 48px;
--tab-collapsed-width: calc(var(--tab-collapsed-background-width) + 2 * var(--tab-inner-inline-margin)); --tab-collapsed-width: calc(var(--tab-collapsed-background-width) + 2 * var(--tab-inner-inline-margin));
--tab-collapsed-split-pill-offset: 0px;
--tab-pinned-min-width-expanded: calc(var(--tab-pinned-expanded-background-width) + 2 * var(--tab-pinned-margin-inline-expanded)); --tab-pinned-min-width-expanded: calc(var(--tab-pinned-expanded-background-width) + 2 * var(--tab-pinned-margin-inline-expanded));
--tab-note-icon-end-margin: var(--dimension-4); @@ -308,7 +308,6 @@ tab-split-view-wrapper[dragtarget] {
@@ -295,7 +295,6 @@ tab-split-view-wrapper[dragtarget] {
} }
:root:not([uidensity="compact"], [sidebar-expand-on-hover]) &[pinned] { :root:not([uidensity="compact"], [sidebar-expand-on-hover]) &[pinned] {
@@ -19,7 +19,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
} }
&:is([selected], [multiselected]) { &:is([selected], [multiselected]) {
@@ -309,6 +308,7 @@ tab-split-view-wrapper[dragtarget] { @@ -322,6 +321,7 @@ tab-split-view-wrapper[dragtarget] {
border-radius: inherit; border-radius: inherit;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
@@ -27,7 +27,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
&::before { &::before {
position: absolute; position: absolute;
@@ -506,10 +506,6 @@ tab-split-view-wrapper[dragtarget] { @@ -519,10 +519,6 @@ tab-split-view-wrapper[dragtarget] {
@media -moz-pref("browser.tabs.fadeOutUnloadedTabs") { @media -moz-pref("browser.tabs.fadeOutUnloadedTabs") {
&[pending] { &[pending] {
@@ -38,7 +38,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
opacity: 0.5; opacity: 0.5;
/* Fade the favicon out */ /* Fade the favicon out */
transition-property: filter, opacity; transition-property: filter, opacity;
@@ -525,10 +521,6 @@ tab-split-view-wrapper[dragtarget] { @@ -538,10 +534,6 @@ tab-split-view-wrapper[dragtarget] {
@media -moz-pref("browser.tabs.fadeOutExplicitlyUnloadedTabs") { @media -moz-pref("browser.tabs.fadeOutExplicitlyUnloadedTabs") {
&[pending][discarded] { &[pending][discarded] {
@@ -49,7 +49,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
opacity: 0.5; opacity: 0.5;
/* Fade the favicon out */ /* Fade the favicon out */
transition-property: filter, opacity; transition-property: filter, opacity;
@@ -602,7 +594,7 @@ tab-split-view-wrapper[dragtarget] { @@ -615,7 +607,7 @@ tab-split-view-wrapper[dragtarget] {
} }
#tabbrowser-tabs[orient="vertical"] & { #tabbrowser-tabs[orient="vertical"] & {
@@ -58,7 +58,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
} }
&[crashed] { &[crashed] {
@@ -610,7 +602,7 @@ tab-split-view-wrapper[dragtarget] { @@ -623,7 +615,7 @@ tab-split-view-wrapper[dragtarget] {
} }
#tabbrowser-tabs[orient="vertical"]:not([expanded]) &:not([crashed]), #tabbrowser-tabs[orient="vertical"]:not([expanded]) &:not([crashed]),
@@ -67,7 +67,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
&[soundplaying] { &[soundplaying] {
list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-playing-small.svg"); list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-playing-small.svg");
} }
@@ -664,7 +656,7 @@ tab-split-view-wrapper[dragtarget] { @@ -677,7 +669,7 @@ tab-split-view-wrapper[dragtarget] {
} }
} }
@@ -76,7 +76,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
&[crashed] { &[crashed] {
display: revert; display: revert;
} }
@@ -824,7 +816,7 @@ tab-split-view-wrapper[dragtarget] { @@ -837,7 +829,7 @@ tab-split-view-wrapper[dragtarget] {
has not been added to root. There are certain scenarios when that attribute is temporarily has not been added to root. There are certain scenarios when that attribute is temporarily
removed from root such as when toggling the sidebar to expand with the toolbar button. */ removed from root such as when toggling the sidebar to expand with the toolbar button. */
#tabbrowser-tabs[orient="horizontal"] &:not([pinned]):not([crashed]), #tabbrowser-tabs[orient="horizontal"] &:not([pinned]):not([crashed]),
@@ -85,7 +85,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
&:is([soundplaying], [muted], [activemedia-blocked]) { &:is([soundplaying], [muted], [activemedia-blocked]) {
display: flex; display: flex;
} }
@@ -1044,7 +1036,6 @@ tab-split-view-wrapper[dragtarget] { @@ -1151,7 +1143,6 @@ tab-split-view-wrapper[dragtarget] {
.tabbrowser-tab:is([image], [pinned]) > .tab-stack > .tab-content[attention]:not([selected]), .tabbrowser-tab:is([image], [pinned]) > .tab-stack > .tab-content[attention]:not([selected]),
.tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([selected]), .tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([selected]),
#tabbrowser-tabs[orient="vertical"] .tabbrowser-tab > .tab-stack > .tab-content[titlechanged]:not([selected]) { #tabbrowser-tabs[orient="vertical"] .tabbrowser-tab > .tab-stack > .tab-content[titlechanged]:not([selected]) {
@@ -93,7 +93,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
background-position: center bottom 6.5px; background-position: center bottom 6.5px;
background-size: 4px 4px; background-size: 4px 4px;
background-repeat: no-repeat; background-repeat: no-repeat;
@@ -1797,7 +1788,7 @@ tab-group { @@ -1904,7 +1895,7 @@ tab-group {
} }
#tabbrowser-tabs[orient="vertical"][expanded] { #tabbrowser-tabs[orient="vertical"][expanded] {
@@ -102,7 +102,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
&[movingtab][movingtab-addToGroup]:not([movingtab-group], [movingtab-ungroup]) .tabbrowser-tab:is(:active, [multiselected]) { &[movingtab][movingtab-addToGroup]:not([movingtab-group], [movingtab-ungroup]) .tabbrowser-tab:is(:active, [multiselected]) {
margin-inline-start: var(--space-medium); margin-inline-start: var(--space-medium);
} }
@@ -2351,7 +2342,7 @@ tab-group { @@ -2504,7 +2495,7 @@ tab-group {
} }
} }
@@ -111,8 +111,8 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
#vertical-tabs-newtab-button { #vertical-tabs-newtab-button {
appearance: none; appearance: none;
min-height: var(--tab-min-height); min-height: var(--tab-min-height);
@@ -2362,7 +2353,7 @@ tab-group { @@ -2524,7 +2515,7 @@ tab-group {
margin-inline: var(--tab-inner-inline-margin); }
#tabbrowser-tabs[orient="vertical"]:not([expanded]) & > .toolbarbutton-text { #tabbrowser-tabs[orient="vertical"]:not([expanded]) & > .toolbarbutton-text {
- display: none; - display: none;
@@ -120,7 +120,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
} }
&:hover { &:hover {
@@ -2386,7 +2377,7 @@ tab-group { @@ -2548,7 +2539,7 @@ tab-group {
* flex container. #tabs-newtab-button is a child of the arrowscrollbox where * flex container. #tabs-newtab-button is a child of the arrowscrollbox where
* we don't want a gap (between tabs), so we have to add some margin. * we don't want a gap (between tabs), so we have to add some margin.
*/ */
@@ -129,7 +129,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
margin-block: var(--tab-margin-block); margin-block: var(--tab-margin-block);
} }
@@ -2576,7 +2567,6 @@ tab-group { @@ -2740,7 +2731,6 @@ tab-group {
&:not([expanded]) { &:not([expanded]) {
.tabbrowser-tab[pinned] { .tabbrowser-tab[pinned] {
@@ -137,7 +137,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
} }
.tab-background { .tab-background {
@@ -2615,8 +2605,8 @@ tab-group { @@ -2779,8 +2769,8 @@ tab-group {
display: block; display: block;
position: absolute; position: absolute;
inset: auto; inset: auto;
@@ -148,7 +148,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
&:-moz-window-inactive { &:-moz-window-inactive {
background-image: background-image:
@@ -2714,9 +2704,6 @@ tab-group { @@ -2878,9 +2868,6 @@ tab-group {
~ #tabbrowser-tabs[orient="horizontal"]::before { ~ #tabbrowser-tabs[orient="horizontal"]::before {
display: flex; display: flex;
content: ""; content: "";
@@ -158,7 +158,7 @@ index 0820fa040642ee05c2a24f5d2cfa58da5c926647..2d93abcce1729744e5963f1c6ad47f25
} }
} }
@@ -2749,7 +2736,6 @@ toolbar:not(#TabsToolbar) #firefox-view-button { @@ -2913,7 +2900,6 @@ toolbar:not(#TabsToolbar) #firefox-view-button {
list-style-image: url(chrome://global/skin/icons/plus.svg); list-style-image: url(chrome://global/skin/icons/plus.svg);
} }

View File

@@ -1,19 +1,19 @@
diff --git a/browser/themes/shared/urlbar-searchbar.css b/browser/themes/shared/urlbar-searchbar.css diff --git a/browser/themes/shared/urlbar-searchbar.css b/browser/themes/shared/urlbar-searchbar.css
index 22d624d718a289dd7b84ffc2f04dd35893dfbe95..4f57f7853f3043e3ad01d893aa928b9d2e6f3c16 100644 index 149f123e26cd79e89432dfeb504ca7218ee04810..7e0e6d981d6c2aa53bc2a76d82d2078419659065 100644
--- a/browser/themes/shared/urlbar-searchbar.css --- a/browser/themes/shared/urlbar-searchbar.css
+++ b/browser/themes/shared/urlbar-searchbar.css +++ b/browser/themes/shared/urlbar-searchbar.css
@@ -19,8 +19,8 @@ @@ -19,8 +19,8 @@
@media not -moz-pref("browser.nova.enabled") { @media not -moz-pref("browser.nova.enabled") {
--urlbar-basic-component-size: calc(var(--urlbar-min-height) - 2 * (var(--urlbar-input-container-border-width) + var(--urlbar-input-container-padding))); --urlbar-basic-component-size: calc(var(--urlbar-height) - 2 * (var(--urlbar-input-container-border-width) + var(--urlbar-input-container-padding)));
- --urlbar-icon-padding: calc((var(--urlbar-min-height) - 2px /* border */ - 2px /* padding */ - 16px /* icon */) / 2); - --urlbar-icon-padding: calc((var(--urlbar-height) - 2px /* border */ - 2px /* padding */ - 16px /* icon */) / 2);
- --urlbar-input-container-padding: round(up, 1px, env(hairline)); - --urlbar-input-container-padding: round(up, 1px, env(hairline));
+ --urlbar-icon-padding: calc((var(--urlbar-min-height) - 2px /* border */ - 14px /* icon */) / 2); + --urlbar-icon-padding: calc((var(--urlbar-height) - 2px /* border */ - 14px /* icon */) / 2);
+ --urlbar-input-container-padding: 2px; + --urlbar-input-container-padding: 2px;
} }
@media (max-width: 770px) { @media (max-width: 770px) {
--urlbar-container-min-width: 240px; --urlbar-container-min-width: 240px;
@@ -126,7 +126,7 @@ toolbar[inactive="true"] .urlbar, @@ -127,7 +127,7 @@ toolbar[inactive="true"] .urlbar,
.urlbar:not([usertyping]) > .urlbar-input-container > .urlbar-go-button, .urlbar:not([usertyping]) > .urlbar-input-container > .urlbar-go-button,
.urlbar:not(#searchbar-new, [focused]) > .urlbar-input-container > .urlbar-go-button, .urlbar:not(#searchbar-new, [focused]) > .urlbar-input-container > .urlbar-go-button,
#urlbar-revert-button-container { #urlbar-revert-button-container {
@@ -22,7 +22,7 @@ index 22d624d718a289dd7b84ffc2f04dd35893dfbe95..4f57f7853f3043e3ad01d893aa928b9d
} }
/* Document Picture-in-Picture API window */ /* Document Picture-in-Picture API window */
@@ -403,6 +403,10 @@ toolbar[inactive="true"] .urlbar, @@ -405,6 +405,10 @@ toolbar[inactive="true"] .urlbar,
.urlbar:not([focused])[textoverflow="left"][domaindir="rtl"] > .urlbar-input-container > .urlbar-input-box > & { .urlbar:not([focused])[textoverflow="left"][domaindir="rtl"] > .urlbar-input-container > .urlbar-input-box > & {
mask-image: linear-gradient(to right, transparent var(--urlbar-scheme-size), black calc(var(--urlbar-scheme-size) + 3ch)); mask-image: linear-gradient(to right, transparent var(--urlbar-scheme-size), black calc(var(--urlbar-scheme-size) + 3ch));
} }
@@ -33,16 +33,18 @@ index 22d624d718a289dd7b84ffc2f04dd35893dfbe95..4f57f7853f3043e3ad01d893aa928b9d
} }
#urlbar-scheme { #urlbar-scheme {
@@ -492,10 +496,14 @@ toolbar[inactive="true"] .urlbar, @@ -476,10 +480,15 @@ toolbar[inactive="true"] .urlbar,
}
.urlbar[breakout][breakout-extend] { .urlbar[breakout][breakout-extend] {
height: auto; - margin-left: calc(-1 * var(--urlbar-margin-inline));
+ align-items: center; + align-items: center;
+ :root:not([zen-single-toolbar='true']) & {
margin-left: calc(-1 * var(--urlbar-margin-inline));
+ }
width: calc(var(--urlbar-width) + 2 * var(--urlbar-margin-inline)); width: calc(var(--urlbar-width) + 2 * var(--urlbar-margin-inline));
+ :root:not([zen-single-toolbar="true"]) & {
+ margin-left: calc(-1 * var(--urlbar-margin-inline));
+ }
+
> .urlbar-input-container { > .urlbar-input-container {
+ align-items: center; + align-items: center;
height: var(--urlbar-container-height); height: var(--urlbar-container-height);

View File

@@ -812,7 +812,8 @@
#toolbar-context-toggle-vertical-tabs, #toolbar-context-toggle-vertical-tabs,
#toolbar-context-customize-sidebar, #toolbar-context-customize-sidebar,
#sidebarRevampSeparator { #sidebarRevampSeparator,
.fxa-menu-sign-in-promo-image {
display: none !important; display: none !important;
} }
@@ -879,7 +880,7 @@
border-radius: var(--tab-border-radius); border-radius: var(--tab-border-radius);
&:hover { &:hover {
background: var(--toolbarbutton-hover-background); background: var(--toolbarbutton-background-color-hover);
} }
& image { & image {

View File

@@ -1,76 +0,0 @@
diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -411,10 +411,13 @@
pref("browser.urlbar.maxRichResults", 10);
// The maximum number of historical search results to show.
pref("browser.urlbar.maxHistoricalSearchSuggestions", 2);
+// Whether to close the urlbar when blurring the window while the urlbar is focused.
+pref("browser.urlbar.closeOnWindowBlur", true);
+
// The default behavior for the urlbar can be configured to use any combination
// of the match filters with each additional filter adding more results (union).
pref("browser.urlbar.suggest.bookmark", true);
pref("browser.urlbar.suggest.clipboard", true);
pref("browser.urlbar.suggest.history", true);
diff --git a/browser/components/urlbar/UrlbarPrefs.sys.mjs b/browser/components/urlbar/UrlbarPrefs.sys.mjs
--- a/browser/components/urlbar/UrlbarPrefs.sys.mjs
+++ b/browser/components/urlbar/UrlbarPrefs.sys.mjs
@@ -152,10 +152,13 @@
["filter.javascript", true],
// Feature gate pref for flight status suggestions in the urlbar.
["flightStatus.featureGate", false],
+ // Whether to close the urlbar when blurring the window while the urlbar is focused.
+ ["closeOnWindowBlur", true],
+
// The minimum prefix length of a flight status keyword the user must type to
// trigger the suggestion. 0 means the min length should be taken from Nimbus
// or remote settings.
["flightStatus.minKeywordLength", 0],
diff --git a/browser/components/urlbar/content/UrlbarView.mjs b/browser/components/urlbar/content/UrlbarView.mjs
--- a/browser/components/urlbar/content/UrlbarView.mjs
+++ b/browser/components/urlbar/content/UrlbarView.mjs
@@ -3909,10 +3909,16 @@
}
}
}
on_blur() {
+ if (
+ this.document.commandDispatcher.focusedElement == this.input.inputField &&
+ !lazy.UrlbarPrefs.get("closeOnWindowBlur")
+ ) {
+ return;
+ }
// If the view is open without the input being focused, it will not close
// automatically when the window loses focus. We might be in this state
// after a Search Tip is shown on an engine homepage.
if (!lazy.UrlbarPrefs.get("ui.popup.disable_autohide")) {
this.close();
diff --git a/browser/components/urlbar/content/UrlbarInput.mjs b/browser/components/urlbar/content/UrlbarInput.mjs
--- a/browser/components/urlbar/content/UrlbarInput.mjs
+++ b/browser/components/urlbar/content/UrlbarInput.mjs
@@ -5460,11 +5460,17 @@
_on_blur(event) {
if (this.view.resultMenu.hasAttribute("open")) {
return;
}
lazy.logger.debug("Blur Event");
+ if (
+ this.document.commandDispatcher.focusedElement == this.inputField &&
+ !lazy.UrlbarPrefs.get("closeOnWindowBlur")
+ ) {
+ return;
+ }
// We cannot count every blur events after a missed engagement as abandoment
// because the user may have clicked on some view element that executes
// a command causing a focus change. For example opening preferences from
// the oneoff settings button.
// For now we detect that case by discarding the event on command, but we
// may want to figure out a more robust way to detect abandonment.

View File

@@ -31,12 +31,13 @@ diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src
// Ensure the WR profiler callbacks are hooked up to the Gecko profiler. // Ensure the WR profiler callbacks are hooked up to the Gecko profiler.
set_profiler_hooks(Some(&PROFILER_HOOKS)); set_profiler_hooks(Some(&PROFILER_HOOKS));
@@ -2164,10 +2165,11 @@ @@ -2164,11 +2165,12 @@
texture_cache_config, texture_cache_config,
reject_software_rasterizer, reject_software_rasterizer,
low_quality_pinch_zoom, low_quality_pinch_zoom,
max_shared_surface_size, max_shared_surface_size,
enable_dithering, enable_dithering,
enable_shared_instance_buffer,
+ opaque_backdrop_fallback, + opaque_backdrop_fallback,
..Default::default() ..Default::default()
}; };
@@ -73,8 +74,9 @@ diff --git a/gfx/wr/webrender/src/renderer/init.rs b/gfx/wr/webrender/src/render
+ /// See explanation of `gfx.webrender.opaque-backdrop-fallback`. + /// See explanation of `gfx.webrender.opaque-backdrop-fallback`.
+ pub opaque_backdrop_fallback: bool, + pub opaque_backdrop_fallback: bool,
} }
@@ -277,9 +279,10 @@ @@ -277,10 +279,11 @@
enable_instancing: true, enable_instancing: true,
enable_shared_instance_buffer: false,
reject_software_rasterizer: false, reject_software_rasterizer: false,
low_quality_pinch_zoom: false, low_quality_pinch_zoom: false,
max_shared_surface_size: 2048, max_shared_surface_size: 2048,
@@ -84,12 +86,13 @@ diff --git a/gfx/wr/webrender/src/renderer/init.rs b/gfx/wr/webrender/src/render
} }
} }
@@ -802,10 +805,11 @@ @@ -802,11 +805,12 @@
allocated_native_surfaces: FastHashSet::default(), allocated_native_surfaces: FastHashSet::default(),
debug_overlay_state: DebugOverlayState::new(), debug_overlay_state: DebugOverlayState::new(),
buffer_damage_tracker: BufferDamageTracker::default(), buffer_damage_tracker: BufferDamageTracker::default(),
max_primitive_instance_count, max_primitive_instance_count,
enable_instancing: options.enable_instancing, enable_instancing: options.enable_instancing,
use_shared_instance_buffer,
+ opaque_backdrop_fallback: options.opaque_backdrop_fallback, + opaque_backdrop_fallback: options.opaque_backdrop_fallback,
consecutive_oom_frames: 0, consecutive_oom_frames: 0,
target_frame_publish_id: None, target_frame_publish_id: None,
@@ -99,11 +102,14 @@ diff --git a/gfx/wr/webrender/src/renderer/init.rs b/gfx/wr/webrender/src/render
diff --git a/gfx/wr/webrender/src/renderer/mod.rs b/gfx/wr/webrender/src/renderer/mod.rs diff --git a/gfx/wr/webrender/src/renderer/mod.rs b/gfx/wr/webrender/src/renderer/mod.rs
--- a/gfx/wr/webrender/src/renderer/mod.rs --- a/gfx/wr/webrender/src/renderer/mod.rs
+++ b/gfx/wr/webrender/src/renderer/mod.rs +++ b/gfx/wr/webrender/src/renderer/mod.rs
@@ -867,10 +867,12 @@ @@ -867,13 +867,15 @@
buffer_damage_tracker: BufferDamageTracker, buffer_damage_tracker: BufferDamageTracker,
max_primitive_instance_count: usize, max_primitive_instance_count: usize,
enable_instancing: bool, enable_instancing: bool,
/// If true, stream instance data into large buffers shared by multiple
/// draws, rather than allocating a new instance buffer for each draw.
use_shared_instance_buffer: bool,
+ opaque_backdrop_fallback: bool, + opaque_backdrop_fallback: bool,
+ +

View File

@@ -0,0 +1,168 @@
diff --git a/browser/components/sessionstore/test/browser.toml b/browser/components/sessionstore/test/browser.toml
--- a/browser/components/sessionstore/test/browser.toml
+++ b/browser/components/sessionstore/test/browser.toml
@@ -14,10 +14,12 @@
"browser_frame_history_c.html",
"browser_frame_history_c1.html",
"browser_frame_history_c2.html",
"browser_formdata_format_sample.html",
"browser_sessionHistory_slow.sjs",
+ "browser_policy_container_sample.html",
+ "browser_policy_container_sample_frame.html",
"browser_scrollPositions_sample.html",
"browser_scrollPositions_sample2.html",
"browser_scrollPositions_sample_frameset.html",
"browser_scrollPositions_readerModeArticle.html",
"browser_sessionStorage.html",
@@ -226,10 +228,12 @@
["browser_pinned_tabs.js"]
skip-if = [
"ccov", # Bug 1625525
]
+["browser_policy_container_not_stored.js"]
+
["browser_privatetabs.js"]
["browser_purge_domaindata.js"]
["browser_purge_shistory.js"]
diff --git a/browser/components/sessionstore/test/browser_policy_container_not_stored.js b/browser/components/sessionstore/test/browser_policy_container_not_stored.js
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_policy_container_not_stored.js
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+/**
+ * A session history entry only needs to retain the policy container for loads
+ * that inherit their policies (about:blank, about:srcdoc, blob:, data:, ...).
+ * Anything fetched over the network gets its policies from the response again,
+ * so storing them would only bloat the session store (bug 2011236).
+ */
+
+const TEST_ROOT = getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ "https://example.com"
+);
+const PARENT_URL = TEST_ROOT + "browser_policy_container_sample.html";
+const FRAME_URL = TEST_ROOT + "browser_policy_container_sample_frame.html";
+
+add_task(async function test_policy_container_only_for_inheriting_loads() {
+ const tab = BrowserTestUtils.addTab(gBrowser, PARENT_URL);
+ gBrowser.selectedTab = tab;
+ await promiseBrowserLoaded(tab.linkedBrowser, true, PARENT_URL);
+ await TabStateFlusher.flush(tab.linkedBrowser);
+
+ const state = JSON.parse(ss.getTabState(tab));
+ const topEntry = state.entries.at(-1);
+ is(topEntry.url, PARENT_URL, "collected the parent entry");
+
+ const children = topEntry.children ?? [];
+ const networkFrame = children.find(child => child.url === FRAME_URL);
+ const blankFrame = children.find(child => child.url === "about:blank");
+
+ ok(networkFrame, "collected the network-scheme subframe entry");
+ ok(blankFrame, "collected the about:blank subframe entry");
+
+ // The parent has a CSP, so both subframes inherit a policy container onto
+ // their load state. Only the one that cannot recover it from a response
+ // should keep it in session history.
+ ok(
+ !("policyContainer" in networkFrame),
+ "https subframe entry does not store a policyContainer"
+ );
+ ok(
+ "policyContainer" in blankFrame,
+ "about:blank subframe entry still stores its inherited policyContainer"
+ );
+
+ await BrowserTestUtils.removeTab(tab);
+});
diff --git a/browser/components/sessionstore/test/browser_policy_container_sample.html b/browser/components/sessionstore/test/browser_policy_container_sample.html
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_policy_container_sample.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Security-Policy" content="default-src * data: blob: 'unsafe-inline'">
+ <title>policyContainer session store sample</title>
+</head>
+<body>
+ <iframe id="network" src="browser_policy_container_sample_frame.html"></iframe>
+ <iframe id="blank" src="about:blank"></iframe>
+</body>
+</html>
diff --git a/browser/components/sessionstore/test/browser_policy_container_sample_frame.html b/browser/components/sessionstore/test/browser_policy_container_sample_frame.html
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_policy_container_sample_frame.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>policyContainer session store sample frame</title>
+</head>
+<body>
+ frame
+</body>
+</html>
diff --git a/docshell/shistory/SessionHistoryEntry.cpp b/docshell/shistory/SessionHistoryEntry.cpp
--- a/docshell/shistory/SessionHistoryEntry.cpp
+++ b/docshell/shistory/SessionHistoryEntry.cpp
@@ -41,10 +41,18 @@
extern mozilla::LazyLogModule gSHLog;
namespace mozilla {
namespace dom {
+// Only store policy container for loads that can't carry it themselves
+// (about:blank, about:srcdoc, blob:, data:, ...)
+// bug 1867137, bug 2011236
+static nsIPolicyContainer* PolicyContainerToStore(
+ nsIURI* aURI, nsIPolicyContainer* aPolicyContainer) {
+ return CSP_ShouldURIInheritCSP(aURI) ? aPolicyContainer : nullptr;
+}
+
SessionHistoryInfo::SessionHistoryInfo(nsDocShellLoadState* aLoadState,
nsIChannel* aChannel)
: mURI(aLoadState->URI()),
mOriginalURI(aLoadState->OriginalURI()),
mResultPrincipalURI(aLoadState->ResultPrincipalURI()),
@@ -59,11 +67,12 @@
mLoadReplace(aLoadState->LoadReplace()),
mHasUserActivation(aLoadState->HasValidUserGestureActivation()),
mSharedState(SharedState::Create(
aLoadState->TriggeringPrincipal(), aLoadState->PrincipalToInherit(),
aLoadState->PartitionedPrincipalToInherit(),
- aLoadState->PolicyContainer(),
+ PolicyContainerToStore(aLoadState->URI(),
+ aLoadState->PolicyContainer()),
/* FIXME Is this correct? */
aLoadState->TypeHint())) {
MOZ_DIAGNOSTIC_ASSERT(!mURI->SchemeIs("javascript"));
// Pull the upload stream off of the channel instead of the load state, as
@@ -124,11 +133,12 @@
loadInfo->GetPrincipalToInherit(
getter_AddRefs(mSharedState.Get()->mPrincipalToInherit));
mSharedState.Get()->mPartitionedPrincipalToInherit =
aPartitionedPrincipalToInherit;
- mSharedState.Get()->mPolicyContainer = aPolicyContainer;
+ mSharedState.Get()->mPolicyContainer =
+ PolicyContainerToStore(mURI, aPolicyContainer);
aChannel->GetContentType(mSharedState.Get()->mContentType);
aChannel->GetOriginalURI(getter_AddRefs(mOriginalURI));
uint32_t loadFlags;
aChannel->GetLoadFlags(&loadFlags);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
diff --git a/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs b/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs
--- a/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs
+++ b/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs
@@ -119,10 +119,19 @@
}
case "PictureInPicture:VideoTabHidden": {
if (!lazy.PIP_ENABLED || !lazy.PIP_WHEN_SWITCHING_TABS) {
break;
}
+
+ // Suppress auto-toggle if the user deliberately closed this PiP window
+ if (
+ PictureInPicture.weakAutoPipBrowserClosedDeliberately.has(browser)
+ ) {
+ PictureInPicture.weakAutoPipBrowserClosedDeliberately.delete(browser);
+ break;
+ }
+
// If the tab is still selected, then we can ignore this event
if (browser.documentGlobal.gBrowser.selectedBrowser == browser) {
break;
}
let actor = browsingContext.currentWindowGlobal.getActor(
@@ -261,10 +270,12 @@
maxConcurrentPlayerCount: 0,
// Maps auto pip browser to PictureInPictureParent actor
weakAutoPipBrowserToParent: new WeakMap(),
+ weakAutoPipBrowserClosedDeliberately: new WeakSet(),
+
/**
* Returns the player window if one exists and if it hasn't yet been closed.
*
* @param {PictureInPictureParent} pipActorRef
* Reference to the calling PictureInPictureParent actor
@@ -899,10 +910,17 @@
const { reason, actorRef } = closeData;
const win = this.getWeakPipPlayer(actorRef);
if (!win) {
return;
}
+
+ const browser = this.weakWinToBrowser.get(win);
+
+ if (reason === "CloseButton") {
+ PictureInPicture.weakAutoPipBrowserClosedDeliberately.add(browser);
+ }
+
this.removePiPBrowserFromWeakMap(this.weakWinToBrowser.get(win));
this.weakAutoPipBrowserToParent.delete(this.weakWinToBrowser.get(win));
Glean.pictureinpicture["closedMethod" + reason].record();
await this.closePipWindow(win);

View File

@@ -7,14 +7,6 @@
"id": "D299584", "id": "D299584",
"name": "Native MacOS popovers fix" "name": "Native MacOS popovers fix"
}, },
{
"type": "phabricator",
"id": "D284404",
"name": "Add urlbar closeOnWindowBlur preference",
"replaces": {
"\n\n": "\n // may want to figure out a more robust way to detect abandonment."
}
},
{ {
"type": "local", "type": "local",
// TODO: Convert into https://phabricator.services.mozilla.com/D298079 // TODO: Convert into https://phabricator.services.mozilla.com/D298079
@@ -48,5 +40,19 @@
"this._lastJsonLength = uncompressedBytes;": "this._lastJsonLength = uncompressedBytes.jsonLength;", "this._lastJsonLength = uncompressedBytes;": "this._lastJsonLength = uncompressedBytes.jsonLength;",
" jsonLengthHint,": " lengthHint: jsonLengthHint," " jsonLengthHint,": " lengthHint: jsonLengthHint,"
} }
},
{
"type": "phabricator",
"id": "D320897",
"name": "Bug 2011236"
},
{
"type": "phabricator",
"id": "D321446",
"name": "Issue 14710"
},
{
"type": "local",
"path": "firefox/css_corner_shape_rendering.patch"
} }
] ]

View File

@@ -1,16 +1,16 @@
diff --git a/layout/style/StyleColor.cpp b/layout/style/StyleColor.cpp diff --git a/layout/style/StyleColor.cpp b/layout/style/StyleColor.cpp
index bbee32af30f35525730a10d0b242c0e8a8fe4695..a590fff105b30bc96fa7a0d8a8d3b1d5aa997e08 100644 index f922f7fdacc7e1a14beb8da77b48aef3f6ae0b2b..47d19242baaf2a1f25ee07c6e210c839cc7b5089 100644
--- a/layout/style/StyleColor.cpp --- a/layout/style/StyleColor.cpp
+++ b/layout/style/StyleColor.cpp +++ b/layout/style/StyleColor.cpp
@@ -9,6 +9,7 @@ @@ -8,6 +8,7 @@
#include "mozilla/dom/BindingDeclarations.h" #include "mozilla/StyleColorInlines.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsStyleStruct.h" #include "nsStyleStruct.h"
+#include "mozilla/nsZenBoostsBackend.h" +#include "mozilla/nsZenBoostsBackend.h"
#include "nsStyleUtil.h"
namespace mozilla { namespace mozilla {
@@ -98,23 +99,24 @@ StyleAbsoluteColor StyleColor::ResolveColor(
@@ -96,23 +97,24 @@ StyleAbsoluteColor StyleColor::ResolveColor(
template <> template <>
nscolor StyleColor::CalcColor(nscolor aColor) const { nscolor StyleColor::CalcColor(nscolor aColor) const {
@@ -40,7 +40,7 @@ index bbee32af30f35525730a10d0b242c0e8a8fe4695..a590fff105b30bc96fa7a0d8a8d3b1d5
} }
StyleAbsoluteColor StyleAbsoluteColor::ToColorSpace( StyleAbsoluteColor StyleAbsoluteColor::ToColorSpace(
@@ -120,7 +122,7 @@ StyleAbsoluteColor StyleAbsoluteColor::ToColorSpace( @@ -122,7 +124,7 @@ StyleAbsoluteColor StyleAbsoluteColor::ToColorSpace(
return Servo_ConvertColorSpace(this, aColorSpace); return Servo_ConvertColorSpace(this, aColorSpace);
} }
@@ -49,7 +49,7 @@ index bbee32af30f35525730a10d0b242c0e8a8fe4695..a590fff105b30bc96fa7a0d8a8d3b1d5
constexpr StyleColorSpace DEST_COLOR_SPACE = StyleColorSpace::Srgb; constexpr StyleColorSpace DEST_COLOR_SPACE = StyleColorSpace::Srgb;
constexpr float MIN = 0.0f; constexpr float MIN = 0.0f;
@@ -162,11 +164,13 @@ nscolor StyleAbsoluteColor::ToColor() const { @@ -164,11 +166,13 @@ nscolor StyleAbsoluteColor::ToColor() const {
} }
} }

View File

@@ -1,5 +1,5 @@
diff --git a/layout/svg/SVGImageContext.h b/layout/svg/SVGImageContext.h diff --git a/layout/svg/SVGImageContext.h b/layout/svg/SVGImageContext.h
index b1f811989697966e30859610f4fc07579d0385ab..f6f4cd5a45fc49b416111d980fab4e612788903e 100644 index ad833c7c2ee6a4c4984efdb0d59e3576c2d1bc19..36864a34badc0cbfe44d6295798622fd6178f9e3 100644
--- a/layout/svg/SVGImageContext.h --- a/layout/svg/SVGImageContext.h
+++ b/layout/svg/SVGImageContext.h +++ b/layout/svg/SVGImageContext.h
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
@@ -44,7 +44,7 @@ index b1f811989697966e30859610f4fc07579d0385ab..f6f4cd5a45fc49b416111d980fab4e61
const Maybe<SVGPreserveAspectRatio>& GetPreserveAspectRatio() const { const Maybe<SVGPreserveAspectRatio>& GetPreserveAspectRatio() const {
return mPreserveAspectRatio; return mPreserveAspectRatio;
} }
@@ -116,7 +137,11 @@ class SVGImageContext { @@ -110,7 +131,11 @@ class SVGImageContext {
return contextPaintIsEqual && mViewportSize == aOther.mViewportSize && return contextPaintIsEqual && mViewportSize == aOther.mViewportSize &&
mPreserveAspectRatio == aOther.mPreserveAspectRatio && mPreserveAspectRatio == aOther.mPreserveAspectRatio &&
mColorScheme == aOther.mColorScheme && mColorScheme == aOther.mColorScheme &&
@@ -57,8 +57,8 @@ index b1f811989697966e30859610f4fc07579d0385ab..f6f4cd5a45fc49b416111d980fab4e61
} }
bool operator!=(const SVGImageContext&) const = default; bool operator!=(const SVGImageContext&) const = default;
@@ -129,7 +154,8 @@ class SVGImageContext { @@ -123,7 +148,8 @@ class SVGImageContext {
return HashGeneric(hash, mViewportSize.map(HashSize).valueOr(0), return AddToHash(hash, mViewportSize.map(HashSize).valueOr(0),
mPreserveAspectRatio.map(HashPAR).valueOr(0), mPreserveAspectRatio.map(HashPAR).valueOr(0),
mColorScheme.map(HashColorScheme).valueOr(0), mColorScheme.map(HashColorScheme).valueOr(0),
- HashLinkParameters(mLinkParameters)); - HashLinkParameters(mLinkParameters));
@@ -67,7 +67,7 @@ index b1f811989697966e30859610f4fc07579d0385ab..f6f4cd5a45fc49b416111d980fab4e61
} }
private: private:
@@ -167,6 +193,9 @@ class SVGImageContext { @@ -156,6 +182,9 @@ class SVGImageContext {
Maybe<SVGPreserveAspectRatio> mPreserveAspectRatio; Maybe<SVGPreserveAspectRatio> mPreserveAspectRatio;
Maybe<ColorScheme> mColorScheme; Maybe<ColorScheme> mColorScheme;
StyleLinkParameters mLinkParameters; StyleLinkParameters mLinkParameters;

View File

@@ -1,5 +1,5 @@
diff --git a/services/sync/modules/service.sys.mjs b/services/sync/modules/service.sys.mjs diff --git a/services/sync/modules/service.sys.mjs b/services/sync/modules/service.sys.mjs
index 4f4efe572909441abdd81909282936702c225621..81ab06a9414ed656b644a21b40b683f06a4f8dbf 100644 index 4f4efe572909441abdd81909282936702c225621..2b47a2c9e97cf87641a0be9814f9a6be4d43f6ea 100644
--- a/services/sync/modules/service.sys.mjs --- a/services/sync/modules/service.sys.mjs
+++ b/services/sync/modules/service.sys.mjs +++ b/services/sync/modules/service.sys.mjs
@@ -99,6 +99,10 @@ function getEngineModules() { @@ -99,6 +99,10 @@ function getEngineModules() {
@@ -7,8 +7,8 @@ index 4f4efe572909441abdd81909282936702c225621..81ab06a9414ed656b644a21b40b683f0
whenFalse: "ExtensionStorageEngineBridge", whenFalse: "ExtensionStorageEngineBridge",
}; };
+ result.Spaces = { + result.Spaces = {
+ module: "resource:///modules/zen/ZenWorkspacesSync.sys.mjs", + module: "resource:///modules/zen/ZenSpacesSync.sys.mjs",
+ symbol: "ZenWorkspacesEngine", + symbol: "ZenSpacesSyncEngine",
+ }; + };
return result; return result;
} }

View File

@@ -0,0 +1,14 @@
diff --git a/testing/xpcshell/runxpcshelltests.py b/testing/xpcshell/runxpcshelltests.py
index 403401613189ffb758037850dc6bbb1d55f194ab..cad28e245155eb54775e551885532026e56c5fa9 100755
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -2275,6 +2275,9 @@ class XPCShellTests:
appDirKey = None
if "appname" in self.mozInfo:
appDirKey = self.mozInfo["appname"] + "-appdir"
+ if appDirKey == "zen-appdir":
+ # Inherited manifests use firefox-appdir.
+ appDirKey = "firefox-appdir"
# We have to do this before we run tests that depend on having the node
# http/2 server.

View File

@@ -1,37 +0,0 @@
diff --git a/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs b/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs
index 5702ff28cc22206f5ce16584dac8a78d816562ce..3d08ecc97ce5995b30d8a4af0c33df329b428008 100644
--- a/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs
+++ b/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs
@@ -270,11 +270,29 @@ _ContextualIdentityService.prototype = {
});
},
- create(name, icon, color) {
+ create(name, icon, color, id = null) {
this.ensureDataReady();
- // Retrieve the next userContextId available.
- let userContextId = ++this._lastUserContextId;
+ if (id !== null) {
+ id = typeof id == "string" ? Number(id) : id;
+ if (!Number.isSafeInteger(id) || id <= 0) {
+ throw new Error(`Invalid userContextId '${id}'`);
+ }
+ }
+
+ let userContextId;
+ if (
+ id !== null &&
+ !this._identities.some(identity => identity.userContextId === id)
+ ) {
+ userContextId = id;
+ this._lastUserContextId = Math.max(
+ this._lastUserContextId,
+ userContextId
+ );
+ } else {
+ userContextId = ++this._lastUserContextId;
+ }
// Throw an error if the next userContextId available is invalid (the one associated to
// MAX_USER_CONTEXT_ID is already reserved to "userContextIdInternal.webextStorageLocal", which

View File

@@ -1,5 +1,5 @@
diff --git a/toolkit/content/widgets/moz-toggle/moz-toggle.tokens.css b/toolkit/content/widgets/moz-toggle/moz-toggle.tokens.css diff --git a/toolkit/content/widgets/moz-toggle/moz-toggle.tokens.css b/toolkit/content/widgets/moz-toggle/moz-toggle.tokens.css
index 6247d7a3923a6fedd4ec9911aba309ce565cd498..744e670eccc936dde664aa07df3e87bdcafd5e48 100644 index c0976c54418a28046802443931042bd285aefbde..2adb18d25edbb8aac4e396fcfc64a4a664607836 100644
--- a/toolkit/content/widgets/moz-toggle/moz-toggle.tokens.css --- a/toolkit/content/widgets/moz-toggle/moz-toggle.tokens.css
+++ b/toolkit/content/widgets/moz-toggle/moz-toggle.tokens.css +++ b/toolkit/content/widgets/moz-toggle/moz-toggle.tokens.css
@@ -13,8 +13,8 @@ @@ -13,8 +13,8 @@
@@ -11,5 +11,5 @@ index 6247d7a3923a6fedd4ec9911aba309ce565cd498..744e670eccc936dde664aa07df3e87bd
+ --toggle-background-color-pressed: var(--zen-primary-color); + --toggle-background-color-pressed: var(--zen-primary-color);
+ --toggle-background-color-pressed-hover: var(--zen-colors-hover-bg); + --toggle-background-color-pressed-hover: var(--zen-colors-hover-bg);
--toggle-background-color-pressed-active: var(--color-accent-primary-active); --toggle-background-color-pressed-active: var(--color-accent-primary-active);
--toggle-border-color: var(--border-color-interactive); --toggle-border-color: light-dark(var(--color-gray-70), var(--border-color-interactive));
--toggle-border-color-hover: var(--toggle-border-color); --toggle-border-color-hover: var(--toggle-border-color);

View File

@@ -0,0 +1,29 @@
diff --git a/toolkit/content/widgets/panel-list/panel-list.mjs b/toolkit/content/widgets/panel-list/panel-list.mjs
index 68ad2fafc8b31dfff541cf8381d9b9533e376d1c..fa62fec6bfb33338091fc06d3736fb76fd5c47c4 100644
--- a/toolkit/content/widgets/panel-list/panel-list.mjs
+++ b/toolkit/content/widgets/panel-list/panel-list.mjs
@@ -223,7 +223,12 @@ export class PanelList extends HTMLElement {
this.setAttribute("showing", "true");
// Tell the host element to hide any overflow in case the panel extends off
// the page before the alignment is set.
- hostElement.style.overflow = "hidden";
+ const hostHidesOverflow = !getComputedStyle(hostElement)
+ .overflow.split(" ")
+ .includes("visible");
+ if (!hostHidesOverflow) {
+ hostElement.style.overflow = "hidden";
+ }
// Wait for a layout flush, then find the bounds.
let {
@@ -344,7 +349,9 @@ export class PanelList extends HTMLElement {
// Set the alignments and show the panel.
this.setAttribute("align", align);
this.setAttribute("valign", valign);
- hostElement.style.overflow = "";
+ if (!hostHidesOverflow) {
+ hostElement.style.overflow = "";
+ }
// Decide positioning based on where this panel will be rendered
const offsetParentIsBody =
this.supportsPopover() ||

View File

@@ -1,5 +1,5 @@
diff --git a/toolkit/themes/shared/design-system/dist/tokens-shared.css b/toolkit/themes/shared/design-system/dist/tokens-shared.css diff --git a/toolkit/themes/shared/design-system/dist/tokens-shared.css b/toolkit/themes/shared/design-system/dist/tokens-shared.css
index 15c0d98a18b4f19e7f2e03d2b78066b0353f416a..b32f6244c7a07e93894bab422691a605456034a1 100644 index 63c641f560d4c0ce06b40a652ca99d1c48cd6941..39c81e773a442870763396e68fb57bd336e3625a 100644
--- a/toolkit/themes/shared/design-system/dist/tokens-shared.css --- a/toolkit/themes/shared/design-system/dist/tokens-shared.css
+++ b/toolkit/themes/shared/design-system/dist/tokens-shared.css +++ b/toolkit/themes/shared/design-system/dist/tokens-shared.css
@@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
@@ -11,7 +11,22 @@ index 15c0d98a18b4f19e7f2e03d2b78066b0353f416a..b32f6244c7a07e93894bab422691a605
@layer tokens-foundation { @layer tokens-foundation {
:root, :root,
:host(.anonymous-content-host) { :host(.anonymous-content-host) {
@@ -424,8 +426,8 @@ @@ -28,10 +30,10 @@
--border-color-selected: var(--color-accent-primary);
--border-color-transparent: transparent;
--border-radius-circle: 9999px;
- --border-radius-xsmall: 2px;
- --border-radius-small: 4px;
- --border-radius-medium: 8px;
- --border-radius-large: 16px;
+ --border-radius-xsmall: calc(2px * var(--zen-squircle-value));
+ --border-radius-small: calc(4px * var(--zen-squircle-value));
+ --border-radius-medium: calc(8px * var(--zen-squircle-value));
+ --border-radius-large: calc(16px * var(--zen-squircle-value));
--border-width: 1px;
/** box-shadow **/
@@ -477,8 +479,8 @@
--panel-background-color-dimmed-further: var(--background-color-dimmed-further); --panel-background-color-dimmed-further: var(--background-color-dimmed-further);
--panel-border-color: light-dark(rgb(240, 240, 244), rgb(82, 82, 94)); --panel-border-color: light-dark(rgb(240, 240, 244), rgb(82, 82, 94));
--panel-border-radius: var(--border-radius-medium); --panel-border-radius: var(--border-radius-medium);

View File

@@ -1,8 +1,8 @@
diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h
index 312011c1c2ac41e78affecbdef25d72766a7c882..e5865c7d6259f0a3df48edf7a26b1b75a23cdb3a 100644 index 22a2a7ef3a5e9257c8bb00ba6a55e8d39d2abbd9..6d8353fd11921585f7101f5717bdb3dd8f2a5eae 100644
--- a/widget/cocoa/nsCocoaWindow.h --- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h
@@ -462,6 +462,10 @@ class nsCocoaWindow final : public nsIWidget { @@ -461,6 +461,10 @@ class nsCocoaWindow final : public nsIWidget {
void SetHideTitlebarSeparator(bool) override; void SetHideTitlebarSeparator(bool) override;
bool IsMacTitlebarDirectionRTL() override; bool IsMacTitlebarDirectionRTL() override;
void SetCustomTitlebar(bool) override; void SetCustomTitlebar(bool) override;
@@ -13,9 +13,9 @@ index 312011c1c2ac41e78affecbdef25d72766a7c882..e5865c7d6259f0a3df48edf7a26b1b75
void UpdateThemeGeometries( void UpdateThemeGeometries(
const nsTArray<ThemeGeometry>& aThemeGeometries) override; const nsTArray<ThemeGeometry>& aThemeGeometries) override;
void LockAspectRatio(bool aShouldLock) override; void LockAspectRatio(bool aShouldLock) override;
@@ -672,6 +676,7 @@ class nsCocoaWindow final : public nsIWidget { @@ -674,6 +678,7 @@ class nsCocoaWindow final : public nsIWidget {
bool mAspectRatioLocked = false; // show (e.g. a window created by detaching a tab from a fullscreen window).
bool mIsAlert = false; // True if this is an non-native alert window. bool mIsInitialFullscreenSuppressed = false;
bool mWasShown = false; bool mWasShown = false;
+ bool mIsBrowserWindow = false; + bool mIsBrowserWindow = false;

View File

@@ -0,0 +1,29 @@
diff --git a/widget/gtk/nsDragSessionSource.cpp b/widget/gtk/nsDragSessionSource.cpp
index a5f67d700f8c80d513f08cc25405b57cf28a2a9a..58186470bcbb7b1eda34ee20a19e29d540ab052a 100644
--- a/widget/gtk/nsDragSessionSource.cpp
+++ b/widget/gtk/nsDragSessionSource.cpp
@@ -13,6 +13,7 @@
#include "mozilla/Services.h"
#include "mozilla/StaticPrefs_widget.h"
#include "mozilla/WidgetUtilsGtk.h"
+#include "mozilla/nsZenDragAndDrop.h"
#include "nsAppShell.h"
#include "nsArrayUtils.h"
#include "nsCRT.h"
@@ -1196,11 +1197,15 @@ bool nsDragSessionSource::SetAlphaPixmap(SourceSurface* aSurface,
cairo_image_surface_get_stride(surf), SurfaceFormat::B8G8R8A8);
if (!dt) return false;
+ auto drag_translucency = DRAG_IMAGE_ALPHA_LEVEL;
+ if (auto zenDragAndDrop = zen::nsZenDragAndDrop::GetZenDragAndDropInstance()) {
+ drag_translucency = zenDragAndDrop->GetDragImageOpacity();
+ }
dt->ClearRect(Rect(0, 0, dragRect.width, dragRect.height));
dt->DrawSurface(
aSurface, Rect(0, 0, dragRect.width, dragRect.height),
Rect(0, 0, dragRect.width, dragRect.height), DrawSurfaceOptions(),
- DrawOptions(DRAG_IMAGE_ALPHA_LEVEL, CompositionOp::OP_SOURCE));
+ DrawOptions(drag_translucency, CompositionOp::OP_SOURCE));
cairo_surface_mark_dirty(surf);
cairo_surface_set_device_offset(surf, -aXOffset, -aYOffset);

View File

@@ -49,9 +49,9 @@
<vbox flex="1" id="zen-boost-filter-wrapper"> <vbox flex="1" id="zen-boost-filter-wrapper">
<hbox class="zen-boost-color-picker-gradient zen-boost-panel-disabled"> <hbox class="zen-boost-color-picker-gradient zen-boost-panel-disabled">
<button data-l10n-id="zen-boost-magic-theme" id="zen-boost-magic-theme" class="subviewbutton mod-button"></button> <button data-l10n-id="zen-boost-magic-theme" id="zen-boost-magic-theme" class="subviewbutton mod-button"></button>
<html:div id="zen-boost-color-picker-dot-primary" class="zen-boost-color-picker-dot"></html:div> <html:div id="zen-boost-color-picker-dot-primary" class="zen-boost-color-picker-dot no-squircles"></html:div>
<html:div id="zen-boost-color-picker-dot-secondary" class="zen-boost-color-picker-dot"></html:div> <html:div id="zen-boost-color-picker-dot-secondary" class="zen-boost-color-picker-dot no-squircles"></html:div>
<html:div class="zen-boost-color-picker-circle"></html:div> <html:div class="zen-boost-color-picker-circle no-squircles"></html:div>
</hbox> </hbox>
<hbox flex="1" id="zen-boost-toolbar-wrapper-colors"> <hbox flex="1" id="zen-boost-toolbar-wrapper-colors">

View File

@@ -194,7 +194,8 @@ body {
max-height: 40px; max-height: 40px;
align-items: center; align-items: center;
background-color: var(--zen-boosts-secondary-background); background-color: var(--zen-boosts-secondary-background);
border: solid 1px var(--zen-boosts-primary-border-color); border: solid 1px transparent;
border-bottom-color: var(--zen-boosts-primary-border-color);
@media (-moz-windows-mica) { @media (-moz-windows-mica) {
background-color: var(--zen-boosts-mica-background); background-color: var(--zen-boosts-mica-background);

View File

@@ -4,6 +4,7 @@
import checkForZenUpdates, { import checkForZenUpdates, {
createWindowUpdateAnimation, createWindowUpdateAnimation,
playWindowSweepAnimation,
} from "chrome://browser/content/ZenUpdates.mjs"; } from "chrome://browser/content/ZenUpdates.mjs";
class ZenStartup { class ZenStartup {
@@ -195,6 +196,14 @@ class ZenStartup {
checkForZenUpdates(); checkForZenUpdates();
return await createWindowUpdateAnimation(); return await createWindowUpdateAnimation();
} }
/**
* Entry point for privileged modules (e.g. the sync applier) to play the
* update sweep animation in this window.
*/
playWindowSweepAnimation() {
return playWindowSweepAnimation();
}
} }
window.gZenStartup = new ZenStartup(); window.gZenStartup = new ZenStartup();

View File

@@ -493,6 +493,13 @@ window.gZenUIManager = {
_clearTimeout: null, _clearTimeout: null,
_lastTab: null, _lastTab: null,
_urlbarSessionCounter: 0,
_urlbarOwner: null,
_isOwner(closeSeq) {
return this._urlbarOwner === closeSeq;
},
// Check if browser elements are in a valid state for tab operations // Check if browser elements are in a valid state for tab operations
_validateBrowserState() { _validateBrowserState() {
// Check if browser window is still open // Check if browser window is still open
@@ -517,8 +524,15 @@ window.gZenUIManager = {
werePassedURL, werePassedURL,
searchClipboard, searchClipboard,
where, where,
overridePreferance = false overridePreferance = false,
closeToken = {}
) { ) {
// Keep this here. It's better to make sure every
// call has a different token rather then forgetting
// to increment it in one of the early returns.
const closeSeq = ++this._urlbarSessionCounter;
closeToken.id = closeSeq;
// Validate browser state first // Validate browser state first
if (!this._validateBrowserState()) { if (!this._validateBrowserState()) {
console.warn("Browser state invalid for new tab operation"); console.warn("Browser state invalid for new tab operation");
@@ -529,6 +543,10 @@ window.gZenUIManager = {
return false; return false;
} }
if (document.documentElement.hasAttribute("zen-welcome-stage")) {
return false;
}
const shouldOpenURLBar = const shouldOpenURLBar =
overridePreferance || overridePreferance ||
(gZenVerticalTabsManager._canReplaceNewTab && (gZenVerticalTabsManager._canReplaceNewTab &&
@@ -542,7 +560,13 @@ window.gZenUIManager = {
// Close the new tab popup on cmd/ctrl + t // Close the new tab popup on cmd/ctrl + t
if (!overridePreferance && gURLBar.hasAttribute("zen-newtab")) { if (!overridePreferance && gURLBar.hasAttribute("zen-newtab")) {
this.handleUrlbarClose(); // The _zenHandleUrlbarClose holds a token in it's closure.
// Call that instead.
if (gURLBar._zenHandleUrlbarClose) {
gURLBar._zenHandleUrlbarClose();
} else {
this.handleUrlbarClose(closeSeq);
}
return true; return true;
} }
@@ -568,7 +592,9 @@ window.gZenUIManager = {
this._prevUrlbarLabel = gURLBar._untrimmedValue || ""; this._prevUrlbarLabel = gURLBar._untrimmedValue || "";
// Set up URL bar for new tab // Set up URL bar for new tab
gURLBar._zenHandleUrlbarClose = this.handleUrlbarClose.bind(this); gURLBar._zenHandleUrlbarClose = (onSwitch, onElementPicked) =>
this.handleUrlbarClose(closeSeq, onSwitch, onElementPicked);
this._urlbarOwner = closeSeq;
gURLBar.setAttribute("zen-newtab", true); gURLBar.setAttribute("zen-newtab", true);
// Update newtab buttons // Update newtab buttons
@@ -582,18 +608,33 @@ window.gZenUIManager = {
document.getElementById("Browser:OpenLocation").doCommand(); document.getElementById("Browser:OpenLocation").doCommand();
} catch (e) { } catch (e) {
console.error("Error opening location in new tab:", e); console.error("Error opening location in new tab:", e);
this.handleUrlbarClose(false); this.handleUrlbarClose(closeSeq, false, false);
return false; return false;
} }
return true; return true;
}, },
/**
* Check whether the closeToken given by handleNewTab
* corresponds to a close event.
*
* @param {object} closeToken - Token previously passed to handleNewTab.
* @param {CustomEvent} event - A ZenURLBarClosed event.
* @returns {boolean}
*/
matchesCloseToken(closeToken, event) {
return (
typeof closeToken?.id === "number" &&
event?.detail?.closeSeq === closeToken.id
);
},
clearUrlbarData() { clearUrlbarData() {
this._prevUrlbarLabel = null; this._prevUrlbarLabel = null;
this._lastSearch = ""; this._lastSearch = "";
}, },
handleUrlbarClose(onSwitch = false, onElementPicked = false) { handleUrlbarClose(closeSeq, onSwitch = false, onElementPicked = false) {
// Validate browser state first // Validate browser state first
if (!this._validateBrowserState()) { if (!this._validateBrowserState()) {
console.warn("Browser state invalid for URL bar close operation"); console.warn("Browser state invalid for URL bar close operation");
@@ -607,6 +648,9 @@ window.gZenUIManager = {
const isFocusedBefore = gURLBar.focused; const isFocusedBefore = gURLBar.focused;
setTimeout(() => { setTimeout(() => {
/* If someone else opened the url bar in the meantime don't be
* stingy and leave it open for them.*/
if (this._isOwner(closeSeq)) {
// We use this attribute on Tabbrowser::addTab // We use this attribute on Tabbrowser::addTab
gURLBar.removeAttribute("zen-newtab"); gURLBar.removeAttribute("zen-newtab");
@@ -652,14 +696,21 @@ window.gZenUIManager = {
} }
gURLBar.handleRevert(); gURLBar.handleRevert();
}
if (isFocusedBefore) { if (isFocusedBefore) {
setTimeout(() => { setTimeout(() => {
window.dispatchEvent( window.dispatchEvent(
new CustomEvent("ZenURLBarClosed", { new CustomEvent("ZenURLBarClosed", {
detail: { onSwitch, onElementPicked }, detail: { onSwitch, onElementPicked, closeSeq },
}) })
); );
if (!this._isOwner(closeSeq)) {
return;
}
this._urlbarOwner = null;
gURLBar.view.close({ elementPicked: onElementPicked }); gURLBar.view.close({ elementPicked: onElementPicked });
gURLBar.updateTextOverflow(); gURLBar.updateTextOverflow();
@@ -683,6 +734,8 @@ window.gZenUIManager = {
} }
} }
}, 0); }, 0);
} else if (this._isOwner(closeSeq)) {
this._urlbarOwner = null;
} }
}, 0); }, 0);
}, },
@@ -815,7 +868,6 @@ window.gZenUIManager = {
}, },
panelUIPosition(panel, anchor) { panelUIPosition(panel, anchor) {
void panel;
// The alignment position of the panel is determined during the "popuppositioned" event // The alignment position of the panel is determined during the "popuppositioned" event
// when the panel opens. The alignment positions help us determine in which orientation // when the panel opens. The alignment positions help us determine in which orientation
// the panel is anchored to the screen space. // the panel is anchored to the screen space.
@@ -1299,11 +1351,13 @@ window.gZenVerticalTabsManager = {
document.documentElement.removeAttribute("zen-right-side"); document.documentElement.removeAttribute("zen-right-side");
} }
delete this._hadSidebarCollapse; const wasSidebarExpanded = document.documentElement.hasAttribute(
if (isSidebarExpanded) {
this._hadSidebarCollapse = !document.documentElement.hasAttribute(
"zen-sidebar-expanded" "zen-sidebar-expanded"
); );
if (isSidebarExpanded !== wasSidebarExpanded) {
delete this._hadSidebarCollapse;
if (isSidebarExpanded) {
this._hadSidebarCollapse = true;
this.navigatorToolbox.setAttribute("zen-sidebar-expanded", "true"); this.navigatorToolbox.setAttribute("zen-sidebar-expanded", "true");
document.documentElement.setAttribute("zen-sidebar-expanded", "true"); document.documentElement.setAttribute("zen-sidebar-expanded", "true");
gBrowser.tabContainer.setAttribute("expanded", "true"); gBrowser.tabContainer.setAttribute("expanded", "true");
@@ -1312,6 +1366,7 @@ window.gZenVerticalTabsManager = {
document.documentElement.removeAttribute("zen-sidebar-expanded"); document.documentElement.removeAttribute("zen-sidebar-expanded");
gBrowser.tabContainer.removeAttribute("expanded"); gBrowser.tabContainer.removeAttribute("expanded");
} }
}
const appContentNavbarContaienr = document.getElementById( const appContentNavbarContaienr = document.getElementById(
"zen-appcontent-navbar-container" "zen-appcontent-navbar-container"

View File

@@ -61,6 +61,14 @@ export async function createWindowUpdateAnimation() {
return; return;
} }
Services.prefs.setStringPref(ZEN_BUILD_ID_PREF, appID); Services.prefs.setStringPref(ZEN_BUILD_ID_PREF, appID);
await playWindowSweepAnimation();
}
/**
* Plays the full-window sweep shown after updates. Also used the first
* time incoming sync data is applied on this profile.
*/
export async function playWindowSweepAnimation() {
await gZenWorkspaces.promiseInitialized; await gZenWorkspaces.promiseInitialized;
const appWrapper = document.getElementById("zen-main-app-wrapper"); const appWrapper = document.getElementById("zen-main-app-wrapper");
const element = document.createElement("div"); const element = document.createElement("div");

View File

@@ -27,7 +27,7 @@ dialog::part(dialog-button) {
position: relative; position: relative;
border: none; border: none;
border-radius: 10px; border-radius: calc(10px * var(--zen-squircle-value));
} }
@media (-moz-platform: macos) { @media (-moz-platform: macos) {

View File

@@ -18,11 +18,11 @@
.urlbar { .urlbar {
--urlbarview-separator-color: light-dark(hsl(0, 0%, 80%), hsl(0, 0%, 20%)); --urlbarview-separator-color: light-dark(hsl(0, 0%, 80%), hsl(0, 0%, 20%));
--urlbarview-background-color-hover: var(--toolbarbutton-hover-background); --urlbarview-background-color-hover: var(--toolbarbutton-background-color-hover);
border-radius: calc(var(--toolbarbutton-border-radius) - 2px); border-radius: calc(var(--toolbarbutton-border-radius) - 2px);
height: var(--urlbar-height);
--urlbarView-results-padding: 10px !important; --urlbarView-results-padding: 10px !important;
--urlbar-container-height: 48px !important; --urlbar-container-height: 48px !important;
--urlbar-input-container-border: none;
--urlbar-margin-inline: 5px; --urlbar-margin-inline: 5px;
--urlbar-container-padding: 4px; --urlbar-container-padding: 4px;
@@ -60,6 +60,9 @@
.urlbar-background { .urlbar-background {
background: var(--zen-toolbar-element-bg) !important; background: var(--zen-toolbar-element-bg) !important;
border-radius: var(--border-radius-medium); border-radius: var(--border-radius-medium);
:root:not([zen-single-toolbar="true"]) & {
border-radius: calc(var(--border-radius-medium) * var(--zen-squircle-value));
}
outline: none !important; outline: none !important;
#urlbar:not([breakout-extend]) & { #urlbar:not([breakout-extend]) & {
@@ -136,8 +139,13 @@
& #identity-box { & #identity-box {
margin-inline-end: 0 !important; margin-inline-end: 0 !important;
:root[zen-has-empty-tab="true"] &[pageproxystate="invalid"]:not(.chromeUI) {
margin-inline-end: -4px !important;
}
&.chromeUI:not([pageproxystate="invalid"]) #identity-icon-box { &.chromeUI:not([pageproxystate="invalid"]) #identity-icon-box {
border-radius: 10px !important; border-radius: calc(10px * var(--zen-squircle-value)) !important;
} }
} }
@@ -166,13 +174,9 @@
} }
:root:not([zen-single-toolbar="true"]):not([zen-has-empty-tab="true"]) #urlbar:not([breakout-extend]) .urlbar-input-container { :root:not([zen-single-toolbar="true"]):not([zen-has-empty-tab="true"]) #urlbar:not([breakout-extend]) .urlbar-input-container {
padding: 2px 3px; padding: 2px 5px;
gap: 2px; gap: 2px;
& .urlbar-page-action {
height: 100%;
}
& #zen-copy-url-button { & #zen-copy-url-button {
order: -1; order: -1;
} }
@@ -291,7 +295,7 @@
&, &,
.urlbar-background { .urlbar-background {
border-radius: 12px !important; border-radius: calc(12px * var(--zen-squircle-value)) !important;
} }
&[breakout-extend][animate-searchmode="true"]::before { &[breakout-extend][animate-searchmode="true"]::before {
@@ -326,6 +330,7 @@
order: 2; order: 2;
} }
/* stylelint-disable-next-line stylelint-plugin-mozilla/no-has-selector */
#notification-popup-box:not([open]):not(:has(> [showing="true"])) { #notification-popup-box:not([open]):not(:has(> [showing="true"])) {
margin-inline-start: calc(-10px - 2 * var(--urlbar-icon-padding)); margin-inline-start: calc(-10px - 2 * var(--urlbar-icon-padding));
opacity: 0; opacity: 0;
@@ -346,7 +351,7 @@
padding: 4px !important; padding: 4px !important;
&:hover { &:hover {
background: var(--toolbarbutton-hover-background); background: var(--toolbarbutton-background-color-hover);
border-radius: var(--toolbarbutton-border-radius); border-radius: var(--toolbarbutton-border-radius);
overflow: visible; overflow: visible;
} }
@@ -405,7 +410,7 @@
} }
#notification-popup-box { #notification-popup-box {
border-radius: 10px !important; border-radius: calc(10px * var(--zen-squircle-value)) !important;
} }
/* Border radius on hover */ /* Border radius on hover */
@@ -487,9 +492,10 @@
translate: -50% 0%; translate: -50% 0%;
left: 50% !important; left: 50% !important;
/* stylelint-disable-next-line stylelint-plugin-mozilla/no-has-selector */
#urlbar-container:has(&) { #urlbar-container:has(&) {
border-radius: var(--border-radius-medium); border-radius: var(--border-radius-medium);
background: var(--toolbarbutton-hover-background); background: var(--toolbarbutton-background-color-hover);
height: var(--urlbar-height) !important; height: var(--urlbar-height) !important;
margin-inline: 0.15rem !important; margin-inline: 0.15rem !important;
:root:not([zen-single-toolbar="true"]) & { :root:not([zen-single-toolbar="true"]) & {
@@ -633,6 +639,7 @@
#urlbar-label-box, #urlbar-label-box,
#urlbar-search-mode-indicator { #urlbar-search-mode-indicator {
--urlbar-basic-component-size: 18px;
background-color: color-mix(in srgb, var(--zen-primary-color) 50%, light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.2)) 50%) !important; background-color: color-mix(in srgb, var(--zen-primary-color) 50%, light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.2)) 50%) !important;
color: white; color: white;
padding: 4px 8px; padding: 4px 8px;
@@ -698,7 +705,7 @@
:root:not([zen-single-toolbar="true"]) #urlbar[breakout-extend]:not([zen-floating-urlbar="true"]) { :root:not([zen-single-toolbar="true"]) #urlbar[breakout-extend]:not([zen-floating-urlbar="true"]) {
& .urlbar-background { & .urlbar-background {
border-radius: 10px !important; border-radius: calc(10px * var(--zen-squircle-value)) !important;
} }
#urlbar-results { #urlbar-results {
@@ -717,6 +724,10 @@
display: none; display: none;
} }
.urlbarView {
overflow: visible;
}
#urlbar-search-mode-indicator-title { #urlbar-search-mode-indicator-title {
font-weight: 600; font-weight: 600;
padding: 0; padding: 0;

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
.dialogBox { .dialogBox {
border-radius: 12px !important; border-radius: calc(12px * var(--zen-squircle-value)) !important;
border: 0.5px solid light-dark(rgba(0, 0, 0, 0.4), var(--zen-dialog-background)) !important; border: 0.5px solid light-dark(rgba(0, 0, 0, 0.4), var(--zen-dialog-background)) !important;
outline: 1px solid light-dark(transparent, rgba(168, 168, 169, 0.50)) !important; outline: 1px solid light-dark(transparent, rgba(168, 168, 169, 0.50)) !important;
box-shadow: 0 10px 8px rgba(0, 0 , 0, 0.15) !important; box-shadow: 0 10px 8px rgba(0, 0 , 0, 0.15) !important;

View File

@@ -335,7 +335,7 @@ menuseparator {
gap: 8px; gap: 8px;
z-index: 1000; z-index: 1000;
padding: var(--zen-toast-padding); padding: var(--zen-toast-padding);
border-radius: 10px; border-radius: 14px;
background: linear-gradient(to bottom, var(--zen-primary-color) -40%, color-mix(in srgb, var(--zen-primary-color), #0f0f0f 20%)); background: linear-gradient(to bottom, var(--zen-primary-color) -40%, color-mix(in srgb, var(--zen-primary-color), #0f0f0f 20%));
box-shadow: light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.4)) 0 0 22px 2px; box-shadow: light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.4)) 0 0 22px 2px;
border: none; border: none;
@@ -374,7 +374,7 @@ menuseparator {
min-width: unset !important; min-width: unset !important;
min-height: 28px; min-height: 28px;
margin: 0 !important; margin: 0 !important;
border-radius: 6px !important; border-radius: 10px !important;
border-top: 2px solid light-dark(transparent, rgba(255, 255, 255, 0.1)); border-top: 2px solid light-dark(transparent, rgba(255, 255, 255, 0.1));
color: light-dark(rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0.8)) !important; color: light-dark(rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0.8)) !important;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.05); box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.05);

View File

@@ -78,13 +78,13 @@
} }
.zen-sidebar-notification-progress { .zen-sidebar-notification-progress {
height: 2px; height: 1px;
overflow: hidden; overflow: hidden;
transform: translateY(-1px); transform: translateY(-1px);
& .zen-sidebar-notification-progress-bar { & .zen-sidebar-notification-progress-bar {
height: 100%; height: 100%;
background: light-dark(color-mix(in srgb, var(--zen-primary-color) 50%, black), color-mix(in srgb, var(--zen-colors-primary) 15%, #ebebeb)); background: light-dark(color-mix(in srgb, var(--zen-primary-color) 50%, black), color-mix(in srgb, var(--zen-colors-primary) 15%, transparent 10%, #6b6b6b));
transform-origin: left center; transform-origin: left center;
} }
} }

View File

@@ -185,7 +185,7 @@
.toolbarbutton-1:not(#tabs-newtab-button), .toolbarbutton-1:not(#tabs-newtab-button),
.urlbar-page-action, .urlbar-page-action,
.identity-box-button { .identity-box-button {
--tab-border-radius: 6px; --tab-border-radius: 8px;
--toolbarbutton-border-radius: var(--tab-border-radius); --toolbarbutton-border-radius: var(--tab-border-radius);
--toolbarbutton-padding-inner: 6px; --toolbarbutton-padding-inner: 6px;
--toolbarbutton-padding-outer: 1px; --toolbarbutton-padding-outer: 1px;
@@ -291,7 +291,7 @@
--panel-width: 234px; --panel-width: 234px;
--menu-panel-width-wide: calc(var(--panel-width) - var(--panel-padding) * 2); --menu-panel-width-wide: calc(var(--panel-width) - var(--panel-padding) * 2);
--uei-icon-size: 16px; --uei-icon-size: 16px;
--arrowpanel-menuitem-border-radius: 10px; --arrowpanel-menuitem-border-radius: calc(10px * var(--zen-squircle-value));
} }
#unified-extensions-empty-state, #unified-extensions-empty-state,
@@ -500,13 +500,16 @@
transition: transition:
transform 0.12s ease-in-out, transform 0.12s ease-in-out,
opacity 0.12s ease-in-out; opacity 0.12s ease-in-out;
will-change: transform;
} }
/* stylelint-disable-next-line stylelint-plugin-mozilla/no-has-selector */
.permission-popup-permission-item:hover &::before, .permission-popup-permission-item:hover &::before,
.permission-popup-boost-item:hover:not(:has(.zen-permission-popup-boost-editor-button:hover)) &::before { .permission-popup-boost-item:hover:not(:has(.zen-permission-popup-boost-editor-button:hover)) &::before {
transform: scale(1.05); transform: scale(1.05);
} }
/* stylelint-disable-next-line stylelint-plugin-mozilla/no-has-selector */
.permission-popup-permission-item:active:hover &::before, .permission-popup-permission-item:active:hover &::before,
.permission-popup-boost-item:active:hover:not(:has(.zen-permission-popup-boost-editor-button:hover)) &::before { .permission-popup-boost-item:active:hover:not(:has(.zen-permission-popup-boost-editor-button:hover)) &::before {
transform: scale(0.95); transform: scale(0.95);
@@ -601,6 +604,8 @@
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
will-change: transform;
@media (-moz-platform: macos) { @media (-moz-platform: macos) {
background: linear-gradient(to bottom, light-dark(rgb(255, 255, 255), rgb(34, 34, 34)), light-dark(rgb(246, 246, 246), rgb(21, 21, 21))); background: linear-gradient(to bottom, light-dark(rgb(255, 255, 255), rgb(34, 34, 34)), light-dark(rgb(246, 246, 246), rgb(21, 21, 21)));

View File

@@ -92,7 +92,11 @@
--in-content-accent-color-active: currentColor !important; --in-content-accent-color-active: currentColor !important;
/* This is like the secondary button */ /* This is like the secondary button */
--in-content-button-background: transparent !important; --in-content-button-background: color-mix(
in srgb,
currentColor,
transparent 90%
) !important;
--in-content-button-text-color: var(--zen-secondary-btn-color) !important; --in-content-button-text-color: var(--zen-secondary-btn-color) !important;
--in-content-button-background-hover: color-mix( --in-content-button-background-hover: color-mix(
in srgb, in srgb,
@@ -164,7 +168,7 @@
--zen-toolbar-height-with-bookmarks: calc(var(--zen-toolbar-height) + 30px); --zen-toolbar-height-with-bookmarks: calc(var(--zen-toolbar-height) + 30px);
} }
--toolbarbutton-hover-background: var(--zen-toolbar-element-bg-hover) !important; --toolbarbutton-background-color-hover: var(--zen-toolbar-element-bg-hover) !important;
--zen-toolbar-button-size: 16px; --zen-toolbar-button-size: 16px;
@media (-moz-platform: macos) { @media (-moz-platform: macos) {
--zen-toolbar-button-size: 17px; --zen-toolbar-button-size: 17px;
@@ -177,7 +181,7 @@
* background on the native theme. */ * background on the native theme. */
--toolbar-background-color: light-dark(rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.15)); --toolbar-background-color: light-dark(rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.15));
--toolbarbutton-active-background: color-mix( --toolbarbutton-background-color-active: color-mix(
in srgb, in srgb,
var(--zen-branding-bg-reverse) 7%, var(--zen-branding-bg-reverse) 7%,
transparent 93% transparent 93%
@@ -187,9 +191,9 @@
--toolbox-textcolor-inactive: var(--toolbox-textcolor) !important; --toolbox-textcolor-inactive: var(--toolbox-textcolor) !important;
/* Other colors */ /* Other colors */
--urlbar-box-active-bgcolor: var(--toolbarbutton-hover-background) !important; --urlbar-box-active-bgcolor: var(--toolbarbutton-background-color-hover) !important;
--zen-input-border-color: light-dark(rgb(204, 204, 204), rgb(66, 65, 77)); --zen-input-border-color: light-dark(rgb(204, 204, 204), rgb(66, 65, 77));
--urlbar-box-hover-bgcolor: var(--toolbarbutton-hover-background) !important; --urlbar-box-hover-bgcolor: var(--toolbarbutton-background-color-hover) !important;
--input-text-background-color: light-dark(rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.2)) !important; --input-text-background-color: light-dark(rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.2)) !important;
--toolbar-field-focus-background-color: light-dark( --toolbar-field-focus-background-color: light-dark(
rgba(255, 255, 255, 0.25), rgba(255, 255, 255, 0.25),
@@ -213,6 +217,16 @@
--toolbarbutton-border-radius: 6px; --toolbarbutton-border-radius: 6px;
--urlbar-margin-inline: 1px !important; --urlbar-margin-inline: 1px !important;
--zen-squircle-value: 1.3;
@media (-moz-platform: windows) {
--zen-squircle-value: 2.1;
}
@media (-moz-platform: linux) {
--zen-squircle-value: 1.2;
}
--tab-icon-overlay-stroke: light-dark(white, black) !important; --tab-icon-overlay-stroke: light-dark(white, black) !important;
--tab-close-button-padding: 4px !important; --tab-close-button-padding: 4px !important;
@@ -253,7 +267,7 @@
--zen-active-tab-scale: 0.985; --zen-active-tab-scale: 0.985;
/* Define tab hover background color */ /* Define tab hover background color */
--tab-background-color-hover: var(--toolbarbutton-hover-background); --tab-background-color-hover: var(--toolbarbutton-background-color-hover);
/* Sidebar Notifications */ /* Sidebar Notifications */
--zen-sidebar-notification-bg: color-mix( --zen-sidebar-notification-bg: color-mix(
@@ -272,7 +286,7 @@
* 1. If the native radius - the separation is less than 4px, use 4px. * 1. If the native radius - the separation is less than 4px, use 4px.
* 2. Otherwise, use the the calculated value (inner radius = outer radius - separation). * 2. Otherwise, use the the calculated value (inner radius = outer radius - separation).
*/ */
max(5px, calc(var(--zen-border-radius) - var(--zen-element-separation) / 2)) max(5px, calc((var(--zen-border-radius) - var(--zen-element-separation) / 2) * var(--zen-squircle-value)))
); );
/** Other theme-related styles */ /** Other theme-related styles */
@@ -344,3 +358,11 @@
} }
%include zen-buttons.css %include zen-buttons.css
@media (-moz-pref('layout.css.corner-shape.enabled')) {
*:not(.no-squircles),
.zen-squircle-before::before,
.zen-squircle-after::after {
corner-shape: superellipse(var(--zen-squircle-value));
}
}

View File

@@ -109,7 +109,7 @@
if (AppConstants.platform == "macosx") { if (AppConstants.platform == "macosx") {
const targetRadius = window.matchMedia("(-moz-mac-tahoe-theme)") const targetRadius = window.matchMedia("(-moz-mac-tahoe-theme)")
.matches .matches
? 14 ? 12
: 10; : 10;
document.documentElement.style.setProperty( document.documentElement.style.setProperty(
"--zen-border-radius", "--zen-border-radius",

View File

@@ -832,8 +832,9 @@ window.gZenCompactModeManager = {
const onLeave = event => { const onLeave = event => {
if (AppConstants.platform == "macosx") { if (AppConstants.platform == "macosx") {
const buttonRect = const buttonRect = window.windowUtils.getBoundsWithoutFlushing(
gZenVerticalTabsManager.actualWindowButtons.getBoundingClientRect(); gZenVerticalTabsManager.actualWindowButtons
);
const MAC_WINDOW_BUTTONS_X_BORDER = buttonRect.width + buttonRect.x; const MAC_WINDOW_BUTTONS_X_BORDER = buttonRect.width + buttonRect.x;
const MAC_WINDOW_BUTTONS_Y_BORDER = buttonRect.height + buttonRect.y; const MAC_WINDOW_BUTTONS_Y_BORDER = buttonRect.height + buttonRect.y;
if ( if (

View File

@@ -58,7 +58,7 @@
:root[zen-no-padding='true'] & { :root[zen-no-padding='true'] & {
--zen-compact-float: 10px; --zen-compact-float: 10px;
--zen-compact-top-toolbar-hidden-fix: var(--zen-compact-float); --zen-compact-top-toolbar-hidden-fix: var(--zen-compact-float);
--zen-compact-mode-no-padding-radius-fix: 2px; --zen-compact-mode-no-padding-radius-fix: 6px;
} }
/* Initial padding for when we are animating */ /* Initial padding for when we are animating */

View File

@@ -29,7 +29,7 @@
&, &,
&::before, &::before,
&::after { &::after {
border-radius: calc(var(--zen-native-inner-radius) - var(--zen-compact-mode-no-padding-radius-fix, 0px)); border-radius: calc((var(--zen-native-inner-radius) - var(--zen-compact-mode-no-padding-radius-fix, 0px)) * var(--zen-squircle-value));
} }
} }

View File

@@ -183,10 +183,10 @@
if (tabClone.hasAttribute("visuallyselected")) { if (tabClone.hasAttribute("visuallyselected")) {
tabClone.style.transform = "translate(-50%, -50%)"; tabClone.style.transform = "translate(-50%, -50%)";
} }
} else if (AppConstants.platform !== "macosx" && !tab.isZenFolder) { } else if (AppConstants.platform == "win" && !tab.isZenFolder) {
// On windows and linux, we still don't add some extra opaqueness // On windows, the shell applies its own translucency to the drag
// for the tab to be more visible. This is a hacky workaround. // image which we can't control, so force some extra contrast for
// TODO: Make windows and linux DnD use nsZenDragAndDrop::mDragImageOpacity // the tab to be more visible. This is a hacky workaround.
tabClone.style.colorScheme = "light"; tabClone.style.colorScheme = "light";
tabClone.style.setProperty("--tab-selected-textcolor", "black"); tabClone.style.setProperty("--tab-selected-textcolor", "black");
} }

View File

@@ -12,7 +12,7 @@ export class nsZenFolder extends MozTabbrowserTabGroup {
#initialized = false; #initialized = false;
static markup = ` static markup = `
<hbox class="tab-group-label-container zen-drop-target" pack="center"> <hbox class="tab-group-label-container zen-squircle-before zen-drop-target" pack="center">
<html:div class="tab-group-folder-icon"/> <html:div class="tab-group-folder-icon"/>
<label class="tab-group-label" role="button"/> <label class="tab-group-label" role="button"/>
<image class="tab-reset-button reset-icon" role="button" keyNav="false" data-l10n-id="zen-folders-unload-all-tooltip"/> <image class="tab-reset-button reset-icon" role="button" keyNav="false" data-l10n-id="zen-folders-unload-all-tooltip"/>

View File

@@ -41,11 +41,11 @@
&:hover { &:hover {
background: light-dark(rgb(41, 41, 41), rgb(204, 204, 204)); background: light-dark(rgb(41, 41, 41), rgb(204, 204, 204));
scale: 1.05; scale: 1.02;
} }
&:hover:active { &:hover:active {
scale: 0.95; scale: 0.98;
} }
& label { & label {

View File

@@ -4,8 +4,8 @@
<html:template id="zen-glance-sidebar-template"> <html:template id="zen-glance-sidebar-template">
<vbox class="zen-glance-sidebar-container"> <vbox class="zen-glance-sidebar-container">
<toolbarbutton class="zen-glance-sidebar-close toolbarbutton-1" command="cmd_zenGlanceClose" data-l10n-id="zen-general-confirm" /> <toolbarbutton class="no-squircles zen-glance-sidebar-close toolbarbutton-1" command="cmd_zenGlanceClose" data-l10n-id="zen-general-confirm" />
<toolbarbutton class="zen-glance-sidebar-open toolbarbutton-1" command="cmd_zenGlanceExpand" /> <toolbarbutton class="no-squircles zen-glance-sidebar-open toolbarbutton-1" command="cmd_zenGlanceExpand" />
<toolbarbutton class="zen-glance-sidebar-split toolbarbutton-1" command="cmd_zenGlanceSplit" /> <toolbarbutton class="no-squircles zen-glance-sidebar-split toolbarbutton-1" command="cmd_zenGlanceSplit" />
</vbox> </vbox>
</html:template> </html:template>

View File

@@ -3,8 +3,7 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this - License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. - file, You can obtain one at http://mozilla.org/MPL/2.0/.
--> -->
<?xml version="1.0" encoding="UTF-8"?> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="192" height="192" viewBox="0 0 192 192">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="192" height="192">
<path d="M0 0 C46.53 0 93.06 0 141 0 C140.31337286 6.17964422 139.55249061 11.27288504 137.70605469 17.05029297 C137.47297387 17.80257864 137.23989305 18.55486431 136.99974918 19.32994652 C136.23144234 21.80315256 135.45168558 24.27258703 134.671875 26.7421875 C134.12437759 28.49738282 133.57765617 30.25282037 133.03166199 32.00848389 C131.87637142 35.71831589 130.71622139 39.42657597 129.55197144 43.13360596 C127.74764855 48.8788063 125.95370897 54.62720979 124.16235352 60.37646484 C123.86778165 61.32180147 123.57320978 62.2671381 123.26971149 63.24112129 C122.67820023 65.13942545 122.08671887 67.03773892 121.49526787 68.93606186 C120.61596105 71.75702774 119.73559404 74.57766091 118.85499573 77.39822388 C113.93371601 93.16794093 109.12231506 108.96839561 104.39160156 124.79638672 C104.15798416 125.57612854 103.92436676 126.35587036 103.68367004 127.15924072 C103.08515835 129.15844483 102.48956633 131.15852242 101.89428711 133.15869141 C101 136 101 136 100 138 C53.47 138 6.94 138 -41 138 C-40.30154873 133.1108411 -39.57595592 129.15411541 -38.15258789 124.53222656 C-37.57916405 122.65642914 -37.57916405 122.65642914 -36.99415588 120.74273682 C-36.57039663 119.37534329 -36.14656076 118.0079735 -35.72265625 116.640625 C-35.27348999 115.1778587 -34.82480765 113.71494372 -34.37657166 112.25189209 C-33.18301778 108.36047716 -31.98331296 104.47098593 -30.78216553 100.58190918 C-29.63602455 96.86810525 -28.49491032 93.15276556 -27.35351562 89.4375 C-24.23585848 79.29161092 -21.11791678 69.14580929 -18 59 C-12.06 39.53 -6.12 20.06 0 0 Z " fill="#C00002" transform="translate(51,54)"/> <path d="M0 0 C46.53 0 93.06 0 141 0 C140.31337286 6.17964422 139.55249061 11.27288504 137.70605469 17.05029297 C137.47297387 17.80257864 137.23989305 18.55486431 136.99974918 19.32994652 C136.23144234 21.80315256 135.45168558 24.27258703 134.671875 26.7421875 C134.12437759 28.49738282 133.57765617 30.25282037 133.03166199 32.00848389 C131.87637142 35.71831589 130.71622139 39.42657597 129.55197144 43.13360596 C127.74764855 48.8788063 125.95370897 54.62720979 124.16235352 60.37646484 C123.86778165 61.32180147 123.57320978 62.2671381 123.26971149 63.24112129 C122.67820023 65.13942545 122.08671887 67.03773892 121.49526787 68.93606186 C120.61596105 71.75702774 119.73559404 74.57766091 118.85499573 77.39822388 C113.93371601 93.16794093 109.12231506 108.96839561 104.39160156 124.79638672 C104.15798416 125.57612854 103.92436676 126.35587036 103.68367004 127.15924072 C103.08515835 129.15844483 102.48956633 131.15852242 101.89428711 133.15869141 C101 136 101 136 100 138 C53.47 138 6.94 138 -41 138 C-40.30154873 133.1108411 -39.57595592 129.15411541 -38.15258789 124.53222656 C-37.57916405 122.65642914 -37.57916405 122.65642914 -36.99415588 120.74273682 C-36.57039663 119.37534329 -36.14656076 118.0079735 -35.72265625 116.640625 C-35.27348999 115.1778587 -34.82480765 113.71494372 -34.37657166 112.25189209 C-33.18301778 108.36047716 -31.98331296 104.47098593 -30.78216553 100.58190918 C-29.63602455 96.86810525 -28.49491032 93.15276556 -27.35351562 89.4375 C-24.23585848 79.29161092 -21.11791678 69.14580929 -18 59 C-12.06 39.53 -6.12 20.06 0 0 Z " fill="#C00002" transform="translate(51,54)"/>
<path d="M0 0 C18.3328319 -0.77792059 36.66127963 -1.35606988 55.00715542 -1.70980167 C63.53040721 -1.87858134 72.04320263 -2.10845198 80.55981445 -2.48950195 C142.46067644 -5.20608208 142.46067644 -5.20608208 159.53827381 9.52021503 C166.76889916 16.3955246 173.28323862 24.18336817 178 33 C178 34.32 178 35.64 178 37 C159.57187597 37.07007601 141.14378652 37.12298126 122.71555805 37.15543652 C114.15904092 37.17090649 105.60260658 37.19199848 97.04614258 37.22631836 C89.58846853 37.25621675 82.13085443 37.27557406 74.67312211 37.28226548 C70.72416302 37.28617701 66.77537545 37.29537225 62.82647133 37.31719017 C59.10909816 37.33756234 55.39196707 37.34383237 51.67454338 37.33932304 C49.66086617 37.34054104 47.64721527 37.35667936 45.63360596 37.3732605 C44.43192276 37.36913651 43.23023956 37.36501251 41.99214172 37.36076355 C40.42831993 37.36491162 40.42831993 37.36491162 38.83290577 37.36914349 C32.93264951 36.60030705 29.62184448 32.77709579 25.875 28.5 C19.58131594 21.47164064 12.89888852 14.86095567 6.14794922 8.2734375 C5.35146973 7.48839844 4.55499023 6.70335937 3.734375 5.89453125 C3.01475586 5.19175049 2.29513672 4.48896973 1.55371094 3.76489258 C0 2 0 2 0 0 Z " fill="#C00002" transform="translate(14,0)"/> <path d="M0 0 C18.3328319 -0.77792059 36.66127963 -1.35606988 55.00715542 -1.70980167 C63.53040721 -1.87858134 72.04320263 -2.10845198 80.55981445 -2.48950195 C142.46067644 -5.20608208 142.46067644 -5.20608208 159.53827381 9.52021503 C166.76889916 16.3955246 173.28323862 24.18336817 178 33 C178 34.32 178 35.64 178 37 C159.57187597 37.07007601 141.14378652 37.12298126 122.71555805 37.15543652 C114.15904092 37.17090649 105.60260658 37.19199848 97.04614258 37.22631836 C89.58846853 37.25621675 82.13085443 37.27557406 74.67312211 37.28226548 C70.72416302 37.28617701 66.77537545 37.29537225 62.82647133 37.31719017 C59.10909816 37.33756234 55.39196707 37.34383237 51.67454338 37.33932304 C49.66086617 37.34054104 47.64721527 37.35667936 45.63360596 37.3732605 C44.43192276 37.36913651 43.23023956 37.36501251 41.99214172 37.36076355 C40.42831993 37.36491162 40.42831993 37.36491162 38.83290577 37.36914349 C32.93264951 36.60030705 29.62184448 32.77709579 25.875 28.5 C19.58131594 21.47164064 12.89888852 14.86095567 6.14794922 8.2734375 C5.35146973 7.48839844 4.55499023 6.70335937 3.734375 5.89453125 C3.01475586 5.19175049 2.29513672 4.48896973 1.55371094 3.76489258 C0 2 0 2 0 0 Z " fill="#C00002" transform="translate(14,0)"/>
<path d="M0 0 C3.791582 0.9478955 4.61038031 1.2276371 7.22387695 3.72460938 C7.82742508 4.29610718 8.43097321 4.86760498 9.05281067 5.4564209 C9.69151596 6.0792395 10.33022125 6.70205811 10.98828125 7.34375 C11.65087448 7.98687134 12.31346771 8.62999268 12.99613953 9.29260254 C14.39307302 10.6568359 15.78562095 12.02557232 17.17407227 13.3984375 C19.30020941 15.4879213 21.45839054 17.54016287 23.61914062 19.59375 C24.97349069 20.92491308 26.32577572 22.25818109 27.67578125 23.59375 C28.64902092 24.50368713 28.64902092 24.50368713 29.641922 25.43200684 C32.90021798 28.73979232 33.96335392 30.20963715 34.18457031 34.98071289 C32.79621492 42.01530122 30.50352034 48.87563397 28.37109375 55.71484375 C27.89774106 57.25373642 27.42510459 58.79284955 26.95314026 60.33216858 C25.70895014 64.38330864 24.4551733 68.43141814 23.19927979 72.47894287 C21.95200374 76.50438366 20.71357304 80.53254149 19.47460938 84.56054688 C18.02569311 89.27038853 16.5746843 93.97953307 15.11288452 98.68539429 C12.90227206 105.80473144 10.71371664 112.92808223 8.60595703 120.07861328 C8.0605703 121.91064049 8.0605703 121.91064049 7.50416565 123.77967834 C6.83459768 126.03485094 6.17462453 128.29290282 5.52598572 130.55418396 C5.23389725 131.5321846 4.94180878 132.51018524 4.64086914 133.51782227 C4.39422012 134.36594986 4.14757111 135.21407745 3.89344788 136.08790588 C3.59861008 136.71889694 3.30377228 137.349888 3 138 C2.01 138.33 1.02 138.66 0 139 C0 93.13 0 47.26 0 0 Z " fill="#C00002" transform="translate(0,15)"/> <path d="M0 0 C3.791582 0.9478955 4.61038031 1.2276371 7.22387695 3.72460938 C7.82742508 4.29610718 8.43097321 4.86760498 9.05281067 5.4564209 C9.69151596 6.0792395 10.33022125 6.70205811 10.98828125 7.34375 C11.65087448 7.98687134 12.31346771 8.62999268 12.99613953 9.29260254 C14.39307302 10.6568359 15.78562095 12.02557232 17.17407227 13.3984375 C19.30020941 15.4879213 21.45839054 17.54016287 23.61914062 19.59375 C24.97349069 20.92491308 26.32577572 22.25818109 27.67578125 23.59375 C28.64902092 24.50368713 28.64902092 24.50368713 29.641922 25.43200684 C32.90021798 28.73979232 33.96335392 30.20963715 34.18457031 34.98071289 C32.79621492 42.01530122 30.50352034 48.87563397 28.37109375 55.71484375 C27.89774106 57.25373642 27.42510459 58.79284955 26.95314026 60.33216858 C25.70895014 64.38330864 24.4551733 68.43141814 23.19927979 72.47894287 C21.95200374 76.50438366 20.71357304 80.53254149 19.47460938 84.56054688 C18.02569311 89.27038853 16.5746843 93.97953307 15.11288452 98.68539429 C12.90227206 105.80473144 10.71371664 112.92808223 8.60595703 120.07861328 C8.0605703 121.91064049 8.0605703 121.91064049 7.50416565 123.77967834 C6.83459768 126.03485094 6.17462453 128.29290282 5.52598572 130.55418396 C5.23389725 131.5321846 4.94180878 132.51018524 4.64086914 133.51782227 C4.39422012 134.36594986 4.14757111 135.21407745 3.89344788 136.08790588 C3.59861008 136.71889694 3.30377228 137.349888 3 138 C2.01 138.33 1.02 138.66 0 139 C0 93.13 0 47.26 0 0 Z " fill="#C00002" transform="translate(0,15)"/>

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -200,6 +200,50 @@ class nsZenLiveFoldersManager {
return this.liveFolders.get(id); return this.liveFolders.get(id);
} }
/**
* Returns the provider config needed to recreate this live folder on
* another device, or null for non-live folders. Fetch bookkeeping fields
* are stripped since they are device-local.
*
* @param {string} id - The folder ID.
*/
getSyncableFolderData(id) {
const liveFolder = this.liveFolders.get(id);
if (!liveFolder) {
return null;
}
const state = { ...liveFolder.serialize().state };
delete state.lastFetched;
delete state.lastErrorId;
return { type: liveFolder.constructor.type, state };
}
/**
* Registers a live folder provider for a folder that arrived from
* Firefox Sync. The folder element must already exist.
*
* @param {string} id - The folder ID.
* @param {{ type: string, state: object }} config - Synced provider config.
*/
async adoptSyncedFolder(id, { type, state } = {}) {
await this.stateRestored.promise;
if (this.liveFolders.has(id)) {
return;
}
const ProviderClass = this.registry.get(type);
if (!ProviderClass || !state) {
return;
}
const liveFolder = new ProviderClass({
id,
state: this.#applyDefaultStateValues({ ...state }),
manager: this,
});
this.liveFolders.set(id, liveFolder);
liveFolder.start();
this.saveState();
}
async createFolder(type) { async createFolder(type) {
const [provider, providerType] = type.split(":"); const [provider, providerType] = type.split(":");
let ProviderClass = this.registry.get(provider); let ProviderClass = this.registry.get(provider);
@@ -324,7 +368,7 @@ class nsZenLiveFoldersManager {
}, },
], ],
content: { content: {
width: "310px", width: "312px",
position: "callout", position: "callout",
title_logo: { title_logo: {
imageURL: icon, imageURL: icon,
@@ -619,6 +663,7 @@ class nsZenLiveFoldersManager {
async #restoreState() { async #restoreState() {
let data = await this.#readStateFromDisk(); let data = await this.#readStateFromDisk();
if (!Array.isArray(data)) { if (!Array.isArray(data)) {
this.stateRestored.resolve();
return; return;
} }

View File

@@ -26,7 +26,8 @@ export class nsGithubLiveFolderProvider extends nsZenLiveFolderProvider {
const hasAnyFilterEnabled = const hasAnyFilterEnabled =
(this.state.options.authorMe ?? false) || (this.state.options.authorMe ?? false) ||
(this.state.options.assignedMe ?? true) || (this.state.options.assignedMe ?? true) ||
(this.state.options.reviewRequested ?? false); (this.state.options.reviewRequested ?? false) ||
(this.state.options.includeDrafts ?? true);
if (!hasAnyFilterEnabled) { if (!hasAnyFilterEnabled) {
return "zen-live-folder-github-no-filter"; return "zen-live-folder-github-no-filter";

View File

@@ -346,7 +346,7 @@ class ZenMediaCard {
onToggle() { onToggle() {
if (this.controller?.isPlaying) { if (this.controller?.isPlaying) {
this.controller.pause(); this.controller.pause("user");
} else { } else {
this.controller?.play(); this.controller?.play();
} }
@@ -365,7 +365,7 @@ class ZenMediaCard {
} }
onSeekDrag(event) { onSeekDrag(event) {
this.controller?.pause(); this.controller?.pause("user");
const newTime = (event.target.value / 100) * this.duration; const newTime = (event.target.value / 100) * this.duration;
this.currentTimeEl.textContent = this.formatSecondsToTime(newTime); this.currentTimeEl.textContent = this.formatSecondsToTime(newTime);
} }
@@ -408,7 +408,7 @@ class ZenMediaCard {
onClose() { onClose() {
if (this.controller) { if (this.controller) {
this.controller.pause(); this.controller.pause("user");
} else { } else {
const webRTC = const webRTC =
this.browser.browsingContext.currentWindowGlobal.getActor("WebRTC"); this.browser.browsingContext.currentWindowGlobal.getActor("WebRTC");

View File

@@ -10,7 +10,6 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, { ChromeUtils.defineESModuleGetters(lazy, {
ZenLiveFoldersManager: ZenLiveFoldersManager:
"resource:///modules/zen/ZenLiveFoldersManager.sys.mjs", "resource:///modules/zen/ZenLiveFoldersManager.sys.mjs",
ZenSyncStore: "resource:///modules/zen/ZenSyncManager.sys.mjs",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs", PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs", SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs",
SessionStartup: "resource:///modules/sessionstore/SessionStartup.sys.mjs", SessionStartup: "resource:///modules/sessionstore/SessionStartup.sys.mjs",
@@ -611,7 +610,9 @@ export class nsZenSessionManager {
} }
); );
this.#collectWindowData(windows); this.#collectWindowData(windows);
lazy.ZenSyncStore.notifyAboutChanges(); // Let interested consumers (e.g. Firefox Sync) know fresh sidebar data
// is available, without this module knowing anything about them.
Services.obs.notifyObservers(null, "zen-sidebar-data-collected");
// This would save the data to disk asynchronously or when quitting the app. // This would save the data to disk asynchronously or when quitting the app.
let sidebar = this.#sidebarWithoutCloning; let sidebar = this.#sidebarWithoutCloning;
this.#file.data = sidebar; this.#file.data = sidebar;

View File

@@ -606,7 +606,9 @@ class nsZenWindowSync {
if (isTab) { if (isTab) {
if (originalIsEssential !== targetIsEssential) { if (originalIsEssential !== targetIsEssential) {
if (originalIsEssential) { if (originalIsEssential) {
gZenPinnedTabManager.addToEssentials(aTargetItem); gZenPinnedTabManager.addToEssentials(aTargetItem, {
replicating: true,
});
} else { } else {
gZenPinnedTabManager.removeEssentials( gZenPinnedTabManager.removeEssentials(
aTargetItem, aTargetItem,
@@ -1232,7 +1234,7 @@ class nsZenWindowSync {
activeIndex = Math.min(activeIndex, entries.length - 1); activeIndex = Math.min(activeIndex, entries.length - 1);
activeIndex = Math.max(activeIndex, 0); activeIndex = Math.max(activeIndex, 0);
let entryToUse = (entries[activeIndex] || entries[0]) ?? null; let entryToUse = (entries[activeIndex] || entries[0]) ?? null;
this.#setPinnedInitialState( this.setPinnedInitialState(
aTab, aTab,
{ url: entryToUse?.url, title: entryToUse?.title }, { url: entryToUse?.url, title: entryToUse?.title },
image image
@@ -1250,14 +1252,22 @@ class nsZenWindowSync {
*/ */
setPinnedUrl(aTab, aUrl, aImage) { setPinnedUrl(aTab, aUrl, aImage) {
this.log(`Setting pinned url for tab ${aTab.id}`); this.log(`Setting pinned url for tab ${aTab.id}`);
this.#setPinnedInitialState( this.setPinnedInitialState(
aTab, aTab,
{ url: aUrl, title: aTab.zenStaticLabel }, { url: aUrl, title: aTab.zenStaticLabel },
aImage aImage
); );
} }
#setPinnedInitialState(aTab, aEntry, aImage) { /**
* Sets the pinned initial state (canonical entry and icon) for a tab's
* instances across all windows.
*
* @param {object} aTab - Any window's instance of the tab.
* @param {object} aEntry - The canonical { url, title } entry.
* @param {string} [aImage] - Optional icon to store.
*/
setPinnedInitialState(aTab, aEntry, aImage) {
const initialState = { entry: aEntry, image: aImage }; const initialState = { entry: aEntry, image: aImage };
this.#runOnAllWindows(null, win => { this.#runOnAllWindows(null, win => {
const targetTab = this.getItemFromWindow(win, aTab.id); const targetTab = this.getItemFromWindow(win, aTab.id);
@@ -1362,7 +1372,9 @@ class nsZenWindowSync {
return; return;
} }
tab._zenContentsVisible = true; tab._zenContentsVisible = true;
if (!tab.id) {
tab.id = this.#newTabSyncId; tab.id = this.#newTabSyncId;
}
if (lazy.gSyncOnlyPinnedTabs && !tab.pinned) { if (lazy.gSyncOnlyPinnedTabs && !tab.pinned) {
return; return;
} }

View File

@@ -27,7 +27,7 @@ class nsZenSpaceRoutingManager {
const element = window.MozXULElement.parseXULToFragment(` const element = window.MozXULElement.parseXULToFragment(`
<menuseparator/> <menuseparator/>
<menuitem id="context_zen-add-domain-to-routing" <menuitem id="context_zen-add-domain-to-routing"
data-lazy-l10n-id="tab-context-zen-add-domain-to-sr" data-l10n-id="tab-context-zen-add-domain-to-sr"
data-l10n-args='{"tabCount": 1}'/> data-l10n-args='{"tabCount": 1}'/>
`); `);
window.document.getElementById("context_undoCloseTab").after(element); window.document.getElementById("context_undoCloseTab").after(element);

View File

@@ -353,7 +353,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
// Add elements in a circular pattern, where the center is the center of the wrapper // Add elements in a circular pattern, where the center is the center of the wrapper
for (let i = 0; i < 16; i++) { for (let i = 0; i < 16; i++) {
const dot = document.createElement("div"); const dot = document.createElement("div");
dot.classList.add("zen-theme-picker-texture-dot"); dot.classList.add("zen-theme-picker-texture-dot", "no-squircles");
const position = (i / 16) * Math.PI * 2 + wrapperWidth; const position = (i / 16) * Math.PI * 2 + wrapperWidth;
dot.style.left = `${Math.cos(position) * 50 + 50}%`; dot.style.left = `${Math.cos(position) * 50 + 50}%`;
dot.style.top = `${Math.sin(position) * 50 + 50}%`; dot.style.top = `${Math.sin(position) * 50 + 50}%`;
@@ -361,6 +361,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
} }
this._textureHandler = document.createElement("div"); this._textureHandler = document.createElement("div");
this._textureHandler.id = "PanelUI-zen-gradient-generator-texture-handler"; this._textureHandler.id = "PanelUI-zen-gradient-generator-texture-handler";
this._textureHandler.classList.add("no-squircles");
this._textureHandler.addEventListener( this._textureHandler.addEventListener(
"mousedown", "mousedown",
this.onTextureHandlerMouseDown.bind(this) this.onTextureHandlerMouseDown.bind(this)
@@ -598,7 +599,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
color.position || this.calculateInitialPosition([r, g, b]); color.position || this.calculateInitialPosition([r, g, b]);
const dotPad = this.panel.querySelector(".zen-theme-picker-gradient"); const dotPad = this.panel.querySelector(".zen-theme-picker-gradient");
dot.classList.add("zen-theme-picker-dot"); dot.classList.add("zen-theme-picker-dot", "no-squircles");
dot.style.left = `${x}px`; dot.style.left = `${x}px`;
dot.style.top = `${y}px`; dot.style.top = `${y}px`;
@@ -720,7 +721,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
}; };
const dot = document.createElement("div"); const dot = document.createElement("div");
dot.classList.add("zen-theme-picker-dot"); dot.classList.add("zen-theme-picker-dot", "no-squircles");
dot.style.left = `${dotData.x}px`; dot.style.left = `${dotData.x}px`;
dot.style.top = `${dotData.y}px`; dot.style.top = `${dotData.y}px`;

View File

@@ -52,7 +52,7 @@ export class nsZenWorkspace extends MozXULElement {
static get markup() { static get markup() {
return ` return `
<vbox class="zen-workspace-tabs-section zen-current-workspace-indicator zen-drop-target" flex="1" context="zenWorkspaceMoreActions"> <vbox class="zen-workspace-tabs-section zen-current-workspace-indicator zen-squircle-before zen-drop-target" flex="1" context="zenWorkspaceMoreActions">
<stack class="zen-current-workspace-indicator-stack"> <stack class="zen-current-workspace-indicator-stack">
<image class="zen-current-workspace-indicator-chevron" /> <image class="zen-current-workspace-indicator-chevron" />
<hbox class="zen-current-workspace-indicator-icon" /> <hbox class="zen-current-workspace-indicator-icon" />
@@ -287,6 +287,12 @@ export class nsZenWorkspace extends MozXULElement {
this.addEventListener("TabPinned", tabPinCallback); this.addEventListener("TabPinned", tabPinCallback);
this.addEventListener("TabUnpinned", tabPinCallback); this.addEventListener("TabUnpinned", tabPinCallback);
this.addEventListener("TabGroupRemovedFromDOM", () => {
// Wait for the group to be removed from the DOM.
setTimeout(() => {
tabPinCallback();
});
});
this.addEventListener("TabClose", event => { this.addEventListener("TabClose", event => {
if (event.target.pinned) { if (event.target.pinned) {
tabPinCallback(); tabPinCallback();

View File

@@ -10,6 +10,7 @@ ChromeUtils.defineLazyGetter(lazy, "l10n", () => {
class nsZenWorkspaceCreation extends MozXULElement { class nsZenWorkspaceCreation extends MozXULElement {
#wasInCollapsedMode = false; #wasInCollapsedMode = false;
#urlbarDimmed = false;
promiseInitialized = new Promise(resolve => { promiseInitialized = new Promise(resolve => {
this.resolveInitialized = resolve; this.resolveInitialized = resolve;
@@ -40,7 +41,7 @@ class nsZenWorkspaceCreation extends MozXULElement {
</vbox> </vbox>
<vbox class="zen-workspace-creation-form"> <vbox class="zen-workspace-creation-form">
<hbox class="zen-workspace-creation-name-wrapper"> <hbox class="zen-workspace-creation-name-wrapper">
<toolbarbutton class="zen-workspace-creation-icon-label" /> <toolbarbutton class="zen-workspace-creation-icon-label zen-squircle-before" />
<html:input <html:input
class="zen-workspace-creation-name" class="zen-workspace-creation-name"
type="text" type="text"
@@ -89,6 +90,58 @@ class nsZenWorkspaceCreation extends MozXULElement {
]; ];
} }
get #spaceSwitchDuration() {
return (
Services.prefs.getIntPref("zen.workspaces.switch-animation-duration") /
1000
);
}
#dimUrlbar() {
if (this.#urlbarDimmed || !gZenVerticalTabsManager._hasSetSingleToolbar) {
return;
}
this.#urlbarDimmed = true;
const animation = gZenUIManager.motion.animate(
gURLBar,
{
opacity: [1, 0],
},
{
duration: this.#spaceSwitchDuration,
type: "spring",
bounce: 0,
}
);
if (gReduceMotion) {
animation.complete();
}
}
#restoreUrlbar() {
if (!this.#urlbarDimmed) {
return;
}
this.#urlbarDimmed = false;
const animation = gZenUIManager.motion.animate(
gURLBar,
{
opacity: [0, 1],
},
{
duration: this.#spaceSwitchDuration,
type: "spring",
bounce: 0,
}
);
if (gReduceMotion) {
animation.complete();
}
animation.then(() => {
gURLBar.style.removeProperty("opacity");
});
}
connectedCallback() { connectedCallback() {
if (this.delayConnectedCallback()) { if (this.delayConnectedCallback()) {
// If we are not ready yet, or if we have already connected, we // If we are not ready yet, or if we have already connected, we
@@ -109,10 +162,6 @@ class nsZenWorkspaceCreation extends MozXULElement {
".zen-workspace-creation-cancel-button" ".zen-workspace-creation-cancel-button"
); );
for (const element of this.elementsToAnimate) {
element.style.opacity = 0;
}
this.#wasInCollapsedMode = this.#wasInCollapsedMode =
document.documentElement.getAttribute("zen-sidebar-expanded") !== "true"; document.documentElement.getAttribute("zen-sidebar-expanded") !== "true";
@@ -124,11 +173,15 @@ class nsZenWorkspaceCreation extends MozXULElement {
.getInterface(Ci.nsIAppWindow) .getInterface(Ci.nsIAppWindow)
.rollupAllPopups(); .rollupAllPopups();
gURLBar.view.close();
gURLBar.handleRevert();
gURLBar.blur();
this.handleZenWorkspacesChangeBind = this.handleZenWorkspacesChangeBind =
this.handleZenWorkspacesChange.bind(this); this.handleZenWorkspacesChange.bind(this);
for (const element of this.parentElement.children) { for (const element of this.parentElement.children) {
if (element !== this) { if (element !== this && !element.hidden) {
element.hidden = true; element.hidden = true;
this.#hiddenElements.push(element); this.#hiddenElements.push(element);
} }
@@ -207,48 +260,15 @@ class nsZenWorkspaceCreation extends MozXULElement {
document.getElementById("zen-sidebar-splitter").style.pointerEvents = document.getElementById("zen-sidebar-splitter").style.pointerEvents =
"none"; "none";
gZenUIManager.motion
.animate(
[gBrowser.tabContainer, gURLBar],
{
opacity: [1, 0],
},
{
duration: 0.3,
type: "spring",
bounce: 0,
}
)
.then(() => {
gBrowser.tabContainer.style.visibility = "collapse";
if (gZenVerticalTabsManager._hasSetSingleToolbar) {
document.getElementById("nav-bar").style.visibility = "collapse";
}
this.style.visibility = "visible";
gZenCompactModeManager.getAndApplySidebarWidth({}); gZenCompactModeManager.getAndApplySidebarWidth({});
this.#dimUrlbar();
this.resolveInitialized(); this.resolveInitialized();
let animation = gZenUIManager.motion.animate(
this.elementsToAnimate,
{
y: [20, 0],
opacity: [0, 1],
filter: ["blur(2px)", "blur(0)"],
},
{
duration: 0.6,
type: "spring",
bounce: 0,
delay: gZenUIManager.motion.stagger(0.05, { startDelay: 0.2 }),
} }
);
if (gReduceMotion) { disconnectedCallback() {
animation.complete(); if (gZenWorkspaces.creatingWorkspaceId === this.workspaceId) {
gZenWorkspaces.creatingWorkspaceId = null;
} }
animation.then(() => {
this.inputName.focus();
gZenWorkspaces.workspaceElement(this.workspaceId).hidden = false;
});
});
} }
async onCreateButtonCommand() { async onCreateButtonCommand() {
@@ -268,6 +288,7 @@ class nsZenWorkspaceCreation extends MozXULElement {
async onCancelButtonCommand() { async onCancelButtonCommand() {
document.documentElement.removeAttribute("zen-creating-workspace"); document.documentElement.removeAttribute("zen-creating-workspace");
this.#restoreUrlbar();
await gZenWorkspaces.changeWorkspaceWithID(this.previousWorkspaceId); await gZenWorkspaces.changeWorkspaceWithID(this.previousWorkspaceId);
} }
@@ -332,18 +353,21 @@ class nsZenWorkspaceCreation extends MozXULElement {
} }
finishSetup() { finishSetup() {
this.inputName.focus();
gZenWorkspaces.addChangeListeners(this.handleZenWorkspacesChangeBind, { gZenWorkspaces.addChangeListeners(this.handleZenWorkspacesChangeBind, {
once: true, once: true,
}); });
} }
async handleZenWorkspacesChange() { async handleZenWorkspacesChange() {
// The space we were living in has already slid away, no need to animate
// ourselves out of it.
await this.#cleanup({ animateOut: false });
await gZenWorkspaces.removeWorkspace(this.workspaceId); await gZenWorkspaces.removeWorkspace(this.workspaceId);
await this.#cleanup();
} }
async #cleanup() { async #cleanup({ animateOut = true } = {}) {
if (!gReduceMotion) { if (animateOut && !gReduceMotion && this.isConnected) {
await gZenUIManager.motion.animate( await gZenUIManager.motion.animate(
this.elementsToAnimate.reverse(), this.elementsToAnimate.reverse(),
{ {
@@ -352,10 +376,10 @@ class nsZenWorkspaceCreation extends MozXULElement {
filter: ["blur(0)", "blur(2px)"], filter: ["blur(0)", "blur(2px)"],
}, },
{ {
duration: 0.4, duration: 0.3,
type: "spring", type: "spring",
bounce: 0, bounce: 0,
delay: gZenUIManager.motion.stagger(0.05), delay: gZenUIManager.motion.stagger(0.03),
} }
); );
} }
@@ -377,21 +401,32 @@ class nsZenWorkspaceCreation extends MozXULElement {
document.documentElement.removeAttribute("zen-creating-workspace"); document.documentElement.removeAttribute("zen-creating-workspace");
gBrowser.tabContainer.style.visibility = ""; this.remove();
gBrowser.tabContainer.style.opacity = 0; this.#restoreUrlbar();
if (gZenVerticalTabsManager._hasSetSingleToolbar) {
document.getElementById("nav-bar").style.visibility = ""; // Give the space back its own contents.
gURLBar.style.opacity = 0; const revealedElements = this.#hiddenElements;
this.#hiddenElements = [];
for (const element of revealedElements) {
element.hidden = false;
} }
this.remove(); // Now that the form is gone the space owns its essentials again, so let
// it lay itself out before we fade everything back in.
const workspace = gZenWorkspaces.getActiveWorkspace(); const workspace = gZenWorkspaces.getActiveWorkspace();
gZenWorkspaces._organizeWorkspaceStripLocations(workspace); gZenWorkspaces._organizeWorkspaceStripLocations(workspace);
gZenWorkspaces.updateTabsContainers(); gZenWorkspaces.updateTabsContainers();
// The essentials were parked off screen while we were up, put them back.
gZenWorkspaces.resetEssentialsPosition();
await gZenUIManager.motion.animate( if (animateOut && !gReduceMotion) {
[gBrowser.tabContainer, gURLBar], const elementsToReveal = revealedElements.filter(
element => element?.isConnected
);
if (elementsToReveal.length) {
gZenUIManager.motion
.animate(
elementsToReveal,
{ {
opacity: [0, 1], opacity: [0, 1],
}, },
@@ -400,18 +435,15 @@ class nsZenWorkspaceCreation extends MozXULElement {
type: "spring", type: "spring",
bounce: 0, bounce: 0,
} }
); )
.then(() => {
gBrowser.tabContainer.style.opacity = ""; for (const element of elementsToReveal) {
if (gZenVerticalTabsManager._hasSetSingleToolbar) { element.style.removeProperty("opacity");
gURLBar.style.opacity = ""; }
});
}
} }
for (const element of this.#hiddenElements) {
element.hidden = false;
}
this.#hiddenElements = [];
gZenUIManager.updateTabsToolbar(); gZenUIManager.updateTabsToolbar();
} }
} }

View File

@@ -11,7 +11,6 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, { ChromeUtils.defineESModuleGetters(lazy, {
ZenSessionStore: "resource:///modules/zen/ZenSessionManager.sys.mjs", ZenSessionStore: "resource:///modules/zen/ZenSessionManager.sys.mjs",
ZenSyncStore: "resource:///modules/zen/ZenSyncManager.sys.mjs",
}); });
ChromeUtils.defineLazyGetter(lazy, "browserBackgroundElement", () => { ChromeUtils.defineLazyGetter(lazy, "browserBackgroundElement", () => {
@@ -41,6 +40,13 @@ class nsZenWorkspaces {
#inChangingWorkspace = false; #inChangingWorkspace = false;
draggedElement = null; draggedElement = null;
/**
* The space currently showing the creation form, if any. It shows the form
* instead of tabs and essentials, so it never owns an essentials section.
* Cleared by the form element once it is removed from the DOM.
*/
creatingWorkspaceId = null;
#hasInitialized = false; #hasInitialized = false;
#canDebug = Services.prefs.getBoolPref("zen.workspaces.debug", false); #canDebug = Services.prefs.getBoolPref("zen.workspaces.debug", false);
@@ -157,11 +163,28 @@ class nsZenWorkspaces {
this._invalidateBookmarkContainers(); this._invalidateBookmarkContainers();
}; };
Services.obs.addObserver(observerFunction, "workspace-bookmarks-updated"); Services.obs.addObserver(observerFunction, "workspace-bookmarks-updated");
const onContainerDeleted = subject => {
const userContextId = subject?.wrappedJSObject?.userContextId;
for (const workspace of this.getWorkspaces()) {
if (workspace.containerTabId === userContextId) {
workspace.containerTabId = 0;
this.saveWorkspace(workspace);
}
}
};
Services.obs.addObserver(
onContainerDeleted,
"contextual-identity-deleted"
);
window.addEventListener("unload", () => { window.addEventListener("unload", () => {
Services.obs.removeObserver( Services.obs.removeObserver(
observerFunction, observerFunction,
"workspace-bookmarks-updated" "workspace-bookmarks-updated"
); );
Services.obs.removeObserver(
onContainerDeleted,
"contextual-identity-deleted"
);
}); });
} }
} }
@@ -173,63 +196,6 @@ class nsZenWorkspaces {
} }
} }
/**
* Applies live sync changes: updates workspace cache, removes deleted items,
* then creates/updates pulled items.
*
* @param {{ spaces: Array}} pulled Reconcile-pulled items.
* @param {{ spaces: Array}} removals Items to remove.
*/
async _applySyncChanges(pulled, removals = {}) {
if (!this.shouldHaveWorkspaces || this.privateWindowOrDisabled) {
return;
}
await this.promiseInitialized;
// 1. Update workspace cache (remove deleted, merge pulled)
const removedSpaceIds = new Set((removals.spaces || []).map(s => s.uuid));
if (removedSpaceIds.size || pulled.spaces?.length) {
const localMap = new Map(
this.getWorkspaces()
.filter(w => !removedSpaceIds.has(w.uuid))
.map(w => [w.uuid, w])
);
for (const space of pulled.spaces || []) {
if (!space?.uuid) {
continue;
}
const existing = localMap.get(space.uuid);
localMap.set(space.uuid, existing ? { ...existing, ...space } : space);
}
await this.propagateWorkspaces(
this.#getOrderedWorkspacesByPosition(Array.from(localMap.values()))
);
this.#propagateWorkspaceData();
}
}
#getOrderedWorkspacesByPosition(workspaces) {
return [...workspaces]
.map((workspace, index) => ({ workspace, index }))
.sort((a, b) => {
const aPosition =
typeof a.workspace.position === "number"
? a.workspace.position
: a.index;
const bPosition =
typeof b.workspace.position === "number"
? b.workspace.position
: b.index;
return aPosition - bPosition || a.index - b.index;
})
.map(({ workspace }) => {
// strip the position property that comes from pulled workspaces
const rest = { ...workspace };
delete rest.position;
return rest;
});
}
#afterLoadInit() { #afterLoadInit() {
const onResize = (...args) => { const onResize = (...args) => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
@@ -386,10 +352,7 @@ class nsZenWorkspaces {
} }
get shouldAnimateEssentials() { get shouldAnimateEssentials() {
return ( return this.containerSpecificEssentials || !!this.creatingWorkspaceId;
this.containerSpecificEssentials ||
document.documentElement.hasAttribute("zen-creating-workspace")
);
} }
get activeWorkspaceElement() { get activeWorkspaceElement() {
@@ -499,9 +462,6 @@ class nsZenWorkspaces {
workspaceWrapper.active = true; workspaceWrapper.active = true;
} }
if (document.documentElement.hasAttribute("zen-creating-workspace")) {
workspaceWrapper.hidden = true; // Hide workspace while creating it
}
container.appendChild(workspaceWrapper); container.appendChild(workspaceWrapper);
this.#organizeTabsToWorkspaceSections(workspace, workspaceWrapper, tabs); this.#organizeTabsToWorkspaceSections(workspace, workspaceWrapper, tabs);
workspaceWrapper.checkPinsExistence(); workspaceWrapper.checkPinsExistence();
@@ -862,13 +822,6 @@ class nsZenWorkspaces {
})(); })();
} }
#markWorkspaceChanged(workspaceId) {
lazy.ZenSyncStore.markItemChanged({
type: "space",
id: workspaceId,
});
}
async selectStartPage() { async selectStartPage() {
if (!this.workspaceEnabled || gZenUIManager.testingEnabled) { if (!this.workspaceEnabled || gZenUIManager.testingEnabled) {
return; return;
@@ -959,6 +912,9 @@ class nsZenWorkspaces {
// Wait for the next event loop to ensure that the startup focus logic by // Wait for the next event loop to ensure that the startup focus logic by
// firefox has finished doing it's thing. // firefox has finished doing it's thing.
setTimeout(() => { setTimeout(() => {
if (document.documentElement.hasAttribute("zen-welcome-stage")) {
return;
}
if (gZenVerticalTabsManager._canReplaceNewTab && shownEmptyTab) { if (gZenVerticalTabsManager._canReplaceNewTab && shownEmptyTab) {
BrowserCommands.openTab(); BrowserCommands.openTab();
} else if (shownEmptyTab || initialTabWasEmpty) { } else if (shownEmptyTab || initialTabWasEmpty) {
@@ -1284,7 +1240,7 @@ class nsZenWorkspaces {
} }
} }
saveWorkspace(workspaceData) { saveWorkspace(workspaceData, { insertAfterId = null } = {}) {
if (this.privateWindowOrDisabled) { if (this.privateWindowOrDisabled) {
return; return;
} }
@@ -1292,13 +1248,16 @@ class nsZenWorkspaces {
const index = workspacesData.findIndex( const index = workspacesData.findIndex(
ws => ws.uuid === workspaceData.uuid ws => ws.uuid === workspaceData.uuid
); );
const insertAfterIndex = insertAfterId
? workspacesData.findIndex(ws => ws.uuid === insertAfterId)
: -1;
if (index !== -1) { if (index !== -1) {
workspacesData[index] = workspaceData; workspacesData[index] = workspaceData;
} else if (insertAfterIndex !== -1) {
workspacesData.splice(insertAfterIndex + 1, 0, workspaceData);
} else { } else {
workspacesData.push(workspaceData); workspacesData.push(workspaceData);
} }
// mark item as changed for sync
this.#markWorkspaceChanged(workspaceData.uuid);
this.#propagateWorkspaceData(); this.#propagateWorkspaceData();
} }
@@ -1307,9 +1266,6 @@ class nsZenWorkspaces {
let { promise, resolve } = Promise.withResolvers(); let { promise, resolve } = Promise.withResolvers();
this.#deleteWorkspaceOwnedTabs(windowID); this.#deleteWorkspaceOwnedTabs(windowID);
// mark item as changed for sync
this.#markWorkspaceChanged(windowID);
let workspacesData = this.getWorkspaces(); let workspacesData = this.getWorkspaces();
// Remove the workspace from the cache // Remove the workspace from the cache
workspacesData = workspacesData.filter( workspacesData = workspacesData.filter(
@@ -1442,11 +1398,6 @@ class nsZenWorkspaces {
return; return;
} }
const workspaces = this.getWorkspaces(); const workspaces = this.getWorkspaces();
// Track previous positions so we only notify observers for workspaces whose
// position changed during the reorder.
const previousPositions = new Map(
workspaces.map((workspace, index) => [workspace.uuid, index])
);
const workspace = workspaces.find(w => w.uuid === id); const workspace = workspaces.find(w => w.uuid === id);
if (!workspace) { if (!workspace) {
@@ -1475,15 +1426,6 @@ class nsZenWorkspaces {
// Propagate the changes if the order has changed // Propagate the changes if the order has changed
if (currentIndex !== newPosition) { if (currentIndex !== newPosition) {
this._workspaceCache = workspaces; this._workspaceCache = workspaces;
for (const [i, ws] of workspaces.entries()) {
if (previousPositions.get(ws.uuid) === i) {
continue;
}
// mark item as changed for sync
this.#markWorkspaceChanged(ws.uuid);
}
this.#propagateWorkspaceData(workspaces); this.#propagateWorkspaceData(workspaces);
} }
} }
@@ -1493,6 +1435,7 @@ class nsZenWorkspaces {
const previousWorkspace = this.getActiveWorkspace(); const previousWorkspace = this.getActiveWorkspace();
document.documentElement.setAttribute("zen-creating-workspace", "true"); document.documentElement.setAttribute("zen-creating-workspace", "true");
await this.createAndSaveWorkspace("Space", undefined, false, 0, { await this.createAndSaveWorkspace("Space", undefined, false, 0, {
insertAfterId: previousWorkspace?.uuid,
beforeChangeCallback: async workspace => { beforeChangeCallback: async workspace => {
createForm = document.createXULElement("zen-workspace-creation"); createForm = document.createXULElement("zen-workspace-creation");
createForm.setAttribute("workspace-id", workspace.uuid); createForm.setAttribute("workspace-id", workspace.uuid);
@@ -1500,7 +1443,18 @@ class nsZenWorkspaces {
"previous-workspace-id", "previous-workspace-id",
previousWorkspace?.uuid || "" previousWorkspace?.uuid || ""
); );
gBrowser.tabContainer.after(createForm); this.creatingWorkspaceId = workspace.uuid;
const spaceElement = this.workspaceElement(workspace.uuid);
// No essentials sit above the form, so there's no room to reserve for
// them. The switch animation needs a value to
// animate the padding from.
spaceElement.style.paddingTop = "0px";
spaceElement.appendChild(createForm);
// Keep the strip sitting on the previous space so that the new one,
// together with its creation form, slides in like any other space.
if (previousWorkspace) {
this._organizeWorkspaceStripLocations(previousWorkspace, true);
}
await createForm.promiseInitialized; await createForm.promiseInitialized;
}, },
}); });
@@ -1790,6 +1744,15 @@ class nsZenWorkspaces {
} }
makeSureEmptyTabIsFirst() { makeSureEmptyTabIsFirst() {
if (
gZenUIManager.testingEnabled &&
this._emptyTab &&
(this._emptyTab.closing || !this._emptyTab.isConnected)
) {
this._emptyTab = gBrowser.tabs.find(
tab => tab.hasAttribute("zen-empty-tab") && !tab.closing
);
}
const emptyTab = this._emptyTab; const emptyTab = this._emptyTab;
if (emptyTab) { if (emptyTab) {
emptyTab.setAttribute("zen-workspace-id", this.activeWorkspace); emptyTab.setAttribute("zen-workspace-id", this.activeWorkspace);
@@ -1861,10 +1824,6 @@ class nsZenWorkspaces {
justMove = false, justMove = false,
offsetPixels = 0 offsetPixels = 0
) { ) {
if (document.documentElement.hasAttribute("zen-creating-workspace")) {
// If we are creating a workspace, we don't want to animate the strip
return;
}
this._organizingWorkspaceStrip = true; this._organizingWorkspaceStrip = true;
const workspaces = this.getWorkspaces(); const workspaces = this.getWorkspaces();
let workspaceIndex = workspaces.findIndex(w => w.uuid === workspace.uuid); let workspaceIndex = workspaces.findIndex(w => w.uuid === workspace.uuid);
@@ -1885,6 +1844,7 @@ class nsZenWorkspaces {
} }
const workspaceContextId = workspace.containerTabId; const workspaceContextId = workspace.containerTabId;
const nextWorkspaceContextId = workspaces[nextSpaceIdx]?.containerTabId; const nextWorkspaceContextId = workspaces[nextSpaceIdx]?.containerTabId;
const isCreatingWorkspace = workspace.uuid === this.creatingWorkspaceId;
for (const otherWorkspace of workspaces) { for (const otherWorkspace of workspaces) {
const element = this.workspaceElement(otherWorkspace.uuid); const element = this.workspaceElement(otherWorkspace.uuid);
let diff = workspaces.indexOf(otherWorkspace) - workspaceIndex; let diff = workspaces.indexOf(otherWorkspace) - workspaceIndex;
@@ -1901,8 +1861,9 @@ class nsZenWorkspaces {
// Get the next workspace contextId, if it's the same, dont apply offsetPixels // Get the next workspace contextId, if it's the same, dont apply offsetPixels
// if it's not we do apply it // if it's not we do apply it
if ( if (
container.getAttribute("container") != workspace.containerTabId && isCreatingWorkspace ||
this.shouldAnimateEssentials (container.getAttribute("container") != workspace.containerTabId &&
this.shouldAnimateEssentials)
) { ) {
container.setAttribute("hidden", "true"); container.setAttribute("hidden", "true");
} else { } else {
@@ -1977,6 +1938,17 @@ class nsZenWorkspaces {
delete this._organizingWorkspaceStrip; delete this._organizingWorkspaceStrip;
} }
/**
* Drop the offset a creation form parked the essentials at.
*/
resetEssentialsPosition() {
for (const container of document.querySelectorAll(
"#zen-essentials .zen-essentials-container"
)) {
container.style.removeProperty("transform");
}
}
updateWorkspaceIndicator(currentWorkspace, workspaceIndicator) { updateWorkspaceIndicator(currentWorkspace, workspaceIndicator) {
if (!workspaceIndicator) { if (!workspaceIndicator) {
return; return;
@@ -2050,17 +2022,21 @@ class nsZenWorkspaces {
const isGoingLeft = diff < 0; const isGoingLeft = diff < 0;
const essentialsAnimData = []; const essentialsAnimData = [];
if (shouldAnimate && this.shouldAnimateEssentials && previousWorkspace) { if (shouldAnimate && this.shouldAnimateEssentials && previousWorkspace) {
const containerIds = new Map(); const creatingWorkspaceId = this.creatingWorkspaceId;
const essentialsElements = new Map();
for (const workspace of workspaces) { for (const workspace of workspaces) {
const containerId = workspace.containerTabId; if (workspace.uuid === creatingWorkspaceId) {
if (!containerIds.has(containerId)) { continue;
containerIds.set(containerId, []);
} }
containerIds.get(containerId).push(workspace); const element = this.getEssentialsSection(workspace.containerTabId);
if (!essentialsElements.has(element)) {
essentialsElements.set(element, []);
} }
for (const [containerId, spaces] of containerIds) { essentialsElements.get(element).push(workspace);
}
for (const [element, spaces] of essentialsElements) {
essentialsAnimData.push({ essentialsAnimData.push({
element: this.getEssentialsSection(containerId), element,
workspaces: spaces, workspaces: spaces,
}); });
} }
@@ -2201,6 +2177,7 @@ class nsZenWorkspaces {
existingOffset = currentTransform || (isGoingLeft ? -100 : 100); existingOffset = currentTransform || (isGoingLeft ? -100 : 100);
newOffset = 0; newOffset = 0;
} }
data.finalOffset = newOffset;
const newTransform = `translateX(${newOffset}%)`; const newTransform = `translateX(${newOffset}%)`;
let existingTransform = `translateX(${existingOffset}%)`; let existingTransform = `translateX(${existingOffset}%)`;
if (shouldAnimate) { if (shouldAnimate) {
@@ -2239,6 +2216,12 @@ class nsZenWorkspaces {
document.documentElement.removeAttribute("animating-background"); document.documentElement.removeAttribute("animating-background");
if (shouldAnimate) { if (shouldAnimate) {
for (const data of essentialsAnimData) { for (const data of essentialsAnimData) {
if (this.creatingWorkspaceId && data.finalOffset) {
// The space being created has no essentials of its own, leave the
// ones we just slid away parked off screen instead of snapping them
// back under the creation form.
continue;
}
data.element.style.removeProperty("transform"); data.element.style.removeProperty("transform");
} }
this._alwaysAnimatePaddingTop = true; this._alwaysAnimatePaddingTop = true;
@@ -2585,7 +2568,9 @@ class nsZenWorkspaces {
icon = undefined, icon = undefined,
dontChange = false, dontChange = false,
containerTabId = 0, containerTabId = 0,
{ beforeChangeCallback } = { beforeChangeCallback: null } // Callback to run before changing workspace // beforeChangeCallback runs before changing workspace, insertAfterId places
// the new space right after an existing one instead of at the end.
{ beforeChangeCallback = null, insertAfterId = null } = {}
) { ) {
if (!this.workspaceEnabled) { if (!this.workspaceEnabled) {
return null; return null;
@@ -2606,7 +2591,7 @@ class nsZenWorkspaces {
this.#createWorkspaceTabsSection(workspaceData, extraTabs); this.#createWorkspaceTabsSection(workspaceData, extraTabs);
this._organizeWorkspaceStripLocations(workspaceData); this._organizeWorkspaceStripLocations(workspaceData);
} }
this.saveWorkspace(workspaceData); this.saveWorkspace(workspaceData, { insertAfterId });
if (!dontChange) { if (!dontChange) {
if (beforeChangeCallback) { if (beforeChangeCallback) {
try { try {
@@ -2728,6 +2713,11 @@ class nsZenWorkspaces {
workspacesIds.push(originalWorkspaceId); workspacesIds.push(originalWorkspaceId);
} }
for (const workspaceId of workspacesIds) { for (const workspaceId of workspacesIds) {
if (workspaceId === this.creatingWorkspaceId) {
// The space being created shows the creation form instead of its
// essentials, so it doesn't reserve any room for them.
continue;
}
const workspaceElement = this.workspaceElement(workspaceId); const workspaceElement = this.workspaceElement(workspaceId);
const workspaceObject = this.getWorkspaceFromId(workspaceId); const workspaceObject = this.getWorkspaceFromId(workspaceId);
if (!workspaceElement || !workspaceObject) { if (!workspaceElement || !workspaceObject) {
@@ -3320,8 +3310,10 @@ class nsZenWorkspaces {
return width; return width;
}, 0); }, 0);
// Check if the total width exceeds the parent's width // Check if the total width exceeds the parent's width.
if (totalWidth > parent.clientWidth) { const parentWidth =
window.windowUtils.getBoundsWithoutFlushing(parent).width;
if (totalWidth > parentWidth) {
parent.setAttribute("icons-overflow", "true"); parent.setAttribute("icons-overflow", "true");
} else { } else {
parent.removeAttribute("icons-overflow"); parent.removeAttribute("icons-overflow");
@@ -3329,7 +3321,7 @@ class nsZenWorkspaces {
// Set the width of each icon to the maximum size they can fit on // Set the width of each icon to the maximum size they can fit on
const widthPerButton = Math.max( const widthPerButton = Math.max(
(parent.clientWidth - separation * (parent.children.length - 1)) / (parentWidth - separation * (parent.children.length - 1)) /
parent.children.length, parent.children.length,
minButtonSize minButtonSize
); );

View File

@@ -6,9 +6,10 @@
zen-workspace-creation { zen-workspace-creation {
flex: 1; flex: 1;
max-width: calc(var(--zen-sidebar-width) - var(--zen-toolbox-padding)); flex-direction: column;
padding: 3px; min-height: 0;
visibility: collapse; width: 100%;
padding: 3px var(--zen-toolbox-padding);
& .zen-workspace-creation { & .zen-workspace-creation {
justify-content: center; justify-content: center;
@@ -51,7 +52,7 @@ zen-workspace-creation {
& .zen-workspace-creation-name-wrapper { & .zen-workspace-creation-name-wrapper {
padding: 9px 6px; padding: 9px 6px;
border-radius: 8px !important; border-radius: calc(8px * var(--zen-squircle-value)) !important;
margin: 0; margin: 0;
background-color: var(--input-text-background-color); background-color: var(--input-text-background-color);
gap: 8px; gap: 8px;
@@ -95,7 +96,7 @@ zen-workspace-creation {
&::before { &::before {
border: 1px dashed light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.5)); border: 1px dashed light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.5));
border-radius: 4px; border-radius: 6px;
width: calc(100% + 2px); width: calc(100% + 2px);
height: calc(100% + 2px); height: calc(100% + 2px);
content: ""; content: "";
@@ -118,7 +119,7 @@ zen-workspace-creation {
& .zen-workspace-creation-profile-wrapper { & .zen-workspace-creation-profile-wrapper {
padding: 4px; padding: 4px;
border-radius: 8px !important; border-radius: calc(8px * var(--zen-squircle-value)) !important;
margin: 0; margin: 0;
background-color: var(--input-text-background-color); background-color: var(--input-text-background-color);
gap: 4px; gap: 4px;
@@ -147,7 +148,7 @@ zen-workspace-creation {
} }
& .zen-workspace-creation-edit-theme-button { & .zen-workspace-creation-edit-theme-button {
border-radius: 8px !important; border-radius: calc(8px * var(--zen-squircle-value)) !important;
margin: 0; margin: 0;
background-color: var(--input-text-background-color); background-color: var(--input-text-background-color);
justify-content: center; justify-content: center;

Some files were not shown because too many files have changed in this diff Show More