Compare commits

...

14 Commits

Author SHA1 Message Date
mr. m
4869e25df3 Update scripts/update_external_patches.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
2026-02-06 22:40:38 +01:00
mr. m
cc4b51529e chore: Automatically import patches from phabricator and librewolf, b=no-bug, c=workflows, scripts 2026-02-06 20:52:00 +01:00
mr. m
c9474cecc0 feat: Remove null-setting for split view data on restore, b=no-bug, c=no-component 2026-02-06 14:10:02 +01:00
mr. m
531be839c9 fix: Fixed frozen window when restore split data is null, b=closes #12260, c=no-component 2026-02-06 14:04:04 +01:00
mr. m
226486b973 fix: Fixed selecting tabs when pinned tabs are collapsed, b=no-bug, c=no-component 2026-02-06 12:45:24 +01:00
mr. m
5a137c95e5 fix: Fixed wrong highlight possition in compact mode, b=closes #12252, c=compact-mode 2026-02-05 23:23:17 +01:00
mr. m
e6154ceb99 feat: Make sure we properly restore split views when only pinned sync is enabled, b=no-bug, c=no-component 2026-02-05 23:01:49 +01:00
mr. m
1ea5d2fa6f feat: Import zen.window-sync.sync-only-pinned-tabs to the prefs list, b=no-bug, c=no-component 2026-02-05 11:18:02 +01:00
mr. m
97d5ebc21e feat: Add pref observer for zen.window-sync.sync-only-pinned-tabs setting, b=no-bug, c=no-component 2026-02-05 11:14:48 +01:00
mr. m
442ec2a5d1 chore: Bump version and format, b=no-bug, c=tests 2026-02-05 11:13:02 +01:00
mr. m
43ae672b44 feat: Revert migration step for syncing only pinned tabs, b=no-bug, c=common 2026-02-05 11:12:01 +01:00
mr. m
84a54c9dbb feat: Add option to only sync up pinned tabs, b=closes #12173, p=#12246, c=common, tabs 2026-02-05 11:05:37 +01:00
mr. m
6c53c3bf37 chore: Sync upstream Firefox to version 147.0.3, p=#12243
* chore: Sync upstream to `Firefox 147.0.3`

* Update candidate version to 147.0.3

Signed-off-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>

* Update Twilight version to RC 147.0.3 in README

Signed-off-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>

---------

Signed-off-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
2026-02-05 11:04:53 +01:00
mr. m
66686ab7f8 New Crowdin updates, p=#11954
* New translations zen-general.ftl (Lithuanian)

* New translations zen-general.ftl (Portuguese)

* New translations zen-preferences.ftl (Lithuanian)

* New translations zen-preferences.ftl (Swedish)

* New translations zen-preferences.ftl (Chinese Traditional)

* New translations zen-preferences.ftl (Welsh)

* New translations zen-menubar.ftl (French)

* New translations zen-menubar.ftl (Catalan)

* New translations zen-menubar.ftl (Hebrew)

* New translations zen-menubar.ftl (Hungarian)

* New translations zen-menubar.ftl (Korean)

* New translations zen-menubar.ftl (Lithuanian)

* New translations zen-menubar.ftl (Portuguese)

* New translations zen-menubar.ftl (Swedish)

* New translations zen-menubar.ftl (Turkish)

* New translations zen-menubar.ftl (Chinese Traditional)

* New translations zen-menubar.ftl (Icelandic)

* New translations zen-menubar.ftl (Portuguese, Brazilian)

* New translations zen-menubar.ftl (Welsh)

* New translations zen-preferences.ftl (Catalan)

* New translations zen-preferences.ftl (Russian)

* New translations zen-preferences.ftl (Turkish)

* New translations zen-general.ftl (Indonesian)

* New translations zen-workspaces.ftl (Chinese Traditional)

* New translations zen-menubar.ftl (Chinese Traditional)

* New translations zen-menubar.ftl (Indonesian)

* New translations zen-workspaces.ftl (Indonesian)

* New translations zen-preferences.ftl (Indonesian)

* New translations zen-general.ftl (Welsh)

* New translations zen-menubar.ftl (French)

* New translations zen-menubar.ftl (Irish)
2026-02-05 11:00:01 +01:00
55 changed files with 391 additions and 153 deletions

View File

@@ -73,15 +73,13 @@ jobs:
npm run sync
fi
- name: Run formatter
if: steps.check-upstream-branch.outputs.branch_exists == 'false'
run: |
sudo apt install python3-autopep8
npm run pretty
- name: Install autopep8
run: sudo apt install python3-autopep8
- name: Check if any files changed
id: git-check
run: |
npm run pretty
if [ -n "$(git status --porcelain)" ]; then
echo "files_changed=true" >> $GITHUB_OUTPUT
else
@@ -111,6 +109,15 @@ jobs:
if: steps.git-check.outputs.files_changed == 'true'
run: python3 scripts/import_external_tests.py || true
- name: Import external patches
if: steps.git-check.outputs.files_changed == 'true'
run: python3 scripts/import_external_patches.py || true
- name: Run formatter
if: steps.check-upstream-branch.outputs.branch_exists == 'false'
run: |
npm run pretty
- name: Create pull request
uses: peter-evans/create-pull-request@v7
if: steps.git-check.outputs.files_changed == 'true'

View File

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

View File

