Compare commits

..

153 Commits

Author SHA1 Message Date
Mr. M
2bd548fe41 Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2025-05-14 08:45:15 +02:00
mr. m
d9d3076e2e Merge pull request #8300 from zen-browser/revert-8286-alert-autofix-9
Revert "Potential fix for code scanning alert no. 9: Workflow does not contain permissions"
2025-05-14 10:42:54 +02:00
mr. m
b8254fdd36 Revert "Potential fix for code scanning alert no. 9: Workflow does not contain permissions" 2025-05-14 10:42:46 +02:00
mr. m
562274a161 Merge pull request #8299 from zen-browser/revert-8282-alert-autofix-16
Revert "Potential fix for code scanning alert no. 16: Workflow does not contain permissions"
2025-05-14 10:41:33 +02:00
mr. m
19f96241e5 Merge pull request #8298 from zen-browser/revert-8291-alert-autofix-11
Revert "Potential fix for code scanning alert no. 11: Workflow does not contain permissions"
2025-05-14 10:41:25 +02:00
mr. m
d735a1fa91 Merge pull request #8297 from zen-browser/revert-8293-alert-autofix-20
Revert "Potential fix for code scanning alert no. 20: Workflow does not contain permissions"
2025-05-14 10:41:21 +02:00
mr. m
40baf2627c Revert "Potential fix for code scanning alert no. 16: Workflow does not contain permissions" 2025-05-14 10:41:14 +02:00
mr. m
5880636b3a Revert "Potential fix for code scanning alert no. 20: Workflow does not contain permissions" 2025-05-14 10:41:11 +02:00
mr. m
531f569f3a Revert "Potential fix for code scanning alert no. 11: Workflow does not contain permissions" 2025-05-14 10:41:06 +02:00
mr. m
00fcd74552 Merge pull request #8296 from zen-browser/revert-8294-alert-autofix-6
Revert "Potential fix for code scanning alert no. 6: Workflow does not contain permissions"
2025-05-14 10:39:35 +02:00
mr. m
f594a0b5c0 Revert "Potential fix for code scanning alert no. 6: Workflow does not contain permissions" 2025-05-14 10:39:27 +02:00
mr. m
94779133ec Merge pull request #8295 from zen-browser/revert-8285-alert-autofix-13
Revert "Potential fix for code scanning alert no. 13: Workflow does not contain permissions"
2025-05-14 10:37:33 +02:00
mr. m
a2b1b38e0c Revert "Potential fix for code scanning alert no. 13: Workflow does not contain permissions" 2025-05-14 10:37:24 +02:00
mr. m
cd3823f180 Merge pull request #8294 from zen-browser/alert-autofix-6
Potential fix for code scanning alert no. 6: Workflow does not contain permissions
2025-05-14 10:31:15 +02:00
mr. m
8451a71af7 Potential fix for code scanning alert no. 6: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:31:08 +02:00
mr. m
455a2c005b Merge pull request #8293 from zen-browser/alert-autofix-20
Potential fix for code scanning alert no. 20: Workflow does not contain permissions
2025-05-14 10:29:04 +02:00
mr. m
4ad29e0ca5 Potential fix for code scanning alert no. 20: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:28:57 +02:00
mr. m
52b19fc137 Merge pull request #8292 from zen-browser/alert-autofix-8
Potential fix for code scanning alert no. 8: Workflow does not contain permissions
2025-05-14 10:26:48 +02:00
mr. m
7958417f96 Merge pull request #8291 from zen-browser/alert-autofix-11
Potential fix for code scanning alert no. 11: Workflow does not contain permissions
2025-05-14 10:26:30 +02:00
mr. m
744618ac25 Potential fix for code scanning alert no. 8: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:26:26 +02:00
mr. m
07296f19a6 Potential fix for code scanning alert no. 11: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:26:23 +02:00
mr. m
db271db087 Merge pull request #8287 from zen-browser/alert-autofix-5
Potential fix for code scanning alert no. 5: Workflow does not contain permissions
2025-05-14 10:25:37 +02:00
mr. m
d30a24e768 Merge pull request #8289 from zen-browser/alert-autofix-1
Potential fix for code scanning alert no. 1: Workflow does not contain permissions
2025-05-14 10:25:00 +02:00
mr. m
2b359ea451 Merge pull request #8288 from zen-browser/alert-autofix-2
Potential fix for code scanning alert no. 2: Workflow does not contain permissions
2025-05-14 10:24:53 +02:00
mr. m
8af3faea16 Merge pull request #8290 from zen-browser/alert-autofix-12
Potential fix for code scanning alert no. 12: Workflow does not contain permissions
2025-05-14 10:24:31 +02:00
mr. m
0c5716fb81 Merge pull request #8286 from zen-browser/alert-autofix-9
Potential fix for code scanning alert no. 9: Workflow does not contain permissions
2025-05-14 10:20:15 +02:00
mr. m
d19a484cb0 Potential fix for code scanning alert no. 12: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:19:55 +02:00
mr. m
38bf9bebc8 Merge pull request #8285 from zen-browser/alert-autofix-13
Potential fix for code scanning alert no. 13: Workflow does not contain permissions
2025-05-14 10:19:47 +02:00
mr. m
d79b89f79b Merge pull request #8284 from zen-browser/alert-autofix-14
Potential fix for code scanning alert no. 14: Workflow does not contain permissions
2025-05-14 10:19:23 +02:00
mr. m
7855d657fd Merge pull request #8283 from zen-browser/alert-autofix-15
Potential fix for code scanning alert no. 15: Workflow does not contain permissions
2025-05-14 10:19:16 +02:00
mr. m
67a52ae02c Potential fix for code scanning alert no. 1: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:18:37 +02:00
mr. m
4b14c1e2f8 Potential fix for code scanning alert no. 2: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:18:35 +02:00
mr. m
fc908f9d4a Potential fix for code scanning alert no. 5: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:18:30 +02:00
mr. m
77bc3ced5d Potential fix for code scanning alert no. 9: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:18:25 +02:00
mr. m
34dc835631 Potential fix for code scanning alert no. 13: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:18:15 +02:00
mr. m
81b279be5f Potential fix for code scanning alert no. 14: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:18:13 +02:00
mr. m
828c7bea19 Potential fix for code scanning alert no. 15: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:18:12 +02:00
mr. m
b4a49636d7 Merge pull request #8282 from zen-browser/alert-autofix-16
Potential fix for code scanning alert no. 16: Workflow does not contain permissions
2025-05-14 10:17:45 +02:00
mr. m
1caa6d9aa5 Potential fix for code scanning alert no. 16: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:17:24 +02:00
mr. m
ecc6df3301 Merge pull request #8281 from zen-browser/alert-autofix-17
Potential fix for code scanning alert no. 17: Overly permissive regular expression range
2025-05-14 10:17:11 +02:00
mr. m
0310e89c39 Potential fix for code scanning alert no. 17: Overly permissive regular expression range
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:16:59 +02:00
mr. m
252af87d9b Merge pull request #8280 from zen-browser/alert-autofix-19
Potential fix for code scanning alert no. 19: Overly permissive regular expression range
2025-05-14 10:16:48 +02:00
mr. m
6732a69c2b Potential fix for code scanning alert no. 19: Overly permissive regular expression range
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:16:36 +02:00
mr. m
3868f8e30f Merge pull request #8279 from zen-browser/alert-autofix-18
Potential fix for code scanning alert no. 18: Overly permissive regular expression range
2025-05-14 10:14:55 +02:00
mr. m
937408f3f6 Potential fix for code scanning alert no. 18: Overly permissive regular expression range
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:14:16 +02:00
mr. m
e53a95e297 Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2025-05-14 10:13:05 +02:00
mr. m
b74153290b chore: Remove remaining bits from zen rices, b=(no-bug), c=workspaces 2025-05-14 10:12:51 +02:00
mr. m
0021c3522f Added security instructions for new reports
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-14 10:03:06 +02:00
Mr. M
367ad74fba chore: Use npm for surfer CI windows signing, b=(no-bug), c=no-component 2025-05-14 08:45:07 +02:00
Mr. M
0abf17cb6b fix: Fixed an issue with opening bookmarks with different containers, b=(no-bug), c=common 2025-05-13 20:00:31 +02:00
mr. m
be76e751e7 Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2025-05-13 19:43:11 +02:00
mr. m
f8a893e6de fix: Small fixes for toast notifications, b=(no-bug), c=common 2025-05-13 19:43:00 +02:00
Mr. M
89dfc86bfb fix: Fixed missaligment on mute/unmute icon, b=(no-bug), c=tabs 2025-05-13 17:33:07 +02:00
Mr. M
bc894f8beb style: Improved URL bar styles, b=(no-bug), c=common 2025-05-13 17:00:58 +02:00
Mr. M
20120ecf27 Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2025-05-13 16:35:38 +02:00
Mr. M
a9c344d385 fix: Fixed background tabs opening when a tab is created by an addon, b=(no-bug), c=tabs, common, compact-mode 2025-05-13 16:35:24 +02:00
mr. m
3cbfae7a8f fix: Fixed macos close buttons being misaligned on collapsed sidebar, b=(closes #7129), c=tabs 2025-05-13 16:12:15 +02:00
Mr. M
90876532b9 fix: Fixed the download animation appearing on all the windows, b=(closes #8247), c=no-component 2025-05-13 16:07:24 +02:00
Mr. M
641d4d0f87 chore: Updated to firefox 138.0.3, b=(no-bug), c=scripts, common 2025-05-13 15:58:39 +02:00
mr. m
7c12ad72b8 Merge pull request #8266 from zen-browser/haptic-feedback 2025-05-13 13:39:54 +02:00
Mr. M
66e0dde1ed fix: Make sure to remove the stylesheets before removing the file, b=(no-bug), c=mods 2025-05-13 13:38:47 +02:00
mr. m
5a4877a141 chore: Minor changes before merge of haptic feedback, b=(no-bug), c=workspaces 2025-05-13 13:37:36 +02:00
mr. m
f9b0f8c436 feat: Finished haptic feedback support, b=(no-bug), c=common, tabs, workspaces 2025-05-13 13:31:03 +02:00
Mr. M
6552ec5f02 test: Added tests for closing glance, b=(no-bug), c=glance, tests 2025-05-13 12:00:39 +02:00
Mr. M
337b1aec53 fix: Fixed top toolbar staying at the top when clicking on the urlbar, b=(no-bug), c=compact-mode 2025-05-13 11:31:07 +02:00
mr. m
33fff9e19b Merge branch 'haptic-feedback' of https://github.com/zen-browser/desktop into haptic-feedback 2025-05-13 10:40:48 +02:00
Mr. M
2cdaf4850d feat: Compile the function even if we are not on mac, b=(no-bug), c=common 2025-05-13 10:40:41 +02:00
mr. m
561da4b6ef chore: Format, b=(no-bug), c=common 2025-05-13 10:39:47 +02:00
Mr. M
3a8767ea5f fix: Fixed windows API build, b=(no-bug), c=tabs, common 2025-05-13 10:37:36 +02:00
Mr. M
4947b4c9a3 feat: Addded haptic feedback support, b=(no-bug), c=common 2025-05-13 10:33:24 +02:00
mr. m
0f140b706e Merge pull request #8265 from kritishd8/dev
Added workspace color bg to search mode indicators
2025-05-13 09:59:48 +02:00
Obscure.
b4812e8182 Added workspace color bg to search mode indicators
Signed-off-by: Obscure. <69711181+kritishd8@users.noreply.github.com>
2025-05-13 08:29:19 +05:45
mr. m
7d94cad876 Merge pull request #8243 from zen-browser/new-share-api
New share API and implementation
2025-05-13 02:55:26 +02:00
mr. m
866e6987a2 feat: Added last details, b=(no-bug), c=common 2025-05-13 02:54:59 +02:00
Mr. M
524f34a461 chore: Bump version, b=(no-bug), c=no-component 2025-05-13 01:11:57 +02:00
Mr. M
949d93d546 Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2025-05-13 01:10:23 +02:00
Mr. M
bd638022df test: Added tests for glance, b=(no-bug), c=tabs, glance, tests 2025-05-13 01:10:18 +02:00
mr. m
26e6d704f5 Merge pull request #8261 from SO9010/Fix-#7910 2025-05-13 00:31:48 +02:00
mr. m
1be8b20b64 Make use of lazy preferences
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-13 00:31:17 +02:00
Samuel Oldham
c8150ccdcc Fix for #7910
This fixes #7910 by adding a conditional check for whether the sidebar is on the right and adjusting the CSS accordingly. 

Signed-off-by: Samuel Oldham <77629938+SO9010@users.noreply.github.com>
2025-05-12 23:26:16 +01:00
Mr. M
77bac52b07 fix: Completed windows API, b=(no-bug), c=no-component 2025-05-13 00:23:33 +02:00
mr. m
3566289cb5 feat: Completed API for cocoa, b=(no-bug), c=common 2025-05-13 01:25:55 +02:00
mr. m
0b34cc3033 chore: Added native macos handling, b=(no-bug), c=common 2025-05-12 23:31:48 +02:00
Mr. M
fdb71c6b0e feat: Make sure switching woprkspaces from browsers always selects the tab first, b=(no-bug), c=common, workspaces 2025-05-12 22:48:09 +02:00
Mr. M
ffea12305d fix: Fixed urlbar shifting when focusing on it, b=(no-bug), c=common 2025-05-12 22:30:57 +02:00
Mr. M
e90f20e1d4 fix: Fixed search engine suggestions being half the height, b=(closes #8258), c=welcome 2025-05-12 21:59:35 +02:00
Mr. M
f58dbd71b6 feat: Added cocoa APIs, b=(no-bug), c=common 2025-05-12 21:53:15 +02:00
Mr. M
b4c7a64631 feat: Added a share button to copy url, b=(no-bug), c=common 2025-05-12 20:36:46 +02:00
Mr. M
e496655953 chore: Made a functioning API for sharing, b=(no-bug), c=common 2025-05-12 19:58:14 +02:00
mr. m
fea0e9b864 Merge pull request #8256 from SO9010/Fix-#7810 2025-05-12 18:04:15 +02:00
mr. m
7a7fb01928 Merge branch 'dev' into Fix-#7810 2025-05-12 18:04:01 +02:00
mr. m
d4575841df Merge pull request #8253 from SO9010/Fix-#7701 2025-05-12 18:03:11 +02:00
Samuel Oldham
d7e634fcfd Undo change to firefox-js.patch
Signed-off-by: Samuel Oldham <77629938+SO9010@users.noreply.github.com>
2025-05-12 15:53:46 +00:00
Samuel Oldham
b1e3df783d Update disablemozilla.inc to remove firefox mobile app advert
Signed-off-by: Samuel Oldham <77629938+SO9010@users.noreply.github.com>
2025-05-12 15:50:42 +00:00
mr. m
80dfcf5eaa Merge branch 'dev' into Fix-#7701 2025-05-12 17:45:40 +02:00
Mr. M
c0d66ee649 Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2025-05-12 17:13:21 +02:00
Mr. M
93e8f6bbd6 fix: Did common fixes for mods, b=(no-bug), c=mods 2025-05-12 17:13:15 +02:00
Samuel Oldham
cdbdaac913 Fix #7701 complete
Added the lock to the pref section.

Signed-off-by: Samuel Oldham <77629938+SO9010@users.noreply.github.com>
2025-05-12 15:12:11 +00:00
Samuel Oldham
9bec7a88fe Lint
Signed-off-by: Samuel Oldham <77629938+SO9010@users.noreply.github.com>
2025-05-12 15:53:21 +01:00
Samuel Oldham
50342e945d Add fix for #7810
Signed-off-by: Samuel Oldham <77629938+SO9010@users.noreply.github.com>
2025-05-12 15:35:49 +01:00
Samuel Oldham
c087493f38 Set browser.contentblocking.report.show_mobile_app to false
Signed-off-by: Samuel Oldham <77629938+SO9010@users.noreply.github.com>
2025-05-12 14:31:36 +00:00
Samuel Oldham
df3c554f27 Delete src/browser/components/protections directory
Signed-off-by: Samuel Oldham <77629938+SO9010@users.noreply.github.com>
2025-05-12 14:26:56 +00:00
Samuel Oldham
e81994a748 Add patch fix #7701
This fixes this issue by just setting it to removed in the preferences automatically, meaning that the users will never see it. This made more sense than having it rewritten just for this page. But if we think linking to Firefox mobile here is necessary, please let me know.

Signed-off-by: Samuel Oldham <77629938+SO9010@users.noreply.github.com>
2025-05-12 14:03:11 +01:00
mr. m
0d1d75588d fix: Fixed gradient having wrong percentages, b=(no-bug), c=workspaces 2025-05-12 13:36:06 +02:00
mr. m
5ddedbbd50 Disable acrylic pref for now
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-12 00:14:21 -07:00
Mr. M
fcc823c33a feat: Add experimental acrylic components for linux and windows, b=(no-bug), c=common, compact-mode, workspaces 2025-05-12 00:52:56 +02:00
Mr. M
1a7f9d9ee0 feat: Added priviledged window sharing API, b=(no-bug), c=common 2025-05-12 00:50:01 +02:00
Mr. M
1a2b527070 fix: Fixed issue with installing mods and unlock normandy preference, b=(closes #7198), c=mods, workspaces 2025-05-11 19:33:06 +02:00
Mr. M
39a357fa57 chore: Format, b=(no-bug), c=common 2025-05-11 19:11:48 +02:00
Mr. M
d2c50df0ab feat: Added more shadow to the urlbar, b=(no-bug), c=common 2025-05-11 19:07:52 +02:00
Mr. M
5dc30c44ff feat: Added blur to compact mode sidebar and the urlbar, b=(no-bug), c=common, compact-mode, workspaces 2025-05-11 18:34:23 +02:00
Mr. M
01d705a3b5 fix: Fixed media player hiding on fullscreen, b=(closes #8228), c=media 2025-05-11 12:56:53 +02:00
Mr. M
fff86fd068 fix: Fixed session restore not opening an essential tab on startup, b=(no-bug), c=workspaces 2025-05-11 12:54:19 +02:00
Mr. M
0fb9b51cc9 feat: Sort browser elements to make the current workspace have more priority, b=(no-bug), c=workspaces 2025-05-11 12:47:16 +02:00
Mr. M
bda91cd9d5 test: Added tests for contaienr specific bookmarks, b=(no-bug), c=tests, workspaces 2025-05-11 12:27:35 +02:00
Mr. M
0343430611 test: Added tests for compact mode, b=(no-bug), c=compact-mode, tests, workspaces 2025-05-11 01:38:31 +02:00
mr. m
1df7da7836 Merge pull request #8221 from SO9010/Fix-#7654 2025-05-11 01:14:23 +02:00
Mr. M
dc018561a0 test: Fixed result number for patch fix, b=(no-bug), c=tests 2025-05-11 01:14:01 +02:00
mr. m
520b41215c Merge branch 'dev' into Fix-#7654
Signed-off-by: mr. m  <91018726+mauro-balades@users.noreply.github.com>
2025-05-11 01:10:54 +02:00
Mr. M
3537680e45 test: Added tests for https://github.com/zen-browser/desktop/pull/8221, b=(no-bug), c=tests 2025-05-11 01:09:46 +02:00
Mr. M
d236035b72 test: Added some tests for pinned tabs, b=(no-bug), c=tabs, tests 2025-05-11 00:58:20 +02:00
Samuel Oldham
e2e742aba2 Add patch file to fix #7654
What I did was add the pinned tabs to the SQL query which allowed that to get searched too, thus fixing the error!

Signed-off-by: Samuel Oldham <77629938+SO9010@users.noreply.github.com>
2025-05-10 22:21:15 +01:00
Mr. M
3d8fc203f9 feat: Lower the time for a toast to exist, b=(no-bug), c=common 2025-05-10 21:23:27 +02:00
Mr. M
7b99f227cd chore: Format with only a maximum of 10 columns, b=(no-bug), c=workflows, common, compact-mode, folders, glance, kbs, media, mods, split-view, tabs, tests, workspaces, welcome 2025-05-10 21:22:16 +02:00
Mr. M
1f68a45417 chore: Better support for restoring previous tabs, b=(no-bug), c=workspaces 2025-05-10 20:00:25 +02:00
Mr. M
cc1619ab5d chore: Upload virus total checker from previous zen repo, b=(no-bug), c=no-component 2025-05-10 18:03:04 +02:00
Mr. M
5c30c83341 chore: Added more checks for restoring previous sessions, b=(no-bug), c=workspaces, tests 2025-05-10 15:50:29 +02:00
Mr. M
d788ac4ad6 style: Fixed compact mode styles for colllapsed toolbar, b=(no-bug), c=compact-mode, folders 2025-05-10 15:09:08 +02:00
Mr. M
826802df21 chore: Cleaned up workflows, b=(no-bug), c=workflows 2025-05-10 15:02:26 +02:00
Mr. M
3b4f96ab2f test: Added tests for https://github.com/zen-browser/desktop/issues/7385, b=(closes #7385), c=tests, vendor 2025-05-10 15:00:22 +02:00
Mr. M
5a59eb6902 test: Added some tests, b=(no-bug), c=tests, workspaces 2025-05-10 14:15:00 +02:00
Mr. M
64293af6f7 fix: Fixed greyed out part of URL sometimes turns back to white incosistently, b=(closes #7315), c=common 2025-05-10 01:13:15 +02:00
Mr. M
8afd08a3d9 fix: Fixed urlbar in double toolbar mode, b=(bug #7385), c=common 2025-05-10 01:01:23 +02:00
Mr. M
6a21a6fdb1 chore: Added some tests for container specific essentials, b=(no-bug), c=tests, workspaces 2025-05-10 00:20:09 +02:00
Mr. M
3e53787a62 fix: Fixed 'show all tabs' button not showing, b=(closes #8188), c=common 2025-05-10 00:19:55 +02:00
mr. m
9823353d8b Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2025-05-09 23:33:10 +02:00
mr. m
d189221f10 fix: Fixed toast notifications appearing offscreen, b=(no-bug), c=workspaces 2025-05-09 23:33:04 +02:00
Mr. M
271fa03cfc fix: Fixed restoring previous session with replace newtab enabled, b=(no-bug), c=workspaces 2025-05-09 23:05:38 +02:00
mr. m
1fc2299801 fix: Fixed workspace tests having an extra tab, b=(no-bug), c=common, compact-mode, workspaces, tests 2025-05-09 19:29:53 +02:00
mr. m
7df278f7ed Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2025-05-09 18:32:12 +02:00
mr. m
2f68f77f87 feat: Added better toast management, b=(no-bug), c=common, compact-mode 2025-05-09 18:32:03 +02:00
Mr. M
49a3974b34 chore: Added more tests and debug points for twilight, b=(no-bug), c=common, workspaces, tests 2025-05-09 17:42:38 +02:00
mr. m
7a00f3c67c feat: Added an option to disable background tab toasts, b=(no-bug), c=common, compact-mode 2025-05-09 08:18:17 +02:00
mr. m
e079732686 fix: Fixed workspace tests not running successfully, b=(no-bug), c=no-component 2025-05-08 20:02:42 +02:00
mr. m
71f2680eef style: Added support for scrolling on private browsing mode, b=(no-bug), c=tabs 2025-05-08 17:03:48 +02:00
mr. m
808a376c65 feat: Disable search suggestions by default, b=(no-bug), c=no-component 2025-05-08 16:32:33 +02:00
mr. m
eff7cfc5fe fix: Fixed the window always closing with last tab, b=(no-bug), c=workspaces 2025-05-08 14:40:05 +02:00
mr. m
bbb6ba4078 style: Fixed essentials width on compact mode, b=(no-bug), c=tabs 2025-05-08 14:14:41 +02:00
mr. m
c10131aca8 fix: Fixed startup tabs being an index behind, b=(no-bug), c=workspaces 2025-05-08 13:46:04 +02:00
mr. m
49159a6d5c fix: Fixed toasts not showing on right side tabs, b=(closes #8143), c=common 2025-05-08 13:45:20 +02:00
mr. m
d80ba6b058 fix: Fixed tabs not loading at startup, b=(closes #8147), c=workspaces 2025-05-08 12:54:21 +02:00
mr. m
f2e188a86c fix: Fixed pinned tabs not being able to reset, b=(no-bug), c=tabs, workspaces 2025-05-08 12:34:41 +02:00
mr. m
2f03446c37 fix: Fixed foreground tabs showing the toast, b=(closes #8146), c=compact-mode 2025-05-08 12:29:35 +02:00
143 changed files with 35197 additions and 1768 deletions

2
.gitattributes vendored
View File

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

View File

@@ -475,7 +475,18 @@ jobs:
if: ${{ inputs.create_release || inputs.update_branch == 'twilight' }}
permissions: write-all
name: Release
needs: [build-data, linux, windows-step-3, check-release, mac-uni, appimage, source, lint, stop-self-hosted]
needs:
[
build-data,
linux,
windows-step-3,
check-release,
mac-uni,
appimage,
source,
lint,
stop-self-hosted,
]
runs-on: ubuntu-latest
environment:
name: ${{ inputs.update_branch == 'release' && 'Deploy-Release' || 'Deploy-Twilight' }}
@@ -490,9 +501,6 @@ jobs:
- name: Download artifact
uses: actions/download-artifact@v4
- name: List
run: find .
- name: Checkout updates repository
uses: actions/checkout@v4
with:

View File

@@ -5,6 +5,9 @@ on:
- cron: '59 4 * * 2'
workflow_dispatch:
permissions:
contents: read
jobs:
check_candidates:
runs-on: ubuntu-latest

View File

@@ -10,6 +10,9 @@ on:
branches:
- dev
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest

View File

@@ -1,4 +1,7 @@
name: Monthly issue metrics
permissions:
contents: write
issues: read
on:
workflow_dispatch:
schedule:
@@ -59,6 +62,6 @@ jobs:
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'Update monthly issue metrics'
commit_message: 'docs: Update monthly issue metrics, b=(no bug), c={docs}'
commit_user_name: Zen Browser Robot
commit_user_email: zen-browser-auto@users.noreply.github.com

View File

@@ -1,4 +1,6 @@
name: macOS Release Build
permissions:
contents: read
on:
workflow_call:

View File

@@ -1,4 +1,6 @@
name: Pull request test
permissions:
contents: read
on:
pull_request:

View File

@@ -1,5 +1,8 @@
name: Windows PGO Builds
permissions:
contents: read
on:
workflow_call:
inputs:

View File

@@ -1,5 +1,8 @@
name: Windows Release Build
permissions:
contents: read
on:
workflow_call:
inputs:

View File

@@ -7,6 +7,6 @@
"useTabs": false,
"jsxSingleQuote": false,
"semi": true,
"printWidth": 128,
"printWidth": 100,
"plugins": ["prettier-plugin-sh"]
}

View File

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

5
SECURITY.md Normal file
View File

@@ -0,0 +1,5 @@
# Security Policy
## Reporting a Vulnerability
Please report security vulnerabilities [here](https://github.com/zen-browser/desktop/security/advisories/new)

View File

@@ -1 +1 @@
8113a66aeeec42dca9739c7b742a3408cb5b7cf7
a7fc259e12695c40d6ae249950f054221fed4f95

View File

@@ -30,8 +30,8 @@ Start-Job -Name "DownloadGitl10n" -ScriptBlock {
Start-Job -Name "SurferInit" -ScriptBlock {
param($PWD)
cd $PWD
surfer -- ci --brand release
npm run import -- --verbose
npm run surfer -- ci --brand release
} -Verbose -ArgumentList $PWD -Debug
echo "Downloading artifacts info"

524
package-lock.json generated
View File

@@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "MPL-2.0",
"dependencies": {
"@zen-browser/surfer": "^1.11.11"
"@zen-browser/surfer": "^1.11.12"
},
"devDependencies": {
"@babel/preset-typescript": "^7.27.0",
@@ -817,14 +817,14 @@
"license": "MIT"
},
"node_modules/@zen-browser/surfer": {
"version": "1.11.11",
"resolved": "https://registry.npmjs.org/@zen-browser/surfer/-/surfer-1.11.11.tgz",
"integrity": "sha512-n5t25jjG77/rg1HETQBloriCc4GVlHaGWDTNdOxU35Y2qqokcSU+3mPP2cy8u/GBfF0AS6YQmCjE2636tbZkRA==",
"version": "1.11.12",
"resolved": "https://registry.npmjs.org/@zen-browser/surfer/-/surfer-1.11.12.tgz",
"integrity": "sha512-wny52xOFvZe5aPXxLVxEcAzDNEiWWoDiCZFlzsNxkyQ5Lw6vzqroMWpjQPJwBRJOc/JssgiXMdd1uwl2LLnovQ==",
"license": "MPL-2.0",
"dependencies": {
"@resvg/resvg-js": "^1.4.0",
"async-icns": "^1.0.2",
"axios": "^0.21.1",
"axios": "^0.30.0",
"chalk": "^4.1.0",
"cli-progress": "^3.9.1",
"commander": "^6.2.1",
@@ -841,7 +841,7 @@
"prompts": "^2.4.1",
"rustic": "^1.2.1",
"semver": "^7.3.7",
"sharp": "^0.30.7",
"sharp": "^0.32.6",
"tiny-glob": "^0.2.9",
"xmlbuilder2": "^3.0.2"
},
@@ -942,13 +942,99 @@
"node": "^12.20.0 || >=14"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"version": "0.30.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.30.0.tgz",
"integrity": "sha512-Z4F3LjCgfjZz8BMYalWdMgAQUnEtKDmpwNHjh/C8pQZWde32TF64cqnSeyL3xD/aTIASRU30RHTNzRiV/NpGMg==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.14.0"
"follow-redirects": "^1.15.4",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/b4a": {
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
"integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==",
"license": "Apache-2.0"
},
"node_modules/bare-events": {
"version": "2.5.4",
"resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz",
"integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==",
"license": "Apache-2.0",
"optional": true
},
"node_modules/bare-fs": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.4.tgz",
"integrity": "sha512-r8+26Voz8dGX3AYpJdFb1ZPaUSM8XOLCZvy+YGpRTmwPHIxA7Z3Jov/oMPtV7hfRQbOnH8qGlLTzQAbgtdNN0Q==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"bare-events": "^2.5.4",
"bare-path": "^3.0.0",
"bare-stream": "^2.6.4"
},
"engines": {
"bare": ">=1.16.0"
},
"peerDependencies": {
"bare-buffer": "*"
},
"peerDependenciesMeta": {
"bare-buffer": {
"optional": true
}
}
},
"node_modules/bare-os": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz",
"integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==",
"license": "Apache-2.0",
"optional": true,
"engines": {
"bare": ">=1.14.0"
}
},
"node_modules/bare-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz",
"integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"bare-os": "^3.0.1"
}
},
"node_modules/bare-stream": {
"version": "2.6.5",
"resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz",
"integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"streamx": "^2.21.0"
},
"peerDependencies": {
"bare-buffer": "*",
"bare-events": "*"
},
"peerDependenciesMeta": {
"bare-buffer": {
"optional": true
},
"bare-events": {
"optional": true
}
}
},
"node_modules/base64-js": {
@@ -1111,6 +1197,19 @@
"integrity": "sha512-LdUw/JMZyKN+EBDbOHqynYtOLXDjgo+uf5vCUhfO5hVsU2chvbqyexizvxUMaU4ipYZy9MiQyIFwMeIgsb6nBA==",
"license": "(MIT OR Apache-2.0)"
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-once-fn": {
"version": "1.0.15",
"resolved": "https://registry.npmjs.org/call-once-fn/-/call-once-fn-1.0.15.tgz",
@@ -1282,6 +1381,18 @@
"dev": true,
"license": "MIT"
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
@@ -1384,15 +1495,38 @@
"node": ">=4.0.0"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/detect-libc": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
"integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/duplexify": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz",
@@ -1455,6 +1589,51 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -1577,6 +1756,12 @@
}
}
},
"node_modules/fast-fifo": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
"integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
"license": "MIT"
},
"node_modules/fifo": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/fifo/-/fifo-2.4.1.tgz",
@@ -1640,6 +1825,21 @@
}
}
},
"node_modules/form-data": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/formal-git": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/formal-git/-/formal-git-1.1.5.tgz",
@@ -1671,6 +1871,15 @@
"node": ">=12"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -1704,6 +1913,43 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@@ -1744,6 +1990,18 @@
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
"license": "MIT"
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -1759,12 +2017,51 @@
"node": ">=8"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hash-string": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/hash-string/-/hash-string-1.0.0.tgz",
"integrity": "sha512-dtNNyxXobzHavayZwOwRWhBTqS9GX4jDjIMsGc0fDyaN2A+4zMn5Ua9ODDCggN6w3Spma6mAHL3ImmW3BkWDmQ==",
"license": "ISC"
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/human-signals": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
@@ -2339,6 +2636,15 @@
"yallist": "^3.0.2"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -2359,6 +2665,27 @@
"node": ">=8.6"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
@@ -2477,9 +2804,9 @@
"license": "ISC"
},
"node_modules/node-abi": {
"version": "3.74.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz",
"integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==",
"version": "3.75.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz",
"integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==",
"license": "MIT",
"dependencies": {
"semver": "^7.3.5"
@@ -2489,9 +2816,9 @@
}
},
"node_modules/node-addon-api": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
"integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
"integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
"license": "MIT"
},
"node_modules/node-releases": {
@@ -2666,6 +2993,59 @@
"node": ">=10"
}
},
"node_modules/prebuild-install/node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"license": "MIT",
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"node_modules/prebuild-install/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/prebuild-install/node_modules/tar-fs": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
"integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==",
"license": "MIT",
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.1.4"
}
},
"node_modules/prebuild-install/node_modules/tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"license": "MIT",
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
},
"engines": {
"node": ">=6"
}
},
"node_modules/prettier": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
@@ -2740,6 +3120,12 @@
"node": ">=6"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
"node_modules/pump": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
@@ -2937,9 +3323,9 @@
"license": "MIT"
},
"node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -2965,23 +3351,23 @@
}
},
"node_modules/sharp": {
"version": "0.30.7",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.30.7.tgz",
"integrity": "sha512-G+MY2YW33jgflKPTXXptVO28HvNOo9G3j0MybYAHeEmby+QuD2U98dT6ueht9cv/XDqZspSpIhoSW+BAKJ7Hig==",
"version": "0.32.6",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz",
"integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"color": "^4.2.3",
"detect-libc": "^2.0.1",
"node-addon-api": "^5.0.0",
"detect-libc": "^2.0.2",
"node-addon-api": "^6.1.0",
"prebuild-install": "^7.1.1",
"semver": "^7.3.7",
"semver": "^7.5.4",
"simple-get": "^4.0.1",
"tar-fs": "^2.1.1",
"tar-fs": "^3.0.4",
"tunnel-agent": "^0.6.0"
},
"engines": {
"node": ">=12.13.0"
"node": ">=14.15.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
@@ -3152,6 +3538,19 @@
"integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==",
"license": "MIT"
},
"node_modules/streamx": {
"version": "2.22.0",
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz",
"integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==",
"license": "MIT",
"dependencies": {
"fast-fifo": "^1.3.2",
"text-decoder": "^1.1.0"
},
"optionalDependencies": {
"bare-events": "^2.2.0"
}
},
"node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -3268,15 +3667,17 @@
}
},
"node_modules/tar-fs": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
"integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==",
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.8.tgz",
"integrity": "sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==",
"license": "MIT",
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.1.4"
"tar-stream": "^3.1.5"
},
"optionalDependencies": {
"bare-fs": "^4.0.1",
"bare-path": "^3.0.0"
}
},
"node_modules/tar-iterator": {
@@ -3299,19 +3700,14 @@
}
},
"node_modules/tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
"integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
"license": "MIT",
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
},
"engines": {
"node": ">=6"
"b4a": "^1.6.4",
"fast-fifo": "^1.2.0",
"streamx": "^2.15.0"
}
},
"node_modules/tar-stream-compat": {
@@ -3341,31 +3737,6 @@
"safe-buffer": "^5.1.1"
}
},
"node_modules/tar-stream/node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"license": "MIT",
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"node_modules/tar-stream/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/temp-suffix": {
"version": "0.1.14",
"resolved": "https://registry.npmjs.org/temp-suffix/-/temp-suffix-0.1.14.tgz",
@@ -3378,6 +3749,15 @@
"node": ">=0.8"
}
},
"node_modules/text-decoder": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
"integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==",
"license": "Apache-2.0",
"dependencies": {
"b4a": "^1.6.4"
}
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",

View File

@@ -40,7 +40,7 @@
},
"homepage": "https://github.com/zen-browser/desktop#readme",
"dependencies": {
"@zen-browser/surfer": "^1.11.11"
"@zen-browser/surfer": "^1.11.12"
},
"devDependencies": {
"@babel/preset-typescript": "^7.27.0",

View File

@@ -38,7 +38,7 @@ def get_rc_response() -> Optional[str]:
for tag_dict in data["tags"]:
tag = tag_dict["tag"]
if (tag.startswith("FIREFOX") and tag.endswith("_BUILD1")
and "ESR" not in tag and "b" not in tag):
and "ESR" not in tag and "b" not in tag and "ANDROID" not in tag):
return (tag.replace("FIREFOX_", "").replace("_BUILD1",
"").replace("_", "."))
except (FileNotFoundError, json.JSONDecodeError) as e:

View File

@@ -35,7 +35,9 @@ pref('browser.download.open_pdf_attachments_inline', true);
pref('browser.download.alwaysOpenPanel', false);
// Updates
#ifdef MOZILLA_OFFICIAL
pref("app.update.checkInstallTime.days", 6);
#endif
#include fullscreen.inc
#include ai.inc

View File

@@ -8,3 +8,4 @@ pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons", false);
pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features", false);
pref("browser.preferences.moreFromMozilla", false, locked);
pref("browser.aboutwelcome.enabled", false);
pref("browser.contentblocking.report.show_mobile_app", false, locked);

View File

@@ -19,6 +19,9 @@ pref('zen.view.show-newtab-button-top', true);
pref('zen.mediacontrols.enabled', true);
// Exposure:
pref('zen.haptic-feedback.enabled', true);
#ifdef MOZILLA_OFFICIAL
pref('zen.rice.api.url', 'https://share.zen-browser.app', locked);
pref('zen.injections.match-urls', 'https://zen-browser.app/*,https://share.zen-browser.app/*', locked);
@@ -34,6 +37,12 @@ pref('zen.theme.border-radius', 10); // In pixels
pref('zen.theme.border-radius', 8); // In pixels
#endif
#ifdef XP_MACOSX
pref('zen.theme.acrylic-elements', false);
#else
pref('zen.theme.acrylic-elements', false);
#endif
pref('zen.theme.color-prefs.use-workspace-colors', true);
pref('zen.view.compact.hide-tabbar', true);
@@ -45,6 +54,7 @@ pref('zen.view.compact.color-toolbar', true);
pref('zen.view.compact.color-sidebar', true);
pref('zen.view.compact.animate-sidebar', true);
pref('zen.view.compact.show-sidebar-and-toolbar-on-hover', true);
pref('zen.view.compact.show-background-tab-toast', true);
pref('zen.urlbar.replace-newtab', true);
pref('zen.urlbar.show-protections-icon', false);
@@ -54,10 +64,11 @@ pref('zen.urlbar.show-domain-only-in-sidebar', true);
pref('zen.urlbar.hide-one-offs', true);
pref('zen.urlbar.enable-overrides', false);
// Exoerimental: Apply a blend mode to the websites so they can render rounded corners
// IMPORTANT: Remove once firefox 139 is released
#ifdef XP_MACOSX
// Disable for macos in the meantime until @HarryHeres finds a solution for hight DPI screens
pref('zen.view.experimental-rounded-view', false);
#else
#else
pref('zen.view.experimental-rounded-view', true);
#endif
@@ -125,6 +136,12 @@ pref('zen.workspaces.scroll-modifier-key','ctrl'); // can be ctrl, alt, shift, o
pref('services.sync.engine.workspaces', false);
pref('zen.workspaces.container-specific-essentials-enabled', false);
#ifdef MOZILLA_OFFICIAL
pref('zen.workspaces.debug', false);
#else
pref('zen.workspaces.debug', true);
#endif
// Zen Split View
pref('zen.splitView.enable-tab-drop', true);
pref('zen.splitView.min-resize-width', 7);

View File

@@ -19,7 +19,7 @@ pref("browser.ping-centre.telemetry", false);
pref("browser.attribution.enabled", false);
pref("toolkit.telemetry.pioneer-new-studies-available", false);
pref("app.shield.optoutstudies.enabled", false, locked);
pref("app.normandy.enabled", false, locked);
pref("app.normandy.enabled", false);
pref("app.normandy.api_url", "", locked);
// Crash reports

View File

@@ -12,6 +12,10 @@ pref("browser.urlbar.untrimOnUserInteraction.featureGate", true);
// Keep in sync with browser/components/topsites/constants.mjs
pref("browser.urlbar.maxRichResults", 7);
// Enable private suggestions
pref('browser.search.suggest.enabled', false);
pref('browser.search.suggest.enabled.private', false);
pref("browser.urlbar.trimHttps", true);
pref("browser.search.separatePrivateDefault.ui.enabled", true);
pref("browser.urlbar.update2.engineAliasRefresh", true);

View File

@@ -1,15 +0,0 @@
diff --git a/browser/base/content/appmenu-viewcache.inc.xhtml b/browser/base/content/appmenu-viewcache.inc.xhtml
index 3c5c4f29b1de25a4ce17089502f2251a27e5c7f5..dfa3260ed3c2bb6067745696fbf103c7e56c639a 100644
--- a/browser/base/content/appmenu-viewcache.inc.xhtml
+++ b/browser/base/content/appmenu-viewcache.inc.xhtml
@@ -421,6 +421,10 @@
class="subviewbutton"
data-l10n-id="appmenu-customizetoolbar"
command="cmd_CustomizeToolbars"/>
+ <toolbarbutton id="appmenu-zen-share-rice"
+ class="subviewbutton"
+ data-l10n-id="appmenu-zen-share-rice"
+ oncommand="gZenThemePicker.shareTheme()" />
<toolbarseparator/>
<html:h2 id="appmenu-developer-tools"
data-l10n-id="appmenu-developer-tools-subheader"

View File

@@ -1,5 +1,5 @@
diff --git a/browser/base/content/browser.xhtml b/browser/base/content/browser.xhtml
index 51a25aaa5558e6e17246d54a7ed95d5ddf3ecdab..b49984c8711fc9f5f19f0cf6ecca07a8cca0d125 100644
index 51a25aaa5558e6e17246d54a7ed95d5ddf3ecdab..08809c25c01d159a9903f1921936b178d51f9875 100644
--- a/browser/base/content/browser.xhtml
+++ b/browser/base/content/browser.xhtml
@@ -26,6 +26,7 @@
@@ -22,12 +22,11 @@ index 51a25aaa5558e6e17246d54a7ed95d5ddf3ecdab..b49984c8711fc9f5f19f0cf6ecca07a8
</head>
<html:body xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
# All sets except for popupsets (commands, keys, and stringbundles)
@@ -127,9 +131,12 @@
@@ -127,9 +131,11 @@
</vbox>
</html:template>
+<hbox id="zen-main-app-wrapper" flex="1" persist="zen-compact-mode">
+ <vbox id="zen-toast-container"></vbox>
#include navigator-toolbox.inc.xhtml
#include browser-box.inc.xhtml

View File

@@ -8,6 +8,6 @@
skipintoolbarset="true"
context="toolbar-context-menu"
mode="icons">
<toolbarbutton removable="true" class="chromeclass-toolbar-additional toolbarbutton-1 zen-sidebar-action-button" id="zen-expand-sidebar-button" command="cmd_zenToggleSidebar" data-l10n-id="sidebar-zen-expand" cui-areatype="toolbar"></toolbarbutton>
<toolbarbutton removable="true" class="chromeclass-toolbar-additional toolbarbutton-1 zen-sidebar-action-button" id="zen-expand-sidebar-button" command="cmd_zenToggleSidebar" data-l10n-id="sidebar-zen-expand"></toolbarbutton>
<toolbarbutton id="zen-workspaces-button" class="chromeclass-toolbar-additional" overflows="false" removable="false"></toolbarbutton>
</toolbar>

View File

@@ -1,2 +1,4 @@
<vbox id="zen-toast-container"></vbox>
#include ../../../zen/split-view/zen-splitview-overlay.inc.xhtml
#include ../../../zen/glance/zen-glance.inc.xhtml

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/customizableui/CustomizableUI.sys.mjs b/browser/components/customizableui/CustomizableUI.sys.mjs
index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee888a3f78 100644
index 91088fab1759b9af908912648d28daa5938a29c9..d420e7a2b1d66ad2bd7699cc580e180ab45a793d 100644
--- a/browser/components/customizableui/CustomizableUI.sys.mjs
+++ b/browser/components/customizableui/CustomizableUI.sys.mjs
@@ -13,6 +13,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
@@ -32,15 +32,16 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
this.registerArea(
CustomizableUI.AREA_NAVBAR,
{
@@ -352,7 +347,6 @@ var CustomizableUIInternal = {
@@ -352,8 +347,6 @@ var CustomizableUIInternal = {
overflowable: true,
defaultPlacements: navbarPlacements,
verticalTabsDefaultPlacements: [
- "firefox-view-button",
"alltabs-button",
- "alltabs-button",
],
defaultCollapsed: false,
@@ -377,10 +371,7 @@ var CustomizableUIInternal = {
},
@@ -377,10 +370,7 @@ var CustomizableUIInternal = {
{
type: CustomizableUI.TYPE_TOOLBAR,
defaultPlacements: [
@@ -51,7 +52,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
],
verticalTabsDefaultPlacements: [],
defaultCollapsed: null,
@@ -462,6 +453,7 @@ var CustomizableUIInternal = {
@@ -462,6 +452,7 @@ var CustomizableUIInternal = {
CustomizableUI.AREA_NAVBAR,
CustomizableUI.AREA_BOOKMARKS,
CustomizableUI.AREA_TABSTRIP,
@@ -59,7 +60,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
]);
if (AppConstants.platform != "macosx") {
toolbars.add(CustomizableUI.AREA_MENUBAR);
@@ -1262,6 +1254,9 @@ var CustomizableUIInternal = {
@@ -1262,6 +1253,9 @@ var CustomizableUIInternal = {
placements = gPlacements.get(area);
}
@@ -69,7 +70,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
// For toolbars that need it, mark as dirty.
let defaultPlacements = areaProperties.get("defaultPlacements");
if (
@@ -1769,7 +1764,7 @@ var CustomizableUIInternal = {
@@ -1769,7 +1763,7 @@ var CustomizableUIInternal = {
lazy.log.info(
"Widget " + aWidgetId + " not found, unable to remove from " + aArea
);
@@ -78,7 +79,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
}
this.notifyDOMChange(widgetNode, null, container, true, () => {
@@ -1779,7 +1774,7 @@ var CustomizableUIInternal = {
@@ -1779,7 +1773,7 @@ var CustomizableUIInternal = {
// We also need to remove the panel context menu if it's there:
this.ensureButtonContextMenu(widgetNode);
if (gPalette.has(aWidgetId) || this.isSpecialWidget(aWidgetId)) {
@@ -87,7 +88,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
} else {
window.gNavToolbox.palette.appendChild(widgetNode);
}
@@ -1947,16 +1942,16 @@ var CustomizableUIInternal = {
@@ -1947,16 +1941,16 @@ var CustomizableUIInternal = {
elem.setAttribute("skipintoolbarset", "true");
}
}
@@ -107,7 +108,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
// Handle initial state of vertical tabs.
if (isVerticalTabs) {
// Show the vertical tabs toolbar
@@ -2198,6 +2193,10 @@ var CustomizableUIInternal = {
@@ -2198,6 +2192,10 @@ var CustomizableUIInternal = {
* The identifier string of the area that aNode is being inserted into.
*/
insertWidgetBefore(aNode, aNextNode, aContainer, aAreaId) {
@@ -118,7 +119,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
this.notifyDOMChange(aNode, aNextNode, aContainer, false, () => {
this.setLocationAttributes(aNode, aAreaId);
aContainer.insertBefore(aNode, aNextNode);
@@ -3321,7 +3320,6 @@ var CustomizableUIInternal = {
@@ -3321,7 +3319,6 @@ var CustomizableUIInternal = {
if (!this.isWidgetRemovable(aWidgetId)) {
return;
}
@@ -126,7 +127,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
let placements = gPlacements.get(oldPlacement.area);
let position = placements.indexOf(aWidgetId);
if (position != -1) {
@@ -4556,7 +4554,7 @@ var CustomizableUIInternal = {
@@ -4556,7 +4553,7 @@ var CustomizableUIInternal = {
* For all registered areas, builds those areas to reflect the current
* placement state of all widgets.
*/
@@ -135,7 +136,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
for (let [areaId, areaNodes] of gBuildAreas) {
let placements = gPlacements.get(areaId);
let isFirstChangedToolbar = true;
@@ -4567,7 +4565,7 @@ var CustomizableUIInternal = {
@@ -4567,7 +4564,7 @@ var CustomizableUIInternal = {
if (area.get("type") == CustomizableUI.TYPE_TOOLBAR) {
let defaultCollapsed = area.get("defaultCollapsed");
let win = areaNode.ownerGlobal;
@@ -144,7 +145,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
win.setToolbarVisibility(
areaNode,
typeof defaultCollapsed == "string"
@@ -5858,6 +5856,7 @@ export var CustomizableUI = {
@@ -5858,6 +5855,7 @@ export var CustomizableUI = {
unregisterArea(aName, aDestroyPlacements) {
CustomizableUIInternal.unregisterArea(aName, aDestroyPlacements);
},
@@ -152,7 +153,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
/**
* Add a widget to an area.
* If the area to which you try to add is not known to CustomizableUI,
@@ -7905,11 +7904,11 @@ class OverflowableToolbar {
@@ -7905,11 +7903,11 @@ class OverflowableToolbar {
parseFloat(style.paddingLeft) -
parseFloat(style.paddingRight) -
toolbarChildrenWidth;
@@ -166,7 +167,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
});
lazy.log.debug(
@@ -7919,7 +7918,8 @@ class OverflowableToolbar {
@@ -7919,7 +7917,8 @@ class OverflowableToolbar {
// If the target has min-width: 0, their children might actually overflow
// it, so check for both cases explicitly.
let targetContentWidth = Math.max(targetWidth, targetChildrenWidth);
@@ -176,7 +177,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
return { isOverflowing, targetContentWidth, totalAvailWidth };
}
@@ -8013,7 +8013,7 @@ class OverflowableToolbar {
@@ -8013,7 +8012,7 @@ class OverflowableToolbar {
}
}
if (!inserted) {
@@ -185,7 +186,7 @@ index 91088fab1759b9af908912648d28daa5938a29c9..52d348342c110dfae47a0d83b30b75ee
}
child.removeAttribute("cui-anchorid");
child.removeAttribute("overflowedItem");
@@ -8358,7 +8358,7 @@ class OverflowableToolbar {
@@ -8358,7 +8357,7 @@ class OverflowableToolbar {
break;
}
case "mousedown": {

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/extensions/parent/ext-tabs.js b/browser/components/extensions/parent/ext-tabs.js
index b47f0510e32d788dfe7c3109474c4512c9900d4a..49697125a2998bbd50d87c54e2c5974baaf9a7e2 100644
index 517ea0079c12941a844a4f9e4ba694c6411887ee..510ab14dfa2178c332c9862d6a01b75bd12dfe3b 100644
--- a/browser/components/extensions/parent/ext-tabs.js
+++ b/browser/components/extensions/parent/ext-tabs.js
@@ -468,6 +468,7 @@ this.tabs = class extends ExtensionAPIPersistent {
@@ -482,6 +482,7 @@ this.tabs = class extends ExtensionAPIPersistent {
}
let tab = tabManager.getWrapper(event.originalTarget);
@@ -10,3 +10,11 @@ index b47f0510e32d788dfe7c3109474c4512c9900d4a..49697125a2998bbd50d87c54e2c5974b
let changeInfo = {};
for (let prop of needed) {
@@ -836,6 +837,7 @@ this.tabs = class extends ExtensionAPIPersistent {
});
}
+ window.gZenCompactModeManager._nextTimeWillBeActive = active;
let nativeTab = window.gBrowser.addTab(url, options);
if (active) {

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/places/PlacesUIUtils.sys.mjs b/browser/components/places/PlacesUIUtils.sys.mjs
index 1f5e163bae58f3f1cac750ca32846cc8a80bd2ca..16034842b4ca5295aa3c9237db55035ecc4016d2 100644
index 1f5e163bae58f3f1cac750ca32846cc8a80bd2ca..028b899b7a5da7ba398965861ff044e596c27666 100644
--- a/browser/components/places/PlacesUIUtils.sys.mjs
+++ b/browser/components/places/PlacesUIUtils.sys.mjs
@@ -59,6 +59,7 @@ class BookmarkState {
@@ -157,20 +157,12 @@ index 1f5e163bae58f3f1cac750ca32846cc8a80bd2ca..16034842b4ca5295aa3c9237db55035e
/**
* Append transactions to update tags by given information.
*
@@ -903,8 +1012,15 @@ export var PlacesUIUtils = {
@@ -903,7 +1012,7 @@ export var PlacesUIUtils = {
aNode,
aWhere,
aWindow,
- { aPrivate = false, userContextId = 0 } = {}
+ { aPrivate = false, userContextId = undefined } = {}
) {
+ if (typeof userContextId == "undefined") {
+ try {
+ let browserWindow = getBrowserWindow(aWindow);
+ userContextId = browserWindow.ZenWorkspaces.getDefaultContainer();
+ } catch {}
+ }
+
if (
aNode &&
lazy.PlacesUtils.nodeIsURI(aNode) &&

View File

@@ -80,17 +80,24 @@ var gZenMarketplaceManager = {
const browser = ZenThemesCommon.currentBrowser;
const mozToggle = document.createElement('moz-toggle');
mozToggle.className = 'zenThemeMarketplaceItemPreferenceToggle zenThemeMarketplaceDisableAllToggle';
mozToggle.className =
'zenThemeMarketplaceItemPreferenceToggle zenThemeMarketplaceDisableAllToggle';
mozToggle.pressed = !areThemesDisabled;
browser.document.l10n.setAttributes(mozToggle, `zen-theme-disable-all-${!areThemesDisabled ? 'enabled' : 'disabled'}`);
browser.document.l10n.setAttributes(
mozToggle,
`zen-theme-disable-all-${!areThemesDisabled ? 'enabled' : 'disabled'}`
);
mozToggle.addEventListener('toggle', async (event) => {
const { pressed = false } = event.target || {};
this.themesList.style.display = pressed ? '' : 'none';
Services.prefs.setBoolPref('zen.themes.disable-all', !pressed);
browser.document.l10n.setAttributes(mozToggle, `zen-theme-disable-all-${pressed ? 'enabled' : 'disabled'}`);
browser.document.l10n.setAttributes(
mozToggle,
`zen-theme-disable-all-${pressed ? 'enabled' : 'disabled'}`
);
});
if (areThemesDisabled) {
@@ -101,7 +108,6 @@ var gZenMarketplaceManager = {
},
async observe() {
ZenThemesCommon.resetThemesCache();
await this._buildThemesList();
},
@@ -269,7 +275,7 @@ var gZenMarketplaceManager = {
const themeList = document.createElement('div');
for (const theme of Object.values(themes).sort((a, b) => a.name.localeCompare(b.name))) {
const sanitizedName = `theme-${theme.name?.replaceAll(/\s/g, '-')?.replaceAll(/[^A-z_-]+/g, '')}`;
const sanitizedName = `theme-${theme.name?.replaceAll(/\s/g, '-')?.replaceAll(/[^A-Za-z_-]+/g, '')}`;
const isThemeEnabled = theme.enabled === undefined || theme.enabled;
const fragment = window.MozXULElement.parseXULToFragment(`
<vbox class="zenThemeMarketplaceItem">
@@ -343,18 +349,28 @@ var gZenMarketplaceManager = {
if (!event.target.hasAttribute('pressed')) {
await this.disableTheme(themeId);
browser.document.l10n.setAttributes(mozToggle, 'zen-theme-marketplace-toggle-disabled-button');
browser.document.l10n.setAttributes(
mozToggle,
'zen-theme-marketplace-toggle-disabled-button'
);
if (theme.preferences) {
document.getElementById(`zenThemeMarketplaceItemConfigureButton-${sanitizedName}`).setAttribute('hidden', true);
document
.getElementById(`zenThemeMarketplaceItemConfigureButton-${sanitizedName}`)
.setAttribute('hidden', true);
}
} else {
await this.enableTheme(themeId);
browser.document.l10n.setAttributes(mozToggle, 'zen-theme-marketplace-toggle-enabled-button');
browser.document.l10n.setAttributes(
mozToggle,
'zen-theme-marketplace-toggle-enabled-button'
);
if (theme.preferences) {
document.getElementById(`zenThemeMarketplaceItemConfigureButton-${sanitizedName}`).removeAttribute('hidden');
document
.getElementById(`zenThemeMarketplaceItemConfigureButton-${sanitizedName}`)
.removeAttribute('hidden');
}
}
setTimeout(() => {
@@ -365,15 +381,19 @@ var gZenMarketplaceManager = {
fragment.querySelector('.zenThemeMarketplaceItemTitle').textContent = themeName;
fragment.querySelector('.zenThemeMarketplaceItemDescription').textContent = theme.description;
fragment.querySelector('.zenThemeMarketplaceItemUninstallButton').addEventListener('click', async (event) => {
const [msg] = await document.l10n.formatValues([{ id: 'zen-theme-marketplace-remove-confirmation' }]);
fragment
.querySelector('.zenThemeMarketplaceItemUninstallButton')
.addEventListener('click', async (event) => {
const [msg] = await document.l10n.formatValues([
{ id: 'zen-theme-marketplace-remove-confirmation' },
]);
if (!confirm(msg)) {
return;
}
if (!confirm(msg)) {
return;
}
await this.removeTheme(event.target.getAttribute('zen-theme-id'));
});
await this.removeTheme(event.target.getAttribute('zen-theme-id'));
});
if (theme.homepage) {
const homepageButton = fragment.querySelector('.zenThemeMarketplaceItemHomepageButton');
@@ -386,12 +406,16 @@ var gZenMarketplaceManager = {
}
if (theme.preferences) {
fragment.querySelector('.zenThemeMarketplaceItemConfigureButton').addEventListener('click', () => {
dialog.showModal();
});
fragment
.querySelector('.zenThemeMarketplaceItemConfigureButton')
.addEventListener('click', () => {
dialog.showModal();
});
if (isThemeEnabled) {
fragment.querySelector('.zenThemeMarketplaceItemConfigureButton').removeAttribute('hidden');
fragment
.querySelector('.zenThemeMarketplaceItemConfigureButton')
.removeAttribute('hidden');
}
}
@@ -432,7 +456,10 @@ var gZenMarketplaceManager = {
if (placeholder) {
defaultItem.setAttribute('label', placeholder || '-');
} else {
browser.document.l10n.setAttributes(defaultItem, 'zen-theme-marketplace-dropdown-default-label');
browser.document.l10n.setAttributes(
defaultItem,
'zen-theme-marketplace-dropdown-default-label'
);
}
menupopup.appendChild(defaultItem);
@@ -500,7 +527,9 @@ var gZenMarketplaceManager = {
</hbox>
`);
const checkboxElement = checkbox.querySelector('.zenThemeMarketplaceItemPreferenceCheckbox');
const checkboxElement = checkbox.querySelector(
'.zenThemeMarketplaceItemPreferenceCheckbox'
);
checkboxElement.setAttribute('label', label);
checkboxElement.setAttribute('tooltiptext', property);
checkboxElement.setAttribute('zen-pref', property);
@@ -546,7 +575,10 @@ var gZenMarketplaceManager = {
if (placeholder) {
input.setAttribute('placeholder', placeholder || '-');
} else {
browser.document.l10n.setAttributes(input, 'zen-theme-marketplace-input-default-placeholder');
browser.document.l10n.setAttributes(
input,
'zen-theme-marketplace-input-default-placeholder'
);
}
input.addEventListener(
@@ -558,9 +590,13 @@ var gZenMarketplaceManager = {
this._triggerBuildUpdateWithoutRebuild();
if (value === '') {
browser.document.querySelector(':root').style.removeProperty(`--${sanitizedProperty}`);
browser.document
.querySelector(':root')
.style.removeProperty(`--${sanitizedProperty}`);
} else {
browser.document.querySelector(':root').style.setProperty(`--${sanitizedProperty}`, value);
browser.document
.querySelector(':root')
.style.setProperty(`--${sanitizedProperty}`, value);
}
}, 500)
);
@@ -630,7 +666,11 @@ var gZenLooksAndFeel = {
layout.classList.remove('selected');
if (layout.getAttribute('layout') == 'single' && isSingleToolbar) {
layout.classList.add('selected');
} else if (layout.getAttribute('layout') == 'multiple' && !isSingleToolbar && isExtendedSidebar) {
} else if (
layout.getAttribute('layout') == 'multiple' &&
!isSingleToolbar &&
isExtendedSidebar
) {
layout.classList.add('selected');
} else if (layout.getAttribute('layout') == 'collapsed' && !isExtendedSidebar) {
layout.classList.add('selected');
@@ -650,7 +690,10 @@ var gZenLooksAndFeel = {
layout.classList.add('selected');
Services.prefs.setBoolPref(kZenExtendedSidebar, layout.getAttribute('layout') != 'collapsed');
Services.prefs.setBoolPref(
kZenExtendedSidebar,
layout.getAttribute('layout') != 'collapsed'
);
Services.prefs.setBoolPref(kZenSingleToolbar, layout.getAttribute('layout') == 'single');
});
}
@@ -734,13 +777,19 @@ var gZenWorkspacesSettings = {
};
Services.prefs.addObserver('zen.tab-unloader.enabled', tabsUnloaderPrefListener);
Services.prefs.addObserver('zen.glance.enabled', tabsUnloaderPrefListener); // We can use the same listener for both prefs
Services.prefs.addObserver('zen.workspaces.container-specific-essentials-enabled', tabsUnloaderPrefListener);
Services.prefs.addObserver(
'zen.workspaces.container-specific-essentials-enabled',
tabsUnloaderPrefListener
);
Services.prefs.addObserver('zen.glance.activation-method', tabsUnloaderPrefListener);
window.addEventListener('unload', () => {
Services.prefs.removeObserver('zen.tab-unloader.enabled', tabsUnloaderPrefListener);
Services.prefs.removeObserver('zen.glance.enabled', tabsUnloaderPrefListener);
Services.prefs.removeObserver('zen.glance.activation-method', tabsUnloaderPrefListener);
Services.prefs.removeObserver('zen.workspaces.container-specific-essentials-enabled', tabsUnloaderPrefListener);
Services.prefs.removeObserver(
'zen.workspaces.container-specific-essentials-enabled',
tabsUnloaderPrefListener
);
});
},
};
@@ -800,7 +849,10 @@ var zenMissingKeyboardShortcutL10n = {
key_accessibility: 'zen-devtools-toggle-accessibility-shortcut',
};
var zenIgnoreKeyboardShortcutL10n = ['zen-full-zoom-reduce-shortcut-alt-b', 'zen-full-zoom-reduce-shortcut-alt-a'];
var zenIgnoreKeyboardShortcutL10n = [
'zen-full-zoom-reduce-shortcut-alt-b',
'zen-full-zoom-reduce-shortcut-alt-a',
];
var gZenCKSSettings = {
async init() {
@@ -928,6 +980,9 @@ var gZenCKSSettings = {
sibling.remove();
}
}
if (target.classList.contains(`${ZEN_CKS_INPUT_FIELD_CLASS}-not-set`)) {
target.label = 'Not set';
}
});
const groupElem = wrapper.querySelector(`[data-group="${ZEN_CKS_GROUP_PREFIX}-${group}"]`);
@@ -964,8 +1019,16 @@ var gZenCKSSettings = {
event.preventDefault();
let input = document.querySelector(`.${ZEN_CKS_INPUT_FIELD_CLASS}[${KEYBIND_ATTRIBUTE_KEY}="${this._currentActionID}"]`);
const modifiers = new KeyShortcutModifiers(event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, false);
let input = document.querySelector(
`.${ZEN_CKS_INPUT_FIELD_CLASS}[${KEYBIND_ATTRIBUTE_KEY}="${this._currentActionID}"]`
);
const modifiers = new KeyShortcutModifiers(
event.ctrlKey,
event.altKey,
event.shiftKey,
event.metaKey,
false
);
const modifiersActive = modifiers.areAnyActive();
input.classList.remove(`${ZEN_CKS_INPUT_FIELD_CLASS}-not-set`);
@@ -977,6 +1040,7 @@ var gZenCKSSettings = {
shortcut = shortcut.replace(/Ctrl|Control|Shift|Alt|Option|Cmd|Meta/, ''); // Remove all modifiers
if (shortcut == 'Tab' && !modifiersActive) {
input.classList.remove(`${ZEN_CKS_INPUT_FIELD_CLASS}-not-set`);
input.classList.remove(`${ZEN_CKS_INPUT_FIELD_CLASS}-editing`);
this._latestValidKey = null;
return;
@@ -1004,6 +1068,9 @@ var gZenCKSSettings = {
input.classList.remove(`${ZEN_CKS_INPUT_FIELD_CLASS}-editing`);
this._editDone(this._latestValidKey, this._latestModifier);
if (this.name == 'Not set') {
input.classList.add(`${ZEN_CKS_INPUT_FIELD_CLASS}-not-set`);
}
this._latestValidKey = null;
this._latestModifier = null;
input.classList.remove(`${ZEN_CKS_INPUT_FIELD_CLASS}-invalid`);
@@ -1025,6 +1092,10 @@ var gZenCKSSettings = {
this._latestValidKey = null;
this._latestModifier = null;
this._hasSafed = true;
const sibling = input.nextElementSibling;
if (sibling && sibling.classList.contains(`${ZEN_CKS_CLASS_BASE}-conflict`)) {
sibling.remove();
}
return;
}

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a5d0924e5 100644
index 6dece2b9d0462d90a28e75350ce983d87816ef73..e54e815b04c311464ed53364007d99bb6c1a0cf3 100644
--- a/browser/components/tabbrowser/content/tabbrowser.js
+++ b/browser/components/tabbrowser/content/tabbrowser.js
@@ -415,11 +415,45 @@
@@ -232,17 +232,20 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
}));
if (focusUrlBar) {
@@ -2898,6 +2966,9 @@
@@ -2898,6 +2966,12 @@
}
}
+ if (typeof window.gZenVerticalTabsManager !== "undefined") {
+ gZenVerticalTabsManager.animateTab(t);
+ }
+ if (typeof window.gZenCompactModeManager !== "undefined" && !skipLoad && insertTab) {
+ gZenCompactModeManager._onTabOpen(t, inBackground);
+ }
// Additionally send pinned tab events
if (pinned) {
this._notifyPinnedStatus(t);
@@ -2945,12 +3016,15 @@
@@ -2945,12 +3019,15 @@
* @param {string} [label=]
* @returns {MozTabbrowserTabGroup}
*/
@@ -259,7 +262,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
return group;
}
@@ -2993,6 +3067,7 @@
@@ -2993,6 +3070,7 @@
insertBefore = null,
isUserTriggered = false,
telemetryUserCreateSource = "unknown",
@@ -267,7 +270,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
} = {}
) {
if (!tabs?.length) {
@@ -3011,7 +3086,12 @@
@@ -3011,7 +3089,12 @@
id = `${Date.now()}-${Math.round(Math.random() * 100)}`;
}
let group = this._createTabGroup(id, color, false, label);
@@ -281,7 +284,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
group,
insertBefore?.group ?? insertBefore
);
@@ -3342,6 +3422,7 @@
@@ -3342,6 +3425,7 @@
openWindowInfo,
skipLoad,
triggeringRemoteType,
@@ -289,7 +292,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
}
) {
// If we don't have a preferred remote type (or it is `NOT_REMOTE`), and
@@ -3411,6 +3492,7 @@
@@ -3411,6 +3495,7 @@
openWindowInfo,
name,
skipLoad,
@@ -297,7 +300,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
});
}
@@ -3599,7 +3681,7 @@
@@ -3599,7 +3684,7 @@
// Add a new tab if needed.
if (!tab) {
let createLazyBrowser =
@@ -306,9 +309,11 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
let url = "about:blank";
if (tabData.entries?.length) {
@@ -3638,6 +3720,27 @@
@@ -3637,7 +3722,29 @@
skipLoad: true,
preferredRemoteType,
});
+ tab._originalUrl = url;
+ if (tabData.zenWorkspace) {
+ tab.setAttribute("zen-workspace-id", tabData.zenWorkspace);
@@ -334,7 +339,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
if (select) {
tabToSelect = tab;
}
@@ -3661,7 +3764,8 @@
@@ -3661,7 +3768,8 @@
// needs calling:
shouldUpdateForPinnedTabs = true;
}
@@ -344,7 +349,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
let { groupId } = tabData;
const tabGroup = tabGroupWorkingData.get(groupId);
// if a tab refers to a tab group we don't know, skip any group
@@ -3675,7 +3779,10 @@
@@ -3675,7 +3783,10 @@
tabGroup.stateData.id,
tabGroup.stateData.color,
tabGroup.stateData.collapsed,
@@ -356,21 +361,18 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
);
tabsFragment.appendChild(tabGroup.node);
}
@@ -3723,8 +3830,21 @@
@@ -3723,8 +3834,16 @@
// to remove the old selected tab.
if (tabToSelect) {
let leftoverTab = this.selectedTab;
+ if (gZenVerticalTabsManager._canReplaceNewTab) {
+ ZenWorkspaces._tabToRemoveForEmpty = leftoverTab;
+ if (Services.prefs.getBoolPref("zen.workspaces.continue-where-left-off")) {
+ ZenWorkspaces._tabToSelect = selectTab - 1;
+ }
+ } else {
this.selectedTab = tabToSelect;
this.removeTab(leftoverTab);
+ if (ZenWorkspaces._initialTab) {
+ ZenWorkspaces._initialTab._shouldRemove = true;
+ }
- this.selectedTab = tabToSelect;
- this.removeTab(leftoverTab);
+ ZenWorkspaces._tabToRemoveForEmpty = leftoverTab;
+ if (Services.prefs.getBoolPref("zen.workspaces.continue-where-left-off")) {
+ ZenWorkspaces._tabToSelect = selectTab - 1;
+ }
+ if (ZenWorkspaces._initialTab && !gZenVerticalTabsManager._canReplaceNewTab) {
+ ZenWorkspaces._initialTab._shouldRemove = true;
+ }
+ }
+ else {
@@ -378,16 +380,16 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
}
if (tabs.length > 1 || !tabs[0].selected) {
@@ -3912,7 +4032,7 @@
@@ -3912,7 +4031,7 @@
// Ensure we have an index if one was not provided.
if (typeof index != "number") {
// Move the new tab after another tab if needed, to the end otherwise.
- index = Infinity;
+ index = Services.prefs.getBoolPref("zen.view.show-newtab-button-top") ? this.pinnedTabCount : Infinity;
+ index = Services.prefs.getBoolPref("zen.view.show-newtab-button-top") ? this._numVisiblePinTabsWithoutCollapsed : Infinity;
if (
!bulkOrderedOpen &&
((openerTab &&
@@ -3935,7 +4055,7 @@
@@ -3935,7 +4054,7 @@
) {
index = Infinity;
} else if (previousTab.visible) {
@@ -396,16 +398,17 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
} else if (previousTab == FirefoxViewHandler.tab) {
index = 0;
}
@@ -3958,18 +4078,18 @@
@@ -3958,18 +4077,18 @@
// Ensure index is within bounds.
if (tab.pinned) {
- index = Math.max(index, 0);
- index = Math.min(index, this.pinnedTabCount);
+ index = Math.max(index, tab.hasAttribute("zen-essential") ? 0 : this._numZenEssentials);
+ index = Math.min(index, tab.hasAttribute("zen-essential") ? this._numZenEssentials : this.pinnedTabCount);
+ index = Math.min(index, tab.hasAttribute("zen-essential") ? this._numZenEssentials : this._numVisiblePinTabsWithoutCollapsed);
} else {
index = Math.max(index, this.pinnedTabCount);
- index = Math.max(index, this.pinnedTabCount);
+ index = Math.max(index, this._numVisiblePinTabsWithoutCollapsed);
index = Math.min(index, this.tabContainer.ariaFocusableItems.length);
}
@@ -419,7 +422,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
if (this.isTab(itemAfter) && itemAfter.group == tabGroup) {
// Place at the front of, or between tabs in, the same tab group
this.tabContainer.insertBefore(tab, itemAfter);
@@ -4290,6 +4410,9 @@
@@ -4290,6 +4409,9 @@
return;
}
@@ -429,7 +432,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
this.removeTabs(selectedTabs, { telemetrySource });
}
@@ -4542,6 +4665,7 @@
@@ -4542,6 +4664,7 @@
telemetrySource,
} = {}
) {
@@ -437,7 +440,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
// When 'closeWindowWithLastTab' pref is enabled, closing all tabs
// can be considered equivalent to closing the window.
if (
@@ -4626,6 +4750,7 @@
@@ -4626,6 +4749,7 @@
if (lastToClose) {
this.removeTab(lastToClose, aParams);
}
@@ -445,7 +448,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
} catch (e) {
console.error(e);
}
@@ -4650,6 +4775,7 @@
@@ -4650,6 +4774,7 @@
telemetrySource,
} = {}
) {
@@ -453,12 +456,12 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
if (UserInteraction.running("browser.tabs.opening", window)) {
UserInteraction.finish("browser.tabs.opening", window);
}
@@ -4663,6 +4789,12 @@
@@ -4663,6 +4788,12 @@
aTab._closeTimeNoAnimTimerId = Glean.browserTabclose.timeNoAnim.start();
}
+ if (ZenWorkspaces.workspaceEnabled) {
+ let newTab = ZenWorkspaces.handleTabBeforeClose(aTab);
+ let newTab = ZenWorkspaces.handleTabBeforeClose(aTab, closeWindowWithLastTab);
+ if (newTab) {
+ this.selectedTab = newTab;
+ }
@@ -466,7 +469,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
// Handle requests for synchronously removing an already
// asynchronously closing tab.
if (!animate && aTab.closing) {
@@ -4677,7 +4809,9 @@
@@ -4677,7 +4808,9 @@
// frame created for it (for example, by updating the visually selected
// state).
let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width;
@@ -477,7 +480,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
if (
!this._beginRemoveTab(aTab, {
closeWindowFastpath: true,
@@ -4840,7 +4974,7 @@
@@ -4840,7 +4973,7 @@
closeWindowWithLastTab != null
? closeWindowWithLastTab
: !window.toolbar.visible ||
@@ -486,7 +489,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
if (closeWindow) {
// We've already called beforeunload on all the relevant tabs if we get here,
@@ -4864,6 +4998,7 @@
@@ -4864,6 +4997,7 @@
newTab = true;
}
@@ -494,7 +497,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
aTab._endRemoveArgs = [closeWindow, newTab];
// swapBrowsersAndCloseOther will take care of closing the window without animation.
@@ -4903,9 +5038,7 @@
@@ -4903,9 +5037,7 @@
aTab._mouseleave();
if (newTab) {
@@ -505,7 +508,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
} else {
TabBarVisibility.update();
}
@@ -5034,6 +5167,8 @@
@@ -5034,6 +5166,8 @@
this.tabs[i]._tPos = i;
}
@@ -514,7 +517,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
if (!this._windowIsClosing) {
if (wasPinned) {
this.tabContainer._positionPinnedTabs();
@@ -5159,8 +5294,8 @@
@@ -5159,8 +5293,8 @@
return closedCount;
}
@@ -525,7 +528,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
if (unloadBlocked) {
return;
}
@@ -5248,6 +5383,7 @@
@@ -5248,6 +5382,7 @@
}
let excludeTabs = new Set(aExcludeTabs);
@@ -533,7 +536,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
// If this tab has a successor, it should be selectable, since
// hiding or closing a tab removes that tab as a successor.
@@ -5260,13 +5396,13 @@
@@ -5260,13 +5395,13 @@
!excludeTabs.has(aTab.owner) &&
Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")
) {
@@ -549,7 +552,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
);
let tab = this.tabContainer.findNextTab(aTab, {
@@ -5282,7 +5418,7 @@
@@ -5282,7 +5417,7 @@
}
if (tab) {
@@ -558,7 +561,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
}
// If no qualifying visible tab was found, see if there is a tab in
@@ -5303,7 +5439,7 @@
@@ -5303,7 +5438,7 @@
});
}
@@ -567,7 +570,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
}
_blurTab(aTab) {
@@ -5704,10 +5840,10 @@
@@ -5704,10 +5839,10 @@
SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
}
@@ -580,7 +583,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
aTab.selected ||
aTab.closing ||
// Tabs that are sharing the screen, microphone or camera cannot be hidden.
@@ -6001,7 +6137,7 @@
@@ -6001,7 +6136,7 @@
// Don't allow mixing pinned and unpinned tabs.
if (this.isTab(element) && element.pinned) {
@@ -589,7 +592,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
} else {
tabIndex = Math.max(tabIndex, this.pinnedTabCount);
}
@@ -6028,9 +6164,16 @@
@@ -6028,9 +6163,16 @@
element,
() => {
let neighbor = this.tabs[tabIndex];
@@ -607,7 +610,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
if (neighbor && this.isTab(element) && tabIndex > element._tPos) {
neighbor.after(element);
} else {
@@ -6099,7 +6242,9 @@
@@ -6099,7 +6241,9 @@
targetElement = targetElement.group;
}
}
@@ -618,7 +621,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
// Don't allow mixing pinned and unpinned tabs.
if (element.pinned && !targetElement?.pinned) {
targetElement = this.tabs[this.pinnedTabCount - 1];
@@ -6109,7 +6254,13 @@
@@ -6109,7 +6253,13 @@
moveBefore = true;
}
@@ -632,7 +635,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
if (element.pinned && this.tabContainer.verticalMode) {
return this.tabContainer.verticalPinnedTabsContainer;
}
@@ -6169,7 +6320,7 @@
@@ -6169,7 +6319,7 @@
if (!this.isTab(aTab)) {
throw new Error("Can only move a tab into a tab group");
}
@@ -641,7 +644,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
return;
}
if (aTab.group && aTab.group.id === aGroup.id) {
@@ -6263,6 +6414,10 @@
@@ -6263,6 +6413,10 @@
moveActionCallback();
@@ -652,7 +655,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
// Clear tabs cache after moving nodes because the order of tabs may have
// changed.
this.tabContainer._invalidateCachedTabs();
@@ -7080,7 +7235,7 @@
@@ -7080,7 +7234,7 @@
// preventDefault(). It will still raise the window if appropriate.
break;
}
@@ -661,7 +664,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
window.focus();
aEvent.preventDefault();
break;
@@ -7981,6 +8136,7 @@
@@ -7981,6 +8135,7 @@
aWebProgress.isTopLevel
) {
this.mTab.setAttribute("busy", "true");
@@ -669,7 +672,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
gBrowser._tabAttrModified(this.mTab, ["busy"]);
this.mTab._notselectedsinceload = !this.mTab.selected;
}
@@ -8954,7 +9110,7 @@ var TabContextMenu = {
@@ -8954,7 +9109,7 @@ var TabContextMenu = {
);
contextUnpinSelectedTabs.hidden =
!this.contextTab.pinned || !this.multiselected;
@@ -678,7 +681,7 @@ index 6dece2b9d0462d90a28e75350ce983d87816ef73..f191c26b73be69880eb16a83006a9e2a
// Move Tab items
let contextMoveTabOptions = document.getElementById(
"context_moveTabOptions"
@@ -9223,6 +9379,7 @@ var TabContextMenu = {
@@ -9223,6 +9378,7 @@ var TabContextMenu = {
telemetrySource: gBrowser.TabMetrics.METRIC_SOURCE.TAB_STRIP,
});
} else {

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js
index ef9c0389ec926e6bc01c0dc3b883beceaf1f7d43..1a3aa415d08379b00960de398808e771c299f2ca 100644
index ef9c0389ec926e6bc01c0dc3b883beceaf1f7d43..3001dd54fccfcac3b96288dd769fbaa16cb76ffb 100644
--- a/browser/components/tabbrowser/content/tabs.js
+++ b/browser/components/tabbrowser/content/tabs.js
@@ -83,7 +83,7 @@
@@ -229,7 +229,7 @@ index ef9c0389ec926e6bc01c0dc3b883beceaf1f7d43..1a3aa415d08379b00960de398808e771
}
+ let glanceTab = child.querySelector("tab[zen-glance-tab]");
+ if (isTab(child) && glanceTab) {
+ glanceTab.elementIndex = elementIndex++;
+ glanceTab.elementIndex = elementIndex - 1;
+ focusableItems.push(glanceTab);
+ }
}

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/urlbar/UrlbarInput.sys.mjs b/browser/components/urlbar/UrlbarInput.sys.mjs
index 4b69136aa31bfef3a1d3b57ad0c75fe07fa26be0..8d94bc2b7f3469258cb1a24888c5890eb83047e1 100644
index 4b69136aa31bfef3a1d3b57ad0c75fe07fa26be0..66ef8de0d2a767376740ca57d75b5372cc11ed40 100644
--- a/browser/components/urlbar/UrlbarInput.sys.mjs
+++ b/browser/components/urlbar/UrlbarInput.sys.mjs
@@ -68,6 +68,13 @@ XPCOMUtils.defineLazyPreferenceGetter(
@@ -208,7 +208,7 @@ index 4b69136aa31bfef3a1d3b57ad0c75fe07fa26be0..8d94bc2b7f3469258cb1a24888c5890e
this.view.autoOpen({ event });
} else {
if (this._untrimOnFocusAfterKeydown) {
@@ -4164,9 +4237,12 @@ export class UrlbarInput {
@@ -4164,9 +4237,16 @@ export class UrlbarInput {
}
_on_mousedown(event) {
@@ -216,24 +216,28 @@ index 4b69136aa31bfef3a1d3b57ad0c75fe07fa26be0..8d94bc2b7f3469258cb1a24888c5890e
+ switch (event.zenOriginalTarget || event.currentTarget) {
case this.textbox: {
this._mousedownOnUrlbarDescendant = true;
+ if (event.type != "click") {
+ const isProbablyFloating =
+ (lazy.ZEN_URLBAR_BEHAVIOR == "floating-on-type" &&
+ this.hasAttribute("breakout-extend") && !this.focusedViaMousedown) ||
+ (lazy.ZEN_URLBAR_BEHAVIOR == "float") || this.window.gZenVerticalTabsManager._hasSetSingleToolbar;
+ if (event.type != "click" && isProbablyFloating || event.type == "click" && !isProbablyFloating) {
+ return true;
+ }
if (
event.target != this.inputField &&
@@ -4176,8 +4252,8 @@ export class UrlbarInput {
break;
}
@@ -4178,6 +4258,10 @@ export class UrlbarInput {
- this.focusedViaMousedown = !this.focused;
- this._preventClickSelectsAll = this.focused;
+ this.focusedViaMousedown = !(lazy.ZEN_URLBAR_BEHAVIOR === 'default' ? this.focused : this.hasAttribute("breakout-extend"));
+ this._preventClickSelectsAll = lazy.ZEN_URLBAR_BEHAVIOR === 'default' ? this.focused : this.hasAttribute("breakout-extend");
this.focusedViaMousedown = !this.focused;
this._preventClickSelectsAll = this.focused;
+ if (isProbablyFloating) {
+ this.focusedViaMousedown = !this.hasAttribute("breakout-extend");
+ this._preventClickSelectsAll = this.hasAttribute("breakout-extend");
+ }
// Keep the focus status, since the attribute may be changed
// upon calling this.focus().
@@ -4218,7 +4294,7 @@ export class UrlbarInput {
@@ -4218,7 +4302,7 @@ export class UrlbarInput {
}
// 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.

View File

@@ -0,0 +1,56 @@
diff --git a/browser/components/urlbar/UrlbarProviderPlaces.sys.mjs b/browser/components/urlbar/UrlbarProviderPlaces.sys.mjs
index b1481a11ef..925f0dc34b 100644
--- a/browser/components/urlbar/UrlbarProviderPlaces.sys.mjs
+++ b/browser/components/urlbar/UrlbarProviderPlaces.sys.mjs
@@ -35,6 +35,8 @@ const QUERYINDEX_SWITCHTAB = 9;
const QUERYINDEX_FRECENCY = 10;
const QUERYINDEX_USERCONTEXTID = 11;
const QUERYINDEX_LASTVIST = 12;
+const QUERYINDEX_PINNEDTITLE = 13;
+const QUERYINDEX_PINNEDURL = 14;
// Constants to support an alternative frecency algorithm.
const PAGES_USE_ALT_FRECENCY = Services.prefs.getBoolPref(
@@ -65,11 +67,14 @@ const SQL_BOOKMARK_TAGS_FRAGMENT = `EXISTS(SELECT 1 FROM moz_bookmarks WHERE fk
// condition once, and avoid evaluating "btitle" and "tags" when it is false.
function defaultQuery(conditions = "") {
let query = `SELECT :query_type, h.url, h.title, ${SQL_BOOKMARK_TAGS_FRAGMENT},
- h.visit_count, h.typed, h.id, t.open_count, ${PAGES_FRECENCY_FIELD}, t.userContextId, h.last_visit_date
+ h.visit_count, h.typed, h.id, t.open_count, ${PAGES_FRECENCY_FIELD}, t.userContextId, h.last_visit_date,
+ zp.title AS pinned_title, zp.url AS pinned_url
FROM moz_places h
LEFT JOIN moz_openpages_temp t
ON t.url = h.url
AND (t.userContextId = :userContextId OR (t.userContextId <> -1 AND :userContextId IS NULL))
+ LEFT JOIN zen_pins zp
+ ON zp.url = h.url
WHERE (
(:switchTabsEnabled AND t.open_count > 0) OR
${PAGES_FRECENCY_FIELD} <> 0
@@ -83,7 +88,7 @@ function defaultQuery(conditions = "") {
:matchBehavior, :searchBehavior, NULL)
ELSE
AUTOCOMPLETE_MATCH(:searchString, h.url,
- h.title, '',
+ IFNULL(zp.title, h.title), '',
h.visit_count, h.typed,
0, t.open_count,
:matchBehavior, :searchBehavior, NULL)
@@ -1132,11 +1137,14 @@ Search.prototype = {
let lastVisit = lastVisitPRTime
? lazy.PlacesUtils.toDate(lastVisitPRTime).getTime()
: undefined;
-
+ let pinnedTitle = row.getResultByIndex(QUERYINDEX_PINNEDTITLE);
+ let pinnedUrl = row.getResultByIndex(QUERYINDEX_PINNEDURL);
+
+
let match = {
placeId,
- value: url,
- comment: bookmarkTitle || historyTitle,
+ value: pinnedUrl || url,
+ comment: pinnedTitle || bookmarkTitle || historyTitle,
icon: UrlbarUtils.getIconForUrl(url),
frecency: frecency || FRECENCY_DEFAULT,
userContextId,

View File

@@ -7,7 +7,10 @@
@namespace html 'http://www.w3.org/1999/xhtml';
:root {
--zen-settings-secondary-background: light-dark(#f2f4f4, color-mix(in srgb, var(--zen-colors-tertiary) 50%, #0f0f0f 50%));
--zen-settings-secondary-background: light-dark(
#f2f4f4,
color-mix(in srgb, var(--zen-colors-tertiary) 50%, #0f0f0f 50%)
);
--in-content-box-background: var(--zen-colors-tertiary) !important;
}

View File

@@ -5,7 +5,8 @@
*/
.subviewbutton,
#zen-welcome-start-button {
#zen-welcome-start-button,
.zen-toast button {
-moz-context-properties: fill, fill-opacity !important;
fill: currentColor !important;
}
@@ -94,8 +95,16 @@
#appMenu-passwords-button,
#password-notification-icon,
#PopupAutoComplete > richlistbox > richlistitem[originaltype='generatedPassword'] > .two-line-wrapper > .ac-site-icon,
#PopupAutoComplete > richlistbox > richlistitem[originaltype='loginWithOrigin'] > .two-line-wrapper > .ac-site-icon,
#PopupAutoComplete
> richlistbox
> richlistitem[originaltype='generatedPassword']
> .two-line-wrapper
> .ac-site-icon,
#PopupAutoComplete
> richlistbox
> richlistitem[originaltype='loginWithOrigin']
> .two-line-wrapper
> .ac-site-icon,
#PopupAutoComplete > richlistbox > richlistitem[originaltype='login'] > .ac-site-icon {
list-style-image: url('passwords.svg') !important;
}
@@ -125,13 +134,19 @@
}
#history-panelmenu,
.urlbarView-row[source='history'] > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-favicon,
.urlbarView-row[source='history']
> .urlbarView-row-inner
> .urlbarView-no-wrap
> .urlbarView-favicon,
#urlbar-engine-one-off-item-history,
#appMenu-history-button,
#appMenu-library-history-button,
#sidebar-switcher-history,
#zen-history-button,
#sidebar-box[sidebarcommand='viewHistorySidebar'] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon {
#sidebar-box[sidebarcommand='viewHistorySidebar']
> #sidebar-header
> #sidebar-switcher-target
> #sidebar-icon {
list-style-image: url('history.svg') !important;
}
@@ -276,7 +291,10 @@
#appMenu-bookmarks-button,
#sidebar-switcher-bookmarks,
#appMenu-library-bookmarks-button,
#sidebar-box[sidebarcommand='viewBookmarksSidebar'] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon {
#sidebar-box[sidebarcommand='viewBookmarksSidebar']
> #sidebar-header
> #sidebar-switcher-target
> #sidebar-icon {
list-style-image: url('bookmark-star-on-tray.svg') !important;
}
@@ -302,7 +320,10 @@
list-style-image: url('page-portrait.svg') !important;
}
#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate='invalid'] #identity-icon {
#urlbar:not(.searchButton)
> #urlbar-input-container
> #identity-box[pageproxystate='invalid']
#identity-icon {
list-style-image: url('search-glass.svg') !important;
}
@@ -405,7 +426,7 @@
list-style-image: url('customize.svg') !important;
}
#appmenu-zen-share-rice {
#zen-copy-current-url-button {
list-style-image: url('share.svg');
}
@@ -428,7 +449,10 @@
list-style-image: url('split.svg');
}
#sidebar-box[sidebarcommand='viewTabsSidebar'] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon,
#sidebar-box[sidebarcommand='viewTabsSidebar']
> #sidebar-header
> #sidebar-switcher-target
> #sidebar-icon,
#sidebar-switcher-tabs {
list-style-image: url('send-to-device.svg') !important;
}
@@ -592,7 +616,10 @@
background-image: url('reload-to-stop.svg') !important;
}
#stop-reload-button[animate] > #reload-button > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image,
#stop-reload-button[animate]
> #reload-button
> .toolbarbutton-animatable-box
> .toolbarbutton-animatable-image,
#zen-sidebar-web-panel-reload[animate]
> #zen-sidebar-web-panel-reload-button
> .toolbarbutton-animatable-box
@@ -630,7 +657,14 @@
),
:not(:not(menubar) > menu, #ContentSelectDropdown)
> menupopup
> menu:not(.menu-iconic, [type='checkbox'], [type='radio'], .in-menulist, .in-menulist menu, .unified-nav-current),
> menu:not(
.menu-iconic,
[type='checkbox'],
[type='radio'],
.in-menulist,
.in-menulist menu,
.unified-nav-current
),
#toggle_toolbar-menubar,
#PanelUI-history toolbarbutton,
#unified-extensions-context-menu menuitem {
@@ -1096,6 +1130,10 @@ menuitem[id='placesContext_new:separator'] {
--menu-image: url('arrow-up.svg');
}
#alltabs-button {
list-style-image: url('chrome://browser/skin/tabs.svg') !important;
}
:not(:not(menubar) > menu, #ContentSelectDropdown)
> menupopup
> menuitem:not(
@@ -1108,10 +1146,18 @@ menuitem[id='placesContext_new:separator'] {
),
:not(:not(menubar) > menu, #ContentSelectDropdown)
> menupopup
> menu:not(.menu-iconic, [type='checkbox'], [type='radio'], .in-menulist, .in-menulist menu, .unified-nav-current),
> menu:not(
.menu-iconic,
[type='checkbox'],
[type='radio'],
.in-menulist,
.in-menulist menu,
.unified-nav-current
),
:not(:not(menubar) > menu, #ContentSelectDropdown) > menupopup > menucaption {
padding-inline-start: calc(
var(--fp-contextmenu-menuitem-padding-inline) + 16px + var(--fp-contextmenu-menuicon-margin-inline)
var(--fp-contextmenu-menuitem-padding-inline) + 16px +
var(--fp-contextmenu-menuicon-margin-inline)
) !important;
}

View File

@@ -11,3 +11,8 @@
value: 1
mirror: always
#endif
- name: zen.haptic-feedback.enabled
type: bool
value: true
mirror: always

View File

@@ -0,0 +1,37 @@
diff --git a/testing/mochitest/browser-test.js b/testing/mochitest/browser-test.js
index ef29179988bb37e7ea441aa051b692e3ccc90f21..6c9641ed27722b5febd83f6e121df24d46b00067 100644
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -444,11 +444,11 @@ Tester.prototype = {
this.currentTest &&
window.gBrowser &&
AppConstants.MOZ_APP_NAME != "thunderbird" &&
- gBrowser.tabs.length > 1
+ gBrowser.tabs.length > 2
) {
let lastURI = "";
let lastURIcount = 0;
- while (gBrowser.tabs.length > 1) {
+ while (gBrowser.tabs.length > 2) {
let lastTab = gBrowser.tabs[gBrowser.tabs.length - 1];
if (!lastTab.closing) {
// Report the stale tab as an error only when they're not closing.
@@ -483,12 +483,12 @@ Tester.prototype = {
// Replace the last tab with a fresh one
if (window.gBrowser && AppConstants.MOZ_APP_NAME != "thunderbird") {
- gBrowser.addTab("about:blank", {
- skipAnimation: true,
- triggeringPrincipal:
- Services.scriptSecurityManager.getSystemPrincipal(),
- });
- gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
+ // gBrowser.addTab("about:blank", {
+ // skipAnimation: true,
+ // triggeringPrincipal:
+ // Services.scriptSecurityManager.getSystemPrincipal(),
+ // });
+ // gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
gBrowser.stop();
}

View File

@@ -52,7 +52,11 @@ declare global {
setBadgeImage(aBadgeImage: imgIContainer, aPaintContext?: nsISVGPaintContext): void;
readonly isAppInDock: boolean;
ensureAppIsPinnedToDock(aAppPath?: string, aAppToReplacePath?: string): boolean;
launchAppBundle(aAppBundle: nsIFile, aArgs: string[], aLaunchOptions?: nsIAppBundleLaunchOptions): void;
launchAppBundle(
aAppBundle: nsIFile,
aArgs: string[],
aLaunchOptions?: nsIAppBundleLaunchOptions
): void;
}
// https://searchfox.org/mozilla-central/source/widget/nsIMacFinderProgress.idl

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,10 @@ declare global {
interface nsIApplicationChooser extends nsISupports {
init(parent: mozIDOMWindowProxy, title: string): void;
open(contentType: string, applicationChooserFinishedCallback: nsIApplicationChooserFinishedCallback): void;
open(
contentType: string,
applicationChooserFinishedCallback: nsIApplicationChooserFinishedCallback
): void;
}
// https://searchfox.org/mozilla-central/source/widget/nsIGtkTaskbarProgress.idl

View File

@@ -30,8 +30,14 @@ type nsIGleanPingWithReason<T> = {
interface MessageListenerManagerMixin {
// Overloads that define `data` arg as required, since it's ~always expected.
addMessageListener(msg: string, listener: { receiveMessage(_: ReceiveMessageArgument & { data }) });
removeMessageListener(msg: string, listener: { receiveMessage(_: ReceiveMessageArgument & { data }) });
addMessageListener(
msg: string,
listener: { receiveMessage(_: ReceiveMessageArgument & { data }) }
);
removeMessageListener(
msg: string,
listener: { receiveMessage(_: ReceiveMessageArgument & { data }) }
);
}
interface MozQueryInterface {
@@ -71,7 +77,12 @@ interface ComponentsExceptionOptions {
interface nsIException extends Exception {}
interface nsIXPCComponents_Exception {
(message?: string, resultOrOptions?: number | ComponentsExceptionOptions, stack?: nsIStackFrame, data?: object): nsIException;
(
message?: string,
resultOrOptions?: number | ComponentsExceptionOptions,
stack?: nsIStackFrame,
data?: object
): nsIException;
}
interface nsIXPCComponents_ID {

View File

@@ -31,7 +31,11 @@ declare global {
// https://searchfox.org/mozilla-central/source/toolkit/components/aboutwindowsmessages/nsIAboutWindowsMessages.idl
interface nsIAboutWindowsMessages extends nsISupports {
getMessages(currentWindow: mozIDOMWindowProxy, messages: OutParam<string[][]>, windowTitles: OutParam<string[]>): void;
getMessages(
currentWindow: mozIDOMWindowProxy,
messages: OutParam<string[][]>,
windowTitles: OutParam<string[]>
): void;
}
// https://searchfox.org/mozilla-central/source/toolkit/components/alerts/nsIWindowsAlertsService.idl
@@ -48,7 +52,9 @@ declare global {
type ImagePlacement = nsIWindowsAlertNotification_ImagePlacement;
}
interface nsIWindowsAlertNotification extends nsIAlertNotification, Enums<typeof nsIWindowsAlertNotification_ImagePlacement> {
interface nsIWindowsAlertNotification
extends nsIAlertNotification,
Enums<typeof nsIWindowsAlertNotification_ImagePlacement> {
imagePlacement: nsIWindowsAlertNotification.ImagePlacement;
}
@@ -157,7 +163,12 @@ declare global {
// https://searchfox.org/mozilla-central/source/toolkit/components/taskscheduler/nsIWinTaskSchedulerService.idl
interface nsIWinTaskSchedulerService extends nsISupports {
registerTask(aFolderName: string, aTaskName: string, aDefinitionXML: string, aUpdateExisting?: boolean): void;
registerTask(
aFolderName: string,
aTaskName: string,
aDefinitionXML: string,
aUpdateExisting?: boolean
): void;
validateTaskDefinition(aDefinitionXML: string): i32;
getTaskXML(aFolderName: string, aTaskName: string): string;
getCurrentUserSid(): string;
@@ -174,7 +185,11 @@ declare global {
obtainAndCacheFaviconAsync(faviconURL: nsIURI): Promise<any>;
isAvailable(): Promise<any>;
checkForRemovals(): Promise<any>;
populateJumpList(aTaskDescriptions: any, aCustomTitle: string, aCustomDescriptions: any): Promise<any>;
populateJumpList(
aTaskDescriptions: any,
aCustomTitle: string,
aCustomDescriptions: any
): Promise<any>;
clearJumpList(): Promise<any>;
}
@@ -183,7 +198,11 @@ declare global {
// https://searchfox.org/mozilla-central/source/widget/nsITaskbarOverlayIconController.idl
interface nsITaskbarOverlayIconController extends nsISupports {
setOverlayIcon(statusIcon: imgIContainer, statusDescription: string, paintContext?: nsISVGPaintContext): void;
setOverlayIcon(
statusIcon: imgIContainer,
statusDescription: string,
paintContext?: nsISVGPaintContext
): void;
}
// https://searchfox.org/mozilla-central/source/widget/nsITaskbarPreview.idl
@@ -259,7 +278,10 @@ declare global {
readonly available: boolean;
readonly defaultGroupId: string;
readonly defaultPrivateGroupId: string;
createTaskbarTabPreview(shell: nsIDocShell, controller: nsITaskbarPreviewController): nsITaskbarTabPreview;
createTaskbarTabPreview(
shell: nsIDocShell,
controller: nsITaskbarPreviewController
): nsITaskbarTabPreview;
getTaskbarWindowPreview(shell: nsIDocShell): nsITaskbarWindowPreview;
getTaskbarProgress(shell: nsIDocShell): nsITaskbarProgress;
getOverlayIconController(shell: nsIDocShell): nsITaskbarOverlayIconController;
@@ -273,7 +295,11 @@ declare global {
interface nsIWindowsUIUtils extends nsISupports {
readonly systemSmallIconSize: i32;
readonly systemLargeIconSize: i32;
setWindowIcon(aWindow: mozIDOMWindowProxy, aSmallIcon: imgIContainer, aLargeIcon: imgIContainer): void;
setWindowIcon(
aWindow: mozIDOMWindowProxy,
aSmallIcon: imgIContainer,
aLargeIcon: imgIContainer
): void;
setWindowIconFromExe(aWindow: mozIDOMWindowProxy, aExe: string, aIndex: u16): void;
setWindowIconNoData(aWindow: mozIDOMWindowProxy): void;
readonly inWin10TabletMode: boolean;
@@ -346,13 +372,19 @@ declare global {
nsIInstalledApplication: nsJSIID<nsIInstalledApplication>;
nsIAboutThirdParty: nsJSIID<nsIAboutThirdParty>;
nsIAboutWindowsMessages: nsJSIID<nsIAboutWindowsMessages>;
nsIWindowsAlertNotification: nsJSIID<nsIWindowsAlertNotification, typeof nsIWindowsAlertNotification_ImagePlacement>;
nsIWindowsAlertNotification: nsJSIID<
nsIWindowsAlertNotification,
typeof nsIWindowsAlertNotification_ImagePlacement
>;
nsIWindowsAlertsService: nsJSIID<nsIWindowsAlertsService>;
nsIDefaultAgent: nsJSIID<nsIDefaultAgent>;
nsIWindowsMutex: nsJSIID<nsIWindowsMutex>;
nsIWindowsMutexFactory: nsJSIID<nsIWindowsMutexFactory>;
nsIGeolocationUIUtilsWin: nsJSIID<nsIGeolocationUIUtilsWin>;
nsIWindowsShellService: nsJSIID<nsIWindowsShellService, typeof nsIWindowsShellService_LaunchOnLoginEnabledEnumerator>;
nsIWindowsShellService: nsJSIID<
nsIWindowsShellService,
typeof nsIWindowsShellService_LaunchOnLoginEnabledEnumerator
>;
nsIWinTaskSchedulerService: nsJSIID<nsIWinTaskSchedulerService>;
nsIJumpListBuilder: nsJSIID<nsIJumpListBuilder>;
nsITaskbarOverlayIconController: nsJSIID<nsITaskbarOverlayIconController>;

File diff suppressed because it is too large Load Diff

View File

@@ -164,7 +164,11 @@ declare namespace MockedExports {
removeObserver: (aDomain: string, aObserver: PrefObserver) => void;
};
type PrefObserverFunction = (aSubject: nsIPrefBranch, aTopic: 'nsPref:changed', aData: string) => unknown;
type PrefObserverFunction = (
aSubject: nsIPrefBranch,
aTopic: 'nsPref:changed',
aData: string
) => unknown;
type PrefObserver = PrefObserverFunction | { observe: PrefObserverFunction };
interface nsIURI {}
@@ -216,7 +220,9 @@ declare namespace MockedExports {
GetFeatures: () => string[];
getProfileDataAsync: (sinceTime?: number) => Promise<object>;
getProfileDataAsArrayBuffer: (sinceTime?: number) => Promise<ArrayBuffer>;
getProfileDataAsGzippedArrayBuffer: (sinceTime?: number) => Promise<ProfileAndAdditionalInformation>;
getProfileDataAsGzippedArrayBuffer: (
sinceTime?: number
) => Promise<ProfileAndAdditionalInformation>;
IsActive: () => boolean;
sharedLibraries: SharedLibrary[];
};
@@ -273,7 +279,10 @@ declare namespace MockedExports {
const PlaceUtilsSYSMJS: {
PlacesUtils: {
promiseFaviconData: (pageUrl: string | URL | nsIURI, preferredWidth?: number) => Promise<FaviconData>;
promiseFaviconData: (
pageUrl: string | URL | nsIURI,
preferredWidth?: number
) => Promise<FaviconData>;
// TS-TODO: Add the rest.
};
};
@@ -429,8 +438,16 @@ declare interface XULCommandEvent extends Event {
}
declare interface XULElementWithCommandHandler {
addEventListener: (type: 'command', handler: (event: XULCommandEvent) => void, isCapture?: boolean) => void;
removeEventListener: (type: 'command', handler: (event: XULCommandEvent) => void, isCapture?: boolean) => void;
addEventListener: (
type: 'command',
handler: (event: XULCommandEvent) => void,
isCapture?: boolean
) => void;
removeEventListener: (
type: 'command',
handler: (event: XULCommandEvent) => void,
isCapture?: boolean
) => void;
}
declare type nsIPrefBranch = MockedExports.nsIPrefBranch;

View File

@@ -65,12 +65,35 @@ var gZenCommonActions = {
if (currentUrl) {
let str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
str.data = currentUrl;
let transferable = Cc['@mozilla.org/widget/transferable;1'].createInstance(Ci.nsITransferable);
let transferable = Cc['@mozilla.org/widget/transferable;1'].createInstance(
Ci.nsITransferable
);
transferable.init(getLoadContext());
transferable.addDataFlavor('text/plain');
transferable.setTransferData('text/plain', str);
Services.clipboard.setData(transferable, null, Ci.nsIClipboard.kGlobalClipboard);
gZenUIManager.showToast('zen-copy-current-url-confirmation');
let button;
if (
Services.zen.canShare() &&
(currentUrl.startsWith('http://') || currentUrl.startsWith('https://'))
) {
button = {
id: 'zen-copy-current-url-button',
command: (event) => {
const buttonRect = event.target.getBoundingClientRect();
Services.zen.share(
Services.io.newURI(currentUrl),
'',
'',
buttonRect.left,
window.innerHeight - buttonRect.bottom,
buttonRect.width,
buttonRect.height
);
},
};
}
gZenUIManager.showToast('zen-copy-current-url-confirmation', { button, timeout: 3000 });
}
},
copyCurrentURLAsMarkdownToClipboard() {
@@ -80,7 +103,9 @@ var gZenCommonActions = {
const markdownLink = `[${tabTitle}](${currentUrl})`;
let str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
str.data = markdownLink;
let transferable = Cc['@mozilla.org/widget/transferable;1'].createInstance(Ci.nsITransferable);
let transferable = Cc['@mozilla.org/widget/transferable;1'].createInstance(
Ci.nsITransferable
);
transferable.init(getLoadContext());
transferable.addDataFlavor('text/plain');
transferable.setTransferData('text/plain', str);

View File

@@ -103,8 +103,13 @@ export var ZenCustomizableUI = new (class {
_moveWindowButtons(window) {
const windowControls = window.document.getElementsByClassName('titlebar-buttonbox-container');
const toolboxIcons = window.document.getElementById('zen-sidebar-top-buttons-customization-target');
if (window.AppConstants.platform === 'macosx' || window.matchMedia('(-moz-gtk-csd-reversed-placement)').matches) {
const toolboxIcons = window.document.getElementById(
'zen-sidebar-top-buttons-customization-target'
);
if (
window.AppConstants.platform === 'macosx' ||
window.matchMedia('(-moz-gtk-csd-reversed-placement)').matches
) {
for (let i = 0; i < windowControls.length; i++) {
if (i === 0) {
toolboxIcons.prepend(windowControls[i]);
@@ -131,7 +136,11 @@ export var ZenCustomizableUI = new (class {
}
registerToolbarNodes(window) {
window.CustomizableUI.registerToolbarNode(window.document.getElementById('zen-sidebar-top-buttons'));
window.CustomizableUI.registerToolbarNode(window.document.getElementById('zen-sidebar-bottom-buttons'));
window.CustomizableUI.registerToolbarNode(
window.document.getElementById('zen-sidebar-top-buttons')
);
window.CustomizableUI.registerToolbarNode(
window.document.getElementById('zen-sidebar-bottom-buttons')
);
}
})();

View File

@@ -37,7 +37,10 @@
this._checkForWelcomePage();
document.l10n.setAttributes(document.getElementById('tabs-newtab-button'), 'tabs-toolbar-new-tab');
document.l10n.setAttributes(
document.getElementById('tabs-newtab-button'),
'tabs-toolbar-new-tab'
);
} catch (e) {
console.error('ZenThemeModifier: Error initializing browser layout', e);
}
@@ -104,7 +107,9 @@
}
)
.then(() => {
for (let elem of document.querySelectorAll('#browser > *, #urlbar, #tabbrowser-tabbox > *')) {
for (let elem of document.querySelectorAll(
'#browser > *, #urlbar, #tabbrowser-tabbox > *'
)) {
elem.style.removeProperty('opacity');
}
});
@@ -141,7 +146,10 @@
_initSidebarScrolling() {
// Disable smooth scroll
const canSmoothScroll = Services.prefs.getBoolPref('zen.startup.smooth-scroll-in-tabs', false);
const canSmoothScroll = Services.prefs.getBoolPref(
'zen.startup.smooth-scroll-in-tabs',
false
);
const tabsWrapper = document.getElementById('zen-tabs-wrapper');
gBrowser.tabContainer.addEventListener('wheel', (event) => {
if (canSmoothScroll) return;
@@ -162,7 +170,9 @@
window.requestAnimationFrame(() => {
tabContainer.arrowScrollbox.toggleAttribute('overflowing', overflowing);
tabContainer.arrowScrollbox.dispatchEvent(new CustomEvent(overflowing ? 'overflow' : 'underflow'));
tabContainer.arrowScrollbox.dispatchEvent(
new CustomEvent(overflowing ? 'overflow' : 'underflow')
);
});
});
observer.observe(tabsWrapper);
@@ -180,7 +190,10 @@
_checkForWelcomePage() {
if (!Services.prefs.getBoolPref('zen.welcome-screen.seen', false)) {
Services.prefs.setBoolPref('zen.welcome-screen.seen', true);
Services.scriptloader.loadSubScript('chrome://browser/content/zen-components/ZenWelcome.mjs', window);
Services.scriptloader.loadSubScript(
'chrome://browser/content/zen-components/ZenWelcome.mjs',
window
);
}
},
};

View File

@@ -4,25 +4,46 @@ var gZenUIManager = {
_hasLoadedDOM: false,
testingEnabled: Services.prefs.getBoolPref('zen.testing.enabled', false),
_toastTimeouts: [],
init() {
document.addEventListener('popupshowing', this.onPopupShowing.bind(this));
document.addEventListener('popuphidden', this.onPopupHidden.bind(this));
XPCOMUtils.defineLazyPreferenceGetter(this, 'sidebarHeightThrottle', 'zen.view.sidebar-height-throttle', 500);
XPCOMUtils.defineLazyPreferenceGetter(this, 'contentElementSeparation', 'zen.theme.content-element-separation', 0);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'sidebarHeightThrottle',
'zen.view.sidebar-height-throttle',
500
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'contentElementSeparation',
'zen.theme.content-element-separation',
0
);
XPCOMUtils.defineLazyPreferenceGetter(this, 'urlbarWaitToClear', 'zen.urlbar.wait-to-clear', 0);
XPCOMUtils.defineLazyPreferenceGetter(this, 'urlbarShowDomainOnly', 'zen.urlbar.show-domain-only-in-sidebar', true);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'urlbarShowDomainOnly',
'zen.urlbar.show-domain-only-in-sidebar',
true
);
gURLBar._zenTrimURL = this.urlbarTrim.bind(this);
ChromeUtils.defineLazyGetter(this, 'motion', () => {
return ChromeUtils.importESModule('chrome://browser/content/zen-vendor/motion.min.mjs', { global: 'current' });
return ChromeUtils.importESModule('chrome://browser/content/zen-vendor/motion.min.mjs', {
global: 'current',
});
});
ChromeUtils.defineLazyGetter(this, '_toastContainer', () => {
return document.getElementById('zen-toast-container');
});
new ResizeObserver(this.updateTabsToolbar.bind(this)).observe(document.getElementById('TabsToolbar'));
new ResizeObserver(this.updateTabsToolbar.bind(this)).observe(
document.getElementById('TabsToolbar')
);
new ResizeObserver(
gZenCommonActions.throttle(
@@ -50,6 +71,7 @@ var gZenUIManager = {
);
gZenVerticalTabsManager.actualWindowButtons.removeAttribute('zen-has-hover');
gZenVerticalTabsManager.recalculateURLBarHeight();
setTimeout(gURLBar.formatValue.bind(gURLBar), 0);
if (!this._preventToolbarRebuild) {
setTimeout(() => {
ZenWorkspaces.updateTabsContainers();
@@ -129,7 +151,8 @@ var gZenUIManager = {
// we also ignore menus inside panels
if (
!el.contains(showEvent.explicitOriginalTarget) ||
(showEvent.explicitOriginalTarget instanceof Element && showEvent.explicitOriginalTarget?.closest('panel'))
(showEvent.explicitOriginalTarget instanceof Element &&
showEvent.explicitOriginalTarget?.closest('panel'))
) {
continue;
}
@@ -199,7 +222,9 @@ var gZenUIManager = {
const timeSinceLastSwitch = now - this._tabSwitchState.lastSwitchTime;
if (timeSinceLastSwitch < this._tabSwitchState.debounceTime) {
await new Promise((resolve) => setTimeout(resolve, this._tabSwitchState.debounceTime - timeSinceLastSwitch));
await new Promise((resolve) =>
setTimeout(resolve, this._tabSwitchState.debounceTime - timeSinceLastSwitch)
);
}
// Execute operation
@@ -244,7 +269,11 @@ var gZenUIManager = {
return false;
}
const shouldOpenURLBar = gZenVerticalTabsManager._canReplaceNewTab && !werePassedURL && !searchClipboard && where === 'tab';
const shouldOpenURLBar =
gZenVerticalTabsManager._canReplaceNewTab &&
!werePassedURL &&
!searchClipboard &&
where === 'tab';
if (!shouldOpenURLBar) {
return false;
@@ -320,7 +349,12 @@ var gZenUIManager = {
gURLBar.removeAttribute('zen-newtab');
// Safely restore tab visual state with proper validation
if (this._lastTab && !this._lastTab.closing && this._lastTab.ownerGlobal && !this._lastTab.ownerGlobal.closed) {
if (
this._lastTab &&
!this._lastTab.closing &&
this._lastTab.ownerGlobal &&
!this._lastTab.ownerGlobal.closed
) {
this._lastTab._visuallySelected = true;
this._lastTab = null;
}
@@ -385,9 +419,16 @@ var gZenUIManager = {
// Check if this message ID already exists
for (const child of this._toastContainer.children) {
if (child._messageId === messageId) {
if (options.button && child.querySelector('button')) {
const button = child.querySelector('button');
const clone = button.cloneNode(true);
button.replaceWith(clone);
clone.addEventListener('command', options.button.command);
}
return [child, true];
}
}
const wrapper = document.createXULElement('hbox');
const element = document.createXULElement('vbox');
const label = document.createXULElement('label');
document.l10n.setAttributes(label, messageId, options);
@@ -398,35 +439,58 @@ var gZenUIManager = {
document.l10n.setAttributes(description, options.descriptionId, options);
element.appendChild(description);
}
element.classList.add('zen-toast');
element._messageId = messageId;
return [element, false];
wrapper.appendChild(element);
if (options.button) {
const button = document.createXULElement('button');
button.id = options.button.id;
button.classList.add('footer-button');
button.classList.add('primary');
button.addEventListener('command', options.button.command);
wrapper.appendChild(button);
wrapper.setAttribute('button', true);
}
wrapper.classList.add('zen-toast');
wrapper._messageId = messageId;
return [wrapper, false];
},
async showToast(messageId, options = {}) {
const [toast, reused] = this._createToastElement(messageId, options);
this._toastContainer.removeAttribute('hidden');
this._toastContainer.appendChild(toast);
const timeoutFunction = () => {
this.motion
.animate(toast, { opacity: [1, 0], scale: [1, 0.5] }, { duration: 0.2, bounce: 0 })
.then(() => {
toast.remove();
if (this._toastContainer.children.length === 0) {
this._toastContainer.setAttribute('hidden', true);
}
});
};
if (reused) {
await this.motion.animate(toast, { scale: 0.2 }, { duration: 0.1, bounce: 0 });
toast._useCount++;
} else {
toast._useCount = 1;
toast.addEventListener('mouseover', () => {
if (this._toastTimeouts[messageId]) {
clearTimeout(this._toastTimeouts[messageId]);
}
});
toast.addEventListener('mouseout', () => {
if (this._toastTimeouts[messageId]) {
clearTimeout(this._toastTimeouts[messageId]);
}
this._toastTimeouts[messageId] = setTimeout(timeoutFunction, options.timeout || 2000);
});
}
if (!toast.style.hasOwnProperty('transform')) {
toast.style.transform = 'scale(0)';
}
await this.motion.animate(toast, { scale: 1 }, { type: 'spring', bounce: 0.2, duration: 0.5 });
await new Promise((resolve) => setTimeout(resolve, 3000));
if (toast._useCount <= 1) {
await this.motion.animate(toast, { opacity: [1, 0], scale: [1, 0.5] }, { duration: 0.2, bounce: 0 });
toast.remove();
if (!this._toastContainer.hasChildNodes()) {
this._toastContainer.setAttribute('hidden', 'true');
}
return;
if (this._toastTimeouts[messageId]) {
clearTimeout(this._toastTimeouts[messageId]);
}
toast._useCount--;
this._toastTimeouts[messageId] = setTimeout(timeoutFunction, options.timeout || 2000);
},
get panelUIPosition() {
@@ -456,7 +520,12 @@ var gZenVerticalTabsManager = {
);
});
XPCOMUtils.defineLazyPreferenceGetter(this, '_canReplaceNewTab', 'zen.urlbar.replace-newtab', true);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_canReplaceNewTab',
'zen.urlbar.replace-newtab',
true
);
var updateEvent = this._updateEvent.bind(this);
var onPrefChange = this._onPrefChange.bind(this);
@@ -505,7 +574,9 @@ var gZenVerticalTabsManager = {
if (this.__topButtonsSeparatorElement) {
return this.__topButtonsSeparatorElement;
}
this.__topButtonsSeparatorElement = document.getElementById('zen-sidebar-top-buttons-separator');
this.__topButtonsSeparatorElement = document.getElementById(
'zen-sidebar-top-buttons-separator'
);
return this.__topButtonsSeparatorElement;
},
@@ -572,7 +643,10 @@ var gZenVerticalTabsManager = {
async _preCustomize() {
await this._multiWindowFeature.foreachWindowAsActive(async (browser) => {
browser.gZenVerticalTabsManager._updateEvent({ forCustomizableMode: true, dontRebuildAreas: true });
browser.gZenVerticalTabsManager._updateEvent({
forCustomizableMode: true,
dontRebuildAreas: true,
});
});
this.rebuildAreas();
this.navigatorToolbox.setAttribute('zen-sidebar-expanded', 'true');
@@ -587,10 +661,34 @@ var gZenVerticalTabsManager = {
},
initializePreferences(updateEvent) {
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsVerticalTabs', 'zen.tabs.vertical', true, updateEvent);
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsRightSide', 'zen.tabs.vertical.right-side', false, updateEvent);
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsUseSingleToolbar', 'zen.view.use-single-toolbar', false, updateEvent);
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsSidebarExpanded', 'zen.view.sidebar-expanded', false, updateEvent);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_prefsVerticalTabs',
'zen.tabs.vertical',
true,
updateEvent
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_prefsRightSide',
'zen.tabs.vertical.right-side',
false,
updateEvent
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_prefsUseSingleToolbar',
'zen.view.use-single-toolbar',
false,
updateEvent
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_prefsSidebarExpanded',
'zen.view.sidebar-expanded',
false,
updateEvent
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_prefsSidebarExpandedMaxWidth',
@@ -647,7 +745,10 @@ var gZenVerticalTabsManager = {
this._updateMaxWidth();
if (window.docShell) {
window.docShell.treeOwner.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIAppWindow).rollupAllPopups();
window.docShell.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIAppWindow)
.rollupAllPopups();
}
const topButtons = document.getElementById('zen-sidebar-top-buttons');
@@ -662,7 +763,10 @@ var gZenVerticalTabsManager = {
const titlebar = document.getElementById('titlebar');
gBrowser.tabContainer.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal');
gBrowser.tabContainer.arrowScrollbox.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal');
gBrowser.tabContainer.arrowScrollbox.setAttribute(
'orient',
isVerticalTabs ? 'vertical' : 'horizontal'
);
// on purpose, we set the orient to horizontal, because the arrowScrollbox is vertical
gBrowser.tabContainer.arrowScrollbox.scrollbox.setAttribute(
'orient',
@@ -774,7 +878,13 @@ var gZenVerticalTabsManager = {
}
// Case: single toolbar, not compact mode, not right side and macos styled buttons
if (!doNotChangeWindowButtons && isSingleToolbar && !isCompactMode && !isRightSide && !this.isWindowsStyledButtons) {
if (
!doNotChangeWindowButtons &&
isSingleToolbar &&
!isCompactMode &&
!isRightSide &&
!this.isWindowsStyledButtons
) {
topButtons.prepend(windowButtons);
}
// Case: single toolbar, compact mode, right side and windows styled buttons
@@ -889,7 +999,11 @@ var gZenVerticalTabsManager = {
}
if (this._tabEdited.getAttribute('zen-pin-id')) {
// Update pin title in storage
await gZenPinnedTabManager.updatePinTitle(this._tabEdited, this._tabEdited.label, !!newName);
await gZenPinnedTabManager.updatePinTitle(
this._tabEdited,
this._tabEdited.label,
!!newName
);
}
document.documentElement.removeAttribute('zen-renaming-tab');
@@ -922,7 +1036,11 @@ var gZenVerticalTabsManager = {
)
return;
this._tabEdited = event.target.closest('.tabbrowser-tab');
if (!this._tabEdited || !this._tabEdited.pinned || this._tabEdited.hasAttribute('zen-essential')) {
if (
!this._tabEdited ||
!this._tabEdited.pinned ||
this._tabEdited.hasAttribute('zen-essential')
) {
this._tabEdited = null;
return;
}

View File

@@ -177,7 +177,11 @@
.titlebar-buttonbox-container {
/* Draw 3 dots as background to represent the window controls,
all with the same cololr as the titlebar */
background-image: radial-gradient(circle, var(--zen-toolbar-element-bg) 6px, transparent 0.5px);
background-image: radial-gradient(
circle,
var(--zen-toolbar-element-bg) 6px,
transparent 0.5px
);
background-size: 20px 22px;
background-position: 53% 50%;

View File

@@ -62,5 +62,9 @@ panel[type='arrow'] {
--panel-border-color: transparent;
/* This should be kept in sync with GetMenuMaskImage() */
--panel-border-radius: 6px;
&::part(content) {
background-color: light-dark(rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.2)) !important;
}
}
}

View File

@@ -11,7 +11,8 @@
:root {
--panel-subview-body-padding: 2px 0;
--arrowpanel-menuitem-border-radius: 5px;
--arrowpanel-menuitem-margin: var(--uc-arrowpanel-menuitem-margin-block) var(--uc-arrowpanel-menuitem-margin-inline);
--arrowpanel-menuitem-margin: var(--uc-arrowpanel-menuitem-margin-block)
var(--uc-arrowpanel-menuitem-margin-inline);
--arrowpanel-menuitem-padding-block: 8px;
--arrowpanel-menuitem-padding-inline: 14px;
--uc-arrowpanel-menuicon-margin-inline: 14px;
@@ -22,7 +23,9 @@
--uc-panel-zoom-button-padding: 8px;
--uc-panel-zoom-button-inline-padding: 9px;
--uc-panel-zoom-padding-block: calc(var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block));
--uc-panel-zoom-padding-block: calc(
var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block)
);
--uc-autocomplete-panel-menuitem-margin: 4px;
--uc-autocomplete-panel-menuicon-padding-inline: 14px;
@@ -62,7 +65,9 @@ panel {
}
.widget-overflow-list .toolbarbutton-1:not(.toolbarbutton-combined) > .toolbarbutton-text,
.subviewbutton:not(#appMenu-zoom-controls > .subviewbutton) > .toolbarbutton-icon + .toolbarbutton-text,
.subviewbutton:not(#appMenu-zoom-controls > .subviewbutton)
> .toolbarbutton-icon
+ .toolbarbutton-text,
#appMenu-fxa-label2 > vbox {
padding-inline-start: var(--uc-arrowpanel-menuicon-margin-inline);
}
@@ -101,7 +106,9 @@ panel {
/* zoom controls */
#appMenu-zoom-controls {
border-top: 1px solid var(--panel-separator-color);
padding-inline: calc(var(--arrowpanel-menuitem-padding-inline) + var(--uc-arrowpanel-menuitem-margin-inline))
padding-inline: calc(
var(--arrowpanel-menuitem-padding-inline) + var(--uc-arrowpanel-menuitem-margin-inline)
)
var(--uc-arrowpanel-menuitem-margin-inline);
padding-block: var(--uc-panel-zoom-padding-block);
margin: var(--panel-separator-margin-vertical) 0 calc(var(--panel-separator-margin-vertical) * -1);
@@ -118,7 +125,9 @@ panel {
/* #appMenu-zoomReduce-button2, */
#appMenu-zoom-controls > #appMenu-fullscreen-button2 {
margin-left: calc((var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block)) * 2 + 1px);
margin-left: calc(
(var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block)) * 2 + 1px
);
}
#appMenu-zoom-controls > #appMenu-fullscreen-button2::before {
@@ -350,8 +359,21 @@ menuitem {
}
& .zen-toast {
padding: 10px;
border-radius: 12px;
:root[zen-right-side='true'] & {
translate: 100%;
}
--zen-toast-padding: 6px;
--zen-toast-max-height: 46px;
@media (-moz-platform: macos) {
--zen-toast-padding: 10px;
--zen-toast-max-height: 52px;
}
gap: 10px;
z-index: 1000;
padding: var(--zen-toast-padding);
border-radius: 14px;
background: linear-gradient(
170deg,
var(--zen-primary-color) -40%,
@@ -362,15 +384,35 @@ menuitem {
border: 1px solid rgba(0, 0, 0, 0.1);
display: flex;
font-weight: 600;
flex-direction: column;
align-items: center;
width: max-content;
font-size: medium;
font-size: small;
position: absolute;
transform-origin: top center;
max-height: var(--zen-toast-max-height);
min-height: var(--zen-toast-max-height);
font-size: 14px;
& .description {
opacity: 0.6;
font-size: small;
font-size: smaller;
}
& label {
margin-top: 0;
margin-bottom: 0;
}
& button {
width: min-content;
padding: 0 12px !important;
min-width: unset !important;
margin: 0px !important;
border-radius: 8px !important;
:root[zen-right-side='true'] & {
order: -1;
}
}
}
}

View File

@@ -23,10 +23,6 @@
display: none !important;
}
#alltabs-button {
display: none !important;
}
.private-browsing-indicator-with-label {
display: none !important;
}

View File

@@ -35,9 +35,17 @@
--zen-colors-hover-bg: color-mix(in srgb, var(--zen-primary-color) 90%, white 10%);
--zen-colors-primary-foreground: var(--zen-branding-bg-reverse);
--zen-colors-border: color-mix(in srgb, var(--zen-colors-secondary) 97%, black 3%);
--zen-colors-border-contrast: color-mix(in srgb, var(--zen-colors-secondary) 10%, rgba(181, 181, 181, 0.11) 90%);
--zen-colors-border-contrast: color-mix(
in srgb,
var(--zen-colors-secondary) 10%,
rgba(181, 181, 181, 0.11) 90%
);
--zen-colors-input-bg: color-mix(in srgb, var(--zen-primary-color) 1%, var(--zen-colors-tertiary) 99%);
--zen-colors-input-bg: color-mix(
in srgb,
var(--zen-primary-color) 1%,
var(--zen-colors-tertiary) 99%
);
--zen-dialog-background: var(--zen-colors-tertiary);
--zen-urlbar-background: color-mix(in srgb, var(--zen-primary-color) 3%, #f4f4f4 97%);
@@ -71,7 +79,11 @@
/* This is like the secondary button */
--in-content-button-background: transparent !important;
--in-content-button-text-color: var(--zen-secondary-btn-color) !important;
--in-content-button-background-hover: color-mix(in srgb, currentColor 3%, transparent 97%) !important;
--in-content-button-background-hover: color-mix(
in srgb,
currentColor 3%,
transparent 97%
) !important;
--button-bgcolor: var(--in-content-button-background) !important;
--button-hover-bgcolor: var(--in-content-button-background-hover) !important;
--button-hover-color: var(--in-content-button-text-color-hover) !important;
@@ -95,7 +107,11 @@
--link-color: var(--zen-branding-bg-reverse) !important;
--link-color-hover: var(--zen-colors-primary-foreground) !important;
--link-color-active: color-mix(in srgb, var(--zen-colors-primary-foreground) 80%, transparent 20%) !important;
--link-color-active: color-mix(
in srgb,
var(--zen-colors-primary-foreground) 80%,
transparent 20%
) !important;
--in-content-page-background: var(--zen-colors-tertiary) !important;
--zen-in-content-dialog-background: var(--zen-colors-tertiary);
@@ -110,7 +126,11 @@
--zen-toolbar-button-inner-padding: 6px;
--toolbarbutton-outer-padding: 4px;
--toolbarbutton-hover-background: color-mix(in srgb, var(--zen-branding-bg-reverse) 10%, transparent 90%);
--toolbarbutton-hover-background: color-mix(
in srgb,
var(--zen-branding-bg-reverse) 10%,
transparent 90%
);
/* Other colors */
--urlbar-box-bgcolor: var(--zen-urlbar-background) !important;
@@ -143,7 +163,8 @@
--fp-contextmenu-menuicon-margin-inline: 12px;
--fp-contextmenu-menuitem-margin-inline: calc(4px - var(--fp-contextmenu-menuitem-border-width));
--fp-contextmenu-menuitem-margin-block: 0px;
--fp-contextmenu-menuitem-margin: var(--fp-contextmenu-menuitem-margin-block) var(--fp-contextmenu-menuitem-margin-inline);
--fp-contextmenu-menuitem-margin: var(--fp-contextmenu-menuitem-margin-block)
var(--fp-contextmenu-menuitem-margin-inline);
--fp-contextmenu-separator-vertical: calc(4px - var(--fp-contextmenu-menuitem-border-width));
--fp-contextmenu-separator-horizontal: 0;
--fp-contextmenu-bgcolor: light-dark(Menu, rgb(43 42 51 / 0.95));
@@ -163,7 +184,11 @@
background: transparent;
--zen-themed-toolbar-bg-transparent: transparent;
@media -moz-pref('widget.windows.mica.toplevel-backdrop', 2) {
--zen-themed-toolbar-bg-transparent: color-mix(in srgb, var(--zen-themed-toolbar-bg) 35%, transparent 65%);
--zen-themed-toolbar-bg-transparent: color-mix(
in srgb,
var(--zen-themed-toolbar-bg) 35%,
transparent 65%
);
}
}
@@ -179,7 +204,11 @@
--zen-active-tab-scale: 0.98;
/* Define tab hover background color */
--tab-hover-background-color: color-mix(in srgb, var(--toolbarbutton-hover-background) 50%, transparent 50%);
--tab-hover-background-color: color-mix(
in srgb,
var(--toolbarbutton-hover-background) 50%,
transparent 50%
);
/* Nativity */
--zen-native-content-radius: var(--zen-border-radius);
@@ -218,20 +247,48 @@
:root {
--zen-in-content-dialog-background: var(--zen-branding-bg);
--zen-dark-color-mix-base: var(--zen-branding-bg);
--zen-colors-primary: color-mix(in srgb, var(--zen-primary-color) 20%, var(--zen-dark-color-mix-base) 80%);
--zen-colors-secondary: color-mix(in srgb, var(--zen-primary-color) 30%, var(--zen-dark-color-mix-base) 70%);
--zen-colors-tertiary: color-mix(in srgb, var(--zen-primary-color) 1%, var(--zen-dark-color-mix-base) 99%);
--zen-colors-primary: color-mix(
in srgb,
var(--zen-primary-color) 20%,
var(--zen-dark-color-mix-base) 80%
);
--zen-colors-secondary: color-mix(
in srgb,
var(--zen-primary-color) 30%,
var(--zen-dark-color-mix-base) 70%
);
--zen-colors-tertiary: color-mix(
in srgb,
var(--zen-primary-color) 1%,
var(--zen-dark-color-mix-base) 99%
);
--zen-colors-hover-bg: color-mix(in srgb, var(--zen-primary-color) 90%, var(--zen-dark-color-mix-base) 10%);
--zen-colors-hover-bg: color-mix(
in srgb,
var(--zen-primary-color) 90%,
var(--zen-dark-color-mix-base) 10%
);
--zen-colors-primary-foreground: color-mix(in srgb, var(--zen-primary-color) 80%, white 20%);
--zen-colors-input-bg: color-mix(in srgb, var(--zen-primary-color) 1%, var(--zen-dark-color-mix-base) 99%);
--zen-colors-input-bg: color-mix(
in srgb,
var(--zen-primary-color) 1%,
var(--zen-dark-color-mix-base) 99%
);
--zen-colors-border: color-mix(in srgb, var(--zen-colors-secondary) 20%, rgb(79, 79, 79) 80%);
--zen-colors-border-contrast: color-mix(in srgb, var(--zen-colors-secondary) 10%, rgba(255, 255, 255, 0.11) 90%);
--zen-colors-border-contrast: color-mix(
in srgb,
var(--zen-colors-secondary) 10%,
rgba(255, 255, 255, 0.11) 90%
);
--zen-dialog-background: var(--zen-dark-color-mix-base);
--zen-urlbar-background: color-mix(in srgb, var(--zen-primary-color) 4%, rgb(24, 24, 24) 96%);
--zen-browser-gradient-base: color-mix(in srgb, var(--zen-primary-color) 30%, var(--zen-dark-color-mix-base) 70%);
--zen-browser-gradient-base: color-mix(
in srgb,
var(--zen-primary-color) 30%,
var(--zen-dark-color-mix-base) 70%
);
}
}

View File

@@ -27,6 +27,9 @@
:root:not([zen-single-toolbar='true']) &[zen-floating-urlbar='true'] {
--urlbar-container-padding: 2px !important;
}
--urlbar-margin-inline: 5px;
--urlbar-container-padding: 5px;
}
:root:not([zen-single-toolbar='true']) #urlbar:not([zen-floating-urlbar='true']) {
@@ -95,10 +98,20 @@
position: relative;
}
:root[zen-single-toolbar='true'] #urlbar:not([breakout-extend='true']) #identity-box {
margin-inline-end: 0 !important;
&.chromeUI:not([pageproxystate='invalid']) #identity-icon-box {
border-radius: 10px !important;
#identity-icon-box {
outline: none !important;
}
:root[zen-single-toolbar='true'] #urlbar:not([breakout-extend='true']) {
& #urlbar-input {
cursor: default;
}
& #identity-box {
margin-inline-end: 0 !important;
&.chromeUI:not([pageproxystate='invalid']) #identity-icon-box {
border-radius: 10px !important;
}
}
}
@@ -126,18 +139,6 @@
margin-bottom: auto !important;
}
#identity-box:has(#notification-popup-box:not([hidden='true'])) #identity-icon-box,
#identity-box:has(#notification-popup-box:not([hidden='true'])) #identity-permission-box {
margin-right: 0px !important;
}
#identity-box:has(#identity-permission-box:is([hasPermissions], [hasSharingIcon])):not([pageproxystate='invalid'])
#identity-icon-box {
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
margin-right: 0 !important;
}
#tracking-protection-icon-container,
#page-action-buttons {
order: 2 !important;
@@ -149,25 +150,39 @@
#urlbar[breakout-extend='true'] {
z-index: 2;
--urlbar-margin-inline: 5px;
:root:not([zen-single-toolbar='true']) & .urlbar-input-container {
--urlbar-container-padding: 0px;
}
& #identity-box {
margin-right: var(--urlbar-margin-inline);
margin-right: calc(var(--urlbar-margin-inline) - 1px);
}
& #urlbar-background {
/* We cant have a transparent background with a backdrop-filter because on normal websites,
the backdrop woudn't work, we would need to apply a clip-path to the site and that's not recommended
due to performance issues */
background-color: light-dark(
--zen-urlbar-background-base: light-dark(
hsl(0, 0%, 100%),
color-mix(in srgb, hsl(0, 0%, 5%) 70%, var(--zen-colors-primary) 30%)
color-mix(in srgb, hsl(0, 0%, 5%) 80%, var(--zen-colors-primary) 20%)
);
@media -moz-pref('zen.theme.acrylic-elements') {
--zen-urlbar-background-transparent: color-mix(
in srgb,
var(--zen-urlbar-background-base) 70%,
transparent 30%
);
}
background-color: var(
--zen-urlbar-background-transparent,
var(--zen-urlbar-background-base)
) !important;
box-shadow: 0px 0px 90px -10px rgba(0, 0, 0, 0.6) !important;
box-shadow: 0px 0px 10rem -2px rgba(0, 0, 0, 0.9) !important;
backdrop-filter: none !important;
border-radius: 12px !important;
outline: 0.5px solid light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.15)) !important;
outline-offset: -2px;
@media -moz-pref('zen.theme.acrylic-elements') {
backdrop-filter: blur(42px) saturate(110%) brightness(0.25) contrast(100%) !important;
}
}
}
@@ -202,9 +217,9 @@
}
#urlbar[open]
:is(#tracking-protection-icon-container, .urlbar-page-action, .identity-box-button):not([hidden='true']):not(
#identity-permission-box
),
:is(#tracking-protection-icon-container, .urlbar-page-action, .identity-box-button):not(
[hidden='true']
):not(#identity-permission-box),
#urlbar:hover #identity-icon-box {
opacity: 1 !important;
margin-inline-start: 0 !important;
@@ -221,7 +236,7 @@
#urlbar:not([open]) {
#identity-box:not([pageproxystate='invalid']) {
order: 9;
order: 2;
}
}
@@ -242,6 +257,7 @@
margin-bottom: auto;
height: 24px; /* double 12px */
width: 24px;
padding: 4px !important;
&:hover {
background: var(--toolbarbutton-hover-background);
@@ -254,18 +270,15 @@
:root:not([zen-single-toolbar='true']) {
#notification-popup-box {
border-radius: 999px;
margin: 0 4px 0 0 !important;
padding: 0 4px;
min-width: calc(var(--urlbar-min-height) - 4px - 4 * var(--urlbar-container-padding)) !important;
height: calc(var(--urlbar-min-height) - 4px - 4 * var(--urlbar-container-padding)) !important;
justify-content: center;
gap: 8px;
background: transparent;
& > image {
padding: 0;
margin-top: auto;
margin-bottom: auto;
padding: 0;
}
}
}
@@ -280,7 +293,8 @@ button.popup-notification-dropmarker {
border-bottom-left-radius: 0 !important;
}
.panel-footer:has(button.popup-notification-dropmarker:not([hidden='true'])) button.popup-notification-secondary-button {
.panel-footer:has(button.popup-notification-dropmarker:not([hidden='true']))
button.popup-notification-secondary-button {
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
@@ -355,8 +369,11 @@ button.popup-notification-dropmarker {
/* Border radius on hover */
#urlbar .urlbar-page-action,
#urlbar #tracking-protection-icon-container,
#urlbar:not([breakout-extend='true']) #identity-box:is(:not(.chromeUI), [pageproxystate='invalid']) #identity-icon-box {
#urlbar:not([breakout-extend='true'])
#identity-box:is(:not(.chromeUI), [pageproxystate='invalid'])
#identity-icon-box {
border-radius: var(--urlbar-icon-border-radius) !important;
min-width: 30px;
}
/* Notification Stack */
@@ -477,6 +494,10 @@ button.popup-notification-dropmarker {
}
}
#urlbar-search-mode-indicator {
background-color: color-mix(in srgb, var(--zen-primary-color) 50%, transparent 50%) !important;
}
/* Code ~~stolen~~ taken inspiration from https://github.com/greeeen-dev/zen-arc-cmd-bar
*
* MIT License
@@ -547,6 +568,7 @@ button.popup-notification-dropmarker {
margin-right: 28px !important;
position: relative;
scale: 0.93;
transform-origin: right;
&::after {
content: '';
@@ -591,7 +613,11 @@ button.popup-notification-dropmarker {
&:hover {
.urlbarView-favicon,
& {
background-color: color-mix(in srgb, var(--zen-branding-bg-reverse) 5%, transparent 95%) !important;
background-color: color-mix(
in srgb,
var(--zen-branding-bg-reverse) 5%,
transparent 95%
) !important;
}
}

View File

@@ -69,7 +69,9 @@ document.addEventListener(
gZenThemePicker.openThemePicker(event);
break;
case 'cmd_zenChangeWorkspaceTab':
ZenWorkspaces.changeTabWorkspace(event.sourceEvent.target.getAttribute('zen-workspace-id'));
ZenWorkspaces.changeTabWorkspace(
event.sourceEvent.target.getAttribute('zen-workspace-id')
);
break;
case 'cmd_zenToggleTabsOnRight':
gZenVerticalTabsManager.toggleTabsOnRight();

View File

@@ -10,7 +10,11 @@
* FOR ANY WEBSITE THAT WOULD NEED TO USE THE ACCENT COLOR, ETC
*/
const kZenThemePrefsList = ['zen.theme.accent-color', 'zen.theme.border-radius', 'zen.theme.content-element-separation'];
const kZenThemePrefsList = [
'zen.theme.accent-color',
'zen.theme.border-radius',
'zen.theme.content-element-separation',
];
const kZenMaxElementSeparation = 12;
/**
@@ -79,7 +83,10 @@ var ZenThemeModifier = {
},
get elementSeparation() {
return Math.min(Services.prefs.getIntPref('zen.theme.content-element-separation'), kZenMaxElementSeparation);
return Math.min(
Services.prefs.getIntPref('zen.theme.content-element-separation'),
kZenMaxElementSeparation
);
},
/**

View File

@@ -21,7 +21,9 @@ XPCOMUtils.defineLazyPreferenceGetter(
true
);
ChromeUtils.defineLazyGetter(lazyCompactMode, 'mainAppWrapper', () => document.getElementById('zen-main-app-wrapper'));
ChromeUtils.defineLazyGetter(lazyCompactMode, 'mainAppWrapper', () =>
document.getElementById('zen-main-app-wrapper')
);
var gZenCompactModeManager = {
_flashTimeouts: {},
@@ -31,7 +33,8 @@ var gZenCompactModeManager = {
preInit() {
// Remove it before initializing so we can properly calculate the width
// of the sidebar at startup and avoid overflowing items not being hidden
const isCompactMode = lazyCompactMode.mainAppWrapper.getAttribute('zen-compact-mode') === 'true';
const isCompactMode =
lazyCompactMode.mainAppWrapper.getAttribute('zen-compact-mode') === 'true';
lazyCompactMode.mainAppWrapper.removeAttribute('zen-compact-mode');
this._wasInCompactMode = isCompactMode;
@@ -41,14 +44,23 @@ var gZenCompactModeManager = {
init() {
this.addMouseActions();
Services.prefs.addObserver('zen.tabs.vertical.right-side', this._updateSidebarIsOnRight.bind(this));
Services.prefs.addObserver(
'zen.tabs.vertical.right-side',
this._updateSidebarIsOnRight.bind(this)
);
gZenUIManager.addPopupTrackingAttribute(this.sidebar);
gZenUIManager.addPopupTrackingAttribute(document.getElementById('zen-appcontent-navbar-container'));
gZenUIManager.addPopupTrackingAttribute(
document.getElementById('zen-appcontent-navbar-container')
);
// Clear hover states when window state changes (minimize, maximize, etc.)
window.addEventListener('sizemodechange', () => this._clearAllHoverStates());
window.addEventListener('TabOpen', this._onTabOpen.bind(this));
this._canShowBackgroundTabToast = Services.prefs.getBoolPref(
'zen.view.compact.show-background-tab-toast',
true
);
if (AppConstants.platform == 'macosx') {
window.addEventListener('mouseover', (event) => {
@@ -65,7 +77,10 @@ var gZenCompactModeManager = {
},
set preference(value) {
if (this.preference === value || document.documentElement.hasAttribute('zen-compact-animating')) {
if (
this.preference === value ||
document.documentElement.hasAttribute('zen-compact-animating')
) {
if (typeof this._wasInCompactMode !== 'undefined') {
// We wont do anything with it anyway, so we remove it
delete this._wasInCompactMode;
@@ -100,7 +115,12 @@ var gZenCompactModeManager = {
if (aInstant) {
gZenVerticalTabsManager.recalculateURLBarHeight();
}
if (!aInstant && this.preference && lazyCompactMode.COMPACT_MODE_FLASH_ENABLED && !gZenGlanceManager._animating) {
if (
!aInstant &&
this.preference &&
lazyCompactMode.COMPACT_MODE_FLASH_ENABLED &&
!gZenGlanceManager._animating
) {
this.flashSidebar();
}
},
@@ -151,6 +171,13 @@ var gZenCompactModeManager = {
this._evenListeners.push(callback);
},
removeEventListener(callback) {
const index = this._evenListeners.indexOf(callback);
if (index !== -1) {
this._evenListeners.splice(index, 1);
}
},
async _updateEvent() {
// IF we are animating IN, call the callbacks first so we can calculate the width
// once the window buttons are shown
@@ -191,11 +218,15 @@ var gZenCompactModeManager = {
// Get the splitter width before hiding it (we need to hide it before animating on right)
document.documentElement.setAttribute('zen-compact-animating', 'true');
// We need to set the splitter width before hiding it
let splitterWidth = document.getElementById('zen-sidebar-splitter').getBoundingClientRect().width;
let splitterWidth = document
.getElementById('zen-sidebar-splitter')
.getBoundingClientRect().width;
const isCompactMode = this.preference;
const canHideSidebar =
Services.prefs.getBoolPref('zen.view.compact.hide-tabbar') || gZenVerticalTabsManager._hasSetSingleToolbar;
let canAnimate = lazyCompactMode.COMPACT_MODE_CAN_ANIMATE_SIDEBAR && !this.isSidebarPotentiallyOpen();
Services.prefs.getBoolPref('zen.view.compact.hide-tabbar') ||
gZenVerticalTabsManager._hasSetSingleToolbar;
let canAnimate =
lazyCompactMode.COMPACT_MODE_CAN_ANIMATE_SIDEBAR && !this.isSidebarPotentiallyOpen();
if (typeof this._wasInCompactMode !== 'undefined') {
canAnimate = false;
delete this._wasInCompactMode;
@@ -315,7 +346,9 @@ var gZenCompactModeManager = {
},
updateContextMenu() {
document.getElementById('zen-context-menu-compact-mode-toggle').setAttribute('checked', this.preference);
document
.getElementById('zen-context-menu-compact-mode-toggle')
.setAttribute('checked', this.preference);
const hideTabBar = Services.prefs.getBoolPref('zen.view.compact.hide-tabbar', false);
const hideToolbar = Services.prefs.getBoolPref('zen.view.compact.hide-toolbar', false);
@@ -329,7 +362,9 @@ var gZenCompactModeManager = {
_removeOpenStateOnUnifiedExtensions() {
// Fix for bug https://github.com/zen-browser/desktop/issues/1925
const buttons = document.querySelectorAll('toolbarbutton:is(#unified-extensions-button, .webextension-browser-action)');
const buttons = document.querySelectorAll(
'toolbarbutton:is(#unified-extensions-button, .webextension-browser-action)'
);
for (let button of buttons) {
button.removeAttribute('open');
}
@@ -412,9 +447,6 @@ var gZenCompactModeManager = {
addMouseActions() {
gURLBar.textbox.addEventListener('mouseenter', (event) => {
if (!gZenVerticalTabsManager._hasSetSingleToolbar) {
return;
}
if (event.target.closest('#urlbar[zen-floating-urlbar]')) {
// Ignore sidebar mouse enter if the urlbar is floating
this.clearFlashTimeout('has-hover' + gZenVerticalTabsManager._hasSetSingleToolbar);
@@ -433,7 +465,10 @@ var gZenCompactModeManager = {
if (event.type === 'mouseenter' && !event.target.matches(':hover')) return;
// Dont register the hover if the urlbar is floating and we are hovering over it
this.clearFlashTimeout('has-hover' + target.id);
if (document.documentElement.getAttribute('supress-primary-adjustment') === 'true' || this._hasHoveredUrlbar) {
if (
document.documentElement.getAttribute('supress-primary-adjustment') === 'true' ||
this._hasHoveredUrlbar
) {
return;
}
window.requestAnimationFrame(() => target.setAttribute('zen-has-hover', 'true'));
@@ -456,7 +491,10 @@ var gZenCompactModeManager = {
}
// If it's a child element but not the target, ignore the event
if (target.contains(event.explicitOriginalTarget) && event.explicitOriginalTarget !== target) {
if (
target.contains(event.explicitOriginalTarget) &&
event.explicitOriginalTarget !== target
) {
return;
}
@@ -466,16 +504,24 @@ var gZenCompactModeManager = {
if (
event.explicitOriginalTarget.closest('#urlbar[zen-floating-urlbar]') ||
document.documentElement.getAttribute('supress-primary-adjustment') === 'true' ||
(document.documentElement.getAttribute('supress-primary-adjustment') === 'true' &&
gZenVerticalTabsManager._hasSetSingleToolbar) ||
this._hasHoveredUrlbar
) {
return;
}
if (this.hoverableElements[i].keepHoverDuration) {
this.flashElement(target, this.hoverableElements[i].keepHoverDuration, 'has-hover' + target.id, 'zen-has-hover');
this.flashElement(
target,
this.hoverableElements[i].keepHoverDuration,
'has-hover' + target.id,
'zen-has-hover'
);
} else {
this._removeHoverFrames[target.id] = window.requestAnimationFrame(() => target.removeAttribute('zen-has-hover'));
this._removeHoverFrames[target.id] = window.requestAnimationFrame(() =>
target.removeAttribute('zen-has-hover')
);
}
};
@@ -498,7 +544,12 @@ var gZenCompactModeManager = {
}
window.cancelAnimationFrame(this._removeHoverFrames[target.id]);
this.flashElement(target, this.hideAfterHoverDuration, 'has-hover' + target.id, 'zen-has-hover');
this.flashElement(
target,
this.hideAfterHoverDuration,
'has-hover' + target.id,
'zen-has-hover'
);
document.addEventListener(
'mousemove',
() => {
@@ -558,11 +609,18 @@ var gZenCompactModeManager = {
);
},
_onTabOpen(event) {
const tab = event.target;
if (!tab.selected && this.preference && !this.isSidebarPotentiallyOpen()) {
async _onTabOpen(tab, inBackground) {
if (
inBackground &&
this.preference &&
!this.isSidebarPotentiallyOpen() &&
this._canShowBackgroundTabToast &&
!gZenGlanceManager._animating &&
!this._nextTimeWillBeActive
) {
gZenUIManager.showToast('zen-background-tab-opened-toast');
}
delete this._nextTimeWillBeActive;
},
};

View File

@@ -7,6 +7,11 @@
:root[zen-compact-mode='true']:not([customizing]):not([inDOMFullscreen='true']) {
%include ../tabs/zen-tabs/vertical-tabs-topbuttons-fix.css
& #urlbar {
visibility: visible;
}
@media -moz-pref('zen.view.compact.hide-tabbar') or -moz-pref('zen.view.use-single-toolbar') {
&:not([zen-compact-animating]) {
& #zen-sidebar-splitter {
@@ -49,10 +54,6 @@
/* Initial padding for when we are animating */
padding: 0 0 0 var(--zen-toolbox-padding) !important;
& #urlbar {
visibility: visible;
}
&:not([animate='true']) {
position: fixed;
z-index: 10;
@@ -110,17 +111,13 @@
}
#navigator-toolbox:not([animate='true']) #titlebar {
border-radius: calc(var(--zen-native-inner-radius) + var(--zen-element-separation) / 4);
padding: var(--zen-toolbox-padding) !important;
:root:not([zen-sidebar-expanded='true']) & {
padding: var(--zen-toolbox-padding) 0 !important;
max-width: var(--zen-sidebar-width);
}
position: relative;
background: var(--zen-dialog-background);
outline: 1px solid var(--zen-colors-border-contrast);
outline-offset: -1px;
min-width: var(--zen-toolbox-min-width);
box-shadow: var(--zen-big-shadow);
transition: visibility 0.15s; /* Same as the toolbox */
visibility: hidden;
@@ -133,16 +130,31 @@
margin-left: 0 !important;
}
@media -moz-pref('zen.view.compact.color-sidebar') {
background: var(--zen-main-browser-background-toolbar) !important;
background-attachment: fixed !important;
background-size: 2000px !important; /* Dont ask me why */
/* NOTE: We MUST not add a backdrop-filter if we want the URL
* bar to be floating correctly:
* https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_display/Containing_block#identifying_the_containing_block */
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--zen-dialog-background);
outline: 1px solid var(--zen-colors-border-contrast);
outline-offset: -1px;
box-shadow: var(--zen-big-shadow);
pointer-events: none;
z-index: -1;
border-radius: calc(var(--zen-native-inner-radius) + var(--zen-element-separation) / 4);
@media -moz-pref('zen.view.compact.color-sidebar') {
background: var(--zen-main-browser-background-toolbar) !important;
background-attachment: fixed !important;
background-size: 2000px !important;
@media -moz-pref('zen.theme.acrylic-elements') {
backdrop-filter: blur(42px) saturate(110%) brightness(0.25) contrast(100%) !important;
}
}
}
&::before {
&::after {
content: '';
position: absolute;
top: 0;
@@ -345,7 +357,7 @@
position: relative !important;
}
& #urlbar {
& #urlbar:not([breakout-extend='true']) {
opacity: 0 !important;
}
@@ -357,12 +369,12 @@
}
}
& #zen-appcontent-navbar-container[zen-has-hover],
& #zen-appcontent-navbar-container:hover,
& #zen-appcontent-navbar-container:focus-within,
& #zen-appcontent-navbar-container[zen-has-hover]:not(:has(#urlbar[zen-floating-urlbar='true']:hover)),
& #zen-appcontent-navbar-container[zen-user-show],
& #zen-appcontent-navbar-container[has-popup-menu],
& #zen-appcontent-navbar-container:has(*:is([panelopen='true'], [open='true']):not(.zen-compact-mode-ignore)) {
& #zen-appcontent-navbar-container:has(
*:is([panelopen='true'], [open='true'], #urlbar:focus-within, [breakout-extend='true']):not(#urlbar[zen-floating-urlbar='true']):not(.zen-compact-mode-ignore)
) {
opacity: 1;
border-top-width: 1px;

View File

@@ -36,17 +36,24 @@
onDownloadAdded: this.#handleNewDownload.bind(this),
});
} catch (error) {
console.error(`[${ZenDownloadAnimation.name}] Failed to set up download animation listeners: ${error}`);
console.error(
`[${ZenDownloadAnimation.name}] Failed to set up download animation listeners: ${error}`
);
}
}
#handleNewDownload() {
if (!Services.prefs.getBoolPref('zen.downloads.download-animation')) {
if (
!Services.prefs.getBoolPref('zen.downloads.download-animation') ||
!ZenMultiWindowFeature.isActiveWindow
) {
return;
}
if (!this.#lastClickPosition) {
console.warn(`[${ZenDownloadAnimation.name}] No recent click position available for animation`);
console.warn(
`[${ZenDownloadAnimation.name}] No recent click position available for animation`
);
return;
}
@@ -80,7 +87,10 @@
try {
const link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', 'chrome://browser/content/zen-styles/zen-download-arc-animation.css');
link.setAttribute(
'href',
'chrome://browser/content/zen-styles/zen-download-arc-animation.css'
);
this.shadowRoot.appendChild(link);
} catch (error) {
console.error(`[${ZenDownloadAnimationElement.name}] Error loading arc styles: ${error}`);
@@ -89,7 +99,9 @@
async initializeAnimation(startPosition) {
if (!startPosition) {
console.warn(`[${ZenDownloadAnimationElement.name}] No start position provided, skipping animation`);
console.warn(
`[${ZenDownloadAnimationElement.name}] No start position provided, skipping animation`
);
return;
}
@@ -102,13 +114,27 @@
// Calculate optimal arc parameters based on available space
const distance = this.#calculateDistance(startPosition, endPosition);
const { arcHeight, shouldArcDownward } = this.#calculateOptimalArc(startPosition, endPosition, distance);
const { arcHeight, shouldArcDownward } = this.#calculateOptimalArc(
startPosition,
endPosition,
distance
);
const distanceX = endPosition.clientX - startPosition.clientX;
const distanceY = endPosition.clientY - startPosition.clientY;
const arcSequence = this.#createArcAnimationSequence(distanceX, distanceY, arcHeight, shouldArcDownward);
const arcSequence = this.#createArcAnimationSequence(
distanceX,
distanceY,
arcHeight,
shouldArcDownward
);
// Start the download animation
await this.#startDownloadAnimation(areTabsPositionedRight, isDownloadButtonVisible, arcAnimationElement, arcSequence);
await this.#startDownloadAnimation(
areTabsPositionedRight,
isDownloadButtonVisible,
arcAnimationElement,
arcSequence
);
}
#areTabsOnRightSide() {
@@ -170,7 +196,8 @@
// Calculate available space for the arc
const availableTopSpace = Math.min(startPosition.clientY, endPosition.clientY);
const viewportHeight = window.innerHeight;
const availableBottomSpace = viewportHeight - Math.max(startPosition.clientY, endPosition.clientY);
const availableBottomSpace =
viewportHeight - Math.max(startPosition.clientY, endPosition.clientY);
// Determine if we should arc downward or upward based on available space
const shouldArcDownward = availableBottomSpace > availableTopSpace;
@@ -194,7 +221,12 @@
return Math.sqrt(distanceX * distanceX + distanceY * distanceY);
}
async #startDownloadAnimation(areTabsPositionedRight, isDownloadButtonVisible, arcAnimationElement, sequence) {
async #startDownloadAnimation(
areTabsPositionedRight,
isDownloadButtonVisible,
arcAnimationElement,
sequence
) {
try {
if (!isDownloadButtonVisible) {
this.#startBoxAnimation(areTabsPositionedRight);
@@ -272,7 +304,9 @@
sequence.offset.push(progress);
sequence.opacity.push(opacity);
sequence.transform.push(`translate(calc(${x}px - 50%), calc(${y}px - 50%)) rotate(${rotation}deg) scale(${scale})`);
sequence.transform.push(
`translate(calc(${x}px - 50%), calc(${y}px - 50%)) rotate(${rotation}deg) scale(${scale})`
);
}
return sequence;
@@ -285,7 +319,9 @@
async #startBoxAnimation(areTabsPositionedRight) {
// If animation is already in progress, don't start a new one
if (this.#isBoxAnimationRunning) {
console.warn(`[${ZenDownloadAnimationElement.name}] Box animation already running, skipping new request.`);
console.warn(
`[${ZenDownloadAnimationElement.name}] Box animation already running, skipping new request.`
);
return;
}
@@ -300,7 +336,9 @@
const wrapper = document.getElementById('zen-main-app-wrapper');
if (!wrapper) {
console.warn(`[${ZenDownloadAnimationElement.name}] Cannot start box animation, Wrapper element not found`);
console.warn(
`[${ZenDownloadAnimationElement.name}] Cannot start box animation, Wrapper element not found`
);
return;
}
@@ -357,7 +395,9 @@
this.#getBoxAnimationDurationMs()
);
} catch (error) {
console.error(`[${ZenDownloadAnimationElement.name}] Error during box entry animation: ${error}`);
console.error(
`[${ZenDownloadAnimationElement.name}] Error during box entry animation: ${error}`
);
this.#cleanBoxAnimation();
} finally {
this.#isBoxAnimationRunning = false;
@@ -406,7 +446,9 @@
}
).finished;
} catch (error) {
console.warn(`[${ZenDownloadAnimationElement.name}] Error during box exit animation: ${error}`);
console.warn(
`[${ZenDownloadAnimationElement.name}] Error during box exit animation: ${error}`
);
} finally {
this.#cleanBoxAnimation();
}
@@ -426,7 +468,10 @@
try {
this.#boxAnimationElement.remove();
} catch (error) {
console.error(`[${ZenDownloadAnimationElement.name}] Error removing box animation element: ${error}`, error);
console.error(
`[${ZenDownloadAnimationElement.name}] Error removing box animation element: ${error}`,
error
);
}
}
this.#cleanBoxAnimationState();
@@ -441,7 +486,12 @@
// Is 1 and no 0 because if you pin the download button in the overflow menu
// the download button is in the viewport but in the position 0,0 so this
// avoid this case
if (rect.bottom < 1 || rect.right < 1 || rect.top > window.innerHeight || rect.left > window.innerWidth) {
if (
rect.bottom < 1 ||
rect.right < 1 ||
rect.top > window.innerHeight ||
rect.left > window.innerWidth
) {
return false;
}

View File

@@ -87,7 +87,10 @@
gBrowser.pinTab(otherTab);
}
this._piningFolder = false;
gBrowser.verticalPinnedTabsContainer.insertBefore(group, gBrowser.verticalPinnedTabsContainer.lastChild);
gBrowser.verticalPinnedTabsContainer.insertBefore(
group,
gBrowser.verticalPinnedTabsContainer.lastChild
);
gBrowser.tabContainer._invalidateCachedTabs();
return true;
}

View File

@@ -23,13 +23,17 @@ tab-group[split-view-group] {
outline-color: var(--tab-selected-outline-color);
transition: scale 0.1s ease;
align-items: center;
--zen-split-view-active-tab-bg: color-mix(in srgb, var(--zen-toolbar-element-bg), transparent 40%);
--zen-split-view-active-tab-bg: color-mix(
in srgb,
var(--zen-toolbar-element-bg),
transparent 40%
);
:root:not([zen-sidebar-expanded='true']) & {
padding: 0 2px;
--tab-min-height: 30px;
--tab-collapsed-width: 38px;
margin: 0 4px;
margin: 2px 0;
--tab-min-width: 34px;
}

View File

@@ -19,8 +19,12 @@
false
);
ChromeUtils.defineLazyGetter(this, 'sidebarButtons', () => document.getElementById('zen-glance-sidebar-container'));
document.getElementById('tabbrowser-tabpanels').addEventListener('click', this.onOverlayClick.bind(this));
ChromeUtils.defineLazyGetter(this, 'sidebarButtons', () =>
document.getElementById('zen-glance-sidebar-container')
);
document
.getElementById('tabbrowser-tabpanels')
.addEventListener('click', this.onOverlayClick.bind(this));
Services.obs.addObserver(this, 'quit-application-requested');
this.#addSidebarButtonListeners();
@@ -80,7 +84,7 @@
}
getTabPosition(tab) {
return Math.max(gBrowser.pinnedTabCount, tab._tPos);
return tab._tPos;
}
createBrowserElement(url, currentTab, existingTab = null) {
@@ -93,7 +97,8 @@
};
currentTab._selected = true;
const newUUID = gZenUIManager.generateUuidv4();
const newTab = existingTab ?? gBrowser.addTrustedTab(Services.io.newURI(url).spec, newTabOptions);
const newTab =
existingTab ?? gBrowser.addTrustedTab(Services.io.newURI(url).spec, newTabOptions);
if (currentTab.hasAttribute('zenDefaultUserContextId')) {
newTab.setAttribute('zenDefaultUserContextId', true);
}
@@ -119,6 +124,11 @@
showSidebarButtons(animate = false) {
if (this.sidebarButtons.hasAttribute('hidden') && animate) {
if (gZenVerticalTabsManager._prefsRightSide) {
this.sidebarButtons.setAttribute('right', true);
} else {
this.sidebarButtons.setAttribute('right', false);
}
for (const button of this.sidebarButtons.querySelectorAll('toolbarbutton')) {
button.style.opacity = 0;
}
@@ -166,66 +176,69 @@
this.overlay.classList.add('zen-glance-overlay');
this.browserWrapper.removeAttribute('animate-end');
window.requestAnimationFrame(() => {
this.quickOpenGlance({ dontOpenButtons: true });
this.showSidebarButtons(true);
return new Promise((resolve) => {
window.requestAnimationFrame(() => {
this.quickOpenGlance({ dontOpenButtons: true });
this.showSidebarButtons(true);
gZenUIManager.motion.animate(
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer'),
{
scale: [1, 0.98],
backdropFilter: ['blur(0px)', 'blur(5px)'],
opacity: [1, 0.5],
},
{
duration: 0.4,
type: 'spring',
bounce: 0.2,
}
);
this.#currentBrowser.setAttribute('animate-glance-open', true);
this.overlay.removeAttribute('fade-out');
this.browserWrapper.setAttribute('animate', true);
const top = initialY + initialHeight / 2;
const left = initialX + initialWidth / 2;
this.browserWrapper.style.top = `${top}px`;
this.browserWrapper.style.left = `${left}px`;
this.browserWrapper.style.width = `${initialWidth}px`;
this.browserWrapper.style.height = `${initialHeight}px`;
this.browserWrapper.style.opacity = 0.8;
this.#glances.get(this.#currentGlanceID).originalPosition = {
top: this.browserWrapper.style.top,
left: this.browserWrapper.style.left,
width: this.browserWrapper.style.width,
height: this.browserWrapper.style.height,
};
this.browserWrapper.style.transform = 'translate(-50%, -50%)';
this.overlay.style.overflow = 'visible';
gZenUIManager.motion
.animate(
this.browserWrapper,
gZenUIManager.motion.animate(
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer'),
{
top: '50%',
left: '50%',
width: '85%',
height: '100%',
opacity: 1,
scale: [1, 0.98],
backdropFilter: ['blur(0px)', 'blur(5px)'],
opacity: [1, 0.5],
},
{
duration: 0.3,
duration: 0.4,
type: 'spring',
bounce: 0.2,
}
)
.then(() => {
this.#currentBrowser.removeAttribute('animate-glance-open');
this.overlay.style.removeProperty('overflow');
this.browserWrapper.removeAttribute('animate');
this.browserWrapper.setAttribute('animate-end', true);
this.browserWrapper.setAttribute('has-finished-animation', true);
this._animating = false;
this.animatingOpen = false;
});
);
this.#currentBrowser.setAttribute('animate-glance-open', true);
this.overlay.removeAttribute('fade-out');
this.browserWrapper.setAttribute('animate', true);
const top = initialY + initialHeight / 2;
const left = initialX + initialWidth / 2;
this.browserWrapper.style.top = `${top}px`;
this.browserWrapper.style.left = `${left}px`;
this.browserWrapper.style.width = `${initialWidth}px`;
this.browserWrapper.style.height = `${initialHeight}px`;
this.browserWrapper.style.opacity = 0.8;
this.#glances.get(this.#currentGlanceID).originalPosition = {
top: this.browserWrapper.style.top,
left: this.browserWrapper.style.left,
width: this.browserWrapper.style.width,
height: this.browserWrapper.style.height,
};
this.browserWrapper.style.transform = 'translate(-50%, -50%)';
this.overlay.style.overflow = 'visible';
gZenUIManager.motion
.animate(
this.browserWrapper,
{
top: '50%',
left: '50%',
width: '85%',
height: '100%',
opacity: 1,
},
{
duration: 0.3,
type: 'spring',
bounce: 0.2,
}
)
.then(() => {
this.#currentBrowser.removeAttribute('animate-glance-open');
this.overlay.style.removeProperty('overflow');
this.browserWrapper.removeAttribute('animate');
this.browserWrapper.setAttribute('animate-end', true);
this.browserWrapper.setAttribute('has-finished-animation', true);
this._animating = false;
this.animatingOpen = false;
resolve(this.#currentTab);
});
});
});
}
@@ -243,7 +256,12 @@
hasFocused = false,
skipPermitUnload = false,
} = {}) {
if (this._animating || !this.#currentBrowser || this.animatingOpen || this._duringOpening) {
if (
(this._animating && !onTabClose) ||
!this.#currentBrowser ||
(this.animatingOpen && !onTabClose) ||
this._duringOpening
) {
return;
}
@@ -266,7 +284,9 @@
this.browserWrapper.removeAttribute('has-finished-animation');
if (noAnimation) {
this._clearContainerStyles(this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer'));
this._clearContainerStyles(
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer')
);
this.quickCloseGlance({ closeCurrentTab: false });
return;
}
@@ -308,70 +328,78 @@
}
)
.then(() => {
this._clearContainerStyles(this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer'));
this._clearContainerStyles(
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer')
);
});
this.browserWrapper.style.opacity = 1;
gZenUIManager.motion
.animate(
this.browserWrapper,
{
...originalPosition,
opacity: 0,
},
{ type: 'spring', bounce: 0, duration: 0.5, easing: 'ease-in' }
)
.then(() => {
this.browserWrapper.removeAttribute('animate');
this.browserWrapper.removeAttribute('animate-end');
if (!this.#currentParentTab) {
return;
}
return new Promise((resolve) => {
gZenUIManager.motion
.animate(
this.browserWrapper,
{
...originalPosition,
opacity: 0,
},
{ type: 'spring', bounce: 0, duration: 0.5, easing: 'ease-in' }
)
.then(() => {
this.browserWrapper.removeAttribute('animate');
this.browserWrapper.removeAttribute('animate-end');
if (!this.#currentParentTab) {
return;
}
if (!onTabClose || quikcCloseZen) {
this.quickCloseGlance({ clearID: false });
}
this.overlay.removeAttribute('fade-out');
this.browserWrapper.removeAttribute('animate');
if (!onTabClose || quikcCloseZen) {
this.quickCloseGlance({ clearID: false });
}
this.overlay.removeAttribute('fade-out');
this.browserWrapper.removeAttribute('animate');
this.lastCurrentTab = this.#currentTab;
this.lastCurrentTab = this.#currentTab;
this.overlay.classList.remove('zen-glance-overlay');
gBrowser._getSwitcher().setTabStateNoAction(this.lastCurrentTab, gBrowser.AsyncTabSwitcher.STATE_UNLOADED);
this.overlay.classList.remove('zen-glance-overlay');
gBrowser
._getSwitcher()
.setTabStateNoAction(this.lastCurrentTab, gBrowser.AsyncTabSwitcher.STATE_UNLOADED);
if (!onTabClose) {
this.#currentParentTab._visuallySelected = false;
}
if (!onTabClose) {
this.#currentParentTab._visuallySelected = false;
}
// reset everything
this.browserWrapper = null;
this.overlay = null;
this.contentWrapper = null;
// reset everything
this.browserWrapper = null;
this.overlay = null;
this.contentWrapper = null;
this.lastCurrentTab.removeAttribute('zen-glance-tab');
this.lastCurrentTab._closingGlance = true;
this.lastCurrentTab.removeAttribute('zen-glance-tab');
this.lastCurrentTab._closingGlance = true;
if (!isDifferent) {
gBrowser.selectedTab = this.#currentParentTab;
}
this._ignoreClose = true;
gBrowser.removeTab(this.lastCurrentTab, { animate: true, skipPermitUnload: true });
gBrowser.tabContainer._invalidateCachedTabs();
if (!isDifferent) {
gBrowser.selectedTab = this.#currentParentTab;
}
this._ignoreClose = true;
gBrowser.removeTab(this.lastCurrentTab, { animate: true, skipPermitUnload: true });
gBrowser.tabContainer._invalidateCachedTabs();
this.#currentParentTab.removeAttribute('glance-id');
this.#currentParentTab.removeAttribute('glance-id');
this.#glances.delete(this.#currentGlanceID);
this.#currentGlanceID = setNewID;
this.#glances.delete(this.#currentGlanceID);
this.#currentGlanceID = setNewID;
this.lastCurrentTab = null;
this._duringOpening = false;
this.lastCurrentTab = null;
this._duringOpening = false;
this._animating = false;
this.closingGlance = false;
this._animating = false;
this.closingGlance = false;
if (this.#currentGlanceID) {
this.quickOpenGlance();
}
});
if (this.#currentGlanceID) {
this.quickOpenGlance();
}
resolve();
});
});
}
quickOpenGlance({ dontOpenButtons = false } = {}) {
@@ -383,7 +411,9 @@
this.showSidebarButtons();
}
const parentBrowserContainer = this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer');
const parentBrowserContainer = this.#currentParentTab.linkedBrowser.closest(
'.browserSidebarContainer'
);
parentBrowserContainer.classList.add('zen-glance-background');
parentBrowserContainer.classList.remove('zen-glance-overlay');
parentBrowserContainer.classList.add('deck-selected');
@@ -401,16 +431,25 @@
this._duringOpening = false;
}
quickCloseGlance({ closeCurrentTab = true, closeParentTab = true, justAnimateParent = false, clearID = true } = {}) {
quickCloseGlance({
closeCurrentTab = true,
closeParentTab = true,
justAnimateParent = false,
clearID = true,
} = {}) {
const parentHasBrowser = !!this.#currentParentTab.linkedBrowser;
this.hideSidebarButtons();
if (parentHasBrowser) {
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('zen-glance-background');
this.#currentParentTab.linkedBrowser
.closest('.browserSidebarContainer')
.classList.remove('zen-glance-background');
}
if (!justAnimateParent && this.overlay) {
if (parentHasBrowser) {
if (closeParentTab) {
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('deck-selected');
this.#currentParentTab.linkedBrowser
.closest('.browserSidebarContainer')
.classList.remove('deck-selected');
}
this.#currentParentTab.linkedBrowser.zenModeActive = false;
}
@@ -471,7 +510,9 @@
setTimeout(() => {
gBrowser.selectedTab = curTab;
if (prevTab?.linkedBrowser) {
prevTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('deck-selected');
prevTab.linkedBrowser
.closest('.browserSidebarContainer')
.classList.remove('deck-selected');
}
}, 0);
} else if (gBrowser.selectedTab === this.#currentTab) {
@@ -495,7 +536,11 @@
this._ignoreClose = false;
return false;
}
this.closeGlance({ onTabClose: true, setNewID: isDifferent ? oldGlanceID : null, isDifferent });
this.closeGlance({
onTabClose: true,
setNewID: isDifferent ? oldGlanceID : null,
isDifferent,
});
// only keep continueing tab close if we are not on the currently selected tab
return !isDifferent;
}
@@ -513,7 +558,11 @@
}
// https://github.com/zen-browser/desktop/issues/7173: Only glance up links that are http(s) or file
const url2Spec = url2.spec;
if (!url2Spec.startsWith('http') && !url2Spec.startsWith('https') && !url2Spec.startsWith('file')) {
if (
!url2Spec.startsWith('http') &&
!url2Spec.startsWith('https') &&
!url2Spec.startsWith('file')
) {
return false;
}
return Services.io.newURI(url1).host !== url2.host;
@@ -543,7 +592,13 @@
if (this.shouldOpenTabInGlance(tab, uri)) {
const browserRect = gBrowser.tabbox.getBoundingClientRect();
this.openGlance(
{ url: undefined, x: browserRect.width / 2, y: browserRect.height / 2, width: 0, height: 0 },
{
url: undefined,
x: browserRect.width / 2,
y: browserRect.height / 2,
width: 0,
height: 0,
},
tab,
tab.owner
);
@@ -567,9 +622,7 @@
this.animatingFullOpen = true;
this.#currentTab.setAttribute('zen-dont-split-glance', true);
gBrowser.zenInsertTabAtIndex(this.#currentTab, {
index: this.getTabPosition(this.#currentTab),
});
gBrowser.zenInsertTabAtIndex(this.#currentTab, this.getTabPosition(this.#currentTab));
this.#currentTab.removeAttribute('zen-glance-tab');
this._clearContainerStyles(this.browserWrapper);
@@ -578,7 +631,9 @@
this.#currentTab.removeAttribute('glance-id');
this.#currentParentTab.removeAttribute('glance-id');
gBrowser.selectedTab = this.#currentTab;
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('zen-glance-background');
this.#currentParentTab.linkedBrowser
.closest('.browserSidebarContainer')
.classList.remove('zen-glance-background');
this.#currentParentTab._visuallySelected = false;
this.hideSidebarButtons();
if (gReduceMotion || forSplit) {

View File

@@ -46,7 +46,11 @@ export class ZenGlanceChild extends JSWindowActorChild {
this.contentWindow.addEventListener('mouseup', this.mouseUpListener);
this.contentWindow.document.removeEventListener('click', this.clickListener);
} else if (activationMethod === 'ctrl' || activationMethod === 'alt' || activationMethod === 'shift') {
} else if (
activationMethod === 'ctrl' ||
activationMethod === 'alt' ||
activationMethod === 'shift'
) {
this.contentWindow.document.addEventListener('click', this.clickListener, { capture: true });
this.contentWindow.removeEventListener('mousedown', this.mouseDownListener);

View File

@@ -18,7 +18,13 @@
padding: 5px;
gap: 12px;
left: 2%;
&[right='true'] {
right: 2%;
}
&[right='false'] {
left: 2%;
}
& toolbarbutton {
width: 32px;

View File

@@ -222,9 +222,11 @@ class KeyShortcutModifiers {
this.#shift == other.#shift &&
this.#control == other.#control &&
(AppConstants.platform == 'macosx'
? (this.#meta || this.#accel) == (other.#meta || other.#accel) && this.#control == other.#control
? (this.#meta || this.#accel) == (other.#meta || other.#accel) &&
this.#control == other.#control
: // In other platforms, we can have control and accel counting as the same thing
this.#meta == other.#meta && (this.#control || this.#accel) == (other.#control || other.#accel))
this.#meta == other.#meta &&
(this.#control || this.#accel) == (other.#control || other.#accel))
);
}
@@ -295,7 +297,18 @@ class KeyShortcut {
#reserved = false;
#internal = false;
constructor(id, key, keycode, group, modifiers, action, l10nId, disabled = false, reserved = false, internal = false) {
constructor(
id,
key,
keycode,
group,
modifiers,
action,
l10nId,
disabled = false,
reserved = false,
internal = false
) {
this.#id = id;
this.#key = key?.toLowerCase();
this.#keycode = keycode;
@@ -359,7 +372,10 @@ class KeyShortcut {
key.getAttribute('key'),
key.getAttribute('keycode'),
group ??
KeyShortcut.getGroupFromL10nId(KeyShortcut.sanitizeL10nId(key.getAttribute('data-l10n-id')), key.getAttribute('id')),
KeyShortcut.getGroupFromL10nId(
KeyShortcut.sanitizeL10nId(key.getAttribute('data-l10n-id')),
key.getAttribute('id')
),
KeyShortcutModifiers.parseFromXHTMLAttribute(key.getAttribute('modifiers')),
key.getAttribute('command'),
key.getAttribute('data-l10n-id'),
@@ -986,7 +1002,10 @@ var gZenKeyboardShortcutsManager = {
// handled wont wait for the async function to finish.
void this.getZenKeyset();
this._hasCleared = Services.prefs.getBoolPref('zen.keyboard.shortcuts.disable-mainkeyset-clear', false);
this._hasCleared = Services.prefs.getBoolPref(
'zen.keyboard.shortcuts.disable-mainkeyset-clear',
false
);
window.addEventListener('zen-devtools-keyset-added', this._hasAddedDevtoolShortcuts.bind(this));
this.init();
@@ -1225,7 +1244,10 @@ var gZenKeyboardShortcutsManager = {
continue;
}
if (targetShortcut.getModifiers().equals(modifiers) && targetShortcut.getKeyNameOrCode()?.toLowerCase() == realShortcut) {
if (
targetShortcut.getModifiers().equals(modifiers) &&
targetShortcut.getKeyNameOrCode()?.toLowerCase() == realShortcut
) {
return true;
}
}

View File

@@ -152,11 +152,21 @@
}
if (linkedBrowser?.browsingContext?.mediaController) {
this.deinitMediaController(linkedBrowser.browsingContext.mediaController, true, isCurrentBrowser, true);
this.deinitMediaController(
linkedBrowser.browsingContext.mediaController,
true,
isCurrentBrowser,
true
);
}
}
async deinitMediaController(mediaController, shouldForget = true, shouldOverride = true, shouldHide = true) {
async deinitMediaController(
mediaController,
shouldForget = true,
shouldOverride = true,
shouldHide = true
) {
if (shouldForget && mediaController) {
mediaController.removeEventListener('pictureinpicturemodechange', this.onPipModeChange);
mediaController.removeEventListener('positionstatechange', this.onPositionstateChange);
@@ -230,7 +240,8 @@
if (!this.isSharing) {
if (!this._currentMediaController) return;
if (this._currentMediaController.isBeingUsedInPIPModeOrFullscreen) return this.hideMediaControls();
if (this._currentMediaController.isBeingUsedInPIPModeOrFullscreen)
return this.hideMediaControls();
this.updatePipButton();
}
@@ -280,11 +291,15 @@
setupMediaControlUI(metadata, positionState) {
this.updatePipButton();
if (!this.mediaControlBar.classList.contains('playing') && this._currentMediaController.isPlaying) {
if (
!this.mediaControlBar.classList.contains('playing') &&
this._currentMediaController.isPlaying
) {
this.mediaControlBar.classList.add('playing');
}
const iconURL = this._currentBrowser.mIconURL || `page-icon:${this._currentBrowser.currentURI.spec}`;
const iconURL =
this._currentBrowser.mIconURL || `page-icon:${this._currentBrowser.currentURI.spec}`;
this.mediaFocusButton.style.listStyleImage = `url(${iconURL})`;
this.mediaTitle.textContent = metadata.title || '';
@@ -309,7 +324,8 @@
this.updateMuteState();
this.switchController();
if (!mediaController.isActive || this._currentBrowser?.browserId === browser.browserId) return;
if (!mediaController.isActive || this._currentBrowser?.browserId === browser.browserId)
return;
const metadata = mediaController.getMetadata();
const positionState = mediaController.getPositionState();
@@ -385,7 +401,12 @@
}
_onDeactivated(event) {
this.deinitMediaController(event.target, true, event.target.id === this._currentMediaController.id, true);
this.deinitMediaController(
event.target,
true,
event.target.id === this._currentMediaController.id,
true
);
this.switchController();
}
@@ -455,7 +476,8 @@
const elapsedTime = Math.floor((Date.now() - nextController.lastUpdated) / 1000);
this.setupMediaControlUI(nextController.controller.getMetadata(), {
position: nextController.position + (nextController.controller.isPlaying ? elapsedTime : 0),
position:
nextController.position + (nextController.controller.isPlaying ? elapsedTime : 0),
duration: nextController.duration,
playbackRate: nextController.playbackRate,
});
@@ -475,7 +497,8 @@
this._mediaUpdateInterval = null;
}
if (this._currentDuration >= 900_000) return this.mediaControlBar.setAttribute('media-position-hidden', 'true');
if (this._currentDuration >= 900_000)
return this.mediaControlBar.setAttribute('media-position-hidden', 'true');
else this.mediaControlBar.removeAttribute('media-position-hidden');
if (!this._currentDuration) return;
@@ -619,18 +642,26 @@
onMicrophoneMuteToggle() {
if (this._currentBrowser) {
const shouldMute = this.mediaControlBar.hasAttribute('mic-muted') ? 'webrtc:UnmuteMicrophone' : 'webrtc:MuteMicrophone';
const shouldMute = this.mediaControlBar.hasAttribute('mic-muted')
? 'webrtc:UnmuteMicrophone'
: 'webrtc:MuteMicrophone';
this._currentBrowser.browsingContext.currentWindowGlobal.getActor('WebRTC').sendAsyncMessage(shouldMute);
this._currentBrowser.browsingContext.currentWindowGlobal
.getActor('WebRTC')
.sendAsyncMessage(shouldMute);
this.mediaControlBar.toggleAttribute('mic-muted');
}
}
onCameraMuteToggle() {
if (this._currentBrowser) {
const shouldMute = this.mediaControlBar.hasAttribute('camera-muted') ? 'webrtc:UnmuteCamera' : 'webrtc:MuteCamera';
const shouldMute = this.mediaControlBar.hasAttribute('camera-muted')
? 'webrtc:UnmuteCamera'
: 'webrtc:MuteCamera';
this._currentBrowser.browsingContext.currentWindowGlobal.getActor('WebRTC').sendAsyncMessage(shouldMute);
this._currentBrowser.browsingContext.currentWindowGlobal
.getActor('WebRTC')
.sendAsyncMessage(shouldMute);
this.mediaControlBar.toggleAttribute('camera-muted');
}
}
@@ -644,7 +675,9 @@
if (!this._currentBrowser) return;
if (this.isSharing) return;
const { totalPipCount, totalPipDisabled } = PictureInPicture.getEligiblePipVideoCount(this._currentBrowser);
const { totalPipCount, totalPipDisabled } = PictureInPicture.getEligiblePipVideoCount(
this._currentBrowser
);
const canPip = totalPipCount === 1 || (totalPipDisabled > 0 && lazy.RESPECT_PIP_DISABLED);
this.mediaControlBar.toggleAttribute('can-pip', canPip);

View File

@@ -2,6 +2,7 @@
class="browser-toolbar customization-target zen-sidebar-toolbar"
context="toolbar-context-menu"
mode="icons"
fullscreentoolbar="true"
hidden="true">
<toolbaritem>
<vbox id="zen-media-main-vbox">

View File

@@ -3,7 +3,18 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
var ZenThemesCommon = {
kZenColors: ['#aac7ff', '#74d7cb', '#a0d490', '#dec663', '#ffb787', '#dec1b1', '#ffb1c0', '#ddbfc3', '#f6b0ea', '#d4bbff'],
kZenColors: [
'#aac7ff',
'#74d7cb',
'#a0d490',
'#dec663',
'#ffb787',
'#dec1b1',
'#ffb1c0',
'#ddbfc3',
'#f6b0ea',
'#d4bbff',
],
get browsers() {
return Services.wm.getEnumerator('navigator:browser');
@@ -25,35 +36,27 @@ var ZenThemesCommon = {
return PathUtils.join(this.themesRootPath, themeId);
},
resetThemesCache() {
this.themes = null;
},
async getThemes() {
if (!this.themes) {
if (!(await IOUtils.exists(this.themesDataFile))) {
await IOUtils.writeJSON(this.themesDataFile, {});
}
try {
this.themes = await IOUtils.readJSON(this.themesDataFile);
} catch (e) {
// If we have a corrupted file, reset it
await IOUtils.writeJSON(this.themesDataFile, {});
this.themes = {};
gNotificationBox.appendNotification(
'zen-themes-corrupted',
{
label: { 'l10n-id': 'zen-themes-corrupted' },
image: 'chrome://browser/skin/notification-icons/persistent-storage-blocked.svg',
priority: gNotificationBox.PRIORITY_WARNING_HIGH,
},
[]
);
}
if (!(await IOUtils.exists(this.themesDataFile))) {
await IOUtils.writeJSON(this.themesDataFile, {});
}
return this.themes;
let themes = {};
try {
themes = await IOUtils.readJSON(this.themesDataFile);
if (themes === null || typeof themes !== 'object') {
throw new Error('Themes data file is null');
}
} catch (e) {
// If we have a corrupted file, reset it
await IOUtils.writeJSON(this.themesDataFile, {});
Services.wm
.getMostRecentWindow('navigator:browser')
.gZenUIManager.showToast('zen-themes-corrupted', {
timeout: 8000,
});
}
return themes;
},
async getThemePreferences(theme) {
@@ -72,7 +75,8 @@ var ZenThemesCommon = {
const newThemePreferences = [];
for (let [entry, label] of Object.entries(preferences)) {
const [_, negation = '', os = '', property] = /(!?)(?:(macos|windows|linux):)?([A-z0-9-_.]+)/g.exec(entry);
const [_, negation = '', os = '', property] =
/(!?)(?:(macos|windows|linux):)?([A-Za-z0-9-_.]+)/g.exec(entry);
const isNegation = negation === '!';
if (
@@ -94,7 +98,8 @@ var ZenThemesCommon = {
}
return preferences.filter(
({ disabledOn = [] }) => !disabledOn.includes(gZenOperatingSystemCommonUtils.currentOperatingSystem)
({ disabledOn = [] }) =>
!disabledOn.includes(gZenOperatingSystemCommonUtils.currentOperatingSystem)
);
},

View File

@@ -55,11 +55,15 @@ var gZenThemesImporter = new (class {
constructor() {
try {
window.SessionStore.promiseInitialized.then(async () => {
if (Services.prefs.getBoolPref('zen.themes.disable-all', false) || Services.appinfo.inSafeMode) {
if (
Services.prefs.getBoolPref('zen.themes.disable-all', false) ||
Services.appinfo.inSafeMode
) {
console.log('[ZenThemesImporter]: Disabling all themes.');
return;
}
await ZenThemesCommon.getThemes(); // Check for any errors in the themes data file
const themes = await this.getEnabledThemes();
const themesWithPreferences = await Promise.all(
@@ -83,13 +87,23 @@ var gZenThemesImporter = new (class {
console.error('[ZenThemesImporter]: Error importing Zen Themes: ', e);
}
Services.prefs.addObserver('zen.themes.updated-value-observer', this.rebuildThemeStylesheet.bind(this), false);
Services.prefs.addObserver('zen.themes.disable-all', this.handleDisableThemes.bind(this), false);
Services.prefs.addObserver(
'zen.themes.updated-value-observer',
this.rebuildThemeStylesheet.bind(this),
false
);
Services.prefs.addObserver(
'zen.themes.disable-all',
this.handleDisableThemes.bind(this),
false
);
}
get sss() {
if (!this._sss) {
this._sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
this._sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(
Ci.nsIStyleSheetService
);
}
return this._sss;
}
@@ -118,7 +132,9 @@ var gZenThemesImporter = new (class {
}
getStylesheetURIForTheme(theme) {
return Services.io.newFileURI(new FileUtils.File(PathUtils.join(ZenThemesCommon.getThemeFolder(theme.id), 'chrome.css')));
return Services.io.newFileURI(
new FileUtils.File(PathUtils.join(ZenThemesCommon.getThemeFolder(theme.id), 'chrome.css'))
);
}
async insertStylesheet() {
@@ -133,16 +149,15 @@ var gZenThemesImporter = new (class {
async removeStylesheet() {
await this.sss.unregisterSheet(this.styleSheetURI, this.sss.AGENT_SHEET);
const rv = this.sss.sheetRegistered(this.styleSheetURI, this.sss.AGENT_SHEET);
await IOUtils.remove(this.styleSheetPath, { ignoreAbsent: true });
if (!this.sss.sheetRegistered(this.styleSheetURI, this.sss.AGENT_SHEET) && !(await IOUtils.exists(this.styleSheetPath))) {
if (!rv && !(await IOUtils.exists(this.styleSheetPath))) {
console.debug('[ZenThemesImporter]: Sheet successfully unregistered');
}
}
async rebuildThemeStylesheet() {
ZenThemesCommon.themes = null;
await this.removeStylesheet();
const themes = await this.getEnabledThemes();
@@ -169,7 +184,9 @@ var gZenThemesImporter = new (class {
async getEnabledThemes() {
const themeObject = await ZenThemesCommon.getThemes();
const themes = Object.values(themeObject).filter((theme) => theme.enabled === undefined || theme.enabled);
const themes = Object.values(themeObject).filter(
(theme) => theme.enabled === undefined || theme.enabled
);
const themeList = themes.map(({ name }) => name).join(', ');
@@ -198,7 +215,9 @@ var gZenThemesImporter = new (class {
case 'checkbox': {
const value = Services.prefs.getBoolPref(property, false);
if (typeof defaultValue !== 'boolean') {
console.log(`[ZenThemesImporter]: Warning, invalid data type received for expected type boolean, skipping.`);
console.log(
`[ZenThemesImporter]: Warning, invalid data type received for expected type boolean, skipping.`
);
continue;
}
@@ -212,7 +231,9 @@ var gZenThemesImporter = new (class {
const value = Services.prefs.getStringPref(property, 'zen-property-no-saved');
if (typeof defaultValue !== 'string' && typeof defaultValue !== 'number') {
console.log(`[ZenThemesImporter]: Warning, invalid data type received (${typeof defaultValue}), skipping.`);
console.log(
`[ZenThemesImporter]: Warning, invalid data type received (${typeof defaultValue}), skipping.`
);
continue;
}
@@ -228,7 +249,7 @@ var gZenThemesImporter = new (class {
writeToDom(themesWithPreferences) {
for (const browser of ZenMultiWindowFeature.browsers) {
for (const { enabled, preferences, name } of themesWithPreferences) {
const sanitizedName = `theme-${name?.replaceAll(/\s/g, '-')?.replaceAll(/[^A-z_-]+/g, '')}`;
const sanitizedName = `theme-${name?.replaceAll(/\s/g, '-')?.replaceAll(/[^A-Za-z_-]+/g, '')}`;
if (enabled !== undefined && !enabled) {
const element = browser.document.getElementById(sanitizedName);
@@ -271,9 +292,13 @@ var gZenThemesImporter = new (class {
case 'string': {
if (value === '') {
browser.document.querySelector(':root').style.removeProperty(`--${sanitizedProperty}`);
browser.document
.querySelector(':root')
.style.removeProperty(`--${sanitizedProperty}`);
} else {
browser.document.querySelector(':root').style.setProperty(`--${sanitizedProperty}`, value);
browser.document
.querySelector(':root')
.style.setProperty(`--${sanitizedProperty}`, value);
}
break;
}
@@ -288,7 +313,6 @@ var gZenThemesImporter = new (class {
async writeStylesheet(themeList = []) {
const themes = [];
ZenThemesCommon.themes = null;
for (let theme of themeList) {
theme._chromeURL = this.getStylesheetURIForTheme(theme).spec;
@@ -309,5 +333,8 @@ gZenActorsManager.addJSWindowActor('ZenThemeMarketplace', {
DOMContentLoaded: {},
},
},
matches: [...Services.prefs.getStringPref('zen.injections.match-urls').split(','), 'about:preferences'],
matches: [
...Services.prefs.getStringPref('zen.injections.match-urls').split(','),
'about:preferences',
],
});

View File

@@ -31,7 +31,10 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
}
this.initiateThemeMarketplace();
this.contentWindow.document.addEventListener('ZenCheckForThemeUpdates', this.checkForThemeUpdates.bind(this));
this.contentWindow.document.addEventListener(
'ZenCheckForThemeUpdates',
this.checkForThemeUpdates.bind(this)
);
}
collectRiceMetadata() {

View File

@@ -75,32 +75,40 @@ export class ZenThemeMarketplaceParent extends JSWindowActorParent {
console.info('ZenThemeMarketplaceParent: Checking for theme updates');
let updates = [];
this._themes = null;
const themes = await this.getThemes();
for (const theme of Object.values(await this.getThemes())) {
try {
const themeInfo = await this.sendQuery('ZenThemeMarketplace:GetThemeInfo', { themeId: theme.id });
const themeInfo = await this.sendQuery('ZenThemeMarketplace:GetThemeInfo', {
themeId: theme.id,
});
if (!themeInfo) {
continue;
}
if (!this.compareVersions(themeInfo.version, theme.version || '0.0.0') && themeInfo.version != theme.version) {
console.info('ZenThemeMarketplaceParent: Theme update found', theme.id, theme.version, themeInfo.version);
if (
!this.compareVersions(themeInfo.version, theme.version || '0.0.0') &&
themeInfo.version != theme.version
) {
console.info(
'ZenThemeMarketplaceParent: Theme update found',
theme.id,
theme.version,
themeInfo.version
);
themeInfo.enabled = theme.enabled;
updates.push(themeInfo);
await this.removeTheme(theme.id, false);
this._themes[themeInfo.id] = themeInfo;
themes[themeInfo.id] = themeInfo;
}
} catch (e) {
console.error('ZenThemeMarketplaceParent: Error checking for theme updates', e);
}
}
await this.updateThemes(this._themes);
await this.updateThemes(themes);
this.sendAsyncMessage('ZenThemeMarketplace:CheckForUpdatesFinished', { updates });
}
@@ -110,17 +118,13 @@ export class ZenThemeMarketplaceParent extends JSWindowActorParent {
}
async getThemes() {
if (!this._themes) {
if (!(await IOUtils.exists(this.themesDataFile))) {
await IOUtils.writeJSON(this.themesDataFile, {});
}
this._themes = await IOUtils.readJSON(this.themesDataFile);
}
return this._themes;
return await IOUtils.readJSON(this.themesDataFile);
}
async updateThemes(themes) {
this._themes = themes;
async updateThemes(themes = undefined) {
if (!themes) {
themes = await this.getThemes();
}
await IOUtils.writeJSON(this.themesDataFile, themes);
await this.checkForThemeChanges();
}
@@ -156,7 +160,10 @@ export class ZenThemeMarketplaceParent extends JSWindowActorParent {
await this.downloadUrlToFile(theme.style, PathUtils.join(themePath, 'chrome.css'), true);
await this.downloadUrlToFile(theme.readme, PathUtils.join(themePath, 'readme.md'));
if (theme.preferences) {
await this.downloadUrlToFile(theme.preferences, PathUtils.join(themePath, 'preferences.json'));
await this.downloadUrlToFile(
theme.preferences,
PathUtils.join(themePath, 'preferences.json')
);
}
}

View File

@@ -3,12 +3,9 @@
# 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/.
BROWSER_CHROME_MANIFESTS += [
"tests/browser.toml",
]
DIRS += [
"glance",
"mods"
"mods",
"tests",
"toolkit",
]

View File

@@ -82,21 +82,39 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
init() {
this.handleTabEvent = this._handleTabEvent.bind(this);
XPCOMUtils.defineLazyPreferenceGetter(this, 'minResizeWidth', 'zen.splitView.min-resize-width', 7);
XPCOMUtils.defineLazyPreferenceGetter(this, '_edgeHoverSize', 'zen.splitView.rearrange-edge-hover-size', 24);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'minResizeWidth',
'zen.splitView.min-resize-width',
7
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'_edgeHoverSize',
'zen.splitView.rearrange-edge-hover-size',
24
);
ChromeUtils.defineLazyGetter(this, 'overlay', () => document.getElementById('zen-splitview-overlay'));
ChromeUtils.defineLazyGetter(this, 'overlay', () =>
document.getElementById('zen-splitview-overlay')
);
ChromeUtils.defineLazyGetter(this, 'dropZone', () => document.getElementById('zen-splitview-dropzone'));
ChromeUtils.defineLazyGetter(this, 'dropZone', () =>
document.getElementById('zen-splitview-dropzone')
);
window.addEventListener('TabClose', this.handleTabClose.bind(this));
window.addEventListener('TabSelect', this.onTabSelect.bind(this));
this.initializeContextMenu();
this.insertIntoContextMenu();
window.addEventListener('AfterWorkspacesSessionRestore', this.onAfterWorkspaceSessionRestore.bind(this), {
once: true,
});
window.addEventListener(
'AfterWorkspacesSessionRestore',
this.onAfterWorkspaceSessionRestore.bind(this),
{
once: true,
}
);
// Add drag over listener to the browser view
if (Services.prefs.getBoolPref('zen.splitView.enable-tab-drop')) {
@@ -200,7 +218,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
this.fakeBrowser ||
!this._lastOpenedTab ||
(this._lastOpenedTab &&
this._lastOpenedTab.getAttribute('zen-workspace-id') !== draggedTab.getAttribute('zen-workspace-id') &&
this._lastOpenedTab.getAttribute('zen-workspace-id') !==
draggedTab.getAttribute('zen-workspace-id') &&
!this._lastOpenedTab.hasAttribute('zen-essential')) ||
draggedTab === this._lastOpenedTab
) {
@@ -224,7 +243,12 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
return;
}
// first quarter or last quarter of the screen, but not the middle
if (!(event.clientX < panelsRect.left + panelsWidth / 4 || event.clientX > panelsRect.left + (panelsWidth / 4) * 3)) {
if (
!(
event.clientX < panelsRect.left + panelsWidth / 4 ||
event.clientX > panelsRect.left + (panelsWidth / 4) * 3
)
) {
return;
}
dt.mozCursor = 'default';
@@ -244,7 +268,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
// Add a min width to all the browser elements to prevent them from resizing
const panelsWidth = gBrowser.tabbox.getBoundingClientRect().width;
const halfWidth = panelsWidth / 2;
let threshold = gNavToolbox.getBoundingClientRect().width * (gZenVerticalTabsManager._prefsRightSide ? 0 : 1);
let threshold =
gNavToolbox.getBoundingClientRect().width *
(gZenVerticalTabsManager._prefsRightSide ? 0 : 1);
if (gZenCompactModeManager.preference) {
threshold = 0;
}
@@ -267,7 +293,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
this.fakeBrowser.setAttribute('has-split-view', 'true');
}
gBrowser.tabbox.appendChild(this.fakeBrowser);
this.fakeBrowser.style.setProperty('--zen-split-view-fake-icon', `url(${draggedTab.getAttribute('image')})`);
this.fakeBrowser.style.setProperty(
'--zen-split-view-fake-icon',
`url(${draggedTab.getAttribute('image')})`
);
draggedTab._visuallySelected = true;
this.fakeBrowser.setAttribute('side', side);
this._finishAllAnimatingPromise = Promise.all([
@@ -497,12 +526,18 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
if (!this.rearrangeViewEnabled) return;
if (event) {
// Click or "ESC" key
if ((event.type === 'click' && event.button !== 0) || (event.type === 'keydown' && event.key !== 'Escape')) {
if (
(event.type === 'click' && event.button !== 0) ||
(event.type === 'keydown' && event.key !== 'Escape')
) {
return;
}
}
if (!this.rearrangeViewEnabled || (event && event.target.classList.contains('zen-split-view-splitter'))) {
if (
!this.rearrangeViewEnabled ||
(event && event.target.classList.contains('zen-split-view-splitter'))
) {
return;
}
@@ -650,7 +685,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
if (hoverSide !== 'center') {
const isVertical = hoverSide === 'top' || hoverSide === 'bottom';
const browserSize = 100 - (isVertical ? posToRoot.top + posToRoot.bottom : posToRoot.right + posToRoot.left);
const browserSize =
100 - (isVertical ? posToRoot.top + posToRoot.bottom : posToRoot.right + posToRoot.left);
const reduce = browserSize * 0.5;
posToRoot[this._oppositeSide(hoverSide)] += reduce;
@@ -712,7 +748,11 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
const droppedOnTab = gBrowser.getTabForBrowser(event.target.querySelector('browser'));
if (droppedTab === droppedOnTab) return;
const hoverSide = this.calculateHoverSide(event.clientX, event.clientY, browserDroppedOn.getBoundingClientRect());
const hoverSide = this.calculateHoverSide(
event.clientX,
event.clientY,
browserDroppedOn.getBoundingClientRect()
);
const droppedSplitNode = this.getSplitNodeFromTab(droppedTab);
const droppedOnSplitNode = this.getSplitNodeFromTab(droppedOnTab);
if (hoverSide === 'center') {
@@ -902,7 +942,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
* @returns {boolean} True if the tabs can be split, false otherwise.
*/
contextCanSplitTabs() {
if (window.gBrowser.selectedTabs.length < 2 || window.gBrowser.selectedTabs.length > this.MAX_TABS) {
if (
window.gBrowser.selectedTabs.length < 2 ||
window.gBrowser.selectedTabs.length > this.MAX_TABS
) {
return false;
}
for (const tab of window.gBrowser.selectedTabs) {
@@ -979,7 +1022,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
if (gridTypeChange || !newTabsAdded) {
// reset layout
group.gridType = gridType;
group.layoutTree = this.calculateLayoutTree([...new Set(group.tabs.concat(tabs))], gridType);
group.layoutTree = this.calculateLayoutTree(
[...new Set(group.tabs.concat(tabs))],
gridType
);
} else {
// Add any tabs that are not already in the group
for (let i = 0; i < tabs.length; i++) {
@@ -1266,7 +1312,13 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
let currentSplitters = this._splitNodeToSplitters.get(parentNode) || [];
if (!splittersNeeded || currentSplitters.length === splittersNeeded) return currentSplitters;
for (let i = currentSplitters?.length || 0; i < splittersNeeded; i++) {
currentSplitters.push(this.createSplitter(parentNode.direction === 'column' ? 'horizontal' : 'vertical', parentNode, i));
currentSplitters.push(
this.createSplitter(
parentNode.direction === 'column' ? 'horizontal' : 'vertical',
parentNode,
i
)
);
currentSplitters[i].parentSplitNode = parentNode;
}
if (currentSplitters.length > splittersNeeded) {
@@ -1278,7 +1330,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
}
removeSplitters() {
[...this.overlay.children].filter((c) => c.classList.contains('zen-split-view-splitter')).forEach((s) => s.remove());
[...this.overlay.children]
.filter((c) => c.classList.contains('zen-split-view-splitter'))
.forEach((s) => s.remove());
this._splitNodeToSplitters.clear();
}
@@ -1309,7 +1363,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
return;
}
const container = event.currentTarget.closest('.browserSidebarContainer');
const tab = window.gBrowser.tabs.find((t) => t.linkedBrowser.closest('.browserSidebarContainer') === container);
const tab = window.gBrowser.tabs.find(
(t) => t.linkedBrowser.closest('.browserSidebarContainer') === container
);
if (tab) {
window.gBrowser.selectedTab = tab;
}
@@ -1325,8 +1381,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
const startPosition = event[clientAxis];
const splitNode = event.target.parentSplitNode;
let rootToNodeSize;
if (isVertical) rootToNodeSize = 100 / (100 - splitNode.positionToRoot.right - splitNode.positionToRoot.left);
else rootToNodeSize = 100 / (100 - splitNode.positionToRoot.bottom - splitNode.positionToRoot.top);
if (isVertical)
rootToNodeSize = 100 / (100 - splitNode.positionToRoot.right - splitNode.positionToRoot.left);
else
rootToNodeSize = 100 / (100 - splitNode.positionToRoot.bottom - splitNode.positionToRoot.top);
const originalSizes = splitNode.children.map((c) => c.sizeInParent);
const dragFunc = (dEvent) => {
@@ -1334,7 +1392,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
originalSizes.forEach((s, i) => (splitNode.children[i].sizeInParent = s)); // reset changes
const movement = dEvent[clientAxis] - startPosition;
let movementPercent = (movement / this.tabBrowserPanel.getBoundingClientRect()[dimension]) * rootToNodeSize * 100;
let movementPercent =
(movement / this.tabBrowserPanel.getBoundingClientRect()[dimension]) *
rootToNodeSize *
100;
let reducingMovement = Math.max(movementPercent, -movementPercent);
for (
@@ -1351,7 +1412,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
}
const increasingMovement = Math.max(movementPercent, -movementPercent) - reducingMovement;
const increaseIndex = gridIdx + (movementPercent < 0 ? 1 : 0);
splitNode.children[increaseIndex].sizeInParent = originalSizes[increaseIndex] + increasingMovement;
splitNode.children[increaseIndex].sizeInParent =
originalSizes[increaseIndex] + increasingMovement;
this.applyGridLayout(splitNode);
});
};
@@ -1562,7 +1624,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
const containerRect = this.fakeBrowser.getBoundingClientRect();
const padding = ZenThemeModifier.elementSeparation;
const dropTarget = document.elementFromPoint(
dropSide === 'left' ? containerRect.left + containerRect.width + padding + 5 : containerRect.left - padding - 5,
dropSide === 'left'
? containerRect.left + containerRect.width + padding + 5
: containerRect.left - padding - 5,
event.clientY
);
const browser = dropTarget?.closest('browser');
@@ -1609,9 +1673,18 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
if (hoverSide !== 'center') {
const splitDirection = hoverSide === 'left' || hoverSide === 'right' ? 'row' : 'column';
if (parentNode.direction !== splitDirection) {
this.splitIntoNode(droppedOnSplitNode, new SplitLeafNode(draggedTab, 50), hoverSide, 0.5);
this.splitIntoNode(
droppedOnSplitNode,
new SplitLeafNode(draggedTab, 50),
hoverSide,
0.5
);
} else {
this.addTabToSplit(draggedTab, parentNode, /* prepend = */ hoverSide === 'left' || hoverSide === 'top');
this.addTabToSplit(
draggedTab,
parentNode,
/* prepend = */ hoverSide === 'left' || hoverSide === 'top'
);
}
} else {
this.addTabToSplit(draggedTab, group.layoutTree);
@@ -1636,7 +1709,11 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
//}
// Put tabs always as if it was dropped from the left
this.splitTabs(dropSide == 'left' ? [draggedTab, droppedOnTab] : [droppedOnTab, draggedTab], gridType, 1);
this.splitTabs(
dropSide == 'left' ? [draggedTab, droppedOnTab] : [droppedOnTab, draggedTab],
gridType,
1
);
}
}
if (this._finishAllAnimatingPromise) {
@@ -1711,7 +1788,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
// Try to find an existing split view group
let splitGroup = gBrowser.tabGroups.find(
(group) => group.getAttribute('split-view-group') && group.tabs.some((tab) => tabs.includes(tab) && tab.splitView)
(group) =>
group.getAttribute('split-view-group') &&
group.tabs.some((tab) => tabs.includes(tab) && tab.splitView)
);
if (splitGroup) {
@@ -1762,7 +1841,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
}
onAfterWorkspaceSessionRestore() {
if (gBrowser.selectedTab.group?.hasAttribute('split-view-group') && !gBrowser.selectedTab.pinned) {
if (
gBrowser.selectedTab.group?.hasAttribute('split-view-group') &&
!gBrowser.selectedTab.pinned
) {
// Activate all browsers in the split view
this.currentView = -1;
this.onLocationChange(gBrowser.selectedTab.linkedBrowser);

View File

@@ -141,7 +141,9 @@
border-top-right-radius: 0;
}
:root:not([inDOMFullscreen='true']) .browserSidebarContainer:hover .zen-view-splitter-header-container,
:root:not([inDOMFullscreen='true'])
.browserSidebarContainer:hover
.zen-view-splitter-header-container,
.zen-view-splitter-header-container:hover {
pointer-events: all;
opacity: 1;

View File

@@ -19,7 +19,9 @@
'zen.pinned-tab-manager.close-shortcut-behavior',
'switch'
);
ChromeUtils.defineESModuleGetters(lazy, { E10SUtils: 'resource://gre/modules/E10SUtils.sys.mjs' });
ChromeUtils.defineESModuleGetters(lazy, {
E10SUtils: 'resource://gre/modules/E10SUtils.sys.mjs',
});
this.#listenPinnedTabEvents();
}
@@ -100,7 +102,9 @@
} catch {}
} else {
if (tab.hasAttribute('zen-essential')) {
tab.querySelector('.tab-background').style.setProperty('--zen-tab-icon', `url(${iconUrl})`);
tab
.querySelector('.tab-background')
.style.setProperty('--zen-tab-icon', `url(${iconUrl})`);
}
}
// TODO: work on this
@@ -354,8 +358,13 @@
tab.position = tab._tPos;
for (let otherTab of gBrowser.tabs) {
if (otherTab.pinned && otherTab.getAttribute('zen-pin-id') !== tab.getAttribute('zen-pin-id')) {
const actualPin = this._pinsCache.find((pin) => pin.uuid === otherTab.getAttribute('zen-pin-id'));
if (
otherTab.pinned &&
otherTab.getAttribute('zen-pin-id') !== tab.getAttribute('zen-pin-id')
) {
const actualPin = this._pinsCache.find(
(pin) => pin.uuid === otherTab.getAttribute('zen-pin-id')
);
if (!actualPin) {
continue;
}
@@ -379,6 +388,11 @@
actualPin.title = tab.label;
}
await this.savePin(actualPin);
tab.dispatchEvent(
new CustomEvent('ZenPinnedTabMoved', {
detail: { tab },
})
);
}
_onTabClick(e) {
@@ -454,6 +468,11 @@
});
tab.setAttribute('zen-pin-id', uuid);
tab.dispatchEvent(
new CustomEvent('ZenPinnedTabCreated', {
detail: { tab },
})
);
// This is used while migrating old pins to new system - we don't want to refresh when migrating
if (tab.getAttribute('zen-pinned-entry')) {
@@ -488,6 +507,11 @@
}
}
await this._refreshPinnedTabs();
tab.dispatchEvent(
new CustomEvent('ZenPinnedTabRemoved', {
detail: { tab },
})
);
}
_initClosePinnedTabShortcut() {
@@ -507,7 +531,11 @@
}
}
_onCloseTabShortcut(event, selectedTab = gBrowser.selectedTab, behavior = lazy.zenPinnedTabCloseShortcutBehavior) {
_onCloseTabShortcut(
event,
selectedTab = gBrowser.selectedTab,
behavior = lazy.zenPinnedTabCloseShortcutBehavior
) {
if (!selectedTab?.pinned) {
return;
}
@@ -687,7 +715,11 @@
}
removeEssentials(tab, unpin = true) {
const tabs = tab ? [tab] : TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
const tabs = tab
? [tab]
: TabContextMenu.contextTab.multiselected
? gBrowser.selectedTabs
: [TabContextMenu.contextTab];
for (let i = 0; i < tabs.length; i++) {
const tab = tabs[i];
tab.removeAttribute('zen-essential');
@@ -742,7 +774,11 @@
// TODO: remove this as it's not possible to know the base pinned url any more as it's now stored in tab state
resetPinnedTabData(tabData) {
if (lazy.zenPinnedTabRestorePinnedTabsToPinnedUrl && tabData.pinned && tabData.zenPinnedEntry) {
if (
lazy.zenPinnedTabRestorePinnedTabsToPinnedUrl &&
tabData.pinned &&
tabData.zenPinnedEntry
) {
tabData.entries = [JSON.parse(tabData.zenPinnedEntry)];
tabData.image = tabData.zenPinnedIcon;
tabData.index = 0;
@@ -754,22 +790,27 @@
return;
}
const isVisible = contextTab.pinned && !contextTab.multiselected;
document.getElementById('context_zen-reset-pinned-tab').hidden = !isVisible || !contextTab.getAttribute('zen-pin-id');
document.getElementById('context_zen-reset-pinned-tab').hidden =
!isVisible || !contextTab.getAttribute('zen-pin-id');
document.getElementById('context_zen-replace-pinned-url-with-current').hidden = !isVisible;
document.getElementById('context_zen-add-essential').hidden =
contextTab.getAttribute('zen-essential') || !!contextTab.group;
document.getElementById('context_zen-remove-essential').hidden = !contextTab.getAttribute('zen-essential');
document.getElementById('context_zen-remove-essential').hidden =
!contextTab.getAttribute('zen-essential');
document.getElementById('context_unpinTab').hidden =
document.getElementById('context_unpinTab').hidden || contextTab.getAttribute('zen-essential');
document.getElementById('context_unpinTab').hidden ||
contextTab.getAttribute('zen-essential');
document.getElementById('context_unpinSelectedTabs').hidden =
document.getElementById('context_unpinSelectedTabs').hidden || contextTab.getAttribute('zen-essential');
document.getElementById('context_unpinSelectedTabs').hidden ||
contextTab.getAttribute('zen-essential');
document.getElementById('context_zen-pinned-tab-separator').hidden = !isVisible;
}
moveToAnotherTabContainerIfNecessary(event, movingTabs) {
try {
const pinnedTabsTarget =
event.target.closest('#vertical-pinned-tabs-container') || event.target.closest('.zen-current-workspace-indicator');
event.target.closest('#vertical-pinned-tabs-container') ||
event.target.closest('.zen-current-workspace-indicator');
const essentialTabsTarget = event.target.closest('.zen-essentials-container');
const tabsTarget = event.target.closest('#tabbrowser-arrowscrollbox');
// Remove group labels from the moving tabs and replace it
@@ -801,7 +842,10 @@
}
// Check for essentials container
else if (essentialTabsTarget) {
if (!draggedTab.hasAttribute('zen-essential') && !draggedTab?.group?.hasAttribute('split-view-group')) {
if (
!draggedTab.hasAttribute('zen-essential') &&
!draggedTab?.group?.hasAttribute('split-view-group')
) {
this.addToEssentials(draggedTab);
moved = true;
isVertical = false;
@@ -898,6 +942,9 @@
}
removeTabContainersDragoverClass() {
if (this._dragIndicator) {
Services.zen.playHapticFeedback();
}
this.dragIndicator.remove();
this._dragIndicator = null;
ZenWorkspaces.activeWorkspaceIndicator?.removeAttribute('open');
@@ -958,7 +1005,9 @@
const tabsTarget = event.target.closest('#tabbrowser-arrowscrollbox');
let targetTab = event.target.closest('.tabbrowser-tab');
targetTab = targetTab?.group || targetTab;
draggedTab = draggedTab?.group?.hasAttribute('split-view-group') ? draggedTab.group : draggedTab;
draggedTab = draggedTab?.group?.hasAttribute('split-view-group')
? draggedTab.group
: draggedTab;
if (event.target.closest('.zen-current-workspace-indicator')) {
this.removeTabContainersDragoverClass();
ZenWorkspaces.activeWorkspaceIndicator?.setAttribute('open', true);
@@ -997,16 +1046,19 @@
// Calculate middle to decide 'before' or 'after'
const rect = targetTab.getBoundingClientRect();
let shouldPlayHapticFeedback = false;
if (isVertical) {
const separation = 8;
const middleY = targetTab.screenY + rect.height / 2;
const indicator = this.dragIndicator;
let top = 0;
if (event.screenY > middleY) {
top = rect.top + rect.height + 'px';
top = Math.round(rect.top + rect.height) + 'px';
} else {
top = rect.top + 'px';
top = Math.round(rect.top) + 'px';
}
if (indicator.style.top !== top) {
shouldPlayHapticFeedback = true;
}
indicator.setAttribute('orientation', 'horizontal');
indicator.style.setProperty('--indicator-left', rect.left + separation / 2 + 'px');
@@ -1019,9 +1071,12 @@
const indicator = this.dragIndicator;
let left = 0;
if (event.screenX > middleX) {
left = rect.left + rect.width + 1 + 'px';
left = Math.round(rect.left + rect.width + 1) + 'px';
} else {
left = rect.left - 2 + 'px';
left = Math.round(rect.left - 2) + 'px';
}
if (indicator.style.left !== left) {
shouldPlayHapticFeedback = true;
}
indicator.setAttribute('orientation', 'vertical');
indicator.style.setProperty('--indicator-top', rect.top + separation / 2 + 'px');
@@ -1029,6 +1084,9 @@
indicator.style.left = left;
indicator.style.removeProperty('top');
}
if (shouldPlayHapticFeedback) {
Services.zen.playHapticFeedback();
}
}
async onTabLabelChanged(tab) {

View File

@@ -106,7 +106,8 @@ var ZenPinnedTabsStorage = {
`
INSERT OR REPLACE INTO zen_pins (
uuid, title, url, container_id, workspace_uuid, position,
is_essential, is_group, parent_uuid, created_at, updated_at
is_essential, is_group, parent_uuid, created_at, updated_at,
edited_title
) VALUES (
:uuid, :title, :url, :container_id, :workspace_uuid, :position,
:is_essential, :is_group, :parent_uuid, :edited_title,
@@ -201,7 +202,9 @@ var ZenPinnedTabsStorage = {
await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.removePin', async (db) => {
await db.executeTransaction(async () => {
// Get all child UUIDs first for change tracking
const children = await db.execute(`SELECT uuid FROM zen_pins WHERE parent_uuid = :uuid`, { uuid });
const children = await db.execute(`SELECT uuid FROM zen_pins WHERE parent_uuid = :uuid`, {
uuid,
});
// Add child UUIDs to changedUUIDs array
for (const child of children) {
@@ -282,7 +285,9 @@ var ZenPinnedTabsStorage = {
shouldReorderPins(before, current, after) {
const minGap = 1; // Minimum allowed gap between positions
return (before !== null && current - before < minGap) || (after !== null && after - current < minGap);
return (
(before !== null && current - before < minGap) || (after !== null && after - current < minGap)
);
},
async reorderAllPins(db, changedUUIDs) {
@@ -328,41 +333,44 @@ var ZenPinnedTabsStorage = {
async updatePinPositions(pins) {
const changedUUIDs = new Set();
await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.updatePinPositions', async (db) => {
await db.executeTransaction(async () => {
const now = Date.now();
await PlacesUtils.withConnectionWrapper(
'ZenPinnedTabsStorage.updatePinPositions',
async (db) => {
await db.executeTransaction(async () => {
const now = Date.now();
for (let i = 0; i < pins.length; i++) {
const pin = pins[i];
const newPosition = (i + 1) * 1000;
for (let i = 0; i < pins.length; i++) {
const pin = pins[i];
const newPosition = (i + 1) * 1000;
await db.execute(
`
await db.execute(
`
UPDATE zen_pins
SET position = :newPosition
WHERE uuid = :uuid
`,
{ newPosition, uuid: pin.uuid }
);
{ newPosition, uuid: pin.uuid }
);
changedUUIDs.add(pin.uuid);
changedUUIDs.add(pin.uuid);
// Record the change
await db.execute(
`
// Record the change
await db.execute(
`
INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`,
{
uuid: pin.uuid,
timestamp: Math.floor(now / 1000),
}
);
}
{
uuid: pin.uuid,
timestamp: Math.floor(now / 1000),
}
);
}
await this.updateLastChangeTimestamp(db);
});
});
await this.updateLastChangeTimestamp(db);
});
}
);
this._notifyPinsChanged('zen-pin-updated', Array.from(changedUUIDs));
},

View File

@@ -1,11 +1,26 @@
{
const lazy = {};
XPCOMUtils.defineLazyPreferenceGetter(lazy, 'zenTabUnloaderEnabled', 'zen.tab-unloader.enabled', false);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
'zenTabUnloaderEnabled',
'zen.tab-unloader.enabled',
false
);
XPCOMUtils.defineLazyPreferenceGetter(lazy, 'zenTabUnloaderTimeout', 'zen.tab-unloader.timeout-minutes', 20);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
'zenTabUnloaderTimeout',
'zen.tab-unloader.timeout-minutes',
20
);
XPCOMUtils.defineLazyPreferenceGetter(lazy, 'zenTabUnloaderExcludedUrls', 'zen.tab-unloader.excluded-urls', '');
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
'zenTabUnloaderExcludedUrls',
'zen.tab-unloader.excluded-urls',
''
);
const ZEN_TAB_UNLOADER_DEFAULT_EXCLUDED_URLS = [
'^about:',
@@ -68,7 +83,10 @@
constructor(unloader) {
this.unloader = unloader;
this.interval = setInterval(this.intervalListener.bind(this), ZenTabsIntervalUnloader.INTERVAL);
this.interval = setInterval(
this.intervalListener.bind(this),
ZenTabsIntervalUnloader.INTERVAL
);
}
intervalListener() {
@@ -218,7 +236,10 @@
get excludedUrls() {
// Check if excludedrls is the same as the pref value
const excludedUrls = this.lazyExcludeUrls;
if (!this.arraysEqual(this.#excludedUrls, excludedUrls) || !this.#compiledExcludedUrls.length) {
if (
!this.arraysEqual(this.#excludedUrls, excludedUrls) ||
!this.#compiledExcludedUrls.length
) {
this.#excludedUrls = excludedUrls;
this.#compiledExcludedUrls = excludedUrls.map((url) => new RegExp(url));
}
@@ -231,7 +252,9 @@
}
unloadTab() {
const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
const tabs = TabContextMenu.contextTab.multiselected
? gBrowser.selectedTabs
: [TabContextMenu.contextTab];
this.explicitUnloadTabs(tabs);
}
@@ -244,7 +267,9 @@
}
preventUnloadTab() {
const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
const tabs = TabContextMenu.contextTab.multiselected
? gBrowser.selectedTabs
: [TabContextMenu.contextTab];
for (let i = 0; i < tabs.length; i++) {
const tab = tabs[i];
tab.zenIgnoreUnload = true;
@@ -252,7 +277,9 @@
}
ignoreUnloadTab() {
const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
const tabs = TabContextMenu.contextTab.multiselected
? gBrowser.selectedTabs
: [TabContextMenu.contextTab];
for (let i = 0; i < tabs.length; i++) {
const tab = tabs[i];
tab.zenIgnoreUnload = false;
@@ -288,7 +315,9 @@
}
const diff = currentTimestamp - lastActivity;
// Check if the tab has been inactive for more than the timeout
return diff > lazy.zenTabUnloaderTimeout * 60 * 1000 && this._tabPermitsUnload(tab, extraArgs);
return (
diff > lazy.zenTabUnloaderTimeout * 60 * 1000 && this._tabPermitsUnload(tab, extraArgs)
);
}
_tabPermitsUnload(tab, extraArgs) {

View File

@@ -95,7 +95,7 @@
}
/* Pull window buttons container rightwards over the collapsed sidebar */
& .titlebar-buttonbox-container {
margin-left: calc(-1 * var(--zen-toolbox-max-width) + var(--zen-toolbox-padding) / 2) !important;
margin-left: calc(-1 * var(--zen-toolbox-max-width) + var(--zen-toolbox-padding)) !important;
}
/* Allow overflow for the button box */
& #zen-appcontent-wrapper {

View File

@@ -14,7 +14,9 @@ z-index: 1;
}
}
&:not([zen-has-hover='true']):not([has-popup-menu]):not(:focus-within):not(:has(*:is([panelopen='true'], [open='true']))) {
&:not([zen-has-hover='true']):not([has-popup-menu]):not(:focus-within):not(
:has(*:is([panelopen='true'], [open='true']))
) {
transition-delay: 0.2s;
/* In order to still use it on fullscreen, even if it's 0px, add .1px (almost invisible) */
height: calc(var(--zen-element-separation) + 0.1px);

View File

@@ -103,7 +103,10 @@
--zen-min-toolbox-padding: 0.35rem;
}
/* Actual padding used, ensuring it's at least min padding or based on element separation */
--zen-toolbox-padding: max(var(--zen-min-toolbox-padding), calc(var(--zen-element-separation) / 1.5));
--zen-toolbox-padding: max(
var(--zen-min-toolbox-padding),
calc(var(--zen-element-separation) / 1.5)
);
}
/* ==========================================================================
@@ -290,7 +293,9 @@
/* Scale down tab slightly on active press (but not when dragging or clicking images) */
#tabbrowser-tabs:not([movingtab]) &:active:not(:has(.tab-content > image:active)) {
scale: var(--zen-active-tab-scale); /* Requires --zen-active-tab-scale to be defined elsewhere */
scale: var(
--zen-active-tab-scale
); /* Requires --zen-active-tab-scale to be defined elsewhere */
}
/* Scale down icon/image specifically on active press */
@@ -518,6 +523,7 @@
& .tab-audio-button {
margin-inline-start: -4px;
margin-inline-end: 2px;
margin-top: -2px;
}
& #titlebar {
@@ -535,7 +541,9 @@
/* Specific padding for URL bar input in single toolbar mode */
:root[zen-single-toolbar='true'] & {
& #urlbar:not([breakout-extend='true']):not([pageproxystate='invalid']) .urlbar-input-container {
&
#urlbar:not([breakout-extend='true']):not([pageproxystate='invalid'])
.urlbar-input-container {
padding-left: 8px;
padding-right: 4px;
}
@@ -660,7 +668,10 @@
/* --- Pinned Tab Icon Repositioning & Reset Button --- */
/* Reposition icon stack absolutely when tab is pinned (and not essential) */
&[zen-pinned-changed='true']:not([zen-essential]) > .tab-stack > .tab-content > .tab-icon-stack {
&[zen-pinned-changed='true']:not([zen-essential])
> .tab-stack
> .tab-content
> .tab-icon-stack {
position: absolute;
top: 50%;
transform: translateY(-50%);
@@ -889,7 +900,9 @@
:is(
:root[uidensity='compact'],
#tabbrowser-tabs[secondarytext-unsupported],
:root:not([uidensity='compact']) #tabbrowser-tabs:not([secondarytext-unsupported]) .tabbrowser-tab:hover
:root:not([uidensity='compact'])
#tabbrowser-tabs:not([secondarytext-unsupported])
.tabbrowser-tab:hover
)
.tab-icon-stack[indicator-replaces-favicon]
> :not(&),
@@ -1024,7 +1037,9 @@
display: flex; /* Use flex for alignment */
position: relative; /* For pseudo-element positioning */
height: calc(100% - var(--tab-block-margin) * 2); /* Adjust height based on margins */
margin-left: calc(-1 * var(--tab-inline-padding) + var(--tab-block-margin)); /* Overlap slightly */
margin-left: calc(
-1 * var(--tab-inline-padding) + var(--tab-block-margin)
); /* Overlap slightly */
margin-right: 8px;
padding: 0 calc(var(--toolbarbutton-inner-padding) - 2px) 0
calc(var(--toolbarbutton-inner-padding) / 4 + var(--tab-inline-padding) - 2px); /* Custom padding */
@@ -1118,7 +1133,9 @@
/* Adjust inner padding based on sidebar state */
:root[zen-sidebar-expanded='true'] & {
--toolbarbutton-inner-padding: var(--zen-toolbar-button-inner-padding) !important; /* Use theme variable */
--toolbarbutton-inner-padding: var(
--zen-toolbar-button-inner-padding
) !important; /* Use theme variable */
}
:root[zen-single-toolbar='true'] & {
--toolbarbutton-inner-padding: calc(
@@ -1153,7 +1170,9 @@
/* Standardize height and padding for toolbar buttons (excluding titlebar buttons) */
& toolbarbutton:not(.titlebar-button) {
height: calc(2 * var(--toolbarbutton-inner-padding) + 16px); /* Calculate height based on padding + icon */
height: calc(
2 * var(--toolbarbutton-inner-padding) + 16px
); /* Calculate height based on padding + icon */
padding: 0 var(--toolbarbutton-outer-padding) !important; /* Apply outer padding */
}
@@ -1231,7 +1250,10 @@
content: '';
display: block;
height: 1px;
background: light-dark(rgba(1, 1, 1, 0.075), rgba(255, 255, 255, 0.1)); /* Separator color */
background: light-dark(
rgba(1, 1, 1, 0.075),
rgba(255, 255, 255, 0.1)
); /* Separator color */
width: 98%; /* Near full width */
position: absolute;
top: -8px; /* Position above the button */
@@ -1269,7 +1291,10 @@
grid-template-columns: repeat(auto-fit, minmax(max(30%, 48px), auto));
}
&[data-hack-type='2'] {
grid-template-columns: repeat(auto-fit, minmax(max(23%, 48px), 1fr) minmax(max(23%, 48px), 1fr));
grid-template-columns: repeat(
auto-fit,
minmax(max(23%, 48px), 1fr) minmax(max(23%, 48px), 1fr)
);
}
&[data-hack-type='3'] {
grid-template-columns: repeat(auto-fit, minmax(max(25%, 48px), 1fr));
@@ -1281,8 +1306,10 @@
display: grid;
&[hidden='true'] {
--hidden-essentials-width: var(--actual-zen-sidebar-width);
max-width: var(--hidden-essentials-width) !important; /* To still allow essentials to grid the tabs */
--hidden-essentials-width: var(--zen-sidebar-width);
max-width: var(
--hidden-essentials-width
) !important; /* To still allow essentials to grid the tabs */
min-width: var(--hidden-essentials-width) !important;
}
}
@@ -1351,7 +1378,9 @@
&::before {
background: light-dark(rgba(255, 255, 255, 0.85), rgba(68, 64, 64, 0.85));
margin: var(--zen-essential-bg-margin); /* Apply margin */
border-radius: calc(var(--border-radius-medium) - var(--zen-essential-bg-margin)); /* Adjust radius */
border-radius: calc(
var(--border-radius-medium) - var(--zen-essential-bg-margin)
); /* Adjust radius */
position: absolute;
inset: 0;
z-index: 0; /* Position above ::after, below content */
@@ -1477,3 +1506,12 @@
position: fixed; /* Fix position to prevent scrolling */
}
}
/* ==========================================================================
Section: Workspaces disabled, due to private browsing mode
========================================================================== */
:root:not([zen-workspace-id]) #tabbrowser-arrowscrollbox {
width: 100%;
position: absolute;
}

View File

@@ -1,2 +0,0 @@
["workspaces/browser_basic_workspaces.js"]

View File

@@ -0,0 +1,2 @@
["browser_compact_mode_width.js"]

View File

@@ -0,0 +1,67 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
function goToRightSideTabs(callback) {
return new Promise(async (resolve) => {
await SpecialPowers.pushPrefEnv({
set: [['zen.tabs.vertical.right-side', true]],
});
setTimeout(async () => {
await callback();
await SpecialPowers.popPrefEnv();
setTimeout(() => {
resolve();
}, 1000); // Wait for new layout
}, 1000); // Wait for new layout
});
}
async function testSidebarWidth() {
let resolvePromise;
const promise = new Promise((resolve) => {
resolvePromise = resolve;
});
let hasRan = false;
const ogSize = gNavToolbox.getBoundingClientRect().width;
const onCompactChanged = (event) => {
if (hasRan) {
setTimeout(() => {
gZenCompactModeManager.removeEventListener(onCompactChanged);
resolvePromise();
}, 500);
return;
}
setTimeout(() => {
const newSize = gNavToolbox.style.getPropertyValue('--zen-sidebar-width').replace('px', '');
Assert.equal(
newSize,
ogSize,
'The size of the titlebar should be the same as the original size'
);
hasRan = true;
gZenCompactModeManager.preference = false;
}, 500);
};
gZenCompactModeManager.addEventListener(onCompactChanged);
gZenCompactModeManager.preference = true;
await promise;
}
add_task(async function test_Compact_Mode_Width() {
await testSidebarWidth();
});
add_task(async function test_Compact_Mode_Width_Right_Side() {
await goToRightSideTabs(testSidebarWidth);
});
add_task(async function test_Compact_Mode_Hover() {
gNavToolbox.setAttribute('zen-has-hover', true);
await testSidebarWidth();
gNavToolbox.removeAttribute('zen-has-hover');
});

View File

@@ -0,0 +1,4 @@
[DEFAULT]
prefs = ["zen.workspaces.container-specific-essentials-enabled=true"]
["browser_container_specific_essentials.js"]

View File

@@ -0,0 +1,39 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Check_Creation() {
await ZenWorkspaces.createAndSaveWorkspace('Container Profile 1', undefined, false, 1);
const workspaces = await ZenWorkspaces._workspaces();
ok(workspaces.workspaces.length === 2, 'Two workspaces should exist.');
let newTab = BrowserTestUtils.addTab(gBrowser, 'about:blank', {
skipAnimation: true,
userContextId: 1,
});
ok(newTab, 'New tab should be opened.');
gZenPinnedTabManager.addToEssentials(newTab);
ok(
newTab.hasAttribute('zen-essential') && newTab.parentNode.getAttribute('container') == '1',
'New tab should be marked as essential.'
);
ok(
gBrowser.tabs.find(
(t) => t.hasAttribute('zen-essential') && t.getAttribute('usercontextid') == 1
),
'New tab should be marked as essential.'
);
const newWorkspaceUUID = ZenWorkspaces.activeWorkspace;
// Change to the original workspace, there should be no essential tabs
await ZenWorkspaces.changeWorkspace(workspaces.workspaces[0]);
ok(
!gBrowser.tabs.find(
(t) => t.hasAttribute('zen-essential') && t.getAttribute('usercontextid') == 1
),
'No essential tabs should be found in the original workspace.'
);
await ZenWorkspaces.removeWorkspace(newWorkspaceUUID);
});

View File

@@ -0,0 +1,8 @@
[DEFAULT]
support-files = [
"head.js",
]
["browser_glance_basic.js"]
["browser_glance_expand.js"]
["browser_glance_close.js"]

View File

@@ -0,0 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Glance_Basic_Open() {
await openGlanceOnTab(async (glanceTab) => {
ok(
glanceTab.hasAttribute('zen-glance-tab'),
'The glance tab should have the zen-glance-tab attribute'
);
});
});

View File

@@ -0,0 +1,25 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Glance_Basic_Close() {
const currentTab = gBrowser.selectedTab;
await openGlanceOnTab(async (glanceTab) => {
ok(
currentTab.hasAttribute('glance-id'),
'The glance tab should have the zen-glance-tab attribute'
);
await BrowserTestUtils.removeTab(glanceTab);
await new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 500);
});
ok(
!currentTab.hasAttribute('glance-id'),
'The glance tab should not have the zen-glance-tab attribute'
);
await BrowserTestUtils.removeTab(glanceTab);
}, false);
});

View File

@@ -0,0 +1,105 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Glance_Basic_Open() {
const selectedTab = gBrowser.selectedTab;
await openGlanceOnTab(async (glanceTab) => {
await gZenGlanceManager.fullyOpenGlance();
ok(
!glanceTab.hasAttribute('zen-glance-tab'),
'The glance tab should not have the zen-glance-tab attribute'
);
ok(
gBrowser.tabs.filter((tab) => tab.hasAttribute('zen-glance-tab')).length === 0,
'There should be no zen-glance-tab attribute on any tab'
);
Assert.greater(
glanceTab._tPos,
selectedTab._tPos,
'The glance tab should be on the right of the selected tab'
);
Assert.equal(
glanceTab._tPos,
gBrowser.tabs.length - 1,
'The glance tab should be the last tab'
);
BrowserTestUtils.removeTab(glanceTab);
}, false);
});
add_task(async function test_Glance_Open_Sibling() {
const tabsToRemove = [];
for (let i = 0; i < 5; i++) {
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
tabsToRemove.push(gBrowser.selectedTab);
}
gBrowser.selectedTab = gBrowser.tabs[2];
const selectedTab = gBrowser.selectedTab;
await openGlanceOnTab(async (glanceTab) => {
await gZenGlanceManager.fullyOpenGlance();
Assert.equal(
glanceTab._tPos,
selectedTab._tPos + 1,
'The glance tab should be on the right of the selected tab'
);
BrowserTestUtils.removeTab(glanceTab);
}, false);
for (const tab of tabsToRemove) {
await BrowserTestUtils.removeTab(tab);
}
});
add_task(async function test_Glance_Basic_Open() {
const tabsToRemove = [];
for (let i = 0; i < 3; i++) {
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
gBrowser.pinTab(gBrowser.selectedTab);
tabsToRemove.push(gBrowser.selectedTab);
}
gBrowser.selectedTab = gBrowser.tabs.find((tab) => tab.pinned);
await openGlanceOnTab(async (glanceTab) => {
await gZenGlanceManager.fullyOpenGlance();
Assert.equal(
glanceTab._tPos,
3,
'The glance tab should be the first normal tab (Ignoring empty tabs)'
);
BrowserTestUtils.removeTab(glanceTab);
}, false);
for (const tab of tabsToRemove) {
await BrowserTestUtils.removeTab(tab);
}
});
add_task(async function test_Glance_New_From_essential() {
await BrowserTestUtils.withNewTab({ gBrowser, url: 'https://example.com/' }, async (browser) => {
const selectedTab = gBrowser.selectedTab;
gZenPinnedTabManager.addToEssentials(selectedTab);
await openGlanceOnTab(async (glanceTab) => {
await gZenGlanceManager.fullyOpenGlance();
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true, {
skipAnimation: true,
});
Assert.equal(
gBrowser.selectedTab._tPos,
1,
'The new tab should be the first normal tab (Ignoring empty tabs)'
);
Assert.equal(
glanceTab._tPos,
2,
'The glance tab should be the second normal tab (Ignoring empty tabs)'
);
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
BrowserTestUtils.removeTab(glanceTab);
}, false);
});
});

View File

@@ -0,0 +1,33 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
function openGlanceOnTab(callback, close = true) {
return new Promise(async (resolve) => {
setTimeout(() => {
gZenGlanceManager
.openGlance({
url: 'https://example.com',
x: 0,
y: 0,
width: 0,
height: 0,
})
.then(async (glanceTab) => {
await callback(glanceTab);
if (close) {
gZenGlanceManager
.closeGlance({
onTabClose: true,
})
.then(() => {
resolve();
});
} else {
resolve();
}
});
});
});
}

9
src/zen/tests/moz.build Normal file
View File

@@ -0,0 +1,9 @@
BROWSER_CHROME_MANIFESTS += [
"compact_mode/browser.toml",
"container_essentials/browser.toml",
"glance/browser.toml",
"pinned/browser.toml",
"urlbar/browser.toml",
"workspaces/browser.toml",
]

View File

@@ -0,0 +1,8 @@
["browser_pinned_changed.js"]
["browser_pinned_created.js"]
["browser_pinned_edit_label.js"]
["browser_pinned_removed.js"]
["browser_pinned_reorder_changed_label.js"]
["browser_pinned_reordered.js"]
["browser_issue_7654.js"]

View File

@@ -0,0 +1,60 @@
/* 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',
});
add_task(async function test_Search_Pinned_Title() {
let resolvePromise;
const promise = new Promise((resolve) => {
resolvePromise = resolve;
});
const customLabel = 'ZEN ROCKS';
await BrowserTestUtils.withNewTab({ gBrowser, url: 'https://example.com/1' }, async (browser) => {
const tab = gBrowser.getTabForBrowser(browser);
tab.addEventListener(
'ZenPinnedTabCreated',
async function () {
const pinTabID = tab.getAttribute('zen-pin-id');
ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned');
await gZenPinnedTabManager.updatePinTitle(tab, customLabel, true);
const pinnedTabs = await ZenPinnedTabsStorage.getPins();
const pinObject = pinnedTabs.find((pin) => pin.uuid === pinTabID);
Assert.equal(pinObject.title, customLabel, 'The pin object should have the correct title');
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/2', true);
await UrlbarTestUtils.promiseAutocompleteResultPopup({
window,
value: customLabel,
waitForFocus: SimpleTest.waitForFocus,
});
const total = UrlbarTestUtils.getResultCount(window);
info(`Found ${total} matches`);
const result = await UrlbarTestUtils.getDetailsOfResultAt(window, 1);
const url = result?.url;
Assert.equal(
url,
'https://example.com/1',
`Should have the found result '${url}' in the expected list of entries`
);
BrowserTestUtils.removeTab(gBrowser.selectedTab);
resolvePromise();
},
{ once: true }
);
gBrowser.pinTab(tab);
await promise;
});
});

View File

@@ -0,0 +1,37 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Create_Pinned() {
let resolvePromise;
const promise = new Promise((resolve) => {
resolvePromise = resolve;
});
await BrowserTestUtils.withNewTab({ gBrowser, url: 'https://example.com/1' }, async (browser) => {
const tab = gBrowser.getTabForBrowser(browser);
tab.addEventListener(
'ZenPinnedTabCreated',
async function (event) {
ok(tab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()');
const pinTabID = tab.getAttribute('zen-pin-id');
ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned');
BrowserTestUtils.startLoadingURIString(browser, 'https://example.com/2');
await BrowserTestUtils.browserLoaded(browser, false, 'https://example.com/2');
setTimeout(() => {
ok(
tab.hasAttribute('zen-pinned-changed'),
'The tab should have a zen-pinned-changed attribute after being pinned'
);
resolvePromise();
}, 0);
},
{ once: true }
);
gBrowser.pinTab(tab);
await promise;
});
});

View File

@@ -0,0 +1,49 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Create_Pinned() {
let resolvePromise;
const promise = new Promise((resolve) => {
resolvePromise = resolve;
});
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
const newTab = gBrowser.selectedTab;
newTab.addEventListener(
'ZenPinnedTabCreated',
async function (event) {
ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()');
const pinTabID = newTab.getAttribute('zen-pin-id');
ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned');
try {
const pins = await ZenPinnedTabsStorage.getPins();
const pinObject = pins.find((pin) => pin.uuid === pinTabID);
ok(pinObject, 'The pin object should exist in the ZenPinnedTabsStorage');
Assert.equal(
pinObject.url,
'https://example.com/',
'The pin object should have the correct URL'
);
Assert.equal(
pinObject.workspaceUuid,
ZenWorkspaces.activeWorkspace,
'The pin object should have the correct workspace UUID'
);
} catch (error) {
ok(false, 'Error while checking the pin object in ZenPinnedTabsStorage: ' + error);
}
resolvePromise();
},
{ once: true }
);
gBrowser.pinTab(newTab);
await promise;
await BrowserTestUtils.removeTab(newTab);
});

View File

@@ -0,0 +1,42 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Create_Pinned() {
let resolvePromise;
const promise = new Promise((resolve) => {
resolvePromise = resolve;
});
const customLabel = 'Test Label';
await BrowserTestUtils.withNewTab({ gBrowser, url: 'https://example.com/' }, async (browser) => {
const tab = gBrowser.getTabForBrowser(browser);
tab.addEventListener(
'ZenPinnedTabCreated',
async function (event) {
ok(tab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()');
const pinTabID = tab.getAttribute('zen-pin-id');
ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned');
await gZenPinnedTabManager.updatePinTitle(tab, customLabel, true);
const pinnedTabs = await ZenPinnedTabsStorage.getPins();
const pinObject = pinnedTabs.find((pin) => pin.uuid === pinTabID);
Assert.equal(pinObject.title, customLabel, 'The pin object should have the correct title');
Assert.equal(
pinObject.url,
'https://example.com/',
'The pin object should have the correct URL'
);
resolvePromise();
},
{ once: true }
);
gBrowser.pinTab(tab);
await promise;
});
});

View File

@@ -0,0 +1,52 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Remove_Pinned() {
let resolvePromise;
const promise = new Promise((resolve) => {
resolvePromise = resolve;
});
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
const newTab = gBrowser.selectedTab;
newTab.addEventListener(
'ZenPinnedTabCreated',
async function (event) {
ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()');
const pinTabID = newTab.getAttribute('zen-pin-id');
ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned');
const pins = await ZenPinnedTabsStorage.getPins();
const pinObject = pins.find((pin) => pin.uuid === pinTabID);
ok(pinObject, 'The pin object should exist in the ZenPinnedTabsStorage');
newTab.addEventListener(
'ZenPinnedTabRemoved',
async function (event) {
const pins = await ZenPinnedTabsStorage.getPins();
const pinObject = pins.find((pin) => pin.uuid === pinTabID);
ok(
!pinObject,
'The pin object should not exist in the ZenPinnedTabsStorage after removal'
);
ok(
!newTab.hasAttribute('zen-pin-id'),
'The tab should not have a zen-pin-id attribute after removal'
);
ok(!newTab.pinned, 'The tab should not be pinned after removal');
resolvePromise();
},
{ once: true }
);
gBrowser.unpinTab(newTab);
},
{ once: true }
);
gBrowser.pinTab(newTab);
await promise;
await BrowserTestUtils.removeTab(newTab);
});

View File

@@ -0,0 +1,126 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Pinned_Reorder_Changed_Label() {
let resolvePromise;
const promise = new Promise((resolve) => {
resolvePromise = resolve;
});
const tabsToRemove = [];
for (let i = 0; i < 3; i++) {
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
gBrowser.pinTab(gBrowser.selectedTab);
tabsToRemove.push(gBrowser.selectedTab);
}
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
tabsToRemove.push(gBrowser.selectedTab);
const customLabel = 'Test Label';
const newTab = gBrowser.selectedTab;
newTab.addEventListener(
'ZenPinnedTabCreated',
async function (event) {
ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()');
const pinTabID = newTab.getAttribute('zen-pin-id');
ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned');
await gZenPinnedTabManager.updatePinTitle(newTab, customLabel, true);
const pins = await ZenPinnedTabsStorage.getPins();
const pinObject = pins.find((pin) => pin.uuid === pinTabID);
newTab.addEventListener(
'ZenPinnedTabMoved',
async function (event) {
const pins = await ZenPinnedTabsStorage.getPins();
const pinObject = pins.find((pin) => pin.uuid === pinTabID);
Assert.equal(
pinObject.title,
customLabel,
'The pin object should have the correct title'
);
Assert.equal(
pinObject.position,
2,
'The pin object should have the correct position after moving'
);
resolvePromise();
},
{ once: true }
);
gBrowser.moveTabTo(newTab, { tabIndex: 2 });
},
{ once: true }
);
gBrowser.pinTab(newTab);
await promise;
for (const tab of tabsToRemove) {
await BrowserTestUtils.removeTab(tab);
}
});
add_task(async function test_Pinned_Reorder_Changed_Label() {
let resolvePromise;
const promise = new Promise((resolve) => {
resolvePromise = resolve;
});
const tabsToRemove = [];
for (let i = 0; i < 3; i++) {
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
gBrowser.pinTab(gBrowser.selectedTab);
tabsToRemove.push(gBrowser.selectedTab);
}
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
tabsToRemove.push(gBrowser.selectedTab);
const customLabel = 'Test Label';
const newTab = gBrowser.selectedTab;
newTab.addEventListener(
'ZenPinnedTabCreated',
async function (event) {
ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()');
const pinTabID = newTab.getAttribute('zen-pin-id');
ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned');
newTab.addEventListener(
'ZenPinnedTabMoved',
async function (event) {
await gZenPinnedTabManager.updatePinTitle(newTab, customLabel, true);
const pins = await ZenPinnedTabsStorage.getPins();
const pinObject = pins.find((pin) => pin.uuid === pinTabID);
Assert.equal(
pinObject.title,
customLabel,
'The pin object should have the correct title'
);
Assert.equal(
pinObject.position,
1,
'The pin object should have the correct position after moving'
);
resolvePromise();
},
{ once: true }
);
gBrowser.moveTabTo(newTab, { tabIndex: 1 });
},
{ once: true }
);
gBrowser.pinTab(newTab);
await promise;
for (const tab of tabsToRemove) {
await BrowserTestUtils.removeTab(tab);
}
});

View File

@@ -0,0 +1,97 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Create_Pinned() {
let resolvePromise;
const promise = new Promise((resolve) => {
resolvePromise = resolve;
});
const tabsToRemove = [];
for (let i = 0; i < 3; i++) {
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
gBrowser.pinTab(gBrowser.selectedTab);
tabsToRemove.push(gBrowser.selectedTab);
}
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
tabsToRemove.push(gBrowser.selectedTab);
const newTab = gBrowser.selectedTab;
newTab.addEventListener(
'ZenPinnedTabCreated',
async function (event) {
ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()');
const pinTabID = newTab.getAttribute('zen-pin-id');
ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned');
const pins = await ZenPinnedTabsStorage.getPins();
const pinObject = pins.find((pin) => pin.uuid === pinTabID);
const startIndex = pinObject.position;
Assert.greater(startIndex, 0, 'The pin object should have the correct start index');
resolvePromise();
},
{ once: true }
);
gBrowser.pinTab(newTab);
await promise;
for (const tab of tabsToRemove) {
await BrowserTestUtils.removeTab(tab);
}
});
add_task(async function test_Create_Pinned() {
let resolvePromise;
const promise = new Promise((resolve) => {
resolvePromise = resolve;
});
const tabsToRemove = [];
for (let i = 0; i < 3; i++) {
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
gBrowser.pinTab(gBrowser.selectedTab);
tabsToRemove.push(gBrowser.selectedTab);
}
await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true);
tabsToRemove.push(gBrowser.selectedTab);
const newTab = gBrowser.selectedTab;
newTab.addEventListener(
'ZenPinnedTabCreated',
async function (event) {
ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()');
const pinTabID = newTab.getAttribute('zen-pin-id');
ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned');
newTab.addEventListener(
'ZenPinnedTabMoved',
async function (event) {
const pins = await ZenPinnedTabsStorage.getPins();
const pinObject = pins.find((pin) => pin.uuid === pinTabID);
Assert.equal(
pinObject.position,
0,
'The pin object should have the correct position after moving'
);
resolvePromise();
},
{ once: true }
);
gBrowser.moveTabTo(newTab, { tabIndex: 0 });
},
{ once: true }
);
gBrowser.pinTab(newTab);
await promise;
for (const tab of tabsToRemove) {
await BrowserTestUtils.removeTab(tab);
}
});

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