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

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

View file

@ -10,16 +10,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v2
- name: Check out repository
uses: actions/checkout@v2
- name: Fetch JSON Response
run: |
curl -s "https://hg.mozilla.org/releases/mozilla-release/json-tags" > rc-response.json
- name: Fetch JSON Response
run: |
curl -s "https://hg.mozilla.org/releases/mozilla-release/json-tags" > rc-response.json
- name: Check for any updates
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
DISCORD_PING_IDS: ${{ secrets.DISCORD_PING_IDS }}
run: |
python3 scripts/check-rc-response.py || true
- name: Check for any updates
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
DISCORD_PING_IDS: ${{ secrets.DISCORD_PING_IDS }}
run: |
python3 scripts/check-rc-response.py || true

View file

@ -10,56 +10,55 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
token: ${{ secrets.DEPLOY_KEY }}
- name: Checkout code
uses: actions/checkout@v2
with:
token: ${{ secrets.DEPLOY_KEY }}
- name: Get dates for last month
shell: bash
run: |
# Get the current date
current_date=$(date +'%Y-%m-%d')
- name: Get dates for last month
shell: bash
run: |
# Get the current date
current_date=$(date +'%Y-%m-%d')
# Calculate the previous month
previous_date=$(date -d "$current_date -1 month" +'%Y-%m-%d')
# Calculate the previous month
previous_date=$(date -d "$current_date -1 month" +'%Y-%m-%d')
# Extract the year and month from the previous date
previous_year=$(date -d "$previous_date" +'%Y')
previous_month=$(date -d "$previous_date" +'%m')
# Extract the year and month from the previous date
previous_year=$(date -d "$previous_date" +'%Y')
previous_month=$(date -d "$previous_date" +'%m')
# Calculate the first day of the previous month
first_day=$(date -d "$previous_year-$previous_month-01" +'%Y-%m-%d')
# Calculate the first day of the previous month
first_day=$(date -d "$previous_year-$previous_month-01" +'%Y-%m-%d')
# Calculate the last day of the previous month
last_day=$(date -d "$first_day +1 month -1 day" +'%Y-%m-%d')
# Calculate the last day of the previous month
last_day=$(date -d "$first_day +1 month -1 day" +'%Y-%m-%d')
echo "$first_day..$last_day"
echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
echo "last_month_year=$previous_year" >> "$GITHUB_ENV"
echo "$first_day..$last_day"
echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
echo "last_month_year=$previous_year" >> "$GITHUB_ENV"
- name: Run issue-metrics tool
uses: github/issue-metrics@v2
env:
GH_TOKEN: ${{ secrets.DEPLOY_KEY }}
HIDE_AUTHOR: true
HIDE_TIME_TO_ANSWER: true
SEARCH_QUERY: 'repo:zen-browser/desktop is:issue created:${{ env.last_month }}'
- name: Run issue-metrics tool
uses: github/issue-metrics@v2
env:
GH_TOKEN: ${{ secrets.DEPLOY_KEY }}
HIDE_AUTHOR: true
HIDE_TIME_TO_ANSWER: true
SEARCH_QUERY: 'repo:zen-browser/desktop is:issue created:${{ env.last_month }}'
- name: Move metrics to docs folder
run: |
mkdir -p docs/issue-metrics
rm -f docs/issue-metrics/${{ env.last_month_year }}_${{ env.last_month }}.md
mv issue_metrics.md docs/issue-metrics/${{ env.last_month_year }}_${{ env.last_month }}.md
- name: Move metrics to docs folder
run: |
mkdir -p docs/issue-metrics
rm -f docs/issue-metrics/${{ env.last_month_year }}_${{ env.last_month }}.md
mv issue_metrics.md docs/issue-metrics/${{ env.last_month_year }}_${{ env.last_month }}.md
- name: Remove metrisc JSON
run: |
rm -f issue_metrics.json
- name: Remove metrisc JSON
run: |
rm -f issue_metrics.json
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'Update monthly issue metrics'
commit_user_name: Zen Browser Robot
commit_user_email: zen-browser-auto@users.noreply.github.com
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'Update monthly issue metrics'
commit_user_name: Zen Browser Robot
commit_user_email: zen-browser-auto@users.noreply.github.com

View file

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

View file

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

View file

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

View file

@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -9,126 +9,124 @@
flex-direction: column !important;
}
& #navigator-toolbox {
display: flex !important;
flex-direction: row !important;
max-width: unset !important;
min-width: unset !important;
width: 100% !important;
padding: var(--zen-toolbox-padding) !important;
}
& #navigator-toolbox {
display: flex !important;
flex-direction: row !important;
max-width: unset !important;
min-width: unset !important;
width: 100% !important;
padding: var(--zen-toolbox-padding) !important;
}
#tabbrowser-tabs {
display: -webkit-box !important;
-webkit-box-orient: horizontal;
-webkit-box-pack: start;
max-width: 10000px !important;
display: -webkit-box !important;
-webkit-box-orient: horizontal;
-webkit-box-pack: start;
max-width: 10000px !important;
--tabstrip-min-height: calc(var(--tab-min-height) - 4 * var(--tab-block-margin));
--tab-min-height: 10px !important;
--tabstrip-min-height: calc(var(--tab-min-height) - 4 * var(--tab-block-margin));
--tab-min-height: 10px !important;
}
#vertical-pinned-tabs-container-separator {
display: none !important;
display: none !important;
}
#zen-essentials-container,
#vertical-pinned-tabs-container,
#tabbrowser-arrowscrollbox {
-webkit-box-flex: 1;
-webkit-box-flex: 1;
}
#vertical-pinned-tabs-container:empty {
-webkit-box-flex: 0 !important;
width: 0 !important;
padding: 0 !important;
margin: 0 !important;
border: none !important;
visibility: collapse !important;
-webkit-box-flex: 0 !important;
width: 0 !important;
padding: 0 !important;
margin: 0 !important;
border: none !important;
visibility: collapse !important;
}
#navigator-toolbox {
flex-direction: row !important;
align-items: center;
flex-direction: row !important;
align-items: center;
}
#titlebar {
flex-direction: row !important;
width: 100%;
height: 36px !important;
flex-direction: row !important;
width: 100%;
height: 36px !important;
}
#zen-essentials-container {
--tab-min-height: 36px !important;
display: flex !important;
flex-direction: row !important;
padding-inline-end: 0 !important;
--tab-min-height: 36px !important;
display: flex !important;
flex-direction: row !important;
padding-inline-end: 0 !important;
}
#vertical-pinned-tabs-container {
display: flex !important;
flex-direction: row !important;
padding-inline-end: 0 !important;
display: flex !important;
flex-direction: row !important;
padding-inline-end: 0 !important;
}
#zen-essentials-container .tabbrowser-tab {
width: 0% !important;
width: 0% !important;
}
#vertical-pinned-tabs-container .tabbrowser-tab {
width: 0% !important;
width: 0% !important;
}
.tabbrowser-tab[zen-glance-tab="true"] {
.tab-label-container {
display: none !important;
width: 0px !important;
max-width: 0px !important;
}
.tabbrowser-tab[zen-glance-tab='true'] {
.tab-label-container {
display: none !important;
width: 0px !important;
max-width: 0px !important;
}
}
#tabbrowser-arrowscrollbox {
display: flex !important;
max-width: -moz-available;
overflow: hidden !important;
display: flex !important;
max-width: -moz-available;
overflow: hidden !important;
}
#TabsToolbar {
flex-direction: row !important;
gap: 8px;
overflow: hidden !important;
display: flex !important;
flex-direction: row !important;
gap: 8px;
overflow: hidden !important;
display: flex !important;
}
#TabsToolbar-customization-target {
flex-direction: row !important;
flex-direction: row !important;
}
#tabbrowser-tabs[orient="vertical"] {
flex-direction: row !important;
#tabbrowser-tabs[orient='vertical'] {
flex-direction: row !important;
}
tabs {
flex-direction: row !important;
flex-direction: row !important;
}
#zen-essentials-container {
container-name: tab-container;
container-type: normal;
max-width: 36px !important;
flex: 1 1 36px !important;
container-name: tab-container;
container-type: normal;
max-width: 36px !important;
flex: 1 1 36px !important;
}
#vertical-pinned-tabs-container {
container-name: tab-container;
container-type: normal;
max-width: 36px !important;
min-width: 36px !important;
flex: 1 1 36px !important;
container-name: tab-container;
container-type: normal;
max-width: 36px !important;
min-width: 36px !important;
flex: 1 1 36px !important;
}
#vertical-pinned-tabs-container .tab-close-button {
display: none !important;
display: none !important;
}
#vertical-pinned-tabs-container .tab-reset-button {
@ -136,11 +134,11 @@
}
#vertical-pinned-tabs-container .tab-label-container {
display: none !important;
display: none !important;
}
#vertical-pinned-tabs-container .tab-icon-image {
margin: 0 !important;
margin: 0 !important;
}
.tabbrowser-tab {
@ -162,131 +160,131 @@
}
@container tab-container (max-width: 80px) {
.tab-close-button {
margin-right: 0px !important;
}
.tab-icon-image {
padding: 0 !important;
margin-left: min(2.5px, 5%) !important;
margin-right: min(10px, 5%) !important;
}
.tab-label-container,
.tab-content {
margin: 0 !important;
padding-left: min(8px, 5%) !important;
padding-right: min(8px, 5%) !important;
}
.tab-close-button {
margin-right: 0px !important;
}
.tab-icon-image {
padding: 0 !important;
margin-left: min(2.5px, 5%) !important;
margin-right: min(10px, 5%) !important;
}
.tab-label-container,
.tab-content {
margin: 0 !important;
padding-left: min(8px, 5%) !important;
padding-right: min(8px, 5%) !important;
}
}
@container tab-container (max-width: 44px) {
.tab-label-container {
display: none !important;
.tab-label-container {
display: none !important;
}
.tab-content {
justify-content: space-around !important;
}
.tab-close-button {
display: none !important;
}
.tabbrowser-tab[selected] {
& .tab-icon-image,
.tab-icon-stack {
display: none !important;
}
.tab-content {
justify-content: space-around !important;
& .tab-content {
justify-content: space-around !important;
padding: 0 !important;
}
.tab-close-button {
display: none !important;
}
.tabbrowser-tab[selected] {
& .tab-icon-image,
.tab-icon-stack {
display: none !important;
}
& .tab-content {
justify-content: space-around !important;
padding: 0 !important;
}
.tab-close-button {
display: block !important;
}
display: block !important;
}
}
}
#vertical-pinned-tabs-container::after {
z-index: -1;
content: "";
position: absolute;
right: 0;
width: 1px;
height: 45%;
top: 50%;
transform: translateY(-50%);
background: hsl(255, 10%, 100%);
z-index: -1;
content: '';
position: absolute;
right: 0;
width: 1px;
height: 45%;
top: 50%;
transform: translateY(-50%);
background: hsl(255, 10%, 100%);
}
/* Other UI Elements */
#zen-current-workspace-indicator {
display: none !important;
display: none !important;
}
#zen-sidebar-splitter {
display: none !important;
display: none !important;
}
#tabbrowser-tabpanels {
padding-left: var(--zen-element-separation) !important;
padding-left: var(--zen-element-separation) !important;
}
#appcontent * {
overflow: visible !important;
overflow: visible !important;
}
#TabsToolbar-customization-target::after {
display: none !important;
display: none !important;
}
#zen-sidebar-icons-wrapper {
width: auto !important;
padding: 0 !important;
width: auto !important;
padding: 0 !important;
}
/* Height Adjustments */
#vertical-pinned-tabs-container,
#zen-essentials-container,
#tabbrowser-arrowscrollbox {
max-height: none !important;
max-height: none !important;
}
#PanelUI-zen-gradient-generator {
min-width: 390px !important;
min-width: 390px !important;
}
#zen-essentials-container:not(:empty),
#vertical-pinned-tabs-container:not(:empty),
#tabbrowser-arrowscrollbox {
-webkit-box-flex: 1;
min-width: min-content;
width: auto !important;
-webkit-box-flex: 1;
min-width: min-content;
width: auto !important;
}
#vertical-pinned-tabs-container:not(:empty) {
display: -webkit-box !important;
-webkit-box-orient: horizontal;
min-width: fit-content !important;
width: fit-content !important;
position: relative;
margin-right: -1px !important;
display: -webkit-box !important;
-webkit-box-orient: horizontal;
min-width: fit-content !important;
width: fit-content !important;
position: relative;
margin-right: -1px !important;
}
#vertical-pinned-tabs-container:not(:empty) .tabbrowser-tab {
position: relative;
display: -webkit-box !important;
position: relative;
display: -webkit-box !important;
}
#tabbrowser-arrowscrollbox {
margin-left: 0 !important;
margin-left: 0 !important;
}
#vertical-pinned-tabs-container:empty,
#zen-essentials-container:empty {
-webkit-box-flex: 0 !important;
width: 0 !important;
min-width: 0 !important;
padding: 0 !important;
margin: 0 !important;
border: none !important;
visibility: collapse !important;
-webkit-box-flex: 0 !important;
width: 0 !important;
min-width: 0 !important;
padding: 0 !important;
margin: 0 !important;
border: none !important;
visibility: collapse !important;
}
#nav-bar {
@ -299,39 +297,39 @@
}
hbox#nav-bar-customization-target toolbarbutton.chromeclass-toolbar-additional:nth-of-type(1) {
padding-inline-start: var(--toolbar-start-end-padding) !important;
padding-inline-start: var(--toolbar-start-end-padding) !important;
}
toolbar#PersonalToolbar {
padding-left: 6px !important;
padding-left: 6px !important;
}
.tab-context-line {
width: 100% !important;
height: 3px !important;
width: 100% !important;
height: 3px !important;
}
.tabbrowser-tab[zen-glance-tab="true"] {
flex-basis: fit-content !important;
max-width: 36px !important;
.tabbrowser-tab[zen-glance-tab='true'] {
flex-basis: fit-content !important;
max-width: 36px !important;
}
#zen-essentials-container .tabbrowser-tab[zen-glance-tab="true"] {
left: 2px;
#zen-essentials-container .tabbrowser-tab[zen-glance-tab='true'] {
left: 2px;
}
#vertical-pinned-tabs-container .tabbrowser-tab[zen-glance-tab="true"] {
position: absolute !important;
#vertical-pinned-tabs-container .tabbrowser-tab[zen-glance-tab='true'] {
position: absolute !important;
}
#TabsToolbar-customization-target toolbarbutton,
#TabsToolbar-customization-target toolbarpaletteitem {
-webkit-box-flex: 0 !important;
min-width: min-content;
width: auto !important;
-webkit-box-flex: 0 !important;
min-width: min-content;
width: auto !important;
.toolbarbutton-text {
display: none !important;
}
.toolbarbutton-text {
display: none !important;
}
}
}

View file

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

View file

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

View file

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

View file

@ -266,7 +266,6 @@
}
}
/* Workspace icon picker styles */
#PanelUI-zen-workspaces-icon-picker-wrapper {
display: flex;
@ -391,7 +390,6 @@
background-color: var(--toolbarbutton-icon-fill-attention);
}
#PanelUI-zen-workspaces-reorder-mode[active='true'] {
color: var(--toolbarbutton-icon-fill-attention) !important;
}
@ -476,7 +474,7 @@
max-width: calc(100% - var(--zen-toolbox-padding) * 4);
}
& #zen-current-workspace-indicator-icon:not([hidden]) + #zen-current-workspace-indicator-name {
& #zen-current-workspace-indicator-icon:not([hidden]) + #zen-current-workspace-indicator-name {
padding-left: 24px;
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -24,7 +24,6 @@ var ZenPinnedTabsStorage = {
)
`);
// Create indices
await db.execute(`
CREATE INDEX IF NOT EXISTS idx_zen_pins_uuid ON zen_pins(uuid)
@ -75,17 +74,21 @@ var ZenPinnedTabsStorage = {
newPosition = pin.position;
} else {
// Get the maximum position within the same parent group (or null for root level)
const maxPositionResult = await db.execute(`
const maxPositionResult = await db.execute(
`
SELECT MAX("position") as max_position
FROM zen_pins
WHERE COALESCE(parent_uuid, '') = COALESCE(:parent_uuid, '')
`, { parent_uuid: pin.parentUuid || null });
`,
{ parent_uuid: pin.parentUuid || null }
);
const maxPosition = maxPositionResult[0].getResultByName('max_position') || 0;
newPosition = maxPosition + 1000;
}
// Insert or replace the pin
await db.executeCached(`
await db.executeCached(
`
INSERT OR REPLACE INTO zen_pins (
uuid, title, url, container_id, workspace_uuid, position,
is_essential, is_group, parent_uuid, created_at, updated_at
@ -95,26 +98,31 @@ 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,
container_id: pin.containerTabId || null,
workspace_uuid: pin.workspaceUuid || null,
position: newPosition,
is_essential: pin.isEssential || false,
is_group: pin.isGroup || false,
parent_uuid: pin.parentUuid || null,
now
});
`,
{
uuid: pin.uuid,
title: pin.title,
url: pin.isGroup ? null : pin.url,
container_id: pin.containerTabId || null,
workspace_uuid: pin.workspaceUuid || null,
position: newPosition,
is_essential: pin.isEssential || false,
is_group: pin.isGroup || false,
parent_uuid: pin.parentUuid || null,
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)
});
`,
{
uuid: pin.uuid,
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
});
`,
{
uuid: changedUuid,
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)
});
`,
{
uuid,
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)
});
`,
{
uuid: pin.uuid,
timestamp: Math.floor(now / 1000),
}
);
}
await this.updateLastChangeTimestamp(db);
});
});
this._notifyPinsChanged("zen-pin-updated", Array.from(changedUUIDs));
this._notifyPinsChanged('zen-pin-updated', Array.from(changedUUIDs));
},
async __dropTables() {
@ -334,7 +354,7 @@ var ZenPinnedTabsStorage = {
await db.execute(`DROP TABLE IF EXISTS zen_pins`);
await db.execute(`DROP TABLE IF EXISTS zen_pins_changes`);
});
}
},
};
ZenPinnedTabsStorage.init();

View file

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

View file

@ -303,7 +303,7 @@ class ZenBrowserManagerSidebar extends ZenDOMOperatedFeature {
// Don't reload content if at least one of the panel tabs was loaded
if (this._lastOpenedPanel) {
return;
return;
}
let data = this.sidebarData;

View file

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

View file

@ -303,15 +303,15 @@ var gZenThemesImporter = new (class {
}
})();
gZenActorsManager.addJSWindowActor("ZenThemeMarketplace", {
gZenActorsManager.addJSWindowActor('ZenThemeMarketplace', {
parent: {
esModuleURI: "chrome://browser/content/zen-components/actors/ZenThemeMarketplaceParent.sys.mjs",
esModuleURI: 'chrome://browser/content/zen-components/actors/ZenThemeMarketplaceParent.sys.mjs',
},
child: {
esModuleURI: "chrome://browser/content/zen-components/actors/ZenThemeMarketplaceChild.sys.mjs",
esModuleURI: 'chrome://browser/content/zen-components/actors/ZenThemeMarketplaceChild.sys.mjs',
events: {
DOMContentLoaded: {},
},
},
matches: [...Services.prefs.getStringPref("zen.injections.match-urls").split(","), "about:preferences"],
matches: [...Services.prefs.getStringPref('zen.injections.match-urls').split(','), 'about:preferences'],
});

View file

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

View file

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

View file

@ -3,8 +3,8 @@ var ZenWorkspacesStorage = {
async init() {
ChromeUtils.defineESModuleGetters(this.lazy, {
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
Weave: "resource://services-sync/main.sys.mjs",
PlacesUtils: 'resource://gre/modules/PlacesUtils.sys.mjs',
Weave: 'resource://services-sync/main.sys.mjs',
});
await this._ensureTable();
@ -32,7 +32,7 @@ var ZenWorkspacesStorage = {
// SQLite doesn't have a direct "ADD COLUMN IF NOT EXISTS" syntax,
// so we need to check if the columns exist first
const columns = await db.execute(`PRAGMA table_info(zen_workspaces)`);
const columnNames = columns.map(row => row.getResultByName('name'));
const columnNames = columns.map((row) => row.getResultByName('name'));
// Helper function to add column if it doesn't exist
const addColumnIfNotExists = async (columnName, definition) => {
@ -111,7 +111,9 @@ var ZenWorkspacesStorage = {
// Handle default workspace
if (workspace.default) {
await db.execute(`UPDATE zen_workspaces SET is_default = 0 WHERE uuid != :uuid`, { uuid: workspace.uuid });
const unsetDefaultRows = await db.execute(`SELECT uuid FROM zen_workspaces WHERE is_default = 0 AND uuid != :uuid`, { uuid: workspace.uuid });
const unsetDefaultRows = await db.execute(`SELECT uuid FROM zen_workspaces WHERE is_default = 0 AND uuid != :uuid`, {
uuid: workspace.uuid,
});
for (const row of unsetDefaultRows) {
changedUUIDs.add(row.getResultByName('uuid'));
}
@ -128,7 +130,8 @@ var ZenWorkspacesStorage = {
}
// Insert or replace the workspace
await db.executeCached(`
await db.executeCached(
`
INSERT OR REPLACE INTO zen_workspaces (
uuid, name, icon, is_default, container_id, created_at, updated_at, "position",
theme_type, theme_colors, theme_opacity, theme_rotation, theme_texture
@ -139,29 +142,34 @@ var ZenWorkspacesStorage = {
:position,
:theme_type, :theme_colors, :theme_opacity, :theme_rotation, :theme_texture
)
`, {
uuid: workspace.uuid,
name: workspace.name,
icon: workspace.icon || null,
is_default: workspace.default ? 1 : 0,
container_id: workspace.containerTabId || null,
now,
position: newPosition,
theme_type: workspace.theme?.type || null,
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
});
`,
{
uuid: workspace.uuid,
name: workspace.name,
icon: workspace.icon || null,
is_default: workspace.default ? 1 : 0,
container_id: workspace.containerTabId || null,
now,
position: newPosition,
theme_type: workspace.theme?.type || null,
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,
}
);
// 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)
});
`,
{
uuid: workspace.uuid,
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') ? {
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
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,
}));
},
@ -201,27 +211,30 @@ var ZenWorkspacesStorage = {
await this.lazy.PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.removeWorkspace', async (db) => {
await db.execute(
`
`
DELETE FROM zen_workspaces WHERE uuid = :uuid
`,
{ uuid }
{ uuid }
);
// 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)
});
`,
{
uuid,
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)
});
`,
{
uuid,
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)
});
`,
{
uuid,
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
});
`,
{
type: theme.type,
colors: JSON.stringify(theme.gradientColors),
opacity: theme.opacity,
rotation: theme.rotation,
texture: theme.texture,
now: Date.now(),
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)
});
`,
{
uuid: workspace.uuid,
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 db.execute(`DELETE FROM zen_bookmarks_workspaces_changes`);
});
await ZenWorkspacesStorage.lazy.PlacesUtils.withConnectionWrapper(
'ZenWorkspaceBookmarksStorage.clearChangedIDs',
async (db) => {
await db.execute(`DELETE FROM zen_bookmarks_workspaces_changes`);
}
);
},
};
ZenWorkspacesStorage.init();

View file

@ -1,36 +1,34 @@
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) {
CryptoWrapper.call(this, collection, id);
CryptoWrapper.call(this, 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
function ZenWorkspacesStore(name, engine) {
Store.call(this, name, engine);
Store.call(this, name, engine);
}
ZenWorkspacesStore.prototype = Object.create(Store.prototype);
@ -40,8 +38,8 @@ ZenWorkspacesStore.prototype.constructor = ZenWorkspacesStore;
* Initializes the store by loading the current changeset.
*/
ZenWorkspacesStore.prototype.initialize = async function () {
await Store.prototype.initialize.call(this);
// Additional initialization if needed
await Store.prototype.initialize.call(this);
// Additional initialization if needed
};
/**
@ -49,17 +47,17 @@ ZenWorkspacesStore.prototype.initialize = async function () {
* @returns {Object} An object mapping workspace UUIDs to true.
*/
ZenWorkspacesStore.prototype.getAllIDs = async function () {
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
const ids = {};
for (const workspace of workspaces) {
ids[workspace.uuid] = true;
}
return ids;
} catch (error) {
this._log.error("Error fetching all workspace IDs", error);
throw error;
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
const ids = {};
for (const workspace of workspaces) {
ids[workspace.uuid] = true;
}
return ids;
} catch (error) {
this._log.error('Error fetching all workspace IDs', error);
throw error;
}
};
/**
@ -68,19 +66,19 @@ ZenWorkspacesStore.prototype.getAllIDs = async function () {
* @param {String} newID - The new UUID.
*/
ZenWorkspacesStore.prototype.changeItemID = async function (oldID, newID) {
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
const workspace = workspaces.find(ws => ws.uuid === oldID);
if (workspace) {
workspace.uuid = newID;
await ZenWorkspacesStorage.saveWorkspace(workspace,false);
// Mark the new ID as changed for sync
await ZenWorkspacesStorage.markChanged(newID);
}
} catch (error) {
this._log.error(`Error changing workspace ID from ${oldID} to ${newID}`, error);
throw error;
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
const workspace = workspaces.find((ws) => ws.uuid === oldID);
if (workspace) {
workspace.uuid = newID;
await ZenWorkspacesStorage.saveWorkspace(workspace, false);
// Mark the new ID as changed for sync
await ZenWorkspacesStorage.markChanged(newID);
}
} catch (error) {
this._log.error(`Error changing workspace ID from ${oldID} to ${newID}`, error);
throw error;
}
};
/**
@ -89,13 +87,13 @@ ZenWorkspacesStore.prototype.changeItemID = async function (oldID, newID) {
* @returns {Boolean} True if the workspace exists, false otherwise.
*/
ZenWorkspacesStore.prototype.itemExists = async function (id) {
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
return workspaces.some(ws => ws.uuid === id);
} catch (error) {
this._log.error(`Error checking if workspace exists with ID ${id}`, error);
throw error;
}
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
return workspaces.some((ws) => ws.uuid === id);
} catch (error) {
this._log.error(`Error checking if workspace exists with ID ${id}`, error);
throw error;
}
};
/**
@ -105,34 +103,34 @@ ZenWorkspacesStore.prototype.itemExists = async function (id) {
* @returns {ZenWorkspaceRecord} The workspace record.
*/
ZenWorkspacesStore.prototype.createRecord = async function (id, collection) {
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
const workspace = workspaces.find(ws => ws.uuid === id);
const record = new ZenWorkspaceRecord(collection, id);
try {
const workspaces = await ZenWorkspacesStorage.getWorkspaces();
const workspace = workspaces.find((ws) => ws.uuid === id);
const record = new ZenWorkspaceRecord(collection, id);
if (workspace) {
record.name = workspace.name;
record.icon = workspace.icon;
record.default = workspace.default;
record.containerTabId = workspace.containerTabId;
record.position = workspace.position;
if (workspace.theme) {
record.theme_type = workspace.theme.type;
record.theme_colors = JSON.stringify(workspace.theme.gradientColors);
record.theme_opacity = workspace.theme.opacity;
record.theme_rotation = workspace.theme.rotation;
record.theme_texture = workspace.theme.texture;
}
record.deleted = false;
} else {
record.deleted = true;
}
return record;
} catch (error) {
this._log.error(`Error creating record for workspace ID ${id}`, error);
throw error;
if (workspace) {
record.name = workspace.name;
record.icon = workspace.icon;
record.default = workspace.default;
record.containerTabId = workspace.containerTabId;
record.position = workspace.position;
if (workspace.theme) {
record.theme_type = workspace.theme.type;
record.theme_colors = JSON.stringify(workspace.theme.gradientColors);
record.theme_opacity = workspace.theme.opacity;
record.theme_rotation = workspace.theme.rotation;
record.theme_texture = workspace.theme.texture;
}
record.deleted = false;
} else {
record.deleted = true;
}
return record;
} catch (error) {
this._log.error(`Error creating record for workspace ID ${id}`, error);
throw error;
}
};
/**
@ -140,28 +138,30 @@ ZenWorkspacesStore.prototype.createRecord = async function (id, collection) {
* @param {ZenWorkspaceRecord} record - The workspace record to create.
*/
ZenWorkspacesStore.prototype.create = async function (record) {
try {
this._validateRecord(record);
const workspace = {
uuid: record.id,
name: record.name,
icon: record.icon,
default: record.default,
containerTabId: record.containerTabId,
position: record.position,
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
};
await ZenWorkspacesStorage.saveWorkspace(workspace,false);
} catch (error) {
this._log.error(`Error creating workspace with ID ${record.id}`, error);
throw error;
}
try {
this._validateRecord(record);
const workspace = {
uuid: record.id,
name: record.name,
icon: record.icon,
default: record.default,
containerTabId: record.containerTabId,
position: record.position,
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,
};
await ZenWorkspacesStorage.saveWorkspace(workspace, false);
} catch (error) {
this._log.error(`Error creating workspace with ID ${record.id}`, error);
throw error;
}
};
/**
@ -169,13 +169,13 @@ ZenWorkspacesStore.prototype.create = async function (record) {
* @param {ZenWorkspaceRecord} record - The workspace record to update.
*/
ZenWorkspacesStore.prototype.update = async function (record) {
try {
this._validateRecord(record);
await this.create(record); // Reuse create for update
} catch (error) {
this._log.error(`Error updating workspace with ID ${record.id}`, error);
throw error;
}
try {
this._validateRecord(record);
await this.create(record); // Reuse create for update
} catch (error) {
this._log.error(`Error updating workspace with ID ${record.id}`, error);
throw error;
}
};
/**
@ -183,24 +183,24 @@ ZenWorkspacesStore.prototype.update = async function (record) {
* @param {ZenWorkspaceRecord} record - The workspace record to remove.
*/
ZenWorkspacesStore.prototype.remove = async function (record) {
try {
await ZenWorkspacesStorage.removeWorkspace(record.id, false);
} catch (error) {
this._log.error(`Error removing workspace with ID ${record.id}`, error);
throw error;
}
try {
await ZenWorkspacesStorage.removeWorkspace(record.id, false);
} catch (error) {
this._log.error(`Error removing workspace with ID ${record.id}`, error);
throw error;
}
};
/**
* Wipes all workspaces from the storage.
*/
ZenWorkspacesStore.prototype.wipe = async function () {
try {
await ZenWorkspacesStorage.wipeAllWorkspaces();
} catch (error) {
this._log.error("Error wiping all workspaces", error);
throw error;
}
try {
await ZenWorkspacesStorage.wipeAllWorkspaces();
} catch (error) {
this._log.error('Error wiping all workspaces', error);
throw error;
}
};
/**
@ -208,48 +208,48 @@ 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.name || typeof record.name !== "string") {
throw new Error(`Invalid workspace name for ID ${record.id}`);
}
if (typeof record.default !== "boolean") {
record.default = false;
}
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") {
throw new Error(`Invalid containerTabId for workspace ID ${record.id}`);
}
if(record.position != null && typeof record.position !== "number") {
throw new Error(`Invalid position for workspace ID ${record.id}`);
}
if (!record.id || typeof record.id !== 'string') {
throw new Error('Invalid workspace ID');
}
if (!record.name || typeof record.name !== 'string') {
throw new Error(`Invalid workspace name for ID ${record.id}`);
}
if (typeof record.default !== 'boolean') {
record.default = false;
}
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') {
throw new Error(`Invalid containerTabId for workspace ID ${record.id}`);
}
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") {
throw new Error(`Invalid theme_type for workspace ID ${record.id}`);
}
if (!record.theme_colors || typeof record.theme_colors !== "string") {
throw new Error(`Invalid theme_colors for workspace ID ${record.id}`);
}
try {
JSON.parse(record.theme_colors);
} catch (e) {
throw new Error(`Invalid theme_colors JSON for workspace ID ${record.id}`);
}
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") {
throw new Error(`Invalid theme_rotation for workspace ID ${record.id}`);
}
if (record.theme_texture != null && typeof record.theme_texture !== "number") {
throw new Error(`Invalid theme_texture for workspace ID ${record.id}`);
}
// Validate theme properties if they exist
if (record.theme_type) {
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') {
throw new Error(`Invalid theme_colors for workspace ID ${record.id}`);
}
try {
JSON.parse(record.theme_colors);
} catch (e) {
throw new Error(`Invalid theme_colors JSON for workspace ID ${record.id}`);
}
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') {
throw new Error(`Invalid theme_rotation for workspace ID ${record.id}`);
}
if (record.theme_texture != null && typeof record.theme_texture !== 'number') {
throw new Error(`Invalid theme_texture for workspace ID ${record.id}`);
}
}
};
/**
@ -257,24 +257,24 @@ ZenWorkspacesStore.prototype._validateRecord = function (record) {
* @returns {Object} An object mapping workspace UUIDs to their change timestamps.
*/
ZenWorkspacesStore.prototype.getChangedIDs = async function () {
try {
return await ZenWorkspacesStorage.getChangedIDs();
} catch (error) {
this._log.error("Error retrieving changed IDs from storage", error);
throw error;
}
try {
return await ZenWorkspacesStorage.getChangedIDs();
} catch (error) {
this._log.error('Error retrieving changed IDs from storage', error);
throw error;
}
};
/**
* Clears all recorded changes after a successful sync.
*/
ZenWorkspacesStore.prototype.clearChangedIDs = async function () {
try {
await ZenWorkspacesStorage.clearChangedIDs();
} catch (error) {
this._log.error("Error clearing changed IDs in storage", error);
throw error;
}
try {
await ZenWorkspacesStorage.clearChangedIDs();
} catch (error) {
this._log.error('Error clearing changed IDs in storage', error);
throw error;
}
};
/**
@ -282,29 +282,28 @@ ZenWorkspacesStore.prototype.clearChangedIDs = async function () {
* @param {String} uuid - The UUID of the workspace that changed.
*/
ZenWorkspacesStore.prototype.markChanged = async function (uuid) {
try {
await ZenWorkspacesStorage.markChanged(uuid);
} catch (error) {
this._log.error(`Error marking workspace ${uuid} as changed`, error);
throw error;
}
try {
await ZenWorkspacesStorage.markChanged(uuid);
} catch (error) {
this._log.error(`Error marking workspace ${uuid} as changed`, error);
throw error;
}
};
/**
* Finalizes the store by ensuring all pending operations are completed.
*/
ZenWorkspacesStore.prototype.finalize = async function () {
await Store.prototype.finalize.call(this);
await Store.prototype.finalize.call(this);
};
// Define ZenWorkspacesTracker
function ZenWorkspacesTracker(name, engine) {
Tracker.call(this, name, engine);
this._ignoreAll = false;
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");
// Observe profile-before-change to stop the tracker gracefully
Services.obs.addObserver(this.asyncObserver, 'profile-before-change');
}
ZenWorkspacesTracker.prototype = Object.create(Tracker.prototype);
@ -315,54 +314,54 @@ ZenWorkspacesTracker.prototype.constructor = ZenWorkspacesTracker;
* @returns {Object} An object mapping workspace UUIDs to their change timestamps.
*/
ZenWorkspacesTracker.prototype.getChangedIDs = async function () {
try {
return await this.engine._store.getChangedIDs();
} catch (error) {
this._log.error("Error retrieving changed IDs from store", error);
throw error;
}
try {
return await this.engine._store.getChangedIDs();
} catch (error) {
this._log.error('Error retrieving changed IDs from store', error);
throw error;
}
};
/**
* Clears all recorded changes after a successful sync.
*/
ZenWorkspacesTracker.prototype.clearChangedIDs = async function () {
try {
await this.engine._store.clearChangedIDs();
} catch (error) {
this._log.error("Error clearing changed IDs in store", error);
throw error;
}
try {
await this.engine._store.clearChangedIDs();
} catch (error) {
this._log.error('Error clearing changed IDs in store', error);
throw error;
}
};
/**
* Called when the tracker starts. Registers observers to listen for workspace changes.
*/
ZenWorkspacesTracker.prototype.onStart = function () {
if (this._started) {
return;
}
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");
this._started = true;
if (this._started) {
return;
}
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');
this._started = true;
};
/**
* Called when the tracker stops. Unregisters observers.
*/
ZenWorkspacesTracker.prototype.onStop = function () {
if (!this._started) {
return;
}
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");
this._started = false;
if (!this._started) {
return;
}
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');
this._started = false;
};
/**
@ -372,68 +371,67 @@ ZenWorkspacesTracker.prototype.onStop = function () {
* @param {String} data - Additional data (JSON stringified array of UUIDs).
*/
ZenWorkspacesTracker.prototype.observe = async function (subject, topic, data) {
if (this.ignoreAll) {
return;
}
if (this.ignoreAll) {
return;
}
try {
switch (topic) {
case "profile-before-change":
await this.stop();
break;
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");
}
} catch (parseError) {
this._log.error(`Failed to parse workspace UUIDs from data: ${data}`, parseError);
return;
}
} else {
this._log.error(`No data received for event ${topic}`);
return;
}
this._log.trace(`Observed ${topic} for UUIDs: ${workspaceIDs.join(", ")}`);
// Process each UUID
for (const workspaceID of workspaceIDs) {
if (typeof workspaceID === "string") {
// Inform the store about the change
await this.engine._store.markChanged(workspaceID);
} else {
this._log.warn(`Invalid workspace ID encountered: ${workspaceID}`);
}
}
// Bump the score once after processing all changes
if (workspaceIDs.length > 0) {
this.score += SCORE_INCREMENT_XLARGE;
}
break;
try {
switch (topic) {
case 'profile-before-change':
await this.stop();
break;
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');
}
} catch (parseError) {
this._log.error(`Failed to parse workspace UUIDs from data: ${data}`, parseError);
return;
}
} else {
this._log.error(`No data received for event ${topic}`);
return;
}
} catch (error) {
this._log.error(`Error handling ${topic} in observe method`, error);
this._log.trace(`Observed ${topic} for UUIDs: ${workspaceIDs.join(', ')}`);
// Process each UUID
for (const workspaceID of workspaceIDs) {
if (typeof workspaceID === 'string') {
// Inform the store about the change
await this.engine._store.markChanged(workspaceID);
} else {
this._log.warn(`Invalid workspace ID encountered: ${workspaceID}`);
}
}
// Bump the score once after processing all changes
if (workspaceIDs.length > 0) {
this.score += SCORE_INCREMENT_XLARGE;
}
break;
}
} catch (error) {
this._log.error(`Error handling ${topic} in observe method`, error);
}
};
/**
* Finalizes the tracker by ensuring all pending operations are completed.
*/
ZenWorkspacesTracker.prototype.finalize = async function () {
await Tracker.prototype.finalize.call(this);
await Tracker.prototype.finalize.call(this);
};
// Define ZenWorkspacesEngine
function ZenWorkspacesEngine(service) {
SyncEngine.call(this, "Workspaces", service);
SyncEngine.call(this, 'Workspaces', service);
}
ZenWorkspacesEngine.prototype = Object.create(SyncEngine.prototype);
@ -448,5 +446,3 @@ ZenWorkspacesEngine.prototype.syncPriority = 10;
ZenWorkspacesEngine.prototype.allowSkippedRecord = false;
Object.setPrototypeOf(ZenWorkspacesEngine.prototype, SyncEngine.prototype);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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