@@ -1 +1 @@
7712a9ac90683965f71be525fe2827467632715d
b1e00b74d3791a5a7bbd6ba3d32b69b60471e73b

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Commuta l'emmagatzematge
zen-devtools-toggle-dom-shortcut = Commuta el DOM
zen-devtools-toggle-accessibility-shortcut = Commuta l'accessibilitat
zen-close-all-unpinned-tabs-shortcut = Tanca totes les pestanyes no fixades
zen-new-unsynced-window-shortcut = Nova finestra no sincronitzada
zen-new-unsynced-window-shortcut = Nova finestra en blanc

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Fosca
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nova finestra en blanc

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Toglo Storio
zen-devtools-toggle-dom-shortcut = Toglo DOM
zen-devtools-toggle-accessibility-shortcut = Toglo Hygyrchedd
zen-close-all-unpinned-tabs-shortcut = Cau Pob Tab Heb ei Binio
zen-new-unsynced-window-shortcut = Ffenestr Newydd Heb ei Chydweddu
zen-new-unsynced-window-shortcut = Ffenestr Wag Newydd

View File

@@ -2,8 +2,8 @@
# 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/.
zen-panel-ui-current-profile-text = proffil cyfredol
unified-extensions-description = Mae ychwanegiadau'n cael ei defnyddio er mwyn ychwanegu fwy o weithrediadau i { -brand-short-name }.
zen-panel-ui-current-profile-text = y proffil cyfredol
unified-extensions-description = Mae estyniadau'n cael ei defnyddio er mwyn ychwanegu fwy o swyddogaeth i { -brand-short-name }.
tab-context-zen-reset-pinned-tab =
.label = Ailosod Tab wedi'i Binio
.accesskey = A
@@ -109,7 +109,7 @@ zen-sidebar-notification-updated-tooltip =
zen-sidebar-notification-restart-safe-mode-label = Rhywbeth wedi torri?
zen-sidebar-notification-restart-safe-mode-tooltip =
.title = Ailgychwyn yn y Modd Diogel
zen-window-sync-migration-dialog-title = Keep Your Windows in Sync
zen-window-sync-migration-dialog-message = Zen now syncs windows on the same device, so changes in one window are reflected across the others instantly.
zen-window-sync-migration-dialog-learn-more = Learn More
zen-window-sync-migration-dialog-accept = Got It
zen-window-sync-migration-dialog-title = Cadw Eich Ffenestr Wedi'u Cydweddu
zen-window-sync-migration-dialog-message = Mae Zen bellach yn cydweddu ffenestri ar yr un ddyfais, felly mae newidiadau mewn un ffenestr yn cael eu dangos ar y lleill yn syth.
zen-window-sync-migration-dialog-learn-more = Dysgu Rhagor
zen-window-sync-migration-dialog-accept = Iawn

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Tywyll
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Ffenestr Wag Newydd

View File

@@ -59,6 +59,9 @@ zen-tabs-select-recently-used-on-close =
zen-tabs-close-on-back-with-no-history =
.label = Close tab and switch to its owner tab (or most recently used tab) when going back with no history
zen-settings-workspaces-sync-unpinned-tabs =
.label = Sync only pinned tabs in workspaces
zen-tabs-cycle-by-attribute =
.label = Ctrl+Tab cycles within Essential or Workspace tabs only
zen-tabs-cycle-ignore-pending-tabs =

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Sombre
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nouvelle fenêtre non synchronisée

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Dorcha
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Fuinneog Nua Bán

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = כהה
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = חלון ריק חדש

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Sötét
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Új üres lap

View File

@@ -49,8 +49,8 @@ zen-tabs-close-on-back-with-no-history =
zen-tabs-cycle-by-attribute =
.label = Ctrl+Tab berputar hanya dalam tab Esensial atau Ruang Kerja
zen-tabs-cycle-ignore-pending-tabs =
.label = Ignore Pending tabs when cycling with Ctrl+Tab
zen-tabs-cycle-by-attribute-warning = Ctrl+Tab will cycle by recently used order, as it is enabled
.label = Lewati tab tak termuat saat beralih dengan Ctrl+Tab
zen-tabs-cycle-by-attribute-warning = Ctrl+Tab akan beralih berdasarkan urutan terakhir digunakan
zen-look-and-feel-compact-toolbar-themed =
.label = Gunakan latar belakang bertema untuk bilah atas dalam mode ringkas
zen-workspace-continue-where-left-off =
@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Ubah Penyimpanan
zen-devtools-toggle-dom-shortcut = Ubah DOM
zen-devtools-toggle-accessibility-shortcut = Ubah Aksesibilitas
zen-close-all-unpinned-tabs-shortcut = Tutup Semua Tab yang Tidak Disematkan
zen-new-unsynced-window-shortcut = New Unsynced Window
zen-new-unsynced-window-shortcut = Jendela Kosong Baru

View File

