forked from ZenBrowserMirrors/zen-desktop
Refactor CSS and JavaScript files for consistency; clean up whitespace and formatting
This commit is contained in:
parent
22515592f0
commit
7dfa6d55ba
56 changed files with 1607 additions and 1515 deletions
1
.github/workflows/issue-metrics.yml
vendored
1
.github/workflows/issue-metrics.yml
vendored
|
@ -10,7 +10,6 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -28,4 +28,3 @@ jobs:
|
|||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
|
|
2
.github/workflows/update-submodules.yml
vendored
2
.github/workflows/update-submodules.yml
vendored
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
[](https://crowdin.com/project/zen-browser)
|
||||
[](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`.
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
# Branch Structure
|
||||
|
||||
The repository is structured as follows:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -60,7 +61,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
#tabbrowser-tabpanels:has(> [zen-split='true']), #zen-splitview-overlay {
|
||||
#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);
|
||||
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'] {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
.printSettingsBrowser {
|
||||
min-width: 350px;
|
||||
}
|
||||
|
|
|
@ -341,6 +341,6 @@ menuitem {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
#editBMPanel_workspaceList input[type="checkbox"] {
|
||||
#editBMPanel_workspaceList input[type='checkbox'] {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
body > #confetti {
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
& > * {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -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}`);
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
@ -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 });
|
||||
|
@ -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: {},
|
||||
},
|
||||
|
|
|
@ -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,7 +203,7 @@
|
|||
// 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 };
|
||||
|
@ -209,7 +212,7 @@
|
|||
// 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);
|
||||
const y = Math.floor(pixel / 4 / this.canvas.width);
|
||||
return { x: x / this.canvas.width, y: y / this.canvas.height };
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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={};
|
||||
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;
|
||||
([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
|
||||
(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]:"");
|
||||
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)
|
||||
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,10 +755,9 @@
|
|||
}
|
||||
|
||||
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;
|
||||
|
@ -743,7 +771,7 @@
|
|||
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();
|
||||
}
|
||||
|
||||
|
@ -754,7 +782,6 @@
|
|||
if (this.updated) {
|
||||
await this.updateCurrentWorkspace(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 }
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
|
@ -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) {
|
||||
// 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");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -454,7 +463,7 @@
|
|||
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");
|
||||
tab.removeAttribute('zen-essential');
|
||||
if (ZenWorkspaces.workspaceEnabled && ZenWorkspaces.getActiveWorkspaceFromCache.uuid) {
|
||||
tab.setAttribute("zen-workspace-id", 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
[]
|
||||
|
|
|
@ -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'],
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
@ -188,26 +180,26 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
|||
* @private
|
||||
*/
|
||||
_removeNodeSplitters(node, recursive) {
|
||||
this.getSplitters(node)?.forEach(s => s.remove());
|
||||
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();
|
||||
|
@ -371,23 +354,22 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
|||
if (hoverSide !== 'center') {
|
||||
const isVertical = hoverSide === 'top' || hoverSide === 'bottom';
|
||||
const browserSize = 100 - (isVertical ? posToRoot.top + posToRoot.bottom : posToRoot.right + posToRoot.left);
|
||||
const 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);
|
||||
|
@ -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;
|
||||
|
@ -951,16 +942,20 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
|||
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.
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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,7 +525,7 @@ 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() {
|
||||
|
@ -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);
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,7 +68,7 @@ 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);
|
||||
|
@ -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,13 +147,15 @@ 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);
|
||||
} catch (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);
|
||||
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
]);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -577,7 +577,6 @@
|
|||
fill: white !important;
|
||||
}
|
||||
|
||||
|
||||
/* reload/stop animation */
|
||||
#stop-reload-button[animate]
|
||||
> #reload-button[displaystop]
|
||||
|
|
|
@ -47,9 +47,7 @@
|
|||
}
|
||||
},
|
||||
"license": {
|
||||
"ignoredFiles": [
|
||||
".*\\.json"
|
||||
],
|
||||
"ignoredFiles": [".*\\.json"],
|
||||
"licenseType": "MPL-2.0"
|
||||
},
|
||||
"updateHostname": "updates.zen-browser.app"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue