mirror of
https://github.com/zen-browser/desktop.git
synced 2025-07-08 00:10:00 +02:00
Refactor CSS and JavaScript files for consistency; clean up whitespace and formatting
This commit is contained in:
parent
22515592f0
commit
7dfa6d55ba
56 changed files with 1607 additions and 1515 deletions
22
.github/workflows/check-candidate-release.yml
vendored
22
.github/workflows/check-candidate-release.yml
vendored
|
@ -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
|
||||
|
|
4
.github/workflows/clear-cache.yml
vendored
4
.github/workflows/clear-cache.yml
vendored
|
@ -20,7 +20,7 @@ jobs:
|
|||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
|
||||
|
||||
for (const cache of caches.data.actions_caches) {
|
||||
console.log(cache)
|
||||
await github.rest.actions.deleteActionsCacheById({
|
||||
|
@ -29,5 +29,5 @@ jobs:
|
|||
cache_id: cache.id,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
console.log("Clear completed")
|
||||
|
|
85
.github/workflows/issue-metrics.yml
vendored
85
.github/workflows/issue-metrics.yml
vendored
|
@ -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
|
||||
|
|
|
@ -28,4 +28,3 @@ jobs:
|
|||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
|
|
4
.github/workflows/update-submodules.yml
vendored
4
.github/workflows/update-submodules.yml
vendored
|
@ -11,7 +11,7 @@ jobs:
|
|||
update-submodules:
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
@ -26,6 +26,6 @@ jobs:
|
|||
- name: Commit
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "[skip ci] 📦 Update submodules"
|
||||
commit_message: '[skip ci] 📦 Update submodules'
|
||||
commit_user_name: Zen Browser Robot
|
||||
commit_user_email: zen-browser-auto@users.noreply.github.com
|
||||
|
|
|
@ -3,6 +3,7 @@ engine/
|
|||
**/*.html
|
||||
**/*.xhtml
|
||||
**/*.inc.xhtml
|
||||
**/*.bundle.min.js
|
||||
|
||||
**/*.svg
|
||||
|
||||
|
@ -11,5 +12,9 @@ pnpm-lock.yaml
|
|||
|
||||
**/engine/
|
||||
|
||||
docs/issue-metrics/*.md
|
||||
|
||||
# Some CSS files are preprocessed and prettier doesn't handle them well
|
||||
# We also dont want to format the CSS files that are generated by the build
|
||||
src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css
|
||||
src/browser/base/zen-components/ZenEmojies.mjs
|
||||
|
|
|
@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
|
|||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
- Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
- The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
@ -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
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
[](https://crowdin.com/project/zen-browser)
|
||||
[](https://github.com/zen-browser/desktop/actions/workflows/build.yml)
|
||||
|
||||
|
||||
✨ Experience tranquillity while browsing the web without people tracking you! Zen is a privacy-focused browser that blocks trackers, ads, and other unwanted content while offering the best browsing experience!
|
||||
|
||||
<div flex="true">
|
||||
|
@ -53,7 +52,7 @@ Zen uses [Semantic Versioning](https://semver.org/) for versioning. Meaning, ver
|
|||
|
||||
### Branches
|
||||
|
||||
Zen is divided into 2 main branches. We use `dev` for development and `stable` for stable releases. The `dev` branch is where all the new features are added and where `twilight` builds are generated. The `stable` branch is where the stable releases are generated.
|
||||
Zen is divided into 2 main branches. We use `dev` for development and `stable` for stable releases. The `dev` branch is where all the new features are added and where `twilight` builds are generated. The `stable` branch is where the stable releases are generated.
|
||||
|
||||
We divide into 2 branches in case there's any really important security update (for example) that needs to be released before the next stable release. This allows us to do patches without releasing unstable versions to the public.
|
||||
|
||||
|
@ -99,7 +98,7 @@ yay -S zen-browser-bin
|
|||
##### Other Linux distributions (AppImage with automated system integration)
|
||||
|
||||
- `native` tarball install:
|
||||
```bash <(curl -s https://updates.zen-browser.app/install.sh)```
|
||||
`bash <(curl -s https://updates.zen-browser.app/install.sh)`
|
||||
|
||||
- `zsync` is required for the Update feature of the script below
|
||||
|
||||
|
@ -107,7 +106,7 @@ yay -S zen-browser-bin
|
|||
bash <(curl https://updates.zen-browser.app/appimage.sh)
|
||||
```
|
||||
|
||||
* Again, if you don't see your OS listed above, that's because we already have it in our [downloads page](https://zen-browser.app/download)! 🔄
|
||||
- Again, if you don't see your OS listed above, that's because we already have it in our [downloads page](https://zen-browser.app/download)! 🔄
|
||||
|
||||
To upgrade the browser to a newer version, use the embedded update functionality in `About Zen`.
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
# Branch Structure
|
||||
|
||||
The repository is structured as follows:
|
||||
|
@ -7,14 +6,14 @@ The repository is structured as follows:
|
|||
dev (main branch)
|
||||
| |
|
||||
| \--->-- stable (release branch)
|
||||
| ^
|
||||
| ^
|
||||
^ |
|
||||
| \-<- Hotfix (hotfixes directly from stable)
|
||||
|
|
||||
\-<- (features branches)
|
||||
```
|
||||
|
||||
The `central` branch is the main branch of the repository, and it is the default branch for the repository. The `twilight` branch is the feature branch, and it is branched off from the `central` branch. The `stable` branch is the release branch, and it is branched off from the `central` branch.
|
||||
The `central` branch is the main branch of the repository, and it is the default branch for the repository. The `twilight` branch is the feature branch, and it is branched off from the `central` branch. The `stable` branch is the release branch, and it is branched off from the `central` branch.
|
||||
|
||||
The `stable` branch may have hotfixes directly from the `stable` branch, and the `twilight` branch may have feature branches branched off from the `twilight` branch. This is done so that we can apply hotfixes like security patches directly to the `stable` branch without having to merge the changes from the `twilight` branch.
|
||||
|
||||
|
@ -34,4 +33,4 @@ To merge zen stable branch from the twilight branch, you can use the following c
|
|||
|
||||
```bash
|
||||
sh ./scripts/merge-to-branch.sh stable
|
||||
```
|
||||
```
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -28,13 +28,14 @@
|
|||
// Fix notification deck
|
||||
const deckTemplate = document.getElementById('tab-notification-deck-template');
|
||||
if (deckTemplate) {
|
||||
document
|
||||
.getElementById('zen-appcontent-navbar-container')
|
||||
.appendChild(deckTemplate);
|
||||
document.getElementById('zen-appcontent-navbar-container').appendChild(deckTemplate);
|
||||
}
|
||||
|
||||
// Disable smooth scroll
|
||||
gBrowser.tabContainer.arrowScrollbox.smoothScroll = Services.prefs.getBoolPref('zen.startup.smooth-scroll-in-tabs', false);
|
||||
gBrowser.tabContainer.arrowScrollbox.smoothScroll = Services.prefs.getBoolPref(
|
||||
'zen.startup.smooth-scroll-in-tabs',
|
||||
false
|
||||
);
|
||||
|
||||
ZenWorkspaces.init();
|
||||
gZenUIManager.init();
|
||||
|
|
|
@ -6,20 +6,18 @@ var gZenUIManager = {
|
|||
document.addEventListener('popupshowing', this.onPopupShowing.bind(this));
|
||||
document.addEventListener('popuphidden', this.onPopupHidden.bind(this));
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, 'sidebarHeightThrottle', 'zen.view.sidebar-height-throttle', 500);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
'contentElementSeparation',
|
||||
'zen.theme.content-element-separation',
|
||||
0
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, 'contentElementSeparation', 'zen.theme.content-element-separation', 0);
|
||||
|
||||
new ResizeObserver(gZenCommonActions.throttle(this.updateTabsToolbar.bind(this), this.sidebarHeightThrottle)).observe(
|
||||
document.getElementById('tabbrowser-tabs')
|
||||
);
|
||||
|
||||
new ResizeObserver(gZenCommonActions.throttle(gZenCompactModeManager.getAndApplySidebarWidth.bind(gZenCompactModeManager), this.sidebarHeightThrottle)).observe(
|
||||
document.getElementById('navigator-toolbox')
|
||||
);
|
||||
new ResizeObserver(
|
||||
gZenCommonActions.throttle(
|
||||
gZenCompactModeManager.getAndApplySidebarWidth.bind(gZenCompactModeManager),
|
||||
this.sidebarHeightThrottle
|
||||
)
|
||||
).observe(document.getElementById('navigator-toolbox'));
|
||||
},
|
||||
|
||||
updateTabsToolbar() {
|
||||
|
@ -30,7 +28,7 @@ var gZenUIManager = {
|
|||
const toolbarRect = toolbarItems.getBoundingClientRect();
|
||||
let height = toolbarRect.height;
|
||||
// -5 for the controls padding
|
||||
let totalHeight = toolbarRect.height - (this.contentElementSeparation * 2) - 5;
|
||||
let totalHeight = toolbarRect.height - this.contentElementSeparation * 2 - 5;
|
||||
// remove the height from other elements that aren't hidden
|
||||
const otherElements = document.querySelectorAll('#tabbrowser-tabs > *:not([hidden="true"])');
|
||||
for (let tab of otherElements) {
|
||||
|
@ -83,7 +81,10 @@ var gZenUIManager = {
|
|||
for (const el of this._popupTrackingElements) {
|
||||
// target may be inside a shadow root, not directly under the element
|
||||
// we also ignore menus inside panels
|
||||
if (!el.contains(showEvent.explicitOriginalTarget) || (showEvent.explicitOriginalTarget instanceof Element && showEvent.explicitOriginalTarget?.closest('panel'))) {
|
||||
if (
|
||||
!el.contains(showEvent.explicitOriginalTarget) ||
|
||||
(showEvent.explicitOriginalTarget instanceof Element && showEvent.explicitOriginalTarget?.closest('panel'))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
document.removeEventListener('mousemove', this.__removeHasPopupAttribute);
|
||||
|
@ -115,8 +116,11 @@ var gZenVerticalTabsManager = {
|
|||
this._multiWindowFeature = new ZenMultiWindowFeature();
|
||||
|
||||
ChromeUtils.defineLazyGetter(this, 'isWindowsStyledButtons', () => {
|
||||
return !(window.AppConstants.platform === 'macosx' || window.matchMedia('(-moz-gtk-csd-reversed-placement)').matches
|
||||
|| Services.prefs.getBoolPref('zen.view.experimental-force-window-controls-left'));
|
||||
return !(
|
||||
window.AppConstants.platform === 'macosx' ||
|
||||
window.matchMedia('(-moz-gtk-csd-reversed-placement)').matches ||
|
||||
Services.prefs.getBoolPref('zen.view.experimental-force-window-controls-left')
|
||||
);
|
||||
});
|
||||
|
||||
ChromeUtils.defineLazyGetter(this, 'hidesTabsToolbar', () => {
|
||||
|
@ -144,7 +148,7 @@ var gZenVerticalTabsManager = {
|
|||
XPCOMUtils.defineLazyPreferenceGetter(this, 'canOpenTabOnMiddleClick', 'zen.tabs.newtab-on-middle-click', true);
|
||||
|
||||
if (!this.isWindowsStyledButtons) {
|
||||
document.documentElement.setAttribute("zen-window-buttons-reversed", true);
|
||||
document.documentElement.setAttribute('zen-window-buttons-reversed', true);
|
||||
}
|
||||
|
||||
if (tabs) {
|
||||
|
@ -199,9 +203,9 @@ var gZenVerticalTabsManager = {
|
|||
get actualWindowButtons() {
|
||||
// we have multiple ".titlebar-buttonbox-container" in the DOM, because of the titlebar
|
||||
if (!this.__actualWindowButtons) {
|
||||
this.__actualWindowButtons = (!this.isWindowsStyledButtons) ?
|
||||
document.querySelector('.titlebar-buttonbox-container') : // TODO: test if it works 100% of the time
|
||||
document.querySelector('#nav-bar .titlebar-buttonbox-container');
|
||||
this.__actualWindowButtons = !this.isWindowsStyledButtons
|
||||
? document.querySelector('.titlebar-buttonbox-container') // TODO: test if it works 100% of the time
|
||||
: document.querySelector('#nav-bar .titlebar-buttonbox-container');
|
||||
}
|
||||
return this.__actualWindowButtons;
|
||||
},
|
||||
|
@ -225,44 +229,20 @@ var gZenVerticalTabsManager = {
|
|||
initializePreferences(updateEvent) {
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"_prefsCompactMode",
|
||||
"zen.view.compact",
|
||||
'_prefsCompactMode',
|
||||
'zen.view.compact',
|
||||
false
|
||||
// no need to update the event, it's handled by the compact mode manager
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsVerticalTabs', 'zen.tabs.vertical', true, updateEvent);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsRightSide', 'zen.tabs.vertical.right-side', false, updateEvent);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsUseSingleToolbar', 'zen.view.use-single-toolbar', false, updateEvent);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, '_prefsSidebarExpanded', 'zen.view.sidebar-expanded', false, updateEvent);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"_prefsVerticalTabs",
|
||||
"zen.tabs.vertical",
|
||||
true,
|
||||
updateEvent
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"_prefsRightSide",
|
||||
"zen.tabs.vertical.right-side",
|
||||
false,
|
||||
updateEvent
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"_prefsUseSingleToolbar",
|
||||
"zen.view.use-single-toolbar",
|
||||
false,
|
||||
updateEvent
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"_prefsSidebarExpanded",
|
||||
"zen.view.sidebar-expanded",
|
||||
false,
|
||||
updateEvent
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"_prefsSidebarExpandedMaxWidth",
|
||||
"zen.view.sidebar-expanded.max-width",
|
||||
'_prefsSidebarExpandedMaxWidth',
|
||||
'zen.view.sidebar-expanded.max-width',
|
||||
300,
|
||||
updateEvent
|
||||
);
|
||||
|
@ -276,17 +256,17 @@ var gZenVerticalTabsManager = {
|
|||
try {
|
||||
this._updateMaxWidth();
|
||||
|
||||
window.docShell.treeOwner
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIAppWindow)
|
||||
.rollupAllPopups();
|
||||
window.docShell.treeOwner.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIAppWindow).rollupAllPopups();
|
||||
|
||||
const topButtons = document.getElementById('zen-sidebar-top-buttons');
|
||||
const isCompactMode = this._prefsCompactMode && !forCustomizableMode;
|
||||
const isVerticalTabs = this._prefsVerticalTabs || forCustomizableMode;
|
||||
const isSidebarExpanded = this._prefsSidebarExpanded || !isVerticalTabs;
|
||||
const isRightSide = this._prefsRightSide && isVerticalTabs;
|
||||
const isSingleToolbar = ((this._prefsUseSingleToolbar && (isVerticalTabs && isSidebarExpanded) )|| !isVerticalTabs) && !forCustomizableMode && !this.hidesTabsToolbar;
|
||||
const isSingleToolbar =
|
||||
((this._prefsUseSingleToolbar && isVerticalTabs && isSidebarExpanded) || !isVerticalTabs) &&
|
||||
!forCustomizableMode &&
|
||||
!this.hidesTabsToolbar;
|
||||
const titlebar = document.getElementById('titlebar');
|
||||
|
||||
gBrowser.tabContainer.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal');
|
||||
|
@ -311,10 +291,12 @@ var gZenVerticalTabsManager = {
|
|||
|
||||
const appContentNavbarContaienr = document.getElementById('zen-appcontent-navbar-container');
|
||||
let shouldHide = false;
|
||||
if (((!isRightSide && this.isWindowsStyledButtons) || (isRightSide && !this.isWindowsStyledButtons)
|
||||
|| (
|
||||
isCompactMode && isSingleToolbar && this.isWindowsStyledButtons
|
||||
)) && isSingleToolbar) {
|
||||
if (
|
||||
((!isRightSide && this.isWindowsStyledButtons) ||
|
||||
(isRightSide && !this.isWindowsStyledButtons) ||
|
||||
(isCompactMode && isSingleToolbar && this.isWindowsStyledButtons)) &&
|
||||
isSingleToolbar
|
||||
) {
|
||||
appContentNavbarContaienr.setAttribute('should-hide', 'true');
|
||||
shouldHide = true;
|
||||
} else {
|
||||
|
@ -322,10 +304,7 @@ var gZenVerticalTabsManager = {
|
|||
}
|
||||
|
||||
// Check if the sidebar is in hover mode
|
||||
if (
|
||||
!this.navigatorToolbox.hasAttribute('zen-right-side') &&
|
||||
!isCompactMode
|
||||
) {
|
||||
if (!this.navigatorToolbox.hasAttribute('zen-right-side') && !isCompactMode) {
|
||||
this.navigatorToolbox.prepend(topButtons);
|
||||
}
|
||||
|
||||
|
@ -335,7 +314,9 @@ var gZenVerticalTabsManager = {
|
|||
|
||||
if (isSingleToolbar) {
|
||||
this._navbarParent = navBar.parentElement;
|
||||
let elements = document.querySelectorAll('#nav-bar-customization-target > :is([cui-areatype="toolbar"], .chromeclass-toolbar-additional):not(#urlbar-container)');
|
||||
let elements = document.querySelectorAll(
|
||||
'#nav-bar-customization-target > :is([cui-areatype="toolbar"], .chromeclass-toolbar-additional):not(#urlbar-container)'
|
||||
);
|
||||
elements = Array.from(elements).reverse();
|
||||
// Add separator if it doesn't exist
|
||||
if (!buttonsTarget.contains(this._topButtonsSeparatorElement)) {
|
||||
|
@ -356,18 +337,20 @@ var gZenVerticalTabsManager = {
|
|||
titlebar.before(topButtons);
|
||||
titlebar.before(navBar);
|
||||
}
|
||||
document.documentElement.setAttribute("zen-single-toolbar", true);
|
||||
document.documentElement.setAttribute('zen-single-toolbar', true);
|
||||
this._hasSetSingleToolbar = true;
|
||||
} else if (this._hasSetSingleToolbar) {
|
||||
this._hasSetSingleToolbar = false;
|
||||
// Do the opposite
|
||||
this._navbarParent.prepend(navBar);
|
||||
const elements = document.querySelectorAll('#zen-sidebar-top-buttons-customization-target > :is([cui-areatype="toolbar"], .chromeclass-toolbar-additional)');
|
||||
const elements = document.querySelectorAll(
|
||||
'#zen-sidebar-top-buttons-customization-target > :is([cui-areatype="toolbar"], .chromeclass-toolbar-additional)'
|
||||
);
|
||||
for (const button of elements) {
|
||||
document.getElementById('nav-bar-customization-target').append(button);
|
||||
}
|
||||
this._topButtonsSeparatorElement.remove();
|
||||
document.documentElement.removeAttribute("zen-single-toolbar");
|
||||
document.documentElement.removeAttribute('zen-single-toolbar');
|
||||
navBar.appendChild(document.getElementById('PanelUI-button'));
|
||||
this._toolbarOriginalParent.prepend(navBar);
|
||||
if (!dontRebuildAreas) {
|
||||
|
@ -398,7 +381,7 @@ var gZenVerticalTabsManager = {
|
|||
if (isRightSide && !isSidebarExpanded) {
|
||||
navBar.appendChild(windowButtons);
|
||||
} else {
|
||||
document.getElementById("zen-sidebar-top-buttons-customization-target").appendChild(windowButtons);
|
||||
document.getElementById('zen-sidebar-top-buttons-customization-target').appendChild(windowButtons);
|
||||
}
|
||||
} else if (!isSingleToolbar && !isCompactMode) {
|
||||
if (this.isWindowsStyledButtons) {
|
||||
|
@ -407,7 +390,8 @@ var gZenVerticalTabsManager = {
|
|||
} else {
|
||||
navBar.append(windowButtons);
|
||||
}
|
||||
} else { // not windows styled buttons
|
||||
} else {
|
||||
// not windows styled buttons
|
||||
if (isRightSide || !isSidebarExpanded) {
|
||||
navBar.prepend(windowButtons);
|
||||
} else {
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
transform: translateY(-25px);
|
||||
}
|
||||
60% {
|
||||
opacity: 0.8 ;
|
||||
opacity: 0.8;
|
||||
transform: translateY(4px);
|
||||
}
|
||||
100% {
|
||||
|
|
|
@ -24,6 +24,6 @@
|
|||
font-feature-settings: 'swsh' 1;
|
||||
|
||||
& .zen-branding-title-italic {
|
||||
font-family: "Zen-Junicode-Italic", serif;
|
||||
font-family: 'Zen-Junicode-Italic', serif;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
position: relative;
|
||||
|
||||
/* For glance */
|
||||
transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out;
|
||||
transition:
|
||||
transform 0.1s ease-in-out,
|
||||
opacity 0.1s ease-in-out;
|
||||
|
||||
box-shadow: 0 0 1px 1px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.5));
|
||||
overflow: hidden;
|
||||
|
@ -20,11 +22,11 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (-moz-bool-pref: 'zen.view.experimental-rounded-view') {
|
||||
#tabbrowser-tabpanels {
|
||||
mix-blend-mode: multiply;
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
&[animating='true']::after {
|
||||
background: var(--zen-main-browser-background-old);
|
||||
backdrop-filter: blur(5px);
|
||||
animation: zen-main-app-wrapper-animation .6s ease forwards;
|
||||
animation: zen-main-app-wrapper-animation 0.6s ease forwards;
|
||||
transition: 0s;
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,6 @@
|
|||
border: none;
|
||||
}
|
||||
|
||||
|
||||
@supports (-moz-osx-font-smoothing: auto) {
|
||||
#zen-main-app-wrapper,
|
||||
#zen-appcontent-wrapper,
|
||||
|
|
|
@ -48,7 +48,10 @@
|
|||
&:not([animate='true']) {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
transition: left 0.25s ease, right 0.25s ease, opacity 1.5s ease;
|
||||
transition:
|
||||
left 0.25s ease,
|
||||
right 0.25s ease,
|
||||
opacity 1.5s ease;
|
||||
top: 0;
|
||||
bottom: var(--zen-element-separation);
|
||||
opacity: 0;
|
||||
|
@ -124,9 +127,13 @@
|
|||
#navigator-toolbox[has-popup-menu],
|
||||
#navigator-toolbox[movingtab],
|
||||
#navigator-toolbox:has(.tabbrowser-tab:active),
|
||||
#navigator-toolbox:has(*:is([panelopen='true'], [open='true'], #nav-bar:focus-within):not(tab):not(.zen-compact-mode-ignore)) {
|
||||
#navigator-toolbox:has(
|
||||
*:is([panelopen='true'], [open='true'], #nav-bar:focus-within):not(tab):not(.zen-compact-mode-ignore)
|
||||
) {
|
||||
&:not([animate='true']) {
|
||||
transition: left 0.25s ease, right 0.25s ease;
|
||||
transition:
|
||||
left 0.25s ease,
|
||||
right 0.25s ease;
|
||||
opacity: 1;
|
||||
|
||||
left: -1px;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
}
|
||||
#zen-splitview-dropzone {
|
||||
border-radius: var(--zen-webview-border-radius, var(--zen-border-radius));
|
||||
transition: inset ease-out .08s;
|
||||
transition: inset ease-out 0.08s;
|
||||
display: none;
|
||||
background-color: color-mix(in srgb, var(--zen-colors-secondary) 30%, transparent 70%);
|
||||
}
|
||||
|
@ -25,7 +25,8 @@
|
|||
display: initial;
|
||||
}
|
||||
|
||||
#tabbrowser-tabpanels[zen-split-view='true'] > [zen-split='true'], #zen-splitview-dropzone {
|
||||
#tabbrowser-tabpanels[zen-split-view='true'] > [zen-split='true'],
|
||||
#zen-splitview-dropzone {
|
||||
flex: 1;
|
||||
margin: calc(var(--zen-split-column-gap) / 2) calc(var(--zen-split-row-gap) / 2 + 1px) !important;
|
||||
margin-bottom: 0 !important;
|
||||
|
@ -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 {
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
& .browserContainer {
|
||||
opacity: 1;
|
||||
animation: zen-glance-content-animation-out .3s ease-in-out forwards !important;
|
||||
animation: zen-glance-content-animation-out 0.3s ease-in-out forwards !important;
|
||||
|
||||
& browser {
|
||||
opacity: 1 !important;
|
||||
|
@ -40,7 +40,7 @@
|
|||
|
||||
& #zen-glance-sidebar-container {
|
||||
opacity: 0;
|
||||
transition: opacity .1s ease-in-out;
|
||||
transition: opacity 0.1s ease-in-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@
|
|||
}
|
||||
|
||||
&[animate='true'] {
|
||||
animation: zen-glance-content-animation .4s ease-in-out forwards;
|
||||
animation: zen-glance-content-animation 0.4s ease-in-out forwards;
|
||||
|
||||
&:not([animate-end='true']) {
|
||||
pointer-events: none;
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
bottom: 2px;
|
||||
right: 0;
|
||||
border: 2px solid var(--zen-colors-border);
|
||||
transition: transform .2s;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
&[dragging='true']::after {
|
||||
|
@ -152,7 +152,7 @@
|
|||
padding: 2px 4px !important;
|
||||
margin: 0 !important;
|
||||
margin-left: auto !important;
|
||||
transition: opacity .1s;
|
||||
transition: opacity 0.1s;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
@ -246,8 +246,8 @@
|
|||
box-shadow: 0 0 0 2px var(--zen-themed-toolbar-bg);
|
||||
cursor: pointer;
|
||||
border: 2px solid #fff;
|
||||
animation: zen-theme-picker-dot-animation .5s;
|
||||
transition: transform .2s;
|
||||
animation: zen-theme-picker-dot-animation 0.5s;
|
||||
transition: transform 0.2s;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
&[dragging='true'] {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
panel[type='arrow'][animate][animate='open']::part(content) {
|
||||
animation: zen-jello-animation .35s ease;
|
||||
animation: zen-jello-animation 0.35s ease;
|
||||
}
|
||||
|
||||
panel[type='arrow'][animate]:not([animate='open'])::part(content) {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
.printSettingsBrowser {
|
||||
min-width: 350px;
|
||||
}
|
||||
|
|
|
@ -341,6 +341,6 @@ menuitem {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
#editBMPanel_workspaceList input[type="checkbox"] {
|
||||
#editBMPanel_workspaceList input[type='checkbox'] {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#zen-rice-share-dialog-overlay:not([hidden]) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
@ -17,15 +16,15 @@
|
|||
color: var(--panel-color);
|
||||
background: var(--arrowpanel-background);
|
||||
border-radius: var(--zen-panel-radius);
|
||||
box-shadow: 0 0 1px 1px hsla(0,0%,0%,.2);;
|
||||
box-shadow: 0 0 1px 1px hsla(0, 0%, 0%, 0.2);
|
||||
border: var(--zen-appcontent-border);
|
||||
overflow: hidden;
|
||||
|
||||
animation: zen-jello-animation-large 0.4s ease;
|
||||
max-width: 400px;
|
||||
|
||||
&[animate="true"] {
|
||||
animation: zen-rice-submit-animation 1s cubic-bezier(.77,0,.18,1);
|
||||
&[animate='true'] {
|
||||
animation: zen-rice-submit-animation 1s cubic-bezier(0.77, 0, 0.18, 1);
|
||||
}
|
||||
|
||||
& .zen-rice-share-content {
|
||||
|
@ -47,7 +46,7 @@
|
|||
padding: 0 10px;
|
||||
}
|
||||
|
||||
& #zen-rice-share-first-form input[type="text"] {
|
||||
& #zen-rice-share-first-form input[type='text'] {
|
||||
width: 100%;
|
||||
padding: 1px 2px;
|
||||
border: 0;
|
||||
|
@ -78,8 +77,10 @@
|
|||
|
||||
max-height: 30px;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease, height 0.3s ease;
|
||||
&[zen-collapsed="false"] {
|
||||
transition:
|
||||
max-height 0.3s ease,
|
||||
height 0.3s ease;
|
||||
&[zen-collapsed='false'] {
|
||||
max-height: 350px;
|
||||
}
|
||||
|
||||
|
@ -106,7 +107,7 @@
|
|||
height: 15px;
|
||||
}
|
||||
|
||||
&[zen-collapsed="false"] > .options-header image {
|
||||
&[zen-collapsed='false'] > .options-header image {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
|
@ -162,7 +163,7 @@
|
|||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
}
|
||||
|
||||
.zen-sidebar-web-panel-splitter,
|
||||
.zen-split-view-splitter[orient="vertical"] {
|
||||
.zen-split-view-splitter[orient='vertical'] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
@ -131,7 +131,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.zen-split-view-splitter[orient="vertical"]::before {
|
||||
.zen-split-view-splitter[orient='vertical']::before {
|
||||
transform: translate(-75%, -50%);
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@
|
|||
}
|
||||
|
||||
#zen-sidebar-web-panel-title {
|
||||
font-size: .9em;
|
||||
font-size: 0.9em;
|
||||
font-weight: 600;
|
||||
margin: 0 10px;
|
||||
padding: 0;
|
||||
|
@ -316,4 +316,3 @@
|
|||
#zen-sidebar-web-panel[hidden] {
|
||||
animation: better-sidebar-hide 0.15s ease-in-out forwards !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,4 +78,4 @@
|
|||
/* Menubar */
|
||||
#toolbar-menubar {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
body > #confetti {
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
& > * {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
outline-color: none !important;
|
||||
}
|
||||
|
||||
#identity-box.chromeUI:not([pageproxystate="invalid"]) {
|
||||
#identity-box.chromeUI:not([pageproxystate='invalid']) {
|
||||
& #identity-icon-box {
|
||||
background: light-dark(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1)) !important;
|
||||
}
|
||||
|
@ -125,7 +125,6 @@
|
|||
}
|
||||
|
||||
:root[zen-single-toolbar='true'] {
|
||||
|
||||
.urlbar-page-action:not(#star-button-box):not([open]),
|
||||
#tracking-protection-icon-container {
|
||||
margin-inline-end: calc(-16px - 2 * var(--urlbar-icon-padding)) !important;
|
||||
|
@ -437,7 +436,10 @@ button.popup-notification-dropmarker {
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
**/
|
||||
.urlbarView-title, .urlbarView-title-separator, .urlbarView-action, .urlbarView-url {
|
||||
.urlbarView-title,
|
||||
.urlbarView-title-separator,
|
||||
.urlbarView-action,
|
||||
.urlbarView-url {
|
||||
margin-top: auto !important;
|
||||
margin-bottom: auto !important;
|
||||
}
|
||||
|
@ -447,7 +449,8 @@ button.popup-notification-dropmarker {
|
|||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.urlbarView-url, .urlbarView-title-separator::before {
|
||||
.urlbarView-url,
|
||||
.urlbarView-title-separator::before {
|
||||
font-size: 14px !important;
|
||||
font-weight: 500 !important;
|
||||
color: #aaa !important;
|
||||
|
@ -460,7 +463,7 @@ button.popup-notification-dropmarker {
|
|||
border-radius: 6px !important;
|
||||
}
|
||||
|
||||
.urlbarView-row[has-action]:is([type="switchtab"], [type="remotetab"], [type="clipboard"]) .urlbarView-action {
|
||||
.urlbarView-row[has-action]:is([type='switchtab'], [type='remotetab'], [type='clipboard']) .urlbarView-action {
|
||||
margin-left: auto !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
@ -477,7 +480,8 @@ button.popup-notification-dropmarker {
|
|||
background-color: color-mix(in srgb, var(--zen-branding-bg-reverse) 20%, transparent 80%) !important;
|
||||
}
|
||||
|
||||
.urlbarView-url, .urlbarView-title-separator::before {
|
||||
.urlbarView-url,
|
||||
.urlbarView-title-separator::before {
|
||||
color: color-mix(in srgb, var(--zen-colors-primary) 30%, lightgray) !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -266,7 +266,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* Workspace icon picker styles */
|
||||
#PanelUI-zen-workspaces-icon-picker-wrapper {
|
||||
display: flex;
|
||||
|
@ -391,7 +390,6 @@
|
|||
background-color: var(--toolbarbutton-icon-fill-attention);
|
||||
}
|
||||
|
||||
|
||||
#PanelUI-zen-workspaces-reorder-mode[active='true'] {
|
||||
color: var(--toolbarbutton-icon-fill-attention) !important;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,9 +76,9 @@ var ZenThemeModifier = {
|
|||
const separation = Services.prefs.getIntPref('zen.theme.content-element-separation');
|
||||
document.documentElement.style.setProperty('--zen-element-separation', separation + 'px');
|
||||
if (separation == 0) {
|
||||
document.documentElement.setAttribute("zen-no-padding", true);
|
||||
document.documentElement.setAttribute('zen-no-padding', true);
|
||||
} else {
|
||||
document.documentElement.removeAttribute("zen-no-padding");
|
||||
document.documentElement.removeAttribute('zen-no-padding');
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
// Utility to register JSWindowActors
|
||||
var gZenActorsManager = {
|
||||
_actors: new Set(),
|
||||
|
@ -16,4 +15,4 @@ var gZenActorsManager = {
|
|||
console.warn(`Failed to register JSWindowActor: ${e}`);
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -62,22 +62,14 @@ var gZenCommonActions = {
|
|||
copyCurrentURLToClipboard() {
|
||||
const currentUrl = gBrowser.currentURI.spec;
|
||||
if (currentUrl) {
|
||||
let str = Cc["@mozilla.org/supports-string;1"].createInstance(
|
||||
Ci.nsISupportsString
|
||||
);
|
||||
let str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
|
||||
str.data = currentUrl;
|
||||
let transferable = Cc[
|
||||
"@mozilla.org/widget/transferable;1"
|
||||
].createInstance(Ci.nsITransferable);
|
||||
let transferable = Cc['@mozilla.org/widget/transferable;1'].createInstance(Ci.nsITransferable);
|
||||
transferable.init(getLoadContext());
|
||||
transferable.addDataFlavor("text/plain");
|
||||
transferable.setTransferData("text/plain", str);
|
||||
Services.clipboard.setData(
|
||||
transferable,
|
||||
null,
|
||||
Ci.nsIClipboard.kGlobalClipboard
|
||||
);
|
||||
ConfirmationHint.show(document.getElementById("PanelUI-menu-button"), "zen-copy-current-url-confirmation");
|
||||
transferable.addDataFlavor('text/plain');
|
||||
transferable.setTransferData('text/plain', str);
|
||||
Services.clipboard.setData(transferable, null, Ci.nsIClipboard.kGlobalClipboard);
|
||||
ConfirmationHint.show(document.getElementById('PanelUI-menu-button'), 'zen-copy-current-url-confirmation');
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -87,5 +79,5 @@ var gZenCommonActions = {
|
|||
clearTimeout(timer);
|
||||
timer = setTimeout(() => f.apply(this, args), delay);
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -69,7 +69,11 @@ var gZenCompactModeManager = {
|
|||
updateCompactModeContext(isSingleToolbar) {
|
||||
this.getAndApplySidebarWidth(); // Ignore return value
|
||||
|
||||
const IDs = ['zen-context-menu-compact-mode-hide-sidebar', 'zen-context-menu-compact-mode-hide-toolbar', 'zen-context-menu-compact-mode-hide-both'];
|
||||
const IDs = [
|
||||
'zen-context-menu-compact-mode-hide-sidebar',
|
||||
'zen-context-menu-compact-mode-hide-toolbar',
|
||||
'zen-context-menu-compact-mode-hide-both',
|
||||
];
|
||||
for (let id of IDs) {
|
||||
document.getElementById(id).disabled = isSingleToolbar;
|
||||
}
|
||||
|
@ -104,7 +108,7 @@ var gZenCompactModeManager = {
|
|||
getAndApplySidebarWidth() {
|
||||
let sidebarWidth = this.sidebar.getBoundingClientRect().width;
|
||||
if (sidebarWidth > 1) {
|
||||
this.sidebar.style.setProperty("--zen-sidebar-width", `${sidebarWidth}px`);
|
||||
this.sidebar.style.setProperty('--zen-sidebar-width', `${sidebarWidth}px`);
|
||||
}
|
||||
return sidebarWidth;
|
||||
},
|
||||
|
@ -118,40 +122,40 @@ var gZenCompactModeManager = {
|
|||
this._isAnimating = true;
|
||||
// Do this so we can get the correct width ONCE compact mode styled have been applied
|
||||
if (this._canAnimateSidebar) {
|
||||
this.sidebar.setAttribute("animate", "true");
|
||||
this.sidebar.setAttribute('animate', 'true');
|
||||
}
|
||||
window.requestAnimationFrame(() => {
|
||||
let sidebarWidth = this.getAndApplySidebarWidth();
|
||||
if (!this._canAnimateSidebar) {
|
||||
this.sidebar.removeAttribute("animate");
|
||||
this.sidebar.removeAttribute('animate');
|
||||
this._isAnimating = false;
|
||||
return;
|
||||
}
|
||||
if (canHideSidebar && isCompactMode) {
|
||||
window.requestAnimationFrame(() => {
|
||||
this.sidebar.style.position = "unset";
|
||||
this.sidebar.style.transition = "margin .4s ease";
|
||||
this.sidebar.style.left = "0";
|
||||
this.sidebar.style.position = 'unset';
|
||||
this.sidebar.style.transition = 'margin .4s ease';
|
||||
this.sidebar.style.left = '0';
|
||||
if (!this.sidebarIsOnRight) {
|
||||
this.sidebar.style.marginLeft = `${-1 * sidebarWidth}px`;
|
||||
} else {
|
||||
this.sidebar.style.marginRight = `${-1 * sidebarWidth}px`;
|
||||
}
|
||||
this.sidebar.style.pointerEvents = "none";
|
||||
this.sidebar.style.pointerEvents = 'none';
|
||||
|
||||
window.requestAnimationFrame(() => {
|
||||
setTimeout(() => {
|
||||
window.requestAnimationFrame(() => {
|
||||
this.sidebar.style.removeProperty("pointer-events");
|
||||
this.sidebar.style.removeProperty("position");
|
||||
this.sidebar.style.removeProperty("margin-left");
|
||||
this.sidebar.style.removeProperty("margin-right");
|
||||
this.sidebar.style.removeProperty("transform");
|
||||
this.sidebar.style.removeProperty("left");
|
||||
document.getElementById('browser').style.removeProperty("overflow");
|
||||
this.sidebar.removeAttribute("animate");
|
||||
this.sidebar.style.removeProperty('pointer-events');
|
||||
this.sidebar.style.removeProperty('position');
|
||||
this.sidebar.style.removeProperty('margin-left');
|
||||
this.sidebar.style.removeProperty('margin-right');
|
||||
this.sidebar.style.removeProperty('transform');
|
||||
this.sidebar.style.removeProperty('left');
|
||||
document.getElementById('browser').style.removeProperty('overflow');
|
||||
this.sidebar.removeAttribute('animate');
|
||||
window.requestAnimationFrame(() => {
|
||||
this.sidebar.style.removeProperty("transition");
|
||||
this.sidebar.style.removeProperty('transition');
|
||||
this._isAnimating = false;
|
||||
});
|
||||
});
|
||||
|
@ -159,9 +163,9 @@ var gZenCompactModeManager = {
|
|||
});
|
||||
});
|
||||
} else if (canHideSidebar && !isCompactMode) {
|
||||
document.getElementById('browser').style.overflow = "hidden";
|
||||
this.sidebar.style.position = "relative";
|
||||
this.sidebar.style.left = "0";
|
||||
document.getElementById('browser').style.overflow = 'hidden';
|
||||
this.sidebar.style.position = 'relative';
|
||||
this.sidebar.style.left = '0';
|
||||
|
||||
if (!this.sidebarIsOnRight) {
|
||||
this.sidebar.style.marginLeft = `${-1 * sidebarWidth}px`;
|
||||
|
@ -171,35 +175,35 @@ var gZenCompactModeManager = {
|
|||
}
|
||||
|
||||
window.requestAnimationFrame(() => {
|
||||
this.sidebar.style.transition = "margin .3s ease, transform .275s ease, opacity .3s ease";
|
||||
this.sidebar.style.transition = 'margin .3s ease, transform .275s ease, opacity .3s ease';
|
||||
// we are in compact mode and we are exiting it
|
||||
if (!this.sidebarIsOnRight) {
|
||||
this.sidebar.style.marginLeft = "0";
|
||||
this.sidebar.style.marginLeft = '0';
|
||||
} else {
|
||||
this.sidebar.style.marginRight = "0";
|
||||
this.sidebar.style.transform = "translateX(0)";
|
||||
this.sidebar.style.marginRight = '0';
|
||||
this.sidebar.style.transform = 'translateX(0)';
|
||||
}
|
||||
this.sidebar.style.pointerEvents = "none";
|
||||
this.sidebar.style.pointerEvents = 'none';
|
||||
|
||||
setTimeout(() => {
|
||||
window.requestAnimationFrame(() => {
|
||||
this._isAnimating = false;
|
||||
this.sidebar.style.removeProperty("position");
|
||||
this.sidebar.style.removeProperty("pointer-events");
|
||||
this.sidebar.style.removeProperty("opacity");
|
||||
this.sidebar.style.removeProperty("margin-left");
|
||||
this.sidebar.style.removeProperty("margin-right");
|
||||
this.sidebar.style.removeProperty("transform");
|
||||
this.sidebar.style.removeProperty("transition");
|
||||
this.sidebar.style.removeProperty("left");
|
||||
this.sidebar.style.removeProperty('position');
|
||||
this.sidebar.style.removeProperty('pointer-events');
|
||||
this.sidebar.style.removeProperty('opacity');
|
||||
this.sidebar.style.removeProperty('margin-left');
|
||||
this.sidebar.style.removeProperty('margin-right');
|
||||
this.sidebar.style.removeProperty('transform');
|
||||
this.sidebar.style.removeProperty('transition');
|
||||
this.sidebar.style.removeProperty('left');
|
||||
|
||||
document.getElementById('browser').style.removeProperty("overflow");
|
||||
this.sidebar.removeAttribute("animate");
|
||||
document.getElementById('browser').style.removeProperty('overflow');
|
||||
this.sidebar.removeAttribute('animate');
|
||||
});
|
||||
}, 400);
|
||||
});
|
||||
} else {
|
||||
this.sidebar.removeAttribute("animate"); // remove the attribute if we are not animating
|
||||
this.sidebar.removeAttribute('animate'); // remove the attribute if we are not animating
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
{
|
||||
|
||||
class ZenGlanceManager extends ZenDOMOperatedFeature {
|
||||
#currentBrowser = null;
|
||||
#currentTab = null;
|
||||
|
@ -8,23 +6,19 @@
|
|||
#animating = false;
|
||||
|
||||
init() {
|
||||
document.documentElement.setAttribute("zen-glance-uuid", gZenUIManager.generateUuidv4());
|
||||
window.addEventListener("keydown", this.onKeyDown.bind(this));
|
||||
window.addEventListener("TabClose", this.onTabClose.bind(this));
|
||||
document.documentElement.setAttribute('zen-glance-uuid', gZenUIManager.generateUuidv4());
|
||||
window.addEventListener('keydown', this.onKeyDown.bind(this));
|
||||
window.addEventListener('TabClose', this.onTabClose.bind(this));
|
||||
|
||||
ChromeUtils.defineLazyGetter(
|
||||
this,
|
||||
'sidebarButtons',
|
||||
() => document.getElementById('zen-glance-sidebar-container')
|
||||
);
|
||||
ChromeUtils.defineLazyGetter(this, 'sidebarButtons', () => document.getElementById('zen-glance-sidebar-container'));
|
||||
|
||||
document.getElementById('tabbrowser-tabpanels').addEventListener("click", this.onOverlayClick.bind(this));
|
||||
document.getElementById('tabbrowser-tabpanels').addEventListener('click', this.onOverlayClick.bind(this));
|
||||
|
||||
Services.obs.addObserver(this, "quit-application-requested");
|
||||
Services.obs.addObserver(this, 'quit-application-requested');
|
||||
}
|
||||
|
||||
onKeyDown(event) {
|
||||
if (event.key === "Escape" && this.#currentBrowser) {
|
||||
if (event.key === 'Escape' && this.#currentBrowser) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.closeGlance();
|
||||
|
@ -39,7 +33,7 @@
|
|||
|
||||
observe(subject, topic) {
|
||||
switch (topic) {
|
||||
case "quit-application-requested":
|
||||
case 'quit-application-requested':
|
||||
this.onUnload();
|
||||
break;
|
||||
}
|
||||
|
@ -54,7 +48,7 @@
|
|||
|
||||
createBrowserElement(url, currentTab) {
|
||||
const newTabOptions = {
|
||||
userContextId: currentTab.getAttribute("usercontextid") || "",
|
||||
userContextId: currentTab.getAttribute('usercontextid') || '',
|
||||
skipBackgroundNotify: true,
|
||||
insertTab: true,
|
||||
skipLoad: false,
|
||||
|
@ -64,8 +58,8 @@
|
|||
const newTab = gBrowser.addTrustedTab(Services.io.newURI(url).spec, newTabOptions);
|
||||
|
||||
gBrowser.selectedTab = newTab;
|
||||
currentTab.querySelector(".tab-content").appendChild(newTab);
|
||||
newTab.setAttribute("zen-glance-tab", true);
|
||||
currentTab.querySelector('.tab-content').appendChild(newTab);
|
||||
newTab.setAttribute('zen-glance-tab', true);
|
||||
this.#currentBrowser = newTab.linkedBrowser;
|
||||
this.#currentTab = newTab;
|
||||
return this.#currentBrowser;
|
||||
|
@ -81,12 +75,12 @@
|
|||
const initialWidth = data.width;
|
||||
const initialHeight = data.height;
|
||||
|
||||
this.browserWrapper?.removeAttribute("animate");
|
||||
this.browserWrapper?.removeAttribute("animate-end");
|
||||
this.browserWrapper?.removeAttribute("animate-full");
|
||||
this.browserWrapper?.removeAttribute("animate-full-end");
|
||||
this.browserWrapper?.removeAttribute("has-finished-animation");
|
||||
this.overlay?.removeAttribute("post-fade-out");
|
||||
this.browserWrapper?.removeAttribute('animate');
|
||||
this.browserWrapper?.removeAttribute('animate-end');
|
||||
this.browserWrapper?.removeAttribute('animate-full');
|
||||
this.browserWrapper?.removeAttribute('animate-full-end');
|
||||
this.browserWrapper?.removeAttribute('has-finished-animation');
|
||||
this.overlay?.removeAttribute('post-fade-out');
|
||||
|
||||
const url = data.url;
|
||||
const currentTab = gBrowser.selectedTab;
|
||||
|
@ -94,29 +88,29 @@
|
|||
this.animatingOpen = true;
|
||||
const browserElement = this.createBrowserElement(url, currentTab);
|
||||
|
||||
this.overlay = browserElement.closest(".browserSidebarContainer");
|
||||
this.browserWrapper = browserElement.closest(".browserContainer");
|
||||
this.contentWrapper = browserElement.closest(".browserStack");
|
||||
this.overlay = browserElement.closest('.browserSidebarContainer');
|
||||
this.browserWrapper = browserElement.closest('.browserContainer');
|
||||
this.contentWrapper = browserElement.closest('.browserStack');
|
||||
|
||||
this.browserWrapper.prepend(this.sidebarButtons);
|
||||
|
||||
this.overlay.classList.add("zen-glance-overlay");
|
||||
this.overlay.classList.add('zen-glance-overlay');
|
||||
|
||||
this.browserWrapper.removeAttribute("animate-end");
|
||||
this.browserWrapper.removeAttribute('animate-end');
|
||||
window.requestAnimationFrame(() => {
|
||||
this.quickOpenGlance();
|
||||
|
||||
this.browserWrapper.style.setProperty("--initial-x", `${initialX}px`);
|
||||
this.browserWrapper.style.setProperty("--initial-y", `${initialY}px`);
|
||||
this.browserWrapper.style.setProperty("--initial-width", initialWidth + "px");
|
||||
this.browserWrapper.style.setProperty("--initial-height", initialHeight + "px");
|
||||
this.browserWrapper.style.setProperty('--initial-x', `${initialX}px`);
|
||||
this.browserWrapper.style.setProperty('--initial-y', `${initialY}px`);
|
||||
this.browserWrapper.style.setProperty('--initial-width', initialWidth + 'px');
|
||||
this.browserWrapper.style.setProperty('--initial-height', initialHeight + 'px');
|
||||
|
||||
this.overlay.removeAttribute("fade-out");
|
||||
this.browserWrapper.setAttribute("animate", true);
|
||||
this.overlay.removeAttribute('fade-out');
|
||||
this.browserWrapper.setAttribute('animate', true);
|
||||
this.#animating = true;
|
||||
setTimeout(() => {
|
||||
this.browserWrapper.setAttribute("animate-end", true);
|
||||
this.browserWrapper.setAttribute("has-finished-animation", true);
|
||||
this.browserWrapper.setAttribute('animate-end', true);
|
||||
this.browserWrapper.setAttribute('has-finished-animation', true);
|
||||
this.#animating = false;
|
||||
this.animatingOpen = false;
|
||||
}, 500);
|
||||
|
@ -128,7 +122,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
this.browserWrapper.removeAttribute("has-finished-animation");
|
||||
this.browserWrapper.removeAttribute('has-finished-animation');
|
||||
if (noAnimation) {
|
||||
this.quickCloseGlance({ closeCurrentTab: false });
|
||||
this.#currentBrowser = null;
|
||||
|
@ -156,13 +150,13 @@
|
|||
|
||||
// do NOT touch here, I don't know what it does, but it works...
|
||||
window.requestAnimationFrame(() => {
|
||||
this.#currentTab.style.display = "none";
|
||||
this.browserWrapper.removeAttribute("animate");
|
||||
this.browserWrapper.removeAttribute("animate-end");
|
||||
this.overlay.setAttribute("fade-out", true);
|
||||
this.#currentTab.style.display = 'none';
|
||||
this.browserWrapper.removeAttribute('animate');
|
||||
this.browserWrapper.removeAttribute('animate-end');
|
||||
this.overlay.setAttribute('fade-out', true);
|
||||
window.requestAnimationFrame(() => {
|
||||
this.quickCloseGlance({ justAnimateParent: true });
|
||||
this.browserWrapper.setAttribute("animate", true);
|
||||
this.browserWrapper.setAttribute('animate', true);
|
||||
setTimeout(() => {
|
||||
if (!this.currentParentTab) {
|
||||
return;
|
||||
|
@ -171,12 +165,12 @@
|
|||
if (!onTabClose || quikcCloseZen) {
|
||||
this.quickCloseGlance();
|
||||
}
|
||||
this.overlay.removeAttribute("fade-out");
|
||||
this.browserWrapper.removeAttribute("animate");
|
||||
this.overlay.removeAttribute('fade-out');
|
||||
this.browserWrapper.removeAttribute('animate');
|
||||
|
||||
this.lastCurrentTab = this.#currentTab;
|
||||
|
||||
this.overlay.classList.remove("zen-glance-overlay");
|
||||
this.overlay.classList.remove('zen-glance-overlay');
|
||||
gBrowser._getSwitcher().setTabStateNoAction(this.lastCurrentTab, gBrowser.AsyncTabSwitcher.STATE_UNLOADED);
|
||||
|
||||
if (!onTabClose && gBrowser.selectedTab === this.lastCurrentTab) {
|
||||
|
@ -190,7 +184,7 @@
|
|||
this.overlay = null;
|
||||
this.contentWrapper = null;
|
||||
|
||||
this.lastCurrentTab.removeAttribute("zen-glance-tab");
|
||||
this.lastCurrentTab.removeAttribute('zen-glance-tab');
|
||||
this.lastCurrentTab._closingGlance = true;
|
||||
|
||||
gBrowser.tabContainer._invalidateCachedTabs();
|
||||
|
@ -215,26 +209,28 @@
|
|||
gBrowser.selectedTab = this.#currentTab;
|
||||
} catch (e) {}
|
||||
|
||||
this.currentParentTab.linkedBrowser.closest(".browserSidebarContainer").classList.add("deck-selected", "zen-glance-background");
|
||||
this.currentParentTab.linkedBrowser.closest(".browserSidebarContainer").classList.remove("zen-glance-overlay");
|
||||
this.currentParentTab.linkedBrowser
|
||||
.closest('.browserSidebarContainer')
|
||||
.classList.add('deck-selected', 'zen-glance-background');
|
||||
this.currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('zen-glance-overlay');
|
||||
this.currentParentTab.linkedBrowser.zenModeActive = true;
|
||||
this.#currentBrowser.zenModeActive = true;
|
||||
this.currentParentTab.linkedBrowser.docShellIsActive = true;
|
||||
this.#currentBrowser.docShellIsActive = true;
|
||||
this.#currentBrowser.setAttribute("zen-glance-selected", true);
|
||||
this.#currentBrowser.setAttribute('zen-glance-selected', true);
|
||||
|
||||
this.currentParentTab._visuallySelected = true;
|
||||
this.overlay.classList.add("deck-selected");
|
||||
this.overlay.classList.add('deck-selected');
|
||||
|
||||
this._duringOpening = false;
|
||||
}
|
||||
|
||||
quickCloseGlance({ closeCurrentTab = true, closeParentTab = true, justAnimateParent = false } = {}) {
|
||||
const parentHasBrowser = !!(this.currentParentTab.linkedBrowser);
|
||||
const parentHasBrowser = !!this.currentParentTab.linkedBrowser;
|
||||
if (!justAnimateParent) {
|
||||
if (parentHasBrowser) {
|
||||
if (closeParentTab) {
|
||||
this.currentParentTab.linkedBrowser.closest(".browserSidebarContainer").classList.remove("deck-selected");
|
||||
this.currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('deck-selected');
|
||||
}
|
||||
this.currentParentTab.linkedBrowser.zenModeActive = false;
|
||||
}
|
||||
|
@ -244,15 +240,15 @@
|
|||
}
|
||||
if (closeCurrentTab) {
|
||||
this.#currentBrowser.docShellIsActive = false;
|
||||
this.overlay.classList.remove("deck-selected");
|
||||
this.overlay.classList.remove('deck-selected');
|
||||
}
|
||||
if (!this.currentParentTab._visuallySelected && closeParentTab) {
|
||||
this.currentParentTab._visuallySelected = false;
|
||||
}
|
||||
this.#currentBrowser.removeAttribute("zen-glance-selected");
|
||||
this.#currentBrowser.removeAttribute('zen-glance-selected');
|
||||
}
|
||||
if (parentHasBrowser) {
|
||||
this.currentParentTab.linkedBrowser.closest(".browserSidebarContainer").classList.remove("zen-glance-background");
|
||||
this.currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('zen-glance-background');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,15 +281,15 @@
|
|||
this.animatingFullOpen = true;
|
||||
this.currentParentTab._visuallySelected = false;
|
||||
|
||||
this.browserWrapper.removeAttribute("has-finished-animation");
|
||||
this.browserWrapper.setAttribute("animate-full", true);
|
||||
this.#currentTab.removeAttribute("zen-glance-tab");
|
||||
this.browserWrapper.removeAttribute('has-finished-animation');
|
||||
this.browserWrapper.setAttribute('animate-full', true);
|
||||
this.#currentTab.removeAttribute('zen-glance-tab');
|
||||
gBrowser.selectedTab = this.#currentTab;
|
||||
this.currentParentTab.linkedBrowser.closest(".browserSidebarContainer").classList.remove("zen-glance-background");
|
||||
this.currentParentTab.linkedBrowser.closest('.browserSidebarContainer').classList.remove('zen-glance-background');
|
||||
setTimeout(() => {
|
||||
window.requestAnimationFrame(() => {
|
||||
this.browserWrapper.setAttribute("animate-full-end", true);
|
||||
this.overlay.classList.remove("zen-glance-overlay");
|
||||
this.browserWrapper.setAttribute('animate-full-end', true);
|
||||
this.overlay.classList.remove('zen-glance-overlay');
|
||||
setTimeout(() => {
|
||||
this.animatingFullOpen = false;
|
||||
this.closeGlance({ noAnimation: true });
|
||||
|
@ -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: {},
|
||||
},
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 }
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -38,10 +38,10 @@ var ZenThemesCommon = {
|
|||
await IOUtils.writeJSON(this.themesDataFile, {});
|
||||
this.themes = {};
|
||||
gNotificationBox.appendNotification(
|
||||
"zen-themes-corrupted",
|
||||
'zen-themes-corrupted',
|
||||
{
|
||||
label: { "l10n-id": "zen-themes-corrupted" },
|
||||
image: "chrome://browser/skin/notification-icons/persistent-storage-blocked.svg",
|
||||
label: { 'l10n-id': 'zen-themes-corrupted' },
|
||||
image: 'chrome://browser/skin/notification-icons/persistent-storage-blocked.svg',
|
||||
priority: gNotificationBox.PRIORITY_WARNING_HIGH,
|
||||
},
|
||||
[]
|
||||
|
|
|
@ -303,15 +303,15 @@ var gZenThemesImporter = new (class {
|
|||
}
|
||||
})();
|
||||
|
||||
gZenActorsManager.addJSWindowActor("ZenThemeMarketplace", {
|
||||
gZenActorsManager.addJSWindowActor('ZenThemeMarketplace', {
|
||||
parent: {
|
||||
esModuleURI: "chrome://browser/content/zen-components/actors/ZenThemeMarketplaceParent.sys.mjs",
|
||||
esModuleURI: 'chrome://browser/content/zen-components/actors/ZenThemeMarketplaceParent.sys.mjs',
|
||||
},
|
||||
child: {
|
||||
esModuleURI: "chrome://browser/content/zen-components/actors/ZenThemeMarketplaceChild.sys.mjs",
|
||||
esModuleURI: 'chrome://browser/content/zen-components/actors/ZenThemeMarketplaceChild.sys.mjs',
|
||||
events: {
|
||||
DOMContentLoaded: {},
|
||||
},
|
||||
},
|
||||
matches: [...Services.prefs.getStringPref("zen.injections.match-urls").split(","), "about:preferences"],
|
||||
matches: [...Services.prefs.getStringPref('zen.injections.match-urls').split(','), 'about:preferences'],
|
||||
});
|
||||
|
|
|
@ -41,7 +41,7 @@ class SplitNode extends SplitLeafNode {
|
|||
}
|
||||
|
||||
set children(children) {
|
||||
if (children) children.forEach(c => c.parent = this);
|
||||
if (children) children.forEach((c) => (c.parent = this));
|
||||
this._children = children;
|
||||
}
|
||||
|
||||
|
@ -74,17 +74,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
|||
XPCOMUtils.defineLazyPreferenceGetter(this, 'minResizeWidth', 'zen.splitView.min-resize-width', 7);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, '_edgeHoverSize', 'zen.splitView.rearrange-edge-hover-size', 24);
|
||||
|
||||
ChromeUtils.defineLazyGetter(
|
||||
this,
|
||||
'overlay',
|
||||
() => document.getElementById('zen-splitview-overlay')
|
||||
);
|
||||
ChromeUtils.defineLazyGetter(this, 'overlay', () => document.getElementById('zen-splitview-overlay'));
|
||||
|
||||
ChromeUtils.defineLazyGetter(
|
||||
this,
|
||||
'dropZone',
|
||||
() => document.getElementById('zen-splitview-dropzone')
|
||||
);
|
||||
ChromeUtils.defineLazyGetter(this, 'dropZone', () => document.getElementById('zen-splitview-dropzone'));
|
||||
|
||||
window.addEventListener('TabClose', this.handleTabClose.bind(this));
|
||||
this.initializeContextMenu();
|
||||
|
@ -150,7 +142,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
|||
parent.children.splice(childIndex, 1);
|
||||
if (parent.children.length !== 1) {
|
||||
const otherNodeIncrease = 100 / (100 - toRemove.sizeInParent);
|
||||
parent.children.forEach(c => c.sizeInParent *= otherNodeIncrease);
|
||||
parent.children.forEach((c) => (c.sizeInParent *= otherNodeIncrease));
|
||||
return parent;
|
||||
}
|
||||
// node that is not a leaf cannot have less than 2 children, this makes for better resizing
|
||||
|
@ -164,8 +156,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
|||
parent.parent.children[idx] = leftOverChild;
|
||||
} else {
|
||||
// node cannot have same direction as it's parent
|
||||
leftOverChild.children.forEach(c => {
|
||||
c.sizeInParent *= leftOverChild.sizeInParent / 100
|
||||
leftOverChild.children.forEach((c) => {
|
||||
c.sizeInParent *= leftOverChild.sizeInParent / 100;
|
||||
c.parent = parent.parent;
|
||||
});
|
||||
parent.parent.children.splice(idx, 1, ...leftOverChild.children);
|
||||
|
@ -174,7 +166,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
|||
this._removeNodeSplitters(parent, false);
|
||||
return parent.parent;
|
||||
} else {
|
||||
const viewData = Object.values(this._data).find(s => s.layoutTree === parent);
|
||||
const viewData = Object.values(this._data).find((s) => s.layoutTree === parent);
|
||||
viewData.layoutTree = leftOverChild;
|
||||
leftOverChild.positionToRoot = null;
|
||||
leftOverChild.parent = null;
|
||||
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -33,7 +33,7 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
|
|||
id: meta.getAttribute('data-id'),
|
||||
name: meta.getAttribute('data-name'),
|
||||
author: meta.getAttribute('data-author'),
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -94,13 +94,9 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild {
|
|||
}
|
||||
|
||||
injectMarkplaceAPI() {
|
||||
Cu.exportFunction(
|
||||
this.installTheme.bind(this),
|
||||
this.contentWindow,
|
||||
{
|
||||
defineAs: "ZenInstallTheme",
|
||||
}
|
||||
);
|
||||
Cu.exportFunction(this.installTheme.bind(this), this.contentWindow, {
|
||||
defineAs: 'ZenInstallTheme',
|
||||
});
|
||||
}
|
||||
|
||||
async addIntallButtons() {
|
||||
|
|
|
@ -1083,38 +1083,38 @@ Preferences.addAll([
|
|||
default: false,
|
||||
},
|
||||
{
|
||||
id: "zen.glance.activation-method",
|
||||
type: "string",
|
||||
default: "ctrl",
|
||||
id: 'zen.glance.activation-method',
|
||||
type: 'string',
|
||||
default: 'ctrl',
|
||||
},
|
||||
{
|
||||
id: "zen.glance.enabled",
|
||||
type: "bool",
|
||||
id: 'zen.glance.enabled',
|
||||
type: 'bool',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
id: "zen.theme.color-prefs.use-workspace-colors",
|
||||
type: "bool",
|
||||
id: 'zen.theme.color-prefs.use-workspace-colors',
|
||||
type: 'bool',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
id: "zen.view.compact.color-toolbar",
|
||||
type: "bool",
|
||||
id: 'zen.view.compact.color-toolbar',
|
||||
type: 'bool',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
id: "zen.urlbar.behavior",
|
||||
type: "string",
|
||||
default: "float",
|
||||
id: 'zen.urlbar.behavior',
|
||||
type: 'string',
|
||||
default: 'float',
|
||||
},
|
||||
{
|
||||
id: "zen.view.compact.color-sidebar",
|
||||
type: "bool",
|
||||
id: 'zen.view.compact.color-sidebar',
|
||||
type: 'bool',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
id: "zen.essentials.enabled",
|
||||
type: "bool",
|
||||
id: 'zen.essentials.enabled',
|
||||
type: 'bool',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
|
@ -1123,18 +1123,18 @@ Preferences.addAll([
|
|||
default: false,
|
||||
},
|
||||
{
|
||||
id: "zen.tabs.show-newtab-vertical",
|
||||
type: "bool",
|
||||
id: 'zen.tabs.show-newtab-vertical',
|
||||
type: 'bool',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
id: "zen.view.show-newtab-button-border-top",
|
||||
type: "bool",
|
||||
id: 'zen.view.show-newtab-button-border-top',
|
||||
type: 'bool',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
id: "zen.view.show-newtab-button-top",
|
||||
type: "bool",
|
||||
id: 'zen.view.show-newtab-button-top',
|
||||
type: 'bool',
|
||||
default: true,
|
||||
},
|
||||
]);
|
||||
|
|
|
@ -53,8 +53,8 @@ body {
|
|||
|
||||
& button {
|
||||
opacity: 0;
|
||||
animation: fadeIn .5s ease-in-out forwards;
|
||||
animation-delay: .8s;
|
||||
animation: fadeIn 0.5s ease-in-out forwards;
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
& button:nth-child(2) {
|
||||
|
@ -258,7 +258,7 @@ input[type='checkbox'] {
|
|||
.delay-animation,
|
||||
.delay-animation-2 {
|
||||
opacity: 0;
|
||||
animation: fadeIn .5s ease-in-out forwards;
|
||||
animation: fadeIn 0.5s ease-in-out forwards;
|
||||
}
|
||||
|
||||
#importBrowser {
|
||||
|
@ -345,7 +345,7 @@ input[type='checkbox'] {
|
|||
|
||||
#welcome {
|
||||
& h1 {
|
||||
animation-duration: .8s !important;
|
||||
animation-duration: 0.8s !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,7 +405,8 @@ input[type='checkbox'] {
|
|||
border: 3px solid light-dark(#000, #fff);
|
||||
}
|
||||
|
||||
#welcome, #thanks {
|
||||
#welcome,
|
||||
#thanks {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ groupbox h2 {
|
|||
--zen-compact-mode-styles-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.1);
|
||||
|
||||
@media not (prefers-color-scheme: dark) {
|
||||
--zen-compact-mode-styles-shadow: 0 0 .5px .5px rgba(0, 0, 0, 0.1);
|
||||
--zen-compact-mode-styles-shadow: 0 0 0.5px 0.5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
box-shadow: var(--zen-compact-mode-styles-shadow);
|
||||
|
@ -644,5 +644,5 @@ groupbox h2 {
|
|||
|
||||
.sync-engine-workspaces .checkbox-icon,
|
||||
.sync-engine-workspaces.sync-engine-image {
|
||||
list-style-image: url("chrome://devtools/skin/images/tool-storage.svg");
|
||||
list-style-image: url('chrome://devtools/skin/images/tool-storage.svg');
|
||||
}
|
||||
|
|
|
@ -577,7 +577,6 @@
|
|||
fill: white !important;
|
||||
}
|
||||
|
||||
|
||||
/* reload/stop animation */
|
||||
#stop-reload-button[animate]
|
||||
> #reload-button[displaystop]
|
||||
|
|
|
@ -47,9 +47,7 @@
|
|||
}
|
||||
},
|
||||
"license": {
|
||||
"ignoredFiles": [
|
||||
".*\\.json"
|
||||
],
|
||||
"ignoredFiles": [".*\\.json"],
|
||||
"licenseType": "MPL-2.0"
|
||||
},
|
||||
"updateHostname": "updates.zen-browser.app"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue