1
0
Fork 1
mirror of https://github.com/zen-browser/desktop.git synced 2025-07-08 00:10:00 +02:00

Refactor CSS and JavaScript files for consistency; clean up whitespace and formatting

This commit is contained in:
mr. M 2025-01-04 02:21:45 +01:00
parent 22515592f0
commit 7dfa6d55ba
No known key found for this signature in database
GPG key ID: CBD57A2AEDBDA1FB
56 changed files with 1607 additions and 1515 deletions

View file

@ -10,7 +10,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:

View file

@ -28,4 +28,3 @@ jobs:
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'

View file

@ -26,6 +26,6 @@ jobs:
- name: Commit
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "[skip ci] 📦 Update submodules"
commit_message: '[skip ci] 📦 Update submodules'
commit_user_name: Zen Browser Robot
commit_user_email: zen-browser-auto@users.noreply.github.com

View file

@ -3,6 +3,7 @@ engine/
**/*.html
**/*.xhtml
**/*.inc.xhtml
**/*.bundle.min.js
**/*.svg
@ -11,5 +12,9 @@ pnpm-lock.yaml
**/engine/
docs/issue-metrics/*.md
# Some CSS files are preprocessed and prettier doesn't handle them well
# We also dont want to format the CSS files that are generated by the build
src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css
src/browser/base/zen-components/ZenEmojies.mjs

View file

@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities

View file

@ -6,7 +6,6 @@
[![Crowdin](https://badges.crowdin.net/zen-browser/localized.svg)](https://crowdin.com/project/zen-browser)
[![Zen Release builds](https://github.com/zen-browser/desktop/actions/workflows/build.yml/badge.svg?branch=stable)](https://github.com/zen-browser/desktop/actions/workflows/build.yml)
✨ Experience tranquillity while browsing the web without people tracking you! Zen is a privacy-focused browser that blocks trackers, ads, and other unwanted content while offering the best browsing experience!
<div flex="true">
@ -99,7 +98,7 @@ yay -S zen-browser-bin
##### Other Linux distributions (AppImage with automated system integration)
- `native` tarball install:
```bash <(curl -s https://updates.zen-browser.app/install.sh)```
`bash <(curl -s https://updates.zen-browser.app/install.sh)`
- `zsync` is required for the Update feature of the script below
@ -107,7 +106,7 @@ yay -S zen-browser-bin
bash <(curl https://updates.zen-browser.app/appimage.sh)
```
* Again, if you don't see your OS listed above, that's because we already have it in our [downloads page](https://zen-browser.app/download)! 🔄
- Again, if you don't see your OS listed above, that's because we already have it in our [downloads page](https://zen-browser.app/download)! 🔄
To upgrade the browser to a newer version, use the embedded update functionality in `About Zen`.

View file

@ -1,4 +1,3 @@
# Branch Structure
The repository is structured as follows:

View file

@ -71,7 +71,7 @@ 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) {
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]);

View file

@ -28,13 +28,14 @@
// Fix notification deck
const deckTemplate = document.getElementById('tab-notification-deck-template');
if (deckTemplate) {
document
.getElementById('zen-appcontent-navbar-container')
.appendChild(deckTemplate);
document.getElementById('zen-appcontent-navbar-container').appendChild(deckTemplate);
}
// Disable smooth scroll
gBrowser.tabContainer.arrowScrollbox.smoothScroll = Services.prefs.getBoolPref('zen.startup.smooth-scroll-in-tabs', false);
gBrowser.tabContainer.arrowScrollbox.smoothScroll = Services.prefs.getBoolPref(
'zen.startup.smooth-scroll-in-tabs',
false
);
ZenWorkspaces.init();
gZenUIManager.init();

View file

@ -6,20 +6,18 @@ var gZenUIManager = {
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, 'contentElementSeparation', 'zen.theme.content-element-separation', 0);
new ResizeObserver(gZenCommonActions.throttle(this.updateTabsToolbar.bind(this), this.sidebarHeightThrottle)).observe(
document.getElementById('tabbrowser-tabs')
);
new ResizeObserver(gZenCommonActions.throttle(gZenCompactModeManager.getAndApplySidebarWidth.bind(gZenCompactModeManager), this.sidebarHeightThrottle)).observe(
document.getElementById('navigator-toolbox')
);
new ResizeObserver(
gZenCommonActions.throttle(
gZenCompactModeManager.getAndApplySidebarWidth.bind(gZenCompactModeManager),
this.sidebarHeightThrottle
)
).observe(document.getElementById('navigator-toolbox'));
},
updateTabsToolbar() {
@ -30,7 +28,7 @@ var gZenUIManager = {
const toolbarRect = toolbarItems.getBoundingClientRect();
let height = toolbarRect.height;
// -5 for the controls padding
let totalHeight = toolbarRect.height - (this.contentElementSeparation * 2) - 5;
let totalHeight = toolbarRect.height - this.contentElementSeparation * 2 - 5;
// remove the height from other elements that aren't hidden
const otherElements = document.querySelectorAll('#tabbrowser-tabs > *:not([hidden="true"])');
for (let tab of otherElements) {
@ -83,7 +81,10 @@ var gZenUIManager = {
for (const el of this._popupTrackingElements) {
// target may be inside a shadow root, not directly under the element
// we also ignore menus inside panels
if (!el.contains(showEvent.explicitOriginalTarget) || (showEvent.explicitOriginalTarget instanceof Element && showEvent.explicitOriginalTarget?.closest('panel'))) {
if (
!el.contains(showEvent.explicitOriginalTarget) ||
(showEvent.explicitOriginalTarget instanceof Element && showEvent.explicitOriginalTarget?.closest('panel'))
) {
continue;
}
document.removeEventListener('mousemove', this.__removeHasPopupAttribute);
@ -115,8 +116,11 @@ var gZenVerticalTabsManager = {
this._multiWindowFeature = new ZenMultiWindowFeature();
ChromeUtils.defineLazyGetter(this, 'isWindowsStyledButtons', () => {
return !(window.AppConstants.platform === 'macosx' || window.matchMedia('(-moz-gtk-csd-reversed-placement)').matches
|| Services.prefs.getBoolPref('zen.view.experimental-force-window-controls-left'));
return !(
window.AppConstants.platform === 'macosx' ||
window.matchMedia('(-moz-gtk-csd-reversed-placement)').matches ||
Services.prefs.getBoolPref('zen.view.experimental-force-window-controls-left')
);
});
ChromeUtils.defineLazyGetter(this, 'hidesTabsToolbar', () => {
@ -144,7 +148,7 @@ var gZenVerticalTabsManager = {
XPCOMUtils.defineLazyPreferenceGetter(this, 'canOpenTabOnMiddleClick', 'zen.tabs.newtab-on-middle-click', true);
if (!this.isWindowsStyledButtons) {
document.documentElement.setAttribute("zen-window-buttons-reversed", true);
document.documentElement.setAttribute('zen-window-buttons-reversed', true);
}
if (tabs) {
@ -199,9 +203,9 @@ var gZenVerticalTabsManager = {
get actualWindowButtons() {
// we have multiple ".titlebar-buttonbox-container" in the DOM, because of the titlebar
if (!this.__actualWindowButtons) {
this.__actualWindowButtons = (!this.isWindowsStyledButtons) ?
document.querySelector('.titlebar-buttonbox-container') : // TODO: test if it works 100% of the time
document.querySelector('#nav-bar .titlebar-buttonbox-container');
this.__actualWindowButtons = !this.isWindowsStyledButtons
? document.querySelector('.titlebar-buttonbox-container') // TODO: test if it works 100% of the time
: document.querySelector('#nav-bar .titlebar-buttonbox-container');
}
return this.__actualWindowButtons;
},
@ -225,44 +229,20 @@ var gZenVerticalTabsManager = {
initializePreferences(updateEvent) {
XPCOMUtils.defineLazyPreferenceGetter(
this,
"_prefsCompactMode",
"zen.view.compact",
'_prefsCompactMode',
'zen.view.compact',
false
// no need to update the event, it's handled by the compact mode manager
);
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",
"zen.view.sidebar-expanded.max-width",
'_prefsSidebarExpandedMaxWidth',
'zen.view.sidebar-expanded.max-width',
300,
updateEvent
);
@ -276,17 +256,17 @@ var gZenVerticalTabsManager = {
try {
this._updateMaxWidth();
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');
const isCompactMode = this._prefsCompactMode && !forCustomizableMode;
const isVerticalTabs = this._prefsVerticalTabs || forCustomizableMode;
const isSidebarExpanded = this._prefsSidebarExpanded || !isVerticalTabs;
const isRightSide = this._prefsRightSide && isVerticalTabs;
const isSingleToolbar = ((this._prefsUseSingleToolbar && (isVerticalTabs && isSidebarExpanded) )|| !isVerticalTabs) && !forCustomizableMode && !this.hidesTabsToolbar;
const isSingleToolbar =
((this._prefsUseSingleToolbar && isVerticalTabs && isSidebarExpanded) || !isVerticalTabs) &&
!forCustomizableMode &&
!this.hidesTabsToolbar;
const titlebar = document.getElementById('titlebar');
gBrowser.tabContainer.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal');
@ -311,10 +291,12 @@ var gZenVerticalTabsManager = {
const appContentNavbarContaienr = document.getElementById('zen-appcontent-navbar-container');
let shouldHide = false;
if (((!isRightSide && this.isWindowsStyledButtons) || (isRightSide && !this.isWindowsStyledButtons)
|| (
isCompactMode && isSingleToolbar && this.isWindowsStyledButtons
)) && isSingleToolbar) {
if (
((!isRightSide && this.isWindowsStyledButtons) ||
(isRightSide && !this.isWindowsStyledButtons) ||
(isCompactMode && isSingleToolbar && this.isWindowsStyledButtons)) &&
isSingleToolbar
) {
appContentNavbarContaienr.setAttribute('should-hide', 'true');
shouldHide = true;
} else {
@ -322,10 +304,7 @@ var gZenVerticalTabsManager = {
}
// Check if the sidebar is in hover mode
if (
!this.navigatorToolbox.hasAttribute('zen-right-side') &&
!isCompactMode
) {
if (!this.navigatorToolbox.hasAttribute('zen-right-side') && !isCompactMode) {
this.navigatorToolbox.prepend(topButtons);
}
@ -335,7 +314,9 @@ var gZenVerticalTabsManager = {
if (isSingleToolbar) {
this._navbarParent = navBar.parentElement;
let elements = document.querySelectorAll('#nav-bar-customization-target > :is([cui-areatype="toolbar"], .chromeclass-toolbar-additional):not(#urlbar-container)');
let elements = document.querySelectorAll(
'#nav-bar-customization-target > :is([cui-areatype="toolbar"], .chromeclass-toolbar-additional):not(#urlbar-container)'
);
elements = Array.from(elements).reverse();
// Add separator if it doesn't exist
if (!buttonsTarget.contains(this._topButtonsSeparatorElement)) {
@ -356,18 +337,20 @@ var gZenVerticalTabsManager = {
titlebar.before(topButtons);
titlebar.before(navBar);
}
document.documentElement.setAttribute("zen-single-toolbar", true);
document.documentElement.setAttribute('zen-single-toolbar', true);
this._hasSetSingleToolbar = true;
} else if (this._hasSetSingleToolbar) {
this._hasSetSingleToolbar = false;
// Do the opposite
this._navbarParent.prepend(navBar);
const elements = document.querySelectorAll('#zen-sidebar-top-buttons-customization-target > :is([cui-areatype="toolbar"], .chromeclass-toolbar-additional)');
const elements = document.querySelectorAll(
'#zen-sidebar-top-buttons-customization-target > :is([cui-areatype="toolbar"], .chromeclass-toolbar-additional)'
);
for (const button of elements) {
document.getElementById('nav-bar-customization-target').append(button);
}
this._topButtonsSeparatorElement.remove();
document.documentElement.removeAttribute("zen-single-toolbar");
document.documentElement.removeAttribute('zen-single-toolbar');
navBar.appendChild(document.getElementById('PanelUI-button'));
this._toolbarOriginalParent.prepend(navBar);
if (!dontRebuildAreas) {
@ -398,7 +381,7 @@ var gZenVerticalTabsManager = {
if (isRightSide && !isSidebarExpanded) {
navBar.appendChild(windowButtons);
} else {
document.getElementById("zen-sidebar-top-buttons-customization-target").appendChild(windowButtons);
document.getElementById('zen-sidebar-top-buttons-customization-target').appendChild(windowButtons);
}
} else if (!isSingleToolbar && !isCompactMode) {
if (this.isWindowsStyledButtons) {
@ -407,7 +390,8 @@ var gZenVerticalTabsManager = {
} else {
navBar.append(windowButtons);
}
} else { // not windows styled buttons
} else {
// not windows styled buttons
if (isRightSide || !isSidebarExpanded) {
navBar.prepend(windowButtons);
} else {

View file

@ -51,7 +51,7 @@
transform: translateY(-25px);
}
60% {
opacity: 0.8 ;
opacity: 0.8;
transform: translateY(4px);
}
100% {

View file

@ -24,6 +24,6 @@
font-feature-settings: 'swsh' 1;
& .zen-branding-title-italic {
font-family: "Zen-Junicode-Italic", serif;
font-family: 'Zen-Junicode-Italic', serif;
}
}

View file

@ -10,7 +10,9 @@
position: relative;
/* For glance */
transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out;
transition:
transform 0.1s ease-in-out,
opacity 0.1s ease-in-out;
box-shadow: 0 0 1px 1px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.5));
overflow: hidden;
@ -20,7 +22,7 @@
margin-left: var(--zen-element-separation);
}
:root[zen-no-padding='true'] &:not([zen-split="true"]) {
:root[zen-no-padding='true'] &:not([zen-split='true']) {
border-radius: 0 !important;
}
}

View file

@ -51,7 +51,7 @@
&[animating='true']::after {
background: var(--zen-main-browser-background-old);
backdrop-filter: blur(5px);
animation: zen-main-app-wrapper-animation .6s ease forwards;
animation: zen-main-app-wrapper-animation 0.6s ease forwards;
transition: 0s;
}
}
@ -99,7 +99,6 @@
border: none;
}
@supports (-moz-osx-font-smoothing: auto) {
#zen-main-app-wrapper,
#zen-appcontent-wrapper,

View file

@ -48,7 +48,10 @@
&:not([animate='true']) {
position: absolute;
z-index: 10;
transition: left 0.25s ease, right 0.25s ease, opacity 1.5s ease;
transition:
left 0.25s ease,
right 0.25s ease,
opacity 1.5s ease;
top: 0;
bottom: var(--zen-element-separation);
opacity: 0;
@ -124,9 +127,13 @@
#navigator-toolbox[has-popup-menu],
#navigator-toolbox[movingtab],
#navigator-toolbox:has(.tabbrowser-tab:active),
#navigator-toolbox:has(*:is([panelopen='true'], [open='true'], #nav-bar:focus-within):not(tab):not(.zen-compact-mode-ignore)) {
#navigator-toolbox:has(
*:is([panelopen='true'], [open='true'], #nav-bar:focus-within):not(tab):not(.zen-compact-mode-ignore)
) {
&:not([animate='true']) {
transition: left 0.25s ease, right 0.25s ease;
transition:
left 0.25s ease,
right 0.25s ease;
opacity: 1;
left: -1px;

View file

@ -17,7 +17,7 @@
}
#zen-splitview-dropzone {
border-radius: var(--zen-webview-border-radius, var(--zen-border-radius));
transition: inset ease-out .08s;
transition: inset ease-out 0.08s;
display: none;
background-color: color-mix(in srgb, var(--zen-colors-secondary) 30%, transparent 70%);
}
@ -25,7 +25,8 @@
display: initial;
}
#tabbrowser-tabpanels[zen-split-view='true'] > [zen-split='true'], #zen-splitview-dropzone {
#tabbrowser-tabpanels[zen-split-view='true'] > [zen-split='true'],
#zen-splitview-dropzone {
flex: 1;
margin: calc(var(--zen-split-column-gap) / 2) calc(var(--zen-split-row-gap) / 2 + 1px) !important;
margin-bottom: 0 !important;
@ -51,7 +52,7 @@
#tabbrowser-tabbox:has(#tabbrowser-tabpanels[zen-split-view='true']) {
--zen-split-row-gap: calc(var(--zen-element-separation) + 1px);
--zen-split-column-gap: calc(var(--zen-element-separation)*3 + 1px);
--zen-split-column-gap: calc(var(--zen-element-separation) * 3 + 1px);
margin-right: calc(-1 * var(--zen-split-column-gap));
:root[zen-right-side='true'] & {
@ -60,12 +61,13 @@
}
}
#tabbrowser-tabpanels:has(> [zen-split='true']), #zen-splitview-overlay {
margin-right: calc(var(--zen-element-separation) - var(--zen-split-row-gap)/2);
margin-bottom: calc(var(--zen-element-separation) - var(--zen-split-column-gap)/2);
#tabbrowser-tabpanels:has(> [zen-split='true']),
#zen-splitview-overlay {
margin-right: calc(var(--zen-element-separation) - var(--zen-split-row-gap) / 2);
margin-bottom: calc(var(--zen-element-separation) - var(--zen-split-column-gap) / 2);
margin-left: calc(var(--zen-split-row-gap)/-2);
margin-top: calc(var(--zen-split-column-gap)/-2);
margin-left: calc(var(--zen-split-row-gap) / -2);
margin-top: calc(var(--zen-split-column-gap) / -2);
@media (-moz-bool-pref: 'zen.view.compact') {
:root:not([customizing]) & {
@ -112,7 +114,6 @@
pointer-events: all;
}
.zen-split-view-splitter[orient='vertical'] {
width: var(--zen-split-row-gap);
margin-left: calc(var(--zen-split-row-gap) / -2);
@ -181,7 +182,7 @@
border-radius: 3px;
width: 100%;
height: 100%;
transition: .1s;
transition: 0.1s;
}
&:hover box {

View file

@ -32,7 +32,7 @@
& .browserContainer {
opacity: 1;
animation: zen-glance-content-animation-out .3s ease-in-out forwards !important;
animation: zen-glance-content-animation-out 0.3s ease-in-out forwards !important;
& browser {
opacity: 1 !important;
@ -40,7 +40,7 @@
& #zen-glance-sidebar-container {
opacity: 0;
transition: opacity .1s ease-in-out;
transition: opacity 0.1s ease-in-out;
}
}
}
@ -118,7 +118,7 @@
}
&[animate='true'] {
animation: zen-glance-content-animation .4s ease-in-out forwards;
animation: zen-glance-content-animation 0.4s ease-in-out forwards;
&:not([animate-end='true']) {
pointer-events: none;

View file

@ -51,7 +51,7 @@
bottom: 2px;
right: 0;
border: 2px solid var(--zen-colors-border);
transition: transform .2s;
transition: transform 0.2s;
}
&[dragging='true']::after {
@ -152,7 +152,7 @@
padding: 2px 4px !important;
margin: 0 !important;
margin-left: auto !important;
transition: opacity .1s;
transition: opacity 0.1s;
opacity: 0;
}
@ -246,8 +246,8 @@
box-shadow: 0 0 0 2px var(--zen-themed-toolbar-bg);
cursor: pointer;
border: 2px solid #fff;
animation: zen-theme-picker-dot-animation .5s;
transition: transform .2s;
animation: zen-theme-picker-dot-animation 0.5s;
transition: transform 0.2s;
transform: translate(-50%, -50%);
&[dragging='true'] {

View file

@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
panel[type='arrow'][animate][animate='open']::part(content) {
animation: zen-jello-animation .35s ease;
animation: zen-jello-animation 0.35s ease;
}
panel[type='arrow'][animate]:not([animate='open'])::part(content) {

View file

@ -4,7 +4,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
.printSettingsBrowser {
min-width: 350px;
}

View file

@ -341,6 +341,6 @@ menuitem {
cursor: pointer;
}
#editBMPanel_workspaceList input[type="checkbox"] {
#editBMPanel_workspaceList input[type='checkbox'] {
margin-right: 8px;
}

View file

@ -1,4 +1,3 @@
#zen-rice-share-dialog-overlay:not([hidden]) {
position: absolute;
top: 0;
@ -17,15 +16,15 @@
color: var(--panel-color);
background: var(--arrowpanel-background);
border-radius: var(--zen-panel-radius);
box-shadow: 0 0 1px 1px hsla(0,0%,0%,.2);;
box-shadow: 0 0 1px 1px hsla(0, 0%, 0%, 0.2);
border: var(--zen-appcontent-border);
overflow: hidden;
animation: zen-jello-animation-large 0.4s ease;
max-width: 400px;
&[animate="true"] {
animation: zen-rice-submit-animation 1s cubic-bezier(.77,0,.18,1);
&[animate='true'] {
animation: zen-rice-submit-animation 1s cubic-bezier(0.77, 0, 0.18, 1);
}
& .zen-rice-share-content {
@ -47,7 +46,7 @@
padding: 0 10px;
}
& #zen-rice-share-first-form input[type="text"] {
& #zen-rice-share-first-form input[type='text'] {
width: 100%;
padding: 1px 2px;
border: 0;
@ -78,8 +77,10 @@
max-height: 30px;
overflow: hidden;
transition: max-height 0.3s ease, height 0.3s ease;
&[zen-collapsed="false"] {
transition:
max-height 0.3s ease,
height 0.3s ease;
&[zen-collapsed='false'] {
max-height: 350px;
}
@ -106,7 +107,7 @@
height: 15px;
}
&[zen-collapsed="false"] > .options-header image {
&[zen-collapsed='false'] > .options-header image {
transform: rotate(90deg);
}
@ -162,7 +163,7 @@
overflow: hidden;
&::before {
content: "";
content: '';
position: absolute;
top: 0;
left: 0;

View file

@ -101,7 +101,7 @@
}
.zen-sidebar-web-panel-splitter,
.zen-split-view-splitter[orient="vertical"] {
.zen-split-view-splitter[orient='vertical'] {
position: absolute;
top: 0;
left: 0;
@ -131,7 +131,7 @@
}
}
.zen-split-view-splitter[orient="vertical"]::before {
.zen-split-view-splitter[orient='vertical']::before {
transform: translate(-75%, -50%);
}
@ -256,7 +256,7 @@
}
#zen-sidebar-web-panel-title {
font-size: .9em;
font-size: 0.9em;
font-weight: 600;
margin: 0 10px;
padding: 0;
@ -316,4 +316,3 @@
#zen-sidebar-web-panel[hidden] {
animation: better-sidebar-hide 0.15s ease-in-out forwards !important;
}

View file

@ -66,7 +66,6 @@
display: none !important;
}
body > #confetti {
z-index: 1;
}

View file

@ -18,7 +18,6 @@
padding: var(--zen-toolbox-padding) !important;
}
#tabbrowser-tabs {
display: -webkit-box !important;
-webkit-box-orient: horizontal;
@ -79,8 +78,7 @@
width: 0% !important;
}
.tabbrowser-tab[zen-glance-tab="true"] {
.tabbrowser-tab[zen-glance-tab='true'] {
.tab-label-container {
display: none !important;
width: 0px !important;
@ -105,7 +103,7 @@
flex-direction: row !important;
}
#tabbrowser-tabs[orient="vertical"] {
#tabbrowser-tabs[orient='vertical'] {
flex-direction: row !important;
}
@ -205,7 +203,7 @@
#vertical-pinned-tabs-container::after {
z-index: -1;
content: "";
content: '';
position: absolute;
right: 0;
width: 1px;
@ -311,16 +309,16 @@
height: 3px !important;
}
.tabbrowser-tab[zen-glance-tab="true"] {
.tabbrowser-tab[zen-glance-tab='true'] {
flex-basis: fit-content !important;
max-width: 36px !important;
}
#zen-essentials-container .tabbrowser-tab[zen-glance-tab="true"] {
#zen-essentials-container .tabbrowser-tab[zen-glance-tab='true'] {
left: 2px;
}
#vertical-pinned-tabs-container .tabbrowser-tab[zen-glance-tab="true"] {
#vertical-pinned-tabs-container .tabbrowser-tab[zen-glance-tab='true'] {
position: absolute !important;
}

View file

@ -2,7 +2,9 @@ height: var(--zen-toolbar-height);
@media (-moz-bool-pref: 'zen.view.hide-window-controls') {
& {
transition: height 0.15s ease, opacity 0.1s ease-out;
transition:
height 0.15s ease,
opacity 0.1s ease-out;
transition-delay: 0.2s;
& > * {

View file

@ -3,7 +3,7 @@
* 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/.
*/
/* Here, we contain all the theme related variables, for example theme
/* Here, we contain all the theme related variables, for example theme
* colors, border radius, etc.
* We have `--zen-border-radius` and `--zen-primary-color` as variables.
*/
@ -21,7 +21,7 @@
/* Branding */
--zen-branding-dark: #202020;
--zen-branding-coral: #F76F53;
--zen-branding-coral: #f76f53;
--zen-branding-paper: #ebebeb;
--zen-branding-bg: light-dark(var(--zen-branding-paper), var(--zen-branding-dark));
@ -43,9 +43,21 @@
--zen-secondary-btn-color: var(--zen-colors-primary-foreground);
--in-content-primary-button-background: color-mix(in srgb, var(--zen-primary-color) 10%, var(--zen-branding-bg) 90%) !important;
--in-content-primary-button-background-hover: color-mix(in srgb, var(--zen-primary-color) 15%, var(--zen-branding-bg) 85%) !important;
--in-content-primary-button-background-active: color-mix(in srgb, var(--zen-primary-color) 20%, var(--zen-branding-bg) 80%) !important;
--in-content-primary-button-background: color-mix(
in srgb,
var(--zen-primary-color) 10%,
var(--zen-branding-bg) 90%
) !important;
--in-content-primary-button-background-hover: color-mix(
in srgb,
var(--zen-primary-color) 15%,
var(--zen-branding-bg) 85%
) !important;
--in-content-primary-button-background-active: color-mix(
in srgb,
var(--zen-primary-color) 20%,
var(--zen-branding-bg) 80%
) !important;
--button-text-color-primary: var(--zen-branding-bg-reverse) !important;
--in-content-primary-button-text-color: var(--zen-colors-primary-foreground) !important;
--in-content-primary-button-border-color: transparent !important;
@ -91,10 +103,7 @@
--zen-button-border-radius: 5px;
--zen-button-padding: 0.6rem 1.2rem;
--zen-toolbar-element-bg: light-dark(
rgba(255, 255, 255, 0.4),
rgba(170, 170, 170, 0.2)
);
--zen-toolbar-element-bg: light-dark(rgba(255, 255, 255, 0.4), rgba(170, 170, 170, 0.2));
/* Toolbar */
--zen-toolbar-height: 38px;
@ -137,7 +146,10 @@
--fp-contextmenu-bgcolor: light-dark(Menu, rgb(43 42 51 / 0.95));
--toolbar-bgcolor: transparent;
--toolbarbutton-active-background: light-dark(rgba(255, 255, 255, .9), color-mix(in srgb, var(--zen-primary-color) 50%, rgba(255, 255, 255, .1)));
--toolbarbutton-active-background: light-dark(
rgba(255, 255, 255, 0.9),
color-mix(in srgb, var(--zen-primary-color) 50%, rgba(255, 255, 255, 0.1))
);
--input-bgcolor: var(--zen-colors-tertiary) !important;
--input-border-color: var(--zen-input-border-color) !important;
@ -147,13 +159,16 @@
@media (-moz-windows-mica) or (-moz-platform: macos) {
background: transparent;
--zen-themed-toolbar-bg-transparency: 0;
--zen-themed-toolbar-bg-transparent: light-dark(rgba(255, 255, 255, var(--zen-themed-toolbar-bg-transparency)), rgba(0, 0, 0, var(--zen-themed-toolbar-bg-transparency)));
--zen-themed-toolbar-bg-transparent: light-dark(
rgba(255, 255, 255, var(--zen-themed-toolbar-bg-transparency)),
rgba(0, 0, 0, var(--zen-themed-toolbar-bg-transparency))
);
}
--toolbar-field-background-color: var(--zen-colors-input-bg) !important;
--arrowpanel-background: var(--zen-dialog-background) !important;
--tab-selected-shadow: 0 0 1px 1px rgba(0,0,0,.1) !important;
--tab-selected-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1) !important;
}
@media (prefers-color-scheme: dark) {

View file

@ -48,7 +48,7 @@
outline-color: none !important;
}
#identity-box.chromeUI:not([pageproxystate="invalid"]) {
#identity-box.chromeUI:not([pageproxystate='invalid']) {
& #identity-icon-box {
background: light-dark(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1)) !important;
}
@ -125,7 +125,6 @@
}
:root[zen-single-toolbar='true'] {
.urlbar-page-action:not(#star-button-box):not([open]),
#tracking-protection-icon-container {
margin-inline-end: calc(-16px - 2 * var(--urlbar-icon-padding)) !important;
@ -437,7 +436,10 @@ button.popup-notification-dropmarker {
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
**/
.urlbarView-title, .urlbarView-title-separator, .urlbarView-action, .urlbarView-url {
.urlbarView-title,
.urlbarView-title-separator,
.urlbarView-action,
.urlbarView-url {
margin-top: auto !important;
margin-bottom: auto !important;
}
@ -447,7 +449,8 @@ button.popup-notification-dropmarker {
font-weight: 500 !important;
}
.urlbarView-url, .urlbarView-title-separator::before {
.urlbarView-url,
.urlbarView-title-separator::before {
font-size: 14px !important;
font-weight: 500 !important;
color: #aaa !important;
@ -460,7 +463,7 @@ button.popup-notification-dropmarker {
border-radius: 6px !important;
}
.urlbarView-row[has-action]:is([type="switchtab"], [type="remotetab"], [type="clipboard"]) .urlbarView-action {
.urlbarView-row[has-action]:is([type='switchtab'], [type='remotetab'], [type='clipboard']) .urlbarView-action {
margin-left: auto !important;
margin-right: 0 !important;
}
@ -477,7 +480,8 @@ button.popup-notification-dropmarker {
background-color: color-mix(in srgb, var(--zen-branding-bg-reverse) 20%, transparent 80%) !important;
}
.urlbarView-url, .urlbarView-title-separator::before {
.urlbarView-url,
.urlbarView-title-separator::before {
color: color-mix(in srgb, var(--zen-colors-primary) 30%, lightgray) !important;
}
}

View file

@ -266,7 +266,6 @@
}
}
/* Workspace icon picker styles */
#PanelUI-zen-workspaces-icon-picker-wrapper {
display: flex;
@ -391,7 +390,6 @@
background-color: var(--toolbarbutton-icon-fill-attention);
}
#PanelUI-zen-workspaces-reorder-mode[active='true'] {
color: var(--toolbarbutton-icon-fill-attention) !important;
}

View file

@ -76,9 +76,9 @@ var ZenThemeModifier = {
const separation = Services.prefs.getIntPref('zen.theme.content-element-separation');
document.documentElement.style.setProperty('--zen-element-separation', separation + 'px');
if (separation == 0) {
document.documentElement.setAttribute("zen-no-padding", true);
document.documentElement.setAttribute('zen-no-padding', true);
} else {
document.documentElement.removeAttribute("zen-no-padding");
document.documentElement.removeAttribute('zen-no-padding');
}
},

View file

@ -1,4 +1,3 @@
// Utility to register JSWindowActors
var gZenActorsManager = {
_actors: new Set(),
@ -16,4 +15,4 @@ var gZenActorsManager = {
console.warn(`Failed to register JSWindowActor: ${e}`);
}
},
}
};

View file

@ -62,22 +62,14 @@ var gZenCommonActions = {
copyCurrentURLToClipboard() {
const currentUrl = gBrowser.currentURI.spec;
if (currentUrl) {
let str = Cc["@mozilla.org/supports-string;1"].createInstance(
Ci.nsISupportsString
);
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
);
ConfirmationHint.show(document.getElementById("PanelUI-menu-button"), "zen-copy-current-url-confirmation");
transferable.addDataFlavor('text/plain');
transferable.setTransferData('text/plain', str);
Services.clipboard.setData(transferable, null, Ci.nsIClipboard.kGlobalClipboard);
ConfirmationHint.show(document.getElementById('PanelUI-menu-button'), 'zen-copy-current-url-confirmation');
}
},
@ -87,5 +79,5 @@ var gZenCommonActions = {
clearTimeout(timer);
timer = setTimeout(() => f.apply(this, args), delay);
};
}
},
};

View file

@ -69,7 +69,11 @@ var gZenCompactModeManager = {
updateCompactModeContext(isSingleToolbar) {
this.getAndApplySidebarWidth(); // Ignore return value
const IDs = ['zen-context-menu-compact-mode-hide-sidebar', 'zen-context-menu-compact-mode-hide-toolbar', 'zen-context-menu-compact-mode-hide-both'];
const IDs = [
'zen-context-menu-compact-mode-hide-sidebar',
'zen-context-menu-compact-mode-hide-toolbar',
'zen-context-menu-compact-mode-hide-both',
];
for (let id of IDs) {
document.getElementById(id).disabled = isSingleToolbar;
}
@ -104,7 +108,7 @@ var gZenCompactModeManager = {
getAndApplySidebarWidth() {
let sidebarWidth = this.sidebar.getBoundingClientRect().width;
if (sidebarWidth > 1) {
this.sidebar.style.setProperty("--zen-sidebar-width", `${sidebarWidth}px`);
this.sidebar.style.setProperty('--zen-sidebar-width', `${sidebarWidth}px`);
}
return sidebarWidth;
},
@ -118,40 +122,40 @@ var gZenCompactModeManager = {
this._isAnimating = true;
// Do this so we can get the correct width ONCE compact mode styled have been applied
if (this._canAnimateSidebar) {
this.sidebar.setAttribute("animate", "true");
this.sidebar.setAttribute('animate', 'true');
}
window.requestAnimationFrame(() => {
let sidebarWidth = this.getAndApplySidebarWidth();
if (!this._canAnimateSidebar) {
this.sidebar.removeAttribute("animate");
this.sidebar.removeAttribute('animate');
this._isAnimating = false;
return;
}
if (canHideSidebar && isCompactMode) {
window.requestAnimationFrame(() => {
this.sidebar.style.position = "unset";
this.sidebar.style.transition = "margin .4s ease";
this.sidebar.style.left = "0";
this.sidebar.style.position = 'unset';
this.sidebar.style.transition = 'margin .4s ease';
this.sidebar.style.left = '0';
if (!this.sidebarIsOnRight) {
this.sidebar.style.marginLeft = `${-1 * sidebarWidth}px`;
} else {
this.sidebar.style.marginRight = `${-1 * sidebarWidth}px`;
}
this.sidebar.style.pointerEvents = "none";
this.sidebar.style.pointerEvents = 'none';
window.requestAnimationFrame(() => {
setTimeout(() => {
window.requestAnimationFrame(() => {
this.sidebar.style.removeProperty("pointer-events");
this.sidebar.style.removeProperty("position");
this.sidebar.style.removeProperty("margin-left");
this.sidebar.style.removeProperty("margin-right");
this.sidebar.style.removeProperty("transform");
this.sidebar.style.removeProperty("left");
document.getElementById('browser').style.removeProperty("overflow");
this.sidebar.removeAttribute("animate");
this.sidebar.style.removeProperty('pointer-events');
this.sidebar.style.removeProperty('position');
this.sidebar.style.removeProperty('margin-left');
this.sidebar.style.removeProperty('margin-right');
this.sidebar.style.removeProperty('transform');
this.sidebar.style.removeProperty('left');
document.getElementById('browser').style.removeProperty('overflow');
this.sidebar.removeAttribute('animate');
window.requestAnimationFrame(() => {
this.sidebar.style.removeProperty("transition");
this.sidebar.style.removeProperty('transition');
this._isAnimating = false;
});
});
@ -159,9 +163,9 @@ var gZenCompactModeManager = {
});
});
} else if (canHideSidebar && !isCompactMode) {
document.getElementById('browser').style.overflow = "hidden";
this.sidebar.style.position = "relative";
this.sidebar.style.left = "0";
document.getElementById('browser').style.overflow = 'hidden';
this.sidebar.style.position = 'relative';
this.sidebar.style.left = '0';
if (!this.sidebarIsOnRight) {
this.sidebar.style.marginLeft = `${-1 * sidebarWidth}px`;
@ -171,35 +175,35 @@ var gZenCompactModeManager = {
}
window.requestAnimationFrame(() => {
this.sidebar.style.transition = "margin .3s ease, transform .275s ease, opacity .3s ease";
this.sidebar.style.transition = 'margin .3s ease, transform .275s ease, opacity .3s ease';
// we are in compact mode and we are exiting it
if (!this.sidebarIsOnRight) {
this.sidebar.style.marginLeft = "0";
this.sidebar.style.marginLeft = '0';
} else {
this.sidebar.style.marginRight = "0";
this.sidebar.style.transform = "translateX(0)";
this.sidebar.style.marginRight = '0';
this.sidebar.style.transform = 'translateX(0)';
}
this.sidebar.style.pointerEvents = "none";
this.sidebar.style.pointerEvents = 'none';
setTimeout(() => {
window.requestAnimationFrame(() => {
this._isAnimating = false;
this.sidebar.style.removeProperty("position");
this.sidebar.style.removeProperty("pointer-events");
this.sidebar.style.removeProperty("opacity");
this.sidebar.style.removeProperty("margin-left");
this.sidebar.style.removeProperty("margin-right");
this.sidebar.style.removeProperty("transform");
this.sidebar.style.removeProperty("transition");
this.sidebar.style.removeProperty("left");
this.sidebar.style.removeProperty('position');
this.sidebar.style.removeProperty('pointer-events');
this.sidebar.style.removeProperty('opacity');
this.sidebar.style.removeProperty('margin-left');
this.sidebar.style.removeProperty('margin-right');
this.sidebar.style.removeProperty('transform');
this.sidebar.style.removeProperty('transition');
this.sidebar.style.removeProperty('left');
document.getElementById('browser').style.removeProperty("overflow");
this.sidebar.removeAttribute("animate");
document.getElementById('browser').style.removeProperty('overflow');
this.sidebar.removeAttribute('animate');
});
}, 400);
});
} else {
this.sidebar.removeAttribute("animate"); // remove the attribute if we are not animating
this.sidebar.removeAttribute('animate'); // remove the attribute if we are not animating
}
});
},

View file

@ -1,6 +1,4 @@
{
class ZenGlanceManager extends ZenDOMOperatedFeature {
#currentBrowser = null;
#currentTab = null;
@ -8,23 +6,19 @@
#animating = false;
init() {
document.documentElement.setAttribute("zen-glance-uuid", gZenUIManager.generateUuidv4());
window.addEventListener("keydown", this.onKeyDown.bind(this));
window.addEventListener("TabClose", this.onTabClose.bind(this));
document.documentElement.setAttribute('zen-glance-uuid', gZenUIManager.generateUuidv4());
window.addEventListener('keydown', this.onKeyDown.bind(this));
window.addEventListener('TabClose', this.onTabClose.bind(this));
ChromeUtils.defineLazyGetter(
this,
'sidebarButtons',
() => document.getElementById('zen-glance-sidebar-container')
);
ChromeUtils.defineLazyGetter(this, 'sidebarButtons', () => document.getElementById('zen-glance-sidebar-container'));
document.getElementById('tabbrowser-tabpanels').addEventListener("click", this.onOverlayClick.bind(this));
document.getElementById('tabbrowser-tabpanels').addEventListener('click', this.onOverlayClick.bind(this));
Services.obs.addObserver(this, "quit-application-requested");
Services.obs.addObserver(this, 'quit-application-requested');
}
onKeyDown(event) {
if (event.key === "Escape" && this.#currentBrowser) {
if (event.key === 'Escape' && this.#currentBrowser) {
event.preventDefault();
event.stopPropagation();
this.closeGlance();
@ -39,7 +33,7 @@
observe(subject, topic) {
switch (topic) {
case "quit-application-requested":
case 'quit-application-requested':
this.onUnload();
break;
}
@ -54,7 +48,7 @@
createBrowserElement(url, currentTab) {
const newTabOptions = {
userContextId: currentTab.getAttribute("usercontextid") || "",
userContextId: currentTab.getAttribute('usercontextid') || '',
skipBackgroundNotify: true,
insertTab: true,
skipLoad: false,
@ -64,8 +58,8 @@
const newTab = gBrowser.addTrustedTab(Services.io.newURI(url).spec, newTabOptions);
gBrowser.selectedTab = newTab;
currentTab.querySelector(".tab-content").appendChild(newTab);
newTab.setAttribute("zen-glance-tab", true);
currentTab.querySelector('.tab-content').appendChild(newTab);
newTab.setAttribute('zen-glance-tab', true);
this.#currentBrowser = newTab.linkedBrowser;
this.#currentTab = newTab;
return this.#currentBrowser;
@ -81,12 +75,12 @@
const initialWidth = data.width;
const initialHeight = data.height;
this.browserWrapper?.removeAttribute("animate");
this.browserWrapper?.removeAttribute("animate-end");
this.browserWrapper?.removeAttribute("animate-full");
this.browserWrapper?.removeAttribute("animate-full-end");
this.browserWrapper?.removeAttribute("has-finished-animation");
this.overlay?.removeAttribute("post-fade-out");
this.browserWrapper?.removeAttribute('animate');
this.browserWrapper?.removeAttribute('animate-end');
this.browserWrapper?.removeAttribute('animate-full');
this.browserWrapper?.removeAttribute('animate-full-end');
this.browserWrapper?.removeAttribute('has-finished-animation');
this.overlay?.removeAttribute('post-fade-out');
const url = data.url;
const currentTab = gBrowser.selectedTab;
@ -94,29 +88,29 @@
this.animatingOpen = true;
const browserElement = this.createBrowserElement(url, currentTab);
this.overlay = browserElement.closest(".browserSidebarContainer");
this.browserWrapper = browserElement.closest(".browserContainer");
this.contentWrapper = browserElement.closest(".browserStack");
this.overlay = browserElement.closest('.browserSidebarContainer');
this.browserWrapper = browserElement.closest('.browserContainer');
this.contentWrapper = browserElement.closest('.browserStack');
this.browserWrapper.prepend(this.sidebarButtons);
this.overlay.classList.add("zen-glance-overlay");
this.overlay.classList.add('zen-glance-overlay');
this.browserWrapper.removeAttribute("animate-end");
this.browserWrapper.removeAttribute('animate-end');
window.requestAnimationFrame(() => {
this.quickOpenGlance();
this.browserWrapper.style.setProperty("--initial-x", `${initialX}px`);
this.browserWrapper.style.setProperty("--initial-y", `${initialY}px`);
this.browserWrapper.style.setProperty("--initial-width", initialWidth + "px");
this.browserWrapper.style.setProperty("--initial-height", initialHeight + "px");
this.browserWrapper.style.setProperty('--initial-x', `${initialX}px`);
this.browserWrapper.style.setProperty('--initial-y', `${initialY}px`);
this.browserWrapper.style.setProperty('--initial-width', initialWidth + 'px');
this.browserWrapper.style.setProperty('--initial-height', initialHeight + 'px');
this.overlay.removeAttribute("fade-out");
this.browserWrapper.setAttribute("animate", true);
this.overlay.removeAttribute('fade-out');
this.browserWrapper.setAttribute('animate', true);
this.#animating = true;
setTimeout(() => {
this.browserWrapper.setAttribute("animate-end", true);
this.browserWrapper.setAttribute("has-finished-animation", true);
this.browserWrapper.setAttribute('animate-end', true);
this.browserWrapper.setAttribute('has-finished-animation', true);
this.#animating = false;
this.animatingOpen = false;
}, 500);
@ -128,7 +122,7 @@
return;
}
this.browserWrapper.removeAttribute("has-finished-animation");
this.browserWrapper.removeAttribute('has-finished-animation');
if (noAnimation) {
this.quickCloseGlance({ closeCurrentTab: false });
this.#currentBrowser = null;
@ -156,13 +150,13 @@
// do NOT touch here, I don't know what it does, but it works...
window.requestAnimationFrame(() => {
this.#currentTab.style.display = "none";
this.browserWrapper.removeAttribute("animate");
this.browserWrapper.removeAttribute("animate-end");
this.overlay.setAttribute("fade-out", true);
this.#currentTab.style.display = 'none';
this.browserWrapper.removeAttribute('animate');
this.browserWrapper.removeAttribute('animate-end');
this.overlay.setAttribute('fade-out', true);
window.requestAnimationFrame(() => {
this.quickCloseGlance({ justAnimateParent: true });
this.browserWrapper.setAttribute("animate", true);
this.browserWrapper.setAttribute('animate', true);
setTimeout(() => {
if (!this.currentParentTab) {
return;
@ -171,12 +165,12 @@
if (!onTabClose || quikcCloseZen) {
this.quickCloseGlance();
}
this.overlay.removeAttribute("fade-out");
this.browserWrapper.removeAttribute("animate");
this.overlay.removeAttribute('fade-out');
this.browserWrapper.removeAttribute('animate');
this.lastCurrentTab = this.#currentTab;
this.overlay.classList.remove("zen-glance-overlay");
this.overlay.classList.remove('zen-glance-overlay');
gBrowser._getSwitcher().setTabStateNoAction(this.lastCurrentTab, gBrowser.AsyncTabSwitcher.STATE_UNLOADED);
if (!onTabClose && gBrowser.selectedTab === this.lastCurrentTab) {
@ -190,7 +184,7 @@
this.overlay = null;
this.contentWrapper = null;
this.lastCurrentTab.removeAttribute("zen-glance-tab");
this.lastCurrentTab.removeAttribute('zen-glance-tab');
this.lastCurrentTab._closingGlance = true;
gBrowser.tabContainer._invalidateCachedTabs();
@ -215,26 +209,28 @@
gBrowser.selectedTab = this.#currentTab;
} catch (e) {}
this.currentParentTab.linkedBrowser.closest(".browserSidebarContainer").classList.add("deck-selected", "zen-glance-background");
this.currentParentTab.linkedBrowser.closest(".browserSidebarContainer").classList.remove("zen-glance-overlay");
this.currentParentTab.linkedBrowser
.closest('.browserSidebarContainer')
.classList.add('deck-selected', 'zen-glance-background');
this.currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('zen-glance-overlay');
this.currentParentTab.linkedBrowser.zenModeActive = true;
this.#currentBrowser.zenModeActive = true;
this.currentParentTab.linkedBrowser.docShellIsActive = true;
this.#currentBrowser.docShellIsActive = true;
this.#currentBrowser.setAttribute("zen-glance-selected", true);
this.#currentBrowser.setAttribute('zen-glance-selected', true);
this.currentParentTab._visuallySelected = true;
this.overlay.classList.add("deck-selected");
this.overlay.classList.add('deck-selected');
this._duringOpening = false;
}
quickCloseGlance({ closeCurrentTab = true, closeParentTab = true, justAnimateParent = false } = {}) {
const parentHasBrowser = !!(this.currentParentTab.linkedBrowser);
const parentHasBrowser = !!this.currentParentTab.linkedBrowser;
if (!justAnimateParent) {
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;
}
@ -244,15 +240,15 @@
}
if (closeCurrentTab) {
this.#currentBrowser.docShellIsActive = false;
this.overlay.classList.remove("deck-selected");
this.overlay.classList.remove('deck-selected');
}
if (!this.currentParentTab._visuallySelected && closeParentTab) {
this.currentParentTab._visuallySelected = false;
}
this.#currentBrowser.removeAttribute("zen-glance-selected");
this.#currentBrowser.removeAttribute('zen-glance-selected');
}
if (parentHasBrowser) {
this.currentParentTab.linkedBrowser.closest(".browserSidebarContainer").classList.remove("zen-glance-background");
this.currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('zen-glance-background');
}
}
@ -285,15 +281,15 @@
this.animatingFullOpen = true;
this.currentParentTab._visuallySelected = false;
this.browserWrapper.removeAttribute("has-finished-animation");
this.browserWrapper.setAttribute("animate-full", true);
this.#currentTab.removeAttribute("zen-glance-tab");
this.browserWrapper.removeAttribute('has-finished-animation');
this.browserWrapper.setAttribute('animate-full', true);
this.#currentTab.removeAttribute('zen-glance-tab');
gBrowser.selectedTab = this.#currentTab;
this.currentParentTab.linkedBrowser.closest(".browserSidebarContainer").classList.remove("zen-glance-background");
this.currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('zen-glance-background');
setTimeout(() => {
window.requestAnimationFrame(() => {
this.browserWrapper.setAttribute("animate-full-end", true);
this.overlay.classList.remove("zen-glance-overlay");
this.browserWrapper.setAttribute('animate-full-end', true);
this.overlay.classList.remove('zen-glance-overlay');
setTimeout(() => {
this.animatingFullOpen = false;
this.closeGlance({ noAnimation: true });
@ -313,7 +309,7 @@
return;
} else if (activationMethod === 'meta' && !event.metaKey) {
return;
}else if (activationMethod === 'mantain' || typeof activationMethod === 'undefined') {
} else if (activationMethod === 'mantain' || typeof activationMethod === 'undefined') {
return;
}
@ -338,13 +334,13 @@
window.gZenGlanceManager = new ZenGlanceManager();
function registerWindowActors() {
if (Services.prefs.getBoolPref("zen.glance.enabled", true)) {
gZenActorsManager.addJSWindowActor("ZenGlance", {
if (Services.prefs.getBoolPref('zen.glance.enabled', true)) {
gZenActorsManager.addJSWindowActor('ZenGlance', {
parent: {
esModuleURI: "chrome://browser/content/zen-components/actors/ZenGlanceParent.sys.mjs",
esModuleURI: 'chrome://browser/content/zen-components/actors/ZenGlanceParent.sys.mjs',
},
child: {
esModuleURI: "chrome://browser/content/zen-components/actors/ZenGlanceChild.sys.mjs",
esModuleURI: 'chrome://browser/content/zen-components/actors/ZenGlanceChild.sys.mjs',
events: {
DOMContentLoaded: {},
},

View file

@ -18,8 +18,12 @@
ChromeUtils.defineLazyGetter(this, 'panel', () => document.getElementById('PanelUI-zen-gradient-generator'));
ChromeUtils.defineLazyGetter(this, 'toolbox', () => document.getElementById('TabsToolbar'));
ChromeUtils.defineLazyGetter(this, 'customColorInput', () => document.getElementById('PanelUI-zen-gradient-generator-custom-input'));
ChromeUtils.defineLazyGetter(this, 'customColorList', () => document.getElementById('PanelUI-zen-gradient-generator-custom-list'));
ChromeUtils.defineLazyGetter(this, 'customColorInput', () =>
document.getElementById('PanelUI-zen-gradient-generator-custom-input')
);
ChromeUtils.defineLazyGetter(this, 'customColorList', () =>
document.getElementById('PanelUI-zen-gradient-generator-custom-list')
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
@ -27,7 +31,7 @@
'zen.theme.color-prefs.use-workspace-colors',
true,
this.onDarkModeChange.bind(this)
)
);
this.initRotation();
this.initCanvas();
@ -74,7 +78,6 @@
this.image.onload = this.onImageLoad.bind(this);
}
onImageLoad() {
// resize the image to fit the panel
const imageSize = 300 - 20; // 20 is the padding (10px)
@ -145,7 +148,7 @@
x = event.clientX;
y = event.clientY;
}
const degrees = Math.round(Math.atan2(y - centerY, x - centerX) * 180 / Math.PI);
const degrees = Math.round((Math.atan2(y - centerY, x - centerX) * 180) / Math.PI);
this.setRotationInput(degrees);
this.updateCurrentWorkspace();
}
@ -200,17 +203,17 @@
// Check if there's an exact match
for (const pixel of similarPixels) {
const x = (pixel / 4) % this.canvas.width;
const y = Math.floor((pixel / 4) / this.canvas.width);
const y = Math.floor(pixel / 4 / this.canvas.width);
const pixelColor = this.getColorFromPosition(x, y);
if (pixelColor[0] === r && pixelColor[1] === g && pixelColor[2] === b) {
return {x: x / this.canvas.width, y: y / this.canvas.height};
return { x: x / this.canvas.width, y: y / this.canvas.height };
}
}
// If there's no exact match, return the first similar pixel
const pixel = similarPixels[0];
const x = (pixel / 4) % this.canvas.width;
const y = Math.floor((pixel / 4) / this.canvas.width);
return {x: x / this.canvas.width, y: y / this.canvas.height};
const y = Math.floor(pixel / 4 / this.canvas.width);
return { x: x / this.canvas.width, y: y / this.canvas.height };
}
getColorFromPosition(x, y) {
@ -245,7 +248,7 @@
onThemePickerClick(event) {
event.preventDefault();
if (event.button !== 0 || this.dragging ) return;
if (event.button !== 0 || this.dragging) return;
const gradient = this.panel.querySelector('.zen-theme-picker-gradient');
const rect = gradient.getBoundingClientRect();
const padding = 90; // each side
@ -268,7 +271,6 @@
// Only proceed if not clicking on an existing dot
if (!isExistingDot) {
const relativeX = event.clientX - rect.left;
const relativeY = event.clientY - rect.top;
@ -287,11 +289,8 @@
this.updateCurrentWorkspace(true);
}
}
onDotMouseDown(event) {
event.preventDefault();
if (event.button === 2) {
@ -305,11 +304,10 @@
// Store the starting position of the drag
this.dragStartPosition = {
x: event.clientX,
y: event.clientY
y: event.clientY,
};
}
onDotMouseMove(event) {
if (this.dragging) {
event.preventDefault();
@ -324,7 +322,7 @@
const radius = (rect.width - padding) / 2;
let pixelX = event.clientX;
let pixelY = event.clientY;
const distance = Math.sqrt((pixelX - centerX) **2 + (pixelY - centerY) **2);
const distance = Math.sqrt((pixelX - centerX) ** 2 + (pixelY - centerY) ** 2);
if (distance > radius) {
const angle = Math.atan2(pixelY - centerY, pixelX - centerX);
pixelX = centerX + Math.cos(angle) * radius;
@ -436,7 +434,7 @@
// Store the starting position of the drag
this.dragStartPosition = {
x: event.clientX,
y: event.clientY
y: event.clientY,
};
}
@ -465,19 +463,16 @@
this.numberOfDots = this.panel.querySelectorAll('.zen-theme-picker-dot').length;
}
themedColors(colors) {
const isDarkMode = this.isDarkMode;
const factor = isDarkMode ? 0.5 : 1.1;
return colors.map(color => {
return colors.map((color) => {
return {
c: color.isCustom ? color.c : [
Math.min(255, color.c[0] * factor),
Math.min(255, color.c[1] * factor),
Math.min(255, color.c[2] * factor),
],
c: color.isCustom
? color.c
: [Math.min(255, color.c[0] * factor), Math.min(255, color.c[1] * factor), Math.min(255, color.c[2] * factor)],
isCustom: color.isCustom,
}
};
});
}
@ -492,8 +487,8 @@
}
getToolbarModifiedBase() {
return this.isDarkMode ?
'color-mix(in srgb, var(--zen-themed-toolbar-bg) 80%, #fff 20%)'
return this.isDarkMode
? 'color-mix(in srgb, var(--zen-themed-toolbar-bg) 80%, #fff 20%)'
: 'color-mix(in srgb, var(--zen-themed-toolbar-bg) 95%, #000 5%)';
}
@ -508,17 +503,17 @@
getGradient(colors, forToolbar = false) {
const themedColors = this.themedColors(colors);
if (themedColors.length === 0) {
return forToolbar ? "var(--zen-themed-toolbar-bg)" : "var(--zen-themed-toolbar-bg-transparent)";
return forToolbar ? 'var(--zen-themed-toolbar-bg)' : 'var(--zen-themed-toolbar-bg-transparent)';
} else if (themedColors.length === 1) {
return this.getSingleRGBColor(themedColors[0], forToolbar);
}
return `linear-gradient(${this.currentRotation}deg, ${themedColors.map(color => this.getSingleRGBColor(color, forToolbar)).join(', ')})`;
return `linear-gradient(${this.currentRotation}deg, ${themedColors.map((color) => this.getSingleRGBColor(color, forToolbar)).join(', ')})`;
}
static getTheme(colors = [], opacity = 0.5, rotation = 45, texture = 0) {
return {
type: 'gradient',
gradientColors: colors ? colors.filter(color => color) : [], // remove undefined
gradientColors: colors ? colors.filter((color) => color) : [], // remove undefined
opacity,
rotation,
texture,
@ -535,43 +530,70 @@
hex = hex.substring(1);
}
if (hex.length === 3) {
hex = hex.split('').map(char => char + char).join('');
hex = hex
.split('')
.map((char) => char + char)
.join('');
}
return [
parseInt(hex.substring(0, 2), 16),
parseInt(hex.substring(2, 4), 16),
parseInt(hex.substring(4, 6), 16),
];
return [parseInt(hex.substring(0, 2), 16), parseInt(hex.substring(2, 4), 16), parseInt(hex.substring(4, 6), 16)];
}
pSBC=(p,c0,c1,l)=>{
let r,g,b,P,f,t,h,i=parseInt,m=Math.round,a=typeof(c1)=="string";
if(typeof(p)!="number"||p<-1||p>1||typeof(c0)!="string"||(c0[0]!='r'&&c0[0]!='#')||(c1&&!a))return null;
if(!this.pSBCr)this.pSBCr=(d)=>{
let n=d.length,x={};
if(n>9){
[r,g,b,a]=d=d.split(","),n=d.length;
if(n<3||n>4)return null;
x.r=i(r[3]=="a"?r.slice(5):r.slice(4)),x.g=i(g),x.b=i(b),x.a=a?parseFloat(a):-1
}else{
if(n==8||n==6||n<4)return null;
if(n<6)d="#"+d[1]+d[1]+d[2]+d[2]+d[3]+d[3]+(n>4?d[4]+d[4]:"");
d=i(d.slice(1),16);
if(n==9||n==5)x.r=d>>24&255,x.g=d>>16&255,x.b=d>>8&255,x.a=m((d&255)/0.255)/1000;
else x.r=d>>16,x.g=d>>8&255,x.b=d&255,x.a=-1
}return x};
h=c0.length>9,h=a?c1.length>9?true:c1=="c"?!h:false:h,f=this.pSBCr(c0),P=p<0,t=c1&&c1!="c"?this.pSBCr(c1):P?{r:0,g:0,b:0,a:-1}:{r:255,g:255,b:255,a:-1},p=P?p*-1:p,P=1-p;
if(!f||!t)return null;
if(l)r=m(P*f.r+p*t.r),g=m(P*f.g+p*t.g),b=m(P*f.b+p*t.b);
else r=m((P*f.r**2+p*t.r**2)**0.5),g=m((P*f.g**2+p*t.g**2)**0.5),b=m((P*f.b**2+p*t.b**2)**0.5);
a=f.a,t=t.a,f=a>=0||t>=0,a=f?a<0?t:t<0?a:a*P+t*p:0;
if(h)return"rgb"+(f?"a(":"(")+r+","+g+","+b+(f?","+m(a*1000)/1000:"")+")";
else return"#"+(4294967296+r*16777216+g*65536+b*256+(f?m(a*255):0)).toString(16).slice(1,f?undefined:-2)
pSBC = (p, c0, c1, l) => {
let r,
g,
b,
P,
f,
t,
h,
i = parseInt,
m = Math.round,
a = typeof c1 == 'string';
if (typeof p != 'number' || p < -1 || p > 1 || typeof c0 != 'string' || (c0[0] != 'r' && c0[0] != '#') || (c1 && !a))
return null;
if (!this.pSBCr)
this.pSBCr = (d) => {
let n = d.length,
x = {};
if (n > 9) {
([r, g, b, a] = d = d.split(',')), (n = d.length);
if (n < 3 || n > 4) return null;
(x.r = i(r[3] == 'a' ? r.slice(5) : r.slice(4))), (x.g = i(g)), (x.b = i(b)), (x.a = a ? parseFloat(a) : -1);
} else {
if (n == 8 || n == 6 || n < 4) return null;
if (n < 6) d = '#' + d[1] + d[1] + d[2] + d[2] + d[3] + d[3] + (n > 4 ? d[4] + d[4] : '');
d = i(d.slice(1), 16);
if (n == 9 || n == 5)
(x.r = (d >> 24) & 255), (x.g = (d >> 16) & 255), (x.b = (d >> 8) & 255), (x.a = m((d & 255) / 0.255) / 1000);
else (x.r = d >> 16), (x.g = (d >> 8) & 255), (x.b = d & 255), (x.a = -1);
}
return x;
};
(h = c0.length > 9),
(h = a ? (c1.length > 9 ? true : c1 == 'c' ? !h : false) : h),
(f = this.pSBCr(c0)),
(P = p < 0),
(t = c1 && c1 != 'c' ? this.pSBCr(c1) : P ? { r: 0, g: 0, b: 0, a: -1 } : { r: 255, g: 255, b: 255, a: -1 }),
(p = P ? p * -1 : p),
(P = 1 - p);
if (!f || !t) return null;
if (l) (r = m(P * f.r + p * t.r)), (g = m(P * f.g + p * t.g)), (b = m(P * f.b + p * t.b));
else
(r = m((P * f.r ** 2 + p * t.r ** 2) ** 0.5)),
(g = m((P * f.g ** 2 + p * t.g ** 2) ** 0.5)),
(b = m((P * f.b ** 2 + p * t.b ** 2) ** 0.5));
(a = f.a), (t = t.a), (f = a >= 0 || t >= 0), (a = f ? (a < 0 ? t : t < 0 ? a : a * P + t * p) : 0);
if (h) return 'rgb' + (f ? 'a(' : '(') + r + ',' + g + ',' + b + (f ? ',' + m(a * 1000) / 1000 : '') + ')';
else
return (
'#' +
(4294967296 + r * 16777216 + g * 65536 + b * 256 + (f ? m(a * 255) : 0)).toString(16).slice(1, f ? undefined : -2)
);
};
getMostDominantColor(allColors) {
const colors = this.themedColors(allColors);
const themedColors = colors.filter(color => !color.isCustom);
const themedColors = colors.filter((color) => !color.isCustom);
if (themedColors.length === 0 || !this.allowWorkspaceColors) {
return null;
}
@ -579,7 +601,9 @@
let dominantColor = themedColors[0].c;
let dominantColorCount = 0;
for (const color of themedColors) {
const count = themedColors.filter(c => c.c[0] === color.c[0] && c.c[1] === color.c[1] && c.c[2] === color.c[2]).length;
const count = themedColors.filter(
(c) => c.c[0] === color.c[0] && c.c[1] === color.c[1] && c.c[2] === color.c[2]
).length;
if (count > dominantColorCount) {
dominantColorCount = count;
dominantColor = color.c;
@ -587,12 +611,12 @@
}
const result = this.pSBC(
this.isDarkMode ? 0.2 : -0.5,
`rgb(${dominantColor[0]}, ${dominantColor[1]}, ${dominantColor[2]})`);
`rgb(${dominantColor[0]}, ${dominantColor[1]}, ${dominantColor[2]})`
);
return result?.match(/\d+/g).map(Number);
}
async onWorkspaceChange(workspace, skipUpdate = false, theme = null) {
const uuid = workspace.uuid;
// Use theme from workspace object or passed theme
let workspaceTheme = theme || workspace.theme;
@ -616,12 +640,12 @@
}
}
const appWrapper = browser.document.getElementById('browser');
if (!skipUpdate && !this._animatingBackground) {
this._animatingBackground = true;
appWrapper.removeAttribute('animating');
browser.document.documentElement.style.setProperty('--zen-main-browser-background-old',
browser.document.documentElement.style.setProperty(
'--zen-main-browser-background-old',
browser.document.documentElement.style.getPropertyValue('--zen-main-browser-background')
);
browser.window.requestAnimationFrame(() => {
@ -656,8 +680,10 @@
browser.gZenThemePicker.numberOfDots = workspaceTheme.gradientColors.length;
browser.document.getElementById('PanelUI-zen-gradient-generator-opacity').value = browser.gZenThemePicker.currentOpacity;
browser.document.getElementById('PanelUI-zen-gradient-generator-texture').value = browser.gZenThemePicker.currentTexture;
browser.document.getElementById('PanelUI-zen-gradient-generator-opacity').value =
browser.gZenThemePicker.currentOpacity;
browser.document.getElementById('PanelUI-zen-gradient-generator-texture').value =
browser.gZenThemePicker.currentTexture;
browser.gZenThemePicker.setRotationInput(browser.gZenThemePicker.currentRotation);
const gradient = browser.gZenThemePicker.getGradient(workspaceTheme.gradientColors);
@ -675,7 +701,10 @@
const dominantColor = this.getMostDominantColor(workspaceTheme.gradientColors);
if (dominantColor) {
browser.document.documentElement.style.setProperty('--zen-primary-color', `rgb(${dominantColor[0]}, ${dominantColor[1]}, ${dominantColor[2]})`);
browser.document.documentElement.style.setProperty(
'--zen-primary-color',
`rgb(${dominantColor[0]}, ${dominantColor[1]}, ${dominantColor[2]})`
);
}
if (!skipUpdate) {
@ -726,24 +755,23 @@
}
async updateCurrentWorkspace(skipSave = true) {
this.updated = skipSave;
const dots = this.panel.querySelectorAll('.zen-theme-picker-dot');
const colors = Array.from(dots).map(dot => {
const colors = Array.from(dots).map((dot) => {
const color = dot.style.getPropertyValue('--zen-theme-picker-dot-color');
if (color === 'undefined') {
return;
}
const isCustom = dot.classList.contains('custom');
return {c: isCustom ? color : color.match(/\d+/g).map(Number), isCustom};
return { c: isCustom ? color : color.match(/\d+/g).map(Number), isCustom };
});
const gradient = ZenThemePicker.getTheme(colors, this.currentOpacity, this.currentRotation, this.currentTexture);
let currentWorkspace = await ZenWorkspaces.getActiveWorkspace();
if(!skipSave) {
if (!skipSave) {
await ZenWorkspacesStorage.saveWorkspaceTheme(currentWorkspace.uuid, gradient);
await ZenWorkspaces._propagateWorkspaceData();
ConfirmationHint.show(document.getElementById("PanelUI-menu-button"), "zen-panel-ui-gradient-generator-saved-message");
ConfirmationHint.show(document.getElementById('PanelUI-menu-button'), 'zen-panel-ui-gradient-generator-saved-message');
currentWorkspace = await ZenWorkspaces.getActiveWorkspace();
}
@ -751,10 +779,9 @@
}
async handlePanelClose() {
if(this.updated) {
if (this.updated) {
await this.updateCurrentWorkspace(false);
}
}
}

View file

@ -103,7 +103,9 @@ const defaultKeyboardGroups = {
'zen-bidi-switch-direction-shortcut',
'zen-screenshot-shortcut',
],
devTools: [/*Filled automatically*/],
devTools: [
/*Filled automatically*/
],
};
const fixedL10nIds = {
@ -215,9 +217,9 @@ 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)
// 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 || 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))
);
}
@ -362,7 +364,8 @@ class KeyShortcut {
key.getAttribute('id'),
key.getAttribute('key'),
key.getAttribute('keycode'),
group ?? KeyShortcut.getGroupFromL10nId(KeyShortcut.sanitizeL10nId(key.getAttribute('data-l10n-id')), key.getAttribute('id')),
group ??
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'),
@ -737,9 +740,14 @@ class ZenKeyboardShortcutsLoader {
}
// Make sure to stay in sync with https://searchfox.org/mozilla-central/source/devtools/startup/DevToolsStartup.sys.mjs#879
static IGNORED_DEVTOOLS_SHORTCUTS = ['key_toggleToolboxF12', 'profilerStartStop',
'profilerStartStopAlternate', 'profilerCapture', 'profilerCaptureAlternate',
'javascriptTracingToggle'];
static IGNORED_DEVTOOLS_SHORTCUTS = [
'key_toggleToolboxF12',
'profilerStartStop',
'profilerStartStopAlternate',
'profilerCapture',
'profilerCaptureAlternate',
'javascriptTracingToggle',
];
static zenGetDefaultDevToolsShortcuts() {
let keySet = document.getElementById(ZEN_DEVTOOLS_KEYSET_ID);
@ -925,7 +933,7 @@ var gZenKeyboardShortcutsManager = {
// Create the main keyset before calling the async init function,
// This is because other browser-sets needs this element and the JS event
// handled wont wait for the async function to finish.
void(this.getZenKeyset());
void this.getZenKeyset();
this._hasCleared = Services.prefs.getBoolPref('zen.keyboard.shortcuts.disable-mainkeyset-clear', false);
window.addEventListener('zen-devtools-keyset-added', this._hasAddedDevtoolShortcuts.bind(this));
@ -962,10 +970,10 @@ var gZenKeyboardShortcutsManager = {
} catch (e) {
console.error('Zen CKS: Error parsing saved shortcuts. Resetting to defaults...', e);
gNotificationBox.appendNotification(
"zen-shortcuts-corrupted",
'zen-shortcuts-corrupted',
{
label: { "l10n-id": "zen-shortcuts-corrupted" },
image: "chrome://browser/skin/notification-icons/persistent-storage-blocked.svg",
label: { 'l10n-id': 'zen-shortcuts-corrupted' },
image: 'chrome://browser/skin/notification-icons/persistent-storage-blocked.svg',
priority: gNotificationBox.PRIORITY_WARNING_HIGH,
},
[]
@ -1179,8 +1187,12 @@ var gZenKeyboardShortcutsManager = {
},
};
document.addEventListener("MozBeforeInitialXULLayout", () => {
document.addEventListener(
'MozBeforeInitialXULLayout',
() => {
if (Services.prefs.getBoolPref('zen.keyboard.shortcuts.enabled', false)) {
gZenKeyboardShortcutsManager.beforeInit();
}
}, { once: true });
},
{ once: true }
);

View file

@ -7,9 +7,19 @@
#listeners = [];
constructor() {
XPCOMUtils.defineLazyPreferenceGetter(lazy, 'zenPinnedTabRestorePinnedTabsToPinnedUrl', 'zen.pinned-tab-manager.restore-pinned-tabs-to-pinned-url', false);
XPCOMUtils.defineLazyPreferenceGetter(lazy, 'zenPinnedTabCloseShortcutBehavior', 'zen.pinned-tab-manager.close-shortcut-behavior', 'switch');
ChromeUtils.defineESModuleGetters(lazy, {E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs"});
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
'zenPinnedTabRestorePinnedTabsToPinnedUrl',
'zen.pinned-tab-manager.restore-pinned-tabs-to-pinned-url',
false
);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
'zenPinnedTabCloseShortcutBehavior',
'zen.pinned-tab-manager.close-shortcut-behavior',
'switch'
);
ChromeUtils.defineESModuleGetters(lazy, { E10SUtils: 'resource://gre/modules/E10SUtils.sys.mjs' });
this.#listenPinnedTabEvents();
}
@ -37,7 +47,6 @@
}
class ZenPinnedTabManager extends ZenDOMOperatedFeature {
init() {
if (!this.enabled) {
return;
@ -56,7 +65,7 @@
return;
}
await this._refreshPinnedTabs(newWorkspace,{ init: onInit });
await this._refreshPinnedTabs(newWorkspace, { init: onInit });
}
get enabled() {
@ -70,9 +79,9 @@
return this._enabled;
}
async _refreshPinnedTabs(currentWorkspace,{ init = false } = {}) {
async _refreshPinnedTabs(currentWorkspace, { init = false } = {}) {
await this._initializePinsCache();
await this._initializePinnedTabs(init,currentWorkspace);
await this._initializePinnedTabs(init, currentWorkspace);
}
async _initializePinsCache() {
@ -81,30 +90,31 @@
const pins = await ZenPinnedTabsStorage.getPins();
// Enhance pins with favicons
const enhancedPins = await Promise.all(pins.map(async pin => {
const enhancedPins = await Promise.all(
pins.map(async (pin) => {
try {
const image = await this.getFaviconAsBase64(Services.io.newURI(pin.url).spec);
return {
...pin,
iconUrl: image || null
iconUrl: image || null,
};
} catch(ex) {
} catch (ex) {
// If favicon fetch fails, continue without icon
return {
...pin,
iconUrl: null
iconUrl: null,
};
}
}));
})
);
this._pinsCache = enhancedPins.sort((a, b) => {
if (!a.workspaceUuid && b.workspaceUuid) return -1;
if (a.workspaceUuid && !b.workspaceUuid) return 1;
return 0;
});
} catch (ex) {
console.error("Failed to initialize pins cache:", ex);
console.error('Failed to initialize pins cache:', ex);
this._pinsCache = [];
}
@ -121,11 +131,11 @@
const activeTab = gBrowser.selectedTab;
const pinnedTabsByUUID = new Map();
const pinsToCreate = new Set(pins.map(p => p.uuid));
const pinsToCreate = new Set(pins.map((p) => p.uuid));
// First pass: identify existing tabs and remove those without pins
for (let tab of gBrowser.tabs) {
const pinId = tab.getAttribute("zen-pin-id");
const pinId = tab.getAttribute('zen-pin-id');
if (!pinId) {
continue;
}
@ -161,7 +171,7 @@
userContextId: pin.containerTabId || 0,
createLazyBrowser: true,
skipLoad: true,
noInitialLabel: false
noInitialLabel: false,
};
// Create and initialize the tab
@ -177,26 +187,28 @@
gBrowser.setIcon(newTab, pin.iconUrl);
}
newTab.setAttribute("zen-pin-id", pin.uuid);
newTab.setAttribute('zen-pin-id', pin.uuid);
if (pin.workspaceUuid) {
newTab.setAttribute("zen-workspace-id", pin.workspaceUuid);
newTab.setAttribute('zen-workspace-id', pin.workspaceUuid);
}
if (pin.isEssential) {
newTab.setAttribute("zen-essential", "true");
newTab.setAttribute('zen-essential', 'true');
}
// Initialize browser state if needed
if (!newTab.linkedBrowser._remoteAutoRemoved) {
let state = {
entries: [{
entries: [
{
url: pin.url,
title: pin.title,
triggeringPrincipal_base64: E10SUtils.SERIALIZED_SYSTEMPRINCIPAL
}],
triggeringPrincipal_base64: E10SUtils.SERIALIZED_SYSTEMPRINCIPAL,
},
],
userContextId: pin.containerTabId || 0,
image: pin.iconUrl
image: pin.iconUrl,
};
SessionStore.setTabState(newTab, state);
@ -204,7 +216,6 @@
gBrowser.pinTab(newTab);
newTab.initialize();
}
@ -219,8 +230,8 @@
_shouldShowPin(pin, currentWorkspace, workspaces) {
const isEssential = pin.isEssential;
const pinWorkspaceUuid = pin.workspaceUuid;
const pinContextId = pin.containerTabId ? pin.containerTabId.toString() : "0";
const workspaceContextId = currentWorkspace.containerTabId?.toString() || "0";
const pinContextId = pin.containerTabId ? pin.containerTabId.toString() : '0';
const workspaceContextId = currentWorkspace.containerTabId?.toString() || '0';
const containerSpecificEssentials = ZenWorkspaces.containerSpecificEssentials;
// Handle essential pins
@ -229,14 +240,16 @@
return true; // Show all essential pins when containerSpecificEssentials is false
}
if (workspaceContextId !== "0") {
if (workspaceContextId !== '0') {
// In workspaces with default container: Show essentials that match the container
return pinContextId === workspaceContextId;
} else {
// In workspaces without a default container: Show essentials that aren't in container-specific workspaces
// or have userContextId="0" or no userContextId
return !pinContextId || pinContextId === "0" || !workspaces.workspaces.some(
workspace => workspace.containerTabId === parseInt(pinContextId, 10)
return (
!pinContextId ||
pinContextId === '0' ||
!workspaces.workspaces.some((workspace) => workspace.containerTabId === parseInt(pinContextId, 10))
);
}
}
@ -255,19 +268,19 @@
if (!this.enabled) return;
const tab = event.target;
switch (action) {
case "TabPinned":
case 'TabPinned':
tab._zenClickEventListener = this._zenClickEventListener;
tab.addEventListener("click", tab._zenClickEventListener);
tab.addEventListener('click', tab._zenClickEventListener);
this._setPinnedAttributes(tab);
break;
case "TabUnpinned":
case 'TabUnpinned':
this._removePinnedAttributes(tab);
if (tab._zenClickEventListener) {
tab.removeEventListener("click", tab._zenClickEventListener);
tab.removeEventListener('click', tab._zenClickEventListener);
delete tab._zenClickEventListener;
}
break;
case "TabMove":
case 'TabMove':
this._onTabMove(tab);
break;
default:
@ -288,26 +301,25 @@
for (let otherTab of gBrowser.tabs) {
if (otherTab.pinned && otherTab._tPos > tab.position) {
const actualPin = this._pinsCache.find(pin => pin.uuid === otherTab.getAttribute("zen-pin-id"));
const actualPin = this._pinsCache.find((pin) => pin.uuid === otherTab.getAttribute('zen-pin-id'));
actualPin.position = otherTab._tPos;
await ZenPinnedTabsStorage.savePin(actualPin, false);
}
}
const actualPin = this._pinsCache.find(pin => pin.uuid === tab.getAttribute("zen-pin-id"));
const actualPin = this._pinsCache.find((pin) => pin.uuid === tab.getAttribute('zen-pin-id'));
actualPin.position = tab.position;
await ZenPinnedTabsStorage.savePin(actualPin);
}
_onTabClick(e) {
const tab = e.target?.closest("tab");
const tab = e.target?.closest('tab');
if (e.button === 1 && tab) {
this._onCloseTabShortcut(e, tab);
}
}
async resetPinnedTab(tab) {
if (!tab) {
tab = TabContextMenu.contextTab;
}
@ -321,23 +333,23 @@
async replacePinnedUrlWithCurrent() {
const tab = TabContextMenu.contextTab;
if (!tab || !tab.pinned || !tab.getAttribute("zen-pin-id")) {
if (!tab || !tab.pinned || !tab.getAttribute('zen-pin-id')) {
return;
}
const browser = tab.linkedBrowser;
const pin = this._pinsCache.find(pin => pin.uuid === tab.getAttribute("zen-pin-id"));
const pin = this._pinsCache.find((pin) => pin.uuid === tab.getAttribute('zen-pin-id'));
if (!pin) {
return;
}
const userContextId = tab.getAttribute("usercontextid");
const userContextId = tab.getAttribute('usercontextid');
pin.title = tab.label || browser.contentTitle;
pin.url = browser.currentURI.spec;
pin.workspaceUuid = tab.getAttribute("zen-workspace-id");
pin.workspaceUuid = tab.getAttribute('zen-workspace-id');
pin.userContextId = userContextId ? parseInt(userContextId, 10) : 0;
await ZenPinnedTabsStorage.savePin(pin);
@ -346,20 +358,19 @@
}
async _setPinnedAttributes(tab) {
if (tab.hasAttribute("zen-pin-id")) {
if (tab.hasAttribute('zen-pin-id')) {
return;
}
const browser = tab.linkedBrowser;
const uuid = gZenUIManager.generateUuidv4();
const userContextId = tab.getAttribute("usercontextid");
const userContextId = tab.getAttribute('usercontextid');
let entry = null;
if(tab.getAttribute("zen-pinned-entry")) {
entry = JSON.parse(tab.getAttribute("zen-pinned-entry"));
if (tab.getAttribute('zen-pinned-entry')) {
entry = JSON.parse(tab.getAttribute('zen-pinned-entry'));
}
await ZenPinnedTabsStorage.savePin({
@ -367,15 +378,15 @@
title: entry?.title || tab.label || browser.contentTitle,
url: entry?.url || browser.currentURI.spec,
containerTabId: userContextId ? parseInt(userContextId, 10) : 0,
workspaceUuid: tab.getAttribute("zen-workspace-id"),
isEssential: tab.getAttribute("zen-essential") === "true"
workspaceUuid: tab.getAttribute('zen-workspace-id'),
isEssential: tab.getAttribute('zen-essential') === 'true',
});
tab.setAttribute("zen-pin-id", uuid);
tab.setAttribute('zen-pin-id', uuid);
// This is used while migrating old pins to new system - we don't want to refresh when migrating
if (tab.getAttribute("zen-pinned-entry")) {
tab.removeAttribute("zen-pinned-entry");
if (tab.getAttribute('zen-pinned-entry')) {
tab.removeAttribute('zen-pinned-entry');
return;
}
const currentWorkspace = await ZenWorkspaces.getActiveWorkspace();
@ -383,19 +394,19 @@
}
async _removePinnedAttributes(tab, isClosing = false) {
if(!tab.getAttribute("zen-pin-id") || this._temporarilyUnpiningEssential) {
if (!tab.getAttribute('zen-pin-id') || this._temporarilyUnpiningEssential) {
this._temporarilyUnpiningEssential = false;
return;
}
await ZenPinnedTabsStorage.removePin(tab.getAttribute("zen-pin-id"));
await ZenPinnedTabsStorage.removePin(tab.getAttribute('zen-pin-id'));
if(!isClosing) {
tab.removeAttribute("zen-pin-id");
if (!isClosing) {
tab.removeAttribute('zen-pin-id');
if (!tab.hasAttribute("zen-workspace-id") && ZenWorkspaces.workspaceEnabled) {
if (!tab.hasAttribute('zen-workspace-id') && ZenWorkspaces.workspaceEnabled) {
const workspace = await ZenWorkspaces.getActiveWorkspace();
tab.setAttribute("zen-workspace-id", workspace.uuid);
tab.setAttribute('zen-workspace-id', workspace.uuid);
}
}
const currentWorkspace = await ZenWorkspaces.getActiveWorkspace();
@ -411,9 +422,7 @@
}
_onCloseTabShortcut(event, selectedTab = gBrowser.selectedTab) {
if (
!selectedTab?.pinned
) {
if (!selectedTab?.pinned) {
return;
}
@ -448,13 +457,13 @@
}
_handleTabSwitch(selectedTab) {
if(selectedTab !== gBrowser.selectedTab) {
if (selectedTab !== gBrowser.selectedTab) {
return;
}
const findNextTab = (direction) =>
gBrowser.tabContainer.findNextTab(selectedTab, {
direction,
filter: tab => !tab.hidden && !tab.pinned,
filter: (tab) => !tab.hidden && !tab.pinned,
});
let nextTab = findNextTab(1) || findNextTab(-1);
@ -471,12 +480,12 @@
}
async _resetTabToStoredState(tab) {
const id = tab.getAttribute("zen-pin-id");
const id = tab.getAttribute('zen-pin-id');
if (!id) {
return;
}
const pin = this._pinsCache.find(pin => pin.uuid === id);
const pin = this._pinsCache.find((pin) => pin.uuid === id);
if (!pin) {
return;
}
@ -484,11 +493,13 @@
const tabState = SessionStore.getTabState(tab);
const state = JSON.parse(tabState);
state.entries = [{
state.entries = [
{
url: pin.url,
title: pin.title,
triggeringPrincipal_base64: lazy.E10SUtils.SERIALIZED_SYSTEMPRINCIPAL
}];
triggeringPrincipal_base64: lazy.E10SUtils.SERIALIZED_SYSTEMPRINCIPAL,
},
];
state.image = pin.iconUrl || null;
state.index = 0;
@ -508,7 +519,7 @@
// Convert to base64
const base64String = btoa(
Array.from(array)
.map(b => String.fromCharCode(b))
.map((b) => String.fromCharCode(b))
.join('')
);
@ -524,9 +535,9 @@
const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
for (let i = 0; i < tabs.length; i++) {
const tab = tabs[i];
tab.setAttribute("zen-essential", "true");
if(tab.hasAttribute("zen-workspace-id")) {
tab.removeAttribute("zen-workspace-id");
tab.setAttribute('zen-essential', 'true');
if (tab.hasAttribute('zen-workspace-id')) {
tab.removeAttribute('zen-workspace-id');
}
if (tab.pinned) {
this._temporarilyUnpiningEssential = true;
@ -540,9 +551,9 @@
const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
for (let i = 0; i < tabs.length; i++) {
const tab = tabs[i];
tab.removeAttribute("zen-essential");
if(ZenWorkspaces.workspaceEnabled && ZenWorkspaces.getActiveWorkspaceFromCache.uuid) {
tab.setAttribute("zen-workspace-id", ZenWorkspaces.getActiveWorkspaceFromCache.uuid);
tab.removeAttribute('zen-essential');
if (ZenWorkspaces.workspaceEnabled && ZenWorkspaces.getActiveWorkspaceFromCache.uuid) {
tab.setAttribute('zen-workspace-id', ZenWorkspaces.getActiveWorkspaceFromCache.uuid);
}
gBrowser.unpinTab(tab);
}
@ -590,13 +601,15 @@
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-replace-pinned-url-with-current").hidden = !isVisible;
document.getElementById("context_zen-add-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_unpinSelectedTabs").hidden = document.getElementById("context_unpinSelectedTabs").hidden || contextTab.getAttribute("zen-essential");
document.getElementById("context_zen-pinned-tab-separator").hidden = !isVisible;
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');
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_unpinSelectedTabs').hidden =
document.getElementById('context_unpinSelectedTabs').hidden || contextTab.getAttribute('zen-essential');
document.getElementById('context_zen-pinned-tab-separator').hidden = !isVisible;
}
}

View file

@ -24,7 +24,6 @@ var ZenPinnedTabsStorage = {
)
`);
// Create indices
await db.execute(`
CREATE INDEX IF NOT EXISTS idx_zen_pins_uuid ON zen_pins(uuid)
@ -75,17 +74,21 @@ var ZenPinnedTabsStorage = {
newPosition = pin.position;
} else {
// Get the maximum position within the same parent group (or null for root level)
const maxPositionResult = await db.execute(`
const maxPositionResult = await db.execute(
`
SELECT MAX("position") as max_position
FROM zen_pins
WHERE COALESCE(parent_uuid, '') = COALESCE(:parent_uuid, '')
`, { parent_uuid: pin.parentUuid || null });
`,
{ parent_uuid: pin.parentUuid || null }
);
const maxPosition = maxPositionResult[0].getResultByName('max_position') || 0;
newPosition = maxPosition + 1000;
}
// Insert or replace the pin
await db.executeCached(`
await db.executeCached(
`
INSERT OR REPLACE INTO zen_pins (
uuid, title, url, container_id, workspace_uuid, position,
is_essential, is_group, parent_uuid, created_at, updated_at
@ -95,7 +98,8 @@ var ZenPinnedTabsStorage = {
COALESCE((SELECT created_at FROM zen_pins WHERE uuid = :uuid), :now),
:now
)
`, {
`,
{
uuid: pin.uuid,
title: pin.title,
url: pin.isGroup ? null : pin.url,
@ -105,16 +109,20 @@ var ZenPinnedTabsStorage = {
is_essential: pin.isEssential || false,
is_group: pin.isGroup || false,
parent_uuid: pin.parentUuid || null,
now
});
now,
}
);
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`, {
`,
{
uuid: pin.uuid,
timestamp: Math.floor(now / 1000)
});
timestamp: Math.floor(now / 1000),
}
);
changedUUIDs.add(pin.uuid);
await this.updateLastChangeTimestamp(db);
@ -122,7 +130,7 @@ var ZenPinnedTabsStorage = {
});
if (notifyObservers) {
this._notifyPinsChanged("zen-pin-updated", Array.from(changedUUIDs));
this._notifyPinsChanged('zen-pin-updated', Array.from(changedUUIDs));
}
},
@ -141,17 +149,20 @@ var ZenPinnedTabsStorage = {
position: row.getResultByName('position'),
isEssential: Boolean(row.getResultByName('is_essential')),
isGroup: Boolean(row.getResultByName('is_group')),
parentUuid: row.getResultByName('parent_uuid')
parentUuid: row.getResultByName('parent_uuid'),
}));
},
async getGroupChildren(groupUuid) {
const db = await PlacesUtils.promiseDBConnection();
const rows = await db.executeCached(`
const rows = await db.executeCached(
`
SELECT * FROM zen_pins
WHERE parent_uuid = :groupUuid
ORDER BY position ASC
`, { groupUuid });
`,
{ groupUuid }
);
return rows.map((row) => ({
uuid: row.getResultByName('uuid'),
@ -162,7 +173,7 @@ var ZenPinnedTabsStorage = {
position: row.getResultByName('position'),
isEssential: Boolean(row.getResultByName('is_essential')),
isGroup: Boolean(row.getResultByName('is_group')),
parentUuid: row.getResultByName('parent_uuid')
parentUuid: row.getResultByName('parent_uuid'),
}));
},
@ -172,10 +183,7 @@ 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) {
@ -183,27 +191,24 @@ var ZenPinnedTabsStorage = {
}
// Delete all children in a single statement
await db.execute(
`DELETE FROM zen_pins WHERE parent_uuid = :uuid`,
{ uuid }
);
await db.execute(`DELETE FROM zen_pins WHERE parent_uuid = :uuid`, { uuid });
// Delete the pin/group itself
await db.execute(
`DELETE FROM zen_pins WHERE uuid = :uuid`,
{ uuid }
);
await db.execute(`DELETE FROM zen_pins WHERE uuid = :uuid`, { uuid });
// Record the changes
const now = Math.floor(Date.now() / 1000);
for (const changedUuid of changedUUIDs) {
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`, {
`,
{
uuid: changedUuid,
timestamp: now
});
timestamp: now,
}
);
}
await this.updateLastChangeTimestamp(db);
@ -211,7 +216,7 @@ var ZenPinnedTabsStorage = {
});
if (notifyObservers) {
this._notifyPinsChanged("zen-pin-removed", changedUUIDs);
this._notifyPinsChanged('zen-pin-removed', changedUUIDs);
}
},
@ -226,13 +231,16 @@ var ZenPinnedTabsStorage = {
async markChanged(uuid) {
await PlacesUtils.withConnectionWrapper('ZenPinnedTabsStorage.markChanged', async (db) => {
const now = Date.now();
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`, {
`,
{
uuid,
timestamp: Math.floor(now / 1000)
});
timestamp: Math.floor(now / 1000),
}
);
});
},
@ -268,21 +276,27 @@ var ZenPinnedTabsStorage = {
for (let i = 0; i < pins.length; i++) {
const newPosition = (i + 1) * 1000; // Use large increments
await db.execute(`
await db.execute(
`
UPDATE zen_pins
SET position = :newPosition
WHERE uuid = :uuid
`, { newPosition, uuid: pins[i].getResultByName('uuid') });
`,
{ newPosition, uuid: pins[i].getResultByName('uuid') }
);
changedUUIDs.add(pins[i].getResultByName('uuid'));
}
},
async updateLastChangeTimestamp(db) {
const now = Date.now();
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO moz_meta (key, value)
VALUES ('zen_pins_last_change', :now)
`, { now });
`,
{ now }
);
},
async getLastChangeTimestamp() {
@ -304,29 +318,35 @@ var ZenPinnedTabsStorage = {
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);
// Record the change
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO zen_pins_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`, {
`,
{
uuid: pin.uuid,
timestamp: Math.floor(now / 1000)
});
timestamp: Math.floor(now / 1000),
}
);
}
await this.updateLastChangeTimestamp(db);
});
});
this._notifyPinsChanged("zen-pin-updated", Array.from(changedUUIDs));
this._notifyPinsChanged('zen-pin-updated', Array.from(changedUUIDs));
},
async __dropTables() {
@ -334,7 +354,7 @@ var ZenPinnedTabsStorage = {
await db.execute(`DROP TABLE IF EXISTS zen_pins`);
await db.execute(`DROP TABLE IF EXISTS zen_pins_changes`);
});
}
},
};
ZenPinnedTabsStorage.init();

View file

@ -1,6 +1,5 @@
{
const ZEN_RICE_API = Services.prefs.getStringPref("zen.rice.api.url", '');
const ZEN_RICE_API = Services.prefs.getStringPref('zen.rice.api.url', '');
class ZenRiceCollector {
constructor() {}
@ -14,9 +13,13 @@
}
async gatherAll({
userUserChrome = true, userContent = true,
enabledMods = true, preferences = true,
modPrefs = true, workspaceThemes = true } = {}) {
userUserChrome = true,
userContent = true,
enabledMods = true,
preferences = true,
modPrefs = true,
workspaceThemes = true,
} = {}) {
this.clear();
// Get the mods first, as they may be needed for the preferences
if (enabledMods) {
@ -39,7 +42,7 @@
const path = PathUtils.join(this.profileDir, 'chrome', 'userChrome.css');
this._userChrome = await IOUtils.readUTF8(path);
} catch (e) {
console.warn("[ZenRiceCollector]: Error reading userChrome.css: ", e);
console.warn('[ZenRiceCollector]: Error reading userChrome.css: ', e);
return null;
}
}
@ -49,7 +52,7 @@
const path = PathUtils.join(this.profileDir, 'chrome', 'userContent.css');
this._userContent = await IOUtils.readUTF8(path);
} catch (e) {
console.warn("[ZenRiceCollector]: Error reading userContent.css: ", e);
console.warn('[ZenRiceCollector]: Error reading userContent.css: ', e);
return null;
}
}
@ -85,18 +88,12 @@
'zen.tabs.vertical.right-side',
'zen.view.experimental-no-window-controls',
'zen.view.hide-window-controls',
...(gZenOperatingSystemCommonUtils.currentOperatingSystem === "windows"
? ['widget.windows.mica']
: []
),
...(gZenOperatingSystemCommonUtils.currentOperatingSystem === "macos"
...(gZenOperatingSystemCommonUtils.currentOperatingSystem === 'windows' ? ['widget.windows.mica'] : []),
...(gZenOperatingSystemCommonUtils.currentOperatingSystem === 'macos'
? ['widget.macos.titlebar-blend-mode.behind-window']
: []
),
];
const stringPrefsToCollect = [
'browser.uiCustomization.state'
: []),
];
const stringPrefsToCollect = ['browser.uiCustomization.state'];
for (const pref of boolPrefsToCollect) {
this._preferences[pref] = Services.prefs.getBoolPref(pref);
}
@ -107,7 +104,7 @@
async gatherWorkspaceThemes() {
const workspaces = (await ZenWorkspaces._workspaces()).workspaces;
this._workspaceThemes = workspaces.map(w => w.theme);
this._workspaceThemes = workspaces.map((w) => w.theme);
}
async packRice(...args) {
@ -115,7 +112,7 @@
const rice = {
userChrome: this._userChrome,
userContent: this._userContent,
enabledMods: this._enabledMods?.map(t => t.id),
enabledMods: this._enabledMods?.map((t) => t.id),
preferences: this._preferences,
workspaceThemes: this._workspaceThemes,
};
@ -128,12 +125,11 @@
this._collector = new ZenRiceCollector();
}
init() {
}
init() {}
get conffettiWrapper() {
if (!this.confetti) {
Services.scriptloader.loadSubScript("chrome://browser/content/zen-vendor/tsparticles.confetti.bundle.min.js", this);
Services.scriptloader.loadSubScript('chrome://browser/content/zen-vendor/tsparticles.confetti.bundle.min.js', this);
}
return this.confetti;
}
@ -204,57 +200,54 @@
</vbox>
</vbox>
`);
document.getElementById("zen-main-app-wrapper").appendChild(this._shareDialog);
this._shareDialog = document.getElementById("zen-rice-share-dialog-overlay");
document.getElementById('zen-main-app-wrapper').appendChild(this._shareDialog);
this._shareDialog = document.getElementById('zen-rice-share-dialog-overlay');
return this._shareDialog;
}
get hasAcceptedNotice() {
return Services.prefs.getBoolPref("zen.rice.share.notice.accepted", false);
return Services.prefs.getBoolPref('zen.rice.share.notice.accepted', false);
}
set hasAcceptedNotice(value) {
Services.prefs.setBoolPref("zen.rice.share.notice.accepted", value);
Services.prefs.setBoolPref('zen.rice.share.notice.accepted', value);
}
openLink(event) {
event.stopPropagation();
this.cancel();
gZenUIManager.openAndChangeToTab("https://docs.zen-browser.app/guides/");
gZenUIManager.openAndChangeToTab('https://docs.zen-browser.app/guides/');
}
acceptNotice() {
this.hasAcceptedNotice = true;
const notice = document.getElementById("zen-rice-share-dialog-notice");
notice.setAttribute("hidden", "true");
const notice = document.getElementById('zen-rice-share-dialog-notice');
notice.setAttribute('hidden', 'true');
this.openShareDialog();
}
toggleOptions(event) {
if (event.originalTarget.closest(".options-header")) {
const options = document.getElementById("zen-rice-share-options");
options.setAttribute("zen-collapsed", options.getAttribute("zen-collapsed") === "true" ? "false" : "true");
if (event.originalTarget.closest('.options-header')) {
const options = document.getElementById('zen-rice-share-options');
options.setAttribute('zen-collapsed', options.getAttribute('zen-collapsed') === 'true' ? 'false' : 'true');
}
this.validateShareDialog();
}
openShareDialog() {
window.docShell.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIAppWindow)
.rollupAllPopups();
window.docShell.treeOwner.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIAppWindow).rollupAllPopups();
const dialog = this.shareDialog;
dialog.removeAttribute("hidden");
dialog.removeAttribute('hidden');
if (!this.hasAcceptedNotice) {
const notice = document.getElementById("zen-rice-share-dialog-notice");
notice.removeAttribute("hidden");
const notice = document.getElementById('zen-rice-share-dialog-notice');
notice.removeAttribute('hidden');
return;
}
document.getElementById("zen-rice-share-dialog").removeAttribute("hidden");
document.getElementById("zen-rice-share-dialog-notice").setAttribute("hidden", "true");
document.getElementById("zen-rice-share-name").focus();
document.getElementById('zen-rice-share-dialog').removeAttribute('hidden');
document.getElementById('zen-rice-share-dialog-notice').setAttribute('hidden', 'true');
document.getElementById('zen-rice-share-name').focus();
// Initialize the dialog with the current values
this.validateShareDialog();
@ -262,17 +255,17 @@
resetShareDialog() {
const dialog = this.shareDialog;
dialog.setAttribute("hidden", "true");
document.getElementById("zen-rice-share-dialog").removeAttribute("animate");
document.getElementById("zen-rice-share-name").value = "";
document.getElementById("zen-rice-share-author").value = "";
document.getElementById("zen-rice-share-save").disabled = true;
document.getElementById("zen-rice-share-first-form").removeAttribute("fade-out");
document.getElementById("zen-rice-share-second-form").setAttribute("hidden", "true");
document.getElementById("zen-rice-share-second-form").removeAttribute("fade-out");
document.getElementById("zen-rice-share-error").setAttribute("hidden", "true");
document.getElementById("zen-rice-share-success").setAttribute("hidden", "true");
document.getElementById("zen-rice-share-options").setAttribute("zen-collapsed", "true");
dialog.setAttribute('hidden', 'true');
document.getElementById('zen-rice-share-dialog').removeAttribute('animate');
document.getElementById('zen-rice-share-name').value = '';
document.getElementById('zen-rice-share-author').value = '';
document.getElementById('zen-rice-share-save').disabled = true;
document.getElementById('zen-rice-share-first-form').removeAttribute('fade-out');
document.getElementById('zen-rice-share-second-form').setAttribute('hidden', 'true');
document.getElementById('zen-rice-share-second-form').removeAttribute('fade-out');
document.getElementById('zen-rice-share-error').setAttribute('hidden', 'true');
document.getElementById('zen-rice-share-success').setAttribute('hidden', 'true');
document.getElementById('zen-rice-share-options').setAttribute('zen-collapsed', 'true');
// Remove confetti module from memory
this.confetti = null;
@ -284,12 +277,12 @@
getAllowedRice() {
return {
userChrome: document.getElementById("zen-rice-share-include-userchrome").checked,
userContent: document.getElementById("zen-rice-share-include-usercontent").checked,
mods: document.getElementById("zen-rice-share-include-mods").checked,
modPrefs: document.getElementById("zen-rice-share-include-mod-prefs").checked,
preferences: document.getElementById("zen-rice-share-include-preferences").checked,
workspaceThemes: document.getElementById("zen-rice-share-include-workspace-themes").checked,
userChrome: document.getElementById('zen-rice-share-include-userchrome').checked,
userContent: document.getElementById('zen-rice-share-include-usercontent').checked,
mods: document.getElementById('zen-rice-share-include-mods').checked,
modPrefs: document.getElementById('zen-rice-share-include-mod-prefs').checked,
preferences: document.getElementById('zen-rice-share-include-preferences').checked,
workspaceThemes: document.getElementById('zen-rice-share-include-workspace-themes').checked,
};
}
@ -299,37 +292,41 @@
canShareRice() {
const allowedRice = this.getAllowedRice();
const modsPrefs = document.getElementById("zen-rice-share-include-mod-prefs");
const modsPrefs = document.getElementById('zen-rice-share-include-mod-prefs');
// remove "share mod prefs" if mods are not included
if (!allowedRice.mods) {
allowedRice.modPrefs = false;
modsPrefs.disabled = true;
}
modsPrefs.disabled = !allowedRice.mods;
return Object.values(allowedRice).some(v => v);
return Object.values(allowedRice).some((v) => v);
}
validateShareDialog() {
const saveButton = document.getElementById("zen-rice-share-save");
const authorInput = document.getElementById("zen-rice-share-author");
const input = document.getElementById("zen-rice-share-name");
saveButton.disabled = !this.canShareRice() || input.value.trim().length < 3 || input.value.trim().length > 30
|| authorInput.value.trim().length < 3 || authorInput.value.trim().length > 15;
const saveButton = document.getElementById('zen-rice-share-save');
const authorInput = document.getElementById('zen-rice-share-author');
const input = document.getElementById('zen-rice-share-name');
saveButton.disabled =
!this.canShareRice() ||
input.value.trim().length < 3 ||
input.value.trim().length > 30 ||
authorInput.value.trim().length < 3 ||
authorInput.value.trim().length > 15;
}
async submit() {
const firstForm = document.getElementById("zen-rice-share-first-form");
const secondForm = document.getElementById("zen-rice-share-second-form");
firstForm.setAttribute("fade-out", "true");
secondForm.removeAttribute("hidden");
const firstForm = document.getElementById('zen-rice-share-first-form');
const secondForm = document.getElementById('zen-rice-share-second-form');
firstForm.setAttribute('fade-out', 'true');
secondForm.removeAttribute('hidden');
await this._submit();
}
async _submit() {
const allowedRice = this.getAllowedRice();
const rice = await this._collector.packRice(allowedRice);
const name = document.getElementById("zen-rice-share-name").value;
const author = document.getElementById("zen-rice-share-author").value;
const name = document.getElementById('zen-rice-share-name').value;
const author = document.getElementById('zen-rice-share-author').value;
const response = await this._sendRice({ name, author, rice });
if (response) {
this.showSuccessDialog(response);
@ -338,20 +335,20 @@
async _sendRice({ name, author, rice }) {
const headers = new Headers();
headers.append("X-Zen-Rice-Name", name);
headers.append("X-Zen-Rice-Author", author);
headers.append("User-Agent", this.userAgent);
headers.append("Content-Type", "application/json");
headers.append("Accept", "application/json");
headers.append('X-Zen-Rice-Name', name);
headers.append('X-Zen-Rice-Author', author);
headers.append('User-Agent', this.userAgent);
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
let response;
try {
response = await fetch(`${ZEN_RICE_API}/rices`, {
method: "POST",
method: 'POST',
headers,
body: JSON.stringify(rice),
});
} catch (e) {
this.showErrorMessage("An error occurred while sharing your rice. Please try again later.");
this.showErrorMessage('An error occurred while sharing your rice. Please try again later.');
console.error(e);
return null;
}
@ -362,7 +359,7 @@
async _verifyResponse(response) {
const json = await response.json();
if (!response.ok) {
const message = json.message || "An error occurred while sharing your rice.";
const message = json.message || 'An error occurred while sharing your rice.';
this.showErrorMessage(message);
console.error(json);
return null;
@ -371,20 +368,20 @@
}
showErrorMessage(message) {
const errorBox = document.getElementById("zen-rice-share-error");
errorBox.removeAttribute("hidden");
errorBox.querySelector("label").textContent = message;
const errorBox = document.getElementById('zen-rice-share-error');
errorBox.removeAttribute('hidden');
errorBox.querySelector('label').textContent = message;
}
showSuccessDialog(riceInfo) {
const { slug, token } = riceInfo;
// 'token' is like some sort of password to edit the rice, do NOT expose it
setTimeout(() => {
document.getElementById("zen-rice-share-dialog").setAttribute("animate", "true");
const successBox = document.getElementById("zen-rice-share-success");
document.getElementById("zen-rice-share-second-form").setAttribute("fade-out", "true");
successBox.removeAttribute("hidden");
const link = document.getElementById("zen-rice-share-success-link");
document.getElementById('zen-rice-share-dialog').setAttribute('animate', 'true');
const successBox = document.getElementById('zen-rice-share-success');
document.getElementById('zen-rice-share-second-form').setAttribute('fade-out', 'true');
successBox.removeAttribute('hidden');
const link = document.getElementById('zen-rice-share-success-link');
link.value = `${ZEN_RICE_API}/rices/${slug}`;
this.showConffetti();
}, 2000);
@ -422,7 +419,7 @@
}
openRicePage({ name, id, author }) {
console.log("Opening rice page: ", name, id, author);
console.log('Opening rice page: ', name, id, author);
gBrowser.removeTab(gBrowser.selectedTab);
}
}

View file

@ -38,10 +38,10 @@ var ZenThemesCommon = {
await IOUtils.writeJSON(this.themesDataFile, {});
this.themes = {};
gNotificationBox.appendNotification(
"zen-themes-corrupted",
'zen-themes-corrupted',
{
label: { "l10n-id": "zen-themes-corrupted" },
image: "chrome://browser/skin/notification-icons/persistent-storage-blocked.svg",
label: { 'l10n-id': 'zen-themes-corrupted' },
image: 'chrome://browser/skin/notification-icons/persistent-storage-blocked.svg',
priority: gNotificationBox.PRIORITY_WARNING_HIGH,
},
[]

View file

@ -303,15 +303,15 @@ var gZenThemesImporter = new (class {
}
})();
gZenActorsManager.addJSWindowActor("ZenThemeMarketplace", {
gZenActorsManager.addJSWindowActor('ZenThemeMarketplace', {
parent: {
esModuleURI: "chrome://browser/content/zen-components/actors/ZenThemeMarketplaceParent.sys.mjs",
esModuleURI: 'chrome://browser/content/zen-components/actors/ZenThemeMarketplaceParent.sys.mjs',
},
child: {
esModuleURI: "chrome://browser/content/zen-components/actors/ZenThemeMarketplaceChild.sys.mjs",
esModuleURI: 'chrome://browser/content/zen-components/actors/ZenThemeMarketplaceChild.sys.mjs',
events: {
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

@ -41,7 +41,7 @@ class SplitNode extends SplitLeafNode {
}
set children(children) {
if (children) children.forEach(c => c.parent = this);
if (children) children.forEach((c) => (c.parent = this));
this._children = children;
}
@ -74,17 +74,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
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));
this.initializeContextMenu();
@ -150,7 +142,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
parent.children.splice(childIndex, 1);
if (parent.children.length !== 1) {
const otherNodeIncrease = 100 / (100 - toRemove.sizeInParent);
parent.children.forEach(c => c.sizeInParent *= otherNodeIncrease);
parent.children.forEach((c) => (c.sizeInParent *= otherNodeIncrease));
return parent;
}
// node that is not a leaf cannot have less than 2 children, this makes for better resizing
@ -164,8 +156,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
parent.parent.children[idx] = leftOverChild;
} else {
// node cannot have same direction as it's parent
leftOverChild.children.forEach(c => {
c.sizeInParent *= leftOverChild.sizeInParent / 100
leftOverChild.children.forEach((c) => {
c.sizeInParent *= leftOverChild.sizeInParent / 100;
c.parent = parent.parent;
});
parent.parent.children.splice(idx, 1, ...leftOverChild.children);
@ -174,7 +166,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
this._removeNodeSplitters(parent, false);
return parent.parent;
} else {
const viewData = Object.values(this._data).find(s => s.layoutTree === parent);
const viewData = Object.values(this._data).find((s) => s.layoutTree === parent);
viewData.layoutTree = leftOverChild;
leftOverChild.positionToRoot = null;
leftOverChild.parent = null;
@ -187,27 +179,27 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
* @param {boolean} recursive
* @private
*/
_removeNodeSplitters(node, recursive ) {
this.getSplitters(node)?.forEach(s => s.remove());
_removeNodeSplitters(node, recursive) {
this.getSplitters(node)?.forEach((s) => s.remove());
this._splitNodeToSplitters.delete(node);
if (!recursive) return;
if (node.children) node.children.forEach(c => this._removeNodeSplitters(c));
if (node.children) node.children.forEach((c) => this._removeNodeSplitters(c));
}
get rearangeActionTarget() {
return document.getElementById("urlbar-container");
return document.getElementById('urlbar-container');
}
afterRearangeAction() {
document.getElementById("zenSplitViewModifier").hidePopup();
ConfirmationHint.show(document.getElementById("zen-split-views-box"), "zen-split-view-modifier-enabled-toast", {
descriptionId: "zen-split-view-modifier-enabled-toast-description",
document.getElementById('zenSplitViewModifier').hidePopup();
ConfirmationHint.show(document.getElementById('zen-split-views-box'), 'zen-split-view-modifier-enabled-toast', {
descriptionId: 'zen-split-view-modifier-enabled-toast-description',
showDescription: true,
});
}
afterRearangeRemove() {
ConfirmationHint.show(document.getElementById("zen-split-views-box"), "zen-split-view-modifier-disabled-toast");
ConfirmationHint.show(document.getElementById('zen-split-views-box'), 'zen-split-view-modifier-disabled-toast');
}
toggleWrapperDisplay(value) {
@ -222,20 +214,20 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
this.rearrangeViewEnabled = true;
this.rearrangeViewView = this.currentView;
if (!this._thumnailCanvas) {
this._thumnailCanvas = document.createElement("canvas");
this._thumnailCanvas = document.createElement('canvas');
this._thumnailCanvas.width = 280 * devicePixelRatio;
this._thumnailCanvas.height = 140 * devicePixelRatio;
}
const browsers = this._data[this.currentView].tabs.map(t => t.linkedBrowser);
browsers.forEach(b => {
const browsers = this._data[this.currentView].tabs.map((t) => t.linkedBrowser);
browsers.forEach((b) => {
b.style.pointerEvents = 'none';
b.style.opacity = '.85';
});
this.tabBrowserPanel.addEventListener('dragstart', this.onBrowserDragStart);
this.tabBrowserPanel.addEventListener('dragover', this.onBrowserDragOver);
this.tabBrowserPanel.addEventListener('drop', this.onBrowserDrop);
this.tabBrowserPanel.addEventListener('dragend', this.onBrowserDragEnd)
this.tabBrowserPanel.addEventListener('dragend', this.onBrowserDragEnd);
this.tabBrowserPanel.addEventListener('click', this.disableTabRearrangeView);
window.addEventListener('keydown', this.disableTabRearrangeView);
this.afterRearangeAction();
@ -245,8 +237,7 @@ 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;
}
}
@ -260,15 +251,15 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
this.tabBrowserPanel.removeEventListener('drop', this.onBrowserDrop);
this.tabBrowserPanel.removeEventListener('click', this.disableTabRearrangeView);
window.removeEventListener('keydown', this.disableTabRearrangeView);
const browsers = this._data[this.rearrangeViewView].tabs.map(t => t.linkedBrowser);
browsers.forEach(b => {
const browsers = this._data[this.rearrangeViewView].tabs.map((t) => t.linkedBrowser);
browsers.forEach((b) => {
b.style.pointerEvents = '';
b.style.opacity = '';
});
this.rearrangeViewEnabled = false;
this.rearrangeViewView = null;
this.afterRearangeRemove();
}
};
onBrowserDragStart = (event) => {
if (!this.splitViewActive) return;
@ -285,12 +276,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
let scale = window.devicePixelRatio;
let canvas = this._dndCanvas;
if (!canvas) {
this._dndCanvas = canvas = document.createElementNS(
"http://www.w3.org/1999/xhtml",
"canvas"
);
canvas.style.width = "100%";
canvas.style.height = "100%";
this._dndCanvas = canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
canvas.style.width = '100%';
canvas.style.height = '100%';
}
canvas.width = 160 * scale;
@ -298,15 +286,15 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
let toDrag = canvas;
let dragImageOffset = -16;
if (gMultiProcessBrowser) {
var context = canvas.getContext("2d");
context.fillStyle = "white";
var context = canvas.getContext('2d');
context.fillStyle = 'white';
context.fillRect(0, 0, canvas.width, canvas.height);
let captureListener;
let platform = AppConstants.platform;
// On Windows and Mac we can update the drag image during a drag
// using updateDragImage. On Linux, we can use a panel.
if (platform === "win" || platform === "macosx") {
if (platform === 'win' || platform === 'macosx') {
captureListener = function () {
dt.updateDragImage(canvas, dragImageOffset, dragImageOffset);
};
@ -316,15 +304,12 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
// the pointer while a dnd session is on.
if (!this._dndPanel) {
this._dndCanvas = canvas;
this._dndPanel = document.createXULElement("panel");
this._dndPanel.className = "dragfeedback-tab";
this._dndPanel.setAttribute("type", "drag");
let wrapper = document.createElementNS(
"http://www.w3.org/1999/xhtml",
"div"
);
wrapper.style.width = "160px";
wrapper.style.height = "90px";
this._dndPanel = document.createXULElement('panel');
this._dndPanel.className = 'dragfeedback-tab';
this._dndPanel.setAttribute('type', 'drag');
let wrapper = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
wrapper.style.width = '160px';
wrapper.style.height = '90px';
wrapper.appendChild(canvas);
this._dndPanel.appendChild(wrapper);
document.documentElement.appendChild(this._dndPanel);
@ -335,18 +320,16 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
// since we can update the image during the dnd.
PageThumbs.captureToCanvas(browser, canvas)
.then(captureListener)
.catch(e => console.error(e));
.catch((e) => console.error(e));
} else {
// For the non e10s case we can just use PageThumbs
// sync, so let's use the canvas for setDragImage.
PageThumbs.captureToCanvas(browser, canvas).catch(e =>
console.error(e)
);
PageThumbs.captureToCanvas(browser, canvas).catch((e) => console.error(e));
dragImageOffset = dragImageOffset * scale;
}
dt.setDragImage(toDrag, dragImageOffset, dragImageOffset);
return true;
}
};
onBrowserDragOver = (event) => {
event.preventDefault();
@ -364,30 +347,29 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
}
const splitNode = this.getSplitNodeFromTab(tab);
const posToRoot = {...splitNode.positionToRoot};
const posToRoot = { ...splitNode.positionToRoot };
const browserRect = browser.getBoundingClientRect();
const hoverSide = this.calculateHoverSide(event.clientX, event.clientY, browserRect);
if (hoverSide !== 'center') {
const isVertical = hoverSide === 'top' || hoverSide === 'bottom';
const browserSize = 100 - (isVertical ? posToRoot.top + posToRoot.bottom : posToRoot.right + posToRoot.left);
const reduce= browserSize * .5;
const reduce = browserSize * 0.5;
posToRoot[this._oppositeSide(hoverSide)] += reduce;
}
const newInset =
`${posToRoot.top}% ${posToRoot.right}% ${posToRoot.bottom}% ${posToRoot.left}%`;
const newInset = `${posToRoot.top}% ${posToRoot.right}% ${posToRoot.bottom}% ${posToRoot.left}%`;
if (this.dropZone.style.inset !== newInset) {
window.requestAnimationFrame(() => this.dropZone.style.inset = newInset);
}
window.requestAnimationFrame(() => (this.dropZone.style.inset = newInset));
}
};
onBrowserDragEnd = (event) => {
this.dropZone.removeAttribute('enabled');
const draggingBrowser = this._draggingTab.linkedBrowser;
draggingBrowser.style.opacity = '.85';
this._draggingTab = null;
}
};
_oppositeSide(side) {
if (side === 'top') return 'bottom';
@ -397,8 +379,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
}
calculateHoverSide(x, y, elementRect) {
const hPixelHoverSize = (elementRect.right - elementRect.left) * this._edgeHoverSize / 100;
const vPixelHoverSize = (elementRect.bottom - elementRect.top) * this._edgeHoverSize / 100;
const hPixelHoverSize = ((elementRect.right - elementRect.left) * this._edgeHoverSize) / 100;
const vPixelHoverSize = ((elementRect.bottom - elementRect.top) * this._edgeHoverSize) / 100;
if (x <= elementRect.left + hPixelHoverSize) return 'left';
if (x > elementRect.right - hPixelHoverSize) return 'right';
if (y <= elementRect.top + vPixelHoverSize) return 'top';
@ -412,9 +394,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
const droppedTab = this._draggingTab;
if (!droppedTab) return;
const droppedOnTab = gBrowser.getTabForBrowser(
event.target.querySelector('browser')
);
const droppedOnTab = gBrowser.getTabForBrowser(event.target.querySelector('browser'));
if (droppedTab === droppedOnTab) return;
const hoverSide = this.calculateHoverSide(event.clientX, event.clientY, browserDroppedOn.getBoundingClientRect());
@ -426,9 +406,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
return;
}
this.removeNode(droppedSplitNode);
this.splitIntoNode(droppedOnSplitNode, droppedSplitNode, hoverSide, .5);
this.splitIntoNode(droppedOnSplitNode, droppedSplitNode, hoverSide, 0.5);
this.activateSplitView(this._data[this.currentView], true);
}
};
/**
*
@ -470,7 +450,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
const nodeIndex = node.parent.children.indexOf(node);
node.parent.children[nodeIndex] = newParent;
} else {
const viewData = Object.values(this._data).find(s => s.layoutTree === node);
const viewData = Object.values(this._data).find((s) => s.layoutTree === node);
viewData.layoutTree = newParent;
}
newParent.addChild(node);
@ -595,7 +575,11 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
* Splits a link in a new tab.
*/
splitLinkInNewTab() {
const url = window.gContextMenu.linkURL || window.gContextMenu.mediaURL || window.gContextMenu.contentData.docLocation || window.gContextMenu.target.ownerDocument.location.href;
const url =
window.gContextMenu.linkURL ||
window.gContextMenu.mediaURL ||
window.gContextMenu.contentData.docLocation ||
window.gContextMenu.target.ownerDocument.location.href;
const currentTab = window.gBrowser.selectedTab;
const newTab = this.openAndSwitchToTab(url);
this.splitTabs([currentTab, newTab]);
@ -656,8 +640,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
if (existingSplitTab) {
const groupIndex = this._data.findIndex((group) => group.tabs.includes(existingSplitTab));
const group = this._data[groupIndex];
const gridTypeChange = gridType && (group.gridType !== gridType);
const newTabsAdded = tabs.find(t => !group.tabs.includes(t));
const gridTypeChange = gridType && group.gridType !== gridType;
const newTabsAdded = tabs.find((t) => !group.tabs.includes(t));
if (gridTypeChange || !newTabsAdded) {
// reset layout
group.gridType = gridType;
@ -680,7 +664,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
tabs,
gridType,
layoutTree: this.calculateLayoutTree(tabs, gridType),
}
};
this._data.push(splitData);
window.gBrowser.selectedTab = tabs[0];
this.activateSplitView(splitData);
@ -688,7 +672,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
addTabToSplit(tab, splitNode) {
const reduce = splitNode.children.length / (splitNode.children.length + 1);
splitNode.children.forEach(c => c.sizeInParent *= reduce);
splitNode.children.forEach((c) => (c.sizeInParent *= reduce));
splitNode.addChild(new SplitLeafNode(tab, (1 - reduce) * 100));
}
@ -757,10 +741,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
let rootNode;
if (gridType === 'vsep' || (tabs.length === 2 && gridType === 'grid')) {
rootNode = new SplitNode('row');
rootNode.children = tabs.map(tab => new SplitLeafNode(tab, 100 / tabs.length));
rootNode.children = tabs.map((tab) => new SplitLeafNode(tab, 100 / tabs.length));
} else if (gridType === 'hsep') {
rootNode = new SplitNode('column');
rootNode.children = tabs.map(tab => new SplitLeafNode(tab, 100 / tabs.length));
rootNode.children = tabs.map((tab) => new SplitLeafNode(tab, 100 / tabs.length));
} else if (gridType === 'grid') {
rootNode = new SplitNode('row');
const rowWidth = 100 / Math.ceil(tabs.length / 2);
@ -798,7 +782,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
*/
applyGridLayout(splitNode) {
if (!splitNode.positionToRoot) {
splitNode.positionToRoot = {top: 0, bottom: 0, left: 0, right: 0};
splitNode.positionToRoot = { top: 0, bottom: 0, left: 0, right: 0 };
}
const nodeRootPosition = splitNode.positionToRoot;
if (!splitNode.children) {
@ -808,8 +792,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
return;
}
const rootToNodeWidthRatio = ((100 - nodeRootPosition.right) - nodeRootPosition.left) / 100;
const rootToNodeHeightRatio = ((100 - nodeRootPosition.bottom) - nodeRootPosition.top) / 100;
const rootToNodeWidthRatio = (100 - nodeRootPosition.right - nodeRootPosition.left) / 100;
const rootToNodeHeightRatio = (100 - nodeRootPosition.bottom - nodeRootPosition.top) / 100;
const splittersNeeded = splitNode.children.length - 1;
const currentSplitters = this.getSplitters(splitNode, splittersNeeded);
@ -817,7 +801,12 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
let leftOffset = nodeRootPosition.left;
let topOffset = nodeRootPosition.top;
splitNode.children.forEach((childNode, i) => {
const childRootPosition = {top: topOffset, right: 100 - (leftOffset + childNode.widthInParent * rootToNodeWidthRatio), bottom: 100 - (topOffset + childNode.heightInParent * rootToNodeHeightRatio), left: leftOffset};
const childRootPosition = {
top: topOffset,
right: 100 - (leftOffset + childNode.widthInParent * rootToNodeWidthRatio),
bottom: 100 - (topOffset + childNode.heightInParent * rootToNodeHeightRatio),
left: leftOffset,
};
childNode.positionToRoot = childRootPosition;
this.applyGridLayout(childNode);
@ -849,7 +838,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
splitter.className = 'zen-split-view-splitter';
splitter.setAttribute('orient', orient);
splitter.setAttribute('gridIdx', idx);
this.overlay.insertAdjacentElement("afterbegin", splitter);
this.overlay.insertAdjacentElement('afterbegin', splitter);
splitter.addEventListener('mousedown', this.handleSplitterMouseDown);
return splitter;
@ -863,13 +852,11 @@ 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) {
currentSplitters.slice(splittersNeeded - currentSplitters.length).forEach(s => s.remove());
currentSplitters.slice(splittersNeeded - currentSplitters.length).forEach((s) => s.remove());
currentSplitters = currentSplitters.slice(0, splittersNeeded);
}
this._splitNodeToSplitters.set(parentNode, currentSplitters);
@ -877,7 +864,7 @@ 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();
}
@ -928,17 +915,21 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
let rootToNodeSize;
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 originalSizes = splitNode.children.map((c) => c.sizeInParent);
const dragFunc = (dEvent) => {
requestAnimationFrame(() => {
originalSizes.forEach((s, i) => splitNode.children[i].sizeInParent = s); // reset changes
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 (let i = gridIdx + (movementPercent < 0 ? 0 : 1); 0 <= i && i < originalSizes.length; i += movementPercent < 0 ? -1 : 1) {
for (
let i = gridIdx + (movementPercent < 0 ? 0 : 1);
0 <= i && i < originalSizes.length;
i += movementPercent < 0 ? -1 : 1
) {
const current = originalSizes[i];
const newSize = Math.max(this.minResizeWidth, current - reducingMovement);
splitNode.children[i].sizeInParent = newSize;
@ -946,21 +937,25 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
reducingMovement -= amountReduced;
if (reducingMovement <= 0) break;
}
const increasingMovement = Math.max(movementPercent, - movementPercent) - reducingMovement;
const increasingMovement = Math.max(movementPercent, -movementPercent) - reducingMovement;
const increaseIndex = gridIdx + (movementPercent < 0 ? 1 : 0);
splitNode.children[increaseIndex].sizeInParent = originalSizes[increaseIndex] + increasingMovement;
this.applyGridLayout(splitNode);
});
}
};
setCursor(isVertical ? 'ew-resize' : 'ns-resize');
document.addEventListener('mousemove', dragFunc);
document.addEventListener('mouseup', () => {
document.addEventListener(
'mouseup',
() => {
document.removeEventListener('mousemove', dragFunc);
setCursor('auto');
this.tabBrowserPanel.removeAttribute('zen-split-resizing');
}, {once: true});
}
},
{ once: true }
);
};
/**
* Sets the docshell state for the tabs.

View file

@ -9,16 +9,16 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
_swipeState = {
isGestureActive: true,
cumulativeDelta: 0,
direction: null
direction: null,
};
_hoveringSidebar = false;
_lastScrollTime = 0;
bookmarkMenus = [
"PlacesToolbar",
"bookmarks-menu-button",
"BMB_bookmarksToolbar",
"BMB_unsortedBookmarks",
"BMB_mobileBookmarks"
'PlacesToolbar',
'bookmarks-menu-button',
'BMB_bookmarksToolbar',
'BMB_unsortedBookmarks',
'BMB_mobileBookmarks',
];
async init() {
@ -29,24 +29,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
this.ownerWindow = window;
XPCOMUtils.defineLazyPreferenceGetter(
this,
'activationMethod',
'zen.workspaces.scroll-modifier-key',
'ctrl',
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'naturalScroll',
'zen.workspaces.natural-scroll',
true
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'shouldWrapAroundNavigation',
'zen.workspaces.wrap-around-navigation',
true
);
XPCOMUtils.defineLazyPreferenceGetter(this, 'activationMethod', 'zen.workspaces.scroll-modifier-key', 'ctrl');
XPCOMUtils.defineLazyPreferenceGetter(this, 'naturalScroll', 'zen.workspaces.natural-scroll', true);
XPCOMUtils.defineLazyPreferenceGetter(this, 'shouldWrapAroundNavigation', 'zen.workspaces.wrap-around-navigation', true);
XPCOMUtils.defineLazyPreferenceGetter(
this,
'shouldShowIconStrip',
@ -90,11 +75,14 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
Services.obs.addObserver(this, 'weave:engine:sync:finish');
Services.obs.addObserver(async function observe(subject) {
Services.obs.addObserver(
async function observe(subject) {
this._workspaceBookmarksCache = null;
await this.workspaceBookmarks();
this._invalidateBookmarkContainers();
}.bind(this), "workspace-bookmarks-updated");
}.bind(this),
'workspace-bookmarks-updated'
);
}
initializeWorkspaceNavigation() {
@ -104,13 +92,13 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
_setupAppCommandHandlers() {
// Remove existing handler temporarily - this is needed so that _handleAppCommand is called before the original
window.removeEventListener("AppCommand", HandleAppCommandEvent, true);
window.removeEventListener('AppCommand', HandleAppCommandEvent, true);
// Add our handler first
window.addEventListener("AppCommand", this._handleAppCommand.bind(this), true);
window.addEventListener('AppCommand', this._handleAppCommand.bind(this), true);
// Re-add original handler
window.addEventListener("AppCommand", HandleAppCommandEvent, true);
window.addEventListener('AppCommand', HandleAppCommandEvent, true);
}
_handleAppCommand(event) {
@ -121,12 +109,12 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
const direction = this.naturalScroll ? -1 : 1;
// event is forward or back
switch (event.command) {
case "Forward":
case 'Forward':
this.changeWorkspaceShortcut(1 * direction);
event.stopImmediatePropagation();
event.preventDefault();
break;
case "Back":
case 'Back':
this.changeWorkspaceShortcut(-1 * direction);
event.stopImmediatePropagation();
event.preventDefault();
@ -148,7 +136,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
const scrollCooldown = 200; // Milliseconds to wait before allowing another scroll
const scrollThreshold = 2; // Minimum scroll delta to trigger workspace change
toolbox.addEventListener('wheel', async (event) => {
toolbox.addEventListener(
'wheel',
async (event) => {
if (!this.workspaceEnabled) return;
// Only process non-gesture scrolls
@ -159,7 +149,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
//if the scroll is vertical this checks that a modifier key is used before proceeding
if (isVerticalScroll) {
const activationKeyMap = {
ctrl: event.ctrlKey,
alt: event.altKey,
@ -186,14 +175,16 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
this.changeWorkspaceShortcut(rawDirection * direction);
this._lastScrollTime = currentTime;
}, { passive: true });
},
{ passive: true }
);
}
initializeGestureHandlers() {
const elements = [
document.getElementById('navigator-toolbox'),
// event handlers do not work on elements inside shadow DOM so we need to attach them directly
document.getElementById("tabbrowser-arrowscrollbox").shadowRoot.querySelector("scrollbox"),
document.getElementById('tabbrowser-arrowscrollbox').shadowRoot.querySelector('scrollbox'),
];
// Attach gesture handlers to each element
@ -233,7 +224,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
this._swipeState = {
isGestureActive: true,
cumulativeDelta: 0,
direction: null
direction: null,
};
}
@ -261,7 +252,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
let rawDirection = moveForward ? 1 : -1;
if (this._swipeState.direction) {
let direction = this.naturalScroll ? -1 : 1;
this.changeWorkspaceShortcut(rawDirection * direction);
}
@ -270,7 +260,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
this._swipeState = {
isGestureActive: false,
cumulativeDelta: 0,
direction: null
direction: null,
};
}
@ -450,9 +440,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
const shouldOpenNewTabIfLastUnpinnedTabIsClosed = this.shouldOpenNewTabIfLastUnpinnedTabIsClosed;
let tabs = gBrowser.tabs.filter(t =>
let tabs = gBrowser.tabs.filter(
(t) =>
t.getAttribute('zen-workspace-id') === workspaceID &&
(!shouldOpenNewTabIfLastUnpinnedTabIsClosed ||!t.pinned || t.getAttribute("pending") !== "true")
(!shouldOpenNewTabIfLastUnpinnedTabIsClosed || !t.pinned || t.getAttribute('pending') !== 'true')
);
if (tabs.length === 1 && tabs[0] === tab) {
@ -466,7 +457,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
_createNewTabForWorkspace(window) {
let tab = gZenUIManager.openAndChangeToTab(Services.prefs.getStringPref('browser.startup.homepage'));
if(window.uuid){
if (window.uuid) {
tab.setAttribute('zen-workspace-id', window.uuid);
}
return tab;
@ -479,7 +470,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
searchIcons(input, icons) {
input = input.toLowerCase();
if ((input === ':') || (input === '')) {
if (input === ':' || input === '') {
return icons;
}
const emojiScores = [];
@ -492,8 +483,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
let alignmentScore = -1;
let normalizedEmojiName = currentEmoji[1].toLowerCase();
let keywordList = currentEmoji[2].split(',').map(keyword => keyword.trim().toLowerCase());
if (input[0] === ":") {
let keywordList = currentEmoji[2].split(',').map((keyword) => keyword.trim().toLowerCase());
if (input[0] === ':') {
let searchTerm = input.slice(1);
let nameMatchIndex = normalizedEmojiName.indexOf(searchTerm);
@ -508,7 +499,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (nameMatchIndex !== -1) {
if (nameMatchIndex === 0) {
alignmentScore = calculateSearchScore(input.length, normalizedEmojiName.length, 150);
} else if (input[input.length - 1] !== " ") {
} else if (input[input.length - 1] !== ' ') {
alignmentScore += calculateSearchScore(input.length, normalizedEmojiName.length, 40);
}
}
@ -517,7 +508,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (keywordMatchIndex !== -1) {
if (keywordMatchIndex === 0) {
alignmentScore += calculateSearchScore(input.length, keyword.length, 50);
} else if (input[input.length - 1] !== " ") {
} else if (input[input.length - 1] !== ' ') {
alignmentScore += calculateSearchScore(input.length, keyword.length, 5);
}
}
@ -526,7 +517,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
//if match score is not -1, add it
if (alignmentScore !== -1) {
emojiScores.push({ "emoji": currentEmoji[0], "score": alignmentScore });
emojiScores.push({ emoji: currentEmoji[0], score: alignmentScore });
}
}
// Sort the emojis by their score in descending order
@ -534,10 +525,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
// Return the emojis in the order of their rank
let filteredEmojiScores = emojiScores;
return filteredEmojiScores.map(score => score.emoji);
return filteredEmojiScores.map((score) => score.emoji);
}
resetWorkspaceIconSearch(){
resetWorkspaceIconSearch() {
let container = document.getElementById('PanelUI-zen-workspaces-icon-picker-wrapper');
let searchInput = document.getElementById('PanelUI-zen-workspaces-icon-search-input');
@ -586,14 +577,12 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
const buttons = Array.from(container.querySelectorAll('.toolbarbutton-1'));
buttons.forEach(button => button.style.display = 'none');
buttons.forEach((button) => (button.style.display = 'none'));
const filteredIcons = this.searchIcons(query, this.emojis);
filteredIcons.forEach(emoji => {
const matchingButton = buttons.find(button =>
button.getAttribute('label') === emoji
);
filteredIcons.forEach((emoji) => {
const matchingButton = buttons.find((button) => button.getAttribute('label') === emoji);
if (matchingButton) {
matchingButton.style.display = '';
container.appendChild(matchingButton);
@ -930,7 +919,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
return element;
};
if(clearCache) {
if (clearCache) {
browser.ZenWorkspaces._workspaceCache = null;
browser.ZenWorkspaces._workspaceBookmarksCache = null;
}
@ -1020,11 +1009,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (!this.workspaceEnabled) {
return;
}
let target = event.target.closest("#zen-current-workspace-indicator") || document.getElementById('zen-workspaces-button');
let target = event.target.closest('#zen-current-workspace-indicator') || document.getElementById('zen-workspaces-button');
let panel = document.getElementById('PanelUI-zen-workspaces');
await this._propagateWorkspaceData({
ignoreStrip: true,
clearCache: false
clearCache: false,
});
PanelMultiView.openPopup(panel, target, {
position: 'bottomright topright',
@ -1197,7 +1186,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
document.documentElement.setAttribute('zen-workspace-id', window.uuid);
let tabCount = 0;
for (let tab of gBrowser.tabs) {
const isEssential = tab.getAttribute("zen-essential") === "true";
const isEssential = tab.getAttribute('zen-essential') === 'true';
if (!tab.hasAttribute('zen-workspace-id') && !tab.pinned && !isEssential) {
tab.setAttribute('zen-workspace-id', window.uuid);
tabCount++;
@ -1211,7 +1200,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
_createNewTabForWorkspace(window) {
let tab = gZenUIManager.openAndChangeToTab(BROWSER_NEW_TAB_URL);
if(window.uuid){
if (window.uuid) {
tab.setAttribute('zen-workspace-id', window.uuid);
}
}
@ -1310,9 +1299,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
// Animate acordingly
if (previousWorkspace && !this._animatingChange) {
// we want to know if we are moving forward or backward in sense of animation
let isNextWorkspace = onInit ||
(workspaces.workspaces.findIndex((w) => w.uuid === previousWorkspace.uuid)
< workspaces.workspaces.findIndex((w) => w.uuid === window.uuid));
let isNextWorkspace =
onInit ||
workspaces.workspaces.findIndex((w) => w.uuid === previousWorkspace.uuid) <
workspaces.workspaces.findIndex((w) => w.uuid === window.uuid);
gBrowser.tabContainer.setAttribute('zen-workspace-animation', isNextWorkspace ? 'next' : 'previous');
this._animatingChange = true;
setTimeout(() => {
@ -1322,7 +1312,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
}
_processTabVisibility(workspaceUuid, containerId, workspaces) {
const visibleTabs = new Set();
const lastSelectedTab = this._lastSelectedWorkspaceTabs[workspaceUuid];
@ -1330,7 +1319,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
this.tabContainer.setAttribute('dont-animate-tabs', 'true');
for (const tab of gBrowser.tabs) {
const tabWorkspaceId = tab.getAttribute('zen-workspace-id');
const isEssential = tab.getAttribute("zen-essential") === "true";
const isEssential = tab.getAttribute('zen-essential') === 'true';
// Always hide last selected tabs from other workspaces
if (lastSelectedTab === tab && tabWorkspaceId !== workspaceUuid && !isEssential) {
@ -1358,9 +1347,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
_shouldShowTab(tab, workspaceUuid, containerId, workspaces) {
const isEssential = tab.getAttribute("zen-essential") === "true";
const isEssential = tab.getAttribute('zen-essential') === 'true';
const tabWorkspaceId = tab.getAttribute('zen-workspace-id');
const tabContextId = tab.getAttribute("usercontextid");
const tabContextId = tab.getAttribute('usercontextid');
// Handle essential tabs
if (isEssential) {
@ -1374,8 +1363,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
} else {
// In workspaces without a default container: Show essentials that aren't in container-specific workspaces
// or have usercontextid="0" or no usercontextid
return !tabContextId || tabContextId === "0" || !workspaces.workspaces.some(
workspace => workspace.containerTabId === parseInt(tabContextId, 10)
return (
!tabContextId ||
tabContextId === '0' ||
!workspaces.workspaces.some((workspace) => workspace.containerTabId === parseInt(tabContextId, 10))
);
}
}
@ -1408,13 +1399,16 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
tabToSelect = currentSelectedTab;
}
// Try last selected tab if it is visible
else if (lastSelectedTab && this._shouldShowTab(lastSelectedTab, window.uuid, containerId, workspaces) && visibleTabs.has(lastSelectedTab)) {
else if (
lastSelectedTab &&
this._shouldShowTab(lastSelectedTab, window.uuid, containerId, workspaces) &&
visibleTabs.has(lastSelectedTab)
) {
tabToSelect = lastSelectedTab;
}
// Find first suitable tab
else {
tabToSelect = Array.from(visibleTabs)
.find(tab => !tab.pinned);
tabToSelect = Array.from(visibleTabs).find((tab) => !tab.pinned);
}
const previousSelectedTab = gBrowser.selectedTab;
@ -1436,7 +1430,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
}
}
async _updateWorkspaceState(window, onInit) {
// Update document state
document.documentElement.setAttribute('zen-workspace-id', window.uuid);
@ -1535,7 +1528,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
async onTabBrowserInserted(event) {
let tab = event.originalTarget;
const isEssential = tab.getAttribute("zen-essential") === "true";
const isEssential = tab.getAttribute('zen-essential') === 'true';
if (tab.getAttribute('zen-workspace-id') || !this.workspaceEnabled || isEssential) {
return;
}
@ -1555,7 +1548,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
const parent = browser.ownerGlobal;
const tab = gBrowser.getTabForBrowser(browser);
const workspaceID = tab.getAttribute('zen-workspace-id');
const isEssential = tab.getAttribute("zen-essential") === "true";
const isEssential = tab.getAttribute('zen-essential') === 'true';
if (!isEssential) {
const activeWorkspace = await parent.ZenWorkspaces.getActiveWorkspace();
if (!activeWorkspace) {
@ -1660,7 +1653,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
return this._emojis;
}
const lazy = {};
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenEmojies.mjs", lazy);
Services.scriptloader.loadSubScript('chrome://browser/content/zen-components/ZenEmojies.mjs', lazy);
this._emojis = lazy.zenGlobalEmojis();
return this._emojis;
}
@ -1670,7 +1663,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
this._emojis = null;
}
async changeWorkspaceShortcut(offset = 1){
async changeWorkspaceShortcut(offset = 1) {
// Cycle through workspaces
let workspaces = await this._workspaces();
let activeWorkspace = await this.getActiveWorkspace();
@ -1686,7 +1679,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
targetIndex = Math.max(0, Math.min(workspaces.workspaces.length - 1, targetIndex));
}
let nextWorkspace = workspaces.workspaces[(targetIndex)];
let nextWorkspace = workspaces.workspaces[targetIndex];
await this.changeWorkspace(nextWorkspace);
}
@ -1739,7 +1732,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (this.shouldForceContainerTabsToWorkspace && typeof userContextId !== 'undefined' && this._workspaceCache?.workspaces) {
// Find all workspaces that match the given userContextId
const matchingWorkspaces = this._workspaceCache.workspaces.filter((workspace) => workspace.containerTabId === userContextId);
const matchingWorkspaces = this._workspaceCache.workspaces.filter(
(workspace) => workspace.containerTabId === userContextId
);
// Check if exactly one workspace matches
if (matchingWorkspaces.length === 1) {
@ -1794,5 +1789,4 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
// Return true only if the bookmark is in another workspace and not in the active one
return isInOtherWorkspace && !isInActiveWorkspace;
}
})();

View file

@ -3,8 +3,8 @@ var ZenWorkspacesStorage = {
async init() {
ChromeUtils.defineESModuleGetters(this.lazy, {
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
Weave: "resource://services-sync/main.sys.mjs",
PlacesUtils: 'resource://gre/modules/PlacesUtils.sys.mjs',
Weave: 'resource://services-sync/main.sys.mjs',
});
await this._ensureTable();
@ -32,7 +32,7 @@ var ZenWorkspacesStorage = {
// SQLite doesn't have a direct "ADD COLUMN IF NOT EXISTS" syntax,
// so we need to check if the columns exist first
const columns = await db.execute(`PRAGMA table_info(zen_workspaces)`);
const columnNames = columns.map(row => row.getResultByName('name'));
const columnNames = columns.map((row) => row.getResultByName('name'));
// Helper function to add column if it doesn't exist
const addColumnIfNotExists = async (columnName, definition) => {
@ -111,7 +111,9 @@ var ZenWorkspacesStorage = {
// Handle default workspace
if (workspace.default) {
await db.execute(`UPDATE zen_workspaces SET is_default = 0 WHERE uuid != :uuid`, { uuid: workspace.uuid });
const unsetDefaultRows = await db.execute(`SELECT uuid FROM zen_workspaces WHERE is_default = 0 AND uuid != :uuid`, { uuid: workspace.uuid });
const unsetDefaultRows = await db.execute(`SELECT uuid FROM zen_workspaces WHERE is_default = 0 AND uuid != :uuid`, {
uuid: workspace.uuid,
});
for (const row of unsetDefaultRows) {
changedUUIDs.add(row.getResultByName('uuid'));
}
@ -128,7 +130,8 @@ var ZenWorkspacesStorage = {
}
// Insert or replace the workspace
await db.executeCached(`
await db.executeCached(
`
INSERT OR REPLACE INTO zen_workspaces (
uuid, name, icon, is_default, container_id, created_at, updated_at, "position",
theme_type, theme_colors, theme_opacity, theme_rotation, theme_texture
@ -139,7 +142,8 @@ var ZenWorkspacesStorage = {
:position,
:theme_type, :theme_colors, :theme_opacity, :theme_rotation, :theme_texture
)
`, {
`,
{
uuid: workspace.uuid,
name: workspace.name,
icon: workspace.icon || null,
@ -151,17 +155,21 @@ var ZenWorkspacesStorage = {
theme_colors: workspace.theme ? JSON.stringify(workspace.theme.gradientColors) : null,
theme_opacity: workspace.theme?.opacity || null,
theme_rotation: workspace.theme?.rotation || null,
theme_texture: workspace.theme?.texture || null
});
theme_texture: workspace.theme?.texture || null,
}
);
// Record the change
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`, {
`,
{
uuid: workspace.uuid,
timestamp: Math.floor(now / 1000)
});
timestamp: Math.floor(now / 1000),
}
);
changedUUIDs.add(workspace.uuid);
@ -170,7 +178,7 @@ var ZenWorkspacesStorage = {
});
if (notifyObservers) {
this._notifyWorkspacesChanged("zen-workspace-updated", Array.from(changedUUIDs));
this._notifyWorkspacesChanged('zen-workspace-updated', Array.from(changedUUIDs));
}
},
@ -186,13 +194,15 @@ var ZenWorkspacesStorage = {
default: !!row.getResultByName('is_default'),
containerTabId: row.getResultByName('container_id'),
position: row.getResultByName('position'),
theme: row.getResultByName('theme_type') ? {
theme: row.getResultByName('theme_type')
? {
type: row.getResultByName('theme_type'),
gradientColors: JSON.parse(row.getResultByName('theme_colors')),
opacity: row.getResultByName('theme_opacity'),
rotation: row.getResultByName('theme_rotation'),
texture: row.getResultByName('theme_texture')
} : null
texture: row.getResultByName('theme_texture'),
}
: null,
}));
},
@ -209,19 +219,22 @@ var ZenWorkspacesStorage = {
// Record the removal as a change
const now = Date.now();
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`, {
`,
{
uuid,
timestamp: Math.floor(now / 1000)
});
timestamp: Math.floor(now / 1000),
}
);
await this.updateLastChangeTimestamp(db);
});
if (notifyObservers) {
this._notifyWorkspacesChanged("zen-workspace-removed", changedUUIDs);
this._notifyWorkspacesChanged('zen-workspace-removed', changedUUIDs);
}
},
@ -243,7 +256,9 @@ var ZenWorkspacesStorage = {
await db.execute(`UPDATE zen_workspaces SET is_default = 0 WHERE uuid != :uuid`, { uuid });
// Collect UUIDs of workspaces that were unset as default
const unsetDefaultRows = await db.execute(`SELECT uuid FROM zen_workspaces WHERE is_default = 0 AND uuid != :uuid`, { uuid });
const unsetDefaultRows = await db.execute(`SELECT uuid FROM zen_workspaces WHERE is_default = 0 AND uuid != :uuid`, {
uuid,
});
for (const row of unsetDefaultRows) {
changedUUIDs.push(row.getResultByName('uuid'));
}
@ -252,13 +267,16 @@ var ZenWorkspacesStorage = {
await db.execute(`UPDATE zen_workspaces SET is_default = 1 WHERE uuid = :uuid`, { uuid });
// Record the change for the specified workspace
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`, {
`,
{
uuid,
timestamp: Math.floor(now / 1000)
});
timestamp: Math.floor(now / 1000),
}
);
// Add the main workspace UUID to the changed set
changedUUIDs.push(uuid);
@ -268,27 +286,31 @@ var ZenWorkspacesStorage = {
});
if (notifyObservers) {
this._notifyWorkspacesChanged("zen-workspace-updated", changedUUIDs);
this._notifyWorkspacesChanged('zen-workspace-updated', changedUUIDs);
}
},
async markChanged(uuid) {
await this.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.markChanged', async (db) => {
const now = Date.now();
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`, {
`,
{
uuid,
timestamp: Math.floor(now / 1000)
});
timestamp: Math.floor(now / 1000),
}
);
});
},
async saveWorkspaceTheme(uuid, theme, notifyObservers = true) {
const changedUUIDs = [uuid];
await this.lazy.PlacesUtils.withConnectionWrapper('saveWorkspaceTheme', async (db) => {
await db.execute(`
await db.execute(
`
UPDATE zen_workspaces
SET
theme_type = :type,
@ -298,22 +320,24 @@ var ZenWorkspacesStorage = {
theme_texture = :texture,
updated_at = :now
WHERE uuid = :uuid
`, {
`,
{
type: theme.type,
colors: JSON.stringify(theme.gradientColors),
opacity: theme.opacity,
rotation: theme.rotation,
texture: theme.texture,
now: Date.now(),
uuid
});
uuid,
}
);
await this.markChanged(uuid);
await this.updateLastChangeTimestamp(db);
});
if (notifyObservers) {
this._notifyWorkspacesChanged("zen-workspace-updated", changedUUIDs);
this._notifyWorkspacesChanged('zen-workspace-updated', changedUUIDs);
}
},
@ -349,21 +373,27 @@ var ZenWorkspacesStorage = {
for (let i = 0; i < workspaces.length; i++) {
const newPosition = (i + 1) * 1000; // Use large increments
await db.execute(`
await db.execute(
`
UPDATE zen_workspaces
SET "position" = :newPosition
WHERE uuid = :uuid
`, { newPosition, uuid: workspaces[i].getResultByName('uuid') });
`,
{ newPosition, uuid: workspaces[i].getResultByName('uuid') }
);
changedUUIDs.add(workspaces[i].getResultByName('uuid'));
}
},
async updateLastChangeTimestamp(db) {
const now = Date.now();
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO moz_meta (key, value)
VALUES ('zen_workspaces_last_change', :now)
`, { now });
`,
{ now }
);
},
async getLastChangeTimestamp() {
@ -385,29 +415,35 @@ var ZenWorkspacesStorage = {
const workspace = workspaces[i];
const newPosition = (i + 1) * 1000;
await db.execute(`
await db.execute(
`
UPDATE zen_workspaces
SET "position" = :newPosition
WHERE uuid = :uuid
`, { newPosition, uuid: workspace.uuid });
`,
{ newPosition, uuid: workspace.uuid }
);
changedUUIDs.add(workspace.uuid);
// Record the change
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
VALUES (:uuid, :timestamp)
`, {
`,
{
uuid: workspace.uuid,
timestamp: Math.floor(now / 1000)
});
timestamp: Math.floor(now / 1000),
}
);
}
await this.updateLastChangeTimestamp(db);
});
});
this._notifyWorkspacesChanged("zen-workspace-updated", Array.from(changedUUIDs));
this._notifyWorkspacesChanged('zen-workspace-updated', Array.from(changedUUIDs));
},
};
@ -458,7 +494,6 @@ var ZenWorkspaceBookmarksStorage = {
CREATE INDEX IF NOT EXISTS idx_bookmarks_workspaces_changes
ON zen_bookmarks_workspaces_changes(bookmark_guid, workspace_uuid)
`);
});
},
@ -468,10 +503,13 @@ var ZenWorkspaceBookmarksStorage = {
*/
async updateLastChangeTimestamp(db) {
const now = Date.now();
await db.execute(`
await db.execute(
`
INSERT OR REPLACE INTO moz_meta (key, value)
VALUES ('zen_bookmarks_workspaces_last_change', :now)
`, { now });
`,
{ now }
);
},
/**
@ -489,13 +527,16 @@ var ZenWorkspaceBookmarksStorage = {
async getBookmarkWorkspaces(bookmarkGuid) {
const db = await ZenWorkspacesStorage.lazy.PlacesUtils.promiseDBConnection();
const rows = await db.execute(`
const rows = await db.execute(
`
SELECT workspace_uuid
FROM zen_bookmarks_workspaces
WHERE bookmark_guid = :bookmark_guid
`, { bookmark_guid: bookmarkGuid });
`,
{ bookmark_guid: bookmarkGuid }
);
return rows.map(row => row.getResultByName("workspace_uuid"));
return rows.map((row) => row.getResultByName('workspace_uuid'));
},
/**
@ -519,8 +560,8 @@ var ZenWorkspaceBookmarksStorage = {
const result = {};
for (const row of rows) {
const workspaceUuid = row.getResultByName("workspace_uuid");
const bookmarkGuids = row.getResultByName("bookmark_guids");
const workspaceUuid = row.getResultByName('workspace_uuid');
const bookmarkGuids = row.getResultByName('bookmark_guids');
result[workspaceUuid] = bookmarkGuids ? bookmarkGuids.split(',') : [];
}
@ -543,7 +584,7 @@ var ZenWorkspaceBookmarksStorage = {
const key = `${row.getResultByName('bookmark_guid')}:${row.getResultByName('workspace_uuid')}`;
changes[key] = {
type: row.getResultByName('change_type'),
timestamp: row.getResultByName('timestamp')
timestamp: row.getResultByName('timestamp'),
};
}
return changes;
@ -553,11 +594,13 @@ var ZenWorkspaceBookmarksStorage = {
* Clear all recorded changes.
*/
async clearChangedIDs() {
await ZenWorkspacesStorage.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspaceBookmarksStorage.clearChangedIDs', async (db) => {
await ZenWorkspacesStorage.lazy.PlacesUtils.withConnectionWrapper(
'ZenWorkspaceBookmarksStorage.clearChangedIDs',
async (db) => {
await db.execute(`DELETE FROM zen_bookmarks_workspaces_changes`);
});
}
);
},
};
ZenWorkspacesStorage.init();

View file

@ -1,9 +1,7 @@
var { Tracker, Store, SyncEngine } = ChromeUtils.importESModule("resource://services-sync/engines.sys.mjs");
var { CryptoWrapper } = ChromeUtils.importESModule("resource://services-sync/record.sys.mjs");
var { Utils } = ChromeUtils.importESModule("resource://services-sync/util.sys.mjs");
var { SCORE_INCREMENT_XLARGE } = ChromeUtils.importESModule("resource://services-sync/constants.sys.mjs");
var { Tracker, Store, SyncEngine } = ChromeUtils.importESModule('resource://services-sync/engines.sys.mjs');
var { CryptoWrapper } = ChromeUtils.importESModule('resource://services-sync/record.sys.mjs');
var { Utils } = ChromeUtils.importESModule('resource://services-sync/util.sys.mjs');
var { SCORE_INCREMENT_XLARGE } = ChromeUtils.importESModule('resource://services-sync/constants.sys.mjs');
// Define ZenWorkspaceRecord
function ZenWorkspaceRecord(collection, id) {
@ -13,19 +11,19 @@ function ZenWorkspaceRecord(collection, id) {
ZenWorkspaceRecord.prototype = Object.create(CryptoWrapper.prototype);
ZenWorkspaceRecord.prototype.constructor = ZenWorkspaceRecord;
ZenWorkspaceRecord.prototype._logName = "Sync.Record.ZenWorkspace";
ZenWorkspaceRecord.prototype._logName = 'Sync.Record.ZenWorkspace';
Utils.deferGetSet(ZenWorkspaceRecord, "cleartext", [
"name",
"icon",
"default",
"containerTabId",
"position",
"theme_type",
"theme_colors",
"theme_opacity",
"theme_rotation",
"theme_texture"
Utils.deferGetSet(ZenWorkspaceRecord, 'cleartext', [
'name',
'icon',
'default',
'containerTabId',
'position',
'theme_type',
'theme_colors',
'theme_opacity',
'theme_rotation',
'theme_texture',
]);
// Define ZenWorkspacesStore
@ -57,7 +55,7 @@ ZenWorkspacesStore.prototype.getAllIDs = async function () {
}
return ids;
} catch (error) {
this._log.error("Error fetching all workspace IDs", error);
this._log.error('Error fetching all workspace IDs', error);
throw error;
}
};
@ -70,10 +68,10 @@ ZenWorkspacesStore.prototype.getAllIDs = async function () {
ZenWorkspacesStore.prototype.changeItemID = async function (oldID, newID) {
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
const workspace = workspaces.find(ws => ws.uuid === oldID);
const workspace = workspaces.find((ws) => ws.uuid === oldID);
if (workspace) {
workspace.uuid = newID;
await ZenWorkspacesStorage.saveWorkspace(workspace,false);
await ZenWorkspacesStorage.saveWorkspace(workspace, false);
// Mark the new ID as changed for sync
await ZenWorkspacesStorage.markChanged(newID);
}
@ -91,7 +89,7 @@ ZenWorkspacesStore.prototype.changeItemID = async function (oldID, newID) {
ZenWorkspacesStore.prototype.itemExists = async function (id) {
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
return workspaces.some(ws => ws.uuid === id);
return workspaces.some((ws) => ws.uuid === id);
} catch (error) {
this._log.error(`Error checking if workspace exists with ID ${id}`, error);
throw error;
@ -107,7 +105,7 @@ ZenWorkspacesStore.prototype.itemExists = async function (id) {
ZenWorkspacesStore.prototype.createRecord = async function (id, collection) {
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
const workspace = workspaces.find(ws => ws.uuid === id);
const workspace = workspaces.find((ws) => ws.uuid === id);
const record = new ZenWorkspaceRecord(collection, id);
if (workspace) {
@ -149,15 +147,17 @@ ZenWorkspacesStore.prototype.create = async function (record) {
default: record.default,
containerTabId: record.containerTabId,
position: record.position,
theme: record.theme_type ? {
theme: record.theme_type
? {
type: record.theme_type,
gradientColors: JSON.parse(record.theme_colors),
opacity: record.theme_opacity,
rotation: record.theme_rotation,
texture: record.theme_texture
} : null
texture: record.theme_texture,
}
: null,
};
await ZenWorkspacesStorage.saveWorkspace(workspace,false);
await ZenWorkspacesStorage.saveWorkspace(workspace, false);
} catch (error) {
this._log.error(`Error creating workspace with ID ${record.id}`, error);
throw error;
@ -198,7 +198,7 @@ ZenWorkspacesStore.prototype.wipe = async function () {
try {
await ZenWorkspacesStorage.wipeAllWorkspaces();
} catch (error) {
this._log.error("Error wiping all workspaces", error);
this._log.error('Error wiping all workspaces', error);
throw error;
}
};
@ -208,31 +208,31 @@ ZenWorkspacesStore.prototype.wipe = async function () {
* @param {ZenWorkspaceRecord} record - The workspace record to validate.
*/
ZenWorkspacesStore.prototype._validateRecord = function (record) {
if (!record.id || typeof record.id !== "string") {
throw new Error("Invalid workspace ID");
if (!record.id || typeof record.id !== 'string') {
throw new Error('Invalid workspace ID');
}
if (!record.name || typeof record.name !== "string") {
if (!record.name || typeof record.name !== 'string') {
throw new Error(`Invalid workspace name for ID ${record.id}`);
}
if (typeof record.default !== "boolean") {
if (typeof record.default !== 'boolean') {
record.default = false;
}
if (record.icon != null && typeof record.icon !== "string") {
if (record.icon != null && typeof record.icon !== 'string') {
throw new Error(`Invalid icon for workspace ID ${record.id}`);
}
if (record.containerTabId != null && typeof record.containerTabId !== "number") {
if (record.containerTabId != null && typeof record.containerTabId !== 'number') {
throw new Error(`Invalid containerTabId for workspace ID ${record.id}`);
}
if(record.position != null && typeof record.position !== "number") {
if (record.position != null && typeof record.position !== 'number') {
throw new Error(`Invalid position for workspace ID ${record.id}`);
}
// Validate theme properties if they exist
if (record.theme_type) {
if (typeof record.theme_type !== "string") {
if (typeof record.theme_type !== 'string') {
throw new Error(`Invalid theme_type for workspace ID ${record.id}`);
}
if (!record.theme_colors || typeof record.theme_colors !== "string") {
if (!record.theme_colors || typeof record.theme_colors !== 'string') {
throw new Error(`Invalid theme_colors for workspace ID ${record.id}`);
}
try {
@ -240,13 +240,13 @@ ZenWorkspacesStore.prototype._validateRecord = function (record) {
} catch (e) {
throw new Error(`Invalid theme_colors JSON for workspace ID ${record.id}`);
}
if (record.theme_opacity != null && typeof record.theme_opacity !== "number") {
if (record.theme_opacity != null && typeof record.theme_opacity !== 'number') {
throw new Error(`Invalid theme_opacity for workspace ID ${record.id}`);
}
if (record.theme_rotation != null && typeof record.theme_rotation !== "number") {
if (record.theme_rotation != null && typeof record.theme_rotation !== 'number') {
throw new Error(`Invalid theme_rotation for workspace ID ${record.id}`);
}
if (record.theme_texture != null && typeof record.theme_texture !== "number") {
if (record.theme_texture != null && typeof record.theme_texture !== 'number') {
throw new Error(`Invalid theme_texture for workspace ID ${record.id}`);
}
}
@ -260,7 +260,7 @@ ZenWorkspacesStore.prototype.getChangedIDs = async function () {
try {
return await ZenWorkspacesStorage.getChangedIDs();
} catch (error) {
this._log.error("Error retrieving changed IDs from storage", error);
this._log.error('Error retrieving changed IDs from storage', error);
throw error;
}
};
@ -272,7 +272,7 @@ ZenWorkspacesStore.prototype.clearChangedIDs = async function () {
try {
await ZenWorkspacesStorage.clearChangedIDs();
} catch (error) {
this._log.error("Error clearing changed IDs in storage", error);
this._log.error('Error clearing changed IDs in storage', error);
throw error;
}
};
@ -297,14 +297,13 @@ ZenWorkspacesStore.prototype.finalize = async function () {
await Store.prototype.finalize.call(this);
};
// Define ZenWorkspacesTracker
function ZenWorkspacesTracker(name, engine) {
Tracker.call(this, name, engine);
this._ignoreAll = false;
// Observe profile-before-change to stop the tracker gracefully
Services.obs.addObserver(this.asyncObserver, "profile-before-change");
Services.obs.addObserver(this.asyncObserver, 'profile-before-change');
}
ZenWorkspacesTracker.prototype = Object.create(Tracker.prototype);
@ -318,7 +317,7 @@ ZenWorkspacesTracker.prototype.getChangedIDs = async function () {
try {
return await this.engine._store.getChangedIDs();
} catch (error) {
this._log.error("Error retrieving changed IDs from store", error);
this._log.error('Error retrieving changed IDs from store', error);
throw error;
}
};
@ -330,7 +329,7 @@ ZenWorkspacesTracker.prototype.clearChangedIDs = async function () {
try {
await this.engine._store.clearChangedIDs();
} catch (error) {
this._log.error("Error clearing changed IDs in store", error);
this._log.error('Error clearing changed IDs in store', error);
throw error;
}
};
@ -342,11 +341,11 @@ ZenWorkspacesTracker.prototype.onStart = function () {
if (this._started) {
return;
}
this._log.trace("Starting tracker");
this._log.trace('Starting tracker');
// Register observers for workspace changes
Services.obs.addObserver(this.asyncObserver, "zen-workspace-added");
Services.obs.addObserver(this.asyncObserver, "zen-workspace-removed");
Services.obs.addObserver(this.asyncObserver, "zen-workspace-updated");
Services.obs.addObserver(this.asyncObserver, 'zen-workspace-added');
Services.obs.addObserver(this.asyncObserver, 'zen-workspace-removed');
Services.obs.addObserver(this.asyncObserver, 'zen-workspace-updated');
this._started = true;
};
@ -357,11 +356,11 @@ ZenWorkspacesTracker.prototype.onStop = function () {
if (!this._started) {
return;
}
this._log.trace("Stopping tracker");
this._log.trace('Stopping tracker');
// Unregister observers for workspace changes
Services.obs.removeObserver(this.asyncObserver, "zen-workspace-added");
Services.obs.removeObserver(this.asyncObserver, "zen-workspace-removed");
Services.obs.removeObserver(this.asyncObserver, "zen-workspace-updated");
Services.obs.removeObserver(this.asyncObserver, 'zen-workspace-added');
Services.obs.removeObserver(this.asyncObserver, 'zen-workspace-removed');
Services.obs.removeObserver(this.asyncObserver, 'zen-workspace-updated');
this._started = false;
};
@ -378,18 +377,18 @@ ZenWorkspacesTracker.prototype.observe = async function (subject, topic, data) {
try {
switch (topic) {
case "profile-before-change":
case 'profile-before-change':
await this.stop();
break;
case "zen-workspace-removed":
case "zen-workspace-updated":
case "zen-workspace-added":
case 'zen-workspace-removed':
case 'zen-workspace-updated':
case 'zen-workspace-added':
let workspaceIDs;
if (data) {
try {
workspaceIDs = JSON.parse(data);
if (!Array.isArray(workspaceIDs)) {
throw new Error("Parsed data is not an array");
throw new Error('Parsed data is not an array');
}
} catch (parseError) {
this._log.error(`Failed to parse workspace UUIDs from data: ${data}`, parseError);
@ -400,11 +399,11 @@ ZenWorkspacesTracker.prototype.observe = async function (subject, topic, data) {
return;
}
this._log.trace(`Observed ${topic} for UUIDs: ${workspaceIDs.join(", ")}`);
this._log.trace(`Observed ${topic} for UUIDs: ${workspaceIDs.join(', ')}`);
// Process each UUID
for (const workspaceID of workspaceIDs) {
if (typeof workspaceID === "string") {
if (typeof workspaceID === 'string') {
// Inform the store about the change
await this.engine._store.markChanged(workspaceID);
} else {
@ -430,10 +429,9 @@ ZenWorkspacesTracker.prototype.finalize = async function () {
await Tracker.prototype.finalize.call(this);
};
// Define ZenWorkspacesEngine
function ZenWorkspacesEngine(service) {
SyncEngine.call(this, "Workspaces", service);
SyncEngine.call(this, 'Workspaces', service);
}
ZenWorkspacesEngine.prototype = Object.create(SyncEngine.prototype);
@ -448,5 +446,3 @@ ZenWorkspacesEngine.prototype.syncPriority = 10;
ZenWorkspacesEngine.prototype.allowSkippedRecord = false;
Object.setPrototypeOf(ZenWorkspacesEngine.prototype, SyncEngine.prototype);

View file

@ -108,7 +108,7 @@ export class ZenGlanceChild extends JSWindowActorChild {
return;
} else if (activationMethod === 'meta' && !event.metaKey) {
return;
}else if (activationMethod === 'mantain' || typeof activationMethod === 'undefined') {
} else if (activationMethod === 'mantain' || typeof activationMethod === 'undefined') {
return;
}
// get closest A element

View file

@ -33,7 +33,7 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
id: meta.getAttribute('data-id'),
name: meta.getAttribute('data-name'),
author: meta.getAttribute('data-author'),
}
};
}
return null;
}
@ -94,13 +94,9 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
}
injectMarkplaceAPI() {
Cu.exportFunction(
this.installTheme.bind(this),
this.contentWindow,
{
defineAs: "ZenInstallTheme",
}
);
Cu.exportFunction(this.installTheme.bind(this), this.contentWindow, {
defineAs: 'ZenInstallTheme',
});
}
async addIntallButtons() {

View file

@ -1083,38 +1083,38 @@ Preferences.addAll([
default: false,
},
{
id: "zen.glance.activation-method",
type: "string",
default: "ctrl",
id: 'zen.glance.activation-method',
type: 'string',
default: 'ctrl',
},
{
id: "zen.glance.enabled",
type: "bool",
id: 'zen.glance.enabled',
type: 'bool',
default: true,
},
{
id: "zen.theme.color-prefs.use-workspace-colors",
type: "bool",
id: 'zen.theme.color-prefs.use-workspace-colors',
type: 'bool',
default: false,
},
{
id: "zen.view.compact.color-toolbar",
type: "bool",
id: 'zen.view.compact.color-toolbar',
type: 'bool',
default: true,
},
{
id: "zen.urlbar.behavior",
type: "string",
default: "float",
id: 'zen.urlbar.behavior',
type: 'string',
default: 'float',
},
{
id: "zen.view.compact.color-sidebar",
type: "bool",
id: 'zen.view.compact.color-sidebar',
type: 'bool',
default: true,
},
{
id: "zen.essentials.enabled",
type: "bool",
id: 'zen.essentials.enabled',
type: 'bool',
default: true,
},
{
@ -1123,18 +1123,18 @@ Preferences.addAll([
default: false,
},
{
id: "zen.tabs.show-newtab-vertical",
type: "bool",
id: 'zen.tabs.show-newtab-vertical',
type: 'bool',
default: true,
},
{
id: "zen.view.show-newtab-button-border-top",
type: "bool",
id: 'zen.view.show-newtab-button-border-top',
type: 'bool',
default: false,
},
{
id: "zen.view.show-newtab-button-top",
type: "bool",
id: 'zen.view.show-newtab-button-top',
type: 'bool',
default: true,
},
]);

View file

@ -53,8 +53,8 @@ body {
& button {
opacity: 0;
animation: fadeIn .5s ease-in-out forwards;
animation-delay: .8s;
animation: fadeIn 0.5s ease-in-out forwards;
animation-delay: 0.8s;
}
& button:nth-child(2) {
@ -258,7 +258,7 @@ input[type='checkbox'] {
.delay-animation,
.delay-animation-2 {
opacity: 0;
animation: fadeIn .5s ease-in-out forwards;
animation: fadeIn 0.5s ease-in-out forwards;
}
#importBrowser {
@ -345,7 +345,7 @@ input[type='checkbox'] {
#welcome {
& h1 {
animation-duration: .8s !important;
animation-duration: 0.8s !important;
}
}
@ -405,7 +405,8 @@ input[type='checkbox'] {
border: 3px solid light-dark(#000, #fff);
}
#welcome, #thanks {
#welcome,
#thanks {
justify-content: center;
}

View file

@ -259,7 +259,7 @@ groupbox h2 {
--zen-compact-mode-styles-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.1);
@media not (prefers-color-scheme: dark) {
--zen-compact-mode-styles-shadow: 0 0 .5px .5px rgba(0, 0, 0, 0.1);
--zen-compact-mode-styles-shadow: 0 0 0.5px 0.5px rgba(0, 0, 0, 0.1);
}
box-shadow: var(--zen-compact-mode-styles-shadow);
@ -644,5 +644,5 @@ groupbox h2 {
.sync-engine-workspaces .checkbox-icon,
.sync-engine-workspaces.sync-engine-image {
list-style-image: url("chrome://devtools/skin/images/tool-storage.svg");
list-style-image: url('chrome://devtools/skin/images/tool-storage.svg');
}

View file

@ -577,7 +577,6 @@
fill: white !important;
}
/* reload/stop animation */
#stop-reload-button[animate]
> #reload-button[displaystop]

View file

@ -47,9 +47,7 @@
}
},
"license": {
"ignoredFiles": [
".*\\.json"
],
"ignoredFiles": [".*\\.json"],
"licenseType": "MPL-2.0"
},
"updateHostname": "updates.zen-browser.app"