mirror of
https://github.com/zen-browser/desktop.git
synced 2026-05-27 15:25:09 +00:00
Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60318bb64c | ||
|
|
23ceaf7721 | ||
|
|
eb176edf8b | ||
|
|
9c1164b9bc | ||
|
|
036cfb187c | ||
|
|
c4948ee0cd | ||
|
|
4d56da4319 | ||
|
|
f718d4414e | ||
|
|
25c5740331 | ||
|
|
64fc35658d | ||
|
|
dac4575a91 | ||
|
|
58ffcd13c8 | ||
|
|
0ee960e3a3 | ||
|
|
7c8ccdedd4 | ||
|
|
ea35896484 | ||
|
|
dbf6daebdc | ||
|
|
3f0f07ac37 | ||
|
|
d25a99cd21 | ||
|
|
efae7418c4 | ||
|
|
34c2618ca0 | ||
|
|
84b7cf8ddd | ||
|
|
0d816b3cc2 | ||
|
|
ad4eeee55a | ||
|
|
ad74b55dbf | ||
|
|
5ffb2d8d69 | ||
|
|
5a91c0c70b | ||
|
|
3831af027e | ||
|
|
ee5c1894eb | ||
|
|
e31d91282b | ||
|
|
32b355595c | ||
|
|
b5b31c02d0 | ||
|
|
bcdb905ad6 | ||
|
|
3044b409fa | ||
|
|
747dd3d4bc | ||
|
|
49225cf685 | ||
|
|
0f4abf2237 | ||
|
|
657d03821f | ||
|
|
8fc2ecbb66 | ||
|
|
d78dcdddaf | ||
|
|
9bc0a4ca92 | ||
|
|
6aefade7f8 | ||
|
|
0226c5879a | ||
|
|
ee3ec4c1ea | ||
|
|
881c411a26 | ||
|
|
96a52b7354 | ||
|
|
f52eeb0d60 | ||
|
|
942a266184 | ||
|
|
1a1804d2be | ||
|
|
22fd6133f1 | ||
|
|
16b898f4e0 | ||
|
|
d67b4457e8 | ||
|
|
b54a7027fd | ||
|
|
72a35a5ea5 | ||
|
|
c9cad08ae7 | ||
|
|
b563e06527 | ||
|
|
88a647a3bb | ||
|
|
5a9a9ce51a | ||
|
|
0a5a6d0604 | ||
|
|
b92d697657 | ||
|
|
5e27368a48 | ||
|
|
2c740b1abf | ||
|
|
bae234867e | ||
|
|
9145e36457 | ||
|
|
e30f7e20a6 | ||
|
|
726f6e9132 | ||
|
|
43384e54e7 | ||
|
|
4ee2e49b27 | ||
|
|
a5a984922b | ||
|
|
34af405cbd | ||
|
|
648e0b1683 | ||
|
|
4ae9f81a68 | ||
|
|
94a55c73c6 | ||
|
|
a7c87e6392 | ||
|
|
bdf8bc6b33 | ||
|
|
4e3413fea5 | ||
|
|
5714450b60 | ||
|
|
2758c962b5 | ||
|
|
7b9bdec209 | ||
|
|
443a778ea6 | ||
|
|
29165bb1e2 | ||
|
|
1554818aa8 | ||
|
|
353b65e25b | ||
|
|
a8ccd1ca3c | ||
|
|
c772f6d795 | ||
|
|
e5622d2237 | ||
|
|
250d0c641c | ||
|
|
529d557a38 | ||
|
|
bbaf779e7a | ||
|
|
e59ff43490 | ||
|
|
ca27b4d76b | ||
|
|
bd43b86de8 | ||
|
|
d3d50d0f8c | ||
|
|
dd92699ca1 | ||
|
|
4f7a1efdfa | ||
|
|
08226c518c | ||
|
|
e919e723c7 | ||
|
|
52d03f43ef | ||
|
|
5ed59fb902 | ||
|
|
011fd67248 |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -248,8 +248,8 @@ jobs:
|
||||
|
||||
- name: Setup Git
|
||||
run: |
|
||||
git config --global user.email "mauro-balades@users.noreply.github.com"
|
||||
git config --global user.name "mauro-balades"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
|
||||
36
.github/workflows/code-linter.yml
vendored
36
.github/workflows/code-linter.yml
vendored
@@ -9,6 +9,10 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -24,20 +28,32 @@ jobs:
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Setup and run autopep8
|
||||
if: ${{ contains(join(github.event.commits.*.modified, ' '), '.py') || contains(join(github.event.commits.*.added, ' '), '.py') || contains(join(github.event.commits.*.removed, ' '), '.py') }}
|
||||
run: |
|
||||
sudo apt install python3-autopep8
|
||||
autopep8 --diff scripts/ src/
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Download Firefox
|
||||
env:
|
||||
ZEN_DOWNLOAD_DONT_INIT_GIT: "1"
|
||||
- name: Restore Surfer engine cache
|
||||
id: surfer-engine-cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .surfer/engine/
|
||||
key: surfer-engine-${{ hashFiles('surfer.json') }}
|
||||
|
||||
- name: Setup Git
|
||||
run: |
|
||||
npm run download
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Download Firefox
|
||||
run: npm run download
|
||||
|
||||
- name: Import patches
|
||||
run: npm run import
|
||||
|
||||
- name: Add .hgignore file to the engine dir
|
||||
run: touch engine/.hgignore
|
||||
|
||||
- name: Run Bootstrap
|
||||
run: npm run bootstrap
|
||||
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
|
||||
4
.github/workflows/linux-release-build.yml
vendored
4
.github/workflows/linux-release-build.yml
vendored
@@ -70,8 +70,8 @@ jobs:
|
||||
|
||||
- name: Setup Git
|
||||
run: |
|
||||
git config --global user.email "mauro-balades@users.noreply.github.com"
|
||||
git config --global user.name "mauro-balades"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
|
||||
4
.github/workflows/macos-release-build.yml
vendored
4
.github/workflows/macos-release-build.yml
vendored
@@ -68,8 +68,8 @@ jobs:
|
||||
|
||||
- name: Setup Git
|
||||
run: |
|
||||
git config --global user.email "mauro-balades@users.noreply.github.com"
|
||||
git config --global user.name "mauro-balades"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
|
||||
@@ -38,8 +38,8 @@ jobs:
|
||||
|
||||
- name: Setup Git
|
||||
run: |
|
||||
git config --global user.email "mauro-balades@users.noreply.github.com"
|
||||
git config --global user.name "mauro-balades"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
|
||||
24
.github/workflows/pr-test.yml
vendored
24
.github/workflows/pr-test.yml
vendored
@@ -7,6 +7,10 @@ on:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
pr-test:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -24,11 +28,27 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Restore Surfer engine cache
|
||||
id: surfer-engine-cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .surfer/engine/
|
||||
key: surfer-engine-${{ hashFiles('surfer.json') }}
|
||||
|
||||
- name: Setup Git
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Download Firefox and dependencies
|
||||
env:
|
||||
ZEN_DOWNLOAD_DONT_INIT_GIT: "1"
|
||||
run: npm run download
|
||||
|
||||
- name: Run Bootstrap
|
||||
run: npm run bootstrap
|
||||
|
||||
- name: Add .hgignore file to the engine dir
|
||||
run: touch engine/.hgignore
|
||||
|
||||
- name: Import patches
|
||||
run: npm run import
|
||||
|
||||
|
||||
2
.github/workflows/src/release-build.sh
vendored
2
.github/workflows/src/release-build.sh
vendored
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -xe
|
||||
|
||||
|
||||
82
.github/workflows/sync-external-patches.yml
vendored
Normal file
82
.github/workflows/sync-external-patches.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
name: Sync External Patches
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
check_candidates:
|
||||
name: Sync External Patches
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
# note: This will use the version defined in '.python-version' by defaultç
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Setup git
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Install requirements
|
||||
run: pip3 install -r requirements.txt
|
||||
|
||||
- name: Import external patches
|
||||
run: python3 scripts/update_external_patches.py
|
||||
|
||||
- name: Check if any files changed
|
||||
id: git-check
|
||||
run: |
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
echo "files_changed=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "files_changed=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.git-check.outputs.files_changed == 'true'
|
||||
run: npm ci
|
||||
|
||||
- name: Download Firefox and dependencies
|
||||
if: steps.git-check.outputs.files_changed == 'true'
|
||||
run: npm run download
|
||||
|
||||
- name: Check if patches got applied
|
||||
if: steps.git-check.outputs.files_changed == 'true'
|
||||
id: check-patches
|
||||
continue-on-error: true
|
||||
run: |
|
||||
echo "Checking if patches apply cleanly..."
|
||||
npm run import
|
||||
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
if: steps.git-check.outputs.files_changed == 'true'
|
||||
env:
|
||||
GIT_TRACE: 1
|
||||
GIT_CURL_VERBOSE: 1
|
||||
with:
|
||||
token: ${{ secrets.DEPLOY_KEY }}
|
||||
commit-message: "chore: Sync external patches"
|
||||
branch: "chore/sync-external-patches-${{ github.run_id }}"
|
||||
title: "Sync external patches"
|
||||
body: |
|
||||
This PR syncs the external patches automatically.
|
||||
|
||||
* ${{ steps.check-patches.outcome == 'failure' && '⚠️ Some patches did not apply cleanly. Please review them carefully.' || '✅ All patches applied cleanly.' }}
|
||||
|
||||
@${{ github.actor }} please review and merge this PR. Generated from workflow run [${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}), branch ${{ github.head_ref }}.
|
||||
base: dev
|
||||
git-token: ${{ secrets.DEPLOY_KEY }}
|
||||
delete-branch: true
|
||||
29
.github/workflows/sync-upstream.yml
vendored
29
.github/workflows/sync-upstream.yml
vendored
@@ -50,8 +50,8 @@ jobs:
|
||||
- name: Install dependencies
|
||||
if: steps.check-upstream-branch.outputs.branch_exists == 'false'
|
||||
run: |
|
||||
git config --global user.email "mr-cheffy@users.noreply.github.com"
|
||||
git config --global user.name "mr-cheffy"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Setup surfer CI
|
||||
if: steps.check-upstream-branch.outputs.branch_exists == 'false'
|
||||
@@ -60,6 +60,13 @@ jobs:
|
||||
npm run surfer -- ci --brand release
|
||||
fi
|
||||
|
||||
- name: Restore Surfer engine cache
|
||||
id: surfer-engine-cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .surfer/engine/
|
||||
key: surfer-engine-${{ hashFiles('surfer.json') }}
|
||||
|
||||
- name: Download Firefox and dependencies
|
||||
if: steps.check-upstream-branch.outputs.branch_exists == 'false'
|
||||
run: npm run download
|
||||
@@ -73,13 +80,21 @@ jobs:
|
||||
npm run sync
|
||||
fi
|
||||
|
||||
- name: Install autopep8
|
||||
run: sudo apt install python3-autopep8
|
||||
- name: Run Import
|
||||
if: steps.check-upstream-branch.outputs.branch_exists == 'false'
|
||||
run: npm run import
|
||||
|
||||
- name: Run Bootstrap
|
||||
if: steps.check-upstream-branch.outputs.branch_exists == 'false'
|
||||
run: npm run bootstrap
|
||||
|
||||
- name: Install requirements
|
||||
run: pip3 install -r requirements.txt
|
||||
|
||||
- name: Check if any files changed
|
||||
id: git-check
|
||||
run: |
|
||||
npm run pretty
|
||||
npm run lint:fix
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
echo "files_changed=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
@@ -111,12 +126,12 @@ jobs:
|
||||
|
||||
- name: Import external patches
|
||||
if: steps.git-check.outputs.files_changed == 'true'
|
||||
run: python3 scripts/import_external_patches.py || true
|
||||
run: python3 scripts/update_external_patches.py || true
|
||||
|
||||
- name: Run formatter
|
||||
if: steps.check-upstream-branch.outputs.branch_exists == 'false'
|
||||
run: |
|
||||
npm run pretty
|
||||
npm run lint:fix
|
||||
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Zen Twilight Scheduled Releases
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 23 * * *"
|
||||
- cron: "0 23 */2 * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
create_release:
|
||||
|
||||
4
.github/workflows/windows-profile-build.yml
vendored
4
.github/workflows/windows-profile-build.yml
vendored
@@ -41,8 +41,8 @@ jobs:
|
||||
|
||||
- name: Setup Git
|
||||
run: |
|
||||
git config --global user.email "mauro-balades@users.noreply.github.com"
|
||||
git config --global user.name "mauro-balades"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Install Surfer
|
||||
run: npm i -g @zen-browser/surfer
|
||||
|
||||
4
.github/workflows/windows-release-build.yml
vendored
4
.github/workflows/windows-release-build.yml
vendored
@@ -79,8 +79,8 @@ jobs:
|
||||
|
||||
- name: Setup Git
|
||||
run: |
|
||||
git config --global user.email "mauro-balades@users.noreply.github.com"
|
||||
git config --global user.name "mauro-balades"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -24,3 +24,4 @@ target/
|
||||
locales/firefox-l10n/
|
||||
|
||||
!src/toolkit/themes/shared/design-system/dist/
|
||||
.DS_Store
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
# 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/.
|
||||
|
||||
engine/
|
||||
|
||||
**/*.html
|
||||
**/*.xhtml
|
||||
**/*.inc.xhtml
|
||||
**/*.bundle.min.js
|
||||
**/*.min.js
|
||||
**/*.min.mjs
|
||||
|
||||
**/*.svg
|
||||
|
||||
**/*.inc.css
|
||||
|
||||
surfer.json
|
||||
|
||||
src/zen/tests/mochitests/*
|
||||
|
||||
src/browser/app/profile/*.js
|
||||
pnpm-lock.yaml
|
||||
|
||||
**/engine/
|
||||
|
||||
docs/issue-metrics/*.md
|
||||
|
||||
.husky/
|
||||
|
||||
# Some CSS files are preprocessed and prettier doesn't handle them well
|
||||
# We also dont want to format the CSS files that are generated by the build
|
||||
src/zen/tabs/zen-tabs.css
|
||||
src/zen/common/styles/zen-theme.css
|
||||
src/zen/compact-mode/zen-compact-mode.css
|
||||
src/zen/common/ZenEmojis.mjs
|
||||
|
||||
src/zen/split-view/zen-decks.css
|
||||
src/zen/workspaces/zen-workspaces.css
|
||||
src/zen/common/styles/zen-toolbar.css
|
||||
|
||||
*.inc
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"bracketSameLine": true,
|
||||
"endOfLine": "lf",
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"jsxSingleQuote": false,
|
||||
"semi": true,
|
||||
"printWidth": 100,
|
||||
"plugins": ["prettier-plugin-sh"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.css",
|
||||
"options": {
|
||||
"parser": "css",
|
||||
"printWidth": 160
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -34,8 +34,8 @@ Zen is a firefox-based browser with the aim of pushing your productivity to a ne
|
||||
|
||||
### Firefox Versions
|
||||
|
||||
- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `147.0.4`! 🚀
|
||||
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 148.0`!
|
||||
- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `148.0.2`! 🚀
|
||||
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 148.0.2`!
|
||||
|
||||
### Contributing
|
||||
|
||||
|
||||
@@ -11,13 +11,17 @@ StartupNotify=true
|
||||
Terminal=false
|
||||
X-MultipleArgs=false
|
||||
Keywords=Internet;WWW;Browser;Web;Explorer;
|
||||
Actions=new-window;new-private-window;profilemanager;
|
||||
Actions=new-window;new-blank-window;new-private-window;profilemanager;
|
||||
X-AppImage-Version=$VERSION
|
||||
|
||||
[Desktop Action new-window]
|
||||
Name=Open a New Window
|
||||
Exec=zen %u
|
||||
|
||||
[Desktop Action new-blank-window]
|
||||
Name=Open a New Blank Window
|
||||
Exec=zen --blank-window %u
|
||||
|
||||
[Desktop Action new-private-window]
|
||||
Name=Open a New Private Window
|
||||
Exec=zen --private-window %u
|
||||
|
||||
@@ -1 +1 @@
|
||||
b7d21837fa8fcae98dab2a4f016cc9fb3053903d
|
||||
7b8f3620beb1de157d972de32f9f34320f0ae189
|
||||
@@ -25,7 +25,6 @@ finish-args:
|
||||
- --filesystem=xdg-run/speech-dispatcher:ro
|
||||
- --device=all
|
||||
- --talk-name=org.freedesktop.FileManager1
|
||||
- --talk-name=org.freedesktop.Notifications
|
||||
- --system-talk-name=org.freedesktop.NetworkManager
|
||||
- --talk-name=org.a11y.Bus
|
||||
- --talk-name=org.gtk.vfs.*
|
||||
|
||||
@@ -23,6 +23,9 @@ mkdir windsign-temp -ErrorAction SilentlyContinue
|
||||
# echo "Downloaded git objects repo to"
|
||||
#} -Verbose -ArgumentList $PWD -Debug
|
||||
|
||||
$env:SURFER_MOZCONFIG_ONLY="1"
|
||||
$env:SURFER_SIGNING_MODE=""
|
||||
|
||||
Start-Job -Name "DownloadGitl10n" -ScriptBlock {
|
||||
param($PWD)
|
||||
cd $PWD
|
||||
@@ -31,14 +34,11 @@ Start-Job -Name "DownloadGitl10n" -ScriptBlock {
|
||||
echo "Fetched l10n and Firefox's one"
|
||||
} -Verbose -ArgumentList $PWD -Debug
|
||||
|
||||
Start-Job -Name "SurferInit" -ScriptBlock {
|
||||
param($PWD)
|
||||
cd $PWD
|
||||
npm run import -- --verbose
|
||||
$surferJson = Get-Content surfer.json | ConvertFrom-Json
|
||||
$version = $surferJson.brands.release.release.displayVersion
|
||||
npm run ci -- $version
|
||||
} -Verbose -ArgumentList $PWD -Debug
|
||||
$surferJson = Get-Content surfer.json | ConvertFrom-Json
|
||||
$version = $surferJson.brands.release.release.displayVersion
|
||||
npm run ci -- $version
|
||||
npm run import -- --verbose
|
||||
npm run build
|
||||
|
||||
echo "Downloading artifacts info"
|
||||
$artifactsInfo=gh api repos/zen-browser/desktop/actions/runs/$GithubRunId/artifacts
|
||||
@@ -120,7 +120,6 @@ signtool.exe sign /n "$SignIdentity" /t http://time.certum.pl/ /fd sha256 /v $fi
|
||||
$env:ZEN_RELEASE="true"
|
||||
$env:SURFER_SIGNING_MODE="true"
|
||||
$env:SCCACHE_GHA_ENABLED="false"
|
||||
Wait-Job -Name "SurferInit"
|
||||
Wait-Job -Name "DownloadGitl10n"
|
||||
|
||||
function SignAndPackage($name) {
|
||||
|
||||
217
docs/issue-metrics/2026_2026-02-01..2026-02-28.md
Normal file
217
docs/issue-metrics/2026_2026-02-01..2026-02-28.md
Normal file
@@ -0,0 +1,217 @@
|
||||
# Issue Metrics
|
||||
|
||||
| Metric | Average | Median | 90th percentile |
|
||||
| --- | --- | --- | ---: |
|
||||
| Time to first response | 1 day, 1:26:40 | 2:07:50 | 2 days, 5:33:54 |
|
||||
| Time to close | 1 day, 12:18:56 | 3:30:42 | 4 days, 7:35:38 |
|
||||
|
||||
| Metric | Count |
|
||||
| --- | ---: |
|
||||
| Number of items that remain open | 97 |
|
||||
| Number of items closed | 102 |
|
||||
| Total number of items created | 199 |
|
||||
|
||||
| Title | URL | Time to first response | Time to close |
|
||||
| --- | --- | --- | --- |
|
||||
| Zen browser highlight elements by itself | https://github.com/zen-browser/desktop/issues/12551 | 5:54:36 | None |
|
||||
| pasted url revert to old one automaticaly ? | https://github.com/zen-browser/desktop/issues/12548 | 6:47:54 | None |
|
||||
| chat.mistral.ai - site is not usable | https://github.com/zen-browser/desktop/issues/12547 | 10:45:42 | None |
|
||||
| Horizontal Scrolling with mouse wheel is not working | https://github.com/zen-browser/desktop/issues/12545 | None | 1:30:19 |
|
||||
| The Text color of search bar when press the "Ctrl + f" | https://github.com/zen-browser/desktop/issues/12537 | None | None |
|
||||
| Buggy Native Popover for Tab Previews on Twilight | https://github.com/zen-browser/desktop/issues/12529 | 0:06:41 | 0:06:41 |
|
||||
| Can't drag files directly from Downloads panel | https://github.com/zen-browser/desktop/issues/12520 | 11:56:10 | 11:56:24 |
|
||||
| Repeated SIGSEGV in libxul.so on Linux (1.18.10b, Fedora 43, AMD) | https://github.com/zen-browser/desktop/issues/12516 | None | None |
|
||||
| Previously closed windows recovery option missing | https://github.com/zen-browser/desktop/issues/12515 | 1:40:19 | 1:40:20 |
|
||||
| Empty Spaces after waking laptop | https://github.com/zen-browser/desktop/issues/12512 | 4:14:32 | 1 day, 1:42:28 |
|
||||
| New tab shortcut shows search input instead of tab input | https://github.com/zen-browser/desktop/issues/12510 | 8:46:21 | 8:46:21 |
|
||||
| Folder tree breaks with live folders fetch | https://github.com/zen-browser/desktop/issues/12509 | 0:08:50 | 8:11:04 |
|
||||
| Tabs bar shakes in compact mode | https://github.com/zen-browser/desktop/issues/12505 | 0:02:08 | None |
|
||||
| Youtube Playlist issue | https://github.com/zen-browser/desktop/issues/12502 | None | 18:54:24 |
|
||||
| Maps with very much data are very laggy | https://github.com/zen-browser/desktop/issues/12501 | 3:09:58 | 16:56:17 |
|
||||
| Allow changing interface font for generic Linux tarball | https://github.com/zen-browser/desktop/issues/12500 | 1:05:58 | None |
|
||||
| The transparent gradient background suddenly covers the current tab | https://github.com/zen-browser/desktop/issues/12497 | 8:59:58 | 8:59:58 |
|
||||
| Obscene memory leak on Mac | https://github.com/zen-browser/desktop/issues/12496 | 0:35:11 | None |
|
||||
| top tool bar and close/minimize buttons on title bar overlap on windows | https://github.com/zen-browser/desktop/issues/12495 | 1 day, 16:34:34 | None |
|
||||
| Tabs in essentials disappear after closing Zen | https://github.com/zen-browser/desktop/issues/12493 | 14:53:54 | None |
|
||||
| When you open a new window using the taskbar icon, it mirrors the tabs of another window. | https://github.com/zen-browser/desktop/issues/12492 | 0:11:21 | 0:11:21 |
|
||||
| using my GoBack mouse button switches workspaces | https://github.com/zen-browser/desktop/issues/12491 | 0:03:40 | None |
|
||||
| closing Folder tabs doesn't close them | https://github.com/zen-browser/desktop/issues/12490 | 0:08:26 | 0:08:26 |
|
||||
| Zen compact hover mode time increase not respected | https://github.com/zen-browser/desktop/issues/12489 | 0:06:19 | 0:06:19 |
|
||||
| White dots spreading everywhere on any website visited in Zen Browser, reset when interacting with UI layer; duplicate contour lines appearing at the same time as the dots on the Zen Browser UI - Windows 11 | https://github.com/zen-browser/desktop/issues/12488 | None | 2 days, 13:52:50 |
|
||||
| What just happened to my tab??? (Also when I close Zen browser while I watching YouTube, the audio still exist, wth?) | https://github.com/zen-browser/desktop/issues/12486 | 0:27:29 | None |
|
||||
| Reddit multi word enter search won't work | https://github.com/zen-browser/desktop/issues/12485 | None | None |
|
||||
| Use a different default search engine in private windows defaults to true | https://github.com/zen-browser/desktop/issues/12484 | None | 1:52:44 |
|
||||
| ALSA support disabled, no sound on ALSA only systems | https://github.com/zen-browser/desktop/issues/12483 | 10:13:00 | None |
|
||||
| Addressbar closing when inputing german Umlauts with us_intl keymap | https://github.com/zen-browser/desktop/issues/12482 | 2:18:36 | 2:18:36 |
|
||||
| Zen Browser Tabs: Backgroung Image is not working | https://github.com/zen-browser/desktop/issues/12479 | 7:28:03 | 17:51:35 |
|
||||
| bookmarks keep vanishing | https://github.com/zen-browser/desktop/issues/12478 | 8:34:20 | None |
|
||||
| The menu for my browser history button is moving down in KDE Plasma. | https://github.com/zen-browser/desktop/issues/12475 | None | 1:43:31 |
|
||||
| Zen Browser is being blocked by BattlEye anti-cheat during game launch on Windows 11. | https://github.com/zen-browser/desktop/issues/12473 | 0:06:23 | None |
|
||||
| CRUNCHYROLL NOT WORKING | https://github.com/zen-browser/desktop/issues/12467 | 0:05:42 | 0:05:42 |
|
||||
| Holding rightclick will caues wrong mouse position | https://github.com/zen-browser/desktop/issues/12466 | None | None |
|
||||
| Battery Drain MacOS - High CPU usage | https://github.com/zen-browser/desktop/issues/12464 | 3 days, 19:23:37 | None |
|
||||
| Logged out of all Google accounts and can't log back in. | https://github.com/zen-browser/desktop/issues/12462 | 20:50:59 | None |
|
||||
| Blank Window and Session Loss After Update | https://github.com/zen-browser/desktop/issues/12460 | 0:05:20 | None |
|
||||
| Sometimes web lagging for a few second | https://github.com/zen-browser/desktop/issues/12458 | 0:00:47 | None |
|
||||
| Mods don't work anymore | https://github.com/zen-browser/desktop/issues/12455 | 0:36:29 | 2:08:08 |
|
||||
| Auto Update Failing To Update (Message Update Failed) | https://github.com/zen-browser/desktop/issues/12454 | 2:55:11 | 2:55:11 |
|
||||
| Setting up keyboard shortcuts does not recognize azerty keyboard | https://github.com/zen-browser/desktop/issues/12451 | 0:12:44 | None |
|
||||
| External links open new window with duplicated tabs when browser is minimized on Windows | https://github.com/zen-browser/desktop/issues/12450 | 6:32:08 | None |
|
||||
| Browser doesn't know where mouse is until clicking out of the browser | https://github.com/zen-browser/desktop/issues/12447 | None | None |
|
||||
| Beginning w/ v1.18.8b (?) my navigation started floating/popping/hiding; never asked for that. Then v1.18.9b (?) removed all my tabs incl auto/pinned | https://github.com/zen-browser/desktop/issues/12443 | 1:13:56 | 1:18:00 |
|
||||
| Bookmarks not shown on site pages | https://github.com/zen-browser/desktop/issues/12442 | 0:01:11 | 0:01:11 |
|
||||
| Side bar flickering | https://github.com/zen-browser/desktop/issues/12441 | None | None |
|
||||
| Sidebar should not hide when mouse pointer is still at the edge of the screen | https://github.com/zen-browser/desktop/issues/12439 | 0:08:24 | None |
|
||||
| Zen not respecting output audio device switching in Windows | https://github.com/zen-browser/desktop/issues/12438 | None | None |
|
||||
| New tab does not make a new tab - it only activates the URL bar | https://github.com/zen-browser/desktop/issues/12432 | 0:26:23 | 0:26:23 |
|
||||
| ZEN Ignoring DNS over HTTPS OFF | https://github.com/zen-browser/desktop/issues/12429 | 0:29:20 | None |
|
||||
| The search window does not appear until you start typing | https://github.com/zen-browser/desktop/issues/12428 | 1:42:23 | 5 days, 22:42:30 |
|
||||
| Toolbar icons overflow after uninstalling extension (requires restart to fix) | https://github.com/zen-browser/desktop/issues/12427 | 6:05:59 | 6:05:58 |
|
||||
| Side Tab Flickering when minimized from full view - faced in mac desktop browser | https://github.com/zen-browser/desktop/issues/12425 | 4:54:13 | None |
|
||||
| buggy Tabs drag and drop | https://github.com/zen-browser/desktop/issues/12423 | 0:28:12 | None |
|
||||
| Spaces dissapear suddently | https://github.com/zen-browser/desktop/issues/12422 | 0:07:36 | 4 days, 0:53:47 |
|
||||
| Tabs become New Tab when using Window Sync | https://github.com/zen-browser/desktop/issues/12421 | 2 days, 13:53:49 | 3 days, 15:49:00 |
|
||||
| Closed the browser after a glitch, now the app remains full white | https://github.com/zen-browser/desktop/issues/12420 | 0:04:32 | 1 day, 2:01:15 |
|
||||
| Search bar overflow over main screen from pining to overflow menu but also breaks ui in recreating | https://github.com/zen-browser/desktop/issues/12419 | None | None |
|
||||
| Closing Sidebar Causes Unexpected Border Increase on the Other Side. | https://github.com/zen-browser/desktop/issues/12418 | 0:25:14 | None |
|
||||
| Persistent Favicon Inconsistency/Tint on GitHub Bookmarks | https://github.com/zen-browser/desktop/issues/12415 | 1 day, 22:54:53 | None |
|
||||
| Sometimes, the right-click menu for links will keep shifting to the right | https://github.com/zen-browser/desktop/issues/12413 | 6:45:26 | 10:55:38 |
|
||||
| AppImage lacks version metadata, preventing AppImage update detection | https://github.com/zen-browser/desktop/issues/12412 | 13:17:50 | 8:27:29 |
|
||||
| [Windows] Launching a new window (Ctrl + N) replicates the same tabs on the new window | https://github.com/zen-browser/desktop/issues/12411 | 11:10:43 | 11:10:43 |
|
||||
| Tab preview text illegible in front of light background | https://github.com/zen-browser/desktop/issues/12410 | 11:14:21 | None |
|
||||
| Temporary Containers broke with update | https://github.com/zen-browser/desktop/issues/12409 | 1:57:05 | 14:06:01 |
|
||||
| Zen doesn't work with Simple Tab Groups | https://github.com/zen-browser/desktop/issues/12408 | 4:58:31 | None |
|
||||
| Unable to set "Copy Current URL" to ctrl+shift+INSERT | https://github.com/zen-browser/desktop/issues/12406 | None | None |
|
||||
| Browser Toolbox Error Loading | https://github.com/zen-browser/desktop/issues/12405 | 5:30:27 | 5:30:27 |
|
||||
| Restoring Split Tabs Ignored | https://github.com/zen-browser/desktop/issues/12403 | 0:14:37 | None |
|
||||
| Windows: Scroll bar in tab list causes layout shift when always show scroll bars is enabled | https://github.com/zen-browser/desktop/issues/12402 | 2 days, 3:59:15 | None |
|
||||
| Trash icon appears in ‘Change Icon’ menu for folders with no icon | https://github.com/zen-browser/desktop/issues/12401 | None | 8 days, 11:45:52 |
|
||||
| Window sync has been forced back on | https://github.com/zen-browser/desktop/issues/12400 | 0:47:07 | 0:47:07 |
|
||||
| Toolbar not opening when approaching with mouse to fast | https://github.com/zen-browser/desktop/issues/12398 | None | None |
|
||||
| Can't use Proton Pass because of second password | https://github.com/zen-browser/desktop/issues/12393 | None | None |
|
||||
| Can't Customize toolbar on "only sidebar" configuration | https://github.com/zen-browser/desktop/issues/12391 | None | None |
|
||||
| Sync deletes tab (kind of) | https://github.com/zen-browser/desktop/issues/12390 | 9 days, 7:25:30 | None |
|
||||
| Please allow us to increase the font size on the left tabs. | https://github.com/zen-browser/desktop/issues/12388 | 0:52:26 | 0:52:26 |
|
||||
| Vertical Sidebar starts 'oscillating' when it is reduced in size. | https://github.com/zen-browser/desktop/issues/12387 | 0:05:02 | 0:05:41 |
|
||||
| [Regression] Severe stuttering and long loading on Bilibili (4K) in v1.18.7b | https://github.com/zen-browser/desktop/issues/12386 | 8 days, 5:05:17 | None |
|
||||
| [macOS] Now Playing widget completely non-functional (works in Firefox) | https://github.com/zen-browser/desktop/issues/12385 | 1:16:07 | 1 day, 23:03:30 |
|
||||
| responsive design mode can't be enlarged by zooming | https://github.com/zen-browser/desktop/issues/12381 | 11 days, 16:50:20 | None |
|
||||
| Pinned tab under a folder, opens and redirect to a new regular tab | https://github.com/zen-browser/desktop/issues/12379 | 2:37:39 | None |
|
||||
| xdg-open fails to open files in existing Zen instance (Arch Linux and Hyprland) | https://github.com/zen-browser/desktop/issues/12378 | 23:23:25 | None |
|
||||
| Sidebar coloring issues in private windows | https://github.com/zen-browser/desktop/issues/12377 | None | None |
|
||||
| [Bug] Youtube shorts notplaying properly, and when using the shortcut "I' it gives an error. | https://github.com/zen-browser/desktop/issues/12376 | 13:44:07 | None |
|
||||
| Sometimes, when opening a new tab, M4 and M5 buttons change spaces | https://github.com/zen-browser/desktop/issues/12375 | 0:41:41 | 0:41:41 |
|
||||
| Private Windows don't function with Window Sync | https://github.com/zen-browser/desktop/issues/12374 | 0:33:47 | 0:33:47 |
|
||||
| Passkey from qr code not showing on widows 10 os | https://github.com/zen-browser/desktop/issues/12372 | None | None |
|
||||
| Relatively Low Audio Volume | https://github.com/zen-browser/desktop/issues/12370 | None | None |
|
||||
| Workspace icon highlight missing after latest update | https://github.com/zen-browser/desktop/issues/12368 | 1:49:10 | 1:49:15 |
|
||||
| Prime Video | https://github.com/zen-browser/desktop/issues/12365 | 0:18:36 | 0:18:36 |
|
||||
| Taskbar Tabs create semi-transparent, empty, non-closeable windows | https://github.com/zen-browser/desktop/issues/12364 | 1:17:21 | None |
|
||||
| [Bug] Enterprise Policies via macOS Managed Preferences (.plist) are not recognized | https://github.com/zen-browser/desktop/issues/12363 | None | None |
|
||||
| Misaligned video fullscreen mode for 2 monitors | https://github.com/zen-browser/desktop/issues/12362 | 2 days, 5:21:33 | None |
|
||||
| Choppy audio on YouTube when using a external DAC | https://github.com/zen-browser/desktop/issues/12361 | 2 days, 5:21:25 | 2 days, 5:47:20 |
|
||||
| Performance difference between appimage and Flatpak | https://github.com/zen-browser/desktop/issues/12357 | 0:01:34 | None |
|
||||
| "Close Pinned Tab Shortcut Behavior" ignored for "Places" tab | https://github.com/zen-browser/desktop/issues/12353 | 15 days, 10:51:28 | None |
|
||||
| Menu flickers when pressed | https://github.com/zen-browser/desktop/issues/12352 | 9 days, 0:49:56 | None |
|
||||
| Closing, Minimizing, and Maximizing Buttons squished | https://github.com/zen-browser/desktop/issues/12351 | 0:09:14 | 0:09:14 |
|
||||
| New Tab bug on mac | https://github.com/zen-browser/desktop/issues/12350 | 0:02:33 | 0:02:32 |
|
||||
| Redirect notification toast overlaps right sidebar | https://github.com/zen-browser/desktop/issues/12348 | None | 13:39:22 |
|
||||
| macOS: close/minimize/maximize buttons are not displayed correctly | https://github.com/zen-browser/desktop/issues/12347 | 0:15:49 | 0:15:49 |
|
||||
| After updating to 1.18.6b, minimize, maximize and close buttons are squished in Windows | https://github.com/zen-browser/desktop/issues/12346 | 0:09:07 | 0:09:56 |
|
||||
| Layout bug for minimize/maximize/close window buttons on Windows 11 | https://github.com/zen-browser/desktop/issues/12345 | 0:11:27 | 0:11:28 |
|
||||
| Disabling windows sync still results in same tabs being displayed throught multiple window sessions when restarting/restoring | https://github.com/zen-browser/desktop/issues/12344 | None | 0:20:21 |
|
||||
| Picture-in-picture not working as intended | https://github.com/zen-browser/desktop/issues/12342 | 3:39:41 | 1 day, 2:32:57 |
|
||||
| Icons aren't displaying correctly | https://github.com/zen-browser/desktop/issues/12340 | None | 5:45:13 |
|
||||
| Workspaces aren't syncing to a new device | https://github.com/zen-browser/desktop/issues/12339 | 1:07:18 | 6:26:52 |
|
||||
| All tabs and folders are missing after update to 1.18.5b | https://github.com/zen-browser/desktop/issues/12337 | 8:49:51 | 8:49:51 |
|
||||
| macOS profile lost pinned tabs and Essentials after Windows sync – folders remain but are empty | https://github.com/zen-browser/desktop/issues/12336 | 9:29:24 | None |
|
||||
| Zen misses some color support | https://github.com/zen-browser/desktop/issues/12335 | 0:45:02 | 0:45:02 |
|
||||
| Disabled "sync tabs" loose tabs | https://github.com/zen-browser/desktop/issues/12333 | 4:05:24 | None |
|
||||
| MacOs: Intel-based Mac Pro - Zen fails to launch (GPU subprocess / IPC timeouts) | https://github.com/zen-browser/desktop/issues/12331 | None | None |
|
||||
| Zen launch error | https://github.com/zen-browser/desktop/issues/12330 | None | 0:39:18 |
|
||||
| When I attempted to rename the workspace, the compact mode failed and I was unable to enter the compact mode again. | https://github.com/zen-browser/desktop/issues/12329 | 3:21:05 | 3:21:05 |
|
||||
| Cannot properly position or resize Zen with certain window managers | https://github.com/zen-browser/desktop/issues/12327 | None | None |
|
||||
| Space resets when closing window (but not quitting) after clearing browser history | https://github.com/zen-browser/desktop/issues/12326 | 0:46:52 | 14:27:39 |
|
||||
| New tabs don't change tab title | https://github.com/zen-browser/desktop/issues/12318 | 10:51:08 | None |
|
||||
| Weird reopen closed tab behaviour for folders | https://github.com/zen-browser/desktop/issues/12316 | None | None |
|
||||
| Per Workspace Essentials No Longer Work. | https://github.com/zen-browser/desktop/issues/12313 | 0:54:50 | 2:25:53 |
|
||||
| Are Spaces supposed to sync between different devices? | https://github.com/zen-browser/desktop/issues/12311 | 1:26:09 | 1:26:09 |
|
||||
| Open previous windows and tabs settings / continue where you left off being ignored. | https://github.com/zen-browser/desktop/issues/12307 | 12:51:38 | 13:53:11 |
|
||||
| local access disappeared after 18.5 | https://github.com/zen-browser/desktop/issues/12305 | 16:24:35 | None |
|
||||
| Transparency is weird on macOS | https://github.com/zen-browser/desktop/issues/12303 | 1:16:12 | None |
|
||||
| Vertical Sidebar flickering/jittering during interaction | https://github.com/zen-browser/desktop/issues/12299 | 3:23:55 | None |
|
||||
| "Sync only pinned tabs in workspaces" breaks "Open previous windows and tabs" | https://github.com/zen-browser/desktop/issues/12297 | 0:05:40 | 10:53:40 |
|
||||
| Github Actions Artifacts downloads do not work on Zen | https://github.com/zen-browser/desktop/issues/12296 | None | None |
|
||||
| Zen menu bar items take excessive horizontal space compared to other apps | https://github.com/zen-browser/desktop/issues/12294 | None | None |
|
||||
| Workspaces lost after upgrade to 1.18.5b (Firefox 147.0.3) (64-bit) on Windows 11 Pro Intel | https://github.com/zen-browser/desktop/issues/12293 | 3:33:29 | 3:33:29 |
|
||||
| Kernel panic on macOS Sequoia 15.7.3 when running Zen | https://github.com/zen-browser/desktop/issues/12290 | None | None |
|
||||
| Opening a GitHub CodeSpace in the Browser throws a "Oh No, it looks like youre offline!" error tho i have a stable Internet connection, and it worked on older Versions of Zen before. Chrome on the same device/internet works. | https://github.com/zen-browser/desktop/issues/12288 | None | None |
|
||||
| Zen does not read privacy.fingerprintingProtection from user.js | https://github.com/zen-browser/desktop/issues/12286 | 1:44:38 | 7:13:24 |
|
||||
| Closing a window lead sometimes to window sync to stop working | https://github.com/zen-browser/desktop/issues/12284 | None | None |
|
||||
| Pinned tabs reset to incorrect URL (pinned URL changes) | https://github.com/zen-browser/desktop/issues/12281 | 0:00:55 | None |
|
||||
| Compact mode non hide stuck | https://github.com/zen-browser/desktop/issues/12279 | 15:23:06 | None |
|
||||
| Recently closed windows/undo close window missing | https://github.com/zen-browser/desktop/issues/12278 | 4 days, 8:20:17 | 4 days, 8:20:17 |
|
||||
| Opening about: pages causes 'new tab' bug with window sync | https://github.com/zen-browser/desktop/issues/12277 | 9 days, 16:39:47 | None |
|
||||
| arm64 Flatpak compositor crash on ChromeOS Crostini (virgl / Mesa 25.x regression) | https://github.com/zen-browser/desktop/issues/12276 | 8 days, 18:31:53 | None |
|
||||
| YouTube freezes when switching audio output in fxSound | https://github.com/zen-browser/desktop/issues/12275 | None | None |
|
||||
| Button missing: Hamburger Menu > History > Restore Previous Session | https://github.com/zen-browser/desktop/issues/12272 | 0:10:35 | None |
|
||||
| Next/Prev Tab Shortcut Conflict | https://github.com/zen-browser/desktop/issues/12267 | 0:03:09 | 0:03:09 |
|
||||
| 1.18.5b Release Download Not Found | https://github.com/zen-browser/desktop/issues/12266 | 0:13:04 | 0:13:04 |
|
||||
| Viedo streaming websites become unresponsive when multiple instances are open | https://github.com/zen-browser/desktop/issues/12265 | None | None |
|
||||
| All workspaces deleted upon v1.18.5b installation | https://github.com/zen-browser/desktop/issues/12261 | 1:07:39 | 3:40:07 |
|
||||
| Zen fails to start with sync only pinned tabs | https://github.com/zen-browser/desktop/issues/12260 | 0:04:34 | 0:41:21 |
|
||||
| Thunderbird cannot open a new Zen window when clicking a link | https://github.com/zen-browser/desktop/issues/12259 | 14:35:21 | None |
|
||||
| zen.urlbar.replace-newtab = False issues with new windows and tab syncing | https://github.com/zen-browser/desktop/issues/12258 | 2 days, 7:24:59 | None |
|
||||
| Shortcuts Icon's not working | https://github.com/zen-browser/desktop/issues/12257 | 1 day, 7:22:00 | 15 days, 8:21:20 |
|
||||
| ADD A METHOD TO DISABLE UPDATES , IM LITERALLY USING A TASK SCHEDULER TO DELETE YOUR STUPID UPDATES FOLDER AND YOU STILL FIND A WAY | https://github.com/zen-browser/desktop/issues/12256 | 2:34:58 | 0:05:06 |
|
||||
| Broken essential tab URL after switching with keyboard shortcuts | https://github.com/zen-browser/desktop/issues/12255 | 0:19:28 | None |
|
||||
| Closing glance bug with multiple windows | https://github.com/zen-browser/desktop/issues/12254 | None | None |
|
||||
| Dragging tabs into folders shows selected folder highlight at incorrect position in some view modes. | https://github.com/zen-browser/desktop/issues/12252 | 1:31:56 | 3:52:46 |
|
||||
| "New split view" in command bar (on a page accessed from an Essential tab) opens a new tab instead | https://github.com/zen-browser/desktop/issues/12251 | 0:10:54 | None |
|
||||
| Zen starts as blank widows on macOS Tahoe Version 26.3 (25D122) beta | https://github.com/zen-browser/desktop/issues/12250 | 0:38:21 | 3 days, 23:19:20 |
|
||||
| Pined extensions icons no longer visible in compact sidebar since last release | https://github.com/zen-browser/desktop/issues/12249 | 2 days, 20:44:58 | None |
|
||||
| Facing Glitches On Start Opens 2 Windows for Same tabs. | https://github.com/zen-browser/desktop/issues/12248 | 1:25:01 | None |
|
||||
| Separate windows mirroring | https://github.com/zen-browser/desktop/issues/12247 | 0:12:51 | 0:12:51 |
|
||||
| H.264, HEVC, and AAC Not Supported in Kubuntu App Center Version (1.17.14b) | https://github.com/zen-browser/desktop/issues/12245 | 1 day, 12:07:19 | None |
|
||||
| Private and blank windows ignore CloseWindowWithLastTab setting | https://github.com/zen-browser/desktop/issues/12242 | 9:22:25 | 2 days, 8:59:22 |
|
||||
| Bookmark temporarily removes | https://github.com/zen-browser/desktop/issues/12241 | None | None |
|
||||
| Multiple Windows Launch on Startup after Multiple Windows Have Been Closed | https://github.com/zen-browser/desktop/issues/12238 | 16:04:12 | None |
|
||||
| Duplicated Toggle Full Screen and View Full Screen for keyboard shortcut | https://github.com/zen-browser/desktop/issues/12237 | 10 days, 20:34:41 | 11 days, 11:58:31 |
|
||||
| Container no longer displayed when moving tabs between windows on different spaces | https://github.com/zen-browser/desktop/issues/12235 | 10 days, 13:27:01 | 10 days, 18:33:05 |
|
||||
| Multi account container settings reset | https://github.com/zen-browser/desktop/issues/12234 | None | None |
|
||||
| Clicking the “Copy” button opens an “Open With” dialog on KDE Plasma Wayland. | https://github.com/zen-browser/desktop/issues/12232 | 13 days, 7:34:57 | 14 days, 19:58:57 |
|
||||
| Can't open a new window with clear context | https://github.com/zen-browser/desktop/issues/12229 | None | 0:01:26 |
|
||||
| Can't play DRM content in Linux | https://github.com/zen-browser/desktop/issues/12228 | 4:21:30 | 6:06:50 |
|
||||
| Missing icons in address bar: padlock (https) and star (to bookmark current page) | https://github.com/zen-browser/desktop/issues/12226 | None | 0:08:28 |
|
||||
| Broken extension/browser tools sidebar keybind | https://github.com/zen-browser/desktop/issues/12225 | 5:45:59 | 9 days, 20:16:58 |
|
||||
| Sidebar empty after copying profile from Firefox | https://github.com/zen-browser/desktop/issues/12224 | 0:25:56 | 0:25:56 |
|
||||
| Lost all my folders with the latest update | https://github.com/zen-browser/desktop/issues/12223 | 0:55:54 | 0:55:54 |
|
||||
| History window doesnt follow default system or browser theme | https://github.com/zen-browser/desktop/issues/12222 | None | None |
|
||||
| when i have multiple windows and restart zen , all the windows will be the same , have the same tabs | https://github.com/zen-browser/desktop/issues/12221 | 0:35:11 | 0:22:16 |
|
||||
| Deleting All Data | https://github.com/zen-browser/desktop/issues/12220 | 0:59:01 | None |
|
||||
| Move to Space in Tab Context Menu not available | https://github.com/zen-browser/desktop/issues/12219 | 0:12:00 | None |
|
||||
| When opening Zen after closing multiple windows, only one window has workspaces | https://github.com/zen-browser/desktop/issues/12218 | 0:59:47 | None |
|
||||
| Forms don't allow to be processed | https://github.com/zen-browser/desktop/issues/12217 | 6:15:33 | 6:15:33 |
|
||||
| Cannot drag and drop to create a split view | https://github.com/zen-browser/desktop/issues/12216 | 0:37:06 | 0:37:06 |
|
||||
| Glance does not work via keybind+click in Reader VIew | https://github.com/zen-browser/desktop/issues/12214 | None | None |
|
||||
| "New Blank Window" is not capitalized in Mac OS menu bar | https://github.com/zen-browser/desktop/issues/12213 | None | 7 days, 4:10:17 |
|
||||
| Zen changes tab IDs without sending tabs.onReplaced events | https://github.com/zen-browser/desktop/issues/12212 | 1:12:47 | 1:12:47 |
|
||||
| Private window is adopting Blank windows styling | https://github.com/zen-browser/desktop/issues/12211 | None | 0:19:10 |
|
||||
| The loading indicator on tabs does not appear when a tab is loading. | https://github.com/zen-browser/desktop/issues/12210 | 1:23:55 | 1:23:55 |
|
||||
| Page content cannot scroll fully to top; top area is hidden behind browser UI | https://github.com/zen-browser/desktop/issues/12209 | 13:06:36 | None |
|
||||
| TURN OFF WINDOW SYNC | https://github.com/zen-browser/desktop/issues/12206 | 0:47:53 | 1:23:13 |
|
||||
| Essentials not working correctly | https://github.com/zen-browser/desktop/issues/12205 | 3:18:34 | 3:27:55 |
|
||||
| Tab titles not updating | https://github.com/zen-browser/desktop/issues/12204 | 3:40:45 | 5:54:14 |
|
||||
| Folders disappeared after updating to the Zen version 1.18.3b (Firefox 147.0.2) (aarch64) | https://github.com/zen-browser/desktop/issues/12203 | 9:12:45 | 9:12:45 |
|
||||
| Some websites don't load | https://github.com/zen-browser/desktop/issues/12202 | 1 day, 10:47:54 | None |
|
||||
| Website favicons have the wrong icons | https://github.com/zen-browser/desktop/issues/12201 | 2:36:06 | 0:04:20 |
|
||||
| tab indexes are off by 2 | https://github.com/zen-browser/desktop/issues/12199 | None | 3:02:10 |
|
||||
| Zen doesn't identify itself in the extensions API | https://github.com/zen-browser/desktop/issues/12198 | 1 day, 21:45:16 | 6 days, 22:02:36 |
|
||||
| Part of the screenshot overlay is rendered below glance windows | https://github.com/zen-browser/desktop/issues/12196 | None | 21 days, 5:30:56 |
|
||||
| Glance opens without keyboard shortcut in Essential tabs | https://github.com/zen-browser/desktop/issues/12194 | 8:27:58 | 8:27:58 |
|
||||
| Context menu extensions multiply | https://github.com/zen-browser/desktop/issues/12192 | None | None |
|
||||
| Tab folder not closing properly when a tab is opened | https://github.com/zen-browser/desktop/issues/12190 | None | 10:15:16 |
|
||||
| Can't set a theme | https://github.com/zen-browser/desktop/issues/12189 | 1:38:06 | None |
|
||||
|
||||
_This report was generated with the [Issue Metrics Action](https://github.com/github/issue-metrics)_
|
||||
Search query used to find these items: `repo:zen-browser/desktop is:issue created:2026-02-01..2026-02-28`
|
||||
@@ -47,6 +47,7 @@ pictureinpicture-minimize-btn =
|
||||
zen-panel-ui-gradient-generator-custom-color = Custom Color
|
||||
|
||||
zen-copy-current-url-confirmation = Copied current URL!
|
||||
zen-copy-current-url-as-markdown-confirmation = Copied current URL as Markdown!
|
||||
|
||||
zen-general-cancel-label =
|
||||
.label = Cancel
|
||||
|
||||
@@ -96,3 +96,6 @@ zen-live-folder-github-issues =
|
||||
|
||||
zen-live-folder-github-option-repo-list-note =
|
||||
.label = This list is generated based on your currently active pull requests.
|
||||
|
||||
zen-live-folders-promotion-title = Live Folder Created!
|
||||
zen-live-folders-promotion-description = Latest content from your RSS feeds or GitHub pull requests will appear here automatically.
|
||||
|
||||
1
locales/update-supported-languages.sh
Normal file → Executable file
1
locales/update-supported-languages.sh
Normal file → Executable file
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
LANGS_FILE="./supported-languages"
|
||||
|
||||
# Clean up the file
|
||||
|
||||
4407
package-lock.json
generated
4407
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
35
package.json
35
package.json
@@ -21,9 +21,8 @@
|
||||
"sync:raw": "surfer update",
|
||||
"sync:rc": "python3 scripts/update_ff.py --rc",
|
||||
"sync:l10n": "python3 scripts/update_ff.py --just-l10n",
|
||||
"pretty": "prettier . --write --cache && autopep8 -r --in-place scripts/ src/ --exclude src/zen/tests/",
|
||||
"lint": "npx eslint src/ && prettier . --check --cache",
|
||||
"lint:fix": "npm run pretty && npx eslint src/ --fix",
|
||||
"lint": "cd engine && ./mach lint zen",
|
||||
"lint:fix": "npm run lint -- --fix",
|
||||
"prepare": "husky",
|
||||
"reset-ff": "surfer reset",
|
||||
"surfer": "surfer",
|
||||
@@ -51,32 +50,14 @@
|
||||
"homepage": "https://github.com/zen-browser/desktop#readme",
|
||||
"devDependencies": {
|
||||
"@babel/preset-typescript": "^7.27.0",
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@eslint/json": "^0.14.0",
|
||||
"@microsoft/eslint-plugin-sdl": "^1.1.0",
|
||||
"@zen-browser/surfer": "^1.13.1",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-eslint-plugin": "^7.3.0",
|
||||
"eslint-plugin-html": "^8.1.3",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-jest": "^29.12.1",
|
||||
"eslint-plugin-json": "^4.0.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-lit": "^2.1.1",
|
||||
"eslint-plugin-mozilla": "^4.3.3",
|
||||
"eslint-plugin-no-unsanitized": "4.1.4",
|
||||
"eslint-plugin-promise": "7.2.1",
|
||||
"eslint-plugin-react": "7.37.5",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-spidermonkey-js": "file:tools/eslint-plugin-spidermonkey-js",
|
||||
"@zen-browser/prettier": "^3.9.3",
|
||||
"@zen-browser/surfer": "^1.13.4",
|
||||
"formal-git": "^1.2.9",
|
||||
"globals": "^16.3.0",
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^15.3.0",
|
||||
"prettier": "^3.4.2",
|
||||
"prettier-plugin-sh": "^0.14.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.52.0"
|
||||
}
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"notes(private)": "We don't want to publish to npm, so this is marked as private",
|
||||
"private": true
|
||||
}
|
||||
|
||||
@@ -73,5 +73,9 @@
|
||||
- name: browser.tabs.notes.enabled
|
||||
value: false
|
||||
|
||||
- name: browser.tabs.dragDrop.dragToPin.enabled
|
||||
value: false
|
||||
locked: true
|
||||
|
||||
- name: browser.tabs.dragDrop.moveOverThresholdPercent
|
||||
value: 50 # Percentage of tab height to trigger move over on drag-and-drop
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
- name: browser.search.suggest.enabled.private
|
||||
value: false
|
||||
|
||||
- name: browser.search.separatePrivateDefault.ui.enabled
|
||||
value: true
|
||||
|
||||
- name: browser.urlbar.quicksuggest.enabled
|
||||
value: false
|
||||
locked: true
|
||||
@@ -59,3 +56,8 @@
|
||||
- name: browser.urlbar.suggest.topsites
|
||||
value: true
|
||||
locked: true
|
||||
|
||||
# See https://github.com/zen-browser/desktop/issues/7248
|
||||
# We've submitted a patch to Firefox at https://bugzilla.mozilla.org/show_bug.cgi?id=2018499
|
||||
- name: browser.urlbar.closeOnWindowBlur
|
||||
value: false
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
- name: zen.view.compact.toolbar-hide-after-hover.duration
|
||||
value: 1000
|
||||
|
||||
- name: zen.view.compact.sidebar-keep-hover.duration
|
||||
value: 150
|
||||
|
||||
- name: zen.view.compact.animate-sidebar
|
||||
value: true
|
||||
|
||||
|
||||
@@ -20,3 +20,10 @@
|
||||
cpptype: uint32_t
|
||||
mirror: always
|
||||
type: static
|
||||
|
||||
# Enable native popovers on macOS, we've sent this patch to upstream
|
||||
# but we enable it by default anyways in case they decide to not use it,
|
||||
# or to disable it by default.
|
||||
- name: widget.macos.native-popovers
|
||||
value: true
|
||||
condition: "defined(XP_MACOSX)"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
- name: image.jxl.enabled
|
||||
value: true
|
||||
locked: true
|
||||
|
||||
- name: svg.context-properties.content.enabled
|
||||
value: true
|
||||
|
||||
@@ -10,3 +10,12 @@
|
||||
|
||||
- name: zen.splitView.rearrange-hover-size
|
||||
value: 24
|
||||
|
||||
- name: zen.splitView.enable-drag-over-split
|
||||
value: true
|
||||
|
||||
- name: zen.splitView.drag-over-split-delayMC
|
||||
value: 1000
|
||||
|
||||
- name: zen.splitView.drag-over-split-threshold
|
||||
value: 40
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# 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/.
|
||||
|
||||
[tool.autopep8]
|
||||
max_line_length = 120
|
||||
recursive = true
|
||||
aggressive = 3
|
||||
indent_size = 2
|
||||
@@ -2,7 +2,6 @@
|
||||
# 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/.
|
||||
|
||||
autopep8==2.3.1
|
||||
click==8.1.8
|
||||
mypy-extensions==1.0.0
|
||||
packaging==24.2
|
||||
|
||||
1
scripts/download-language-packs.sh
Normal file → Executable file
1
scripts/download-language-packs.sh
Normal file → Executable file
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# 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/.
|
||||
|
||||
2
scripts/fetch-formal-git-components.sh
Normal file → Executable file
2
scripts/fetch-formal-git-components.sh
Normal file → Executable file
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# 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/.
|
||||
|
||||
5
scripts/recalculate-patches.sh
Normal file → Executable file
5
scripts/recalculate-patches.sh
Normal file → Executable file
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# 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/.
|
||||
@@ -12,6 +12,9 @@ IGNORE_FILES=(
|
||||
"shared.nsh"
|
||||
"ignorePrefs.json"
|
||||
"moz.configure"
|
||||
"AsyncShutdown.sys.mjs"
|
||||
"Info.plist.in"
|
||||
"firefox.js"
|
||||
)
|
||||
|
||||
# Recursively find all .patch files in the current directory and its subdirectories
|
||||
|
||||
2
scripts/remove-failed-jobs.sh
Normal file → Executable file
2
scripts/remove-failed-jobs.sh
Normal file → Executable file
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# 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/.
|
||||
|
||||
2
scripts/update-surfer.sh
Normal file → Executable file
2
scripts/update-surfer.sh
Normal file → Executable file
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# 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/.
|
||||
|
||||
@@ -59,6 +59,15 @@ def main():
|
||||
output_file = os.path.join(OUTPUT_DIR, "firefox", f"{name}.patch")
|
||||
print(f"Processing Phabricator patch: {phab_id} -> {output_file}")
|
||||
download_phab_patch(phab_id, output_file)
|
||||
replaces = patch.get("replaces", {})
|
||||
for replace in replaces.keys():
|
||||
value = replaces[replace]
|
||||
with open(output_file, 'r') as f:
|
||||
content = f.read()
|
||||
if replace not in content:
|
||||
die(f"Replace string '{replace}' not found in {output_file}")
|
||||
with open(output_file, 'w') as f:
|
||||
f.write(content.replace(replace, value))
|
||||
expected_files.add(output_file)
|
||||
elif patch.get("type") == "local":
|
||||
print(f"Local patch: {patch.get('path')}")
|
||||
|
||||
17
src/-prettierignore.patch
Normal file
17
src/-prettierignore.patch
Normal file
@@ -0,0 +1,17 @@
|
||||
diff --git a/.prettierignore b/.prettierignore
|
||||
index cbca8bb4b36cecc44e6b498e9ef15bc4bdc21871..8f3a14e14a2d58875bdd6f04bd31f57e23073148 100644
|
||||
--- a/.prettierignore
|
||||
+++ b/.prettierignore
|
||||
@@ -1795,3 +1795,12 @@ tools/ts/test/baselines/
|
||||
try_task_config.json
|
||||
xpcom/idl-parser/xpidl/fixtures/xpctest.d.json
|
||||
**/package-lock.json
|
||||
+
|
||||
+
|
||||
+*.bundle.min.js
|
||||
+*.min.js
|
||||
+*.min.mjs
|
||||
+*.inc
|
||||
+*/mochitests/*
|
||||
+*.svg
|
||||
+
|
||||
24
src/-stylelintignore.patch
Normal file
24
src/-stylelintignore.patch
Normal file
@@ -0,0 +1,24 @@
|
||||
diff --git a/.stylelintignore b/.stylelintignore
|
||||
index 185490999507b8a5032977237af50f5e61c71df1..e887fafa90b881e852a287ed8898638c995861ab 100644
|
||||
--- a/.stylelintignore
|
||||
+++ b/.stylelintignore
|
||||
@@ -106,3 +106,19 @@ build/pgo/blueprint/**/*.css
|
||||
# under our control or we don't want to modify at this point:
|
||||
testing/web-platform/mozilla/
|
||||
testing/web-platform/tests/
|
||||
+
|
||||
+*.inc.css
|
||||
+
|
||||
+zen/tests/mochitests/*
|
||||
+
|
||||
+# Some CSS files are preprocessed and prettier doesn't handle them well
|
||||
+# We also dont want to format the CSS files that are generated by the build
|
||||
+zen/tabs/zen-tabs.css
|
||||
+zen/common/styles/zen-theme.css
|
||||
+zen/compact-mode/zen-compact-mode.css
|
||||
+
|
||||
+zen/split-view/zen-decks.css
|
||||
+zen/workspaces/zen-workspaces.css
|
||||
+zen/common/styles/zen-toolbar.css
|
||||
+
|
||||
+*.inc
|
||||
25
src/-stylelintrc-js.patch
Normal file
25
src/-stylelintrc-js.patch
Normal file
@@ -0,0 +1,25 @@
|
||||
diff --git a/.stylelintrc.js b/.stylelintrc.js
|
||||
index 36719c9e152c34da2aa76fc74d74e58cb9e6b1cc..4226db2e0af4b36923a93dcd0b76e59f8508ba36 100644
|
||||
--- a/.stylelintrc.js
|
||||
+++ b/.stylelintrc.js
|
||||
@@ -67,7 +67,7 @@ module.exports = {
|
||||
],
|
||||
|
||||
"max-nesting-depth": [
|
||||
- 3,
|
||||
+ 6,
|
||||
{
|
||||
ignore: ["blockless-at-rules"],
|
||||
},
|
||||
@@ -274,9 +274,9 @@ module.exports = {
|
||||
// Remove this line setting `csscontrols/use-logical` to null after implementing fixes
|
||||
"csstools/use-logical": null,
|
||||
"stylelint-plugin-mozilla/no-base-design-tokens": true,
|
||||
- "stylelint-plugin-mozilla/use-design-tokens": true,
|
||||
+ "stylelint-plugin-mozilla/use-design-tokens": false,
|
||||
"stylelint-plugin-mozilla/no-non-semantic-token-usage": true,
|
||||
- "stylelint-plugin-mozilla/use-size-tokens": true,
|
||||
+ "stylelint-plugin-mozilla/use-size-tokens": false,
|
||||
},
|
||||
|
||||
overrides: [
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git a/browser/app/macbuild/Contents/Info.plist.in b/browser/app/macbuild/Contents/Info.plist.in
|
||||
index 0c4fb837a24490c66b284abf2bd9299c2e021de0..ea28831b90662b12bdcb137c35b6bb83626c77e7 100644
|
||||
--- a/browser/app/macbuild/Contents/Info.plist.in
|
||||
+++ b/browser/app/macbuild/Contents/Info.plist.in
|
||||
@@ -190,8 +190,6 @@
|
||||
<string>@MAC_APP_NAME@ @APP_VERSION@</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>firefox.icns</string>
|
||||
- <key>CFBundleIconName</key>
|
||||
- <string>AppIcon</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@MOZ_MACBUNDLE_ID@</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
@@ -1,8 +1,18 @@
|
||||
diff --git a/browser/base/content/browser-box.inc.xhtml b/browser/base/content/browser-box.inc.xhtml
|
||||
index 2faed30e09511c381051bc40910a883d1d7bc10d..6ba2d0d91235ed33e4b4bad281c974b5960beaa2 100644
|
||||
index 2faed30e09511c381051bc40910a883d1d7bc10d..3b8c89902502aa384473dd6f43be7ec49bad06ac 100644
|
||||
--- a/browser/base/content/browser-box.inc.xhtml
|
||||
+++ b/browser/base/content/browser-box.inc.xhtml
|
||||
@@ -25,7 +25,13 @@
|
||||
@@ -3,6 +3,9 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
<hbox flex="1" id="browser">
|
||||
+ <html:div id="zen-browser-background" class="zen-browser-generic-background">
|
||||
+ <html:div class="zen-browser-grain" />
|
||||
+ </html:div>
|
||||
<box context="sidebar-context-menu" id="sidebar-main" hidden="true">
|
||||
<html:sidebar-main flex="1">
|
||||
<box id="vertical-tabs" slot="tabstrip" customizable="true" contextmenu="toolbar-context-menu"></box>
|
||||
@@ -25,7 +28,13 @@
|
||||
</stack>
|
||||
</vbox>
|
||||
<splitter id="sidebar-splitter" class="chromeclass-extrachrome sidebar-splitter" resizebefore="sibling" resizeafter="none" hidden="true"/>
|
||||
@@ -16,7 +26,7 @@ index 2faed30e09511c381051bc40910a883d1d7bc10d..6ba2d0d91235ed33e4b4bad281c974b5
|
||||
<tabpanels id="tabbrowser-tabpanels" flex="1" selectedIndex="0"/>
|
||||
</tabbox>
|
||||
<splitter id="ai-window-splitter" class="chromeclass-extrachrome sidebar-splitter" resizebefore="none" resizeafter="sibling" hidden="true"/>
|
||||
@@ -34,3 +40,5 @@
|
||||
@@ -34,3 +43,5 @@
|
||||
</stack>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml
|
||||
index 4d4223c508560136aba220adb18528aac913a188..7e7432f7adb761a598d3e3e5ca4c6385a3bfe223 100644
|
||||
index 4d4223c508560136aba220adb18528aac913a188..10d4d9cecbb0e7cec9191d78fb81a57376b37ff1 100644
|
||||
--- a/browser/base/content/navigator-toolbox.inc.xhtml
|
||||
+++ b/browser/base/content/navigator-toolbox.inc.xhtml
|
||||
@@ -2,7 +2,7 @@
|
||||
@@ -11,7 +11,7 @@ index 4d4223c508560136aba220adb18528aac913a188..7e7432f7adb761a598d3e3e5ca4c6385
|
||||
<script src="chrome://browser/content/navigator-toolbox.js" />
|
||||
|
||||
<!-- Menu -->
|
||||
@@ -18,9 +18,9 @@
|
||||
@@ -18,9 +18,12 @@
|
||||
#include browser-menubar.inc
|
||||
</toolbaritem>
|
||||
<spacer flex="1" skipintoolbarset="true" style="order: 1000;"/>
|
||||
@@ -19,10 +19,13 @@ index 4d4223c508560136aba220adb18528aac913a188..7e7432f7adb761a598d3e3e5ca4c6385
|
||||
</toolbar>
|
||||
|
||||
+<hbox id="titlebar">
|
||||
+ <html:div id="zen-toolbar-background" class="zen-toolbar-background zen-browser-generic-background">
|
||||
+ <html:div class="zen-browser-grain" />
|
||||
+ </html:div>
|
||||
<toolbar id="TabsToolbar"
|
||||
class="browser-toolbar browser-titlebar"
|
||||
fullscreentoolbar="true"
|
||||
@@ -62,6 +62,9 @@
|
||||
@@ -62,6 +65,9 @@
|
||||
<html:sidebar-pins-promo id="drag-to-pin-promo-card"></html:sidebar-pins-promo>
|
||||
<arrowscrollbox id="pinned-tabs-container" orient="horizontal" clicktoscroll=""></arrowscrollbox>
|
||||
<splitter orient="vertical" id="vertical-pinned-tabs-splitter" resizebefore="sibling" resizeafter="none" hidden="true"/>
|
||||
@@ -32,7 +35,7 @@ index 4d4223c508560136aba220adb18528aac913a188..7e7432f7adb761a598d3e3e5ca4c6385
|
||||
<hbox class="tab-drop-indicator" hidden="true"/>
|
||||
<arrowscrollbox id="tabbrowser-arrowscrollbox" orient="horizontal" flex="1" clicktoscroll="" scrolledtostart="" scrolledtoend="">
|
||||
<tab is="tabbrowser-tab" class="tabbrowser-tab" selected="true" visuallyselected="" fadein=""/>
|
||||
@@ -81,6 +84,7 @@
|
||||
@@ -81,6 +87,7 @@
|
||||
tooltip="dynamic-shortcut-tooltip"
|
||||
data-l10n-id="tabs-toolbar-new-tab"/>
|
||||
<html:span id="tabbrowser-tab-a11y-desc" hidden="true"/>
|
||||
@@ -40,7 +43,7 @@ index 4d4223c508560136aba220adb18528aac913a188..7e7432f7adb761a598d3e3e5ca4c6385
|
||||
</tabs>
|
||||
|
||||
<toolbarbutton id="new-tab-button"
|
||||
@@ -114,9 +118,10 @@
|
||||
@@ -114,9 +121,10 @@
|
||||
|
||||
<toolbarbutton class="content-analysis-indicator toolbarbutton-1 content-analysis-indicator-icon"/>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/base/content/navigator-toolbox.js b/browser/base/content/navigator-toolbox.js
|
||||
index 15469e9d9b91c1eaef2578c9e43b6999edac3392..553402b41bc15f7cd99bf87c54416dc66d7c03e7 100644
|
||||
index 15469e9d9b91c1eaef2578c9e43b6999edac3392..95ae5036b57baeb5237603c0921f1e9252af6919 100644
|
||||
--- a/browser/base/content/navigator-toolbox.js
|
||||
+++ b/browser/base/content/navigator-toolbox.js
|
||||
@@ -6,7 +6,7 @@
|
||||
@@ -19,15 +19,25 @@ index 15469e9d9b91c1eaef2578c9e43b6999edac3392..553402b41bc15f7cd99bf87c54416dc6
|
||||
#picture-in-picture-button,
|
||||
#urlbar-zoom-button,
|
||||
#star-button-box,
|
||||
@@ -206,6 +207,7 @@ document.addEventListener(
|
||||
case "vertical-tabs-newtab-button":
|
||||
case "tabs-newtab-button":
|
||||
case "new-tab-button":
|
||||
+ case "zen-tabs-wrapper":
|
||||
@@ -209,6 +210,17 @@ document.addEventListener(
|
||||
gBrowser.handleNewTabMiddleClick(element, event);
|
||||
break;
|
||||
|
||||
@@ -318,6 +320,7 @@ document.addEventListener(
|
||||
+ case "zen-tabs-wrapper":
|
||||
+ if (event.button == 1) {
|
||||
+ BrowserCommands.openTab();
|
||||
+ // Stop the propagation of the click event, to prevent the event from being
|
||||
+ // handled more than once.
|
||||
+ // E.g. see https://bugzilla.mozilla.org/show_bug.cgi?id=1657992#c4
|
||||
+ event.stopPropagation();
|
||||
+ event.preventDefault();
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
case "back-button":
|
||||
case "forward-button":
|
||||
case "reload-button":
|
||||
@@ -318,6 +330,7 @@ document.addEventListener(
|
||||
#downloads-button,
|
||||
#fxa-toolbar-menu-button,
|
||||
#unified-extensions-button,
|
||||
@@ -35,7 +45,7 @@ index 15469e9d9b91c1eaef2578c9e43b6999edac3392..553402b41bc15f7cd99bf87c54416dc6
|
||||
#library-button,
|
||||
#split-view-button
|
||||
`);
|
||||
@@ -401,6 +404,16 @@ document.addEventListener(
|
||||
@@ -401,6 +414,16 @@ document.addEventListener(
|
||||
gUnifiedExtensions.togglePanel(event);
|
||||
break;
|
||||
|
||||
|
||||
@@ -41,14 +41,13 @@
|
||||
<script type="text/javascript" src="chrome://browser/content/ZenPreloadedScripts.js"></script>
|
||||
|
||||
# Scripts used all over the browser
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenFolder.mjs"></script>
|
||||
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenMediaController.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenWorkspaceCreation.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenGlanceManager.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenPinnedTabManager.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenViewSplitter.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenFolders.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenFolder.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenFolders.mjs"></script>s
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenDownloadAnimation.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenEmojiPicker.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenLiveFoldersUI.mjs"></script>
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
# 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/.
|
||||
|
||||
<panel id="zen-folder-tabs-popup" type="arrow" orient="vertical" side="left">
|
||||
<panel id="zen-folder-tabs-popup"
|
||||
nonnativepopover="true"
|
||||
type="arrow"
|
||||
orient="vertical"
|
||||
side="left"
|
||||
consumeoutsideclicks="never">
|
||||
<hbox class="tabs-list-header" flex="1">
|
||||
<image class="zen-folder-tabs-list-search-icon" src="chrome://global/skin/icons/search-glass.svg"/>
|
||||
<html:input id="zen-folder-tabs-list-search"
|
||||
|
||||
@@ -2,7 +2,14 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
<panel flip="side" type="arrow" popupalign="center" orient="vertical" id="PanelUI-zen-gradient-generator" position="bottomright topright" mainview="true" side="left">
|
||||
<panel flip="side" type="arrow"
|
||||
opupalign="center"
|
||||
orient="vertical"
|
||||
id="PanelUI-zen-gradient-generator"
|
||||
position="bottomright topright"
|
||||
mainview="true"
|
||||
hidepopovertail="true"
|
||||
side="left">
|
||||
<panelmultiview id="PanelUI-zen-gradient-generator-multiview" mainViewId="PanelUI-zen-gradient-generator-view">
|
||||
<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">
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
<menuitem
|
||||
data-l10n-id="zen-live-folder-github-pull-requests"
|
||||
command="cmd_zenNewLiveFolder"
|
||||
image="chrome://browser/content/zen-images/favicons/github.svg" />
|
||||
image="chrome://browser/skin/zen-icons/selectable/logo-github.svg" />
|
||||
<menuitem
|
||||
data-l10n-id="zen-live-folder-github-issues"
|
||||
command="cmd_zenNewLiveFolder"
|
||||
image="chrome://browser/content/zen-images/favicons/github.svg" />
|
||||
image="chrome://browser/skin/zen-icons/selectable/logo-github.svg" />
|
||||
<menuitem
|
||||
data-l10n-id="zen-live-folder-type-rss"
|
||||
command="cmd_zenNewLiveFolder"
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
diff --git a/browser/components/aboutwelcome/content/aboutwelcome.css b/browser/components/aboutwelcome/content/aboutwelcome.css
|
||||
index 0e1985aa519d66b047c5d40977bb12099d966b18..76b59891b4c4464b38d6973858f13fff0285737d 100644
|
||||
--- a/browser/components/aboutwelcome/content/aboutwelcome.css
|
||||
+++ b/browser/components/aboutwelcome/content/aboutwelcome.css
|
||||
@@ -329,6 +329,11 @@ panel#feature-callout {
|
||||
--panel-shadow-margin: 6px;
|
||||
--panel-arrow-space: calc(var(--panel-shadow-margin) + var(--arrow-visible-height) - 1.5px);
|
||||
--panel-margin-offset: calc(-1 * (var(--panel-shadow-margin) + var(--arrow-corner-distance) + (var(--arrow-width) / 2)));
|
||||
+
|
||||
+ @media -moz-pref("widget.macos.native-popovers") and (-moz-platform: macos) {
|
||||
+ --panel-shadow-margin: 0;
|
||||
+ --panel-arrow-space: 0;
|
||||
+ }
|
||||
}
|
||||
|
||||
panel#feature-callout::part(content) {
|
||||
@@ -512,6 +517,12 @@ div#feature-callout.hidden {
|
||||
width: 25em;
|
||||
gap: 16px;
|
||||
background: var(--fc-background);
|
||||
+
|
||||
+ @media -moz-pref("widget.macos.native-popovers") and (-moz-platform: macos) {
|
||||
+ --fc-background: transparent;
|
||||
+ box-shadow: none;
|
||||
+ border-width: 0;
|
||||
+ }
|
||||
}
|
||||
#feature-callout .screen[pos=callout] .section-main .main-content .main-content-inner {
|
||||
gap: 12px;
|
||||
@@ -818,6 +829,10 @@ panel#feature-callout::part(content) {
|
||||
overflow: visible;
|
||||
transform: rotate(45deg);
|
||||
transform-style: preserve-3d;
|
||||
+
|
||||
+ @media -moz-pref("widget.macos.native-popovers") and (-moz-platform: macos) {
|
||||
+ display: none;
|
||||
+ }
|
||||
}
|
||||
#feature-callout:not([arrow-position]) .arrow-box, #feature-callout[hide-arrow] .arrow-box {
|
||||
display: none;
|
||||
@@ -0,0 +1,57 @@
|
||||
diff --git a/browser/components/preferences/config/aiFeatures.mjs b/browser/components/preferences/config/aiFeatures.mjs
|
||||
index f00c1e20a8ca06108fc41c97badd234167430aee..f7d553cc10492f9447c7b0f801f36b2d66b95d43 100644
|
||||
--- a/browser/components/preferences/config/aiFeatures.mjs
|
||||
+++ b/browser/components/preferences/config/aiFeatures.mjs
|
||||
@@ -634,52 +634,6 @@ SettingGroupManager.registerGroups({
|
||||
},
|
||||
],
|
||||
},
|
||||
- {
|
||||
- control: "moz-box-item",
|
||||
- items: [
|
||||
- {
|
||||
- id: "aiControlPdfjsAltTextSelect",
|
||||
- l10nId: "preferences-ai-controls-pdfjs-control",
|
||||
- control: "moz-select",
|
||||
- controlAttrs: {
|
||||
- inputlayout: "inline-end",
|
||||
- },
|
||||
- supportPage: "pdf-alt-text",
|
||||
- options: [...AI_CONTROL_OPTIONS],
|
||||
- },
|
||||
- ],
|
||||
- },
|
||||
- {
|
||||
- control: "moz-box-item",
|
||||
- items: [
|
||||
- {
|
||||
- id: "aiControlSmartTabGroupsSelect",
|
||||
- l10nId:
|
||||
- "preferences-ai-controls-tab-group-suggestions-control",
|
||||
- control: "moz-select",
|
||||
- controlAttrs: {
|
||||
- inputlayout: "inline-end",
|
||||
- },
|
||||
- supportPage: "how-use-ai-enhanced-tab-groups",
|
||||
- options: [...AI_CONTROL_OPTIONS],
|
||||
- },
|
||||
- ],
|
||||
- },
|
||||
- {
|
||||
- control: "moz-box-item",
|
||||
- items: [
|
||||
- {
|
||||
- id: "aiControlLinkPreviewKeyPointsSelect",
|
||||
- l10nId: "preferences-ai-controls-key-points-control",
|
||||
- control: "moz-select",
|
||||
- controlAttrs: {
|
||||
- inputlayout: "inline-end",
|
||||
- },
|
||||
- supportPage: "use-link-previews-firefox",
|
||||
- options: [...AI_CONTROL_OPTIONS],
|
||||
- },
|
||||
- ],
|
||||
- },
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/tabbrowser/content/tab.js b/browser/components/tabbrowser/content/tab.js
|
||||
index 836bee14d2b63604688ebe477a5d915a5e99b305..a675aed711560b4a44604fc17478cffa7fb68439 100644
|
||||
index 836bee14d2b63604688ebe477a5d915a5e99b305..7e105a1ae07657b0a0e664a8e3d9d2eb894fa1d4 100644
|
||||
--- a/browser/components/tabbrowser/content/tab.js
|
||||
+++ b/browser/components/tabbrowser/content/tab.js
|
||||
@@ -21,6 +21,7 @@
|
||||
@@ -65,11 +65,11 @@ index 836bee14d2b63604688ebe477a5d915a5e99b305..a675aed711560b4a44604fc17478cffa
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Selected tabs are always visible
|
||||
+ if (this.selected || this.multiselected || this.hasAttribute("folder-active")) return true;
|
||||
+ if (this.selected || this.multiselected) return true;
|
||||
+ // Recursively check all parent groups
|
||||
+ let currentParent = this.group;
|
||||
+ while (currentParent) {
|
||||
+ if (currentParent.collapsed) {
|
||||
+ if (currentParent.collapsed && !currentParent.activeTabs?.includes(this)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ currentParent = currentParent.group;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
index d7765e0adb37216d35f2125abf96025cbb150bab..27202066cef98d9826884806f71e70812457bd78 100644
|
||||
index d7765e0adb37216d35f2125abf96025cbb150bab..d787c39f68ea4507b2cb902df325498dd65b1fba 100644
|
||||
--- a/browser/components/tabbrowser/content/tabbrowser.js
|
||||
+++ b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
@@ -405,6 +405,7 @@
|
||||
@@ -411,9 +411,12 @@ index d7765e0adb37216d35f2125abf96025cbb150bab..27202066cef98d9826884806f71e7081
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4122,7 +4247,7 @@
|
||||
@@ -4120,9 +4245,9 @@
|
||||
}
|
||||
|
||||
// Add a new tab if needed.
|
||||
if (!tab) {
|
||||
- if (!tab) {
|
||||
+ if (!tab || tab?._markedForReplacement) {
|
||||
let createLazyBrowser =
|
||||
- restoreTabsLazily && !select && !tabData.pinned;
|
||||
+ restoreTabsLazily && !(tabData.pinned && !Services.prefs.getBoolPref("browser.sessionstore.restore_pinned_tabs_on_demand"));
|
||||
@@ -470,10 +473,10 @@ index d7765e0adb37216d35f2125abf96025cbb150bab..27202066cef98d9826884806f71e7081
|
||||
+ gZenWorkspaces._initialTab._shouldRemove = true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
+ else {
|
||||
+ gZenWorkspaces._tabToRemoveForEmpty = this.selectedTab;
|
||||
}
|
||||
+ }
|
||||
+ this._hasAlreadyInitializedZenSessionStore = true;
|
||||
|
||||
if (tabs.length > 1 || !tabs[0].selected) {
|
||||
@@ -605,7 +608,7 @@ index d7765e0adb37216d35f2125abf96025cbb150bab..27202066cef98d9826884806f71e7081
|
||||
aTab._closeTimeAnimTimerId = null;
|
||||
- this._endRemoveTab(aTab);
|
||||
+ if (animate && !gReduceMotion && !(gZenUIManager.testingEnabled && !gZenUIManager.profilingEnabled)) {
|
||||
+ gZenVerticalTabsManager.animateTabClose(aTab, (animate && !gReduceMotion)).then(() => {
|
||||
+ gZenVerticalTabsManager.animateItemClose(aTab, (animate && !gReduceMotion)).then(() => {
|
||||
+ this._endRemoveTab(aTab);
|
||||
+ });
|
||||
+ } else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js
|
||||
index ebcc072abca51ba9936d0e6d97bbd329427c0231..62e8209bbc38fb209340279e5ed3e2cc2441c48c 100644
|
||||
index ebcc072abca51ba9936d0e6d97bbd329427c0231..2b0980a745e2339d3220bb701092f4f621876985 100644
|
||||
--- a/browser/components/tabbrowser/content/tabgroup.js
|
||||
+++ b/browser/components/tabbrowser/content/tabgroup.js
|
||||
@@ -14,11 +14,11 @@
|
||||
@@ -100,7 +100,17 @@ index ebcc072abca51ba9936d0e6d97bbd329427c0231..62e8209bbc38fb209340279e5ed3e2cc
|
||||
|
||||
resetDefaultGroupName = () => {
|
||||
this.#defaultGroupName = "";
|
||||
@@ -211,7 +234,10 @@
|
||||
@@ -166,7 +189,9 @@
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("TabGroupRemoved", { bubbles: true })
|
||||
);
|
||||
+ gZenVerticalTabsManager.animateItemClose(this).then(() => {
|
||||
this.remove();
|
||||
+ });
|
||||
Services.obs.notifyObservers(
|
||||
this,
|
||||
"browser-tabgroup-removed-from-dom"
|
||||
@@ -211,7 +236,10 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -112,7 +122,7 @@ index ebcc072abca51ba9936d0e6d97bbd329427c0231..62e8209bbc38fb209340279e5ed3e2cc
|
||||
}
|
||||
|
||||
get color() {
|
||||
@@ -305,6 +331,9 @@
|
||||
@@ -305,6 +333,9 @@
|
||||
}
|
||||
|
||||
set collapsed(val) {
|
||||
@@ -122,7 +132,7 @@ index ebcc072abca51ba9936d0e6d97bbd329427c0231..62e8209bbc38fb209340279e5ed3e2cc
|
||||
if (!!val == this.collapsed) {
|
||||
return;
|
||||
}
|
||||
@@ -391,7 +420,6 @@
|
||||
@@ -391,7 +422,6 @@
|
||||
tabGroupName,
|
||||
})
|
||||
.then(result => {
|
||||
@@ -130,7 +140,7 @@ index ebcc072abca51ba9936d0e6d97bbd329427c0231..62e8209bbc38fb209340279e5ed3e2cc
|
||||
});
|
||||
}
|
||||
|
||||
@@ -466,13 +494,65 @@
|
||||
@@ -466,13 +496,65 @@
|
||||
* @returns {MozTabbrowserTab[]}
|
||||
*/
|
||||
get tabs() {
|
||||
@@ -145,9 +155,8 @@ index ebcc072abca51ba9936d0e6d97bbd329427c0231..62e8209bbc38fb209340279e5ed3e2cc
|
||||
+ tabsCollect.push(item);
|
||||
+ if (gBrowser.isTabGroup(item)) {
|
||||
+ tabsCollect.push(...item.tabs);
|
||||
}
|
||||
}
|
||||
- return childrenArray.filter(node => node.matches("tab"));
|
||||
+ }
|
||||
+ }
|
||||
+ return tabsCollect.filter(node => node.matches("tab"));
|
||||
+ }
|
||||
+
|
||||
@@ -173,8 +182,9 @@ index ebcc072abca51ba9936d0e6d97bbd329427c0231..62e8209bbc38fb209340279e5ed3e2cc
|
||||
+ result.push(labelContainer);
|
||||
+ }
|
||||
+ result.push(...item.childGroupsAndTabs);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
- return childrenArray.filter(node => node.matches("tab"));
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
@@ -201,7 +211,7 @@ index ebcc072abca51ba9936d0e6d97bbd329427c0231..62e8209bbc38fb209340279e5ed3e2cc
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -569,7 +649,6 @@
|
||||
@@ -569,7 +651,6 @@
|
||||
);
|
||||
} else {
|
||||
if (tabOrSplitView.pinned) {
|
||||
@@ -209,7 +219,7 @@ index ebcc072abca51ba9936d0e6d97bbd329427c0231..62e8209bbc38fb209340279e5ed3e2cc
|
||||
}
|
||||
let tabToMove =
|
||||
this.ownerGlobal === tabOrSplitView.ownerGlobal
|
||||
@@ -634,7 +713,7 @@
|
||||
@@ -634,7 +715,7 @@
|
||||
*/
|
||||
on_click(event) {
|
||||
let isToggleElement =
|
||||
@@ -218,7 +228,7 @@ index ebcc072abca51ba9936d0e6d97bbd329427c0231..62e8209bbc38fb209340279e5ed3e2cc
|
||||
event.target === this.#overflowCountLabel;
|
||||
if (isToggleElement && event.button === 0) {
|
||||
event.preventDefault();
|
||||
@@ -705,5 +784,6 @@
|
||||
@@ -705,5 +786,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -501,6 +501,9 @@ groupbox h2 {
|
||||
#support-firefox,
|
||||
#tabGroupSuggestions,
|
||||
#web-appearance-manage-themes-link,
|
||||
#setting-control-sidebarChatbotFieldset,
|
||||
#aiControlsDescription,
|
||||
#category-ai-features,
|
||||
.mission-message {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
# 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/.
|
||||
<svg fill="context-fill" fill-opacity="context-fill-opacity" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><path d="M256 32C132.3 32 32 134.9 32 261.7c0 101.5 64.2 187.5 153.2 217.9a17.56 17.56 0 003.8.4c8.3 0 11.5-6.1 11.5-11.4 0-5.5-.2-19.9-.3-39.1a102.4 102.4 0 01-22.6 2.7c-43.1 0-52.9-33.5-52.9-33.5-10.2-26.5-24.9-33.6-24.9-33.6-19.5-13.7-.1-14.1 1.4-14.1h.1c22.5 2 34.3 23.8 34.3 23.8 11.2 19.6 26.2 25.1 39.6 25.1a63 63 0 0025.6-6c2-14.8 7.8-24.9 14.2-30.7-49.7-5.8-102-25.5-102-113.5 0-25.1 8.7-45.6 23-61.6-2.3-5.8-10-29.2 2.2-60.8a18.64 18.64 0 015-.5c8.1 0 26.4 3.1 56.6 24.1a208.21 208.21 0 01112.2 0c30.2-21 48.5-24.1 56.6-24.1a18.64 18.64 0 015 .5c12.2 31.6 4.5 55 2.2 60.8 14.3 16.1 23 36.6 23 61.6 0 88.2-52.4 107.6-102.3 113.3 8 7.1 15.2 21.1 15.2 42.5 0 30.7-.3 55.5-.3 63 0 5.4 3.1 11.5 11.4 11.5a19.35 19.35 0 004-.4C415.9 449.2 480 363.1 480 261.7 480 134.9 379.7 32 256 32z"/></svg>
|
||||
<svg fill="context-fill" fill-opacity="context-fill-opacity" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><path d="M219.797 355.243c-60.522-7.339-103.146-50.88-103.146-107.264 0-22.912 8.256-47.68 21.994-64.171-5.952-15.125-5.034-47.232 1.835-60.523 18.347-2.282 43.093 7.339 57.771 20.63 17.408-5.504 35.754-8.235 58.197-8.235s40.811 2.731 57.301 7.787c14.208-12.843 39.424-22.464 57.771-20.182 6.4 12.395 7.339 44.48 1.365 60.054 14.678 17.429 22.464 40.81 22.464 64.64 0 56.384-42.624 99.008-104.042 106.794 15.573 10.091 26.112 32.086 26.112 57.302v47.68c0 13.738 11.456 21.546 25.216 16.042 82.965-31.637 148.053-114.602 148.053-217.28 0-129.728-105.429-235.605-235.136-235.605-129.728 0-234.24 105.877-234.24 235.605a231.255 231.255 0 0 0 151.723 217.728c12.373 4.587 24.298-3.669 24.298-16.042v-36.672a59.7 59.7 0 0 1-22.016 4.586c-30.25 0-48.128-16.49-60.949-47.21-5.056-12.374-10.56-19.712-21.099-21.078-5.504-.469-7.338-2.752-7.338-5.504 0-5.504 9.173-9.621 18.346-9.621 13.291 0 24.747 8.235 36.672 25.195 9.174 13.29 18.795 19.264 30.251 19.264s18.795-4.139 29.333-14.678c7.787-7.786 13.76-14.656 19.264-19.242"/></svg>
|
||||
@@ -499,7 +499,7 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:is([open], [starred]) image {
|
||||
&:where([starred]) image {
|
||||
list-style-image: url("permissions-fill.svg");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# 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/.
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
diff --git a/devtools/server/actors/animation-type-longhand.js b/devtools/server/actors/animation-type-longhand.js
|
||||
index f6cd7b4599ab74fbdc301f316fd7ecc2e2eb841c..8279a943803ca75fe0a231606ae26a678fcc0b60 100644
|
||||
--- a/devtools/server/actors/animation-type-longhand.js
|
||||
+++ b/devtools/server/actors/animation-type-longhand.js
|
||||
@@ -342,6 +342,7 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
|
||||
"transform-origin",
|
||||
"translate",
|
||||
"-moz-window-transform",
|
||||
+ "-zen-window-transform-origin",
|
||||
"-webkit-line-clamp",
|
||||
]),
|
||||
],
|
||||
@@ -1,50 +0,0 @@
|
||||
diff --git a/dom/base/use_counter_metrics.yaml b/dom/base/use_counter_metrics.yaml
|
||||
index 84aa1ac40d01bc73f5039bd5c589c3fdf3a6c8ce..090f9e1eef46ed45c0a98a73013ad59faeb3414f 100644
|
||||
--- a/dom/base/use_counter_metrics.yaml
|
||||
+++ b/dom/base/use_counter_metrics.yaml
|
||||
@@ -22106,6 +22106,22 @@ use.counter.css.page:
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
+ css_zen_window_transform_origin:
|
||||
+ type: counter
|
||||
+ description: >
|
||||
+ Whether a page used the CSS property -zen-window-transform-origin.
|
||||
+ Compare against `use.counter.top_level_content_documents_destroyed`
|
||||
+ to calculate the rate.
|
||||
+ bugs:
|
||||
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
+ data_reviews:
|
||||
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
+ notification_emails:
|
||||
+ - dom-core@mozilla.com
|
||||
+ expires: never
|
||||
+ send_in_pings:
|
||||
+ - use-counters
|
||||
+
|
||||
css_transform_origin:
|
||||
type: counter
|
||||
description: >
|
||||
@@ -34076,6 +34092,22 @@ use.counter.css.doc:
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
+ css_zen_window_transform_origin:
|
||||
+ type: counter
|
||||
+ description: >
|
||||
+ Whether a document used the CSS property -zen-window-transform-origin.
|
||||
+ Compare against `use.counter.content_documents_destroyed`
|
||||
+ to calculate the rate.
|
||||
+ bugs:
|
||||
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
+ data_reviews:
|
||||
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
+ notification_emails:
|
||||
+ - dom-core@mozilla.com
|
||||
+ expires: never
|
||||
+ send_in_pings:
|
||||
+ - use-counters
|
||||
+
|
||||
css_transform_origin:
|
||||
type: counter
|
||||
description: >
|
||||
22
src/eslint-file-globals-config-mjs.patch
Normal file
22
src/eslint-file-globals-config-mjs.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
diff --git a/eslint-file-globals.config.mjs b/eslint-file-globals.config.mjs
|
||||
index 00e49fce00efecab254aa1b8f0f0fe9ed2c24057..e9f390e15537d3d03a87f1c87099cb34698aee49 100644
|
||||
--- a/eslint-file-globals.config.mjs
|
||||
+++ b/eslint-file-globals.config.mjs
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
import globals from "globals";
|
||||
import mozilla from "eslint-plugin-mozilla";
|
||||
+import zenGlobals from "./zen/zen.globals.mjs";
|
||||
|
||||
export default [
|
||||
{
|
||||
@@ -550,4 +551,9 @@ export default [
|
||||
],
|
||||
languageOptions: { globals: globals.worker },
|
||||
},
|
||||
+ {
|
||||
+ name: "zen-globals",
|
||||
+ files: ["zen/**/!(*.sys).mjs", "zen/**/*.js"],
|
||||
+ languageOptions: { globals: zenGlobals.reduce((acc, name) => ({ ...acc, [name]: "readonly" }), {}) },
|
||||
+ }
|
||||
];
|
||||
13
src/eslint-ignores-config-mjs.patch
Normal file
13
src/eslint-ignores-config-mjs.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/eslint-ignores.config.mjs b/eslint-ignores.config.mjs
|
||||
index 0cfd7e02ad58c331f48f1ba8e1588777e1ce2595..888674b5ed2b68dbe77eb177ba0947f94ed57c80 100644
|
||||
--- a/eslint-ignores.config.mjs
|
||||
+++ b/eslint-ignores.config.mjs
|
||||
@@ -312,4 +312,8 @@ export default [
|
||||
// Test files for circular import in modules.
|
||||
"dom/base/test/jsmodules/import_circular.mjs",
|
||||
"dom/base/test/jsmodules/import_circular_1.mjs",
|
||||
+
|
||||
+ "zen/common/emojis/ZenEmojisData.min.mjs",
|
||||
+ "zen/tests/**",
|
||||
+ "zen/vendor/**",
|
||||
];
|
||||
12
src/eslint-test-paths-config-mjs.patch
Normal file
12
src/eslint-test-paths-config-mjs.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/eslint-test-paths.config.mjs b/eslint-test-paths.config.mjs
|
||||
index 53d97521a676d04212abb0263cb166da06c889e0..fa8c261de7a8663a369fb41671476d314722c025 100644
|
||||
--- a/eslint-test-paths.config.mjs
|
||||
+++ b/eslint-test-paths.config.mjs
|
||||
@@ -218,6 +218,7 @@ const extraBrowserTestPaths = [
|
||||
"toolkit/components/windowwatcher/test/",
|
||||
"toolkit/mozapps/extensions/test/xpinstall/",
|
||||
"uriloader/exthandler/tests/mochitest/",
|
||||
+ "zen/tests/",
|
||||
];
|
||||
|
||||
// DO NOT add more items to this list. Please see the note at the top
|
||||
@@ -0,0 +1,75 @@
|
||||
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/UrlbarView.sys.mjs b/browser/components/urlbar/UrlbarView.sys.mjs
|
||||
--- a/browser/components/urlbar/UrlbarView.sys.mjs
|
||||
+++ b/browser/components/urlbar/UrlbarView.sys.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
|
||||
@@ -4783,10 +4783,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
_on_blur(event) {
|
||||
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
|
||||
|
||||
677
src/external-patches/firefox/native_macos_popovers.patch
Normal file
677
src/external-patches/firefox/native_macos_popovers.patch
Normal file
@@ -0,0 +1,677 @@
|
||||
diff --git a/browser/base/content/main-popupset.inc.xhtml b/browser/base/content/main-popupset.inc.xhtml
|
||||
--- a/browser/base/content/main-popupset.inc.xhtml
|
||||
+++ b/browser/base/content/main-popupset.inc.xhtml
|
||||
@@ -193,10 +193,11 @@
|
||||
<!-- Starting point for selection actions -->
|
||||
<panel class="panel-no-padding"
|
||||
id="selection-shortcut-action-panel"
|
||||
noautofocus="true"
|
||||
consumeoutsideclicks="never"
|
||||
+ nonnativepopover="true"
|
||||
type="arrow">
|
||||
<hbox class="panel-subview-body">
|
||||
<html:moz-button id="ai-action-button"/>
|
||||
</hbox>
|
||||
</panel>
|
||||
@@ -204,10 +205,11 @@
|
||||
|
||||
<!-- Shortcut options for Gen AI action -->
|
||||
<panel class="panel-no-padding"
|
||||
id="chat-shortcuts-options-panel"
|
||||
noautofocus="true"
|
||||
+ nonnativepopover="true"
|
||||
type="arrow">
|
||||
<vbox class="panel-subview-body"/>
|
||||
</panel>
|
||||
|
||||
<html:template id="screenshotsPagePanelTemplate">
|
||||
@@ -556,10 +558,11 @@
|
||||
type="arrow"
|
||||
orient="vertical"
|
||||
noautofocus="true"
|
||||
norolluponanchor="true"
|
||||
consumeoutsideclicks="false"
|
||||
+ nonnativepopover="true"
|
||||
role="tooltip">
|
||||
<html:div class="tab-preview-text-container">
|
||||
<html:div class="tab-preview-title"></html:div>
|
||||
<html:div class="tab-preview-uri"></html:div>
|
||||
<html:div class="tab-preview-pid-activeness">
|
||||
diff --git a/browser/components/asrouter/modules/FeatureCallout.sys.mjs b/browser/components/asrouter/modules/FeatureCallout.sys.mjs
|
||||
--- a/browser/components/asrouter/modules/FeatureCallout.sys.mjs
|
||||
+++ b/browser/components/asrouter/modules/FeatureCallout.sys.mjs
|
||||
@@ -1046,10 +1046,11 @@
|
||||
noautofocus="true"
|
||||
flip="slide"
|
||||
type="arrow"
|
||||
consumeoutsideclicks="never"
|
||||
norolluponanchor="true"
|
||||
+
|
||||
position="${panel_position.panel_position_string}"
|
||||
${hide_arrow ? "" : 'show-arrow=""'}
|
||||
${autohide ? "" : 'noautohide="true"'}
|
||||
${ignorekeys ? 'ignorekeys="true"' : ""}
|
||||
${no_open_on_anchor ? 'no-open-on-anchor=""' : ""}
|
||||
diff --git a/browser/components/customizableui/content/panelUI.inc.xhtml b/browser/components/customizableui/content/panelUI.inc.xhtml
|
||||
--- a/browser/components/customizableui/content/panelUI.inc.xhtml
|
||||
+++ b/browser/components/customizableui/content/panelUI.inc.xhtml
|
||||
@@ -276,10 +276,11 @@
|
||||
role="group"
|
||||
type="arrow"
|
||||
hidden="true"
|
||||
flip="slide"
|
||||
position="bottomright topright"
|
||||
+ hidepopovertail="true"
|
||||
noautofocus="true">
|
||||
<panelmultiview id="appMenu-multiView" mainViewId="appMenu-mainView"
|
||||
viewCacheId="appMenu-viewCache">
|
||||
</panelmultiview>
|
||||
</panel>
|
||||
diff --git a/dom/xul/XULPopupElement.cpp b/dom/xul/XULPopupElement.cpp
|
||||
--- a/dom/xul/XULPopupElement.cpp
|
||||
+++ b/dom/xul/XULPopupElement.cpp
|
||||
@@ -84,10 +84,15 @@
|
||||
|
||||
void XULPopupElement::OpenPopupAtScreen(int32_t aXPos, int32_t aYPos,
|
||||
bool aIsContextMenu,
|
||||
Event* aTriggerEvent) {
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
+ // TODO(cheff): We do the same at nsCocoaWindow::Show but it doesn't seem
|
||||
+ // to trigger a restyle so `appearance: auto` doesn't apply the native
|
||||
+ // popover style. We should remove this and use the other implementation
|
||||
+ // because this is a bit of a hack, not sure how reliable it is.
|
||||
+ SetXULBoolAttr(nsGkAtoms::nonnativepopover, true, IgnoreErrors());
|
||||
if (pm) {
|
||||
pm->ShowPopupAtScreen(this, aXPos, aYPos, aIsContextMenu, aTriggerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,10 +101,14 @@
|
||||
int32_t aWidth, int32_t aHeight,
|
||||
bool aIsContextMenu,
|
||||
bool aAttributesOverride,
|
||||
Event* aTriggerEvent) {
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
+ // TODO: See OpenPopupAtScreen. We should remove this and use the other
|
||||
+ // implementation because this is a bit of a hacky way to determine whether to
|
||||
+ // use a native popover or not.
|
||||
+ SetXULBoolAttr(nsGkAtoms::nonnativepopover, true, IgnoreErrors());
|
||||
if (pm) {
|
||||
pm->ShowPopupAtScreenRect(
|
||||
this, aPosition, nsIntRect(aXPos, aYPos, aWidth, aHeight),
|
||||
aIsContextMenu, aAttributesOverride, aTriggerEvent);
|
||||
}
|
||||
diff --git a/layout/xul/nsMenuPopupFrame.h b/layout/xul/nsMenuPopupFrame.h
|
||||
--- a/layout/xul/nsMenuPopupFrame.h
|
||||
+++ b/layout/xul/nsMenuPopupFrame.h
|
||||
@@ -516,18 +516,10 @@
|
||||
|
||||
// Move the popup to the position specified in its |left| and |top|
|
||||
// attributes.
|
||||
void MoveToAttributePosition();
|
||||
|
||||
- // Returns true if the popup should try to remain at the same relative
|
||||
- // location as the anchor while it is open. If the anchor becomes hidden
|
||||
- // either directly or indirectly because a parent popup or other element
|
||||
- // is no longer visible, or a parent deck page is changed, the popup hides
|
||||
- // as well. The second variation also sets the anchor rectangle, relative to
|
||||
- // the popup frame.
|
||||
- bool ShouldFollowAnchor() const;
|
||||
-
|
||||
nsIFrame* GetAnchorFrame() const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Return whether the popup direction should be RTL.
|
||||
@@ -536,10 +528,18 @@
|
||||
*
|
||||
* Return whether the popup direction should be RTL.
|
||||
*/
|
||||
bool IsDirectionRTL() const;
|
||||
|
||||
+ // Returns true if the popup should try to remain at the same relative
|
||||
+ // location as the anchor while it is open. If the anchor becomes hidden
|
||||
+ // either directly or indirectly because a parent popup or other element
|
||||
+ // is no longer visible, or a parent deck page is changed, the popup hides
|
||||
+ // as well. The second variation also sets the anchor rectangle, relative to
|
||||
+ // the popup frame.
|
||||
+ bool ShouldFollowAnchor() const;
|
||||
+
|
||||
bool ShouldFollowAnchor(nsRect& aRect);
|
||||
|
||||
// Returns parent menu widget for submenus that are in the same
|
||||
// frame hierarchy, it's needed for Linux/Wayland which demands
|
||||
// strict popup windows hierarchy.
|
||||
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
|
||||
--- a/modules/libpref/init/StaticPrefList.yaml
|
||||
+++ b/modules/libpref/init/StaticPrefList.yaml
|
||||
@@ -19311,10 +19311,19 @@
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
|
||||
+# If true, use native NSPopover for arrow panel popups (type="arrow") on macOS
|
||||
+# Someone like Zen browser will use this pref by default, so
|
||||
+# please take this into account when you change the behavior of
|
||||
+# native popover. Note: Only panels with type="arrow" will use NSPopover.
|
||||
+- name: widget.macos.native-popovers
|
||||
+ type: RelaxedAtomicBool
|
||||
+ value: false
|
||||
+ mirror: always
|
||||
+
|
||||
# Whether to shift by the menubar height on fullscreen mode.
|
||||
# 0: never
|
||||
# 1: always
|
||||
# 2: auto (tries to detect when it is needed)
|
||||
- name: widget.macos.shift-by-menubar-on-fullscreen
|
||||
diff --git a/toolkit/themes/shared/global-shared.css b/toolkit/themes/shared/global-shared.css
|
||||
--- a/toolkit/themes/shared/global-shared.css
|
||||
+++ b/toolkit/themes/shared/global-shared.css
|
||||
@@ -102,10 +102,22 @@
|
||||
--menuitem-border-radius: var(--arrowpanel-menuitem-border-radius);
|
||||
--menuitem-padding: var(--arrowpanel-menuitem-padding);
|
||||
--menuitem-margin: var(--arrowpanel-menuitem-margin);
|
||||
}
|
||||
|
||||
+/* stylelint-disable-next-line media-query-no-invalid */
|
||||
+@media -moz-pref("widget.macos.native-popovers") and (-moz-platform: macos) {
|
||||
+ panel:not(:where([nonnativepopover="true"])) {
|
||||
+ background-color: transparent;
|
||||
+ --panel-background: transparent;
|
||||
+ --panel-shadow: none;
|
||||
+ --panel-border-color: transparent;
|
||||
+ --panel-shadow-margin: 0px;
|
||||
+ --panel-padding: 0px;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Lightweight theme roots */
|
||||
|
||||
:root[lwtheme] {
|
||||
.browser-toolbox-background,
|
||||
toolbar,
|
||||
diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h
|
||||
--- a/widget/cocoa/nsCocoaWindow.h
|
||||
+++ b/widget/cocoa/nsCocoaWindow.h
|
||||
@@ -133,23 +133,38 @@
|
||||
// to create its "frame view".
|
||||
+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
|
||||
|
||||
@end
|
||||
|
||||
-@interface PopupWindow : BaseWindow {
|
||||
+@interface PopupWindow : BaseWindow <NSPopoverDelegate> {
|
||||
@private
|
||||
BOOL mIsContextMenu;
|
||||
+
|
||||
+ // NSPopover support for native appearance
|
||||
+ NSPopover* mPopover;
|
||||
+ NSViewController* mPopoverViewController;
|
||||
+ BOOL mUsePopover;
|
||||
}
|
||||
|
||||
- (id)initWithContentRect:(NSRect)contentRect
|
||||
styleMask:(NSUInteger)styleMask
|
||||
backing:(NSBackingStoreType)bufferingType
|
||||
defer:(BOOL)deferCreation;
|
||||
- (BOOL)isContextMenu;
|
||||
- (void)setIsContextMenu:(BOOL)flag;
|
||||
- (BOOL)canBecomeMainWindow;
|
||||
|
||||
+// NSPopover support
|
||||
+- (void)setAllowPopover;
|
||||
+- (BOOL)usePopover;
|
||||
+- (void)showPopoverRelativeToRect:(NSRect)positioningRect
|
||||
+ ofView:(NSView*)positioningView
|
||||
+ preferredEdge:(NSRectEdge)preferredEdge
|
||||
+ hiddenAnchor:(BOOL)hiddenAnchor;
|
||||
+- (void)closePopover;
|
||||
+- (void)updatePopoverContent;
|
||||
+
|
||||
@end
|
||||
|
||||
@interface BorderlessWindow : BaseWindow {
|
||||
}
|
||||
|
||||
@@ -201,10 +216,14 @@
|
||||
typedef nsIWidget Inherited;
|
||||
|
||||
public:
|
||||
nsCocoaWindow();
|
||||
|
||||
+ // Check if this window should use NSPopover for popup/menu display
|
||||
+ bool ShouldUseNSPopover() const;
|
||||
+ bool ShouldShowAsNSPopover() const override;
|
||||
+
|
||||
[[nodiscard]] nsresult Create(nsIWidget* aParent, const DesktopIntRect& aRect,
|
||||
const InitData&) override;
|
||||
|
||||
[[nodiscard]] nsresult Create(nsIWidget* aParent,
|
||||
const LayoutDeviceIntRect& aRect,
|
||||
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
--- a/widget/cocoa/nsCocoaWindow.mm
|
||||
+++ b/widget/cocoa/nsCocoaWindow.mm
|
||||
@@ -5,10 +5,13 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsCocoaWindow.h"
|
||||
|
||||
#include "nsArrayUtils.h"
|
||||
+#include "nsMenuPopupFrame.h"
|
||||
+#include "nsDeviceContext.h"
|
||||
+#include "mozilla/dom/XULPopupElement.h"
|
||||
#include "MOZDynamicCursor.h"
|
||||
#include "nsIAppStartup.h"
|
||||
#include "nsIDOMWindowUtils.h"
|
||||
#include "nsILocalFileMac.h"
|
||||
#include "CocoaCompositorWidget.h"
|
||||
@@ -4958,10 +4961,15 @@
|
||||
if (mWindowType == WindowType::Popup) {
|
||||
SetPopupWindowLevel();
|
||||
mWindow.backgroundColor = NSColor.clearColor;
|
||||
mWindow.opaque = NO;
|
||||
|
||||
+ // Enable NSPopover for panel popup types when preference is enabled
|
||||
+ if ([mWindow isKindOfClass:[PopupWindow class]] && ShouldUseNSPopover()) {
|
||||
+ [(PopupWindow*)mWindow setAllowPopover];
|
||||
+ }
|
||||
+
|
||||
// When multiple spaces are in use and the browser is assigned to a
|
||||
// particular space, override the "Assign To" space and display popups on
|
||||
// the active space. Does not work with multiple displays. See
|
||||
// NeedsRecreateToReshow() for multi-display with multi-space workaround.
|
||||
mWindow.collectionBehavior = mWindow.collectionBehavior |
|
||||
@@ -5163,10 +5171,57 @@
|
||||
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||
}
|
||||
|
||||
bool nsCocoaWindow::IsRunningAppModal() { return [NSApp _isRunningAppModal]; }
|
||||
|
||||
+static NSRectEdge AlignmentPositionToNSRectEdge(int8_t aPosition) {
|
||||
+ switch (aPosition) {
|
||||
+ case POPUPPOSITION_BEFORESTART:
|
||||
+ case POPUPPOSITION_BEFOREEND:
|
||||
+ return NSRectEdgeMaxY;
|
||||
+ case POPUPPOSITION_AFTERSTART:
|
||||
+ case POPUPPOSITION_AFTEREND:
|
||||
+ return NSRectEdgeMinY;
|
||||
+ case POPUPPOSITION_STARTBEFORE:
|
||||
+ case POPUPPOSITION_STARTAFTER:
|
||||
+ return NSRectEdgeMaxX;
|
||||
+ case POPUPPOSITION_ENDBEFORE:
|
||||
+ case POPUPPOSITION_ENDAFTER:
|
||||
+ return NSRectEdgeMinX;
|
||||
+ default:
|
||||
+ return NSRectEdgeMinY;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void SyncPopoverBounds(NSPopover* aPopover,
|
||||
+ nsMenuPopupFrame* aPopupFrame) {
|
||||
+ if (!aPopover || !aPopover.shown || !aPopupFrame) {
|
||||
+ return;
|
||||
+ }
|
||||
+ NSWindow* popoverWindow = aPopover.contentViewController.view.window;
|
||||
+ if (!popoverWindow) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Synchronize the popup frame's internal bounds with the actual bounds that
|
||||
+ // macOS calculated for the popover.
|
||||
+ NSView* contentView = popoverWindow.contentView;
|
||||
+ NSRect contentFrame = [contentView convertRect:contentView.bounds toView:nil];
|
||||
+ NSRect windowFrame = [popoverWindow convertRectToScreen:contentFrame];
|
||||
+
|
||||
+ CGFloat backingScale = popoverWindow.backingScaleFactor;
|
||||
+ mozilla::LayoutDeviceIntRect devPixRect =
|
||||
+ nsCocoaUtils::CocoaRectToGeckoRectDevPix(windowFrame, backingScale);
|
||||
+
|
||||
+ nsPresContext* presContext = aPopupFrame->PresContext();
|
||||
+ mozilla::CSSIntPoint cssPos =
|
||||
+ presContext->DevPixelsToIntCSSPixels(devPixRect.TopLeft());
|
||||
+
|
||||
+ aPopupFrame->MoveTo(mozilla::CSSPoint(cssPos.x, cssPos.y),
|
||||
+ /* aUpdateAttrs */ false);
|
||||
+}
|
||||
+
|
||||
// Hide or show this window
|
||||
void nsCocoaWindow::Show(bool aState) {
|
||||
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
|
||||
|
||||
if (!mWindow) {
|
||||
@@ -5185,10 +5240,17 @@
|
||||
}
|
||||
|
||||
NSWindow* nativeParentWindow =
|
||||
mParent ? (NSWindow*)mParent->GetNativeData(NS_NATIVE_WINDOW) : nil;
|
||||
|
||||
+ bool shouldUseNativePopover = false;
|
||||
+ if (mWindowType == WindowType::Popup && aState) {
|
||||
+ nsMenuPopupFrame* popupFrame = GetPopupFrame();
|
||||
+ popupFrame->PopupElement().SetXULBoolAttr(
|
||||
+ nsGkAtoms::nonnativepopover, !ShouldShowAsNSPopover(), IgnoreErrors());
|
||||
+ }
|
||||
+
|
||||
if (aState && !mBounds.IsEmpty()) {
|
||||
// If we had set the activationPolicy to accessory, then right now we won't
|
||||
// have a dock icon. Make sure that we undo that and show a dock icon now
|
||||
// that we're going to show a window.
|
||||
if (NSApp.activationPolicy != NSApplicationActivationPolicyRegular) {
|
||||
@@ -5227,10 +5289,54 @@
|
||||
mWindow.contentView.needsDisplay = YES;
|
||||
if (!nativeParentWindow || mPopupLevel != PopupLevel::Parent) {
|
||||
[mWindow orderFront:nil];
|
||||
}
|
||||
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||
+ if (ShouldShowAsNSPopover()) {
|
||||
+ nsMenuPopupFrame* popupFrame = GetPopupFrame();
|
||||
+ if (nativeParentWindow) {
|
||||
+ NSRectEdge preferredEdge =
|
||||
+ AlignmentPositionToNSRectEdge(popupFrame->GetAlignmentPosition());
|
||||
+ nsRect anchorRectAppUnits = popupFrame->GetUntransformedAnchorRect();
|
||||
+ nsPresContext* pc = popupFrame->PresContext();
|
||||
+ int32_t appUnitsPerDevPixel = pc->AppUnitsPerDevPixel();
|
||||
+ mozilla::DesktopToLayoutDeviceScale desktopToLayoutScale =
|
||||
+ pc->DeviceContext()->GetDesktopToDeviceScale();
|
||||
+ mozilla::DesktopIntRect popupAnchorRectScaled =
|
||||
+ mozilla::DesktopIntRect::RoundOut(
|
||||
+ mozilla::LayoutDeviceRect::FromAppUnits(anchorRectAppUnits,
|
||||
+ appUnitsPerDevPixel) /
|
||||
+ desktopToLayoutScale);
|
||||
+ // Taking the now correctly scaled anchor rect and turning it into a
|
||||
+ // gecko rect this accounts for the y-axis inversion that cocoa needs,
|
||||
+ // as the origin is in the bottom left. This rect is in screen space
|
||||
+ NSRect cocoaScreenRect =
|
||||
+ nsCocoaUtils::GeckoRectToCocoaRect(popupAnchorRectScaled);
|
||||
+ // We take the screen space rect and convert it to window space
|
||||
+ // coordinates, as NSPopover requires the coordinates to be in view
|
||||
+ // space and inside the view. If the coordinates are outside our view,
|
||||
+ // the popover will fail silently
|
||||
+ NSRect windowRect =
|
||||
+ [nativeParentWindow convertRectFromScreen:cocoaScreenRect];
|
||||
+ NSView* parentView = [nativeParentWindow contentView];
|
||||
+ // We take the window space rect and convert it to view space for the
|
||||
+ // specific parent view
|
||||
+ NSRect positioningRect = [parentView convertRect:windowRect
|
||||
+ fromView:nil];
|
||||
+ BOOL shouldHideAnchor = NO;
|
||||
+ auto& element = popupFrame->PopupElement();
|
||||
+ if (element.GetBoolAttr(nsGkAtoms::hidepopovertail)) {
|
||||
+ shouldHideAnchor = YES;
|
||||
+ }
|
||||
+ [(PopupWindow*)mWindow showPopoverRelativeToRect:positioningRect
|
||||
+ ofView:parentView
|
||||
+ preferredEdge:preferredEdge
|
||||
+ hiddenAnchor:shouldHideAnchor];
|
||||
+ SyncPopoverBounds([(PopupWindow*)mWindow popover], popupFrame);
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
// If our popup window is a non-native context menu, tell the OS (and
|
||||
// other programs) that a menu has opened. This is how the OS knows to
|
||||
// close other programs' context menus when ours open.
|
||||
if ([mWindow isKindOfClass:[PopupWindow class]] &&
|
||||
[(PopupWindow*)mWindow isContextMenu]) {
|
||||
@@ -5301,10 +5407,15 @@
|
||||
// of a window it hides the parent window.
|
||||
if (mWindowType == WindowType::Popup && nativeParentWindow) {
|
||||
[nativeParentWindow removeChildWindow:mWindow];
|
||||
}
|
||||
|
||||
+ // Handle NSPopover hiding or traditional window hiding
|
||||
+ if ([mWindow isKindOfClass:[PopupWindow class]] &&
|
||||
+ [(PopupWindow*)mWindow usePopover]) {
|
||||
+ [(PopupWindow*)mWindow closePopover];
|
||||
+ }
|
||||
[mWindow orderOut:nil];
|
||||
// If our popup window is a non-native context menu, tell the OS (and
|
||||
// other programs) that a menu has closed.
|
||||
if ([mWindow isKindOfClass:[PopupWindow class]] &&
|
||||
[(PopupWindow*)mWindow isContextMenu]) {
|
||||
@@ -5351,10 +5462,28 @@
|
||||
return false;
|
||||
}
|
||||
return nsIWidget::ShouldUseOffMainThreadCompositing();
|
||||
}
|
||||
|
||||
+bool nsCocoaWindow::ShouldUseNSPopover() const {
|
||||
+ // Use NSPopover for panel popups when the preference is enabled
|
||||
+ // But not for detached popups - they should use traditional window logic
|
||||
+ return (mWindowType == WindowType::Popup && mPopupType == PopupType::Panel &&
|
||||
+ mozilla::StaticPrefs::widget_macos_native_popovers());
|
||||
+}
|
||||
+
|
||||
+bool nsCocoaWindow::ShouldShowAsNSPopover() const {
|
||||
+ if (!ShouldUseNSPopover()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ nsMenuPopupFrame* popupFrame = GetPopupFrame();
|
||||
+ return [mWindow isKindOfClass:[PopupWindow class]] &&
|
||||
+ [(PopupWindow*)mWindow usePopover] && popupFrame &&
|
||||
+ popupFrame->ShouldFollowAnchor() &&
|
||||
+ !popupFrame->PopupElement().GetBoolAttr(nsGkAtoms::nonnativepopover);
|
||||
+}
|
||||
+
|
||||
TransparencyMode nsCocoaWindow::GetTransparencyMode() {
|
||||
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
|
||||
|
||||
return mWindow.isOpaque ? TransparencyMode::Opaque
|
||||
: TransparencyMode::Transparent;
|
||||
@@ -6313,10 +6442,20 @@
|
||||
// We ignore aRepaint -- we have to call display:YES, otherwise the
|
||||
// title bar doesn't immediately get repainted and is displayed in
|
||||
// the wrong place, leading to a visual jump.
|
||||
[mWindow setFrame:newFrame display:YES];
|
||||
|
||||
+ if (ShouldUseNSPopover() && [(PopupWindow*)mWindow usePopover]) {
|
||||
+ [(PopupWindow*)mWindow updatePopoverContent];
|
||||
+ // A popover won't resize by setting the frame
|
||||
+ // as it's size is calculated based on the content size
|
||||
+ // Therefor the content size has to be changed as well
|
||||
+ NSSize contentSize = NSMakeSize(aWidth, aHeight);
|
||||
+ [[(PopupWindow*)mWindow popover] setContentSize:contentSize];
|
||||
+ SyncPopoverBounds([(PopupWindow*)mWindow popover], GetPopupFrame());
|
||||
+ }
|
||||
+
|
||||
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||
}
|
||||
|
||||
void nsCocoaWindow::Resize(const DesktopRect& aRect, bool aRepaint) {
|
||||
DoResize(aRect.x, aRect.y, aRect.width, aRect.height, aRepaint, false);
|
||||
@@ -8277,18 +8416,27 @@
|
||||
backing:(NSBackingStoreType)bufferingType
|
||||
defer:(BOOL)deferCreation {
|
||||
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
|
||||
|
||||
mIsContextMenu = false;
|
||||
+ mPopover = nil;
|
||||
+ mPopoverViewController = nil;
|
||||
+ mUsePopover = NO;
|
||||
return [super initWithContentRect:contentRect
|
||||
styleMask:styleMask
|
||||
backing:bufferingType
|
||||
defer:deferCreation];
|
||||
|
||||
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
|
||||
}
|
||||
|
||||
+- (void)dealloc {
|
||||
+ [mPopover release];
|
||||
+ [mPopoverViewController release];
|
||||
+ [super dealloc];
|
||||
+}
|
||||
+
|
||||
// Override the private API _backdropBleedAmount. This determines how much the
|
||||
// desktop wallpaper contributes to the vibrancy backdrop.
|
||||
// Return 0 in order to match what the system does for sheet windows and
|
||||
// _NSPopoverWindows.
|
||||
- (CGFloat)_backdropBleedAmount {
|
||||
@@ -8342,10 +8490,120 @@
|
||||
|
||||
- (void)setIsContextMenu:(BOOL)flag {
|
||||
mIsContextMenu = flag;
|
||||
}
|
||||
|
||||
+- (void)setAllowPopover {
|
||||
+ mUsePopover = YES;
|
||||
+
|
||||
+ if (!mPopover) {
|
||||
+ mPopover = [[NSPopover alloc] init];
|
||||
+
|
||||
+ // Use NSPopoverBehaviorApplicationDefined to prevent auto-closing
|
||||
+ // when other popovers are opened, and to respect the disable_autohide
|
||||
+ // preference
|
||||
+ mPopover.behavior = NSPopoverBehaviorApplicationDefined;
|
||||
+ mPopover.delegate = self;
|
||||
+
|
||||
+ // Create view controller that will contain our content view
|
||||
+ mPopoverViewController = [[NSViewController alloc] init];
|
||||
+
|
||||
+ NSView* contentView = self.contentView;
|
||||
+ if (contentView) {
|
||||
+ // Ensure the content view is properly configured
|
||||
+ [contentView
|
||||
+ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
+
|
||||
+ mPopoverViewController.view = contentView;
|
||||
+ mPopover.contentViewController = mPopoverViewController;
|
||||
+
|
||||
+ // Set popover size to match our window content size
|
||||
+ NSRect contentRect = [contentView frame];
|
||||
+ if (contentRect.size.width > 0 && contentRect.size.height > 0) {
|
||||
+ [mPopover setContentSize:contentRect.size];
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+- (BOOL)usePopover {
|
||||
+ return mUsePopover && !mIsContextMenu;
|
||||
+}
|
||||
+
|
||||
+- (void)showPopoverRelativeToRect:(NSRect)positioningRect
|
||||
+ ofView:(NSView*)positioningView
|
||||
+ preferredEdge:(NSRectEdge)preferredEdge
|
||||
+ hiddenAnchor:(BOOL)hiddenAnchor {
|
||||
+ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
|
||||
+ if (!mPopover) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Close existing popover if it's already shown
|
||||
+ if (mPopover.shown) {
|
||||
+ [mPopover close];
|
||||
+ }
|
||||
+
|
||||
+ // Force content update before showing
|
||||
+ [self updatePopoverContent];
|
||||
+
|
||||
+ if (mPopoverViewController.view) {
|
||||
+ mPopover.behavior = NSPopoverBehaviorApplicationDefined;
|
||||
+
|
||||
+ // This is a hidden API that prevents the popover from showing its arrow
|
||||
+ // pointing to the anchor.
|
||||
+ [mPopover setShouldHideAnchor:hiddenAnchor];
|
||||
+
|
||||
+ [mPopover showRelativeToRect:positioningRect
|
||||
+ ofView:positioningView
|
||||
+ preferredEdge:preferredEdge];
|
||||
+ }
|
||||
+
|
||||
+ NSWindow* popoverWindow = mPopover.contentViewController.view.window;
|
||||
+ [popoverWindow setAcceptsMouseMovedEvents:YES];
|
||||
+
|
||||
+ NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||
+}
|
||||
+
|
||||
+- (void)closePopover {
|
||||
+ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
|
||||
+
|
||||
+ if (mPopover && mPopover.shown) {
|
||||
+ [mPopover close];
|
||||
+ }
|
||||
+
|
||||
+ NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||
+}
|
||||
+
|
||||
+- (void)updatePopoverContent {
|
||||
+ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
|
||||
+
|
||||
+ if (mPopover && mPopoverViewController) {
|
||||
+ NSView* contentView = self.contentView;
|
||||
+ if (contentView) {
|
||||
+ // Ensure proper hit testing for hover events
|
||||
+ [contentView setWantsLayer:YES];
|
||||
+ [contentView setAcceptsTouchEvents:YES];
|
||||
+
|
||||
+ // Update the popover content view to match current window content
|
||||
+ mPopoverViewController.view = contentView;
|
||||
+
|
||||
+ // Update popover size to match content
|
||||
+ NSRect contentRect = [contentView frame];
|
||||
+ if (contentRect.size.width > 0 && contentRect.size.height > 0) {
|
||||
+ mPopover.contentSize = contentRect.size;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||
+}
|
||||
+
|
||||
+- (NSPopover*)popover {
|
||||
+ return mPopover;
|
||||
+}
|
||||
+
|
||||
- (BOOL)canBecomeMainWindow {
|
||||
// This is overriden because the default is 'yes' when a titlebar is present.
|
||||
return NO;
|
||||
}
|
||||
|
||||
diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h
|
||||
--- a/widget/nsIWidget.h
|
||||
+++ b/widget/nsIWidget.h
|
||||
@@ -836,10 +836,15 @@
|
||||
virtual void SuppressAnimation(bool aSuppress) {}
|
||||
|
||||
/** Sets windows-specific mica backdrop on this widget. */
|
||||
virtual void SetMicaBackdrop(bool) {}
|
||||
|
||||
+ /**
|
||||
+ * Determine whether this widget should be shown as an NSPopover.
|
||||
+ */
|
||||
+ virtual bool ShouldShowAsNSPopover() const { return false; }
|
||||
+
|
||||
/**
|
||||
* Return size mode (minimized, maximized, normalized).
|
||||
* Returns a value from nsSizeMode (see nsIWidgetListener.h)
|
||||
*/
|
||||
virtual nsSizeMode SizeMode() = 0;
|
||||
diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py
|
||||
--- a/xpcom/ds/StaticAtoms.py
|
||||
+++ b/xpcom/ds/StaticAtoms.py
|
||||
@@ -535,10 +535,11 @@
|
||||
Atom("hgroup", "hgroup"),
|
||||
Atom("hidden", "hidden"),
|
||||
Atom("hidechrome", "hidechrome"),
|
||||
Atom("hidecolumnpicker", "hidecolumnpicker"),
|
||||
Atom("hidetitlebarseparator", "hidetitlebarseparator"),
|
||||
+ Atom("hidepopovertail", "hidepopovertail"),
|
||||
Atom("hide_popover", "hide-popover"),
|
||||
Atom("high", "high"),
|
||||
Atom("highest", "highest"),
|
||||
Atom("horizontal", "horizontal"),
|
||||
Atom("hover", "hover"),
|
||||
@@ -756,10 +757,11 @@
|
||||
Atom("nohref", "nohref"),
|
||||
Atom("noinitialselection", "noinitialselection"),
|
||||
Atom("nomodule", "nomodule"),
|
||||
Atom("nonce", "nonce"),
|
||||
Atom("none", "none"),
|
||||
+ Atom("nonnativepopover", "nonnativepopover"),
|
||||
Atom("noresize", "noresize"),
|
||||
Atom("normal", "normal"),
|
||||
Atom("normalizeSpace", "normalize-space"),
|
||||
Atom("noscript", "noscript"),
|
||||
Atom("noshade", "noshade"),
|
||||
|
||||
@@ -7,6 +7,26 @@
|
||||
"id": "D279007",
|
||||
"name": "Fix MacOS Crash on Shutdown Firefox 149"
|
||||
},
|
||||
{
|
||||
"type": "phabricator",
|
||||
"id": "D284084",
|
||||
"name": "Native MacOS popovers",
|
||||
"replaces": {
|
||||
// The patch we sent was for firefox 149, but we are currently in 148, so theres
|
||||
// a conflict in the patch. See https://bugzilla.mozilla.org/show_bug.cgi?id=2015354
|
||||
"overridden": "overriden",
|
||||
// Specifically trying to target FeatureCallout.sys.mjs's change.
|
||||
// IMPORTANT: Make sure Feature callouts STILL use native popopvers when
|
||||
// syncing from upstream, as this is a critical part of the patch.
|
||||
"+ nonnativepopover=\"true\"": "+ ",
|
||||
"body,": ".browser-toolbox-background,"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "phabricator",
|
||||
"id": "D284404",
|
||||
"name": "Add urlbar closeOnWindowBlur preference"
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"path": "firefox/no_liquid_glass_icon.patch"
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp
|
||||
index 67ae256038fae1d61824d58f5e544f65505a1ed5..b6e70376f1d9230df9beb01216092969e9322c8f 100644
|
||||
--- a/layout/generic/nsIFrame.cpp
|
||||
+++ b/layout/generic/nsIFrame.cpp
|
||||
@@ -11973,6 +11973,11 @@ gfx::Matrix nsIFrame::ComputeWidgetTransform() const {
|
||||
gfx::Matrix4x4 matrix = nsStyleTransformMatrix::ReadTransforms(
|
||||
uiReset->mMozWindowTransform, refBox, float(appUnitsPerDevPixel));
|
||||
|
||||
+ const StyleTransformOrigin& origin = uiReset->mWindowTransformOrigin;
|
||||
+ Point transformOrigin = nsStyleTransformMatrix::Convert2DPosition(
|
||||
+ origin.horizontal, origin.vertical, refBox, appUnitsPerDevPixel);
|
||||
+ matrix.ChangeBasis(Point3D(transformOrigin.x, transformOrigin.y, 0));
|
||||
+
|
||||
gfx::Matrix result2d;
|
||||
if (!matrix.CanDraw2D(&result2d)) {
|
||||
// FIXME: It would be preferable to reject non-2D transforms at parse time.
|
||||
@@ -1,22 +0,0 @@
|
||||
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
|
||||
index e5883b377afee44626a2928a97205382e6d07e40..57ae3b0567fbd7afbcfb60a2cd662f611339e5ad 100644
|
||||
--- a/layout/style/nsStyleStruct.cpp
|
||||
+++ b/layout/style/nsStyleStruct.cpp
|
||||
@@ -3287,6 +3287,9 @@ nsStyleUIReset::nsStyleUIReset()
|
||||
mWindowShadow(StyleWindowShadow::Auto),
|
||||
mWindowOpacity(1.0),
|
||||
mMozWindowInputRegionMargin(StyleLength::Zero()),
|
||||
+ mWindowTransformOrigin{LengthPercentage::FromPercentage(0.5),
|
||||
+ LengthPercentage::FromPercentage(0.5),
|
||||
+ {0.}},
|
||||
mTransitions(
|
||||
nsStyleAutoArray<StyleTransition>::WITH_SINGLE_INITIAL_ELEMENT),
|
||||
mTransitionTimingFunctionCount(1),
|
||||
@@ -3331,6 +3334,7 @@ nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource)
|
||||
mWindowOpacity(aSource.mWindowOpacity),
|
||||
mMozWindowInputRegionMargin(aSource.mMozWindowInputRegionMargin),
|
||||
mMozWindowTransform(aSource.mMozWindowTransform),
|
||||
+ mWindowTransformOrigin(aSource.mWindowTransformOrigin),
|
||||
mTransitions(aSource.mTransitions.Clone()),
|
||||
mTransitionTimingFunctionCount(aSource.mTransitionTimingFunctionCount),
|
||||
mTransitionDurationCount(aSource.mTransitionDurationCount),
|
||||
@@ -1,12 +0,0 @@
|
||||
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
|
||||
index 14c24446880b7342f6c194bb068f5fd54657ec85..8a0067b2694029242a0fbe6d806b1dd0153f1715 100644
|
||||
--- a/layout/style/nsStyleStruct.h
|
||||
+++ b/layout/style/nsStyleStruct.h
|
||||
@@ -2094,6 +2094,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset {
|
||||
// The margin of the window region that should be transparent to events.
|
||||
mozilla::StyleLength mMozWindowInputRegionMargin;
|
||||
mozilla::StyleTransform mMozWindowTransform;
|
||||
+ mozilla::StyleTransformOrigin mWindowTransformOrigin;
|
||||
|
||||
nsStyleAutoArray<mozilla::StyleTransition> mTransitions;
|
||||
// The number of elements in mTransitions that are not from repeating
|
||||
@@ -1,12 +0,0 @@
|
||||
diff --git a/layout/style/test/ListCSSProperties.cpp b/layout/style/test/ListCSSProperties.cpp
|
||||
index 1870bfc3735255f2d41356b00dc52faf95d9d9f2..59ad4fb11c7d48d9ba84dceef09a67a42b486ed8 100644
|
||||
--- a/layout/style/test/ListCSSProperties.cpp
|
||||
+++ b/layout/style/test/ListCSSProperties.cpp
|
||||
@@ -110,6 +110,7 @@ const char* gInaccessibleProperties[] = {
|
||||
"-moz-window-opacity", // chrome-only internal properties
|
||||
"-moz-window-transform", // chrome-only internal properties
|
||||
"-moz-window-shadow", // chrome-only internal properties
|
||||
+ "-zen-window-transform-origin", // chrome-only internal properties
|
||||
};
|
||||
|
||||
inline int is_inaccessible(const char* aPropName) {
|
||||
12
src/python/mozlint/mozlint/roller-py.patch
Normal file
12
src/python/mozlint/mozlint/roller-py.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/python/mozlint/mozlint/roller.py b/python/mozlint/mozlint/roller.py
|
||||
index aeafa93cc525d2846614b600e95fd817b832b0ef..69414ed032523f1b53b78ad867145efaea422c63 100644
|
||||
--- a/python/mozlint/mozlint/roller.py
|
||||
+++ b/python/mozlint/mozlint/roller.py
|
||||
@@ -92,7 +92,6 @@ def _run_worker(config, paths, **lintargs):
|
||||
res = res or []
|
||||
else:
|
||||
log.error(f"Unexpected result type received: {type(res)}")
|
||||
- assert False
|
||||
except Exception:
|
||||
log.exception(f"{config['name']} failed")
|
||||
res = 1
|
||||
@@ -1,23 +0,0 @@
|
||||
diff --git a/servo/components/style/properties/longhands/ui.mako.rs b/servo/components/style/properties/longhands/ui.mako.rs
|
||||
index 24e1e1b7e8fe4d4b70aaa4f5f022500c3dcfcbae..1176bf5d12885b4d96abb2f72288f6c631072578 100644
|
||||
--- a/servo/components/style/properties/longhands/ui.mako.rs
|
||||
+++ b/servo/components/style/properties/longhands/ui.mako.rs
|
||||
@@ -284,6 +284,18 @@ ${helpers.predefined_type(
|
||||
affects="",
|
||||
)}
|
||||
|
||||
+${helpers.predefined_type(
|
||||
+ "-zen-window-transform-origin",
|
||||
+ "TransformOrigin",
|
||||
+ "computed::TransformOrigin::initial_value()",
|
||||
+ engines="gecko",
|
||||
+ gecko_ffi_name="mWindowTransformOrigin",
|
||||
+ boxed=True,
|
||||
+ spec="None (Nonstandard internal property)",
|
||||
+ enabled_in="chrome",
|
||||
+ affects="overflow",
|
||||
+)}
|
||||
+
|
||||
${helpers.predefined_type(
|
||||
"animation-fill-mode",
|
||||
"AnimationFillMode",
|
||||
@@ -1,28 +0,0 @@
|
||||
diff --git a/toolkit/components/asyncshutdown/AsyncShutdown.sys.mjs b/toolkit/components/asyncshutdown/AsyncShutdown.sys.mjs
|
||||
index 2aaef80411b2cef9563c49f23d36b08222b06b03..7bd15ebb0d9d09da57a287b47beb1f0e2e17d229 100644
|
||||
--- a/toolkit/components/asyncshutdown/AsyncShutdown.sys.mjs
|
||||
+++ b/toolkit/components/asyncshutdown/AsyncShutdown.sys.mjs
|
||||
@@ -492,6 +492,23 @@ function getPhase(topic) {
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
+
|
||||
+ /**
|
||||
+ * Reset the phase after a call to _trigger().
|
||||
+ * For testing purposes only.
|
||||
+ */
|
||||
+ get _reset() {
|
||||
+ let accepted = Services.prefs.getBoolPref(
|
||||
+ "toolkit.asyncshutdown.testing",
|
||||
+ false
|
||||
+ );
|
||||
+ if (accepted) {
|
||||
+ return () => {
|
||||
+ spinner = new Spinner(topic);
|
||||
+ };
|
||||
+ }
|
||||
+ return undefined;
|
||||
+ },
|
||||
});
|
||||
gPhases.set(topic, phase);
|
||||
return phase;
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/toolkit/themes/shared/popup.css b/toolkit/themes/shared/popup.css
|
||||
index c2618b86d7e8bb71f9f7f71ef9916c8140ca1ead..96a602f9cbfb77ee0a52151ce8ccf7ba17cf5c43 100644
|
||||
index c2618b86d7e8bb71f9f7f71ef9916c8140ca1ead..9e2006015e22f1ac043c46066c4c9a85fe053a21 100644
|
||||
--- a/toolkit/themes/shared/popup.css
|
||||
+++ b/toolkit/themes/shared/popup.css
|
||||
@@ -22,8 +22,8 @@ panel {
|
||||
@@ -13,24 +13,3 @@ index c2618b86d7e8bb71f9f7f71ef9916c8140ca1ead..96a602f9cbfb77ee0a52151ce8ccf7ba
|
||||
-moz-window-input-region-margin: var(--panel-shadow-margin);
|
||||
margin: calc(-1 * var(--panel-shadow-margin));
|
||||
|
||||
@@ -143,11 +143,7 @@ panel[type="arrow"] {
|
||||
-moz-window-transform,
|
||||
-moz-window-opacity;
|
||||
@media not (prefers-reduced-motion) {
|
||||
- -moz-window-transform: translateY(-70px);
|
||||
-
|
||||
- &:where([side="bottom"]) {
|
||||
- -moz-window-transform: translateY(70px);
|
||||
- }
|
||||
+ -moz-window-transform: scale(0);
|
||||
}
|
||||
/* Only do the fade-in animation on pre-Big Sur to avoid missing shadows on
|
||||
* Big Sur+, see bug 1672091. */
|
||||
@@ -161,7 +157,6 @@ panel[type="arrow"] {
|
||||
}
|
||||
|
||||
&[animate="cancel"] {
|
||||
- -moz-window-transform: none;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
|
||||
13
src/tools/lint/eslint/__init__-py.patch
Normal file
13
src/tools/lint/eslint/__init__-py.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/tools/lint/eslint/__init__.py b/tools/lint/eslint/__init__.py
|
||||
index cd45822500a8b5e1112efad81ed34e01c0dbcc19..9f47b4a46bf1c36db06b45e047a939ae08bcb703 100644
|
||||
--- a/tools/lint/eslint/__init__.py
|
||||
+++ b/tools/lint/eslint/__init__.py
|
||||
@@ -114,7 +114,7 @@ def lint(paths, config, binary=None, fix=None, rules=[], setup=None, **lintargs)
|
||||
[
|
||||
binary,
|
||||
os.path.join(
|
||||
- module_path, "node_modules", "prettier", "bin", "prettier.cjs"
|
||||
+ module_path, "..", "node_modules", "@zen-browser", "prettier", "bin", "prettier.cjs"
|
||||
),
|
||||
"--list-different",
|
||||
"--no-error-on-unmatched-pattern",
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/require-jsdoc.mjs b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/require-jsdoc.mjs
|
||||
index 87fc32f6a1bdf21a56fb3ce18c767ebbb12c6d67..174fcc3a679ae655c9bce907461f9c3a9030c2a9 100644
|
||||
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/require-jsdoc.mjs
|
||||
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/require-jsdoc.mjs
|
||||
@@ -13,7 +13,7 @@ export default {
|
||||
"error",
|
||||
{
|
||||
require: {
|
||||
- ClassDeclaration: true,
|
||||
+ ClassDeclaration: false,
|
||||
FunctionDeclaration: false,
|
||||
},
|
||||
},
|
||||
12
src/tools/lint/ignorefile-yml.patch
Normal file
12
src/tools/lint/ignorefile-yml.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/tools/lint/ignorefile.yml b/tools/lint/ignorefile.yml
|
||||
index 5ae3b282a54c129bb16bca461470154e4a882618..f46c6256037cbef1392f8d070726d45dadac1289 100644
|
||||
--- a/tools/lint/ignorefile.yml
|
||||
+++ b/tools/lint/ignorefile.yml
|
||||
@@ -3,7 +3,6 @@ ignorefile:
|
||||
description: Linter for .gitignore and .hgignore files
|
||||
include:
|
||||
- '.gitignore'
|
||||
- - '.hgignore'
|
||||
support-files:
|
||||
- 'tools/lint/ignorefile**'
|
||||
type: external
|
||||
12
src/tools/lint/rejected-words-yml.patch
Normal file
12
src/tools/lint/rejected-words-yml.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/tools/lint/rejected-words.yml b/tools/lint/rejected-words.yml
|
||||
index d5ca2e05fb335fcd17d1559d5332ec4a43d7cd1d..1f34e8d5e05508fc541bc7aa6a779cd98206032a 100644
|
||||
--- a/tools/lint/rejected-words.yml
|
||||
+++ b/tools/lint/rejected-words.yml
|
||||
@@ -8,7 +8,6 @@ avoid-blacklist-and-whitelist:
|
||||
ignore-case: true
|
||||
# Based on codespell with idl and webidl added.
|
||||
extensions:
|
||||
- - js
|
||||
- mjs
|
||||
- jsx
|
||||
- idl
|
||||
38
src/zen/@types/lib.gecko.darwin.d.ts
vendored
38
src/zen/@types/lib.gecko.darwin.d.ts
vendored
@@ -53,9 +53,15 @@ declare global {
|
||||
dockMenu: nsIStandaloneNativeMenu;
|
||||
activateApplication(aIgnoreOtherApplications: boolean): void;
|
||||
badgeText: string;
|
||||
setBadgeImage(aBadgeImage: imgIContainer, aPaintContext?: nsISVGPaintContext): void;
|
||||
setBadgeImage(
|
||||
aBadgeImage: imgIContainer,
|
||||
aPaintContext?: nsISVGPaintContext
|
||||
): void;
|
||||
readonly isAppInDock: boolean;
|
||||
ensureAppIsPinnedToDock(aAppPath?: string, aAppToReplacePath?: string): boolean;
|
||||
ensureAppIsPinnedToDock(
|
||||
aAppPath?: string,
|
||||
aAppToReplacePath?: string
|
||||
): boolean;
|
||||
launchAppBundle(
|
||||
aAppBundle: nsIFile,
|
||||
aArgs: string[],
|
||||
@@ -70,7 +76,10 @@ declare global {
|
||||
}>;
|
||||
|
||||
interface nsIMacFinderProgress extends nsISupports {
|
||||
init(path: string, canceledCallback: nsIMacFinderProgressCanceledCallback): void;
|
||||
init(
|
||||
path: string,
|
||||
canceledCallback: nsIMacFinderProgressCanceledCallback
|
||||
): void;
|
||||
updateProgress(currentProgress: u64, totalProgress: u64): void;
|
||||
end(): void;
|
||||
}
|
||||
@@ -86,7 +95,11 @@ declare global {
|
||||
// https://searchfox.org/mozilla-central/source/widget/nsIMacUserActivityUpdater.idl
|
||||
|
||||
interface nsIMacUserActivityUpdater extends nsISupports {
|
||||
updateLocation(pageUrl: string, pageTitle: string, window: nsIBaseWindow): void;
|
||||
updateLocation(
|
||||
pageUrl: string,
|
||||
pageTitle: string,
|
||||
window: nsIBaseWindow
|
||||
): void;
|
||||
}
|
||||
|
||||
// https://searchfox.org/mozilla-central/source/widget/nsIMacWebAppUtils.idl
|
||||
@@ -120,7 +133,11 @@ declare global {
|
||||
readonly STATE_ERROR?: 3;
|
||||
readonly STATE_PAUSED?: 4;
|
||||
|
||||
setProgressState(state: nsTaskbarProgressState, currentValue?: u64, maxValue?: u64): void;
|
||||
setProgressState(
|
||||
state: nsTaskbarProgressState,
|
||||
currentValue?: u64,
|
||||
maxValue?: u64
|
||||
): void;
|
||||
}
|
||||
|
||||
// https://searchfox.org/mozilla-central/source/widget/nsITouchBarHelper.idl
|
||||
@@ -157,11 +174,18 @@ declare global {
|
||||
// https://searchfox.org/mozilla-central/source/widget/nsITouchBarUpdater.idl
|
||||
|
||||
interface nsITouchBarUpdater extends nsISupports {
|
||||
updateTouchBarInputs(aWindow: nsIBaseWindow, aInputs: nsITouchBarInput[]): void;
|
||||
updateTouchBarInputs(
|
||||
aWindow: nsIBaseWindow,
|
||||
aInputs: nsITouchBarInput[]
|
||||
): void;
|
||||
enterCustomizeMode(): void;
|
||||
isTouchBarInitialized(): boolean;
|
||||
setTouchBarInitialized(aIsInitialized: boolean): void;
|
||||
showPopover(aWindow: nsIBaseWindow, aPopover: nsITouchBarInput, aShowing: boolean): void;
|
||||
showPopover(
|
||||
aWindow: nsIBaseWindow,
|
||||
aPopover: nsITouchBarInput,
|
||||
aShowing: boolean
|
||||
): void;
|
||||
}
|
||||
|
||||
// https://searchfox.org/mozilla-central/source/xpcom/base/nsIMacPreferencesReader.idl
|
||||
|
||||
2827
src/zen/@types/lib.gecko.dom.d.ts
vendored
2827
src/zen/@types/lib.gecko.dom.d.ts
vendored
File diff suppressed because it is too large
Load Diff
1250
src/zen/@types/lib.gecko.glean.d.ts
vendored
1250
src/zen/@types/lib.gecko.glean.d.ts
vendored
File diff suppressed because it is too large
Load Diff
6
src/zen/@types/lib.gecko.linux.d.ts
vendored
6
src/zen/@types/lib.gecko.linux.d.ts
vendored
@@ -51,7 +51,11 @@ declare global {
|
||||
readonly STATE_ERROR?: 3;
|
||||
readonly STATE_PAUSED?: 4;
|
||||
|
||||
setProgressState(state: nsTaskbarProgressState, currentValue?: u64, maxValue?: u64): void;
|
||||
setProgressState(
|
||||
state: nsTaskbarProgressState,
|
||||
currentValue?: u64,
|
||||
maxValue?: u64
|
||||
): void;
|
||||
}
|
||||
|
||||
interface nsIXPCComponents_Interfaces {
|
||||
|
||||
3
src/zen/@types/lib.gecko.nsresult.d.ts
vendored
3
src/zen/@types/lib.gecko.nsresult.d.ts
vendored
@@ -705,4 +705,5 @@ interface nsIXPCComponents_Results {
|
||||
NS_ERROR_DOM_QM_CLIENT_INIT_ORIGIN_UNINITIALIZED: 0x80730001;
|
||||
}
|
||||
|
||||
type nsIXPCComponents_Values = nsIXPCComponents_Results[keyof nsIXPCComponents_Results];
|
||||
type nsIXPCComponents_Values =
|
||||
nsIXPCComponents_Results[keyof nsIXPCComponents_Results];
|
||||
|
||||
8
src/zen/@types/lib.gecko.tweaks.d.ts
vendored
8
src/zen/@types/lib.gecko.tweaks.d.ts
vendored
@@ -33,11 +33,15 @@ interface Document {
|
||||
}
|
||||
|
||||
type nsIGleanPingNoReason = {
|
||||
[K in keyof nsIGleanPing]: K extends "submit" ? (_?: never) => void : nsIGleanPing[K];
|
||||
[K in keyof nsIGleanPing]: K extends "submit"
|
||||
? (_?: never) => void
|
||||
: nsIGleanPing[K];
|
||||
};
|
||||
|
||||
type nsIGleanPingWithReason<T> = {
|
||||
[K in keyof nsIGleanPing]: K extends "submit" ? (reason: T) => void : nsIGleanPing[K];
|
||||
[K in keyof nsIGleanPing]: K extends "submit"
|
||||
? (reason: T) => void
|
||||
: nsIGleanPing[K];
|
||||
};
|
||||
|
||||
interface MessageListenerManagerMixin {
|
||||
|
||||
61
src/zen/@types/lib.gecko.win32.d.ts
vendored
61
src/zen/@types/lib.gecko.win32.d.ts
vendored
@@ -56,14 +56,18 @@ declare global {
|
||||
}
|
||||
|
||||
interface nsIWindowsAlertNotification
|
||||
extends nsIAlertNotification,
|
||||
extends
|
||||
nsIAlertNotification,
|
||||
Enums<typeof nsIWindowsAlertNotification_ImagePlacement> {
|
||||
imagePlacement: nsIWindowsAlertNotification.ImagePlacement;
|
||||
}
|
||||
|
||||
interface nsIWindowsAlertsService extends nsIAlertsService {
|
||||
handleWindowsTag(aWindowsTag: string): Promise<any>;
|
||||
getXmlStringForWindowsAlert(aAlert: nsIAlertNotification, aWindowsTag?: string): string;
|
||||
getXmlStringForWindowsAlert(
|
||||
aAlert: nsIAlertNotification,
|
||||
aWindowsTag?: string
|
||||
): string;
|
||||
removeAllNotificationsForInstall(): void;
|
||||
}
|
||||
|
||||
@@ -86,9 +90,18 @@ declare global {
|
||||
aNotificationAction: string,
|
||||
daysSinceLastAppLaunch: u32
|
||||
): void;
|
||||
setDefaultBrowserUserChoice(aAumid: string, aExtraFileExtensions: string[]): void;
|
||||
setDefaultBrowserUserChoiceAsync(aAumid: string, aExtraFileExtensions: string[]): Promise<any>;
|
||||
setDefaultExtensionHandlersUserChoice(aAumid: string, aFileExtensions: string[]): void;
|
||||
setDefaultBrowserUserChoice(
|
||||
aAumid: string,
|
||||
aExtraFileExtensions: string[]
|
||||
): void;
|
||||
setDefaultBrowserUserChoiceAsync(
|
||||
aAumid: string,
|
||||
aExtraFileExtensions: string[]
|
||||
): Promise<any>;
|
||||
setDefaultExtensionHandlersUserChoice(
|
||||
aAumid: string,
|
||||
aFileExtensions: string[]
|
||||
): void;
|
||||
agentDisabled(): boolean;
|
||||
}
|
||||
|
||||
@@ -124,11 +137,13 @@ declare enum nsIWindowsShellService_LaunchOnLoginEnabledEnumerator {
|
||||
|
||||
declare global {
|
||||
namespace nsIWindowsShellService {
|
||||
type LaunchOnLoginEnabledEnumerator = nsIWindowsShellService_LaunchOnLoginEnabledEnumerator;
|
||||
type LaunchOnLoginEnabledEnumerator =
|
||||
nsIWindowsShellService_LaunchOnLoginEnabledEnumerator;
|
||||
}
|
||||
|
||||
interface nsIWindowsShellService
|
||||
extends nsIShellService,
|
||||
extends
|
||||
nsIShellService,
|
||||
Enums<typeof nsIWindowsShellService_LaunchOnLoginEnabledEnumerator> {
|
||||
createShortcut(
|
||||
aBinary: nsIFile,
|
||||
@@ -149,13 +164,19 @@ declare global {
|
||||
pinCurrentAppToTaskbarAsync(aPrivateBrowsing: boolean): Promise<any>;
|
||||
checkPinCurrentAppToTaskbarAsync(aPrivateBrowsing: boolean): Promise<any>;
|
||||
isCurrentAppPinnedToTaskbarAsync(aumid: string): Promise<any>;
|
||||
pinShortcutToTaskbar(aAppUserModelId: string, aShortcutPath: string): Promise<any>;
|
||||
pinShortcutToTaskbar(
|
||||
aAppUserModelId: string,
|
||||
aShortcutPath: string
|
||||
): Promise<any>;
|
||||
createWindowsIcon(aFile: nsIFile, aContainer: imgIContainer): Promise<any>;
|
||||
unpinShortcutFromTaskbar(aShortcutPath: string): void;
|
||||
getTaskbarTabShortcutPath(aShortcutName: string): string;
|
||||
getTaskbarTabPins(): string[];
|
||||
classifyShortcut(aPath: string): string;
|
||||
hasPinnableShortcut(aAUMID: string, aPrivateBrowsing: boolean): Promise<any>;
|
||||
hasPinnableShortcut(
|
||||
aAUMID: string,
|
||||
aPrivateBrowsing: boolean
|
||||
): Promise<any>;
|
||||
canSetDefaultBrowserUserChoice(): boolean;
|
||||
checkAllProgIDsExist(): boolean;
|
||||
checkBrowserUserChoiceHashes(): boolean;
|
||||
@@ -241,7 +262,11 @@ declare global {
|
||||
readonly height: u32;
|
||||
readonly thumbnailAspectRatio: float;
|
||||
requestPreview(aCallback: nsITaskbarPreviewCallback): void;
|
||||
requestThumbnail(aCallback: nsITaskbarPreviewCallback, width: u32, height: u32): void;
|
||||
requestThumbnail(
|
||||
aCallback: nsITaskbarPreviewCallback,
|
||||
width: u32,
|
||||
height: u32
|
||||
): void;
|
||||
onClose(): void;
|
||||
onActivate(): boolean;
|
||||
onClick(button: nsITaskbarPreviewButton): void;
|
||||
@@ -256,7 +281,11 @@ declare global {
|
||||
readonly STATE_ERROR?: 3;
|
||||
readonly STATE_PAUSED?: 4;
|
||||
|
||||
setProgressState(state: nsTaskbarProgressState, currentValue?: u64, maxValue?: u64): void;
|
||||
setProgressState(
|
||||
state: nsTaskbarProgressState,
|
||||
currentValue?: u64,
|
||||
maxValue?: u64
|
||||
): void;
|
||||
}
|
||||
|
||||
// https://searchfox.org/mozilla-central/source/widget/nsITaskbarTabPreview.idl
|
||||
@@ -288,7 +317,9 @@ declare global {
|
||||
): nsITaskbarTabPreview;
|
||||
getTaskbarWindowPreview(shell: nsIDocShell): nsITaskbarWindowPreview;
|
||||
getTaskbarProgress(shell: nsIDocShell): nsITaskbarProgress;
|
||||
getOverlayIconController(shell: nsIDocShell): nsITaskbarOverlayIconController;
|
||||
getOverlayIconController(
|
||||
shell: nsIDocShell
|
||||
): nsITaskbarOverlayIconController;
|
||||
createJumpListBuilder(aPrivateBrowsing: boolean): nsIJumpListBuilder;
|
||||
getGroupIdForWindow(aParent: mozIDOMWindow): string;
|
||||
setGroupIdForWindow(aParent: mozIDOMWindow, aIdentifier: string): void;
|
||||
@@ -304,7 +335,11 @@ declare global {
|
||||
aSmallIcon: imgIContainer,
|
||||
aLargeIcon: imgIContainer
|
||||
): void;
|
||||
setWindowIconFromExe(aWindow: mozIDOMWindowProxy, aExe: string, aIndex: u16): void;
|
||||
setWindowIconFromExe(
|
||||
aWindow: mozIDOMWindowProxy,
|
||||
aExe: string,
|
||||
aIndex: u16
|
||||
): void;
|
||||
setWindowIconNoData(aWindow: mozIDOMWindowProxy): void;
|
||||
readonly inWin10TabletMode: boolean;
|
||||
readonly inWin11TabletMode: boolean;
|
||||
|
||||
2136
src/zen/@types/lib.gecko.xpcom.d.ts
vendored
2136
src/zen/@types/lib.gecko.xpcom.d.ts
vendored
File diff suppressed because it is too large
Load Diff
33
src/zen/@types/zen.d.ts
vendored
33
src/zen/@types/zen.d.ts
vendored
@@ -88,7 +88,9 @@ declare namespace MockedExports {
|
||||
*
|
||||
* Then add the file path to the KnownModules above.
|
||||
*/
|
||||
importESModule: <S extends keyof KnownModules>(module: S) => KnownModules[S];
|
||||
importESModule: <S extends keyof KnownModules>(
|
||||
module: S
|
||||
) => KnownModules[S];
|
||||
defineESModuleGetters: (target: any, mappings: any) => void;
|
||||
}
|
||||
|
||||
@@ -160,7 +162,11 @@ declare namespace MockedExports {
|
||||
setIntPref: SetPref<number>;
|
||||
getBoolPref: GetPref<boolean>;
|
||||
setBoolPref: SetPref<boolean>;
|
||||
addObserver: (aDomain: string, aObserver: PrefObserver, aHoldWeak?: boolean) => void;
|
||||
addObserver: (
|
||||
aDomain: string,
|
||||
aObserver: PrefObserver,
|
||||
aHoldWeak?: boolean
|
||||
) => void;
|
||||
removeObserver: (aDomain: string, aObserver: PrefObserver) => void;
|
||||
};
|
||||
|
||||
@@ -299,7 +305,11 @@ declare namespace MockedExports {
|
||||
class nsIFilePicker {}
|
||||
|
||||
interface FilePicker {
|
||||
init: (browsingContext: BrowsingContext, title: string, mode: number) => void;
|
||||
init: (
|
||||
browsingContext: BrowsingContext,
|
||||
title: string,
|
||||
mode: number
|
||||
) => void;
|
||||
open: (callback: (rv: number) => unknown) => void;
|
||||
// The following are enum values.
|
||||
modeGetFolder: number;
|
||||
@@ -330,7 +340,11 @@ declare namespace MockedExports {
|
||||
* This function sets the attributes data-l10n-id and possibly data-l10n-args
|
||||
* on the element.
|
||||
*/
|
||||
setAttributes(target: Element, id?: string, args?: Record<string, string>): void;
|
||||
setAttributes(
|
||||
target: Element,
|
||||
id?: string,
|
||||
args?: Record<string, string>
|
||||
): void;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +379,8 @@ declare interface ChromeDocument extends Document {
|
||||
* Create a XUL element of a specific type. Right now this function
|
||||
* only refines iframes, but more tags could be added.
|
||||
*/
|
||||
createXULElement: ((type: "iframe") => XULIframeElement) & ((type: string) => XULElement);
|
||||
createXULElement: ((type: "iframe") => XULIframeElement) &
|
||||
((type: string) => XULElement);
|
||||
|
||||
/**
|
||||
* This is a fluent instance connected to this document.
|
||||
@@ -406,7 +421,9 @@ declare interface Window {
|
||||
userContextId: number;
|
||||
forceNonPrivate: boolean;
|
||||
relatedToCurrent: boolean;
|
||||
resolveOnContentBrowserCreated: (contentBrowser: MockedExports.ChromeBrowser) => unknown;
|
||||
resolveOnContentBrowserCreated: (
|
||||
contentBrowser: MockedExports.ChromeBrowser
|
||||
) => unknown;
|
||||
}>
|
||||
) => void;
|
||||
openTrustedLinkIn: (
|
||||
@@ -417,7 +434,9 @@ declare interface Window {
|
||||
userContextId: number;
|
||||
forceNonPrivate: boolean;
|
||||
relatedToCurrent: boolean;
|
||||
resolveOnContentBrowserCreated: (contentBrowser: MockedExports.ChromeBrowser) => unknown;
|
||||
resolveOnContentBrowserCreated: (
|
||||
contentBrowser: MockedExports.ChromeBrowser
|
||||
) => unknown;
|
||||
}>
|
||||
) => void;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
|
||||
|
||||
#anchor;
|
||||
#emojiAsSVG = false;
|
||||
#closeOnSelect = true;
|
||||
#onSelect = null;
|
||||
#hasSelection = false;
|
||||
#lastSelectedEmoji = null;
|
||||
|
||||
#currentPromise = null;
|
||||
#currentPromiseResolve = null;
|
||||
@@ -59,7 +63,9 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
|
||||
case "command":
|
||||
if (event.target.id === "PanelUI-zen-emojis-picker-none") {
|
||||
this.#selectEmoji(null);
|
||||
} else if (event.target.id === "PanelUI-zen-emojis-picker-change-emojis") {
|
||||
} else if (
|
||||
event.target.id === "PanelUI-zen-emojis-picker-change-emojis"
|
||||
) {
|
||||
this.#changePage(false);
|
||||
} else if (event.target.id === "PanelUI-zen-emojis-picker-change-svg") {
|
||||
this.#changePage(true);
|
||||
@@ -100,7 +106,9 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
|
||||
#changePage(toSvg = false) {
|
||||
const itemToScroll = toSvg
|
||||
? this.svgList
|
||||
: document.getElementById("PanelUI-zen-emojis-picker-pages").querySelector('[emojis="true"]');
|
||||
: document
|
||||
.getElementById("PanelUI-zen-emojis-picker-pages")
|
||||
.querySelector('[emojis="true"]');
|
||||
itemToScroll.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "nearest",
|
||||
@@ -120,20 +128,32 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
|
||||
delete this._emojis;
|
||||
}
|
||||
|
||||
#setAllowNone(allowNone) {
|
||||
if (allowNone) {
|
||||
this.#panel.removeAttribute("hide-none-option");
|
||||
return;
|
||||
}
|
||||
this.#panel.setAttribute("hide-none-option", "true");
|
||||
}
|
||||
|
||||
#onSearchInput(event) {
|
||||
const input = event.target;
|
||||
const value = input.value.trim().toLowerCase();
|
||||
// search for emojis.tags and order by emojis.order
|
||||
const filteredEmojis = this.#emojis
|
||||
.filter((emoji) => {
|
||||
return emoji.tags.some((tag) => tag.toLowerCase().includes(value));
|
||||
.filter(emoji => {
|
||||
return emoji.tags.some(tag => tag.toLowerCase().includes(value));
|
||||
})
|
||||
.sort((a, b) => a.order - b.order);
|
||||
for (const button of this.emojiList.children) {
|
||||
const buttonEmoji = button.getAttribute("label");
|
||||
const emojiObject = filteredEmojis.find((emoji) => emoji.emoji === buttonEmoji);
|
||||
const emojiObject = filteredEmojis.find(
|
||||
emoji => emoji.emoji === buttonEmoji
|
||||
);
|
||||
if (emojiObject) {
|
||||
button.hidden = !emojiObject.tags.some((tag) => tag.toLowerCase().includes(value));
|
||||
button.hidden = !emojiObject.tags.some(tag =>
|
||||
tag.toLowerCase().includes(value)
|
||||
);
|
||||
button.style.order = emojiObject.order;
|
||||
} else {
|
||||
button.hidden = true;
|
||||
@@ -192,13 +212,21 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
|
||||
|
||||
this.svgList.innerHTML = "";
|
||||
|
||||
if (this.#currentPromiseReject) {
|
||||
this.#currentPromiseReject(new Error("Emoji picker closed without selection"));
|
||||
if (!this.#hasSelection) {
|
||||
this.#currentPromiseReject?.(
|
||||
new Error("Emoji picker closed without selection")
|
||||
);
|
||||
} else if (!this.#closeOnSelect) {
|
||||
this.#currentPromiseResolve?.(this.#lastSelectedEmoji);
|
||||
}
|
||||
|
||||
this.#currentPromise = null;
|
||||
this.#currentPromiseResolve = null;
|
||||
this.#currentPromiseReject = null;
|
||||
this.#onSelect = null;
|
||||
this.#closeOnSelect = true;
|
||||
this.#hasSelection = false;
|
||||
this.#lastSelectedEmoji = null;
|
||||
|
||||
this.#anchor.removeAttribute("zen-emoji-open");
|
||||
this.#anchor.parentElement.removeAttribute("zen-emoji-open");
|
||||
@@ -213,15 +241,35 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
|
||||
)}</text></svg>`
|
||||
)}`;
|
||||
}
|
||||
this.#setAllowNone(Boolean(emoji));
|
||||
this.#hasSelection = true;
|
||||
this.#lastSelectedEmoji = emoji;
|
||||
this.#onSelect?.(emoji);
|
||||
if (!this.#closeOnSelect) {
|
||||
return;
|
||||
}
|
||||
this.#currentPromiseResolve?.(emoji);
|
||||
this.#panel.hidePopup();
|
||||
}
|
||||
|
||||
open(anchor, { onlySvgIcons = false, emojiAsSVG = false } = {}) {
|
||||
open(
|
||||
anchor,
|
||||
{
|
||||
onlySvgIcons = false,
|
||||
emojiAsSVG = false,
|
||||
allowNone = true,
|
||||
closeOnSelect = true,
|
||||
onSelect = null,
|
||||
} = {}
|
||||
) {
|
||||
if (this.#currentPromise) {
|
||||
return null;
|
||||
}
|
||||
this.#emojiAsSVG = emojiAsSVG;
|
||||
this.#closeOnSelect = closeOnSelect;
|
||||
this.#onSelect = onSelect;
|
||||
this.#hasSelection = false;
|
||||
this.#lastSelectedEmoji = null;
|
||||
this.#currentPromise = new Promise((resolve, reject) => {
|
||||
this.#currentPromiseResolve = resolve;
|
||||
this.#currentPromiseReject = reject;
|
||||
@@ -234,6 +282,7 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
|
||||
} else {
|
||||
this.#panel.removeAttribute("only-svg-icons");
|
||||
}
|
||||
this.#setAllowNone(allowNone);
|
||||
this.#panel.openPopup(anchor, "after_start", 0, 0, false, false);
|
||||
return this.#currentPromise;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -78,7 +78,9 @@ export class nsZenDOMOperatedFeature {
|
||||
export class nsZenPreloadedFeature {
|
||||
constructor() {
|
||||
var initBound = this.init.bind(this);
|
||||
document.addEventListener("MozBeforeInitialXULLayout", initBound, { once: true });
|
||||
document.addEventListener("MozBeforeInitialXULLayout", initBound, {
|
||||
once: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +94,7 @@ window.gZenCommonActions = {
|
||||
if (Services.zen.canShare() && displaySpec.startsWith("http")) {
|
||||
button = {
|
||||
id: "zen-copy-current-url-button",
|
||||
command: (event) => {
|
||||
command: event => {
|
||||
const buttonRect = event.target.getBoundingClientRect();
|
||||
/* eslint-disable mozilla/valid-services */
|
||||
Services.zen.share(
|
||||
@@ -107,7 +109,10 @@ window.gZenCommonActions = {
|
||||
},
|
||||
};
|
||||
}
|
||||
gZenUIManager.showToast("zen-copy-current-url-confirmation", { button, timeout: 3000 });
|
||||
gZenUIManager.showToast("zen-copy-current-url-confirmation", {
|
||||
button,
|
||||
timeout: 3000,
|
||||
});
|
||||
},
|
||||
|
||||
copyCurrentURLAsMarkdownToClipboard() {
|
||||
@@ -115,7 +120,9 @@ window.gZenCommonActions = {
|
||||
const tabTitle = gBrowser.selectedTab.label;
|
||||
const markdownLink = `[${tabTitle}](${currentUrl.displaySpec})`;
|
||||
ClipboardHelper.copyString(markdownLink);
|
||||
gZenUIManager.showToast("zen-copy-current-url-confirmation", { timeout: 3000 });
|
||||
gZenUIManager.showToast("zen-copy-current-url-as-markdown-confirmation", {
|
||||
timeout: 3000,
|
||||
});
|
||||
},
|
||||
|
||||
throttle(f, delay) {
|
||||
@@ -134,10 +141,17 @@ window.gZenCommonActions = {
|
||||
* @returns {boolean} True if the tab should be closed on back
|
||||
*/
|
||||
shouldCloseTabOnBack() {
|
||||
if (!Services.prefs.getBoolPref("zen.tabs.close-on-back-with-no-history", true)) {
|
||||
if (
|
||||
!Services.prefs.getBoolPref(
|
||||
"zen.tabs.close-on-back-with-no-history",
|
||||
true
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
const tab = gBrowser.selectedTab;
|
||||
return Boolean(tab.owner && !tab.pinned && !tab.hasAttribute("zen-empty-tab"));
|
||||
return Boolean(
|
||||
tab.owner && !tab.pinned && !tab.hasAttribute("zen-empty-tab")
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -14,7 +14,12 @@ class nsHasPolyfill {
|
||||
* @param {string} stateAttribute
|
||||
* @param {Array<string>} attributeFilter
|
||||
*/
|
||||
observeSelectorExistence(element, descendantSelectors, stateAttribute, attributeFilter = []) {
|
||||
observeSelectorExistence(
|
||||
element,
|
||||
descendantSelectors,
|
||||
stateAttribute,
|
||||
attributeFilter = []
|
||||
) {
|
||||
const updateState = () => {
|
||||
const exists = descendantSelectors.some(({ selector }) => {
|
||||
let selected = element.querySelector(selector);
|
||||
@@ -26,10 +31,18 @@ class nsHasPolyfill {
|
||||
const { exists: shouldExist = true } = descendantSelectors;
|
||||
if (exists === shouldExist) {
|
||||
if (!element.hasAttribute(stateAttribute)) {
|
||||
gZenCompactModeManager._setElementExpandAttribute(element, true, stateAttribute);
|
||||
gZenCompactModeManager._setElementExpandAttribute(
|
||||
element,
|
||||
true,
|
||||
stateAttribute
|
||||
);
|
||||
}
|
||||
} else if (element.hasAttribute(stateAttribute)) {
|
||||
gZenCompactModeManager._setElementExpandAttribute(element, false, stateAttribute);
|
||||
gZenCompactModeManager._setElementExpandAttribute(
|
||||
element,
|
||||
false,
|
||||
stateAttribute
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,31 +59,35 @@ class nsHasPolyfill {
|
||||
}
|
||||
|
||||
disconnectObserver(observerId) {
|
||||
const index = this.observers.findIndex((o) => o.id === observerId);
|
||||
const index = this.observers.findIndex(o => o.id === observerId);
|
||||
if (index !== -1) {
|
||||
this.observers[index].observer.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
connectObserver(observerId) {
|
||||
const observer = this.observers.find((o) => o.id === observerId);
|
||||
const observer = this.observers.find(o => o.id === observerId);
|
||||
if (observer) {
|
||||
observer.observer.observe(observer.element, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
attributeFilter: observer.attributeFilter.length ? observer.attributeFilter : undefined,
|
||||
attributeFilter: observer.attributeFilter.length
|
||||
? observer.attributeFilter
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.observers.forEach((observer) => observer.observer.disconnect());
|
||||
this.observers.forEach(observer => observer.observer.disconnect());
|
||||
this.observers = [];
|
||||
}
|
||||
}
|
||||
|
||||
const hasPolyfillInstance = new nsHasPolyfill();
|
||||
window.addEventListener("unload", () => hasPolyfillInstance.destroy(), { once: true });
|
||||
window.addEventListener("unload", () => hasPolyfillInstance.destroy(), {
|
||||
once: true,
|
||||
});
|
||||
|
||||
window.ZenHasPolyfill = hasPolyfillInstance;
|
||||
|
||||
@@ -38,7 +38,7 @@ export class nsZenMenuBar {
|
||||
</menupopup>
|
||||
</menu>`);
|
||||
const menu = appearanceMenu.querySelector("menu");
|
||||
menu.addEventListener("command", (event) => {
|
||||
menu.addEventListener("command", event => {
|
||||
const type = event.target.getAttribute("data-type");
|
||||
const schemeValue = WINDOW_SCHEME_MAPPING[type];
|
||||
Services.prefs.setIntPref(WINDOW_SCHEME_PREF, schemeValue);
|
||||
@@ -97,15 +97,17 @@ export class nsZenMenuBar {
|
||||
</menupopup>
|
||||
</menu>`);
|
||||
document.getElementById("view-menu").after(spacesMenubar);
|
||||
document.getElementById("zen-spaces-menubar").addEventListener("popupshowing", () => {
|
||||
if (AppConstants.platform === "linux") {
|
||||
// On linux, there seems to be a bug where the menu freezes up and makes the browser
|
||||
// suppiciously unresponsive if we try to update the menu while it's opening.
|
||||
// See https://github.com/zen-browser/desktop/issues/12024
|
||||
return;
|
||||
}
|
||||
gZenWorkspaces.updateWorkspacesChangeContextMenu();
|
||||
});
|
||||
document
|
||||
.getElementById("zen-spaces-menubar")
|
||||
.addEventListener("popupshowing", () => {
|
||||
if (AppConstants.platform === "linux") {
|
||||
// On linux, there seems to be a bug where the menu freezes up and makes the browser
|
||||
// suppiciously unresponsive if we try to update the menu while it's opening.
|
||||
// See https://github.com/zen-browser/desktop/issues/12024
|
||||
return;
|
||||
}
|
||||
gZenWorkspaces.updateWorkspacesChangeContextMenu();
|
||||
});
|
||||
}
|
||||
|
||||
#initAppMenu() {
|
||||
@@ -133,7 +135,10 @@ export class nsZenMenuBar {
|
||||
if (!Services.prefs.getBoolPref("zen.window-sync.enabled", true)) {
|
||||
return;
|
||||
}
|
||||
const itemsToHide = ["appMenuRecentlyClosedWindows", "historyUndoWindowMenu"];
|
||||
const itemsToHide = [
|
||||
"appMenuRecentlyClosedWindows",
|
||||
"historyUndoWindowMenu",
|
||||
];
|
||||
for (const id of itemsToHide) {
|
||||
const element = PanelMultiView.getViewNode(document, id);
|
||||
element.setAttribute("hidden", "true");
|
||||
|
||||
@@ -9,7 +9,7 @@ class ZenSessionStore extends nsZenPreloadedFeature {
|
||||
this.#waitAndCleanup();
|
||||
}
|
||||
|
||||
promiseInitialized = new Promise((resolve) => {
|
||||
promiseInitialized = new Promise(resolve => {
|
||||
this._resolveInitialized = resolve;
|
||||
});
|
||||
|
||||
|
||||
@@ -47,19 +47,24 @@ class ZenSidebarNotification extends MozLitElement {
|
||||
return html`
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="chrome://browser/content/zen-styles/zen-sidebar-notification.css" />
|
||||
href="chrome://browser/content/zen-styles/zen-sidebar-notification.css"
|
||||
/>
|
||||
<div class="zen-sidebar-notification-header">
|
||||
<label
|
||||
class="zen-sidebar-notification-heading"
|
||||
flex="1"
|
||||
data-l10n-id=${this.headingL10nId}></label>
|
||||
<div class="zen-sidebar-notification-close-button" @click=${() => this.remove()}>
|
||||
data-l10n-id=${this.headingL10nId}
|
||||
></label>
|
||||
<div
|
||||
class="zen-sidebar-notification-close-button"
|
||||
@click=${() => this.remove()}
|
||||
>
|
||||
<img src="chrome://browser/skin/zen-icons/close.svg" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="zen-sidebar-notification-body">
|
||||
${this.links.map(
|
||||
(link) => html`
|
||||
link => html`
|
||||
<div
|
||||
class="zen-sidebar-notification-link-container"
|
||||
data-l10n-id="${link.l10nId}-tooltip"
|
||||
@@ -70,15 +75,21 @@ class ZenSidebarNotification extends MozLitElement {
|
||||
return;
|
||||
}
|
||||
window.openLinkIn(link.url, "tab", {
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
triggeringPrincipal:
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
forceForeground: true,
|
||||
});
|
||||
this.remove();
|
||||
}}>
|
||||
<img class="zen-sidebar-notification-link-icon" src=${link.icon} />
|
||||
}}
|
||||
>
|
||||
<img
|
||||
class="zen-sidebar-notification-link-icon"
|
||||
src=${link.icon}
|
||||
/>
|
||||
<label
|
||||
class="zen-sidebar-notification-link-text"
|
||||
data-l10n-id="${link.l10nId}-label"></label>
|
||||
data-l10n-id="${link.l10nId}-label"
|
||||
></label>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
|
||||
@@ -11,26 +11,21 @@ class ZenStartup {
|
||||
#hasInitializedLayout = false;
|
||||
|
||||
isReady = false;
|
||||
promiseInitialized = new Promise(resolve => {
|
||||
this.promiseInitializedResolve = resolve;
|
||||
});
|
||||
|
||||
init() {
|
||||
this.openWatermark();
|
||||
this.#initBrowserBackground();
|
||||
this.#changeSidebarLocation();
|
||||
this.#zenInitBrowserLayout();
|
||||
}
|
||||
|
||||
#initBrowserBackground() {
|
||||
const background = document.createXULElement("box");
|
||||
background.id = "zen-browser-background";
|
||||
background.classList.add("zen-browser-generic-background");
|
||||
const grain = document.createXULElement("box");
|
||||
grain.classList.add("zen-browser-grain");
|
||||
background.appendChild(grain);
|
||||
document.getElementById("browser").prepend(background);
|
||||
const toolbarBackground = background.cloneNode(true);
|
||||
toolbarBackground.removeAttribute("id");
|
||||
toolbarBackground.classList.add("zen-toolbar-background");
|
||||
document.getElementById("titlebar").prepend(toolbarBackground);
|
||||
get #shouldUseWatermark() {
|
||||
return (
|
||||
Services.prefs.getBoolPref("zen.watermark.enabled", false) &&
|
||||
gZenWorkspaces.shouldHaveWorkspaces
|
||||
);
|
||||
}
|
||||
|
||||
#zenInitBrowserLayout() {
|
||||
@@ -53,7 +48,9 @@ class ZenStartup {
|
||||
}
|
||||
|
||||
// Fix notification deck
|
||||
const deckTemplate = document.getElementById("tab-notification-deck-template");
|
||||
const deckTemplate = document.getElementById(
|
||||
"tab-notification-deck-template"
|
||||
);
|
||||
if (deckTemplate) {
|
||||
document.getElementById("zen-appcontent-wrapper").prepend(deckTemplate);
|
||||
}
|
||||
@@ -96,13 +93,17 @@ class ZenStartup {
|
||||
// Just in case we didn't get the right size.
|
||||
gZenUIManager.updateTabsToolbar();
|
||||
this.closeWatermark();
|
||||
document.getElementById("tabbrowser-arrowscrollbox").setAttribute("orient", "vertical");
|
||||
document
|
||||
.getElementById("tabbrowser-arrowscrollbox")
|
||||
.setAttribute("orient", "vertical");
|
||||
this.isReady = true;
|
||||
this.promiseInitializedResolve();
|
||||
delete this.promiseInitializedResolve;
|
||||
});
|
||||
}
|
||||
|
||||
openWatermark() {
|
||||
if (!Services.prefs.getBoolPref("zen.watermark.enabled", false)) {
|
||||
if (!this.#shouldUseWatermark) {
|
||||
document.documentElement.removeAttribute("zen-before-loaded");
|
||||
return;
|
||||
}
|
||||
@@ -113,11 +114,15 @@ class ZenStartup {
|
||||
|
||||
closeWatermark() {
|
||||
document.documentElement.removeAttribute("zen-before-loaded");
|
||||
if (Services.prefs.getBoolPref("zen.watermark.enabled", false)) {
|
||||
let elementsToIgnore = this.#watermarkIgnoreElements.map((id) => "#" + id).join(", ");
|
||||
if (this.#shouldUseWatermark) {
|
||||
let elementsToIgnore = this.#watermarkIgnoreElements
|
||||
.map(id => "#" + id)
|
||||
.join(", ");
|
||||
gZenUIManager.motion
|
||||
.animate(
|
||||
"#browser > *:not(" + elementsToIgnore + "), #urlbar, #tabbrowser-tabbox > *",
|
||||
"#browser > *:not(" +
|
||||
elementsToIgnore +
|
||||
"), #urlbar, #tabbrowser-tabbox > *",
|
||||
{
|
||||
opacity: [0, 1],
|
||||
},
|
||||
@@ -156,8 +161,14 @@ class ZenStartup {
|
||||
#checkForWelcomePage() {
|
||||
if (!Services.prefs.getBoolPref("zen.welcome-screen.seen", false)) {
|
||||
Services.prefs.setBoolPref("zen.welcome-screen.seen", true);
|
||||
Services.prefs.setStringPref("zen.updates.last-build-id", Services.appinfo.appBuildID);
|
||||
Services.prefs.setStringPref("zen.updates.last-version", Services.appinfo.version);
|
||||
Services.prefs.setStringPref(
|
||||
"zen.updates.last-build-id",
|
||||
Services.appinfo.appBuildID
|
||||
);
|
||||
Services.prefs.setStringPref(
|
||||
"zen.updates.last-version",
|
||||
Services.appinfo.version
|
||||
);
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://browser/content/zen-components/ZenWelcome.mjs",
|
||||
window
|
||||
|
||||
@@ -10,7 +10,10 @@ window.gZenUIManager = {
|
||||
_hoverPausedForExpand: false,
|
||||
_hasLoadedDOM: false,
|
||||
testingEnabled: Services.prefs.getBoolPref("zen.testing.enabled", false),
|
||||
profilingEnabled: Services.prefs.getBoolPref("zen.testing.profiling.enabled", false),
|
||||
profilingEnabled: Services.prefs.getBoolPref(
|
||||
"zen.testing.profiling.enabled",
|
||||
false
|
||||
),
|
||||
|
||||
_lastClickPosition: null,
|
||||
|
||||
@@ -22,7 +25,11 @@ window.gZenUIManager = {
|
||||
document.addEventListener("popupshowing", this.onPopupShowing.bind(this));
|
||||
document.addEventListener("popuphidden", this.onPopupHidden.bind(this));
|
||||
|
||||
document.addEventListener("mousedown", this.handleMouseDown.bind(this), true);
|
||||
document.addEventListener(
|
||||
"mousedown",
|
||||
this.handleMouseDown.bind(this),
|
||||
true
|
||||
);
|
||||
|
||||
ChromeUtils.defineLazyGetter(this, "motion", () => {
|
||||
Services.scriptloader.loadSubScript(
|
||||
@@ -40,7 +47,9 @@ window.gZenUIManager = {
|
||||
|
||||
new ResizeObserver(
|
||||
gZenCommonActions.throttle(
|
||||
gZenCompactModeManager.getAndApplySidebarWidth.bind(gZenCompactModeManager),
|
||||
gZenCompactModeManager.getAndApplySidebarWidth.bind(
|
||||
gZenCompactModeManager
|
||||
),
|
||||
Services.prefs.getIntPref("zen.view.sidebar-height-throttle", 500)
|
||||
)
|
||||
).observe(gNavToolbox);
|
||||
@@ -82,7 +91,10 @@ window.gZenUIManager = {
|
||||
rawKeyframes = { ...rawKeyframes };
|
||||
// Convert 'y' property to 'transform' with translateY and 'x' to translateX,
|
||||
// and 'scale' to 'transform' with scale.
|
||||
if ((rawKeyframes.y || rawKeyframes.x || rawKeyframes.scale) && !rawKeyframes.transform) {
|
||||
if (
|
||||
(rawKeyframes.y || rawKeyframes.x || rawKeyframes.scale) &&
|
||||
!rawKeyframes.transform
|
||||
) {
|
||||
const yValues = rawKeyframes.y || [];
|
||||
const xValues = rawKeyframes.x || [];
|
||||
const scaleValues = rawKeyframes.scale || [];
|
||||
@@ -90,14 +102,23 @@ window.gZenUIManager = {
|
||||
delete rawKeyframes.x;
|
||||
delete rawKeyframes.scale;
|
||||
rawKeyframes.transform = [];
|
||||
if (yValues.length !== 0 && xValues.length !== 0 && yValues.length !== xValues.length) {
|
||||
if (
|
||||
yValues.length !== 0 &&
|
||||
xValues.length !== 0 &&
|
||||
yValues.length !== xValues.length
|
||||
) {
|
||||
console.error("y and x keyframes must have the same length");
|
||||
}
|
||||
const keyframeLength = Math.max(yValues.length, xValues.length, scaleValues.length);
|
||||
const keyframeLength = Math.max(
|
||||
yValues.length,
|
||||
xValues.length,
|
||||
scaleValues.length
|
||||
);
|
||||
for (let i = 0; i < keyframeLength; i++) {
|
||||
const y = yValues[i] !== undefined ? `translateY(${yValues[i]}px)` : "";
|
||||
const x = xValues[i] !== undefined ? `translateX(${xValues[i]}px)` : "";
|
||||
const scale = scaleValues[i] !== undefined ? `scale(${scaleValues[i]})` : "";
|
||||
const scale =
|
||||
scaleValues[i] !== undefined ? `scale(${scaleValues[i]})` : "";
|
||||
rawKeyframes.transform.push(`${x} ${y} ${scale}`.trim());
|
||||
}
|
||||
}
|
||||
@@ -109,7 +130,7 @@ window.gZenUIManager = {
|
||||
}
|
||||
keyframes.push(frame);
|
||||
}
|
||||
return await new Promise((resolve) => {
|
||||
return await new Promise(resolve => {
|
||||
const animation = element.animate(keyframes, ...args);
|
||||
animation.onfinish = () => resolve();
|
||||
});
|
||||
@@ -117,10 +138,19 @@ window.gZenUIManager = {
|
||||
|
||||
_addNewCustomizableButtonsIfNeeded() {
|
||||
const kPref = "zen.ui.migration.compact-mode-button-added";
|
||||
let navbarPlacements = CustomizableUI.getWidgetIdsInArea("zen-sidebar-top-buttons");
|
||||
let navbarPlacements = CustomizableUI.getWidgetIdsInArea(
|
||||
"zen-sidebar-top-buttons"
|
||||
);
|
||||
try {
|
||||
if (!navbarPlacements.length && !Services.prefs.getBoolPref(kPref, false)) {
|
||||
CustomizableUI.addWidgetToArea("zen-toggle-compact-mode", "zen-sidebar-top-buttons", 0);
|
||||
if (
|
||||
!navbarPlacements.length &&
|
||||
!Services.prefs.getBoolPref(kPref, false)
|
||||
) {
|
||||
CustomizableUI.addWidgetToArea(
|
||||
"zen-toggle-compact-mode",
|
||||
"zen-sidebar-top-buttons",
|
||||
0
|
||||
);
|
||||
gZenVerticalTabsManager._topButtonsSeparatorElement.before(
|
||||
document.getElementById("zen-toggle-compact-mode")
|
||||
);
|
||||
@@ -138,7 +168,7 @@ window.gZenUIManager = {
|
||||
// is ran before this function.
|
||||
document.documentElement.setAttribute("zen-has-bookmarks", "true");
|
||||
}
|
||||
bookmarkToolbar.addEventListener("toolbarvisibilitychange", (event) => {
|
||||
bookmarkToolbar.addEventListener("toolbarvisibilitychange", event => {
|
||||
const visible = event.detail.visible;
|
||||
if (visible) {
|
||||
document.documentElement.setAttribute("zen-has-bookmarks", "true");
|
||||
@@ -221,11 +251,16 @@ window.gZenUIManager = {
|
||||
const kUrlbarHeight = 335;
|
||||
gURLBar.style.setProperty(
|
||||
"--zen-urlbar-top",
|
||||
`${window.innerHeight / 2 - Math.max(kUrlbarHeight, gURLBar.getBoundingClientRect().height) / 2}px`
|
||||
`${window.innerHeight / 2 - Math.max(kUrlbarHeight, window.windowUtils.getBoundsWithoutFlushing(gURLBar).height) / 2}px`
|
||||
);
|
||||
gURLBar.style.setProperty("--zen-urlbar-width", `${Math.min(window.innerWidth / 2, 750)}px`);
|
||||
gZenVerticalTabsManager.actualWindowButtons.removeAttribute("zen-has-hover");
|
||||
gZenVerticalTabsManager.recalculateURLBarHeight();
|
||||
gURLBar.style.setProperty(
|
||||
"--zen-urlbar-width",
|
||||
`${Math.min(window.innerWidth / 2, 750)}px`
|
||||
);
|
||||
gZenVerticalTabsManager.actualWindowButtons.removeAttribute(
|
||||
"zen-has-hover"
|
||||
);
|
||||
gZenVerticalTabsManager.recalculateURLBarHeight(true);
|
||||
if (!this._preventToolbarRebuild) {
|
||||
setTimeout(() => {
|
||||
gZenWorkspaces.updateTabsContainers();
|
||||
@@ -256,7 +291,10 @@ window.gZenUIManager = {
|
||||
|
||||
openAndChangeToTab(url, options) {
|
||||
if (window.ownerGlobal.parent) {
|
||||
const tab = window.ownerGlobal.parent.gBrowser.addTrustedTab(url, options);
|
||||
const tab = window.ownerGlobal.parent.gBrowser.addTrustedTab(
|
||||
url,
|
||||
options
|
||||
);
|
||||
window.ownerGlobal.parent.gBrowser.selectedTab = tab;
|
||||
return tab;
|
||||
}
|
||||
@@ -270,7 +308,10 @@ window.gZenUIManager = {
|
||||
},
|
||||
|
||||
createValidXULText(text) {
|
||||
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
return text
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">");
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -302,7 +343,11 @@ window.gZenUIManager = {
|
||||
continue;
|
||||
}
|
||||
document.removeEventListener("mousemove", this.__removeHasPopupAttribute);
|
||||
gZenCompactModeManager._setElementExpandAttribute(el, true, "has-popup-menu");
|
||||
gZenCompactModeManager._setElementExpandAttribute(
|
||||
el,
|
||||
true,
|
||||
"has-popup-menu"
|
||||
);
|
||||
this.__currentPopup = showEvent.target;
|
||||
this.__currentPopupTrackElement = el;
|
||||
break;
|
||||
@@ -315,11 +360,21 @@ window.gZenUIManager = {
|
||||
}
|
||||
const element = this.__currentPopupTrackElement;
|
||||
if (document.getElementById("main-window").matches(":hover")) {
|
||||
gZenCompactModeManager._setElementExpandAttribute(element, false, "has-popup-menu");
|
||||
gZenCompactModeManager._setElementExpandAttribute(
|
||||
element,
|
||||
false,
|
||||
"has-popup-menu"
|
||||
);
|
||||
} else {
|
||||
this.__removeHasPopupAttribute = () =>
|
||||
gZenCompactModeManager._setElementExpandAttribute(element, false, "has-popup-menu");
|
||||
document.addEventListener("mousemove", this.__removeHasPopupAttribute, { once: true });
|
||||
gZenCompactModeManager._setElementExpandAttribute(
|
||||
element,
|
||||
false,
|
||||
"has-popup-menu"
|
||||
);
|
||||
document.addEventListener("mousemove", this.__removeHasPopupAttribute, {
|
||||
once: true,
|
||||
});
|
||||
}
|
||||
this.__currentPopup = null;
|
||||
this.__currentPopupTrackElement = null;
|
||||
@@ -347,9 +402,11 @@ window.gZenUIManager = {
|
||||
const input = gURLBar;
|
||||
if (gURLBar.hasAttribute("breakout-extend") && !this._animatingSearchMode) {
|
||||
this._animatingSearchMode = true;
|
||||
this.motion.animate(input, { scale: [1, 0.98, 1] }, { duration: 0.25 }).then(() => {
|
||||
delete this._animatingSearchMode;
|
||||
});
|
||||
this.motion
|
||||
.animate(input, { scale: [1, 0.98, 1] }, { duration: 0.25 })
|
||||
.then(() => {
|
||||
delete this._animatingSearchMode;
|
||||
});
|
||||
if (searchMode) {
|
||||
gURLBar.setAttribute("animate-searchmode", "true");
|
||||
this._animatingSearchModeTimeout = setTimeout(() => {
|
||||
@@ -416,7 +473,12 @@ window.gZenUIManager = {
|
||||
return true;
|
||||
},
|
||||
|
||||
handleNewTab(werePassedURL, searchClipboard, where, overridePreferance = false) {
|
||||
handleNewTab(
|
||||
werePassedURL,
|
||||
searchClipboard,
|
||||
where,
|
||||
overridePreferance = false
|
||||
) {
|
||||
// Validate browser state first
|
||||
if (!this._validateBrowserState()) {
|
||||
console.warn("Browser state invalid for new tab operation");
|
||||
@@ -548,7 +610,9 @@ window.gZenUIManager = {
|
||||
if (isFocusedBefore) {
|
||||
setTimeout(() => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("ZenURLBarClosed", { detail: { onSwitch, onElementPicked } })
|
||||
new CustomEvent("ZenURLBarClosed", {
|
||||
detail: { onSwitch, onElementPicked },
|
||||
})
|
||||
);
|
||||
gURLBar.view.close({ elementPicked: onElementPicked });
|
||||
gURLBar.updateTextOverflow();
|
||||
@@ -559,8 +623,15 @@ window.gZenUIManager = {
|
||||
|
||||
// Ensure tab and browser are valid before updating state
|
||||
const selectedTab = gBrowser.selectedTab;
|
||||
if (selectedTab && selectedTab.linkedBrowser && !selectedTab.closing && onSwitch) {
|
||||
const browserState = gURLBar.getBrowserState(selectedTab.linkedBrowser);
|
||||
if (
|
||||
selectedTab &&
|
||||
selectedTab.linkedBrowser &&
|
||||
!selectedTab.closing &&
|
||||
onSwitch
|
||||
) {
|
||||
const browserState = gURLBar.getBrowserState(
|
||||
selectedTab.linkedBrowser
|
||||
);
|
||||
if (browserState) {
|
||||
browserState.urlbarFocused = false;
|
||||
}
|
||||
@@ -574,7 +645,10 @@ window.gZenUIManager = {
|
||||
if (gURLBar.hasAttribute("breakout-extend")) {
|
||||
return aURL;
|
||||
}
|
||||
if (gZenVerticalTabsManager._hasSetSingleToolbar && this.urlbarShowDomainOnly) {
|
||||
if (
|
||||
gZenVerticalTabsManager._hasSetSingleToolbar &&
|
||||
this.urlbarShowDomainOnly
|
||||
) {
|
||||
let url = BrowserUIUtils.removeSingleTrailingSlashFromURL(aURL);
|
||||
return url.startsWith("https://") ? url.split("/")[2] : url;
|
||||
}
|
||||
@@ -639,7 +713,11 @@ window.gZenUIManager = {
|
||||
return;
|
||||
}
|
||||
this.motion
|
||||
.animate(toast, { opacity: [1, 0], scale: [1, 0.5] }, { duration: 0.2, bounce: 0 })
|
||||
.animate(
|
||||
toast,
|
||||
{ opacity: [1, 0], scale: [1, 0.5] },
|
||||
{ duration: 0.2, bounce: 0 }
|
||||
)
|
||||
.then(() => {
|
||||
toast.remove();
|
||||
if (this._toastContainer.children.length === 0) {
|
||||
@@ -648,7 +726,11 @@ window.gZenUIManager = {
|
||||
});
|
||||
};
|
||||
if (reused) {
|
||||
await this.motion.animate(toast, { scale: 0.2 }, { duration: 0.1, bounce: 0 });
|
||||
await this.motion.animate(
|
||||
toast,
|
||||
{ scale: 0.2 },
|
||||
{ duration: 0.1, bounce: 0 }
|
||||
);
|
||||
} else {
|
||||
toast.addEventListener("mouseover", () => {
|
||||
if (this._toastTimeouts[messageId]) {
|
||||
@@ -659,17 +741,27 @@ window.gZenUIManager = {
|
||||
if (this._toastTimeouts[messageId]) {
|
||||
clearTimeout(this._toastTimeouts[messageId]);
|
||||
}
|
||||
this._toastTimeouts[messageId] = setTimeout(timeoutFunction, options.timeout || 2000);
|
||||
this._toastTimeouts[messageId] = setTimeout(
|
||||
timeoutFunction,
|
||||
options.timeout || 2000
|
||||
);
|
||||
});
|
||||
}
|
||||
if (!toast.style.transform) {
|
||||
toast.style.transform = "scale(0)";
|
||||
}
|
||||
await this.motion.animate(toast, { scale: 1 }, { type: "spring", bounce: 0.2, duration: 0.5 });
|
||||
await this.motion.animate(
|
||||
toast,
|
||||
{ scale: 1 },
|
||||
{ type: "spring", bounce: 0.2, duration: 0.5 }
|
||||
);
|
||||
if (this._toastTimeouts[messageId]) {
|
||||
clearTimeout(this._toastTimeouts[messageId]);
|
||||
}
|
||||
this._toastTimeouts[messageId] = setTimeout(timeoutFunction, options.timeout || 2000);
|
||||
this._toastTimeouts[messageId] = setTimeout(
|
||||
timeoutFunction,
|
||||
options.timeout || 2000
|
||||
);
|
||||
},
|
||||
|
||||
panelUIPosition(panel, anchor) {
|
||||
@@ -722,10 +814,12 @@ window.gZenUIManager = {
|
||||
block = "topleft";
|
||||
}
|
||||
if (
|
||||
(gZenVerticalTabsManager._hasSetSingleToolbar && gZenVerticalTabsManager._prefsRightSide) ||
|
||||
(gZenVerticalTabsManager._hasSetSingleToolbar &&
|
||||
gZenVerticalTabsManager._prefsRightSide) ||
|
||||
(panel?.id === "zen-unified-site-data-panel" &&
|
||||
!gZenVerticalTabsManager._hasSetSingleToolbar) ||
|
||||
(panel?.id === "unified-extensions-panel" && gZenVerticalTabsManager._hasSetSingleToolbar)
|
||||
(panel?.id === "unified-extensions-panel" &&
|
||||
gZenVerticalTabsManager._hasSetSingleToolbar)
|
||||
) {
|
||||
block = "bottomright";
|
||||
inline = "topright";
|
||||
@@ -787,14 +881,20 @@ window.gZenVerticalTabsManager = {
|
||||
return !(
|
||||
window.AppConstants.platform === "macosx" ||
|
||||
window.matchMedia("(-moz-gtk-csd-reversed-placement)").matches ||
|
||||
Services.prefs.getBoolPref("zen.view.experimental-force-window-controls-left")
|
||||
Services.prefs.getBoolPref(
|
||||
"zen.view.experimental-force-window-controls-left"
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
ChromeUtils.defineLazyGetter(this, "hidesTabsToolbar", () => {
|
||||
return (
|
||||
document.documentElement.getAttribute("chromehidden")?.includes("toolbar") ||
|
||||
document.documentElement.getAttribute("chromehidden")?.includes("menubar")
|
||||
document.documentElement
|
||||
.getAttribute("chromehidden")
|
||||
?.includes("toolbar") ||
|
||||
document.documentElement
|
||||
.getAttribute("chromehidden")
|
||||
?.includes("menubar")
|
||||
);
|
||||
});
|
||||
|
||||
@@ -808,22 +908,35 @@ window.gZenVerticalTabsManager = {
|
||||
var onPrefChange = this._onPrefChange.bind(this);
|
||||
|
||||
this.initializePreferences(onPrefChange);
|
||||
this._toolbarOriginalParent = document.getElementById("nav-bar").parentElement;
|
||||
this._toolbarOriginalParent =
|
||||
document.getElementById("nav-bar").parentElement;
|
||||
|
||||
gZenCompactModeManager.addEventListener(updateEvent);
|
||||
this.initRightSideOrderContextMenu();
|
||||
|
||||
window.addEventListener("customizationstarting", this._preCustomize.bind(this));
|
||||
window.addEventListener("aftercustomization", this._postCustomize.bind(this));
|
||||
window.addEventListener(
|
||||
"customizationstarting",
|
||||
this._preCustomize.bind(this)
|
||||
);
|
||||
window.addEventListener(
|
||||
"aftercustomization",
|
||||
this._postCustomize.bind(this)
|
||||
);
|
||||
|
||||
this._updateEvent();
|
||||
|
||||
if (!this.isWindowsStyledButtons) {
|
||||
document.documentElement.setAttribute("zen-window-buttons-reversed", true);
|
||||
document.documentElement.setAttribute(
|
||||
"zen-window-buttons-reversed",
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
this._renameTabHalt = this.renameTabHalt.bind(this);
|
||||
gBrowser.tabContainer.addEventListener("dblclick", this.renameTabStart.bind(this));
|
||||
gBrowser.tabContainer.addEventListener(
|
||||
"dblclick",
|
||||
this.renameTabStart.bind(this)
|
||||
);
|
||||
},
|
||||
|
||||
toggleExpand() {
|
||||
@@ -896,7 +1009,7 @@ window.gZenVerticalTabsManager = {
|
||||
}
|
||||
)
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -905,7 +1018,8 @@ window.gZenVerticalTabsManager = {
|
||||
aItem.style.removeProperty("opacity");
|
||||
});
|
||||
const itemLabel =
|
||||
aItem.querySelector(".tab-group-label-container") || aItem.querySelector(".tab-content");
|
||||
aItem.querySelector(".tab-group-label-container") ||
|
||||
aItem.querySelector(".tab-content");
|
||||
gZenUIManager.motion
|
||||
.animate(
|
||||
itemLabel,
|
||||
@@ -918,7 +1032,7 @@ window.gZenVerticalTabsManager = {
|
||||
}
|
||||
)
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -929,15 +1043,20 @@ window.gZenVerticalTabsManager = {
|
||||
}
|
||||
},
|
||||
|
||||
animateTabClose(aTab) {
|
||||
if (aTab.hasAttribute("zen-essential") || aTab.group?.hasAttribute("split-view-group")) {
|
||||
animateItemClose(aItem) {
|
||||
if (
|
||||
aItem.hasAttribute("zen-essential") ||
|
||||
aItem.group?.hasAttribute("split-view-group") ||
|
||||
!gZenUIManager.motion ||
|
||||
gReduceMotion
|
||||
) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const height = aTab.getBoundingClientRect().height;
|
||||
const height = aItem.getBoundingClientRect().height;
|
||||
const visibleItems = gBrowser.tabContainer.ariaFocusableItems;
|
||||
const isLastItem = visibleItems[visibleItems.length - 1] === aTab;
|
||||
const isLastItem = visibleItems[visibleItems.length - 1] === aItem;
|
||||
return gZenUIManager.motion.animate(
|
||||
aTab,
|
||||
aItem,
|
||||
{
|
||||
opacity: [1, 0],
|
||||
transform: ["scale(1)", "scale(0.95)"],
|
||||
@@ -966,7 +1085,7 @@ window.gZenVerticalTabsManager = {
|
||||
},
|
||||
|
||||
async _preCustomize() {
|
||||
await this._multiWindowFeature.foreachWindowAsActive(async (browser) => {
|
||||
await this._multiWindowFeature.foreachWindowAsActive(async browser => {
|
||||
browser.gZenVerticalTabsManager._updateEvent({
|
||||
forCustomizableMode: true,
|
||||
dontRebuildAreas: true,
|
||||
@@ -979,7 +1098,7 @@ window.gZenVerticalTabsManager = {
|
||||
|
||||
_postCustomize() {
|
||||
// No need to use `await` here, because the customization is already done
|
||||
this._multiWindowFeature.foreachWindowAsActive(async (browser) => {
|
||||
this._multiWindowFeature.foreachWindowAsActive(async browser => {
|
||||
browser.gZenVerticalTabsManager._updateEvent({ dontRebuildAreas: true });
|
||||
});
|
||||
},
|
||||
@@ -1023,7 +1142,7 @@ window.gZenVerticalTabsManager = {
|
||||
},
|
||||
|
||||
_initWaitPromise() {
|
||||
this._waitPromise = new Promise((resolve) => {
|
||||
this._waitPromise = new Promise(resolve => {
|
||||
this._resolveWaitPromise = resolve;
|
||||
});
|
||||
},
|
||||
@@ -1032,8 +1151,12 @@ window.gZenVerticalTabsManager = {
|
||||
this._resolveWaitPromise();
|
||||
|
||||
// only run if we are in the active window
|
||||
await this._multiWindowFeature.foreachWindowAsActive(async (browser) => {
|
||||
if (browser.gZenVerticalTabsManager._multiWindowFeature.windowIsActive(browser)) {
|
||||
await this._multiWindowFeature.foreachWindowAsActive(async browser => {
|
||||
if (
|
||||
browser.gZenVerticalTabsManager._multiWindowFeature.windowIsActive(
|
||||
browser
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
await browser.gZenVerticalTabsManager._waitPromise;
|
||||
@@ -1047,7 +1170,7 @@ window.gZenVerticalTabsManager = {
|
||||
}
|
||||
},
|
||||
|
||||
recalculateURLBarHeight() {
|
||||
recalculateURLBarHeight(updateFormat = false) {
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
gURLBar.removeAttribute("--urlbar-height");
|
||||
@@ -1060,7 +1183,9 @@ window.gZenVerticalTabsManager = {
|
||||
if (typeof height !== "undefined") {
|
||||
gURLBar.style.setProperty("--urlbar-height", `${height}px`);
|
||||
}
|
||||
gURLBar.zenFormatURLValue();
|
||||
if (updateFormat) {
|
||||
gURLBar.zenFormatURLValue();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -1082,17 +1207,22 @@ window.gZenVerticalTabsManager = {
|
||||
}
|
||||
|
||||
const topButtons = document.getElementById("zen-sidebar-top-buttons");
|
||||
const isCompactMode = gZenCompactModeManager.preference && !forCustomizableMode;
|
||||
const isCompactMode =
|
||||
gZenCompactModeManager.preference && !forCustomizableMode;
|
||||
const isVerticalTabs = this._prefsVerticalTabs || forCustomizableMode;
|
||||
const isSidebarExpanded = this._prefsSidebarExpanded || !isVerticalTabs;
|
||||
const isRightSide = this._prefsRightSide && isVerticalTabs;
|
||||
const isSingleToolbar =
|
||||
((this._prefsUseSingleToolbar && isVerticalTabs && isSidebarExpanded) || !isVerticalTabs) &&
|
||||
((this._prefsUseSingleToolbar && isVerticalTabs && isSidebarExpanded) ||
|
||||
!isVerticalTabs) &&
|
||||
!forCustomizableMode &&
|
||||
!this.hidesTabsToolbar;
|
||||
const titlebar = document.getElementById("titlebar");
|
||||
|
||||
gBrowser.tabContainer.setAttribute("orient", isVerticalTabs ? "vertical" : "horizontal");
|
||||
gBrowser.tabContainer.setAttribute(
|
||||
"orient",
|
||||
isVerticalTabs ? "vertical" : "horizontal"
|
||||
);
|
||||
gBrowser.tabContainer.arrowScrollbox.setAttribute(
|
||||
"orient",
|
||||
isVerticalTabs ? "vertical" : "horizontal"
|
||||
@@ -1103,7 +1233,9 @@ window.gZenVerticalTabsManager = {
|
||||
isVerticalTabs ? "vertical" : "horizontal"
|
||||
);
|
||||
|
||||
const buttonsTarget = document.getElementById("zen-sidebar-top-buttons-customization-target");
|
||||
const buttonsTarget = document.getElementById(
|
||||
"zen-sidebar-top-buttons-customization-target"
|
||||
);
|
||||
if (isRightSide) {
|
||||
this.navigatorToolbox.setAttribute("zen-right-side", "true");
|
||||
document.documentElement.setAttribute("zen-right-side", "true");
|
||||
@@ -1114,7 +1246,9 @@ window.gZenVerticalTabsManager = {
|
||||
|
||||
delete this._hadSidebarCollapse;
|
||||
if (isSidebarExpanded) {
|
||||
this._hadSidebarCollapse = !document.documentElement.hasAttribute("zen-sidebar-expanded");
|
||||
this._hadSidebarCollapse = !document.documentElement.hasAttribute(
|
||||
"zen-sidebar-expanded"
|
||||
);
|
||||
this.navigatorToolbox.setAttribute("zen-sidebar-expanded", "true");
|
||||
document.documentElement.setAttribute("zen-sidebar-expanded", "true");
|
||||
gBrowser.tabContainer.setAttribute("expanded", "true");
|
||||
@@ -1124,8 +1258,12 @@ window.gZenVerticalTabsManager = {
|
||||
gBrowser.tabContainer.removeAttribute("expanded");
|
||||
}
|
||||
|
||||
const appContentNavbarContaienr = document.getElementById("zen-appcontent-navbar-container");
|
||||
const appContentNavbarWrapper = document.getElementById("zen-appcontent-navbar-wrapper");
|
||||
const appContentNavbarContaienr = document.getElementById(
|
||||
"zen-appcontent-navbar-container"
|
||||
);
|
||||
const appContentNavbarWrapper = document.getElementById(
|
||||
"zen-appcontent-navbar-wrapper"
|
||||
);
|
||||
appContentNavbarWrapper.style.transition = "none";
|
||||
let shouldHide = false;
|
||||
if (
|
||||
@@ -1141,12 +1279,16 @@ window.gZenVerticalTabsManager = {
|
||||
}
|
||||
|
||||
// Check if the sidebar is in hover mode
|
||||
if (!this.navigatorToolbox.hasAttribute("zen-right-side") && !isCompactMode) {
|
||||
if (
|
||||
!this.navigatorToolbox.hasAttribute("zen-right-side") &&
|
||||
!isCompactMode
|
||||
) {
|
||||
this.navigatorToolbox.prepend(topButtons);
|
||||
}
|
||||
|
||||
let windowButtons = this.actualWindowButtons;
|
||||
let doNotChangeWindowButtons = !isCompactMode && isRightSide && this.isWindowsStyledButtons;
|
||||
let doNotChangeWindowButtons =
|
||||
!isCompactMode && isRightSide && this.isWindowsStyledButtons;
|
||||
const navBar = document.getElementById("nav-bar");
|
||||
|
||||
if (isSingleToolbar) {
|
||||
@@ -1162,20 +1304,24 @@ window.gZenVerticalTabsManager = {
|
||||
for (const button of elements) {
|
||||
this._topButtonsSeparatorElement.after(button);
|
||||
}
|
||||
buttonsTarget.prepend(document.getElementById("unified-extensions-button"));
|
||||
buttonsTarget.prepend(
|
||||
document.getElementById("unified-extensions-button")
|
||||
);
|
||||
const panelUIButton = document.getElementById("PanelUI-button");
|
||||
buttonsTarget.prepend(panelUIButton);
|
||||
panelUIButton.setAttribute("overflows", "false");
|
||||
buttonsTarget.parentElement.append(document.getElementById("nav-bar-overflow-button"));
|
||||
buttonsTarget.parentElement.append(
|
||||
document.getElementById("nav-bar-overflow-button")
|
||||
);
|
||||
if (this.isWindowsStyledButtons && !doNotChangeWindowButtons) {
|
||||
appContentNavbarContaienr.append(windowButtons);
|
||||
}
|
||||
if (isCompactMode) {
|
||||
titlebar.prepend(navBar);
|
||||
titlebar.prepend(topButtons);
|
||||
titlebar.moveBefore(navBar, titlebar.firstChild);
|
||||
titlebar.moveBefore(topButtons, titlebar.firstChild);
|
||||
} else {
|
||||
titlebar.before(topButtons);
|
||||
titlebar.before(navBar);
|
||||
titlebar.parentNode.moveBefore(topButtons, titlebar);
|
||||
titlebar.parentNode.moveBefore(navBar, titlebar);
|
||||
}
|
||||
document.documentElement.setAttribute("zen-single-toolbar", true);
|
||||
this._hasSetSingleToolbar = true;
|
||||
@@ -1187,7 +1333,9 @@ window.gZenVerticalTabsManager = {
|
||||
'#zen-sidebar-top-buttons-customization-target > :is([cui-areatype="toolbar"], .chromeclass-toolbar-additional)'
|
||||
);
|
||||
for (const button of elements) {
|
||||
document.getElementById("nav-bar-customization-target").append(button);
|
||||
document
|
||||
.getElementById("nav-bar-customization-target")
|
||||
.append(button);
|
||||
}
|
||||
this._topButtonsSeparatorElement.remove();
|
||||
document.documentElement.removeAttribute("zen-single-toolbar");
|
||||
@@ -1220,7 +1368,9 @@ window.gZenVerticalTabsManager = {
|
||||
topButtons.prepend(windowButtons);
|
||||
}
|
||||
|
||||
const canHideTabBarPref = Services.prefs.getBoolPref("zen.view.compact.hide-tabbar");
|
||||
const canHideTabBarPref = Services.prefs.getBoolPref(
|
||||
"zen.view.compact.hide-tabbar"
|
||||
);
|
||||
const captionsShouldStayOnSidebar =
|
||||
!canHideTabBarPref &&
|
||||
((!this.isWindowsStyledButtons && !isRightSide) ||
|
||||
@@ -1233,7 +1383,12 @@ window.gZenVerticalTabsManager = {
|
||||
}
|
||||
|
||||
// Case: single toolbar, compact mode, right side and windows styled buttons
|
||||
if (isSingleToolbar && isCompactMode && isRightSide && this.isWindowsStyledButtons) {
|
||||
if (
|
||||
isSingleToolbar &&
|
||||
isCompactMode &&
|
||||
isRightSide &&
|
||||
this.isWindowsStyledButtons
|
||||
) {
|
||||
topButtons.prepend(windowButtons);
|
||||
}
|
||||
|
||||
@@ -1279,9 +1434,15 @@ window.gZenVerticalTabsManager = {
|
||||
this._hasSetSingleToolbar &&
|
||||
Services.prefs.getBoolPref("zen.view.overflow-webext-toolbar", true)
|
||||
) {
|
||||
topButtons.setAttribute("addon-webext-overflowtarget", "zen-overflow-extensions-list");
|
||||
topButtons.setAttribute(
|
||||
"addon-webext-overflowtarget",
|
||||
"zen-overflow-extensions-list"
|
||||
);
|
||||
} else {
|
||||
topButtons.setAttribute("addon-webext-overflowtarget", "overflowed-extensions-list");
|
||||
topButtons.setAttribute(
|
||||
"addon-webext-overflowtarget",
|
||||
"overflowed-extensions-list"
|
||||
);
|
||||
}
|
||||
|
||||
gZenCompactModeManager.updateCompactModeContext(isSingleToolbar);
|
||||
@@ -1314,11 +1475,15 @@ window.gZenVerticalTabsManager = {
|
||||
},
|
||||
|
||||
rebuildAreas() {
|
||||
CustomizableUI.zenInternalCU._rebuildRegisteredAreas(/* zenDontRebuildCollapsed */ true);
|
||||
CustomizableUI.zenInternalCU._rebuildRegisteredAreas(
|
||||
/* zenDontRebuildCollapsed */ true
|
||||
);
|
||||
},
|
||||
|
||||
_updateMaxWidth() {
|
||||
const maxWidth = Services.prefs.getIntPref("zen.view.sidebar-expanded.max-width");
|
||||
const maxWidth = Services.prefs.getIntPref(
|
||||
"zen.view.sidebar-expanded.max-width"
|
||||
);
|
||||
const toolbox = gNavToolbox;
|
||||
if (!this._prefsCompactMode) {
|
||||
toolbox.style.maxWidth = `${maxWidth}px`;
|
||||
@@ -1391,7 +1556,9 @@ window.gZenVerticalTabsManager = {
|
||||
);
|
||||
}
|
||||
|
||||
const editorContainer = this._tabEdited.querySelector(".tab-editor-container");
|
||||
const editorContainer = this._tabEdited.querySelector(
|
||||
".tab-editor-container"
|
||||
);
|
||||
if (editorContainer) {
|
||||
editorContainer.remove();
|
||||
}
|
||||
@@ -1419,21 +1586,30 @@ window.gZenVerticalTabsManager = {
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (isTab && !target.closest(".tab-label-container") && event.type === "dblclick") {
|
||||
if (
|
||||
isTab &&
|
||||
!target.closest(".tab-label-container") &&
|
||||
event.type === "dblclick"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this._tabEdited =
|
||||
target.closest(".tabbrowser-tab") ||
|
||||
target.closest(".zen-current-workspace-indicator-name") ||
|
||||
(event.explicit && target.closest(".tab-group-label"));
|
||||
if (!this._tabEdited || (this._tabEdited.hasAttribute("zen-essential") && isTab)) {
|
||||
if (
|
||||
!this._tabEdited ||
|
||||
(this._tabEdited.hasAttribute("zen-essential") && isTab)
|
||||
) {
|
||||
this._tabEdited = null;
|
||||
return;
|
||||
}
|
||||
gZenFolders.cancelPopupTimer();
|
||||
event.stopPropagation?.();
|
||||
document.documentElement.setAttribute("zen-renaming-tab", "true");
|
||||
const label = isTab ? this._tabEdited.querySelector(".tab-label-container") : this._tabEdited;
|
||||
const label = isTab
|
||||
? this._tabEdited.querySelector(".tab-label-container")
|
||||
: this._tabEdited;
|
||||
label.classList.add("tab-label-container-editing");
|
||||
|
||||
if (isTab) {
|
||||
@@ -1450,7 +1626,9 @@ window.gZenVerticalTabsManager = {
|
||||
input.addEventListener("keydown", this.renameTabKeydown.bind(this));
|
||||
|
||||
if (isTab) {
|
||||
const containerHtml = this._tabEdited.querySelector(".tab-editor-container");
|
||||
const containerHtml = this._tabEdited.querySelector(
|
||||
".tab-editor-container"
|
||||
);
|
||||
containerHtml.appendChild(input);
|
||||
} else {
|
||||
this._tabEdited.after(input);
|
||||
@@ -1466,7 +1644,9 @@ window.gZenVerticalTabsManager = {
|
||||
return;
|
||||
}
|
||||
document.documentElement.removeAttribute("zen-renaming-tab");
|
||||
const editorContainer = this._tabEdited.querySelector(".tab-editor-container");
|
||||
const editorContainer = this._tabEdited.querySelector(
|
||||
".tab-editor-container"
|
||||
);
|
||||
let input = document.getElementById("tab-label-input");
|
||||
input.remove();
|
||||
if (editorContainer) {
|
||||
|
||||
@@ -17,12 +17,17 @@ export default function checkForZenUpdates() {
|
||||
!gZenUIManager.testingEnabled &&
|
||||
Services.prefs.getBoolPref(ZEN_UPDATE_SHOW, true)
|
||||
) {
|
||||
const updateUrl = Services.prefs.getStringPref("app.releaseNotesURL.prompt", "");
|
||||
const updateUrl = Services.prefs.getStringPref(
|
||||
"app.releaseNotesURL.prompt",
|
||||
""
|
||||
);
|
||||
createSidebarNotification({
|
||||
headingL10nId: "zen-sidebar-notification-updated-heading",
|
||||
links: [
|
||||
{
|
||||
url: Services.urlFormatter.formatURL(updateUrl.replace("%VERSION%", version)),
|
||||
url: Services.urlFormatter.formatURL(
|
||||
updateUrl.replace("%VERSION%", version)
|
||||
),
|
||||
l10nId: "zen-sidebar-notification-updated",
|
||||
special: true,
|
||||
icon: "chrome://browser/skin/zen-icons/heart-circle-fill.svg",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user