mirror of
https://github.com/zen-browser/desktop.git
synced 2026-06-14 07:23:42 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5383737b23 | ||
|
|
b812bff07e | ||
|
|
e04e910a6f | ||
|
|
bf365f8043 | ||
|
|
0a45b82a6c | ||
|
|
2311e183f1 | ||
|
|
8ea65cba48 | ||
|
|
45075e2fbc | ||
|
|
64e2e49a00 | ||
|
|
feca914821 | ||
|
|
c7818fe355 | ||
|
|
2c59265249 | ||
|
|
193d004a37 | ||
|
|
072d874f78 | ||
|
|
7aa0ca05ec | ||
|
|
d76fa13edd |
2
.github/workflows/sync-upstream.yml
vendored
2
.github/workflows/sync-upstream.yml
vendored
@@ -129,7 +129,7 @@ jobs:
|
||||
token: ${{ secrets.DEPLOY_KEY }}
|
||||
commit-message: "chore: Sync upstream to `Firefox ${{ steps.build-data.outputs.version }}`"
|
||||
branch: "chore/upstream-sync"
|
||||
title: "no-bug: Sync upstream Firefox to version ${{ steps.build-data.outputs.version }}"
|
||||
title: "no-bug: Sync upstream Firefox to version `${{ steps.build-data.outputs.version }}`"
|
||||
body: |
|
||||
This PR syncs the upstream Firefox to version ${{ steps.build-data.outputs.version }}.
|
||||
|
||||
|
||||
2
.github/workflows/windows-release-build.yml
vendored
2
.github/workflows/windows-release-build.yml
vendored
@@ -154,7 +154,7 @@ jobs:
|
||||
zlib1g-dev \
|
||||
aria2
|
||||
echo Setup wine
|
||||
aria2c "https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/gecko.cache.level-1.toolchains.v3.linux64-wine.latest/artifacts/public%2Fbuild%2Fwine.tar.zst" -o wine.tar.zst
|
||||
aria2c "https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/dQz_aHy8Rl-Lt0xf2WlrMw/artifacts/public/build/wine.tar.zst" -o wine.tar.zst
|
||||
tar --zstd -xf wine.tar.zst -C ~/win-cross
|
||||
rm wine.tar.zst
|
||||
echo Setup Visual Studio
|
||||
|
||||
@@ -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 `151.0.2`! 🚀
|
||||
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 151.0.2`!
|
||||
- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `151.0.3`! 🚀
|
||||
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 151.0.3`!
|
||||
|
||||
### Contributing
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
05272df13c2e4f435b4e0a706715f302b09ef829
|
||||
5c4d14a559bf26eb4ab3e136d2084310ebe51ac0
|
||||
@@ -16,9 +16,9 @@ if test "$ZEN_CROSS_COMPILING"; then
|
||||
CROSS_COMPILE=1
|
||||
|
||||
if test "$SURFER_COMPAT" = "aarch64"; then
|
||||
export WIN32_REDIST_DIR="$(echo ~)/win-cross/vs2026/VC/Redist/MSVC/14.50.35710/arm64/Microsoft.VC145.CRT"
|
||||
export WIN32_REDIST_DIR="$WINSYSROOT/VC/Redist/MSVC/14.50.35710/arm64/Microsoft.VC145.CRT"
|
||||
else
|
||||
export WIN32_REDIST_DIR="$(echo ~)/win-cross/vs2026/VC/Redist/MSVC/14.50.35710/x64/Microsoft.VC145.CRT"
|
||||
export WIN32_REDIST_DIR="$WINSYSROOT/VC/Redist/MSVC/14.50.35710/x64/Microsoft.VC145.CRT"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Trieu el selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Obre l'inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brillantor
|
||||
zen-bootst-color-original-saturation = Saturació original
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brillantor
|
||||
zen-boost-color-original-saturation = Saturació original
|
||||
zen-add-zap-helper = Feu clic als elements de la pàgina per <b>amagar-los</b>
|
||||
zen-remove-zap-helper = ← Feu clic per mostrar
|
||||
zen-select-this = Insereix un selector per a això
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Selektor auswählen
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Inspektor öffnen
|
||||
zen-bootst-color-contrast = Kontrast
|
||||
zen-bootst-color-brightness = Helligkeit
|
||||
zen-bootst-color-original-saturation = Ausgangssättigung
|
||||
zen-boost-color-contrast = Kontrast
|
||||
zen-boost-color-brightness = Helligkeit
|
||||
zen-boost-color-original-saturation = Ausgangssättigung
|
||||
zen-add-zap-helper = Klicke auf Elemente auf der Seite, um sie mit <b>Zap</b> zu markieren
|
||||
zen-remove-zap-helper = ← Erneut klicken zum Wiederherstellen
|
||||
zen-select-this = Selektor für dieses Element einfügen
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Escoger selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Abrir inspector
|
||||
zen-bootst-color-contrast = Contraste
|
||||
zen-bootst-color-brightness = Brillo
|
||||
zen-bootst-color-original-saturation = Saturación original
|
||||
zen-boost-color-contrast = Contraste
|
||||
zen-boost-color-brightness = Brillo
|
||||
zen-boost-color-original-saturation = Saturación original
|
||||
zen-add-zap-helper = Haga clic en los elementos de la página para <b>borrarlos</b>
|
||||
zen-remove-zap-helper = ← Clic para deshacer
|
||||
zen-select-this = Insertar selector para esto
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Choisir le sélecteur
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Ouvrir l'inspecteur
|
||||
zen-bootst-color-contrast = Contraste
|
||||
zen-bootst-color-brightness = Luminosité
|
||||
zen-bootst-color-original-saturation = Saturation originale
|
||||
zen-boost-color-contrast = Contraste
|
||||
zen-boost-color-brightness = Luminosité
|
||||
zen-boost-color-original-saturation = Saturation originale
|
||||
zen-add-zap-helper = Cliquez sur des éléments de la page pour les <b>zapper</b>
|
||||
zen-remove-zap-helper = ← Cliquez pour démasquer
|
||||
zen-select-this = Insérer un sélecteur pour ceci
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Roghnóir Roghnaigh
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Oscail an Cigire
|
||||
zen-bootst-color-contrast = Codarsnacht
|
||||
zen-bootst-color-brightness = Gile
|
||||
zen-bootst-color-original-saturation = Sáithiú Bunaidh
|
||||
zen-boost-color-contrast = Codarsnacht
|
||||
zen-boost-color-brightness = Gile
|
||||
zen-boost-color-original-saturation = Sáithiú Bunaidh
|
||||
zen-add-zap-helper = Cliceáil ar eilimintí ar an leathanach chun iad a <b>Zapáil</b>
|
||||
zen-remove-zap-helper = ← Cliceáil chun Dízipáil
|
||||
zen-select-this = Cuir roghnóir isteach don seo
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = ניגודיות
|
||||
zen-bootst-color-brightness = בהירות
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = ניגודיות
|
||||
zen-boost-color-brightness = בהירות
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Vizsgáló megnyitása
|
||||
zen-bootst-color-contrast = Kontraszt
|
||||
zen-bootst-color-brightness = Fényerő
|
||||
zen-bootst-color-original-saturation = Eredeti szaturáció
|
||||
zen-boost-color-contrast = Kontraszt
|
||||
zen-boost-color-brightness = Fényerő
|
||||
zen-boost-color-original-saturation = Eredeti szaturáció
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Veljari
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Opna rýni
|
||||
zen-bootst-color-contrast = Birtuskil
|
||||
zen-bootst-color-brightness = Birtustig
|
||||
zen-bootst-color-original-saturation = Upprunaleg litmettun
|
||||
zen-boost-color-contrast = Birtuskil
|
||||
zen-boost-color-brightness = Birtustig
|
||||
zen-boost-color-original-saturation = Upprunaleg litmettun
|
||||
zen-add-zap-helper = Smelltu á atriði á síðunni til að <b>einangra</b> þau (zap)
|
||||
zen-remove-zap-helper = ← Smelltu til að taka úr einangrun
|
||||
zen-select-this = Setja inn veljara fyrir þetta
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = セレクターを選択
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = インスペクタを開く
|
||||
zen-bootst-color-contrast = コントラスト
|
||||
zen-bootst-color-brightness = 明るさ
|
||||
zen-bootst-color-original-saturation = 元の彩度
|
||||
zen-boost-color-contrast = コントラスト
|
||||
zen-boost-color-brightness = 明るさ
|
||||
zen-boost-color-original-saturation = 元の彩度
|
||||
zen-add-zap-helper = <b>Zap</b> にページ上の要素をクリックします
|
||||
zen-remove-zap-helper = ←クリックして解除
|
||||
zen-select-this = このセレクターを挿入
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = 선택자 선택
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = 검사기 열기
|
||||
zen-bootst-color-contrast = 대비
|
||||
zen-bootst-color-brightness = 밝기
|
||||
zen-bootst-color-original-saturation = 원본 채도
|
||||
zen-boost-color-contrast = 대비
|
||||
zen-boost-color-brightness = 밝기
|
||||
zen-boost-color-original-saturation = 원본 채도
|
||||
zen-add-zap-helper = 페이지 내의 요소를 클릭해서 <b>날려</b>버리세요
|
||||
zen-remove-zap-helper = ← 클릭하여 되살리기
|
||||
zen-select-this = 이 요소의 선택자 삽입
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Kontrastas
|
||||
zen-bootst-color-brightness = Šviesumas
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Kontrastas
|
||||
zen-boost-color-brightness = Šviesumas
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Velgselektor
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Åpne inspektør
|
||||
zen-bootst-color-contrast = Kontrast
|
||||
zen-bootst-color-brightness = Lysstyrke
|
||||
zen-bootst-color-original-saturation = Opprinnelig fargemetning
|
||||
zen-boost-color-contrast = Kontrast
|
||||
zen-boost-color-brightness = Lysstyrke
|
||||
zen-boost-color-original-saturation = Opprinnelig fargemetning
|
||||
zen-add-zap-helper = Klikk elementer på siden for å <b>Zappe</b> dem
|
||||
zen-remove-zap-helper = ← Klikk for å avzappe
|
||||
zen-select-this = Sett inn slektor for dette
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Wybierz selektor
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Otwórz Inspektor
|
||||
zen-bootst-color-contrast = Kontrast
|
||||
zen-bootst-color-brightness = Jasność
|
||||
zen-bootst-color-original-saturation = Oryginalne nasycenie
|
||||
zen-boost-color-contrast = Kontrast
|
||||
zen-boost-color-brightness = Jasność
|
||||
zen-boost-color-original-saturation = Oryginalne nasycenie
|
||||
zen-add-zap-helper = Kliknij elementy na stronie, aby je <b>ukryć</b>
|
||||
zen-remove-zap-helper = ← Kliknij, aby cofnąć ukrycie
|
||||
zen-select-this = Wstaw selektor dla tego elementu
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Ferramenta de Seleção
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Abrir Inspetor
|
||||
zen-bootst-color-contrast = Contraste
|
||||
zen-bootst-color-brightness = Brilho
|
||||
zen-bootst-color-original-saturation = Saturação Original
|
||||
zen-boost-color-contrast = Contraste
|
||||
zen-boost-color-brightness = Brilho
|
||||
zen-boost-color-original-saturation = Saturação Original
|
||||
zen-add-zap-helper = Clique em elementos da página para dar um <b>Zap</b> neles
|
||||
zen-remove-zap-helper = Clique para Deszapar
|
||||
zen-select-this = Inserir seletor para isto
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Välj väljare
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Öppna inspektör
|
||||
zen-bootst-color-contrast = Kontrast
|
||||
zen-bootst-color-brightness = Ljusstyrka
|
||||
zen-bootst-color-original-saturation = Ursprunglig mättnad
|
||||
zen-boost-color-contrast = Kontrast
|
||||
zen-boost-color-brightness = Ljusstyrka
|
||||
zen-boost-color-original-saturation = Ursprunglig mättnad
|
||||
zen-add-zap-helper = Klicka på element på sidan för att <b>zappa</b> dem
|
||||
zen-remove-zap-helper = ← Klicka för att avzappa
|
||||
zen-select-this = Infoga väljare för detta
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Pick Selector
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Open Inspector
|
||||
zen-bootst-color-contrast = Contrast
|
||||
zen-bootst-color-brightness = Brightness
|
||||
zen-bootst-color-original-saturation = Original Saturation
|
||||
zen-boost-color-contrast = Contrast
|
||||
zen-boost-color-brightness = Brightness
|
||||
zen-boost-color-original-saturation = Original Saturation
|
||||
zen-add-zap-helper = Click elements on the page to <b>Zap</b> them
|
||||
zen-remove-zap-helper = ← Click to Unzap
|
||||
zen-select-this = Insert selector for this
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Seçici seç
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Denetleyiciyi aç
|
||||
zen-bootst-color-contrast = Kontrast
|
||||
zen-bootst-color-brightness = Parlaklık
|
||||
zen-bootst-color-original-saturation = Orijinal doygunluk
|
||||
zen-boost-color-contrast = Kontrast
|
||||
zen-boost-color-brightness = Parlaklık
|
||||
zen-boost-color-original-saturation = Orijinal doygunluk
|
||||
zen-add-zap-helper = Sayfadaki ögelere tıklayarak onları <b>Zap</b> ile kaldırın
|
||||
zen-remove-zap-helper = ← Unzap için tıklayın
|
||||
zen-select-this = Bu öge için seçici ekle
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Вибір селектора
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Відкрити інспектора
|
||||
zen-bootst-color-contrast = Контраст
|
||||
zen-bootst-color-brightness = Яскравість
|
||||
zen-bootst-color-original-saturation = Оригінальна насиченість
|
||||
zen-boost-color-contrast = Контраст
|
||||
zen-boost-color-brightness = Яскравість
|
||||
zen-boost-color-original-saturation = Оригінальна насиченість
|
||||
zen-add-zap-helper = Клацніть на елементи на сторінці, щоби <b>сховати</b> їх
|
||||
zen-remove-zap-helper = ← Клацніть, аби знову показати
|
||||
zen-select-this = Вставити селектор для цього
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = Chọn phần tử
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = Mở trình kiểm tra
|
||||
zen-bootst-color-contrast = Độ tương phản
|
||||
zen-bootst-color-brightness = Độ sáng
|
||||
zen-bootst-color-original-saturation = Độ bão hòa gốc
|
||||
zen-boost-color-contrast = Độ tương phản
|
||||
zen-boost-color-brightness = Độ sáng
|
||||
zen-boost-color-original-saturation = Độ bão hòa gốc
|
||||
zen-add-zap-helper = Nhấp vào các phần tử trên trang để <b>Khử</b> chúng
|
||||
zen-remove-zap-helper = ← Nhấp để khôi phục
|
||||
zen-select-this = Nhập bộ chọn cho phần tử này
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = 选取选择器
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = 打开查看器
|
||||
zen-bootst-color-contrast = 对比度
|
||||
zen-bootst-color-brightness = 亮度
|
||||
zen-bootst-color-original-saturation = 初始饱和度
|
||||
zen-boost-color-contrast = 对比度
|
||||
zen-boost-color-brightness = 亮度
|
||||
zen-boost-color-original-saturation = 初始饱和度
|
||||
zen-add-zap-helper = 点击页面上的元素以将其<b>屏蔽</b>
|
||||
zen-remove-zap-helper = ← 点击以取消屏蔽
|
||||
zen-select-this = 插入此元素的选择器
|
||||
|
||||
@@ -29,9 +29,9 @@ zen-boost-css-picker =
|
||||
.tooltiptext = 汲取選擇器
|
||||
zen-boost-css-inspector =
|
||||
.tooltiptext = 開啟檢測器
|
||||
zen-bootst-color-contrast = 對比
|
||||
zen-bootst-color-brightness = 亮度
|
||||
zen-bootst-color-original-saturation = 飽和度
|
||||
zen-boost-color-contrast = 對比
|
||||
zen-boost-color-brightness = 亮度
|
||||
zen-boost-color-original-saturation = 飽和度
|
||||
zen-add-zap-helper = 選擇要 <b>Zap</b>的元素
|
||||
zen-remove-zap-helper = ← 按此取消zap
|
||||
zen-select-this = 加入此元素的選擇器
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"surfer": "surfer",
|
||||
"test": "python3 scripts/run_tests.py",
|
||||
"test:dbg": "python3 scripts/run_tests.py --jsdebugger --debug-on-failure",
|
||||
"test:gtest": "cd engine && ./mach gtest",
|
||||
"test:gtest": "cd engine && ./mach gtest Zen*",
|
||||
"ffprefs": "cd tools/ffprefs && cargo run --bin ffprefs -- ../../",
|
||||
"lc": "surfer license-check",
|
||||
"lc:fix": "surfer license-check --fix",
|
||||
|
||||
@@ -825,6 +825,7 @@ var zenIgnoreKeyboardShortcutIDs = [
|
||||
"key_enterFullScreen_compat",
|
||||
"key_exitFullScreen_old",
|
||||
"key_exitFullScreen_compat",
|
||||
"key_duplicateTab",
|
||||
];
|
||||
|
||||
var zenIgnoreKeyboardShortcutL10n = [
|
||||
|
||||
@@ -281,7 +281,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..146b1559b8430773bd4ec173a8f4fe88
|
||||
+ let hasZenDefaultUserContextId = false;
|
||||
+ let zenForcedWorkspaceId = undefined;
|
||||
+ if (typeof gZenWorkspaces !== "undefined" && !_forZenEmptyTab) {
|
||||
+ [userContextId, hasZenDefaultUserContextId, zenForcedWorkspaceId] = gZenWorkspaces.getContextIdIfNeeded(userContextId, fromExternal);
|
||||
+ [userContextId, hasZenDefaultUserContextId, zenForcedWorkspaceId] = gZenWorkspaces.getContextIdIfNeeded(userContextId, fromExternal, triggeringPrincipal);
|
||||
+ }
|
||||
+
|
||||
if (!UserInteraction.running("browser.tabs.opening", window)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/urlbar/content/UrlbarInput.mjs b/browser/components/urlbar/content/UrlbarInput.mjs
|
||||
index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e6463b45191 100644
|
||||
index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f771f0a75a8 100644
|
||||
--- a/browser/components/urlbar/content/UrlbarInput.mjs
|
||||
+++ b/browser/components/urlbar/content/UrlbarInput.mjs
|
||||
@@ -98,6 +98,13 @@ const lazy = XPCOMUtils.declareLazy({
|
||||
@@ -132,15 +132,17 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
// Enable the animation only after the first extend call to ensure it
|
||||
// doesn't run when opening a new window.
|
||||
if (!this.hasAttribute("breakout-extend-animate")) {
|
||||
@@ -2891,6 +2966,27 @@ ${
|
||||
@@ -2891,6 +2966,29 @@ ${
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (this._zenHandleUrlbarClose) {
|
||||
+ this._zenHandleUrlbarClose();
|
||||
+ } else if (!this._untrimmedValue || this.searchMode) {
|
||||
+ } else if (!this._untrimmedValue || this.searchMode || this.window.gZenVerticalTabsManager._hasSetSingleToolbar) {
|
||||
+ // Restore the current page URL when the urlbar is empty on blur
|
||||
+ this.handleRevert();
|
||||
+ this.window.requestAnimationFrame(() => {
|
||||
+ this.handleRevert();
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ // Arc like URLbar: Blur the input on exit
|
||||
@@ -160,7 +162,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
this.removeAttribute("breakout-extend");
|
||||
this.#updateTextboxPosition();
|
||||
}
|
||||
@@ -2921,7 +3017,7 @@ ${
|
||||
@@ -2921,7 +3019,7 @@ ${
|
||||
forceUnifiedSearchButtonAvailable = false
|
||||
) {
|
||||
let prevState = this.getAttribute("pageproxystate");
|
||||
@@ -169,7 +171,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
this.setAttribute("pageproxystate", state);
|
||||
this._inputContainer.setAttribute("pageproxystate", state);
|
||||
this._identityBox?.setAttribute("pageproxystate", state);
|
||||
@@ -3198,10 +3294,12 @@ ${
|
||||
@@ -3198,10 +3296,12 @@ ${
|
||||
return;
|
||||
}
|
||||
this.style.top = px(
|
||||
@@ -182,7 +184,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3260,9 +3358,10 @@ ${
|
||||
@@ -3260,9 +3360,10 @@ ${
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -194,7 +196,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
);
|
||||
this.style.setProperty(
|
||||
"--urlbar-height",
|
||||
@@ -3768,6 +3867,7 @@ ${
|
||||
@@ -3768,6 +3869,7 @@ ${
|
||||
}
|
||||
|
||||
_toggleActionOverride(event) {
|
||||
@@ -202,7 +204,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
if (
|
||||
event.keyCode == KeyEvent.DOM_VK_SHIFT ||
|
||||
event.keyCode == KeyEvent.DOM_VK_ALT ||
|
||||
@@ -3880,8 +3980,8 @@ ${
|
||||
@@ -3880,8 +3982,8 @@ ${
|
||||
if (!this.#isAddressbar) {
|
||||
return val;
|
||||
}
|
||||
@@ -213,7 +215,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
: val;
|
||||
// Only trim value if the directionality doesn't change to RTL and we're not
|
||||
// showing a strikeout https protocol.
|
||||
@@ -4180,6 +4280,7 @@ ${
|
||||
@@ -4180,6 +4282,7 @@ ${
|
||||
resultDetails = null,
|
||||
browser = this.window.gBrowser.selectedBrowser
|
||||
) {
|
||||
@@ -221,7 +223,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
if (this.#isAddressbar) {
|
||||
this.#prepareAddressbarLoad(
|
||||
url,
|
||||
@@ -4291,6 +4392,10 @@ ${
|
||||
@@ -4291,6 +4394,10 @@ ${
|
||||
}
|
||||
reuseEmpty = true;
|
||||
}
|
||||
@@ -232,7 +234,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
if (
|
||||
where == "tab" &&
|
||||
reuseEmpty &&
|
||||
@@ -4298,6 +4403,9 @@ ${
|
||||
@@ -4298,6 +4405,9 @@ ${
|
||||
) {
|
||||
where = "current";
|
||||
}
|
||||
@@ -242,7 +244,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
return where;
|
||||
}
|
||||
|
||||
@@ -4552,6 +4660,7 @@ ${
|
||||
@@ -4552,6 +4662,7 @@ ${
|
||||
this.setResultForCurrentValue(null);
|
||||
this.handleCommand();
|
||||
this.controller.clearLastQueryContextCache();
|
||||
@@ -250,7 +252,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
|
||||
this._suppressStartQuery = false;
|
||||
});
|
||||
@@ -4559,7 +4668,6 @@ ${
|
||||
@@ -4559,7 +4670,6 @@ ${
|
||||
contextMenu.addEventListener("popupshowing", () => {
|
||||
// Close the results pane when the input field contextual menu is open,
|
||||
// because paste and go doesn't want a result selection.
|
||||
@@ -258,7 +260,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
|
||||
let controller =
|
||||
this.document.commandDispatcher.getControllerForCommand("cmd_paste");
|
||||
@@ -4715,7 +4823,11 @@ ${
|
||||
@@ -4715,7 +4825,11 @@ ${
|
||||
if (!engineName && !source && !this.hasAttribute("searchmode")) {
|
||||
return;
|
||||
}
|
||||
@@ -271,7 +273,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
if (this._searchModeIndicatorTitle) {
|
||||
this._searchModeIndicatorTitle.textContent = "";
|
||||
this._searchModeIndicatorTitle.removeAttribute("data-l10n-id");
|
||||
@@ -5031,6 +5143,7 @@ ${
|
||||
@@ -5031,6 +5145,7 @@ ${
|
||||
|
||||
this.document.l10n.setAttributes(
|
||||
this.inputField,
|
||||
@@ -279,7 +281,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
l10nId,
|
||||
l10nId == "urlbar-placeholder-with-name"
|
||||
? { name: engineName }
|
||||
@@ -5156,6 +5269,11 @@ ${
|
||||
@@ -5156,6 +5271,11 @@ ${
|
||||
}
|
||||
|
||||
_on_click(event) {
|
||||
@@ -291,7 +293,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
switch (event.target) {
|
||||
case this.inputField:
|
||||
case this._inputContainer:
|
||||
@@ -5242,7 +5360,7 @@ ${
|
||||
@@ -5242,7 +5362,7 @@ ${
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +302,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
this.view.autoOpen({ event });
|
||||
} else {
|
||||
if (this._untrimOnFocusAfterKeydown) {
|
||||
@@ -5282,9 +5400,16 @@ ${
|
||||
@@ -5282,9 +5402,16 @@ ${
|
||||
}
|
||||
|
||||
_on_mousedown(event) {
|
||||
@@ -318,7 +320,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
if (
|
||||
event.composedTarget != this.inputField &&
|
||||
event.composedTarget != this._inputContainer
|
||||
@@ -5294,6 +5419,10 @@ ${
|
||||
@@ -5294,6 +5421,10 @@ ${
|
||||
|
||||
this.focusedViaMousedown = !this.focused;
|
||||
this.#preventClickSelectsAll = this.focused;
|
||||
@@ -329,7 +331,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
|
||||
// Keep the focus status, since the attribute may be changed
|
||||
// upon calling this.focus().
|
||||
@@ -5329,7 +5458,7 @@ ${
|
||||
@@ -5329,7 +5460,7 @@ ${
|
||||
}
|
||||
// Don't close the view when clicking on a tab; we may want to keep the
|
||||
// view open on tab switch, and the TabSelect event arrived earlier.
|
||||
@@ -338,7 +340,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..e1128b0d7f5accfd48af27f99e3b2e64
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5636,7 +5765,7 @@ ${
|
||||
@@ -5636,7 +5767,7 @@ ${
|
||||
// When we are in actions search mode we can show more results so
|
||||
// increase the limit.
|
||||
let maxResults =
|
||||
|
||||
@@ -520,7 +520,8 @@
|
||||
list-style-image: url("permissions-fill.svg");
|
||||
}
|
||||
&[boosting] image {
|
||||
color: var(--color-accent-primary);
|
||||
fill-opacity: 1 !important;
|
||||
color: var(--zen-sidebar-themed-icon-fill);
|
||||
list-style-image: url("permissions-fill.svg");
|
||||
}
|
||||
|
||||
@@ -537,7 +538,9 @@
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: var(--color-accent-primary);
|
||||
color: var(--zen-sidebar-themed-icon-fill);
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
list-style-image: url("chrome://browser/content/zen-images/boost-indicator.svg");
|
||||
transform: translateX(-20%);
|
||||
z-index: 0;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
|
||||
index 226d0c5a93a9a2404e1974001da4e34b7b670067..b73277448f7d2706d316df2505e17d232f392d47 100644
|
||||
index 0f5dab192533aa42df97ee3bd4176a9f44d4d568..d45ad2409f6d36106fce5a380545aaae9397ae84 100644
|
||||
--- a/toolkit/moz.configure
|
||||
+++ b/toolkit/moz.configure
|
||||
@@ -22,6 +22,7 @@ def check_moz_app_id(moz_app_id, build_project):
|
||||
@@ -20,6 +20,7 @@ def check_moz_app_id(moz_app_id, build_project):
|
||||
|
||||
project_flag(
|
||||
env="MOZ_APP_VENDOR",
|
||||
@@ -10,7 +10,7 @@ index 226d0c5a93a9a2404e1974001da4e34b7b670067..b73277448f7d2706d316df2505e17d23
|
||||
nargs=1,
|
||||
help='Used for application.ini\'s "Vendor" field, which also impacts profile location and user-visible fields',
|
||||
)
|
||||
@@ -35,6 +36,7 @@ project_flag(
|
||||
@@ -33,6 +34,7 @@ project_flag(
|
||||
|
||||
project_flag(
|
||||
"MOZ_APP_PROFILE",
|
||||
@@ -18,7 +18,7 @@ index 226d0c5a93a9a2404e1974001da4e34b7b670067..b73277448f7d2706d316df2505e17d23
|
||||
nargs=1,
|
||||
help='Used for application.ini\'s "Profile" field, which controls profile location',
|
||||
)
|
||||
@@ -86,10 +88,13 @@ option(
|
||||
@@ -84,10 +86,13 @@ option(
|
||||
)
|
||||
set_config("MOZ_INCLUDE_SOURCE_INFO", True, when="MOZ_INCLUDE_SOURCE_INFO")
|
||||
|
||||
@@ -33,7 +33,7 @@ index 226d0c5a93a9a2404e1974001da4e34b7b670067..b73277448f7d2706d316df2505e17d23
|
||||
help="Set distribution-specific id",
|
||||
)
|
||||
set_config("MOZ_DISTRIBUTION_ID", depends("--with-distribution-id")(lambda v: v[0]))
|
||||
@@ -931,9 +936,9 @@ set_config("MOZ_SYSTEM_AV1", True, when="--with-system-av1")
|
||||
@@ -874,9 +879,9 @@ set_config("MOZ_SYSTEM_AV1", True, when="--with-system-av1")
|
||||
option("--disable-jxl", help="Disable jxl image support")
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ index 226d0c5a93a9a2404e1974001da4e34b7b670067..b73277448f7d2706d316df2505e17d23
|
||||
return True
|
||||
|
||||
|
||||
@@ -2070,7 +2075,7 @@ set_define("A11Y_LOG", True, when=a11y_log)
|
||||
@@ -2028,7 +2033,7 @@ set_define("A11Y_LOG", True, when=a11y_log)
|
||||
# ==============================================================
|
||||
@depends(milestone)
|
||||
def require_signing(milestone):
|
||||
@@ -55,7 +55,7 @@ index 226d0c5a93a9a2404e1974001da4e34b7b670067..b73277448f7d2706d316df2505e17d23
|
||||
|
||||
|
||||
option(
|
||||
@@ -3903,7 +3908,7 @@ with only_when(compile_environment):
|
||||
@@ -3912,7 +3917,7 @@ with only_when(compile_environment):
|
||||
return "Mozilla"
|
||||
elif target.os == "Android":
|
||||
return ".mozilla"
|
||||
@@ -64,3 +64,12 @@ index 226d0c5a93a9a2404e1974001da4e34b7b670067..b73277448f7d2706d316df2505e17d23
|
||||
|
||||
option(
|
||||
"--with-user-appdir",
|
||||
@@ -4325,7 +4330,7 @@ with only_when(target_is_windows):
|
||||
|
||||
@depends(target.abi)
|
||||
def desktop_launcher_enabled(abi):
|
||||
- return abi == "msvc"
|
||||
+ return False # See gh-13745
|
||||
|
||||
set_config("DESKTOP_LAUNCHER_ENABLED", True, when=desktop_launcher_enabled)
|
||||
set_define("DESKTOP_LAUNCHER_ENABLED", True, when=desktop_launcher_enabled)
|
||||
|
||||
@@ -82,7 +82,7 @@ export class nsZenBoostStyles {
|
||||
|
||||
if (fontCase != "" || fontFamily != "") {
|
||||
style += `/* Text Format */\n`;
|
||||
style += `body * {\n`;
|
||||
style += `body *:not(.google-symbols, gf-load-icon-font, mat-icon, .google-material-icons) {\n`;
|
||||
style += `${fontFamily}\n`;
|
||||
style += `${fontCase}\n`;
|
||||
style += `}\n`;
|
||||
|
||||
@@ -44,6 +44,7 @@ export class nsZenBoostEditor {
|
||||
this.lastDotSetPos = { x: 0, y: 0 };
|
||||
this.currentBoostData = null;
|
||||
this.boostInfo = null;
|
||||
this.isDarkMode = this.openerWindow.gZenThemePicker.isDarkMode;
|
||||
|
||||
this.killOtherEditorInstances();
|
||||
|
||||
@@ -52,6 +53,7 @@ export class nsZenBoostEditor {
|
||||
});
|
||||
|
||||
this.init();
|
||||
this.initColorScheme();
|
||||
this.initColorPicker();
|
||||
this.initFonts();
|
||||
this.loadBoost(domain);
|
||||
@@ -184,6 +186,17 @@ export class nsZenBoostEditor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the color scheme of the editor window based on the current theme (dark or light mode)
|
||||
*/
|
||||
initColorScheme() {
|
||||
if (this.isDarkMode) {
|
||||
this.doc.documentElement.style.colorScheme = "dark";
|
||||
} else {
|
||||
this.doc.documentElement.style.colorScheme = "light";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the code editor for the css editor
|
||||
*/
|
||||
@@ -205,7 +218,7 @@ export class nsZenBoostEditor {
|
||||
const editor = new Editor({
|
||||
mode: Editor.modes.css,
|
||||
lineNumbers: true,
|
||||
theme: "default", // default is light theme
|
||||
theme: "mozilla",
|
||||
readOnly: false,
|
||||
gutters: ["CodeMirror-linenumbers"],
|
||||
});
|
||||
@@ -361,12 +374,6 @@ export class nsZenBoostEditor {
|
||||
}
|
||||
windowElem.setAttribute("editor", "code");
|
||||
|
||||
// Store the old boost editor width.
|
||||
// The window needs the outer width which includes
|
||||
// window chrome. This results in the window
|
||||
// being smaller than it should be
|
||||
this._boostEditorWidth = this.editorWindow.outerWidth;
|
||||
|
||||
this.editorWindow.requestAnimationFrame(() => {
|
||||
this.editorWindow.resizeTo(
|
||||
this._codeEditorWidth,
|
||||
@@ -400,7 +407,11 @@ export class nsZenBoostEditor {
|
||||
}
|
||||
windowElem.setAttribute("editor", "boost");
|
||||
|
||||
this.editorWindow.requestAnimationFrame(() => {
|
||||
this.doc.getElementById("zen-boost-editor-root").style.display = "flex";
|
||||
this.doc.getElementById("zen-boost-code-editor-root").style.display =
|
||||
"none";
|
||||
|
||||
this.editorWindow.promiseDocumentFlushed(() => {
|
||||
this.editorWindow.resizeTo(
|
||||
this._boostEditorWidth,
|
||||
this.editorWindow.outerHeight
|
||||
@@ -411,10 +422,6 @@ export class nsZenBoostEditor {
|
||||
this.editorWindow.screenY
|
||||
);
|
||||
}
|
||||
|
||||
this.doc.getElementById("zen-boost-editor-root").style.display = "flex";
|
||||
this.doc.getElementById("zen-boost-code-editor-root").style.display =
|
||||
"none";
|
||||
});
|
||||
|
||||
// Disable picker mode
|
||||
@@ -824,13 +831,19 @@ ${cssSelector} {
|
||||
const dotSec = this.doc.querySelector(
|
||||
"#zen-boost-color-picker-dot-secondary"
|
||||
);
|
||||
|
||||
const dotDistance = this.currentBoostData.dotDistance;
|
||||
const dotAngleDeg = this.currentBoostData.dotAngleDeg;
|
||||
const secondaryDotAngleDelta =
|
||||
this.currentBoostData.secondaryDotAngleDegDelta ?? 0;
|
||||
|
||||
dot.style.setProperty(
|
||||
"--zen-theme-picker-dot-color",
|
||||
`hsl(${this.currentBoostData.dotAngleDeg}deg, ${this.currentBoostData.dotDistance * 100}%, 55%)`
|
||||
`hsl(${dotAngleDeg}deg, ${dotDistance * 100}%, 55%)`
|
||||
);
|
||||
dotSec.style.setProperty(
|
||||
"--zen-theme-picker-dot-color",
|
||||
`hsl(${this.currentBoostData.dotAngleDeg + this.currentBoostData.secondaryDotAngleDegDelta}deg, ${this.currentBoostData.dotDistance * 100}%, 20%)`
|
||||
`hsl(${dotAngleDeg + secondaryDotAngleDelta}deg, ${dotDistance * 100}%, 20%)`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -854,22 +867,23 @@ ${cssSelector} {
|
||||
const centerY = rect.top + rect.height / 2;
|
||||
const radius = (rect.width - padding) / 2;
|
||||
|
||||
const dotDistance = this.currentBoostData.dotDistance;
|
||||
const primaryDotAngleDeg = this.currentBoostData.dotAngleDeg;
|
||||
|
||||
let angle = null;
|
||||
if (!pixelX || !pixelY) {
|
||||
if (pixelX == null || pixelY == null) {
|
||||
pixelX = centerX;
|
||||
pixelY = centerY;
|
||||
angle = this.currentBoostData.secondaryDotAngleDegDelta;
|
||||
} else {
|
||||
angle = Math.atan2(pixelY - centerY, pixelX - centerX);
|
||||
pixelX =
|
||||
centerX + Math.cos(angle) * this.currentBoostData.dotDistance * radius;
|
||||
pixelY =
|
||||
centerY + Math.sin(angle) * this.currentBoostData.dotDistance * radius;
|
||||
pixelX = centerX + Math.cos(angle) * dotDistance * radius;
|
||||
pixelY = centerY + Math.sin(angle) * dotDistance * radius;
|
||||
}
|
||||
|
||||
// Rad to degree
|
||||
this.currentBoostData.secondaryDotAngleDegDelta =
|
||||
((angle * 180) / Math.PI + 100 - this.currentBoostData.dotAngleDeg) % 360;
|
||||
((angle * 180) / Math.PI + 100 - primaryDotAngleDeg) % 360;
|
||||
if (this.currentBoostData.secondaryDotAngleDegDelta < 0) {
|
||||
this.currentBoostData.secondaryDotAngleDegDelta += 360;
|
||||
}
|
||||
@@ -902,14 +916,19 @@ ${cssSelector} {
|
||||
const cx = rect.width / 2;
|
||||
const cy = rect.height / 2;
|
||||
|
||||
const dotDistance = this.currentBoostData.dotDistance;
|
||||
const dotAngleDeg = this.currentBoostData.dotAngleDeg;
|
||||
const secondaryDotAngleDelta =
|
||||
this.currentBoostData.secondaryDotAngleDegDelta ?? 0;
|
||||
|
||||
// Updating the circle size to match the distance of the point
|
||||
const circle = this.doc.querySelector(".zen-boost-color-picker-circle");
|
||||
circle.setAttribute("animated", "false");
|
||||
circle.style.width = `${this.currentBoostData.dotDistance * radius * 2}px`;
|
||||
circle.style.height = `${this.currentBoostData.dotDistance * radius * 2}px`;
|
||||
circle.style.width = `${dotDistance * radius * 2}px`;
|
||||
circle.style.height = `${dotDistance * radius * 2}px`;
|
||||
|
||||
const dotColor = `hsl(${this.currentBoostData.dotAngleDeg}deg, ${this.currentBoostData.dotDistance * 100}%, 55%)`;
|
||||
const dotColorSec = `hsl(${this.currentBoostData.dotAngleDeg + this.currentBoostData.secondaryDotAngleDegDelta}deg, ${this.currentBoostData.dotDistance * 100}%, 20%)`;
|
||||
const dotColor = `hsl(${dotAngleDeg}deg, ${dotDistance * 100}%, 55%)`;
|
||||
const dotColorSec = `hsl(${dotAngleDeg + secondaryDotAngleDelta}deg, ${dotDistance * 100}%, 20%)`;
|
||||
|
||||
this.updateArcFill(cx, cy, radius, dotColor, dotColorSec);
|
||||
}
|
||||
@@ -1154,12 +1173,6 @@ ${cssSelector} {
|
||||
invertButton.classList.remove("zen-boost-button-active");
|
||||
}
|
||||
|
||||
if (this.currentBoostData.smartInvert) {
|
||||
invertButton.classList.add("zen-boost-button-active");
|
||||
} else {
|
||||
invertButton.classList.remove("zen-boost-button-active");
|
||||
}
|
||||
|
||||
if (!this.currentBoostData.enableColorBoost) {
|
||||
disableButton.classList.add("zen-boost-button-active-transparent");
|
||||
} else {
|
||||
|
||||
@@ -114,9 +114,12 @@ class nsZenBoostsManager {
|
||||
boostData: {
|
||||
boostName: "My Boost",
|
||||
|
||||
dotAngleDeg: 0,
|
||||
/* These initial values depend on
|
||||
each other. Changing one means having to
|
||||
recalculate all of them manually. */
|
||||
dotAngleDeg: 131.61,
|
||||
dotPos: { x: 0.76, y: 0.66 },
|
||||
dotDistance: 0,
|
||||
dotDistance: 0.91,
|
||||
|
||||
secondaryDotAngleDegDelta: 55,
|
||||
secondaryDotPos: { x: 0.5, y: 0.81 },
|
||||
|
||||
104
src/zen/boosts/gtest/TestZenBoostsAccentCache.cpp
Normal file
104
src/zen/boosts/gtest/TestZenBoostsAccentCache.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/* 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/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/nsZenBoostsBackend.h"
|
||||
|
||||
using zen::detail::AccentCacheSize;
|
||||
using zen::detail::EnsureCachedAccent;
|
||||
using zen::detail::IsAccentCached;
|
||||
using zen::detail::ResetAccentCache;
|
||||
|
||||
namespace {
|
||||
|
||||
class ZenBoostsAccentCache : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override { ResetAccentCache(); }
|
||||
void TearDown() override { ResetAccentCache(); }
|
||||
};
|
||||
|
||||
constexpr nscolor kAccentA = NS_RGBA(80, 120, 200, 200);
|
||||
constexpr nscolor kAccentB = NS_RGBA(200, 80, 80, 200);
|
||||
constexpr nscolor kAccentC = NS_RGBA(80, 200, 120, 200);
|
||||
constexpr nscolor kAccentD = NS_RGBA(200, 200, 80, 200);
|
||||
constexpr nscolor kAccentE = NS_RGBA(120, 80, 200, 200);
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(ZenBoostsAccentCache, SizeIsAtLeastFour) {
|
||||
EXPECT_GE(AccentCacheSize(), 4u);
|
||||
}
|
||||
|
||||
TEST_F(ZenBoostsAccentCache, EmptyAfterReset) {
|
||||
EnsureCachedAccent(kAccentA, 0.0f);
|
||||
ResetAccentCache();
|
||||
EXPECT_FALSE(IsAccentCached(kAccentA, 0.0f));
|
||||
}
|
||||
|
||||
TEST_F(ZenBoostsAccentCache, SameKeyIsCachedAfterEnsure) {
|
||||
EXPECT_FALSE(IsAccentCached(kAccentA, 0.0f));
|
||||
EnsureCachedAccent(kAccentA, 0.0f);
|
||||
EXPECT_TRUE(IsAccentCached(kAccentA, 0.0f));
|
||||
}
|
||||
|
||||
// Keying on accent alone would silently serve a stale complementary accent
|
||||
// when the rotation changes.
|
||||
TEST_F(ZenBoostsAccentCache, DifferentRotationOccupiesDistinctEntry) {
|
||||
EnsureCachedAccent(kAccentA, 0.0f);
|
||||
EnsureCachedAccent(kAccentA, 90.0f);
|
||||
EXPECT_TRUE(IsAccentCached(kAccentA, 0.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentA, 90.0f));
|
||||
}
|
||||
|
||||
TEST_F(ZenBoostsAccentCache, DifferentAccentOccupiesDistinctEntry) {
|
||||
EnsureCachedAccent(kAccentA, 30.0f);
|
||||
EnsureCachedAccent(kAccentB, 30.0f);
|
||||
EXPECT_TRUE(IsAccentCached(kAccentA, 30.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentB, 30.0f));
|
||||
}
|
||||
|
||||
TEST_F(ZenBoostsAccentCache, RoundRobinEvictsOldestEntry) {
|
||||
ASSERT_EQ(AccentCacheSize(), 4u);
|
||||
|
||||
EnsureCachedAccent(kAccentA, 0.0f);
|
||||
EnsureCachedAccent(kAccentB, 0.0f);
|
||||
EnsureCachedAccent(kAccentC, 0.0f);
|
||||
EnsureCachedAccent(kAccentD, 0.0f);
|
||||
|
||||
EXPECT_TRUE(IsAccentCached(kAccentA, 0.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentB, 0.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentC, 0.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentD, 0.0f));
|
||||
|
||||
EnsureCachedAccent(kAccentE, 0.0f);
|
||||
EXPECT_FALSE(IsAccentCached(kAccentA, 0.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentB, 0.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentC, 0.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentD, 0.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentE, 0.0f));
|
||||
}
|
||||
|
||||
// A cache hit must not consume a fresh slot, otherwise repeated paints with
|
||||
// the same accent would evict their own neighbours.
|
||||
TEST_F(ZenBoostsAccentCache, RepeatEnsureDoesNotChurnTheCache) {
|
||||
ASSERT_EQ(AccentCacheSize(), 4u);
|
||||
|
||||
EnsureCachedAccent(kAccentA, 0.0f);
|
||||
EnsureCachedAccent(kAccentB, 0.0f);
|
||||
EnsureCachedAccent(kAccentC, 0.0f);
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
EnsureCachedAccent(kAccentA, 0.0f);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(IsAccentCached(kAccentA, 0.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentB, 0.0f));
|
||||
EXPECT_TRUE(IsAccentCached(kAccentC, 0.0f));
|
||||
|
||||
EnsureCachedAccent(kAccentD, 0.0f);
|
||||
EnsureCachedAccent(kAccentE, 0.0f);
|
||||
|
||||
EXPECT_FALSE(IsAccentCached(kAccentA, 0.0f));
|
||||
}
|
||||
42
src/zen/boosts/gtest/TestZenBoostsResolveStyleColor.cpp
Normal file
42
src/zen/boosts/gtest/TestZenBoostsResolveStyleColor.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/* 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/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/nsZenBoostsBackend.h"
|
||||
|
||||
using zen::nsZenBoostsBackend;
|
||||
|
||||
namespace {
|
||||
|
||||
const nscolor kResolveColors[] = {
|
||||
NS_RGBA(0, 0, 0, 255), NS_RGBA(255, 255, 255, 255),
|
||||
NS_RGBA(128, 128, 128, 255), NS_RGBA(255, 0, 0, 255),
|
||||
NS_RGBA(0, 255, 0, 255), NS_RGBA(0, 0, 255, 255),
|
||||
NS_RGBA(40, 44, 52, 255), NS_RGBA(248, 248, 248, 255),
|
||||
NS_RGBA(20, 22, 28, 255), NS_RGBA(80, 80, 80, 200),
|
||||
NS_RGBA(240, 17, 99, 1), NS_RGBA(0, 0, 0, 0),
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// Removing the null-frame guard would crash chrome-process callers that
|
||||
// legitimately pass nullptr (canvas getComputedStyle, font-palette binding,
|
||||
// the StyleColor(nscolor)/StyleColor(StyleAbsoluteColor) overloads).
|
||||
TEST(ZenBoostsResolveStyleColor, NullFrameIsIdentity)
|
||||
{
|
||||
for (nscolor c : kResolveColors) {
|
||||
EXPECT_EQ(nsZenBoostsBackend::ResolveStyleColor(c, nullptr), c);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ZenBoostsResolveStyleColor, NullFrameIsIdempotent)
|
||||
{
|
||||
for (nscolor c : kResolveColors) {
|
||||
nscolor once = nsZenBoostsBackend::ResolveStyleColor(c, nullptr);
|
||||
nscolor twice = nsZenBoostsBackend::ResolveStyleColor(once, nullptr);
|
||||
EXPECT_EQ(once, c);
|
||||
EXPECT_EQ(twice, c);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"TestZenBoostsAccentCache.cpp",
|
||||
"TestZenBoostsColorFilter.cpp",
|
||||
"TestZenBoostsResolveStyleColor.cpp",
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = "xul-gtest"
|
||||
|
||||
@@ -450,11 +450,9 @@ inline static void GetZenBoostsDataForFrame(const nsIFrame* aFrame,
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef ENABLE_TESTS
|
||||
namespace detail {
|
||||
|
||||
// Thin forwarders that give unit tests access to the pure color math without
|
||||
// pulling in the singleton / BrowsingContext. They are defined here, after the
|
||||
// anonymous namespace, so they can reach those file-local implementations.
|
||||
nsZenAccentOklab PrecomputeAccent(nscolor aAccentColor) {
|
||||
return zenPrecomputeAccent(aAccentColor);
|
||||
}
|
||||
@@ -474,7 +472,33 @@ nscolor InvertColorChannel(nscolor aColor) {
|
||||
return zenInvertColorChannel(aColor);
|
||||
}
|
||||
|
||||
size_t AccentCacheSize() { return kAccentCacheSize; }
|
||||
|
||||
void ResetAccentCache() {
|
||||
for (auto& entry : sAccentCache) {
|
||||
entry.valid = false;
|
||||
entry.accentNS = 0;
|
||||
entry.rotationDeg = 0.0f;
|
||||
}
|
||||
sAccentCacheNext = 0;
|
||||
}
|
||||
|
||||
bool IsAccentCached(nscolor aAccentNS, float aRotationDeg) {
|
||||
for (const auto& entry : sAccentCache) {
|
||||
if (entry.valid && entry.accentNS == aAccentNS &&
|
||||
entry.rotationDeg == aRotationDeg) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EnsureCachedAccent(nscolor aAccentNS, float aRotationDeg) {
|
||||
(void)GetCachedAccent(aAccentNS, aRotationDeg);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
#endif // ENABLE_TESTS
|
||||
|
||||
static mozilla::StaticRefPtr<nsZenBoostsBackend> sZenBoostsBackend;
|
||||
|
||||
|
||||
@@ -27,10 +27,9 @@ struct nsZenAccentOklab {
|
||||
float contrastFactor;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_TESTS
|
||||
// Test-only forwarders into the file-local color math and accent cache.
|
||||
namespace detail {
|
||||
// Pure color-math primitives, exposed for unit testing. These have no
|
||||
// dependency on the singleton, the BrowsingContext, or the process type, so
|
||||
// they can be exercised directly from gtest.
|
||||
nsZenAccentOklab PrecomputeAccent(nscolor aAccentColor);
|
||||
nsZenAccentOklab RotateAccent(const nsZenAccentOklab& aBase,
|
||||
float aRotationDeg);
|
||||
@@ -38,7 +37,13 @@ nscolor FilterColorChannel(nscolor aOriginalColor,
|
||||
const nsZenAccentOklab& aAccent,
|
||||
const nsZenAccentOklab& aComplementary);
|
||||
nscolor InvertColorChannel(nscolor aColor);
|
||||
|
||||
size_t AccentCacheSize();
|
||||
void ResetAccentCache();
|
||||
bool IsAccentCached(nscolor aAccentNS, float aRotationDeg);
|
||||
void EnsureCachedAccent(nscolor aAccentNS, float aRotationDeg);
|
||||
} // namespace detail
|
||||
#endif // ENABLE_TESTS
|
||||
|
||||
class nsZenBoostsBackend final : public nsISupports {
|
||||
public:
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
*/
|
||||
|
||||
#zen-boost-advanced-color-options-panel {
|
||||
color-scheme: light;
|
||||
--panel-padding: 15px;
|
||||
|
||||
& p {
|
||||
color: #3a3a3b;
|
||||
color: var(--zen-boosts-primary-color);
|
||||
}
|
||||
|
||||
& input {
|
||||
|
||||
@@ -34,14 +34,6 @@
|
||||
<link rel="stylesheet" href="chrome://browser/content/zen-styles/zen-advanced-color-options.css" />
|
||||
|
||||
<link rel="localization" href="browser/zen-boosts.ftl"/>
|
||||
|
||||
<!-- Loading in the window module -->
|
||||
<script>
|
||||
const { nsZenBoostEditor } = ChromeUtils.importESModule( "resource:///modules/zen/boosts/ZenBoostsEditor.mjs" );
|
||||
window.addEventListener("load", () => {
|
||||
window.boostEditor = new nsZenBoostEditor(document, window.domain, window, window.openerWindow);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<html:body xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<vbox flex="1" id="zen-boost-editor-root">
|
||||
@@ -120,15 +112,15 @@
|
||||
<popupset id="mainPopupSet">
|
||||
<panel type="arrow" popupalign="topmiddle" id="zen-boost-advanced-color-options-panel">
|
||||
<vbox>
|
||||
<p data-l10n-id="zen-bootst-color-contrast"></p>
|
||||
<p data-l10n-id="zen-boost-color-contrast"></p>
|
||||
<html:input id="zen-boost-color-contrast" type="range" min="0.05" max="0.9" value="0.75" step="0.01"/>
|
||||
</vbox>
|
||||
<vbox>
|
||||
<p data-l10n-id="zen-bootst-color-brightness"></p>
|
||||
<p data-l10n-id="zen-boost-color-brightness"></p>
|
||||
<html:input id="zen-boost-color-brightness" type="range" min="0" max="1" value="0.5" step="0.01"/>
|
||||
</vbox>
|
||||
<vbox>
|
||||
<p data-l10n-id="zen-bootst-color-original-saturation"></p>
|
||||
<p data-l10n-id="zen-boost-color-original-saturation"></p>
|
||||
<html:input id="zen-boost-color-saturation" type="range" min="0" max="1" value="0.5" step="0.01"/>
|
||||
</vbox>
|
||||
</panel>
|
||||
@@ -164,5 +156,10 @@
|
||||
<command id="cmd_zenBoostDelete"
|
||||
oncommand="window.boostEditor.deleteBoost();" />
|
||||
</commandset>
|
||||
|
||||
<script>
|
||||
const { nsZenBoostEditor } = ChromeUtils.importESModule( "resource:///modules/zen/boosts/ZenBoostsEditor.mjs" );
|
||||
window.boostEditor = new nsZenBoostEditor(document, window.domain, window, window.openerWindow);
|
||||
</script>
|
||||
</html:body>
|
||||
</html>
|
||||
|
||||
@@ -5,10 +5,33 @@
|
||||
*/
|
||||
|
||||
#zenBoostWindow {
|
||||
/* For the mica effect we want a white tint */
|
||||
@media not (-moz-platform: linux) {
|
||||
color-scheme: light;
|
||||
}
|
||||
--zen-boosts-primary-background: light-dark(#fcfcfe, #171717);
|
||||
--zen-boosts-secondary-background: light-dark(#f6f6f8, #1c1c1e);
|
||||
--zen-boosts-mica-background: light-dark(#f6f6f8c0, #1c1c1ec0);
|
||||
|
||||
--zen-boosts-primary-color: light-dark(#3a3a3b, #f3f3f3);
|
||||
--zen-boosts-secondary-color: light-dark(#727272, #b1b1b1);
|
||||
|
||||
--zen-boosts-button-background: light-dark(#ebebed, #262626);
|
||||
|
||||
--mod-button-c1: light-dark(#ebebed, #262626);
|
||||
--mod-button-c2: light-dark(#ebebed, #262626);
|
||||
|
||||
--zen-boosts-active-button-background: light-dark(#3a3a3a, #cccccc);
|
||||
--zen-boosts-active-button-hover-background: light-dark(#5b5b5c, #c9c9c9);
|
||||
--zen-boosts-active-button-color: light-dark(#fcfcfe, #1c1c1e);
|
||||
--zen-boosts-back-button-hover-background: light-dark(#e3e3e6, #3a3a3a);
|
||||
|
||||
--zen-boosts-magic-theme-background: light-dark(white, #3a3a3a);
|
||||
--zen-boosts-magic-theme-active-background: light-dark(#3a3a3a, white);
|
||||
|
||||
--zen-boosts-font-wrapper-background: light-dark(white, #262626);
|
||||
|
||||
--zen-boosts-primary-border-color: light-dark(#ededef, #3a3a3a);
|
||||
|
||||
--zen-boosts-color-picker-background: light-dark(#fbfbfdea, #1c1c1eea);
|
||||
--zen-boosts-color-picker-pattern-color: light-dark(#e3e9e4, #3a3a3a);
|
||||
|
||||
appearance: none;
|
||||
border: none;
|
||||
|
||||
@@ -40,12 +63,12 @@
|
||||
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background-color: #f6f6f8;
|
||||
background-color: var(--zen-boosts-secondary-background);
|
||||
@media (-moz-windows-mica) {
|
||||
background-color: #f6f6f8c0;
|
||||
background-color: var(--zen-boosts-mica-background);
|
||||
}
|
||||
|
||||
border: solid 0 #ededef;
|
||||
border: solid 0 var(--zen-boosts-primary-border-color);
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
@@ -58,6 +81,9 @@
|
||||
margin-left: 4px;
|
||||
border-radius: 8px;
|
||||
|
||||
-moz-context-properties: fill;
|
||||
fill: var(--zen-boosts-primary-color);
|
||||
|
||||
opacity: 0.75;
|
||||
background-color: transparent;
|
||||
|
||||
@@ -79,12 +105,12 @@
|
||||
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #f6f6f8;
|
||||
background-color: var(--zen-boosts-secondary-background);
|
||||
@media (-moz-windows-mica) {
|
||||
background-color: #f6f6f8c0;
|
||||
background-color: var(--zen-boosts-mica-background);
|
||||
}
|
||||
|
||||
border: solid 0 #ededef;
|
||||
border: solid 0 var(--zen-boosts-primary-border-color);
|
||||
border-top-width: 1px;
|
||||
|
||||
display: flex;
|
||||
@@ -113,6 +139,7 @@ body {
|
||||
user-select: none;
|
||||
|
||||
width: 100%;
|
||||
min-height: 582px;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
@@ -148,7 +175,7 @@ body {
|
||||
}
|
||||
|
||||
.subviewbutton {
|
||||
color: #3a3a3b;
|
||||
color: var(--zen-boosts-primary-color);
|
||||
}
|
||||
|
||||
#zen-boost-editor-view {
|
||||
@@ -166,11 +193,11 @@ body {
|
||||
min-height: 40px;
|
||||
max-height: 40px;
|
||||
align-items: center;
|
||||
background-color: #f6f6f8;
|
||||
border: solid 1px #e7e7e7ab;
|
||||
background-color: var(--zen-boosts-secondary-background);
|
||||
border: solid 1px var(--zen-boosts-primary-border-color);
|
||||
|
||||
@media (-moz-windows-mica) {
|
||||
background-color: #f6f6f8c0;
|
||||
background-color: var(--zen-boosts-mica-background);
|
||||
border: none;
|
||||
}
|
||||
|
||||
@@ -232,6 +259,7 @@ body {
|
||||
padding: 2px;
|
||||
|
||||
& button {
|
||||
color: var(--zen-boosts-primary-color) !important;
|
||||
padding: auto;
|
||||
margin: auto;
|
||||
background-color: transparent;
|
||||
@@ -243,7 +271,7 @@ body {
|
||||
gap: 14px;
|
||||
padding-top: 6px;
|
||||
|
||||
background-color: #fcfcfe;
|
||||
background-color: var(--zen-boosts-primary-background);
|
||||
|
||||
-moz-window-dragging: drag;
|
||||
& > * {
|
||||
@@ -328,7 +356,7 @@ body {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
background-color: #ebebed;
|
||||
background-color: var(--zen-boosts-button-background);
|
||||
|
||||
transition:
|
||||
0.4s background-color cubic-bezier(0.075, 0.82, 0.165, 1),
|
||||
@@ -348,7 +376,7 @@ body {
|
||||
}
|
||||
|
||||
#zen-boost-case:not([case-mode="none"]) {
|
||||
background-color: #ebebed;
|
||||
background-color: var(--zen-boosts-button-background);
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
@@ -373,7 +401,7 @@ body {
|
||||
font-size: 8pt;
|
||||
text-indent: 2px;
|
||||
vertical-align: middle;
|
||||
color: #3a3a3b;
|
||||
color: var(--zen-boosts-primary-color);
|
||||
|
||||
justify-content: center;
|
||||
}
|
||||
@@ -397,12 +425,16 @@ body {
|
||||
}
|
||||
|
||||
.zen-boost-button-active {
|
||||
background-color: #3a3a3a;
|
||||
color: #fcfcfe;
|
||||
background-color: var(--zen-boosts-active-button-background);
|
||||
color: var(--zen-boosts-active-button-color);
|
||||
|
||||
&#zen-boost-magic-theme {
|
||||
background-color: var(--zen-boosts-magic-theme-active-background);
|
||||
}
|
||||
}
|
||||
|
||||
.zen-boost-button-active:hover {
|
||||
background-color: #5b5b5c;
|
||||
background-color: var(--zen-boosts-active-button-hover-background);
|
||||
}
|
||||
|
||||
.zen-boost-button-active-transparent {
|
||||
@@ -430,12 +462,13 @@ body {
|
||||
}
|
||||
|
||||
&:not(.zen-boost-button-active) {
|
||||
background: white;
|
||||
background: var(--zen-boosts-magic-theme-background);
|
||||
color: var(--zen-boosts-primary-color);
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
background-color: #F6F6F8;
|
||||
background-color: var(--zen-boosts-secondary-background);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
@@ -471,7 +504,7 @@ body {
|
||||
|
||||
transition: 0.2s opacity ease-in-out;
|
||||
|
||||
color: #727272;
|
||||
color: var(--zen-boosts-secondary-color);
|
||||
background: none;
|
||||
|
||||
font-size: 9pt;
|
||||
@@ -490,7 +523,7 @@ body {
|
||||
|
||||
&[has-selection="true"] {
|
||||
opacity: 1;
|
||||
background-color: #ebebed;
|
||||
background-color: var(--zen-boosts-button-background);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,7 +546,7 @@ body {
|
||||
|
||||
#zen-boost-font-wrapper {
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,.15);
|
||||
background-color: #ffffff;
|
||||
background-color: var(--zen-boosts-font-wrapper-background);
|
||||
|
||||
border-radius: 6px;
|
||||
@media (-moz-platform: macos) {
|
||||
@@ -564,35 +597,35 @@ body {
|
||||
|
||||
@property --mod-button-c1 {
|
||||
syntax: "<color>";
|
||||
inherits: false;
|
||||
initial-value: #ebebed;
|
||||
inherits: true;
|
||||
initial-value: transparent;
|
||||
}
|
||||
|
||||
@property --mod-button-c2 {
|
||||
syntax: "<color>";
|
||||
inherits: false;
|
||||
initial-value: #ebebed;
|
||||
inherits: true;
|
||||
initial-value: transparent;
|
||||
}
|
||||
|
||||
.mod-button[mode="orange"] {
|
||||
color: #e3e9e4;
|
||||
--mod-button-c1: #ffbb5d;
|
||||
--mod-button-c2: #ffa01d;
|
||||
--mod-button-c1: light-dark(#ffbb5d, #c37a3f);
|
||||
--mod-button-c2: light-dark(#ffa01d, #9f5a2a);
|
||||
}
|
||||
.mod-button[mode="orange-red"] {
|
||||
color: #e3e9e4;
|
||||
--mod-button-c1: #ff8758;
|
||||
--mod-button-c2: #ff5b1b;
|
||||
--mod-button-c1: light-dark(#ff8758, #bd6048);
|
||||
--mod-button-c2: light-dark(#ff5b1b, #9b422b);
|
||||
}
|
||||
.mod-button[mode="red"] {
|
||||
color: #e3e9e4;
|
||||
--mod-button-c1: #ff595f;
|
||||
--mod-button-c2: #ff121b;
|
||||
--mod-button-c1: light-dark(#ff595f, #b94a50);
|
||||
--mod-button-c2: light-dark(#ff121b, #95272e);
|
||||
}
|
||||
.mod-button[mode="blue"] {
|
||||
color: #e3e9e4;
|
||||
--mod-button-c1: #6650fc;
|
||||
--mod-button-c2: #4125ff;
|
||||
--mod-button-c1: light-dark(#6650fc, #5d56ca);
|
||||
--mod-button-c2: light-dark(#4125ff, #453aa9);
|
||||
}
|
||||
.mod-button[mode] {
|
||||
background: linear-gradient(180deg, var(--mod-button-c1) 0%, var(--mod-button-c2) 100%) border-box;
|
||||
@@ -608,7 +641,7 @@ body {
|
||||
background-color: transparent;
|
||||
|
||||
&:hover {
|
||||
background-color: #e3e3e6;
|
||||
background-color: var(--zen-boosts-back-button-hover-background);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,17 +668,17 @@ body {
|
||||
|
||||
z-index: 2;
|
||||
|
||||
background: #fbfbfdea;
|
||||
background: var(--zen-boosts-color-picker-background);
|
||||
|
||||
background-position: -23px -23px;
|
||||
backdrop-filter: saturate(2) blur(15px);
|
||||
|
||||
background-size: 6px 6px;
|
||||
background-image: radial-gradient(#e3e9e4, 1px, transparent 0);
|
||||
background-image: radial-gradient(var(--zen-boosts-color-picker-pattern-color), 1px, transparent 0);
|
||||
|
||||
@media (-moz-platform: macos) {
|
||||
background-size: 4px 4px;
|
||||
background-image: radial-gradient(#e3e9e4 0.5px, transparent 0);
|
||||
background-image: radial-gradient(var(--zen-boosts-color-picker-pattern-color) 0.5px, transparent 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
}
|
||||
|
||||
#select-component {
|
||||
--zen-boosts-selector-background: light-dark(#f5f7fb, #27272a);
|
||||
--zen-boosts-selector-preview-background: light-dark(#e0e2e63d, #27272a3d);
|
||||
--zen-boosts-selector-preview-color: light-dark(rgb(76, 78, 80), rgb(207, 200, 200));
|
||||
--zen-boosts-selector-button-color: light-dark(#dadada, #f1f1f1);
|
||||
--zen-boosts-selector-outline-color: light-dark(#e0e2e6ae, #474749);
|
||||
|
||||
width: min-content;
|
||||
font-family: system-ui;
|
||||
|
||||
@@ -29,7 +35,7 @@
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
|
||||
background-color: #f5f7fb;
|
||||
background-color: var(--zen-boosts-selector-background);
|
||||
margin: 4px;
|
||||
|
||||
border-radius: 12px;
|
||||
@@ -126,17 +132,29 @@
|
||||
|
||||
width: 250px !important;
|
||||
--related-elements-value: 100%;
|
||||
background: linear-gradient(to top, rgb(247, 66, 0), rgb(245, 134, 86));
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
light-dark(#ff5b1b, #9b422b),
|
||||
light-dark(#ff8758, #bd6048)
|
||||
);
|
||||
|
||||
border: none;
|
||||
color: #dadada;
|
||||
color: var(--zen-boosts-selector-button-color);
|
||||
box-shadow: 0 0 15px #00000052;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0 14px #00000066;
|
||||
background:
|
||||
linear-gradient(to right, transparent var(--related-elements-value), gray var(--related-elements-value)),
|
||||
linear-gradient(to top, rgb(247, 66, 0), rgb(245, 134, 86));
|
||||
linear-gradient(
|
||||
to right,
|
||||
transparent var(--related-elements-value),
|
||||
light-dark(gray, #363636) var(--related-elements-value)
|
||||
),
|
||||
linear-gradient(
|
||||
to top,
|
||||
light-dark(#ff5b1b, #9b422b),
|
||||
light-dark(#ff8758, #bd6048)
|
||||
);
|
||||
|
||||
@media not (-moz-platform: windows) {
|
||||
box-shadow: 0 0 20px #00000077;
|
||||
@@ -147,30 +165,34 @@
|
||||
#select-this {
|
||||
appearance: none;
|
||||
|
||||
background: linear-gradient(0deg, rgba(246, 27, 25, 1) 0%, rgba(254, 67, 59, 1) 100%);
|
||||
background: linear-gradient(
|
||||
0deg,
|
||||
light-dark(#ff121b, #95272e),
|
||||
light-dark(#ff595f, #b94a50)
|
||||
);
|
||||
border: none;
|
||||
color: #dadada;
|
||||
color: var(--zen-boosts-selector-button-color);
|
||||
|
||||
box-shadow: 0 0 15px #00000052;
|
||||
}
|
||||
|
||||
#select-cancel {
|
||||
appearance: none;
|
||||
|
||||
background: rgb(90, 94, 100);
|
||||
@media (-moz-platform: macos) {
|
||||
background: linear-gradient(0deg, rgba(81, 83, 85, 1) 0%, rgba(108, 110, 112, 1) 100%);
|
||||
}
|
||||
background: linear-gradient(
|
||||
0deg,
|
||||
light-dark(#525355, #373739) 0%,
|
||||
light-dark(#6c6e70, #4b4c4e) 100%
|
||||
);
|
||||
|
||||
border: none;
|
||||
color: #dadada;
|
||||
color: var(--zen-boosts-selector-button-color);
|
||||
|
||||
box-shadow: 0 0 15px #00000052;
|
||||
}
|
||||
|
||||
#selector-preview {
|
||||
background-color: #e0e2e63d;
|
||||
outline: 1px solid #e0e2e6ae;
|
||||
background-color: var(--zen-boosts-selector-preview-background);
|
||||
outline: 1px solid var(--zen-boosts-selector-outline-color);
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
text-indent: 18px;
|
||||
@@ -182,7 +204,7 @@
|
||||
#selector-element-preview-text {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 9pt;
|
||||
color: rgb(76, 78, 80);
|
||||
color: var(--zen-boosts-selector-preview-color);
|
||||
}
|
||||
|
||||
#hover-div {
|
||||
|
||||
@@ -495,7 +495,7 @@
|
||||
border-radius: 99px;
|
||||
width: var(--size-item-large);
|
||||
height: var(--size-item-large);
|
||||
background: var(--button-background-color-primary);
|
||||
background: var(--zen-sidebar-themed-icon-fill);
|
||||
opacity: 0.6;
|
||||
transition:
|
||||
transform 0.12s ease-in-out,
|
||||
@@ -540,6 +540,10 @@
|
||||
|
||||
& toolbarbutton {
|
||||
margin: 0;
|
||||
|
||||
&[disabled] {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -621,7 +625,7 @@
|
||||
color: var(--button-primary-color);
|
||||
|
||||
&::before {
|
||||
background: var(--button-background-color-primary);
|
||||
background: var(--zen-sidebar-themed-icon-fill);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -786,4 +790,8 @@
|
||||
@media not -moz-pref("zen.view.enable-loading-indicator") {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:root[inDOMFullscreen="true"] & {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,17 +168,17 @@
|
||||
document.documentElement.setAttribute("zen-no-padding", true);
|
||||
} else {
|
||||
document.documentElement.removeAttribute("zen-no-padding");
|
||||
if (domFullscreen) {
|
||||
const selectedBrowser = gBrowser.selectedBrowser;
|
||||
selectedBrowser.style.paddingRight = "0.5px";
|
||||
window.addEventListener(
|
||||
"MozAfterPaint",
|
||||
() => {
|
||||
selectedBrowser.style.paddingRight = "";
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
}
|
||||
}
|
||||
if (domFullscreen) {
|
||||
const selectedBrowser = gBrowser.selectedBrowser;
|
||||
selectedBrowser.style.paddingRight = "0.5px";
|
||||
window.addEventListener(
|
||||
"MozAfterPaint",
|
||||
() => {
|
||||
selectedBrowser.style.paddingRight = "";
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -861,6 +861,7 @@ class nsZenWorkspaces {
|
||||
"Selecting empty tab because startup page didnt select a valid tab"
|
||||
);
|
||||
this.selectEmptyTab();
|
||||
initialTabWasEmpty = true;
|
||||
}
|
||||
this.log("Removing empty tab added by startup page");
|
||||
this._removedByStartupPage = true;
|
||||
@@ -2978,11 +2979,18 @@ class nsZenWorkspaces {
|
||||
|
||||
// Tab browser utilities
|
||||
|
||||
getContextIdIfNeeded(userContextId, fromExternal) {
|
||||
getContextIdIfNeeded(userContextId, fromExternal, triggeringPrincipal) {
|
||||
if (!this.workspaceEnabled) {
|
||||
return [userContextId, false, undefined];
|
||||
}
|
||||
|
||||
if (
|
||||
triggeringPrincipal &&
|
||||
triggeringPrincipal.isAddonOrExpandedAddonPrincipal
|
||||
) {
|
||||
return [userContextId, false, undefined];
|
||||
}
|
||||
|
||||
if (
|
||||
this.shouldForceContainerTabsToWorkspace &&
|
||||
typeof userContextId !== "undefined" &&
|
||||
|
||||
@@ -322,7 +322,6 @@ zen-workspace {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
color: var(--toolbox-textcolor);
|
||||
will-change: transform;
|
||||
|
||||
@media not (prefers-reduced-motion: reduce) {
|
||||
transition: padding-top 0.1s;
|
||||
|
||||
@@ -1131,7 +1131,6 @@
|
||||
transition:
|
||||
max-height 0.3s ease-out,
|
||||
grid-template-columns 0.3s ease-out;
|
||||
will-change: transform;
|
||||
opacity: 1;
|
||||
--min-essentials-width-wrap: calc(var(--tab-min-height) + 4px);
|
||||
grid-template-columns: repeat(auto-fit, minmax(max(23.7%, var(--min-essentials-width-wrap)), 1fr));
|
||||
|
||||
@@ -8,6 +8,41 @@ support-files = [
|
||||
]
|
||||
|
||||
["browser_boost_selector_basic.js"]
|
||||
|
||||
["browser_boost_selector_escaping.js"]
|
||||
|
||||
["browser_boost_selector_invalid.js"]
|
||||
|
||||
["browser_boost_selector_nthchild.js"]
|
||||
|
||||
["browser_boosts_animation.js"]
|
||||
|
||||
["browser_boosts_background.js"]
|
||||
|
||||
["browser_boosts_border.js"]
|
||||
|
||||
["browser_boosts_gradient.js"]
|
||||
|
||||
["browser_boosts_inline_svg.js"]
|
||||
|
||||
["browser_boosts_input_text.js"]
|
||||
|
||||
["browser_boosts_invert.js"]
|
||||
|
||||
["browser_boosts_outline.js"]
|
||||
|
||||
["browser_boosts_placeholder.js"]
|
||||
|
||||
["browser_boosts_pseudo_before.js"]
|
||||
|
||||
["browser_boosts_shadow.js"]
|
||||
|
||||
["browser_boosts_svg_background_image.js"]
|
||||
|
||||
["browser_boosts_svg_image.js"]
|
||||
|
||||
["browser_boosts_svg_linear_gradient.js"]
|
||||
|
||||
["browser_boosts_svg_use_sprite.js"]
|
||||
|
||||
["browser_boosts_text_color.js"]
|
||||
|
||||
52
src/zen/tests/boosts/browser_boosts_animation.js
Normal file
52
src/zen/tests/boosts/browser_boosts_animation.js
Normal file
@@ -0,0 +1,52 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// The compositor animation path in AnimationInfo.cpp resolves a colour with
|
||||
// the host frame, then either takes it as-is (currentColor keyframe) or
|
||||
// passes it through ResolveStyleColor (absolute keyframe). Both paths must
|
||||
// end up at the same boosted colour as the static equivalent. We pin a
|
||||
// background-color animation at 50% via animation-delay and compare against
|
||||
// a static element that holds the interpolated colour.
|
||||
add_task(async function animated_background_is_boosted() {
|
||||
// Paused-at-50% animation between #000 and #fff → mid grey at the sampled
|
||||
// time. We compare against a static rgb(128,128,128) swatch and require
|
||||
// both to land at the same colour after boost.
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
.swatch { width: 200px; height: 200px; display: inline-block;
|
||||
vertical-align: top; }
|
||||
#static { background-color: rgb(128, 128, 128); }
|
||||
@keyframes fade { from { background-color: black; } to { background-color: white; } }
|
||||
#animated {
|
||||
background-color: black;
|
||||
animation: fade 4s linear infinite;
|
||||
animation-delay: -2s;
|
||||
animation-play-state: paused;
|
||||
}
|
||||
</style>
|
||||
<div id="static" class="swatch"></div>
|
||||
<div id="animated" class="swatch"></div>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const staticBoosted = await pixelInElement(browser, "#static");
|
||||
const animBoosted = await pixelInElement(browser, "#animated");
|
||||
|
||||
Assert.ok(
|
||||
pixelsClose(staticBoosted, animBoosted, 6),
|
||||
`animated and static mid-grey must land at the same boosted colour; ` +
|
||||
`static=${JSON.stringify(staticBoosted)} animated=${JSON.stringify(
|
||||
animBoosted
|
||||
)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
50
src/zen/tests/boosts/browser_boosts_background.js
Normal file
50
src/zen/tests/boosts/browser_boosts_background.js
Normal file
@@ -0,0 +1,50 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Verifies that activating a boost on a tab moves the painted colour of a
|
||||
// plain CSS `background-color` block. Catches regressions where the per-color
|
||||
// boost in StyleAbsoluteColor::ToColor or CalcColor is bypassed for
|
||||
// backgrounds, and the gap that would surface if nsCSSRendering ever stopped
|
||||
// passing the frame through GetVisitedDependentColor.
|
||||
add_task(async function bg_color_is_tinted() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
#bg { width: 200px; height: 200px; background-color: rgb(120, 120, 120); }
|
||||
</style>
|
||||
<div id="bg"></div>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const baseline = await pixelInElement(browser, "#bg");
|
||||
Assert.equal(baseline.r, 120, "baseline R is the literal background");
|
||||
Assert.equal(baseline.g, 120, "baseline G is the literal background");
|
||||
Assert.equal(baseline.b, 120, "baseline B is the literal background");
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const boosted = await pixelInElement(browser, "#bg");
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(baseline, boosted, 3),
|
||||
`boost should tint the background; got baseline=${JSON.stringify(
|
||||
baseline
|
||||
)} boosted=${JSON.stringify(boosted)}`
|
||||
);
|
||||
|
||||
// Sanity: clear the boost and the painted colour returns home.
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const cleared = await pixelInElement(browser, "#bg");
|
||||
Assert.ok(
|
||||
pixelsClose(cleared, baseline, 2),
|
||||
`clearing boost should restore original; got ${JSON.stringify(cleared)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
53
src/zen/tests/boosts/browser_boosts_border.js
Normal file
53
src/zen/tests/boosts/browser_boosts_border.js
Normal file
@@ -0,0 +1,53 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Borders go through nsCSSRendering::ComputeBorderColors → CalcColor with the
|
||||
// frame, so the boost should reach them. Use a thick solid border and sample
|
||||
// inside the border band (which is fully the border colour) rather than the
|
||||
// element interior.
|
||||
add_task(async function border_color_is_tinted() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
#b { width: 200px; height: 200px; margin: 50px;
|
||||
background: white;
|
||||
border: 30px solid rgb(120, 120, 120); }
|
||||
</style>
|
||||
<div id="b"></div>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
// Sample a point inside the top border band: x = centre of element, y just
|
||||
// below the top edge (well inside the 30px-wide border).
|
||||
const point = await SpecialPowers.spawn(browser, [], () => {
|
||||
const r = content.document.querySelector("#b").getBoundingClientRect();
|
||||
return {
|
||||
x: Math.round(r.left + r.width / 2),
|
||||
y: Math.round(r.top + 15),
|
||||
};
|
||||
});
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const baseline = await pixelAt(browser, point.x, point.y);
|
||||
Assert.ok(
|
||||
pixelsClose(baseline, { r: 120, g: 120, b: 120 }, 5),
|
||||
`baseline border colour ≈ rgb(120,120,120); got ${JSON.stringify(baseline)}`
|
||||
);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const boosted = await pixelAt(browser, point.x, point.y);
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(baseline, boosted, 3),
|
||||
`border colour should be tinted; baseline=${JSON.stringify(baseline)} ` +
|
||||
`boosted=${JSON.stringify(boosted)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
83
src/zen/tests/boosts/browser_boosts_gradient.js
Normal file
83
src/zen/tests/boosts/browser_boosts_gradient.js
Normal file
@@ -0,0 +1,83 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// CSS linear-gradient stops are resolved via the nsCSSGradientRenderer +
|
||||
// ColorStopInterpolator path, which threads the frame down into
|
||||
// gfxUtils::ToDeviceColor(StyleAbsoluteColor, frame). If that threading
|
||||
// regresses, gradient stops paint without the boost while everything else
|
||||
// around them gets tinted — a particularly visible regression.
|
||||
add_task(async function linear_gradient_stops_are_boosted() {
|
||||
// Use a two-stop horizontal gradient so a sample near the left edge is
|
||||
// dominated by the first stop and a sample near the right edge by the
|
||||
// second. The element is sized 400×200 so we have generous sample regions.
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
#g { width: 400px; height: 200px;
|
||||
background: linear-gradient(to right,
|
||||
rgb(180, 60, 60),
|
||||
rgb(60, 60, 180)); }
|
||||
</style>
|
||||
<div id="g"></div>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
// Sample 5% in (mostly first stop) and 95% in (mostly last stop).
|
||||
const points = await SpecialPowers.spawn(browser, [], () => {
|
||||
const r = content.document.querySelector("#g").getBoundingClientRect();
|
||||
return {
|
||||
left: {
|
||||
x: Math.round(r.left + r.width * 0.05),
|
||||
y: Math.round(r.top + r.height / 2),
|
||||
},
|
||||
right: {
|
||||
x: Math.round(r.left + r.width * 0.95),
|
||||
y: Math.round(r.top + r.height / 2),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const leftBaseline = await pixelAt(browser, points.left.x, points.left.y);
|
||||
const rightBaseline = await pixelAt(
|
||||
browser,
|
||||
points.right.x,
|
||||
points.right.y
|
||||
);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const leftBoosted = await pixelAt(browser, points.left.x, points.left.y);
|
||||
const rightBoosted = await pixelAt(browser, points.right.x, points.right.y);
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(leftBaseline, leftBoosted, 3),
|
||||
`left gradient stop must tint; baseline=${JSON.stringify(
|
||||
leftBaseline
|
||||
)} boosted=${JSON.stringify(leftBoosted)}`
|
||||
);
|
||||
Assert.ok(
|
||||
pixelsDiffer(rightBaseline, rightBoosted, 3),
|
||||
`right gradient stop must tint; baseline=${JSON.stringify(
|
||||
rightBaseline
|
||||
)} boosted=${JSON.stringify(rightBoosted)}`
|
||||
);
|
||||
|
||||
// The two stops must remain distinguishable after boost — otherwise the
|
||||
// gradient has flattened, which would be a separate regression (e.g.,
|
||||
// ToDeviceColor losing per-stop frame context and collapsing to a single
|
||||
// tinted value).
|
||||
Assert.ok(
|
||||
pixelsDiffer(leftBoosted, rightBoosted, 8),
|
||||
`boosted gradient endpoints collapsed; left=${JSON.stringify(
|
||||
leftBoosted
|
||||
)} right=${JSON.stringify(rightBoosted)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
106
src/zen/tests/boosts/browser_boosts_inline_svg.js
Normal file
106
src/zen/tests/boosts/browser_boosts_inline_svg.js
Normal file
@@ -0,0 +1,106 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// The "twice" diagnostic: paint an inline SVG fill and a CSS background-color
|
||||
// with the *same* source colour, side by side. Under boost they must end up
|
||||
// painted with the same boosted colour. If the SVG sample comes out
|
||||
// noticeably more saturated / further from the baseline than the CSS one, the
|
||||
// SVG paint path is applying the boost twice (the symptom you reported).
|
||||
add_task(async function inline_svg_fill_matches_css_bg_under_boost() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
#div, #svg { width: 200px; height: 200px; display: inline-block;
|
||||
vertical-align: top; }
|
||||
#div { background-color: rgb(51, 54, 57); }
|
||||
</style>
|
||||
<div id="div"></div>
|
||||
<svg id="svg" width="200" height="200" viewBox="0 0 200 200">
|
||||
<rect width="200" height="200" fill="rgb(51, 54, 57)"/>
|
||||
</svg>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const divBaseline = await pixelInElement(browser, "#div");
|
||||
const svgBaseline = await pixelInElement(browser, "#svg");
|
||||
// Sanity: both paint the same source colour before any boost.
|
||||
Assert.ok(
|
||||
pixelsClose(divBaseline, svgBaseline, 2),
|
||||
`pre-boost div/svg should already match; div=${JSON.stringify(
|
||||
divBaseline
|
||||
)} svg=${JSON.stringify(svgBaseline)}`
|
||||
);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const divBoosted = await pixelInElement(browser, "#div");
|
||||
const svgBoosted = await pixelInElement(browser, "#svg");
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(divBaseline, divBoosted, 3),
|
||||
"div background must be tinted under boost (sanity)"
|
||||
);
|
||||
Assert.ok(
|
||||
pixelsDiffer(svgBaseline, svgBoosted, 3),
|
||||
"SVG fill must be tinted under boost (sanity)"
|
||||
);
|
||||
|
||||
// Headline assertion: the SVG fill and the CSS background, both starting
|
||||
// from rgb(51, 54, 57) on the same page, must land at the same colour
|
||||
// after the boost. A larger gap is the "filtered twice" symptom.
|
||||
Assert.ok(
|
||||
pixelsClose(divBoosted, svgBoosted, 4),
|
||||
`SVG fill drifted from CSS background under boost — likely double-` +
|
||||
`applied boost on the SVG path. div=${JSON.stringify(
|
||||
divBoosted
|
||||
)} svg=${JSON.stringify(svgBoosted)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Same comparison but with `fill="currentColor"` — your reported case. The SVG
|
||||
// inherits `color` and resolves it via the path frame; the CSS swatch resolves
|
||||
// via its own frame. Both must land in the same place after one boost pass.
|
||||
add_task(async function inline_svg_currentcolor_matches_css_under_boost() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
.row { color: rgb(51, 54, 57); }
|
||||
#div, #svg { width: 200px; height: 200px; display: inline-block;
|
||||
vertical-align: top; }
|
||||
#div { background-color: currentColor; }
|
||||
</style>
|
||||
<div class="row">
|
||||
<div id="div"></div>
|
||||
<svg id="svg" width="200" height="200" viewBox="0 0 200 200"
|
||||
fill="currentColor">
|
||||
<rect width="200" height="200"/>
|
||||
</svg>
|
||||
</div>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const divBoosted = await pixelInElement(browser, "#div");
|
||||
const svgBoosted = await pixelInElement(browser, "#svg");
|
||||
|
||||
Assert.ok(
|
||||
pixelsClose(divBoosted, svgBoosted, 4),
|
||||
`SVG currentColor fill must match the same-colour CSS swatch after ` +
|
||||
`boost. div=${JSON.stringify(divBoosted)} svg=${JSON.stringify(
|
||||
svgBoosted
|
||||
)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
59
src/zen/tests/boosts/browser_boosts_input_text.js
Normal file
59
src/zen/tests/boosts/browser_boosts_input_text.js
Normal file
@@ -0,0 +1,59 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// The editor content of <input> / <textarea> sits in a UA-widget shadow tree;
|
||||
// the boost-exemption logic must treat it as author content. To get a clean
|
||||
// sample we use textarea (more text area, no themed background overdraw on
|
||||
// the sample point) with an explicit colour so we know the baseline.
|
||||
add_task(async function input_text_is_boosted() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
textarea {
|
||||
appearance: none; /* avoid theme repainting over our sample */
|
||||
background: white;
|
||||
color: rgb(40, 44, 52);
|
||||
font: 200px/1 system-ui, sans-serif;
|
||||
border: none;
|
||||
padding: 0 20px;
|
||||
width: 600px;
|
||||
height: 240px;
|
||||
}
|
||||
</style>
|
||||
<textarea id="t">█</textarea>`;
|
||||
// Full-block U+2588 again — the centre pixel is the solid foreground colour.
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
// The block character sits near the start of the textarea content box.
|
||||
const point = await SpecialPowers.spawn(browser, [], () => {
|
||||
const r = content.document.querySelector("#t").getBoundingClientRect();
|
||||
// Estimate the block's centre: x ≈ left padding + half a glyph width;
|
||||
// y ≈ vertical centre of the line box.
|
||||
return {
|
||||
x: Math.round(r.left + 120),
|
||||
y: Math.round(r.top + 120),
|
||||
};
|
||||
});
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const baseline = await pixelAt(browser, point.x, point.y);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const boosted = await pixelAt(browser, point.x, point.y);
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(baseline, boosted, 3),
|
||||
`editor text must tint with boost; baseline=${JSON.stringify(
|
||||
baseline
|
||||
)} boosted=${JSON.stringify(boosted)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
46
src/zen/tests/boosts/browser_boosts_invert.js
Normal file
46
src/zen/tests/boosts/browser_boosts_invert.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Invert mode: white must come out dark, black must come out light. A double-
|
||||
// invert regression (invert applied twice somewhere in the paint pipeline)
|
||||
// looks like "white stays white" / "black stays black" — which is exactly
|
||||
// what this test guards.
|
||||
add_task(async function invert_flips_lightness() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
.swatch { width: 200px; height: 200px; display: inline-block; }
|
||||
#white { background: white; }
|
||||
#black { background: black; }
|
||||
</style>
|
||||
<div id="white" class="swatch"></div>
|
||||
<div id="black" class="swatch"></div>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
await setBoost(browser, { accent: 0, inverted: false });
|
||||
const whiteOff = await pixelInElement(browser, "#white");
|
||||
const blackOff = await pixelInElement(browser, "#black");
|
||||
Assert.greater(pxLuma(whiteOff), 240, "baseline white is bright");
|
||||
Assert.less(pxLuma(blackOff), 16, "baseline black is dark");
|
||||
|
||||
await setBoost(browser, { accent: 0, inverted: true });
|
||||
const whiteOn = await pixelInElement(browser, "#white");
|
||||
const blackOn = await pixelInElement(browser, "#black");
|
||||
|
||||
Assert.less(
|
||||
pxLuma(whiteOn),
|
||||
pxLuma(whiteOff),
|
||||
"white must darken under invert; double-invert would leave it bright"
|
||||
);
|
||||
Assert.greater(
|
||||
pxLuma(blackOn),
|
||||
pxLuma(blackOff),
|
||||
"black must lighten under invert (and stay off pure black via the floor)"
|
||||
);
|
||||
});
|
||||
});
|
||||
54
src/zen/tests/boosts/browser_boosts_outline.js
Normal file
54
src/zen/tests/boosts/browser_boosts_outline.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// CSS `outline` is painted by nsCSSRendering with its own color path. Pin
|
||||
// that it gets the boost: a thick solid outline must tint when the page is
|
||||
// boosted (just like a border does), and the sample point inside the outline
|
||||
// band must move noticeably.
|
||||
add_task(async function outline_color_is_tinted() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
#o { width: 200px; height: 200px; margin: 60px;
|
||||
background: white;
|
||||
outline: 30px solid rgb(120, 120, 120);
|
||||
outline-offset: 0; }
|
||||
</style>
|
||||
<div id="o"></div>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
// Sample inside the outline band on the left side of the element.
|
||||
const point = await SpecialPowers.spawn(browser, [], () => {
|
||||
const r = content.document.querySelector("#o").getBoundingClientRect();
|
||||
return {
|
||||
x: Math.round(r.left - 15),
|
||||
y: Math.round(r.top + r.height / 2),
|
||||
};
|
||||
});
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const baseline = await pixelAt(browser, point.x, point.y);
|
||||
Assert.ok(
|
||||
pixelsClose(baseline, { r: 120, g: 120, b: 120 }, 5),
|
||||
`baseline outline ≈ rgb(120,120,120); got ${JSON.stringify(baseline)}`
|
||||
);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const boosted = await pixelAt(browser, point.x, point.y);
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(baseline, boosted, 3),
|
||||
`outline must tint; baseline=${JSON.stringify(
|
||||
baseline
|
||||
)} boosted=${JSON.stringify(boosted)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
57
src/zen/tests/boosts/browser_boosts_placeholder.js
Normal file
57
src/zen/tests/boosts/browser_boosts_placeholder.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// `::placeholder` is an element-backed pseudo inside a text-control's UA
|
||||
// widget shadow tree. The boost-exemption logic must un-exempt it the same
|
||||
// way it does the editor's typed text. Use a solid-block character as the
|
||||
// placeholder so we get a clean foreground sample.
|
||||
add_task(async function placeholder_is_boosted() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
input {
|
||||
appearance: none;
|
||||
background: white;
|
||||
color: rgb(40, 44, 52);
|
||||
font: 200px/1 system-ui, sans-serif;
|
||||
border: none;
|
||||
padding: 0 20px;
|
||||
width: 600px;
|
||||
height: 260px;
|
||||
}
|
||||
input::placeholder { color: rgb(40, 44, 52); opacity: 1; }
|
||||
</style>
|
||||
<input id="i" placeholder="█">`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
const point = await SpecialPowers.spawn(browser, [], () => {
|
||||
const r = content.document.querySelector("#i").getBoundingClientRect();
|
||||
// The placeholder block sits near the left of the input.
|
||||
return {
|
||||
x: Math.round(r.left + 120),
|
||||
y: Math.round(r.top + 130),
|
||||
};
|
||||
});
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const baseline = await pixelAt(browser, point.x, point.y);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const boosted = await pixelAt(browser, point.x, point.y);
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(baseline, boosted, 3),
|
||||
`::placeholder must tint with boost; baseline=${JSON.stringify(
|
||||
baseline
|
||||
)} boosted=${JSON.stringify(boosted)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
59
src/zen/tests/boosts/browser_boosts_pseudo_before.js
Normal file
59
src/zen/tests/boosts/browser_boosts_pseudo_before.js
Normal file
@@ -0,0 +1,59 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Generated content (::before/::after) lives in a native-anonymous subtree,
|
||||
// so IsBoostExemptFrame has historically over-exempted it. This test pins the
|
||||
// fix: an inline-block ::before with a solid background-color must take the
|
||||
// page's tint just like a regular element.
|
||||
add_task(async function pseudo_before_is_boosted() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
#host::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: rgb(120, 120, 120);
|
||||
}
|
||||
</style>
|
||||
<div id="host"></div>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
// ::before sits inside the host: sample inside its area (start of host).
|
||||
const point = await SpecialPowers.spawn(browser, [], () => {
|
||||
const r = content.document.querySelector("#host").getBoundingClientRect();
|
||||
return {
|
||||
x: Math.round(r.left + 100),
|
||||
y: Math.round(r.top + 100),
|
||||
};
|
||||
});
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const baseline = await pixelAt(browser, point.x, point.y);
|
||||
Assert.ok(
|
||||
pixelsClose(baseline, { r: 120, g: 120, b: 120 }, 4),
|
||||
`baseline ::before colour ≈ rgb(120,120,120); got ${JSON.stringify(
|
||||
baseline
|
||||
)}`
|
||||
);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const boosted = await pixelAt(browser, point.x, point.y);
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(baseline, boosted, 3),
|
||||
`::before background must tint with the boost; baseline=${JSON.stringify(
|
||||
baseline
|
||||
)} boosted=${JSON.stringify(boosted)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
62
src/zen/tests/boosts/browser_boosts_shadow.js
Normal file
62
src/zen/tests/boosts/browser_boosts_shadow.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// box-shadow is the property where the "alpha byte is contrast for accents but
|
||||
// must stay opacity for content colours" invariant is most visible. We render
|
||||
// a thick, fully-opaque box-shadow on a white background and verify (a) it's
|
||||
// tinted by the boost and (b) the sampled pixel's alpha — after compositing —
|
||||
// is not the accent's contrast byte bleeding through.
|
||||
add_task(async function box_shadow_is_tinted_alpha_preserved() {
|
||||
// Use a solid (alpha = 1.0) shadow colour so we can sample inside the shadow
|
||||
// band on a white background without dealing with partial transparency.
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
#s { width: 100px; height: 100px; margin: 80px; background: white;
|
||||
box-shadow: 0 80px 0 0 rgb(80, 80, 80); }
|
||||
</style>
|
||||
<div id="s"></div>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
const point = await SpecialPowers.spawn(browser, [], () => {
|
||||
const r = content.document.querySelector("#s").getBoundingClientRect();
|
||||
// 40px inside the 80px tall shadow band that lives below the box.
|
||||
return {
|
||||
x: Math.round(r.left + r.width / 2),
|
||||
y: Math.round(r.bottom + 40),
|
||||
};
|
||||
});
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const baseline = await pixelAt(browser, point.x, point.y);
|
||||
Assert.ok(
|
||||
pixelsClose(baseline, { r: 80, g: 80, b: 80 }, 5),
|
||||
`baseline shadow ≈ rgb(80,80,80); got ${JSON.stringify(baseline)}`
|
||||
);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const boosted = await pixelAt(browser, point.x, point.y);
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(baseline, boosted, 3),
|
||||
`box-shadow colour should be tinted; baseline=${JSON.stringify(
|
||||
baseline
|
||||
)} boosted=${JSON.stringify(boosted)}`
|
||||
);
|
||||
|
||||
// The compositor combines RGB only; the rendered pixel from drawWindow is
|
||||
// always alpha=255 because the canvas backing is opaque. The real
|
||||
// alpha-preservation invariant is enforced as a gtest on the filter
|
||||
// primitive (TestZenBoostsColorFilter.ShadowAlphaPreserved). Here we just
|
||||
// assert the visible pixel isn't pathological (e.g., turned transparent).
|
||||
Assert.equal(boosted.a, 255, "composited shadow pixel has full alpha");
|
||||
});
|
||||
});
|
||||
62
src/zen/tests/boosts/browser_boosts_svg_background_image.js
Normal file
62
src/zen/tests/boosts/browser_boosts_svg_background_image.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// `background-image: url(*.svg)` goes through nsImageRenderer's WebRender
|
||||
// blob path, which is a separate code path from the <img> case. Verify that
|
||||
// path also has the boost propagated: a div whose background is an SVG image
|
||||
// must tint just like a div with a CSS background-color of the same value.
|
||||
add_task(async function svg_background_image_is_boosted() {
|
||||
const svgSrc = encodeURIComponent(
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">` +
|
||||
`<rect width="200" height="200" fill="rgb(120, 120, 120)"/>` +
|
||||
`</svg>`
|
||||
);
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
#css, #bg { width: 200px; height: 200px; display: inline-block;
|
||||
vertical-align: top; }
|
||||
#css { background-color: rgb(120, 120, 120); }
|
||||
#bg { background-image: url('data:image/svg+xml;charset=utf-8,${svgSrc}');
|
||||
background-size: 200px 200px; background-repeat: no-repeat; }
|
||||
</style>
|
||||
<div id="css"></div>
|
||||
<div id="bg"></div>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
await waitForRepaint(browser);
|
||||
}
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const cssBaseline = await pixelInElement(browser, "#css");
|
||||
const bgBaseline = await pixelInElement(browser, "#bg");
|
||||
Assert.ok(
|
||||
pixelsClose(cssBaseline, bgBaseline, 3),
|
||||
`baseline mismatch: css=${JSON.stringify(
|
||||
cssBaseline
|
||||
)} bg-image=${JSON.stringify(bgBaseline)}`
|
||||
);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const cssBoosted = await pixelInElement(browser, "#css");
|
||||
const bgBoosted = await pixelInElement(browser, "#bg");
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(bgBaseline, bgBoosted, 3),
|
||||
"background-image SVG must tint under boost"
|
||||
);
|
||||
Assert.ok(
|
||||
pixelsClose(cssBoosted, bgBoosted, 4),
|
||||
`SVG background-image must match CSS background-color after boost. ` +
|
||||
`css=${JSON.stringify(cssBoosted)} bg=${JSON.stringify(bgBoosted)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
63
src/zen/tests/boosts/browser_boosts_svg_image.js
Normal file
63
src/zen/tests/boosts/browser_boosts_svg_image.js
Normal file
@@ -0,0 +1,63 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// SVG used as an image (<img src=*.svg>) renders inside its own image document
|
||||
// with no BrowsingContext, so the boost must be propagated through the
|
||||
// SVGImageContext + AutoRestoreSVGState plumbing onto the image document's
|
||||
// PresContext. Compare the painted colour of an <img>-rendered SVG to an
|
||||
// inline <svg> with the same fill — both should land at the same boosted
|
||||
// colour after one pass.
|
||||
add_task(async function svg_as_img_matches_inline_under_boost() {
|
||||
const svgSrc = encodeURIComponent(
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">` +
|
||||
`<rect width="200" height="200" fill="rgb(120, 120, 120)"/>` +
|
||||
`</svg>`
|
||||
);
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
#img, #inline { width: 200px; height: 200px; display: inline-block;
|
||||
vertical-align: top; }
|
||||
</style>
|
||||
<img id="img" src="data:image/svg+xml;charset=utf-8,${svgSrc}">
|
||||
<svg id="inline" width="200" height="200" viewBox="0 0 200 200">
|
||||
<rect width="200" height="200" fill="rgb(120, 120, 120)"/>
|
||||
</svg>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
// SVG images are loaded async; give the <img> a few frames to paint.
|
||||
for (let i = 0; i < 4; i++) {
|
||||
await waitForRepaint(browser);
|
||||
}
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const imgBaseline = await pixelInElement(browser, "#img");
|
||||
const inlineBaseline = await pixelInElement(browser, "#inline");
|
||||
Assert.ok(
|
||||
pixelsClose(imgBaseline, inlineBaseline, 3),
|
||||
`baseline mismatch between <img>-svg and inline svg: img=` +
|
||||
`${JSON.stringify(imgBaseline)} inline=${JSON.stringify(inlineBaseline)}`
|
||||
);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const imgBoosted = await pixelInElement(browser, "#img");
|
||||
const inlineBoosted = await pixelInElement(browser, "#inline");
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(imgBaseline, imgBoosted, 3),
|
||||
"<img>-rendered SVG must tint under boost"
|
||||
);
|
||||
Assert.ok(
|
||||
pixelsClose(imgBoosted, inlineBoosted, 4),
|
||||
`<img>-rendered SVG must match inline SVG after boost. img=` +
|
||||
`${JSON.stringify(imgBoosted)} inline=${JSON.stringify(inlineBoosted)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
71
src/zen/tests/boosts/browser_boosts_svg_linear_gradient.js
Normal file
71
src/zen/tests/boosts/browser_boosts_svg_linear_gradient.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// SVG paint-server gradients (<linearGradient>) go through SVGGradientFrame
|
||||
// which threads the host frame into ToDeviceColor for each stop. Coverage
|
||||
// here pins that threading: a paint-server gradient must tint stops the same
|
||||
// way a CSS gradient does.
|
||||
add_task(async function svg_linear_gradient_stops_are_boosted() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
</style>
|
||||
<svg id="g" width="400" height="200" viewBox="0 0 400 200">
|
||||
<defs>
|
||||
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="rgb(180, 60, 60)"/>
|
||||
<stop offset="100%" stop-color="rgb(60, 60, 180)"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="400" height="200" fill="url(#grad)"/>
|
||||
</svg>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
const points = await SpecialPowers.spawn(browser, [], () => {
|
||||
const r = content.document.querySelector("#g").getBoundingClientRect();
|
||||
return {
|
||||
left: {
|
||||
x: Math.round(r.left + r.width * 0.05),
|
||||
y: Math.round(r.top + r.height / 2),
|
||||
},
|
||||
right: {
|
||||
x: Math.round(r.left + r.width * 0.95),
|
||||
y: Math.round(r.top + r.height / 2),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const leftBaseline = await pixelAt(browser, points.left.x, points.left.y);
|
||||
const rightBaseline = await pixelAt(
|
||||
browser,
|
||||
points.right.x,
|
||||
points.right.y
|
||||
);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const leftBoosted = await pixelAt(browser, points.left.x, points.left.y);
|
||||
const rightBoosted = await pixelAt(browser, points.right.x, points.right.y);
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(leftBaseline, leftBoosted, 3),
|
||||
"SVG <linearGradient> first stop must tint"
|
||||
);
|
||||
Assert.ok(
|
||||
pixelsDiffer(rightBaseline, rightBoosted, 3),
|
||||
"SVG <linearGradient> last stop must tint"
|
||||
);
|
||||
Assert.ok(
|
||||
pixelsDiffer(leftBoosted, rightBoosted, 8),
|
||||
"SVG <linearGradient> stops must stay distinguishable after boost"
|
||||
);
|
||||
});
|
||||
});
|
||||
61
src/zen/tests/boosts/browser_boosts_svg_use_sprite.js
Normal file
61
src/zen/tests/boosts/browser_boosts_svg_use_sprite.js
Normal file
@@ -0,0 +1,61 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Inline <use href="#symbol"> clones the symbol's content into a shadow tree.
|
||||
// The clone is native-anonymous, so IsBoostExemptFrame must NOT exempt it
|
||||
// (that's what the GetContainingShadow carve-out is for). Compare against a
|
||||
// direct inline rect with the same fill — both must land at the same boosted
|
||||
// colour, demonstrating the use-clone isn't being skipped.
|
||||
add_task(async function svg_use_clone_is_boosted_like_direct_inline() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
.swatch { width: 200px; height: 200px; display: inline-block;
|
||||
vertical-align: top; }
|
||||
</style>
|
||||
<svg width="0" height="0" style="position:absolute">
|
||||
<symbol id="sym" viewBox="0 0 200 200">
|
||||
<rect width="200" height="200" fill="rgb(120, 120, 120)"/>
|
||||
</symbol>
|
||||
</svg>
|
||||
<svg id="direct" class="swatch" viewBox="0 0 200 200">
|
||||
<rect width="200" height="200" fill="rgb(120, 120, 120)"/>
|
||||
</svg>
|
||||
<svg id="used" class="swatch" viewBox="0 0 200 200">
|
||||
<use href="#sym"/>
|
||||
</svg>`;
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const directBaseline = await pixelInElement(browser, "#direct");
|
||||
const usedBaseline = await pixelInElement(browser, "#used");
|
||||
Assert.ok(
|
||||
pixelsClose(directBaseline, usedBaseline, 3),
|
||||
`baseline mismatch between direct and used; direct=${JSON.stringify(
|
||||
directBaseline
|
||||
)} used=${JSON.stringify(usedBaseline)}`
|
||||
);
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const directBoosted = await pixelInElement(browser, "#direct");
|
||||
const usedBoosted = await pixelInElement(browser, "#used");
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(usedBaseline, usedBoosted, 3),
|
||||
"<use>-cloned content must tint under boost (use-shadow not exempt)"
|
||||
);
|
||||
Assert.ok(
|
||||
pixelsClose(directBoosted, usedBoosted, 4),
|
||||
`<use> clone must match direct inline rect after boost. direct=` +
|
||||
`${JSON.stringify(directBoosted)} used=${JSON.stringify(usedBoosted)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
50
src/zen/tests/boosts/browser_boosts_text_color.js
Normal file
50
src/zen/tests/boosts/browser_boosts_text_color.js
Normal file
@@ -0,0 +1,50 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Verifies that text colour is tinted under a boost. Uses a large solid-colour
|
||||
// glyph and samples at its geometric centre, where the rendered pixel is fully
|
||||
// the foreground colour (no anti-aliased blend with the background).
|
||||
add_task(async function text_color_is_tinted() {
|
||||
const html = `
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: white; }
|
||||
#t { color: rgb(40, 44, 52); font: 200px/1 system-ui, sans-serif;
|
||||
display: inline-block; padding: 0 20px; }
|
||||
</style>
|
||||
<span id="t">█</span>`;
|
||||
// Full-block U+2588 fills its glyph cell with the foreground colour, so the
|
||||
// centre pixel is a clean sample of the painted text colour.
|
||||
|
||||
await BrowserTestUtils.withNewTab(dataUrl(html), async browser => {
|
||||
await waitForRepaint(browser);
|
||||
|
||||
await setBoost(browser, { accent: 0 });
|
||||
const baseline = await pixelInElement(browser, "#t");
|
||||
|
||||
await setBoost(browser, {
|
||||
accent: PAGE_ACCENT,
|
||||
complementaryRotation: PAGE_COMPLEMENTARY_ROTATION,
|
||||
});
|
||||
const boosted = await pixelInElement(browser, "#t");
|
||||
|
||||
Assert.ok(
|
||||
pixelsDiffer(baseline, boosted, 3),
|
||||
`text colour should be tinted; baseline=${JSON.stringify(baseline)} ` +
|
||||
`boosted=${JSON.stringify(boosted)}`
|
||||
);
|
||||
|
||||
// The text was clearly darker than white before the boost, and the boost
|
||||
// preserves perceived luminance roughly, so it must stay darker than its
|
||||
// (white) background afterwards. A broken filter that inverts the
|
||||
// luminance direction would flip this.
|
||||
const bg = await pixelAt(browser, 5, 5);
|
||||
Assert.greater(
|
||||
pxLuma(bg),
|
||||
pxLuma(boosted),
|
||||
"boosted text must remain darker than its boosted white background"
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -5,3 +5,108 @@
|
||||
const { SelectorComponent } = ChromeUtils.importESModule(
|
||||
"resource:///modules/zen/boosts/ZenSelectorComponent.sys.mjs"
|
||||
);
|
||||
|
||||
// --- Boost pixel-level test helpers --------------------------------------
|
||||
//
|
||||
// Used by browser_boosts_*.js. Each helper documents what regression in the
|
||||
// boost paint paths it's meant to catch.
|
||||
|
||||
// Construct an nscolor in Firefox's ABGR encoding from RGB + the alpha byte.
|
||||
// The boost backend reuses the alpha byte as the accent's contrast/strength
|
||||
// (see NS_GET_CONTRAST in nsZenBoostsBackend.cpp), so for boost activation
|
||||
// use `contrast` as the fourth arg with a typical value of 200.
|
||||
function nsRGBA(r, g, b, a = 255) {
|
||||
return (((a >>> 0) << 24) | (b << 16) | (g << 8) | r) >>> 0;
|
||||
}
|
||||
|
||||
// Two animation frames is enough for a BC-field-triggered restyle + repaint
|
||||
// to settle in our tests; the DidSet handlers in nsZenBCOverrides.cpp
|
||||
// dispatch a RecascadeSubtree + visual hint that's processed by the next
|
||||
// refresh tick.
|
||||
async function waitForRepaint(browser) {
|
||||
await SpecialPowers.spawn(browser, [], async () => {
|
||||
await new Promise(r => content.requestAnimationFrame(r));
|
||||
await new Promise(r => content.requestAnimationFrame(r));
|
||||
});
|
||||
}
|
||||
|
||||
// Apply (or clear) a boost on the tab's top-level content BrowsingContext.
|
||||
// Passing accent = 0 clears the boost so a test can sample a no-boost
|
||||
// baseline and a boosted state on the same loaded page.
|
||||
async function setBoost(
|
||||
browser,
|
||||
{ accent = 0, complementaryRotation = 0, inverted = false } = {}
|
||||
) {
|
||||
const bc = browser.browsingContext;
|
||||
bc.zenBoostsData = accent;
|
||||
bc.zenBoostsComplementaryRotation = complementaryRotation;
|
||||
bc.isZenBoostsInverted = inverted;
|
||||
await waitForRepaint(browser);
|
||||
}
|
||||
|
||||
// Read the RGBA pixel at content coordinates (x, y). Runs in the content
|
||||
// process so drawWindow targets the real painted output of the tab.
|
||||
async function pixelAt(browser, x, y) {
|
||||
return SpecialPowers.spawn(browser, [x, y], async (px, py) => {
|
||||
const w = content.innerWidth;
|
||||
const h = content.innerHeight;
|
||||
const canvas = content.document.createElementNS(
|
||||
"http://www.w3.org/1999/xhtml",
|
||||
"canvas"
|
||||
);
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.drawWindow(content, 0, 0, w, h, "rgba(0,0,0,0)");
|
||||
const data = ctx.getImageData(px, py, 1, 1).data;
|
||||
return { r: data[0], g: data[1], b: data[2], a: data[3] };
|
||||
});
|
||||
}
|
||||
|
||||
// Sample the centre of the element matching |selector|.
|
||||
async function pixelInElement(browser, selector) {
|
||||
const point = await SpecialPowers.spawn(browser, [selector], sel => {
|
||||
const el = content.document.querySelector(sel);
|
||||
if (!el) {
|
||||
throw new Error(`No element matches selector: ${sel}`);
|
||||
}
|
||||
const r = el.getBoundingClientRect();
|
||||
return {
|
||||
x: Math.round(r.left + r.width / 2),
|
||||
y: Math.round(r.top + r.height / 2),
|
||||
};
|
||||
});
|
||||
return pixelAt(browser, point.x, point.y);
|
||||
}
|
||||
|
||||
// Coarse RGB-distance threshold for "the colour clearly changed". The boost's
|
||||
// duotone moves channels by tens of units even for a modest accent; tolerance
|
||||
// 3 is comfortably below that while ignoring sub-pixel/anti-aliasing noise.
|
||||
function pixelsDiffer(a, b, tol = 3) {
|
||||
return (
|
||||
Math.abs(a.r - b.r) > tol ||
|
||||
Math.abs(a.g - b.g) > tol ||
|
||||
Math.abs(a.b - b.b) > tol
|
||||
);
|
||||
}
|
||||
|
||||
function pixelsClose(a, b, tol = 3) {
|
||||
return !pixelsDiffer(a, b, tol);
|
||||
}
|
||||
|
||||
// BT.601-ish perceived luminance, integer-valued. Matches the coefficients
|
||||
// used by InvertColorChannel in the backend, so a test expressing "X stays
|
||||
// darker than Y after boost" maps to what the user actually perceives.
|
||||
function pxLuma({ r, g, b }) {
|
||||
return (r * 54 + g * 183 + b * 19) >> 8;
|
||||
}
|
||||
|
||||
function dataUrl(html) {
|
||||
return "data:text/html;charset=utf-8," + encodeURIComponent(html);
|
||||
}
|
||||
|
||||
// A "page accent" colour used across the property tests. Strong enough to
|
||||
// move a mid-grey by tens of units per channel; rotation kept small so the
|
||||
// duotone stays cohesive.
|
||||
const PAGE_ACCENT = nsRGBA(80, 120, 200, /*contrast*/ 200);
|
||||
const PAGE_COMPLEMENTARY_ROTATION = 30;
|
||||
|
||||
@@ -14,6 +14,8 @@ support-files = [
|
||||
|
||||
["browser_issue_10455.js"]
|
||||
|
||||
["browser_issue_12112.js"]
|
||||
|
||||
["browser_issue_8699.js"]
|
||||
|
||||
["browser_issue_9900.js"]
|
||||
|
||||
@@ -4,16 +4,24 @@
|
||||
"use strict";
|
||||
|
||||
add_task(async function test_Issue_10455() {
|
||||
debugger;
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.tabs.closeWindowWithLastTab", true]],
|
||||
set: [
|
||||
["browser.tabs.closeWindowWithLastTab", true],
|
||||
["zen.testing.enabled", false],
|
||||
["zen.window-sync.enabled", false],
|
||||
],
|
||||
});
|
||||
debugger;
|
||||
|
||||
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await newWindow.gZenWorkspaces.promiseInitialized;
|
||||
|
||||
const unloadEvent = BrowserTestUtils.waitForEvent(newWindow, "unload");
|
||||
Assert.equal(
|
||||
newWindow.gBrowser.tabs.length,
|
||||
3,
|
||||
"New window should have three tabs"
|
||||
);
|
||||
newWindow.BrowserCommands.closeTabOrWindow();
|
||||
newWindow.BrowserCommands.closeTabOrWindow();
|
||||
await unloadEvent;
|
||||
|
||||
@@ -22,14 +30,23 @@ add_task(async function test_Issue_10455() {
|
||||
});
|
||||
|
||||
add_task(async function test_Issue_10455_Dont_Close() {
|
||||
debugger;
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.tabs.closeWindowWithLastTab", false]],
|
||||
set: [
|
||||
["browser.tabs.closeWindowWithLastTab", false],
|
||||
["zen.testing.enabled", false],
|
||||
["zen.window-sync.enabled", false],
|
||||
],
|
||||
});
|
||||
|
||||
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await newWindow.gZenWorkspaces.promiseInitialized;
|
||||
|
||||
Assert.equal(
|
||||
newWindow.gBrowser.tabs.length,
|
||||
3,
|
||||
"New window should have three tabs"
|
||||
);
|
||||
newWindow.BrowserCommands.closeTabOrWindow();
|
||||
newWindow.BrowserCommands.closeTabOrWindow();
|
||||
Assert.strictEqual(
|
||||
newWindow.gBrowser.tabs.length,
|
||||
|
||||
84
src/zen/tests/spaces/browser_issue_12112.js
Normal file
84
src/zen/tests/spaces/browser_issue_12112.js
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_setup(async function () {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["zen.urlbar.replace-newtab", false]],
|
||||
});
|
||||
registerCleanupFunction(async () => {
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
});
|
||||
|
||||
add_task(
|
||||
async function test_focuses_urlbar_on_startup_without_replace_newtab() {
|
||||
await gZenWorkspaces.promiseInitialized;
|
||||
Assert.ok(
|
||||
!gZenVerticalTabsManager._canReplaceNewTab,
|
||||
"Precondition: zen.urlbar.replace-newtab is disabled"
|
||||
);
|
||||
|
||||
const originalTab = gBrowser.selectedTab;
|
||||
const originalOpenLocation = window.openLocation;
|
||||
const originalTestingEnabled = gZenUIManager.testingEnabled;
|
||||
|
||||
let openLocationCalls = 0;
|
||||
window.openLocation = () => {
|
||||
openLocationCalls++;
|
||||
};
|
||||
|
||||
// selectStartPage() and selectEmptyTab() are both no-ops while testing mode
|
||||
// is enabled; temporarily disable it to exercise the real startup path.
|
||||
gZenUIManager.testingEnabled = false;
|
||||
|
||||
// The tab the startup page leaves selected, which Zen wants to replace.
|
||||
const tabToRemove = BrowserTestUtils.addTab(gBrowser, "about:blank", {
|
||||
skipAnimation: true,
|
||||
});
|
||||
gBrowser.selectedTab = tabToRemove;
|
||||
gZenWorkspaces._tabToRemoveForEmpty = tabToRemove;
|
||||
delete gZenWorkspaces._tabToSelect;
|
||||
delete gZenWorkspaces._shouldOverrideTabs;
|
||||
delete gZenWorkspaces._initialTab;
|
||||
|
||||
try {
|
||||
await gZenWorkspaces.selectStartPage();
|
||||
|
||||
await TestUtils.waitForCondition(
|
||||
() => openLocationCalls > 0,
|
||||
"openLocation() should be called to focus the address bar"
|
||||
);
|
||||
|
||||
Assert.equal(
|
||||
openLocationCalls,
|
||||
1,
|
||||
"The address bar was focused via openLocation()"
|
||||
);
|
||||
Assert.ok(
|
||||
!gBrowser.selectedTab.hasAttribute("zen-empty-tab"),
|
||||
"A fallback homepage tab is selected (no zen-empty-tab attribute), so " +
|
||||
"the focus decision came from initialTabWasEmpty, not shownEmptyTab"
|
||||
);
|
||||
Assert.ok(
|
||||
!gBrowser.tabs.includes(tabToRemove),
|
||||
"The empty tab added by the startup page was removed"
|
||||
);
|
||||
} finally {
|
||||
window.openLocation = originalOpenLocation;
|
||||
gZenUIManager.testingEnabled = originalTestingEnabled;
|
||||
delete gZenWorkspaces._tabToRemoveForEmpty;
|
||||
|
||||
// Remove any tab created by the startup path, then restore the original.
|
||||
for (const tab of [...gBrowser.tabs]) {
|
||||
if (tab !== originalTab && !tab.hasAttribute("zen-empty-tab")) {
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
}
|
||||
if (!originalTab.closing) {
|
||||
gBrowser.selectedTab = originalTab;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -5,7 +5,10 @@
|
||||
|
||||
add_task(async function test_Private_Mode() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["privacy.userContext.enabled", true]],
|
||||
set: [
|
||||
["privacy.userContext.enabled", true],
|
||||
["zen.testing.enabled", false],
|
||||
],
|
||||
});
|
||||
|
||||
let privateWindow = await BrowserTestUtils.openNewBrowserWindow({
|
||||
@@ -13,6 +16,11 @@ add_task(async function test_Private_Mode() {
|
||||
});
|
||||
await privateWindow.gZenWorkspaces.promiseInitialized;
|
||||
|
||||
Assert.ok(
|
||||
privateWindow.gBrowser.selectedTab.hasAttribute("zen-empty-tab"),
|
||||
"Private window should start with a zen empty tab"
|
||||
);
|
||||
|
||||
await BrowserTestUtils.closeWindow(privateWindow);
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
[DEFAULT]
|
||||
prefs = ["browser.urlbar.closeOnWindowBlur=false"]
|
||||
support-files = [
|
||||
"head.js",
|
||||
"!/browser/components/urlbar/tests/browser/head.js",
|
||||
|
||||
@@ -9,27 +9,24 @@ ChromeUtils.defineESModuleGetters(this, {
|
||||
|
||||
add_task(async function test_Selection_Remains_Double_Toolbar() {
|
||||
await goToMultipleLayouts(async () => {
|
||||
const untrimmedValue = "https://example.com";
|
||||
const untrimmedValue = "https://example.com/";
|
||||
let trimmedValue = UrlbarTestUtils.trimURL(untrimmedValue);
|
||||
gURLBar._setValue(untrimmedValue, {
|
||||
allowTrim: true,
|
||||
valueIsTyped: false,
|
||||
});
|
||||
gURLBar.blur();
|
||||
await SimpleTest.promiseFocus(window);
|
||||
Assert.equal(gURLBar.value, trimmedValue, "Value has been trimmed");
|
||||
await selectWithMouseDrag(100, 200);
|
||||
await BrowserTestUtils.withNewTab(untrimmedValue, async () => {
|
||||
Assert.equal(gURLBar.value, trimmedValue, "Value has been trimmed");
|
||||
await selectWithMouseDrag(10, 20);
|
||||
|
||||
Assert.greater(gURLBar.selectionStart, 0, "Selection start is positive.");
|
||||
Assert.greater(
|
||||
gURLBar.selectionEnd,
|
||||
gURLBar.selectionStart,
|
||||
"Selection is not empty."
|
||||
);
|
||||
Assert.greater(gURLBar.selectionStart, 0, "Selection start is positive.");
|
||||
Assert.greater(
|
||||
gURLBar.selectionEnd,
|
||||
gURLBar.selectionStart,
|
||||
"Selection is not empty."
|
||||
);
|
||||
|
||||
Assert.equal(gURLBar.value, untrimmedValue, `Value should be untrimmed`);
|
||||
Assert.equal(gURLBar.value, untrimmedValue, `Value should be untrimmed`);
|
||||
|
||||
gURLBar.handleRevert();
|
||||
gURLBar.view.close();
|
||||
gURLBar.handleRevert();
|
||||
gURLBar.view.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
82
src/zen/tests/urlbar/browser_single_toolbar_blur_revert.js
Normal file
82
src/zen/tests/urlbar/browser_single_toolbar_blur_revert.js
Normal file
@@ -0,0 +1,82 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.defineESModuleGetters(this, {
|
||||
UrlbarTestUtils: "resource://testing-common/UrlbarTestUtils.sys.mjs",
|
||||
});
|
||||
|
||||
const PAGE_URL = "https://example.com/";
|
||||
const TYPED_VALUE = "zen blur revert test";
|
||||
|
||||
async function typeIntoUrlbar() {
|
||||
await UrlbarTestUtils.promiseAutocompleteResultPopup({
|
||||
window,
|
||||
value: TYPED_VALUE,
|
||||
fireInputEvent: true,
|
||||
});
|
||||
Assert.equal(
|
||||
gURLBar.value,
|
||||
TYPED_VALUE,
|
||||
"The typed value is present while the address bar is focused"
|
||||
);
|
||||
}
|
||||
|
||||
add_task(async function test_single_toolbar_reverts_typed_value_on_blur() {
|
||||
await TestUtils.waitForCondition(
|
||||
() => gZenVerticalTabsManager._hasSetSingleToolbar,
|
||||
"The default layout should be single-toolbar"
|
||||
);
|
||||
|
||||
await BrowserTestUtils.withNewTab(PAGE_URL, async () => {
|
||||
await typeIntoUrlbar();
|
||||
|
||||
await UrlbarTestUtils.promisePopupClose(window, () => gURLBar.blur());
|
||||
await SimpleTest.promiseFocus(window);
|
||||
await new Promise(resolve => setTimeout(resolve));
|
||||
|
||||
await TestUtils.waitForCondition(
|
||||
() => gURLBar.value !== TYPED_VALUE,
|
||||
"The address bar should revert away from the typed value on blur"
|
||||
);
|
||||
|
||||
Assert.ok(
|
||||
gURLBar.value.includes("example.com"),
|
||||
`Reverted to the page URL (got "${gURLBar.value}")`
|
||||
);
|
||||
Assert.notEqual(
|
||||
gURLBar.value,
|
||||
TYPED_VALUE,
|
||||
"Single-toolbar blur did not retain the typed value"
|
||||
);
|
||||
});
|
||||
|
||||
gURLBar.handleRevert();
|
||||
});
|
||||
|
||||
add_task(async function test_double_toolbar_keeps_typed_value_on_blur() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["zen.view.use-single-toolbar", false]],
|
||||
});
|
||||
await TestUtils.waitForCondition(
|
||||
() => !gZenVerticalTabsManager._hasSetSingleToolbar,
|
||||
"The layout should switch to double-toolbar"
|
||||
);
|
||||
|
||||
await BrowserTestUtils.withNewTab(PAGE_URL, async () => {
|
||||
await typeIntoUrlbar();
|
||||
|
||||
await UrlbarTestUtils.promisePopupClose(window, () => gURLBar.blur());
|
||||
await SimpleTest.promiseFocus(window);
|
||||
|
||||
Assert.equal(
|
||||
gURLBar.value,
|
||||
TYPED_VALUE,
|
||||
"Double-toolbar blur keeps the typed value (no forced revert)"
|
||||
);
|
||||
});
|
||||
|
||||
gURLBar.handleRevert();
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
@@ -250,12 +250,12 @@ export class nsZenSiteDataPanel {
|
||||
const boostButton = this.document.getElementById("zen-site-data-boost");
|
||||
if (!canBoostSite) {
|
||||
boostButton.removeAttribute("boosting");
|
||||
}
|
||||
|
||||
if (!canBoostSite) {
|
||||
boostButton.setAttribute("disabled", "true");
|
||||
return;
|
||||
}
|
||||
|
||||
boostButton.removeAttribute("disabled");
|
||||
|
||||
if (lazy.gZenBoostsManager.registeredBoostForDomain(domain)) {
|
||||
boostButton.setAttribute("boosting", "true");
|
||||
} else {
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
"binaryName": "zen",
|
||||
"version": {
|
||||
"product": "firefox",
|
||||
"version": "151.0.2",
|
||||
"candidate": "151.0.2",
|
||||
"version": "151.0.3",
|
||||
"candidate": "151.0.3",
|
||||
"candidateBuild": 1
|
||||
},
|
||||
"buildOptions": {
|
||||
@@ -20,7 +20,7 @@
|
||||
"brandShortName": "Zen",
|
||||
"brandFullName": "Zen Browser",
|
||||
"release": {
|
||||
"displayVersion": "1.20.1b",
|
||||
"displayVersion": "1.20.2b",
|
||||
"github": {
|
||||
"repo": "zen-browser/desktop"
|
||||
},
|
||||
@@ -54,4 +54,4 @@
|
||||
"licenseType": "MPL-2.0"
|
||||
},
|
||||
"updateHostname": "updates.zen-browser.app"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user