@@ -60,8 +60,8 @@ zen-site-data-settings = Pengaturan
zen-generic-manage = Kelola
zen-generic-more = Selengkapnya
zen-generic-next = Lanjut
zen-essentials-promo-label = Add to Essentials
zen-essentials-promo-sublabel = Keep your favorite tabs just a click away
zen-essentials-promo-label = Tambahkan ke Essentials
zen-essentials-promo-sublabel = Akses tab favorit Anda hanya dengan sekali klik
# These labels will be used for the site data panel settings
zen-site-data-setting-allow = Diizinkan
zen-site-data-setting-block = Diblokir
@@ -109,7 +109,7 @@ zen-sidebar-notification-updated-tooltip =
zen-sidebar-notification-restart-safe-mode-label = Ada yang rusak?
zen-sidebar-notification-restart-safe-mode-tooltip =
.title = Mulai Ulang dalam Mode Aman
zen-window-sync-migration-dialog-title = Keep Your Windows in Sync
zen-window-sync-migration-dialog-message = Zen now syncs windows on the same device, so changes in one window are reflected across the others instantly.
zen-window-sync-migration-dialog-learn-more = Learn More
zen-window-sync-migration-dialog-accept = Got It
zen-window-sync-migration-dialog-title = Jaga Jendela Anda Tetap Sinkron
zen-window-sync-migration-dialog-message = Zen kini menyinkronkan jendela pada perangkat yang sama, sehingga perubahan di satu jendela akan langsung terlihat di jendela lainnya.
zen-window-sync-migration-dialog-learn-more = Pelajari Lebih Lanjut
zen-window-sync-migration-dialog-accept = Oke!

View File

