1
0
mirror of https://github.com/XFox111/TabsAsideExtension.git synced 2026-07-02 19:52:47 +03:00

Compare commits

...

9 Commits

Author SHA1 Message Date
Michael Gordeev 8d2c83eea6 Patch 1.8.1 (#38)
- Added spanish translation #37 

Co-authored-by: @Wafflects
2020-09-04 01:31:17 +03:00
Michael Gordeev 3e60583427 Minor 1.8 (#34)
- Ability to rename Tab Groups #33
- Added collections view switch #35
2020-08-29 18:39:51 +03:00
Michael Gordeev 10edf4f975 Repo documentation link typos fixed 2020-08-14 14:43:49 +03:00
Michael Gordeev cc854fbd25 Updated README.md 2020-08-11 19:04:20 +03:00
Michael Gordeev ad9acb6208 Create ci.yaml 2020-08-11 18:56:30 +03:00
Michael Gordeev f74eeb5759 [v1.7.3] Firefox compability patch (#32)
- Added Firefox support (#28)
- Updated settings defaults
- Updated `about:` protocol behavior
- Fixed collections header becoming the old one on a tab removing
- Added VS Code debugging config
- Removed trailing whitespaces
2020-08-10 23:46:37 +03:00
Michael Gordeev 80c9dbe1a5 HOTFIX: Chinese language pack path typo fixed 2020-08-05 12:29:01 +03:00
Michael Gordeev c777f1a60a Minor 1.7 (#31)
- Complete UI/UX overhaul
- Updated default hotkeys (#27)
- Added option to disable deletion confirmation (#29)
- Added Chinese translation
- Fixed font artifacts on Windows

Co-authored-by: Dustin-Jiang <56217843+Dustin-Jiang@users.noreply.github.com>
Co-Authored-By: Michael Gordeev <michael@xfox111.net>
2020-08-05 12:07:11 +03:00
Michael Gordeev 1b7b419168 Patch 1.6.1
One tab remove button removes whole collection fixed (#25)
2020-07-18 21:39:15 +03:00
16 changed files with 897 additions and 313 deletions
+73
View File
@@ -0,0 +1,73 @@
name: CI
on:
workflow_dispatch:
push:
branches: [ master ]
paths:
# Trigger deploy on manifest change
- 'manifest.json'
jobs:
Firefox:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build Extension for Firefox
id: web-ext-build
uses: kewisch/action-web-ext@v1
with:
cmd: build
- name: Sign build
id: web-ext-sign
uses: kewisch/action-web-ext@v1
with:
cmd: sign
source: ${{ steps.web-ext-build.outputs.target }}
apiKey: ${{ secrets.FIREFOX_API_KEY }}
apiSecret: ${{ secrets.FIREFOX_CLIENT_SECRET }}
- name: Publish to Firefox Webstore
uses: trmcnvn/firefox-addon@v1
with:
uuid: tabsaside@xfox111.net
xpi: ${{ steps.web-ext-sign.outputs.target }}
manifest: ./manifest.json
api-key: ${{ secrets.FIREFOX_API_KEY }}
api-secret: ${{ secrets.FIREFOX_CLIENT_SECRET }}
- name: Drop artifacts
uses: actions/upload-artifact@v2
with:
name: 'Firefox Artefacts'
path: ${{ steps.web-ext-sign.outputs.target }}
Chrome:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Pack extension
uses: TheDoctor0/zip-release@0.4.1
with:
filename: ./TabsAside.zip
exclusions: '.git/* .vscode/* .github/* *.md'
- name: Publish to Chrome Webstore
uses: SebastienGllmt/chrome-addon@v3
with:
extension: mgmjbodjgijnebfgohlnjkegdpbdjgin
zip: ./TabsAside.zip
client-id: ${{ secrets.CHROME_CLIENT_ID }}
client-secret: ${{ secrets.CHROME_CLIENT_SECRET }}
refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}
- name: Drop artifacts
uses: actions/upload-artifact@v2
with:
name: 'Chrome Artifacts'
path: ./TabsAside.zip
+13
View File
@@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations":
[
{
"name": "Debug",
"type": "firefox",
"request": "launch",
"reAttach": true,
"addonPath": "${workspaceFolder}"
}
]
}
+8 -8
View File
@@ -4,7 +4,7 @@ Welcome, and thank you for your interest in contributing to my project!
There are many ways in which you can contribute, beyond writing code. The goal of this document is to provide a high-level overview of how you can get involved.
## Table of Contents
- [Contribution Guidelines](#gutschedule-contribution-guidelines)
- [Contribution Guidelines](#contribution-guidelines)
- [Table of Contents](#table-of-contents)
- [Asking Questions](#asking-questions)
- [Providing Feedback](#providing-feedback)
@@ -35,15 +35,15 @@ Have a question? Rather than opening an issue, please ask me directly on opensou
## Providing Feedback
Your comments and feedback are welcome.
You can leave your feedbak on feedback@xfox111.net or do it on [Microsoft Edge Add-ons Webstore](https://microsoftedge.microsoft.com/addons/detail/tabs-aside/kmnblllmalkiapkfknnlpobmjjdnlhnd) or [Chrome Webstore](https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin)
You can leave your feedbak on feedback@xfox111.net or do it on [Microsoft Edge Add-ons Webstore](https://microsoftedge.microsoft.com/addons/detail/tabs-aside/kmnblllmalkiapkfknnlpobmjjdnlhnd), [Chrome Extensions Webstore](https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin) or [Mozilla Add-ons Webstore](https://addons.mozilla.org/firefox/addon/ms-edge-tabs-aside/)
## Reporting Issues
Have you identified a reproducible problem in the extension? Have a feature request? I'd like to hear it! Here's how you can make reporting your issue as effective as possible.
### Look For an Existing Issue
Before you create a new issue, please do a search in [open issues](https://github.com/xfox111/ChromiumTabsAside/issues) to see if the issue or feature request has already been filed.
Before you create a new issue, please do a search in [open issues](https://github.com/xfox111/TabsAsideExtension/issues) to see if the issue or feature request has already been filed.
Be sure to scan through the [feature requests](https://github.com/XFox111/ChromiumTabsAside/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement).
Be sure to scan through the [feature requests](https://github.com/XFox111/TabsAsideExtension/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement).
If you find your issue already exists, make relevant comments and add your [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments). Use a reaction in place of a "+1" comment:
@@ -83,7 +83,7 @@ If you are interested in writing code to fix issues or implement new awesome fea
### Deploy test version on your browser
1. Clone repository to local storage using [Git](https://guides.github.com/introduction/git-handbook/)
```
git clone https://github.com/xfox111/ChromiumTabsAside.git
git clone https://github.com/xfox111/TabsAsideExtension.git
```
2. Enable Developers mode on your browser extensions page
3. Click "Load unpacked" button and navigate to the extension root folder (contains `manifest.json`)
@@ -135,14 +135,14 @@ Use "double quotes" wherever it's possible
}
```
- Put spaces between operators and before braces in methods declarations, conditionals and loops
- Wrong:
- Wrong:
- `y=k*x+b`
- `function FunctionName()`
- Correct:
- `y = k * x + b`
- `function FunctionName ()`
- Use ternary conditionals wherever it's possible
- Wrong:
- Wrong:
```
var s;
if (condition)
@@ -175,7 +175,7 @@ Use "double quotes" wherever it's possible
```
### Finding an issue to work on
Check out the [full issues list](https://github.com/XFox111/ChromiumTabsAside/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue) for a list of all potential areas for contributions. **Note** that just because an issue exists in the repository does not mean we will accept a contribution. There are several reasons we may not accept a pull request like:
Check out the [full issues list](https://github.com/XFox111/TabsAsideExtension/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue) for a list of all potential areas for contributions. **Note** that just because an issue exists in the repository does not mean we will accept a contribution. There are several reasons we may not accept a pull request like:
- Performance - One of Tabs Aside core values is to deliver a lightweight extension, that means it should perform well in both real and test environments.
- User experience - Since we want to deliver a lightweight extension, the UX should feel lightweight as well and not be cluttered. Most changes to the UI should go through the issue owner and project owner (@XFox111).
+28 -21
View File
@@ -1,56 +1,63 @@
# Tabs aside for Google Chrome
# Tabs aside
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/xfox111/TabsAsideExtension)](https://github.com/xfox111/TabsAsideExtension/releases/latest)
![CI](https://github.com/XFox111/TabsAsideExtension/workflows/CI/badge.svg)
[![Chrome Web Store](https://img.shields.io/chrome-web-store/users/mgmjbodjgijnebfgohlnjkegdpbdjgin?label=Chrome%20Web%20Store%20downloads)](https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin)
[![Chrome Web Store](https://img.shields.io/chrome-web-store/users/mgmjbodjgijnebfgohlnjkegdpbdjgin?label=Chrome%20Webstore%20downloads)](https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin)
[![Chrome Web Store](https://img.shields.io/chrome-web-store/rating/mgmjbodjgijnebfgohlnjkegdpbdjgin)](https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/xfox111/chromiumtabsaside)](https://github.com/xfox111/chromiumtabsaside/releases/latest)
[![GitHub issues](https://img.shields.io/github/issues/xfox111/chromiumtabsaside)](https://github.com/xfox111/ChromiumTabsAside/issues)
[![GitHub last commit](https://img.shields.io/github/last-commit/xfox111/chromiumtabsaside)](https://github.com/xfox111/ChromiumTabsAside/commits/master)
[![GitHub repo size](https://img.shields.io/github/repo-size/xfox111/chromiumtabsaside?label=repo%20size)](https://github.com/xfox111/ChromiumTabsAside)
[![MIT License](https://img.shields.io/github/license/xfox111/chromiumtabsaside)](https://opensource.org/licenses/MIT)
[![Mozilla Add-on](https://img.shields.io/amo/users/ms-edge-tabs-aside?label=Firefox%20Webstore%20downloads)](https://addons.mozilla.org/firefox/addon/ms-edge-tabs-aside/)
[![Mozilla Add-on](https://img.shields.io/amo/rating/ms-edge-tabs-aside)](https://addons.mozilla.org/firefox/addon/ms-edge-tabs-aside/)
[![Mozilla Add-on](https://img.shields.io/amo/dw/ms-edge-tabs-aside)](https://addons.mozilla.org/firefox/addon/ms-edge-tabs-aside/)
[![GitHub issues](https://img.shields.io/github/issues/xfox111/TabsAsideExtension)](https://github.com/xfox111/TabsAsideExtension/issues)
[![GitHub last commit](https://img.shields.io/github/last-commit/xfox111/TabsAsideExtension)](https://github.com/xfox111/TabsAsideExtension/commits/master)
[![GitHub repo size](https://img.shields.io/github/repo-size/xfox111/TabsAsideExtension?label=repo%20size)](https://github.com/xfox111/TabsAsideExtension)
[![MIT License](https://img.shields.io/github/license/xfox111/TabsAsideExtension)](https://opensource.org/licenses/MIT)
[![Twitter Follow](https://img.shields.io/twitter/follow/xfox111?style=social)](https://twitter.com/xfox111)
[![GitHub followers](https://img.shields.io/github/followers/xfox111?label=Follow%20@xfox111&style=social)](https://github.com/xfox111)
[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-%40xfox111-orange)](https://buymeacoffee.com/xfox111)
![Tabs aside](https://xfox111.net/images/TabsAside.png)
![Tabs aside](https://xfox111.net/y7xk3z)
If youre like me, you often find yourself with a bunch of open tabs. Youd like to get those tabs out of the way sometimes, but theyre maybe not worth saving as actual bookmarks.
In the Edge browser, Microsoft has introduced a new feature called "Tabs aside" (or Tab groups) which lets you set tabs aside in a sort of temporary workspace so that you can call them back up later.
Unfortunately, in new Chromium-based Microsoft Edge, the devs decided not to implement this must-have-feature. So I've decided to create a browser extension which replicates this awesome feature in Chromium-based browsers
Unfortunately, in new Chromium-based Microsoft Edge, the devs decided not to implement this must-have-feature. So I've decided to create a browser extension which replicates this awesome feature
## Features
- Familiar UI inherited from legacy Microsoft Edge with some improvements
- Auto Dark mode
- Now you can restore one tab from collection without removing
- Now you can choose if you want to load restored tabs only when you're navigating onto them
- **Now available for Firefox!**
## Download
- [Google Chrome Webstore](https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin)
- [Microsoft Edge Add-ons Webstore](https://microsoftedge.microsoft.com/addons/detail/kmnblllmalkiapkfknnlpobmjjdnlhnd)
- [GitHub Releases](https://github.com/xfox111/chromiumtabsaside/releases/latest)
- [Firefox Add-ons](https://addons.mozilla.org/firefox/addon/ms-edge-tabs-aside/)
- [GitHub Releases](https://github.com/xfox111/TabsAsideExtension/releases/latest)
## Project roadmap
You can go to the project's [roadmap kanban board](https://github.com/XFox111/ChromiumTabsAside/projects/1) and see what have we planned and watch our progress in realtime
You can go to the project's [roadmap kanban board](https://github.com/XFox111/TabsAsideExtension/projects/1) and see what have we planned and watch our progress in realtime
## Contributing
There are many ways in which you can participate in the project, for example:
- [Submit bugs and feature requests](https://github.com/xfox111/gutschedule/issues), and help us verify as they are checked in
- Review [source code changes](https://github.com/xfox111/gutschedule/pulls)
- [Submit bugs and feature requests](https://github.com/xfox111/TabsAsideExtension/issues), and help us verify as they are checked in
- Review [source code changes](https://github.com/xfox111/TabsAsideExtension/pulls)
- Review documentation and make pull requests for anything from typos to new content
If you are interested in fixing issues and contributing directly to the code base, please see the [Contribution Guidelines](https://github.com/XFox111/ChromiumTabsAside/blob/master/CONTRIBUTING.md), which covers the following:
- [How to deploy the extension on your browser](https://github.com/XFox111/ChromiumTabsAside/blob/master/CONTRIBUTING.md#deploy-test-version-on-your-browser)
- [The development workflow](https://github.com/XFox111/ChromiumTabsAside/blob/master/CONTRIBUTING.md#development-workflow), including debugging and running tests
- [Coding guidelines](https://github.com/XFox111/ChromiumTabsAside/blob/master/CONTRIBUTING.md#coding-guidelines)
- [Submitting pull requests](https://github.com/XFox111/ChromiumTabsAside/blob/master/CONTRIBUTING.md#submitting-pull-requests)
- [Finding an issue to work on](https://github.com/XFox111/ChromiumTabsAside/blob/master/CONTRIBUTING.md#finding-an-issue-to-work-on)
- [Contributing to translations](https://github.com/XFox111/ChromiumTabsAside/blob/master/CONTRIBUTING.md#contributing-to-translations)
If you are interested in fixing issues and contributing directly to the code base, please see the [Contribution Guidelines](https://github.com/XFox111/TabsAsideExtension/blob/master/CONTRIBUTING.md), which covers the following:
- [How to deploy the extension on your browser](https://github.com/XFox111/TabsAsideExtension/blob/master/CONTRIBUTING.md#deploy-test-version-on-your-browser)
- [The development workflow](https://github.com/XFox111/TabsAsideExtension/blob/master/CONTRIBUTING.md#development-workflow), including debugging and running tests
- [Coding guidelines](https://github.com/XFox111/TabsAsideExtension/blob/master/CONTRIBUTING.md#coding-guidelines)
- [Submitting pull requests](https://github.com/XFox111/TabsAsideExtension/blob/master/CONTRIBUTING.md#submitting-pull-requests)
- [Finding an issue to work on](https://github.com/XFox111/TabsAsideExtension/blob/master/CONTRIBUTING.md#finding-an-issue-to-work-on)
- [Contributing to translations](https://github.com/XFox111/TabsAsideExtension/blob/master/CONTRIBUTING.md#contributing-to-translations)
## Code of Conduct
This project has adopted the Contributor Covenant. For more information see the [Code of Conduct](https://github.com/XFox111/ChromiumTabsAside/blob/master/CODE_OF_CONDUCT.md)
This project has adopted the Contributor Covenant. For more information see the [Code of Conduct](https://github.com/XFox111/TabsAsideExtension/blob/master/CODE_OF_CONDUCT.md)
## Copyrights
> ©2020 Michael "XFox" Gordeev
+45 -26
View File
@@ -8,40 +8,59 @@
<link rel="stylesheet" type="text/css" href="css/style.css" />
<link rel="stylesheet" type="text/css" href="css/style.generic.css" />
<link rel="stylesheet" type="text/css" href="css/style.dark.css" />
<link rel="stylesheet" type="text/css" href="css/style.listview.css" />
<meta charset="utf-8" />
</head>
<body>
<div class="tabsAside background">
<aside class="tabsAside pane">
<header>
<div>
<h1 loc="name">Tabs aside</h1>
<button loc_alt="options" class="btn more" title="Options"></button>
<h1 loc="name">Tabs aside</h1>
<button loc_alt="options" class="btn more" title="Options"></button>
<nav>
<p>
<input type="checkbox" id="loadOnRestore"/>
<label loc="loadOnRestore" for="loadOnRestore">Load tabs on restore</label>
</p>
<p>
<input type="checkbox" id="swapIconAction"/>
<label loc="swapIconAction" for="swapIconAction">Set tabs aside on extension icon click (Alt+P or right-click to open the pane)</label>
</p>
<div>
<button loc="github" value="https://github.com/xfox111/ChromiumTabsAside">Visit GitHub page</button>
<button loc="contributors" value="https://github.com/XFox111/ChromiumTabsAside/graphs/contributors">Project contributors</button>
<button loc="feedback" feedback-button>Leave feedback</button>
<button loc="buyMeACoffee" value="https://buymeacoffee.com/xfox111">Buy me a coffee!</button>
</div>
<p>
<small>v1.0</small><br />
<span loc="credits">Developed by Michael Gordeev</span> (<a href="https://twitter.com/xfox111"
target="_blank">@xfox111</a>)
</p>
</nav>
</div>
<nav>
<p>
<input type="checkbox" id="loadOnRestore" />
<label loc="loadOnRestore" for="loadOnRestore">Load tabs on restore</label>
</p>
<p>
<input type="checkbox" id="swapIconAction" />
<label loc="swapIconAction" for="swapIconAction">Set tabs aside on extension icon click (Alt+P or right-click to open the pane)</label>
</p>
<p>
<input type="checkbox" id="showDeleteDialog" />
<label loc="showDeleteDialog" for="showDeleteDialog">Show confirmation dialog before deleting an item</label>
</p>
<hr />
<div>
<button loc="github" value="https://github.com/xfox111/TabsAsideExtension">Visit GitHub page</button>
<button loc="contributors" value="https://github.com/XFox111/TabsAsideExtension/graphs/contributors">Project contributors</button>
<button loc="feedback" feedback-button>Leave feedback</button>
<button loc="buyMeACoffee" value="https://buymeacoffee.com/xfox111">Buy me a coffee!</button>
</div>
<hr />
<p>
<small>v1.0</small><br />
<span loc="credits">Developed by Michael Gordeev</span> (<a href="https://twitter.com/xfox111" target="_blank">@xfox111</a>)
</p>
</nav>
<button loc_alt="closePanel" class="btn remove" title="Close panel"></button>
<a class="saveTabs"><span class="iconArrowRight"></span> <span loc="setAside">Set current tabs aside</span></a>
<hr />
<div class="listviewSwitch tile">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="listviewSwitch list">
<div></div>
<div></div>
<div></div>
</div>
</header>
<section>
+14 -44
View File
@@ -6,7 +6,7 @@
},
"description":
{
"message": "Classic Microsoft Edge \"Tabs Aside\" feature for Chromium browsers",
"message": "Classic Microsoft Edge \"Tabs Aside\" feature",
"description": "Extension description"
},
"author":
@@ -19,14 +19,24 @@
"message": "Options",
"description": "Alternative text for options button in the pane"
},
"closePanel":
{
"message": "Close",
"description": "Alternative text for close panel button"
},
"loadOnRestore":
{
"message": "Load tabs on restore",
"description": "Label for option"
},
"showDeleteDialog":
{
"message": "Show confirmation dialog before deleting an item",
"description": "Label for option"
},
"swapIconAction":
{
"message": "Set tabs aside on extension icon click (Alt+P or right-click to open the pane)",
"message": "Set tabs aside on extension icon click (%TOGGLE_SHORTCUT% or right-click to open the pane)",
"description": "Label for option"
},
"github":
@@ -111,47 +121,7 @@
},
"tabs":
{
"message": "Tabs",
"description": "Collection tabs counter label"
},
"ago":
{
"message": "ago",
"description": "Human friendly timestamp part (e.g. 15 hour(s) ago)"
},
"minutes":
{
"message": "minute(s)",
"description": "Human friendly timestamp part (e.g. 15 minute(s) ago)"
},
"hours":
{
"message": "hour(s)",
"description": "Human friendly timestamp part (e.g. 15 hour(s) ago)"
},
"days":
{
"message": "day(s)",
"description": "Human friendly timestamp part (e.g. 15 day(s) ago)"
},
"weeks":
{
"message": "week(s)",
"description": "Human friendly timestamp part (e.g. 15 week(s) ago)"
},
"months":
{
"message": "month(s)",
"description": "Human friendly timestamp part (e.g. 15 month(s) ago)"
},
"years":
{
"message": "years(s)",
"description": "Human friendly timestamp part (e.g. 15 years(s) ago)"
},
"justNow":
{
"message": "Just now",
"description": "Human friendly timestamp part"
"message": "items",
"description": "Collection tabs counter label (e.g. 8 items)"
}
}
+127
View File
@@ -0,0 +1,127 @@
{
"name":
{
"message": "Pestañas que has reservado",
"description": "Extension name. Displayed in the manifest and pane header"
},
"description":
{
"message": "Función \"Reservar pestañas\" de Microsoft Edge clásico",
"description": "Extension description"
},
"author":
{
"message": "Michael \"XFox\" Gordeev",
"description": "Author name"
},
"options":
{
"message": "Opciones",
"description": "Alternative text for options button in the pane"
},
"closePanel":
{
"message": "Cerrar",
"description": "Alternative text for close panel button"
},
"loadOnRestore":
{
"message": "Cargar pestañas al restaurar",
"description": "Label for option"
},
"showDeleteDialog":
{
"message": "Mostrar diálogo de confirmacion antes de eliminar un item",
"description": "Label for option"
},
"swapIconAction":
{
"message": "Reservar pestañas al apretar el icono de la extensión (%TOGGLE_SHORTCUT% o click-derecho para abrir el panel)",
"description": "Label for option"
},
"github":
{
"message": "Visitar la pagina de GitHub",
"description": "Link title"
},
"contributors":
{
"message": "Contribuidores del proyecto",
"description": "Link title"
},
"feedback":
{
"message": "Deja un comentario",
"description": "Link title"
},
"buyMeACoffee":
{
"message": "¡Comprame un cafe!",
"description": "Link title"
},
"credits":
{
"message": "Desarrollado por Michael 'XFox' Gordeev",
"description": "Options menu credits"
},
"setAside":
{
"message": "Reservar las pestañas actuales",
"description": "Save collection action name. Used in the pane, extension context menu and manifest shortcuts"
},
"nothingSaved":
{
"message": "No tienes pestañas reservadas",
"description": "Placeholder for empty pane"
},
"removeTab":
{
"message": "Eliminar pestañas de la colección",
"description": "Button hint on a tab card"
},
"restoreTabs":
{
"message": "Restaurar pestañas",
"description": "Collection restore action link name"
},
"more":
{
"message": "Más...",
"description": "Collections' more button title"
},
"restoreNoRemove":
{
"message": "Restaurar sin eliminar",
"description": "Context action item name"
},
"removeCollection":
{
"message": "Eliminar la colección",
"description": "Collection remove action name"
},
"removeCollectionConfirm":
{
"message": "¿Está seguro que quiere eliminar esta colección?",
"description": "Prompt dialog content on collection deletion"
},
"removeTabConfirm":
{
"message": "¿Está seguro que quiere eliminar esta pestaña?",
"description": "Prompt dialog content on one tab deletion"
},
"togglePaneContext":
{
"message": "Abrir panel de pestañas",
"description": "Context action name. Used in extension context menu and manifest shortcuts"
},
"noTabsToSave":
{
"message": "No hay pestañas disponibles para reservar",
"description": "Alert dialog message when there's no tabs to save"
},
"tabs":
{
"message": "items",
"description": "Collection tabs counter label (e.g. 8 items)"
}
}
+14 -44
View File
@@ -6,7 +6,7 @@
},
"description":
{
"message": "Функиця классического Microsoft Edge на браузерах Chromium",
"message": "Функиця отложенных вкладок классического Microsoft Edge",
"description": "Extension description"
},
"author":
@@ -19,14 +19,24 @@
"message": "Настройки",
"description": "Alternative text for options button in the pane"
},
"closePanel":
{
"message": "Закрыть",
"description": "Alternative text for close panel button"
},
"loadOnRestore":
{
"message": "Загружать вкладки после открытия",
"description": "Label for option"
},
"showDeleteDialog":
{
"message": "Показывать окно подтверждения перед удалением элемента",
"description": "Label for option"
},
"swapIconAction":
{
"message": "Откладывать вкладки при нажатии на иконку расширения (Alt+P или правая кнопка мыши для открытия панели)",
"message": "Откладывать вкладки при нажатии на иконку расширения (%TOGGLE_SHORTCUT% или правая кнопка мыши для открытия панели)",
"description": "Label for option"
},
"github":
@@ -111,47 +121,7 @@
},
"tabs":
{
"message": "Вкладок",
"description": "Collection tabs counter label"
},
"ago":
{
"message": "назад",
"description": "Human friendly timestamp part (e.g. 15 hour(s) ago)"
},
"minutes":
{
"message": "минут(ы)",
"description": "Human friendly timestamp part (e.g. 15 minute(s) ago)"
},
"hours":
{
"message": "час(ов)",
"description": "Human friendly timestamp part (e.g. 15 hour(s) ago)"
},
"days":
{
"message": "дней",
"description": "Human friendly timestamp part (e.g. 15 day(s) ago)"
},
"weeks":
{
"message": "недель",
"description": "Human friendly timestamp part (e.g. 15 week(s) ago)"
},
"months":
{
"message": "месяц(ев)",
"description": "Human friendly timestamp part (e.g. 15 month(s) ago)"
},
"years":
{
"message": "лет",
"description": "Human friendly timestamp part (e.g. 15 years(s) ago)"
},
"justNow":
{
"message": "Только что",
"description": "Human friendly timestamp part"
"message": "вкладок",
"description": "Collection tabs counter label (e.g. 8 items)"
}
}
+127
View File
@@ -0,0 +1,127 @@
{
"name":
{
"message": "搁置的标签页",
"description": "Extension name. Displayed in the manifest and pane header"
},
"description":
{
"message": "为Chromium浏览器提供旧版 Microsoft Edge 中的\"搁置标签页\" 功能",
"description": "Extension description"
},
"author":
{
"message": "Michael \"XFox\" Gordeev",
"description": "Author name"
},
"options":
{
"message": "设置",
"description": "Alternative text for options button in the pane"
},
"closePanel":
{
"message": "关闭",
"description": "Alternative text for close panel button"
},
"loadOnRestore":
{
"message": "在重新打开时加载页面",
"description": "Label for option"
},
"showDeleteDialog":
{
"message": "在删除项目之前显示确认对话框",
"description": "Label for option"
},
"swapIconAction":
{
"message": "点击拓展图标来搁置所有标签页 (按%TOGGLE_SHORTCUT%或右键来打开侧栏)",
"description": "Label for option"
},
"github":
{
"message": "查看GitHub页面",
"description": "Link title"
},
"contributors":
{
"message": "项目贡献者",
"description": "Link title"
},
"feedback":
{
"message": "给我们反馈",
"description": "Link title"
},
"buyMeACoffee":
{
"message": "给我买杯咖啡!",
"description": "Link title"
},
"credits":
{
"message": "由Michael 'XFox' Gordeev开发",
"description": "Options menu credits"
},
"setAside":
{
"message": "搁置当前的所有标签页",
"description": "Save collection action name. Used in the pane, extension context menu and manifest shortcuts"
},
"nothingSaved":
{
"message": "你目前没有搁置的标签页",
"description": "Placeholder for empty pane"
},
"removeTab":
{
"message": "从标签页集中移除标签页",
"description": "Button hint on a tab card"
},
"restoreTabs":
{
"message": "恢复标签页",
"description": "Collection restore action link name"
},
"more":
{
"message": "更多...",
"description": "Collections' more button title"
},
"restoreNoRemove":
{
"message": "恢复但不移除标签页",
"description": "Context action item name"
},
"removeCollection":
{
"message": "移除标签页集",
"description": "Collection remove action name"
},
"removeCollectionConfirm":
{
"message": "你确定要移除这个标签页集吗?",
"description": "Prompt dialog content on collection deletion"
},
"removeTabConfirm":
{
"message": "你确定要移除这个标签页吗?",
"description": "Prompt dialog content on one tab deletion"
},
"togglePaneContext":
{
"message": "打开或关闭侧栏",
"description": "Context action name. Used in extension context menu and manifest shortcuts"
},
"noTabsToSave":
{
"message": "没有可以搁置的标签页",
"description": "Alert dialog message when there's no tabs to save"
},
"tabs":
{
"message": "项",
"description": "Collection tabs counter label (e.g. 8 items)"
}
}
+93 -52
View File
@@ -18,8 +18,10 @@
right: 0px;
top: 0px;
bottom: 0px;
overflow: auto;
overflow: hidden;
display: grid;
grid-template-rows: auto 1fr;
width: 100%;
min-width: 500px;
@@ -36,7 +38,7 @@
aside[embedded]
{
width: 40% !important;
width: 500px !important;
}
.tabsAside.pane[opened]
@@ -47,36 +49,28 @@
/* Pane header*/
.tabsAside.pane > header
{
margin: 20px 40px;
z-index: 1;
padding: 14px 20px 16px 20px;
box-shadow: 0px 0px 5px rgba(0,0,0,.5);
background-color: white;
display: grid;
grid-template-columns: 1fr auto auto;
grid-column-gap: 10px;
grid-row-gap: 30px;
}
.tabsAside.pane > header > div
{
display: grid;
grid-template-columns: 1fr auto;
}
.tabsAside.pane > header > div > h1
.tabsAside.pane > header > h1
{
margin: 10px 0px;
font-weight: normal;
font-size: 21pt;
margin: 0px 5px;
font-weight: 500;
font-size: 15pt;
}
.tabsAside.pane > header > div > button
.tabsAside.pane > header > nav
{
margin: auto;
top: 45px;
right: 55px;
}
.tabsAside.pane > header > div > nav
{
top: 70px;
right: 40px;
}
.tabsAside.pane > header nav > div
{
box-shadow: 0px 4px 5px -2px rgba(100, 100, 100, .5);
}
.tabsAside.pane > header nav > p
{
@@ -88,25 +82,37 @@
text-decoration: none;
}
.iconArrowRight
.saveTabs
{
width: 13px;
height: 13px;
display: inline-block;
background-repeat: no-repeat;
background-size: 13px;
background-position: center;
background-image: url("chrome-extension://__MSG_@@extension_id__/icons/arrowRight.svg");
display: inline-grid;
grid-template-columns: 16px auto;
grid-column-gap: 15px;
font-weight: 600;
margin-right: auto;
}
.tabsAside.pane > header > hr
.iconArrowRight
{
border: 1px solid #8a8a8a;
width: 16px;
height: 16px;
display: inline-block;
background-repeat: no-repeat;
background-size: 16px;
background-position: center;
background-image: url("chrome-extension://__MSG_@@extension_id__/icons/arrowRight.svg"),
url("moz-extension://__MSG_@@extension_id__/icons/arrowRight.svg");
margin: 2px;
}
.tabsAside.pane section
{
overflow: auto;
}
.tabsAside.pane > section > h2
{
margin: 0px 40px;
margin: 20px;
font-weight: normal;
}
@@ -116,11 +122,34 @@
transition: .2s;
}
.collectionSet
{
background-color: white;
margin: 10px;
border-radius: 5px;
border: 1px solid #eee;
}
.collectionSet:hover
{
box-shadow: 0px 0px 5px rgba(0, 0, 0, .25);
}
.collectionSet .header > *
{
visibility: hidden;
}
.collectionSet:hover .header > *
{
visibility: visible;
}
.collectionSet > .header
{
margin: 0px 20px;
margin: 10px 10px 0px 20px;
display: grid;
grid-template-columns: auto 1fr auto auto auto;
grid-template-columns: 1fr auto auto auto;
grid-column-gap: 10px;
align-items: center;
}
@@ -128,13 +157,23 @@
.collectionSet > .header > small
{
color: gray;
visibility: visible !important;
}
.collectionSet > .header > span
.collectionSet > .header > input
{
font-weight: 600;
margin: 0px;
visibility: visible !important;
font-weight: 500;
border: none;
background: transparent;
}
.collectionSet > .header > input:hover
{
border: 1px solid black;
}
.collectionSet > .header > a
{
font-size: 11pt;
@@ -149,8 +188,7 @@
/* Tabs collection */
.collectionSet > .set
{
margin: 0px 0px 0px 20px;
padding: 10px 40px 10px 20px;
padding: 5px 10px;
white-space: nowrap;
overflow: auto;
}
@@ -163,7 +201,7 @@
.collectionSet > .set:hover::-webkit-scrollbar-thumb
{
visibility: visible;
}
}
.collectionSet > .set > div
{
@@ -172,21 +210,23 @@
margin: 5px;
background-color: #c2c2c2;
background-image: url("chrome-extension://__MSG_@@extension_id__/images/tab_thumbnail.png");
background-image: url("chrome-extension://__MSG_@@extension_id__/images/tab_thumbnail.png"),
url("chrome-extension://__MSG_@@extension_id__/images/tab_thumbnail.png");
background-size: cover;
background-position-x: center;
display: inline-grid;
grid-template-rows: 1fr auto;
box-shadow: 0px 0px 5px rgba(100, 100, 100, .5);
transition: .25s;
cursor: pointer;
border: 1px solid #eee;
border-radius: 5px;
}
.collectionSet > .set > div:hover
{
filter: brightness(120%);
box-shadow: 0px 0px 15px rgba(100, 100, 100, .5);
box-shadow: 0px 0px 5px rgba(100, 100, 100, .5);
}
.collectionSet > .set > div > div
@@ -213,9 +253,10 @@
{
width: 20px;
height: 20px;
margin: 10px;
margin: 8px;
background-image: url("chrome-extension://__MSG_@@extension_id__/images/tab_icon.png");
background-image: url("chrome-extension://__MSG_@@extension_id__/images/tab_icon.png"),
url("moz-extension://__MSG_@@extension_id__/images/tab_icon.png");
background-size: 20px;
}
+38 -3
View File
@@ -4,11 +4,21 @@
}
.tabsAside[darkmode] .pane
{
{
background-color: #333333;
color: white;
}
.tabsAside[darkmode] .pane header .iconArrowRight
{
filter: invert();
}
.tabsAside[darkmode] .pane header
{
background-color: #3b3b3b;
}
.tabsAside[darkmode] .saveTabs > div
{
filter: invert();
@@ -28,6 +38,22 @@
background-color: dimgray;
}
.tabsAside[darkmode] .collectionSet > .header > input
{
color: white;
}
.tabsAside[darkmode] .collectionSet > .header > input:hover
{
border: 1px solid dimgray;
}
.tabsAside[darkmode] .collectionSet > .header > input:focus
{
background: white;
color: black;
}
.tabsAside[darkmode] a
{
color: #48adff;
@@ -50,11 +76,19 @@
background: dimgray;
}
.tabsAside[darkmode] .pane .collectionSet
{
background-color: #3b3b3b;
border-color: #444;
}
/* Tab style */
.tabsAside[darkmode] .pane .collectionSet > .set > div
{
background-color: #0c0c0c;
background-image: url("chrome-extension://__MSG_@@extension_id__/images/tab_thumbnail_dark.png");
background-image: url("chrome-extension://__MSG_@@extension_id__/images/tab_thumbnail_dark.png"),
url("moz-extension://__MSG_@@extension_id__/images/tab_thumbnail_dark.png");
border-color: #444;
}
.tabsAside[darkmode] .pane .collectionSet > .set > div > div
@@ -64,7 +98,8 @@
.tabsAside[darkmode] .pane .collectionSet > .set > div > div > div
{
background-image: url("chrome-extension://__MSG_@@extension_id__/images/tab_icon_dark.png");
background-image: url("chrome-extension://__MSG_@@extension_id__/images/tab_icon_dark.png"),
url("moz-extension://__MSG_@@extension_id__/images/tab_icon_dark.png");
}
/* Context menu style */
+36 -14
View File
@@ -17,7 +17,7 @@
.tabsAside
{
font-family: 'DefaultFont';
font-family: 'Segoe UI' ,'DefaultFont';
font-size: 14px;
user-select: none;
}
@@ -27,7 +27,7 @@
{
color: #0078d7;
}
.tabsAside a:hover
.tabsAside a:hover
{
text-decoration: underline;
cursor: pointer;
@@ -41,15 +41,15 @@
/* Buttons style */
.tabsAside button
{
width: 32px;
height: 32px;
width: 28px;
height: 28px;
background-color: transparent;
border: none;
cursor: pointer;
}
.tabsAside button:hover
{
background-color: #c6c6c6;
background-color: #f2f2f2;
}
.tabsAside button:active
{
@@ -62,27 +62,43 @@
user-select: none;
position: absolute;
width: 250px;
width: 290px;
box-shadow: 0px 0px 10px black;
box-shadow: 0px 0px 10px rgba(0,0,0,.5);
background-color: white;
border-radius: 5px;
z-index: 10;
visibility: hidden;
padding: 4px 0px;
}
.tabsAside nav button
{
.tabsAside nav hr
{
border: none;
height: 1px;
background-color: lightgray;
}
.tabsAside nav button
{
text-align: start;
padding: 0px 10px;
width: 100%;
height: 32px;
font-family: 'Segoe UI' ,'DefaultFont';
}
.tabsAside nav button:hover
{
background-color: #eeee;
}
.tabsAside button + nav:active,
.tabsAside button:focus + nav
.tabsAside button:focus + nav
{
visibility: visible;
}
@@ -91,18 +107,20 @@
.btn
{
background-repeat: no-repeat;
background-size: 15px;
background-size: 12px;
background-position: center;
}
.btn.more
{
background-image: url("chrome-extension://__MSG_@@extension_id__/icons/more.svg");
background-image: url("chrome-extension://__MSG_@@extension_id__/icons/more.svg"),
url("moz-extension://__MSG_@@extension_id__/icons/more.svg");
}
.btn.remove
{
background-image: url("chrome-extension://__MSG_@@extension_id__/icons/cancel.svg");
background-image: url("chrome-extension://__MSG_@@extension_id__/icons/cancel.svg"),
url("moz-extension://__MSG_@@extension_id__/icons/cancel.svg");
}
@font-face
@@ -111,5 +129,9 @@
src: local("Segoe UI"),
url("chrome-extension://__MSG_@@extension_id__/fonts/WeblySleekUI/weblysleekuisemilight.ttf") format("truetype"),
url("chrome-extension://__MSG_@@extension_id__/fonts/WeblySleekUI/weblysleekuisemilight.woff") format("woff"),
url("chrome-extension://__MSG_@@extension_id__/fonts/WeblySleekUI/weblysleekuisemilight.woff2") format("woff2");
url("chrome-extension://__MSG_@@extension_id__/fonts/WeblySleekUI/weblysleekuisemilight.woff2") format("woff2"),
url("moz-extension://__MSG_@@extension_id__/fonts/WeblySleekUI/weblysleekuisemilight.ttf") format("truetype"),
url("moz-extension://__MSG_@@extension_id__/fonts/WeblySleekUI/weblysleekuisemilight.woff") format("woff"),
url("moz-extension://__MSG_@@extension_id__/fonts/WeblySleekUI/weblysleekuisemilight.woff2") format("woff2");
}
+58
View File
@@ -0,0 +1,58 @@
.tabsAside[listview] .collectionSet > .header
{
margin-bottom: 5px;
}
.tabsAside[listview] .collectionSet > .set
{
max-height: 250px;
}
.tabsAside[listview] .collectionSet > .set > div
{
width: initial;
height: initial;
background-image: none !important;
display: block;
}
.listviewSwitch
{
width: 20px;
height: 20px;
display: grid;
grid-row-gap: 2px;
grid-column-gap: 2px;
cursor: pointer;
}
.listviewSwitch.tile
{
grid-template-columns: 1fr 1fr;
}
.listviewSwitch > div
{
border-radius: 1px;
background-color: #c2c2c2;
}
.listviewSwitch:hover > div
{
background-color: #a0a0aa;
}
.tabsAside .listviewSwitch.tile > div
{
background-color: gray;
}
.tabsAside[listview] .listviewSwitch.tile > div
{
background-color: #c2c2c2;
}
.tabsAside[listview] .listviewSwitch.list > div
{
background-color: gray;
}
+144 -77
View File
@@ -1,4 +1,4 @@
if (window.location === window.parent.location && window.location.protocol != "chrome-extension:") // For open/close call
if (window.location === window.parent.location && !window.location.protocol.includes("-extension:")) // For open/close call
{
var iframe = document.querySelector("iframe.tabsAsideIframe");
if (!iframe)
@@ -52,14 +52,14 @@ function Initialize()
if (window.location !== window.parent.location)
{
pane.setAttribute("embedded", "");
window.addEventListener('message', event =>
window.addEventListener('message', event =>
{
if (event.data.target == "TabsAside")
{
pane.parentElement.style.opacity = 0;
pane.removeAttribute("opened");
}
});
});
}
UpdateLocale();
@@ -71,14 +71,17 @@ function Initialize()
}
document.querySelector(".tabsAside .saveTabs").onclick = SetTabsAside;
document.querySelector(".tabsAside header .btn.remove").addEventListener("click", () =>
chrome.runtime.sendMessage({ command: "togglePane" })
);
document.querySelector("nav > p > small").textContent = chrome.runtime.getManifest()["version"];
// Tabs dismiss option
var loadOnRestoreCheckbox = document.querySelector("#loadOnRestore");
chrome.storage.sync.get(
{ "loadOnRestore": false },
values => loadOnRestoreCheckbox.checked = values.loadOnRestore
{ "loadOnRestore": true },
values => loadOnRestoreCheckbox.checked = values?.loadOnRestore ?? true
);
chrome.storage.onChanged.addListener((changes, namespace) =>
{
@@ -98,7 +101,7 @@ function Initialize()
var swapIconAction = document.querySelector("#swapIconAction");
chrome.storage.sync.get(
{ "setAsideOnClick": false },
values => swapIconAction.checked = values.setAsideOnClick
values => swapIconAction.checked = values?.setAsideOnClick ?? false
);
chrome.storage.onChanged.addListener((changes, namespace) =>
{
@@ -114,7 +117,63 @@ function Initialize()
})
);
document.querySelectorAll(".tabsAside.pane > header nav button").forEach(i =>
// Deletion confirmation dialog
var showDeleteDialog = document.querySelector("#showDeleteDialog");
chrome.storage.sync.get(
{ "showDeleteDialog": true },
values => showDeleteDialog.checked = values.showDeleteDialog
);
chrome.storage.onChanged.addListener((changes, namespace) =>
{
if (namespace == 'sync')
for (key in changes)
if (key === 'showDeleteDialog')
showDeleteDialog.checked = changes[key].newValue
});
showDeleteDialog.addEventListener("click", () =>
chrome.storage.sync.set(
{
"showDeleteDialog": showDeleteDialog.checked
})
);
// Collections view switch
chrome.storage.sync.get(
{ "listview": false },
values =>
{
if (values?.listview)
pane.setAttribute("listview", "");
}
);
document.querySelectorAll(".listviewSwitch").forEach(i =>
{
i.onclick = (args) =>
{
if (args.currentTarget.classList[1] == "list")
{
pane.setAttribute("listview", "");
chrome.storage.sync.set({ "listview": true });
}
else
{
pane.removeAttribute("listview");
chrome.storage.sync.set({ "listview": false });
}
}
});
chrome.storage.onChanged.addListener((changes, namespace) =>
{
if (namespace == 'sync')
for (key in changes)
if (key === 'listview')
if (changes[key].newValue)
pane.setAttribute("listview", "");
else
pane.removeAttribute("listview");
});
document.querySelectorAll(".tabsAside.pane > header nav button").forEach(i =>
i.onclick = () =>
{
if (i.hasAttribute("feedback-button"))
@@ -131,7 +190,7 @@ function Initialize()
chrome.runtime.sendMessage({ command: "loadData" }, (collections) =>
{
if (document.querySelector(".tabsAside.pane section div") == null)
collections.forEach(i =>
collections.forEach(i =>
AddCollection(i));
});
@@ -142,6 +201,11 @@ function UpdateLocale()
{
document.querySelectorAll("*[loc]").forEach(i => i.textContent = chrome.i18n.getMessage(i.getAttribute("loc")));
document.querySelectorAll("*[loc_alt]").forEach(i => i.title = chrome.i18n.getMessage(i.getAttribute("loc_alt")));
var swapActionsLabel = document.querySelector("label[loc=swapIconAction]");
chrome.runtime.sendMessage({ command: "getShortcuts" }, (shortcuts) =>
swapActionsLabel.textContent = swapActionsLabel.textContent.replace("%TOGGLE_SHORTCUT%", shortcuts.filter(i => i.name == "toggle-pane")[0].shortcut)
);
}
function AddCollection(collection)
@@ -154,12 +218,12 @@ function AddCollection(collection)
for (var i = 0; i < collection.links.length; i++)
{
rawTabs +=
"<div title='" + collection.titles[i] + "'" + ((collection.thumbnails && collection.thumbnails[i]) ? " style='background-image: url(" + collection.thumbnails[i] + ")'" : "") + ">" +
"<span class='openTab' value='" + collection.links[i] + "'></span>" +
"<div title='" + collection.titles[i] + "'" + ((collection.thumbnails && collection.thumbnails[i]) ? " style='background-image: url(" + collection.thumbnails[i] + ")'" : "") + " value='" + collection.links[i] + "'>" +
//"<span class='openTab' value='" + collection.links[i] + "'></span>" +
"<div>" +
"<div" + ((collection.icons[i] == 0 || collection.icons[i] == null) ? "" : " style='background-image: url(\"" + collection.icons[i] + "\")'") + "></div>" +
"<span>" + collection.titles[i] + "</span>" +
"<button loc_alt='name' class='btn remove' title='Remove tab from collection'></button>" +
"<button loc_alt='removeTab' class='btn remove' title='Remove tab from collection'></button>" +
"</div>" +
"</div>";
}
@@ -167,8 +231,7 @@ function AddCollection(collection)
list.innerHTML +=
"<div class='collectionSet'>" +
"<div class='header'>" +
"<span>" + chrome.i18n.getMessage("tabs") + ": " + collection.links.length + "</span>" +
"<small>" + GetAgo(collection.timestamp) + "</small>" +
"<input type='text' value='" + (collection.name ?? new Date(collection.timestamp).toDateString()) + "'/>" +
"<a loc='restoreTabs' class='restoreCollection'>Restore tabs</a>" +
"<div>" +
"<button loc_alt='more' class='btn more' title='More...'></button>" +
@@ -177,33 +240,41 @@ function AddCollection(collection)
"</nav>" +
"</div>" +
"<button loc_alt='removeCollection' class='btn remove' title='Remove collection'></button>" +
"<small>" + collection.links.length + " " + chrome.i18n.getMessage("tabs") +"</small>" +
"</div>" +
"<div class='set' class='tabsList'>" + rawTabs + "</div>" +
"</div>";
UpdateLocale();
list.querySelectorAll(".restoreCollection").forEach(i =>
list.querySelectorAll("input").forEach(i =>
i.oninput = (event) => RenameCollection(i.parentElement.parentElement, event.target.value));
list.querySelectorAll(".restoreCollection").forEach(i =>
i.onclick = () => RestoreTabs(i.parentElement.parentElement));
list.querySelectorAll(".restoreCollection.noDelete").forEach(i =>
list.querySelectorAll(".restoreCollection.noDelete").forEach(i =>
i.onclick = () => RestoreTabs(i.parentElement.parentElement.parentElement.parentElement, false));
list.querySelectorAll(".openTab").forEach(i =>
i.onclick = () =>
chrome.runtime.sendMessage(
{
command: "openTab",
url: i.getAttribute("value")
}
));
list.querySelectorAll(".set > div").forEach(i =>
i.onclick = (args) =>
{
if (args.target.localName != "button")
chrome.runtime.sendMessage(
{
command: "openTab",
url: i.getAttribute("value")
}
);
});
document.querySelectorAll(".btn.remove").forEach(i =>
document.querySelectorAll(".header .btn.remove").forEach(i =>
i.onclick = () => RemoveTabs(i.parentElement.parentElement));
document.querySelectorAll(".tabsList .btn.remove").forEach(i =>
i.onclick = () => RemoveOneTab(i.parentElement.parentElement));
document.querySelectorAll(".set .btn.remove").forEach(i =>
i.onclick = (args) =>
RemoveOneTab(i.parentElement.parentElement));
}
function SetTabsAside()
@@ -211,6 +282,16 @@ function SetTabsAside()
chrome.runtime.sendMessage({ command: "saveTabs" });
}
function RenameCollection(collectionData, name)
{
chrome.runtime.sendMessage(
{
command: "renameCollection",
newName: name,
collectionIndex: Array.prototype.slice.call(collectionData.parentElement.children).indexOf(collectionData) - 1
});
}
function RestoreTabs(collectionData, removeCollection = true)
{
chrome.runtime.sendMessage(
@@ -229,61 +310,47 @@ function RestoreTabs(collectionData, removeCollection = true)
function RemoveTabs(collectionData)
{
if (!confirm(chrome.i18n.getMessage("removeCollectionConfirm")))
return;
chrome.storage.sync.get({ "showDeleteDialog": true }, values =>
{
if (values.showDeleteDialog && !confirm(chrome.i18n.getMessage("removeCollectionConfirm")))
return;
chrome.runtime.sendMessage(
{
command: "deleteTabs",
collectionIndex: Array.prototype.slice.call(collectionData.parentElement.children).indexOf(collectionData) - 1
},
() => RemoveCollectionElement(collectionData)
);
chrome.runtime.sendMessage(
{
command: "deleteTabs",
collectionIndex: Array.prototype.slice.call(collectionData.parentElement.children).indexOf(collectionData) - 1
},
() => RemoveCollectionElement(collectionData)
);
});
}
function RemoveOneTab(tabData)
{
if (!confirm(chrome.i18n.getMessage("removeTabConfirm")))
return;
chrome.storage.sync.get({ "showDeleteDialog": true }, values =>
{
if (values.showDeleteDialog && !confirm(chrome.i18n.getMessage("removeTabConfirm")))
return;
chrome.runtime.sendMessage(
{
command: "removeTab",
collectionIndex: Array.prototype.slice.call(tabData.parentElement.parentElement.parentElement.children).indexOf(tabData.parentElement.parentElement) - 1,
tabIndex: Array.prototype.slice.call(tabData.parentElement.children).indexOf(tabData)
},
() =>
{
tabData.parentElement.previousElementSibling.children[0].textContent = chrome.i18n.getMessage("tabs") + ": " + (tabData.parentElement.children.length - 1);
if (tabData.parentElement.children.length < 2)
chrome.runtime.sendMessage(
{
RemoveElement(tabData.parentElement.parentElement);
if (document.querySelector("tabsAside.pane > section").children.length < 2)
setTimeout(() => document.querySelector(".tabsAside.pane > section > h2").removeAttribute("hidden"), 250);
}
else
RemoveElement(tabData);
});
}
function GetAgo(timestamp)
{
var minutes = (Date.now() - timestamp) / 60000;
if (minutes < 1)
return chrome.i18n.getMessage("justNow");
else if (minutes < 60)
return Math.floor(minutes) + " " + chrome.i18n.getMessage("minutes") + " " + chrome.i18n.getMessage("ago");
else if (minutes < 24 * 60)
return Math.floor(minutes / 60) + " " + chrome.i18n.getMessage("hours") + " " + chrome.i18n.getMessage("ago");
else if (minutes < 7 * 24 * 60)
return Math.floor(minutes / 24 / 60) + " " + chrome.i18n.getMessage("days") + " " + chrome.i18n.getMessage("ago");
else if (minutes < 30 * 24 * 60)
return Math.floor(minutes / 7 / 24 / 60) + " " + chrome.i18n.getMessage("weeks") + " " + chrome.i18n.getMessage("ago");
else if (minutes < 365 * 24 * 60)
return Math.floor(minutes / 30 / 24 / 60) + " " + chrome.i18n.getMessage("months") + " " + chrome.i18n.getMessage("ago");
else
return Math.floor(minutes / 365 / 24 / 60) + " " + chrome.i18n.getMessage("years") + " " + chrome.i18n.getMessage("ago");
command: "removeTab",
collectionIndex: Array.prototype.slice.call(tabData.parentElement.parentElement.parentElement.children).indexOf(tabData.parentElement.parentElement) - 1,
tabIndex: Array.prototype.slice.call(tabData.parentElement.children).indexOf(tabData)
},
() =>
{
tabData.parentElement.previousElementSibling.querySelector("small").textContent = (tabData.parentElement.children.length - 1) + " " + chrome.i18n.getMessage("tabs");
if (tabData.parentElement.children.length < 2)
{
RemoveElement(tabData.parentElement.parentElement);
if (document.querySelector("tabsAside.pane > section").children.length < 2)
setTimeout(() => document.querySelector(".tabsAside.pane > section > h2").removeAttribute("hidden"), 250);
}
else
RemoveElement(tabData);
});
});
}
function RemoveElement(el)
@@ -294,7 +361,7 @@ function RemoveElement(el)
function RemoveCollectionElement(el)
{
if (el.parentElement.children.length < 3)
setTimeout(() => document.querySelector(".tabsAside.pane > section > h2").removeAttribute("hidden"), 250);
RemoveElement(el);
if (el.parentElement.children.length < 2)
setTimeout(() => document.querySelector(".tabsAside.pane > section > h2").removeAttribute("hidden"), 250);
}
+35 -16
View File
@@ -2,6 +2,7 @@ function TogglePane(tab)
{
if (tab.url.startsWith("http")
&& !tab.url.includes("chrome.google.com")
&& !tab.url.includes("addons.mozilla.org")
&& !tab.url.includes("microsoftedge.microsoft.com"))
{
chrome.tabs.executeScript(tab.id,
@@ -21,14 +22,14 @@ function TogglePane(tab)
active: true
},
(activeTab) =>
chrome.tabs.onActivated.addListener(function TabsAsideCloser(activeInfo)
chrome.tabs.onActivated.addListener(function TabsAsideCloser(activeInfo)
{
chrome.tabs.query({ url: chrome.extension.getURL("TabsAside.html") }, (result) =>
{
if (result.length)
setTimeout(() =>
{
result.forEach(i =>
result.forEach(i =>
{
if (activeInfo.tabId != i.id)
chrome.tabs.remove(i.id);
@@ -61,9 +62,9 @@ function ProcessCommand(command)
chrome.browserAction.onClicked.addListener((tab) =>
{
chrome.storage.sync.get({ "setAsideOnClick": false }, values =>
chrome.storage.sync.get({ "setAsideOnClick": false }, values =>
{
if (values.setAsideOnClick)
if (values?.setAsideOnClick)
SaveCollection();
else
TogglePane(tab);
@@ -87,6 +88,8 @@ chrome.contextMenus.create(
);
var collections = JSON.parse(localStorage.getItem("sets")) || [];
var shortcuts;
chrome.commands.getAll((commands) => shortcuts = commands);
chrome.commands.onCommand.addListener(ProcessCommand);
chrome.contextMenus.onClicked.addListener((info) => ProcessCommand(info.menuItemId));
@@ -116,12 +119,34 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) =>
RemoveTab(message.collectionIndex, message.tabIndex);
sendResponse();
break;
case "renameCollection":
collections[message.collectionIndex].name = message.newName;
localStorage.setItem("sets", JSON.stringify(collections));
break;
case "togglePane":
chrome.tabs.query(
{
active: true,
currentWindow: true
},
(tabs) => TogglePane(tabs[0])
)
break;
case "getShortcuts":
sendResponse(shortcuts);
break;
}
});
// This function updates the extension's toolbar icon
function UpdateTheme()
{
// Updating badge counter
chrome.browserAction.setBadgeText({ text: collections.length < 1 ? "" : collections.length.toString() });
if (chrome.theme) // Firefox sets theme automatically
return;
var theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
var iconStatus = collections.length ? "full" : "empty";
@@ -137,12 +162,6 @@ function UpdateTheme()
"16": basePath + "16.png"
}
});
// Updating badge counter
if (collections.length < 1)
chrome.browserAction.setBadgeText({ });
else
chrome.browserAction.setBadgeText({ text: collections.length.toString() });
}
UpdateTheme();
@@ -155,7 +174,7 @@ function SaveCollection()
{
chrome.tabs.query({ currentWindow: true }, (rawTabs) =>
{
var tabs = rawTabs.filter(i => i.url != chrome.runtime.getURL("TabsAside.html") && !i.pinned && !i.url.includes("//newtab"));
var tabs = rawTabs.filter(i => i.url != chrome.runtime.getURL("TabsAside.html") && !i.pinned && !i.url.includes("//newtab") && !i.url.includes("about:blank") && !i.url.includes("about:home"));
if (tabs.length < 1)
{
@@ -187,7 +206,7 @@ function SaveCollection()
collections = JSON.parse(localStorage.getItem("sets"));
var newTabId;
chrome.tabs.create({}, (tab) =>
chrome.tabs.create({}, (tab) =>
{
newTabId = tab.id;
chrome.tabs.remove(rawTabs.filter(i => !i.pinned && i.id != newTabId).map(tab => tab.id));
@@ -207,7 +226,7 @@ function DeleteCollection(collectionIndex)
function RestoreCollection(collectionIndex, removeCollection)
{
collections[collectionIndex].links.forEach(i =>
collections[collectionIndex].links.forEach(i =>
{
chrome.tabs.create(
{
@@ -216,10 +235,10 @@ function RestoreCollection(collectionIndex, removeCollection)
},
(createdTab) =>
{
chrome.storage.sync.get({ "loadOnRestore" : false }, values =>
chrome.storage.sync.get({ "loadOnRestore" : true }, values =>
{
if (!values.loadOnRestore)
chrome.tabs.onUpdated.addListener(function DiscardTab(updatedTabId, changeInfo, updatedTab)
if (!(values?.loadOnRestore))
chrome.tabs.onUpdated.addListener(function DiscardTab(updatedTabId, changeInfo, updatedTab)
{
if (updatedTabId === createdTab.id) {
chrome.tabs.onUpdated.removeListener(DiscardTab);
+44 -8
View File
@@ -1,12 +1,12 @@
{
"name": "__MSG_name__",
"version": "1.6",
"version": "1.8.1",
"manifest_version": 2,
"description": "__MSG_description__",
"author": "__MSG_author__",
"default_locale": "en",
"permissions":
"permissions":
[
"tabs",
"unlimitedStorage",
@@ -14,15 +14,41 @@
"<all_urls>",
"contextMenus"
],
"icons":
"icons":
{
"128": "icons/light/empty/128.png",
"48": "icons/light/empty/48.png",
"32": "icons/light/empty/32.png",
"16": "icons/light/empty/16.png"
},
"browser_action": { "default_icon": "icons/light/empty/32.png" },
"browser_action":
{
"default_icon": "icons/light/empty/32.png",
"theme_icons":
[
{
"size": 128,
"dark": "icons/light/full/128.png",
"light": "icons/dark/full/128.png"
},
{
"size": 48,
"dark": "icons/light/full/48.png",
"light": "icons/dark/full/48.png"
},
{
"size": 32,
"dark": "icons/light/full/32.png",
"light": "icons/dark/full/32.png"
},
{
"size": 16,
"dark": "icons/light/full/16.png",
"light": "icons/dark/full/16.png"
}
]
},
"web_accessible_resources": [ "*" ],
"background":
@@ -38,7 +64,8 @@
"description": "__MSG_setAside__",
"suggested_key":
{
"default": "Alt+Left"
"default": "Alt+Left",
"mac": "MacCtrl+T"
}
},
"toggle-pane":
@@ -46,8 +73,17 @@
"description": "__MSG_togglePaneContext__",
"suggested_key":
{
"default": "Alt+P"
"default": "Alt+P",
"mac": "Command+Shift+P"
}
}
},
"browser_specific_settings":
{
"gecko":
{
"id": "tabsaside@xfox111.net",
"strict_min_version": "58.0"
}
}
}
}