@@ -4,19 +4,19 @@
zen-menubar-toggle-pinned-tabs =
.label =
{ $pinnedAreCollapsed ->
[true] Expand Pinned Tabs
*[false] Collapse Pinned Tabs
{ $pinnedAreCollapsed ->
[true] Perluas Tab yang Disematkan
*[false] Ciutkan Tab yang Disematkan
}
zen-menubar-appearance =
.label = Appearance
.label = Tampilan
zen-menubar-appearance-description =
.label = Websites will use:
.label = Situs web akan menggunakan:
zen-menubar-appearance-auto =
.label = Automatic
.label = Otomatis
zen-menubar-appearance-light =
.label = Light
.label = Terang
zen-menubar-appearance-dark =
.label = Dark
.label = Gelap
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Jendela Kosong Baru

View File

@@ -4,13 +4,13 @@
zen-panel-ui-workspaces-text = Ruang Kerja Lainnya
zen-panel-ui-spaces-label =
.label = Spaces
.label = Ruang
zen-panel-ui-workspaces-create =
.label = Buat Ruang
zen-panel-ui-folder-create =
.label = Buat Folder
zen-panel-ui-new-empty-split =
.label = New Split
.label = Split Baru
zen-workspaces-panel-context-delete =
.label = Hapus Ruang
.accesskey = D
@@ -66,6 +66,6 @@ zen-workspaces-close-all-unpinned-tabs-title =
.label = Bersihkan
.tooltiptext = Tutup semua tab yang tidak disematkan
zen-panel-ui-workspaces-change-forward =
.label = Next Space
.label = Ruang Selanjutnya
zen-panel-ui-workspaces-change-back =
.label = Previous Space
.label = Ruang Sebelumnya

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Dökkt
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nýr auður gluggi

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = 다크
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = 새 빈 창

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Perjungti saugyklą
zen-devtools-toggle-dom-shortcut = Perjungti DOM
zen-devtools-toggle-accessibility-shortcut = Perjungti prieinamumą
zen-close-all-unpinned-tabs-shortcut = Užverti visas neprisegtas korteles
zen-new-unsynced-window-shortcut = Naujas nesinchronizuotas langas
zen-new-unsynced-window-shortcut = Naujas tuščias langas

View File

@@ -60,8 +60,8 @@ zen-site-data-settings = Nustatymai
zen-generic-manage = Tvarkyti
zen-generic-more = Daugiau
zen-generic-next = Sekantis
zen-essentials-promo-label = Add to Essentials
zen-essentials-promo-sublabel = Keep your favorite tabs just a click away
zen-essentials-promo-label = Įtraukti į būtiniausius
zen-essentials-promo-sublabel = Laikykite mėgstamas korteles vos nuo vienu paspaudimu
# These labels will be used for the site data panel settings
zen-site-data-setting-allow = Leidžiama
zen-site-data-setting-block = Užblokuota
@@ -109,7 +109,7 @@ zen-sidebar-notification-updated-tooltip =
zen-sidebar-notification-restart-safe-mode-label = Kažkas sugedo?
zen-sidebar-notification-restart-safe-mode-tooltip =
.title = Paleisti iš naujo saugioje režime
zen-window-sync-migration-dialog-title = Keep Your Windows in Sync
zen-window-sync-migration-dialog-message = Zen now syncs windows on the same device, so changes in one window are reflected across the others instantly.
zen-window-sync-migration-dialog-learn-more = Learn More
zen-window-sync-migration-dialog-accept = Got It
zen-window-sync-migration-dialog-title = Išlaikykite savo langus sinchronizuotus
zen-window-sync-migration-dialog-message = Zen“ dabar sinchronizuoja langus tame pačiame įrenginyje, todėl viename lange atlikti pakeitimai iš karto atsispindi ir kituose.
zen-window-sync-migration-dialog-learn-more = Sužinoti daugiau
zen-window-sync-migration-dialog-accept = Supratau

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Tamsų
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Naujas tuščias langas

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Escuro
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nova janela em branco

View File

@@ -18,9 +18,9 @@ tab-context-zen-replace-pinned-url-with-current =
.label = Substituir o URL Fixado pelo URL Atual
.accesskey = C
tab-context-zen-edit-title =
.label = Change Label...
.label = Alterar etiqueta...
tab-context-zen-edit-icon =
.label = Change Icon...
.label = Alterar ícone...
zen-themes-corrupted = O seu ficheiro de modificações do { -brand-short-name } está corrompido. Elas foram redefinidas como iguais às do tema padrão.
zen-shortcuts-corrupted = O seu ficheiro de atalhos do { -brand-short-name } está corrompido. Eles foram redefinidos para os atalhos padrão.
# note: Do not translate the "<br/>" tags in the following string
@@ -109,7 +109,7 @@ zen-sidebar-notification-updated-tooltip =
zen-sidebar-notification-restart-safe-mode-label = Falhou alguma coisa?
zen-sidebar-notification-restart-safe-mode-tooltip =
.title = Reiniciar em Modo de Segurança
zen-window-sync-migration-dialog-title = Keep Your Windows in Sync
zen-window-sync-migration-dialog-message = Zen now syncs windows on the same device, so changes in one window are reflected across the others instantly.
zen-window-sync-migration-dialog-title = Mantenha As Suas Janelas Sincronizadas
zen-window-sync-migration-dialog-message = Agora, o Zen sincroniza as janelas no dispositivo, pelo que alterações numa janela são refletidas instantaneamente nas outras.
zen-window-sync-migration-dialog-learn-more = Learn More
zen-window-sync-migration-dialog-accept = Got It
zen-window-sync-migration-dialog-accept = Entendido

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Escuro
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nova janela sem sincronização

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Переключить хранилище
zen-devtools-toggle-dom-shortcut = Переключить DOM
zen-devtools-toggle-accessibility-shortcut = Включить/выключить специальные возможности
zen-close-all-unpinned-tabs-shortcut = Закрыть все не закреплённые вкладки
zen-new-unsynced-window-shortcut = Новое несинхронизированное окно
zen-new-unsynced-window-shortcut = Новое пустое окно

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Växla lagring
zen-devtools-toggle-dom-shortcut = Växla DOM
zen-devtools-toggle-accessibility-shortcut = Växla tillgänglighetsinställningar
zen-close-all-unpinned-tabs-shortcut = Stäng alla flikar som inte är fästa
zen-new-unsynced-window-shortcut = Nytt osynkroniserat fönster
zen-new-unsynced-window-shortcut = Nytt tomt fönster

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Mörkt
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nytt tomt fönster

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Depolamayı Aç/Kapat
zen-devtools-toggle-dom-shortcut = DOM'u Aç/Kapat
zen-devtools-toggle-accessibility-shortcut = Erişilebilirliği Aç/Kapat
zen-close-all-unpinned-tabs-shortcut = Sabitlenmemiş Tüm Sekmeleri Kapat
zen-new-unsynced-window-shortcut = Senkronize Edilmemiş Yeni Pencere
zen-new-unsynced-window-shortcut = Yeni Boş Pencere

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Koyu
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Yeni Boş Pencere

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = 開啟儲存空間檢測器
zen-devtools-toggle-dom-shortcut = 開啟 DOM
zen-devtools-toggle-accessibility-shortcut = 開啟輔助功能
zen-close-all-unpinned-tabs-shortcut = 關閉所有未釘選的分頁
zen-new-unsynced-window-shortcut = 開新未同步視窗
zen-new-unsynced-window-shortcut = 開新初始視窗

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = 暗色
zen-menubar-new-unsynced-window =
.label = 新初始視窗
.label = 新初始視窗

View File

@@ -49,7 +49,7 @@ zen-panel-ui-gradient-click-to-add = 點擊新增顏色
zen-workspace-creation-name =
.placeholder = 工作區名稱
zen-move-tab-to-workspace-button =
.label = 移動至…
.label = 移動至…
.tooltiptext = 將此視窗所有頁面移至單一工作區
zen-workspaces-panel-context-reorder =
.label = 排序工作區

View File

@@ -13,3 +13,6 @@
- name: zen.window-sync.open-link-in-new-unsynced-window
value: true
- name: zen.window-sync.sync-only-pinned-tabs
value: false

View File

@@ -1,41 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import sys
import requests
BASE_URI = "https://phabricator.services.mozilla.com"
OUTPUT_DIR = os.path.join(os.getcwd(), "src", "firefox-patches")
def download_phab_patch(phab_id, output_file):
"""Download a Phabricator patch by its ID and save it to output_file."""
patch_url = f"{BASE_URI}/{phab_id}?download=true"
try:
print(f"Downloading patch from {patch_url}")
response = requests.get(patch_url)
response.raise_for_status() # Raise an error for bad responses
with open(output_file, 'wb') as f:
f.write(response.content)
print(f"Patch saved to {output_file}")
except requests.RequestException as e:
print(f"Error downloading patch: {e}")
sys.exit(1)
def main():
if len(sys.argv) < 2:
print("Usage: python download_phab_patch.py <PHABRICATOR_ID> [output_file]", file=sys.stderr)
sys.exit(1)
phab_id = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else f"phab_{phab_id}"
output_file = os.path.join(OUTPUT_DIR, output_file + ".patch")
download_phab_patch(phab_id, output_file)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,99 @@
# 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/.
import os
import sys
import json
import requests
from json_with_comments import JSONWithCommentsDecoder
BASE_URI = "https://phabricator.services.mozilla.com"
OUTPUT_DIR = os.path.join(os.getcwd(), "src", "external-patches")
def die(message):
print(f"Error: {message}")
sys.exit(1)
def download_phab_patch(phab_id, output_file):
"""Download a Phabricator patch by its ID and save it to output_file."""
patch_url = f"{BASE_URI}/{phab_id}?download=true"
try:
print(f"Downloading patch from {patch_url}")
response = requests.get(patch_url)
response.raise_for_status() # Raise an error for bad responses
with open(output_file, 'wb') as f:
f.write(response.content)
print(f"Patch saved to {output_file}")
except requests.RequestException as e:
die(f"Failed to download patch {phab_id}: {e}")
def download_patch_from_url(url, output_file):
"""Download a patch from a given URL and save it to output_file."""
try:
print(f"Downloading patch from {url}")
response = requests.get(url)
response.raise_for_status() # Raise an error for bad responses
with open(output_file, 'wb') as f:
f.write(response.content)
print(f"Patch saved to {output_file}")
except requests.RequestException as e:
die(f"Failed to download patch from {url}: {e}")
def main():
with open(os.path.join(OUTPUT_DIR, "manifest.json"), 'r') as f:
manifest = json.load(f, cls=JSONWithCommentsDecoder)
expected_files = set()
for patch in manifest:
if patch.get("type") == "phabricator":
phab_id = patch.get("id")
name = patch.get("name")
if not phab_id or not name:
die(f"Patch entry missing 'id' or 'name': {patch}")
name = name.replace(" ", "_").lower()
output_file = os.path.join(OUTPUT_DIR, "firefox", f"{name}.patch")
print(f"Processing Phabricator patch: {phab_id} -> {output_file}")
download_phab_patch(phab_id, output_file)
expected_files.add(output_file)
elif patch.get("type") == "local":
print(f"Local patch: {patch.get('path')}")
expected_files.add(os.path.join(OUTPUT_DIR, patch.get("path")))
elif patch.get("type") == "patch":
url = patch.get("url")
dest = patch.get("dest")
if not url or not dest:
die(f"Patch entry missing 'url' or 'dest': {patch}")
filename = url.split("/")[-1]
output_file = os.path.join(OUTPUT_DIR, dest, filename)
download_patch_from_url(url, output_file)
replaces = patch.get("replaces", {})
for replace in replaces.keys():
value = replaces[replace]
with open(output_file, 'r') as f:
content = f.read()
if replace not in content:
die(f"Replace string '{replace}' not found in {output_file}")
with open(output_file, 'w') as f:
f.write(content.replace(replace, value))
expected_files.add(output_file)
else:
die(f"Unknown patch type: {patch.get('type')}")
# Check for unexpected files in the output directory
# and remove them if they are not in the expected_files set.
for root, dirs, files in os.walk(OUTPUT_DIR):
for file in files:
if file.endswith(".patch"):
file_path = os.path.join(root, file)
if file_path not in expected_files:
print(f"Removing unexpected patch file: {file_path}")
os.remove(file_path)
if __name__ == "__main__":
main()

View File

@@ -736,6 +736,7 @@ var gZenWorkspacesSettings = {
Services.prefs.addObserver("zen.glance.enabled", tabsUnloaderPrefListener); // We can use the same listener for both prefs
Services.prefs.addObserver("zen.workspaces.separate-essentials", tabsUnloaderPrefListener);
Services.prefs.addObserver("zen.glance.activation-method", tabsUnloaderPrefListener);
Services.prefs.addObserver("zen.window-sync.sync-only-pinned-tabs", tabsUnloaderPrefListener);
Services.prefs.addObserver(
"zen.tabs.ctrl-tab.ignore-essential-tabs",
toggleZenCycleByAttrWarning
@@ -745,6 +746,10 @@ var gZenWorkspacesSettings = {
Services.prefs.removeObserver("zen.glance.enabled", tabsUnloaderPrefListener);
Services.prefs.removeObserver("zen.glance.activation-method", tabsUnloaderPrefListener);
Services.prefs.removeObserver("zen.workspaces.separate-essentials", tabsUnloaderPrefListener);
Services.prefs.removeObserver(
"zen.window-sync.sync-only-pinned-tabs",
tabsUnloaderPrefListener
);
Services.prefs.removeObserver(
"zen.tabs.ctrl-tab.ignore-essential-tabs",
toggleZenCycleByAttrWarning
@@ -1198,6 +1203,11 @@ Preferences.addAll([
type: "bool",
default: true,
},
{
id: "zen.window-sync.sync-only-pinned-tabs",
type: "bool",
default: false,
},
]);
Preferences.addSetting({

View File

@@ -20,6 +20,9 @@
<label><html:h2 data-l10n-id="zen-settings-workspaces-header"/></label>
<description class="description-deemphasized" data-l10n-id="zen-settings-workspaces-description" />
<checkbox id="zenWorkspacesSyncUnpinnedTabs"
data-l10n-id="zen-settings-workspaces-sync-unpinned-tabs"
preference="zen.window-sync.sync-only-pinned-tabs"/>
<checkbox id="zenWorkspacesHideDefaultContainer"
data-l10n-id="zen-settings-workspaces-hide-default-container-indicator"
preference="zen.workspaces.hide-default-container-indicator"/>

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tab.js b/browser/components/tabbrowser/content/tab.js
index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c9b8386b3 100644
index 6528da245d922e2ccdb59cbf8106055bc34d1e74..b5d5ac633c06d7d9c909ec9456a5f3c165a6b925 100644
--- a/browser/components/tabbrowser/content/tab.js
+++ b/browser/components/tabbrowser/content/tab.js
@@ -21,6 +21,7 @@
@@ -52,7 +52,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
return;
}
@@ -224,11 +227,21 @@
@@ -224,11 +227,23 @@
}
get visible() {
@@ -64,7 +64,6 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
+ if (!this.isOpen || this.hidden || this.hasAttribute("zen-empty-tab")) {
+ return false;
+ }
+
+ // Selected tabs are always visible
+ if (this.selected || this.multiselected || this.hasAttribute("folder-active")) return true;
+ // Recursively check all parent groups
@@ -75,11 +74,14 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
+ }
+ currentParent = currentParent.group;
+ }
+ if (this.pinned && !this.hasAttribute("zen-essential") && gZenWorkspaces.activeWorkspaceElement?.hasCollapsedPinnedTabs) {
+ return false;
+ }
+ return true;
}
get hidden() {
@@ -307,7 +320,7 @@
@@ -307,7 +322,7 @@
return false;
}
@@ -88,7 +90,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
}
get lastAccessed() {
@@ -384,7 +397,18 @@
@@ -384,7 +399,18 @@
}
get group() {
@@ -108,7 +110,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
}
get splitview() {
@@ -489,6 +513,8 @@
@@ -489,6 +515,8 @@
this.style.MozUserFocus = "ignore";
} else if (
event.target.classList.contains("tab-close-button") ||
@@ -117,7 +119,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
event.target.classList.contains("tab-icon-overlay") ||
event.target.classList.contains("tab-audio-button")
) {
@@ -543,6 +569,10 @@
@@ -543,6 +571,10 @@
this.style.MozUserFocus = "";
}
@@ -128,7 +130,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
on_click(event) {
if (event.button != 0) {
return;
@@ -603,6 +633,14 @@
@@ -603,6 +635,14 @@
// (see tabbrowser-tabs 'click' handler).
gBrowser.tabContainer._blockDblClick = true;
}
@@ -143,7 +145,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
}
on_dblclick(event) {
@@ -626,6 +664,8 @@
@@ -626,6 +666,8 @@
animate: true,
triggeringEvent: event,
});

View File

@@ -0,0 +1,3 @@
# Patches imported from LibreWolf
Firefox sometimes makes changes without considering the impact on forks. This is the case of the patches that are imported from LibreWolf, which are already present in LibreWolf but not yet (or never) present in Firefox. Thanks to LibreWolf for making these patches available and for their work in maintaining them. We will keep these patches as long as they are needed, and we will remove them once they are no longer necessary (for example, when they are merged into Firefox or when the issue they solve is no longer present).

View File

@@ -0,0 +1,12 @@
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
@@ -28,7 +28,7 @@ project_flag(
project_flag(
env="MOZ_APP_UA_NAME",
- default="",
+ default="Firefox",
nargs=1,
help="Application name in the User Agent string",
)

View File

@@ -0,0 +1,65 @@
diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
index 3cf7073..b1c782a 100644
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -1283,9 +1283,11 @@ nsresult nsXREDirProvider::AppendFromAppData(nsIFile* aFile, bool aIsDotted) {
// Similar to nsXREDirProvider::AppendProfilePath.
// TODO: Bug 1990407 - Evaluate if refactoring might be required there in the
// future?
- if (gAppData->profile) {
+ // Use aIsDotted for a different purpose here, will probably break in the future
+ if (gAppData->profile && aIsDotted) {
nsAutoCString profile;
profile = gAppData->profile;
+ profile = "."_ns + nsDependentCString(gAppData->profile);
MOZ_TRY(aFile->AppendRelativeNativePath(profile));
} else {
nsAutoCString vendor;
@@ -1295,8 +1297,8 @@ nsresult nsXREDirProvider::AppendFromAppData(nsIFile* aFile, bool aIsDotted) {
ToLowerCase(vendor);
ToLowerCase(appName);
- MOZ_TRY(aFile->AppendRelativeNativePath(aIsDotted ? ("."_ns + vendor)
- : vendor));
+ //MOZ_TRY(aFile->AppendRelativeNativePath(aIsDotted ? ("."_ns + vendor)
+ // : vendor));
MOZ_TRY(aFile->AppendRelativeNativePath(appName));
}
@@ -1435,28 +1437,22 @@ nsresult nsXREDirProvider::GetLegacyOrXDGHomePath(const char* aHomeDir,
return NS_OK;
}
- // If the build was made against a specific profile name, MOZ_APP_PROFILE=
- // then make sure we respect this and dont move to XDG directory
- if (gAppData->profile) {
- MOZ_TRY(NS_NewNativeLocalFile(nsDependentCString(aHomeDir),
- getter_AddRefs(localDir)));
- } else {
- MOZ_TRY(GetLegacyOrXDGConfigHome(aHomeDir, getter_AddRefs(localDir)));
- MOZ_TRY(localDir->Clone(getter_AddRefs(parentDir)));
- }
+ // Since we set gAppData->profile and don't want to force legacy behaviour
+ MOZ_TRY(GetLegacyOrXDGConfigHome(aHomeDir, getter_AddRefs(localDir)));
+ MOZ_TRY(localDir->Clone(getter_AddRefs(parentDir)));
MOZ_TRY(AppendFromAppData(localDir, false));
}
+ // The profile root directory needs to exists at that point.
+ MOZ_TRY(EnsureDirectoryExists(localDir));
+
// If required return the parent directory that matches the profile root
// directory.
if (aFile) {
- parentDir.forget(aFile);
+ localDir.forget(aFile);
}
- // The profile root directory needs to exists at that point.
- MOZ_TRY(EnsureDirectoryExists(localDir));
-
return NS_OK;
}
#endif // defined(MOZ_WIDGET_GTK)

View File

@@ -0,0 +1,29 @@
// 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/.
[
{
"type": "phabricator",
"id": "D279007",
"name": "Fix MacOS Crash on Shutdown Firefox 149"
},
{
"type": "local",
"path": "firefox/no_liquid_glass_icon.patch"
},
{
"type": "patch",
"url": "https://codeberg.org/librewolf/source/raw/branch/main/patches/firefox-in-ua.patch",
"dest": "librewolf",
"replaces": {
// They don't correctly export this patch, so we need to replace
// the parameter's help description with the correct one.
"application": "Application"
}
},
{
"type": "patch",
"url": "https://codeberg.org/librewolf/source/raw/branch/main/patches/xdg-dir.patch",
"dest": "librewolf"
}
]

View File

@@ -1,13 +0,0 @@
diff --git a/netwerk/protocol/http/moz.build b/netwerk/protocol/http/moz.build
index d2330003caf35c43d6831fb0d356ece513906f78..76c2faf822ddaf645eb03d93380c58b4e3b510c0 100644
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -227,7 +227,7 @@ LOCAL_INCLUDES += [
"/netwerk/url-classifier",
]
-DEFINES["MOZ_APP_UA_NAME"] = f'"{CONFIG["MOZ_APP_UA_NAME"]}"'
+DEFINES["MOZ_APP_UA_NAME"] = f'"Firefox"'
if CONFIG["MOZ_AUTH_EXTENSION"]:
LOCAL_INCLUDES += [

View File

@@ -7,7 +7,7 @@ index 0d7a3e505b6bd30548c6dda1504dd343a517b083..54400def5e02e886765fab68c3854a6b
getBrowserInfo: function () {
const { name, vendor, version, appBuildID } = Services.appinfo;
- const info = { name, vendor, version, buildID: appBuildID };
+ const info = { name: 'firefox', vendor, version: AppConstants.ZEN_FIREFOX_VERSION, buildID: appBuildID };
+ const info = { name: 'Firefox', vendor, version: AppConstants.ZEN_FIREFOX_VERSION, buildID: appBuildID };
return Promise.resolve(info);
},

View File

@@ -10,9 +10,14 @@
}
#zen-dragover-background {
width: calc(100% - var(--zen-toolbox-padding) * 2 - 5px);
width: calc(100% - var(--zen-toolbox-padding) * 2 - 7px);
left: unset;
right: calc(var(--zen-toolbox-padding) + 3px);
transform: translateY(-4px);
:root:not([zen-single-toolbar="true"]) & {
transform: translateY(calc(-100% - 2px));
}
}
#zen-tabbox-wrapper {

View File

@@ -936,7 +936,9 @@
let dropElementFromEvent = event.target.closest(dropZoneSelector);
dropElement = dropElementFromEvent || dropElement;
if (!dropElementFromEvent) {
let hoveringPeriphery = !!event.target.closest("#tabbrowser-arrowscrollbox-periphery");
let hoveringPeriphery = !!event.target.closest(
":is(#tabbrowser-arrowscrollbox-periphery, .pinned-tabs-container-separator)"
);
if (event.target.classList.contains("zen-workspace-empty-space") || hoveringPeriphery) {
let lastTab = gBrowser.tabs.at(-1);
dropElement =

View File

@@ -11,6 +11,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs",
gWindowSyncEnabled: "resource:///modules/zen/ZenWindowSync.sys.mjs",
gSyncOnlyPinnedTabs: "resource:///modules/zen/ZenWindowSync.sys.mjs",
DeferredTask: "resource://gre/modules/DeferredTask.sys.mjs",
});
@@ -562,10 +563,31 @@ export class nsZenSessionManager {
if (!sidebar) {
return;
}
aWindowData.tabs = sidebar.tabs || [];
aWindowData.splitViewData = sidebar.splitViewData;
// If we should only sync the pinned tabs, we should only edit the unpinned
// tabs in the window data and keep the pinned tabs from the window data,
// as they should be the same as the ones in the sidebar.
if (lazy.gSyncOnlyPinnedTabs) {
let pinnedTabs = (sidebar.tabs || []).filter((tab) => tab.pinned);
let unpinedWindowTabs = (aWindowData.tabs || []).filter((tab) => !tab.pinned);
aWindowData.tabs = [...pinnedTabs, ...unpinedWindowTabs];
// We restore ALL the split view data in the sidebar, if the group doesn't exist in the window,
// it should be a no-op anyways.
aWindowData.splitViewData = [
...(sidebar.splitViewData || []),
...(aWindowData.splitViewData || []),
];
// Same thing with groups, we restore all the groups from the sidebar, if they don't have any
// existing tabs in the window, they should be a no-op.
aWindowData.groups = [...(sidebar.groups || []), ...(aWindowData.groups || [])];
} else {
aWindowData.tabs = sidebar.tabs || [];
aWindowData.splitViewData = sidebar.splitViewData;
aWindowData.groups = sidebar.groups;
}
// Folders are always pinned, so we dont need to check for the pinned state here.
aWindowData.folders = sidebar.folders;
aWindowData.groups = sidebar.groups;
aWindowData.spaces = sidebar.spaces;
}
@@ -599,9 +621,10 @@ export class nsZenSessionManager {
this.#restoreWindowData(newWindow);
}
newWindow.tabs = this.#filterUnusedTabs(newWindow.tabs || []);
if (!lazy.gWindowSyncEnabled) {
// Don't bring over any unpinned tabs if window sync is disabled.
if (!lazy.gWindowSyncEnabled || lazy.gSyncOnlyPinnedTabs) {
// Don't bring over any unpinned tabs if window sync is disabled or if syncing only pinned tabs.
newWindow.tabs = newWindow.tabs.filter((tab) => tab.pinned);
newWindow.groups = newWindow.groups?.filter((group) => group.pinned);
}
// These are window-specific from the previous window state that

View File

@@ -19,6 +19,12 @@ ChromeUtils.defineESModuleGetters(lazy, {
});
XPCOMUtils.defineLazyPreferenceGetter(lazy, "gWindowSyncEnabled", "zen.window-sync.enabled", true);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"gSyncOnlyPinnedTabs",
"zen.window-sync.sync-only-pinned-tabs",
true
);
XPCOMUtils.defineLazyPreferenceGetter(lazy, "gShouldLog", "zen.window-sync.log", true);
const OBSERVING = ["browser-window-before-show", "sessionstore-windows-restored"];
@@ -241,7 +247,7 @@ class nsZenWindowSync {
if (tab.pinned && !tab._zenPinnedInitialState) {
await this.setPinnedTabState(tab);
}
if (!lazy.gWindowSyncEnabled) {
if (!lazy.gWindowSyncEnabled || (lazy.gSyncOnlyPinnedTabs && !tab.pinned)) {
tab._zenContentsVisible = true;
}
}
@@ -953,6 +959,9 @@ class nsZenWindowSync {
*/
#delegateGenericSyncEvent(aEvent, flags = 0) {
const item = aEvent.target;
if (lazy.gSyncOnlyPinnedTabs && !item.pinned) {
return;
}
this.#syncItemForAllWindows(item, flags);
}
@@ -1089,16 +1098,19 @@ class nsZenWindowSync {
/* Mark: Event Handlers */
on_TabOpen(aEvent) {
on_TabOpen(aEvent, { duringPinning = false } = {}) {
const tab = aEvent.target;
const window = tab.ownerGlobal;
const isUnsyncedWindow = window.gZenWorkspaces.privateWindowOrDisabled;
if (tab.id) {
if (tab.id && !duringPinning) {
// This tab was opened as part of a sync operation.
return;
}
tab._zenContentsVisible = true;
tab.id = this.#newTabSyncId;
if (lazy.gSyncOnlyPinnedTabs && !tab.pinned) {
return;
}
if (isUnsyncedWindow || !lazy.gWindowSyncEnabled) {
return;
}
@@ -1116,6 +1128,9 @@ class nsZenWindowSync {
SYNC_FLAG_ICON | SYNC_FLAG_LABEL | SYNC_FLAG_MOVE
);
});
if (duringPinning && tab?.splitView) {
this.on_ZenSplitViewTabsSplit({ target: tab.group });
}
this.#maybeFlushTabState(tab);
}
@@ -1137,7 +1152,8 @@ class nsZenWindowSync {
}
on_TabMove(aEvent) {
return this.#delegateGenericSyncEvent(aEvent, SYNC_FLAG_MOVE);
this.#delegateGenericSyncEvent(aEvent, SYNC_FLAG_MOVE);
return Promise.resolve();
}
on_TabPinned(aEvent) {
@@ -1149,7 +1165,14 @@ class nsZenWindowSync {
if (!tab._zenPinnedInitialState) {
tabStatePromise = this.setPinnedTabState(tab);
}
return Promise.all([tabStatePromise, this.on_TabMove(aEvent)]);
return Promise.all([
tabStatePromise,
this.on_TabMove(aEvent).then(() => {
if (lazy.gSyncOnlyPinnedTabs) {
this.on_TabOpen({ target: tab }, { duringPinning: true });
}
}),
]);
}
on_TabUnpinned(aEvent) {
@@ -1160,7 +1183,11 @@ class nsZenWindowSync {
delete targetTab._zenPinnedInitialState;
}
});
return this.on_TabMove(aEvent);
return this.on_TabMove(aEvent).then(() => {
if (lazy.gSyncOnlyPinnedTabs) {
this.on_TabClose({ target: tab });
}
});
}
on_TabAddedToEssentials(aEvent) {
@@ -1351,4 +1378,6 @@ class nsZenWindowSync {
// eslint-disable-next-line mozilla/valid-lazy
export const gWindowSyncEnabled = lazy.gWindowSyncEnabled;
// eslint-disable-next-line mozilla/valid-lazy
export const gSyncOnlyPinnedTabs = lazy.gSyncOnlyPinnedTabs;
export const ZenWindowSync = new nsZenWindowSync();

View File

@@ -560,9 +560,6 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
// eslint-disable-next-line complexity
moveToAnotherTabContainerIfNecessary(event, draggedTab, movingTabs, dropIndex) {
if (!this.enabled) {
return false;
}
let newIndex = dropIndex;
let fromDifferentWindow = false;
movingTabs = Array.from(movingTabs || draggedTab)

View File

@@ -5,8 +5,8 @@
"binaryName": "zen",
"version": {
"product": "firefox",
"version": "147.0.2",
"candidate": "147.0.2",
"version": "147.0.3",
"candidate": "147.0.3",
"candidateBuild": 1
},
"buildOptions": {
@@ -20,7 +20,7 @@
"brandShortName": "Zen",
"brandFullName": "Zen Browser",
"release": {
"displayVersion": "1.18.4b",
"displayVersion": "1.18.5b",
"github": {
"repo": "zen-browser/desktop"
},
@@ -54,4 +54,4 @@
"licenseType": "MPL-2.0"
},
"updateHostname": "updates.zen-browser.app"
}
}