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

Compare commits

...

6 Commits

Author SHA1 Message Date
Michael Gordeev d8c31e3da5 Minor 1.9 (#43)
- Now you can close the panel by clicking outside of it (#40)
- Added ability to move only selected tabs aside (#19)
- Context menu entries removed from pages' context menu (#41)
- After update extension now will open GitHub Releases page with the latest version
- Minor performance improvements

Co-authored-by: Amine A. <15179425+AmineI@users.noreply.github.com>
Co-Authored-By: Michael Gordeev <michael@xfox111.net>
2020-09-12 22:45:39 +03:00
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
11 changed files with 528 additions and 132 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
+1 -1
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)
+5 -3
View File
@@ -1,8 +1,9 @@
# 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%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/TabsAsideExtension)](https://github.com/xfox111/TabsAsideExtension/releases/latest)
[![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/)
@@ -30,6 +31,7 @@ Unfortunately, in new Chromium-based Microsoft Edge, the devs decided not to imp
- 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
- Set tabs you've selected aside
- **Now available for Firefox!**
## Download
@@ -43,8 +45,8 @@ You can go to the project's [roadmap kanban board](https://github.com/XFox111/Ta
## 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/TabsAsideExtension/blob/master/CONTRIBUTING.md), which covers the following:
+44 -33
View File
@@ -8,49 +8,60 @@
<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"/>
<meta charset="utf-8" />
</head>
<body>
<div class="tabsAside background">
<div class="tabsAside closeArea"></div>
<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>
<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>
<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>
</div>
<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>
<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>
+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)"
}
}
+26 -10
View File
@@ -10,6 +10,17 @@
color: black;
}
.tabsAside.closeArea
{
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background-color: transparent;
}
.tabsAside.pane
{
user-select: none;
@@ -53,23 +64,20 @@
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 auto;
grid-column-gap: 10px;
margin-bottom: 29px;
}
.tabsAside.pane > header > div > h1
.tabsAside.pane > header > h1
{
margin: 0px 5px;
font-weight: 500;
font-size: 15pt;
}
.tabsAside.pane > header > div > nav
.tabsAside.pane > header > nav
{
top: 45px;
right: 55px;
@@ -92,6 +100,7 @@
grid-column-gap: 15px;
font-weight: 600;
margin-right: auto;
}
.iconArrowRight
@@ -162,11 +171,18 @@
visibility: visible !important;
}
.collectionSet > .header > h4
.collectionSet > .header > input
{
margin: 0px;
visibility: visible !important;
font-weight: 500;
border: none;
background: transparent;
}
.collectionSet > .header > input:hover
{
border: 1px solid black;
}
.collectionSet > .header > a
+16
View File
@@ -38,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;
+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;
}
+69 -13
View File
@@ -74,6 +74,9 @@ function Initialize()
document.querySelector(".tabsAside header .btn.remove").addEventListener("click", () =>
chrome.runtime.sendMessage({ command: "togglePane" })
);
document.querySelector(".tabsAside.closeArea").addEventListener("click", () =>
chrome.runtime.sendMessage({ command: "togglePane" })
);
document.querySelector("nav > p > small").textContent = chrome.runtime.getManifest()["version"];
@@ -128,7 +131,7 @@ function Initialize()
if (namespace == 'sync')
for (key in changes)
if (key === 'showDeleteDialog')
showDeleteDialog.checked = changes[key].newValue
showDeleteDialog.checked = changes[key].newValue
});
showDeleteDialog.addEventListener("click", () =>
chrome.storage.sync.set(
@@ -137,6 +140,42 @@ function Initialize()
})
);
// 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 = () =>
{
@@ -182,8 +221,8 @@ 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>" +
@@ -195,7 +234,7 @@ function AddCollection(collection)
list.innerHTML +=
"<div class='collectionSet'>" +
"<div class='header'>" +
"<h4>" + new Date(collection.timestamp).toDateString() + "</h4>" +
"<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>" +
@@ -212,26 +251,33 @@ function AddCollection(collection)
UpdateLocale();
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 =>
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(".header .btn.remove").forEach(i =>
i.onclick = () => RemoveTabs(i.parentElement.parentElement));
document.querySelectorAll(".set .btn.remove").forEach(i =>
i.onclick = () => RemoveOneTab(i.parentElement.parentElement));
i.onclick = (args) =>
RemoveOneTab(i.parentElement.parentElement));
}
function SetTabsAside()
@@ -239,6 +285,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(
+107 -70
View File
@@ -1,3 +1,21 @@
//This variable is populated when the browser action icon is clicked, or a command is called (with a shortcut for example).
//We can't populate it later, as selected tabs get deselected on a click inside a tab.
var tabsToSave = [];
//Get the tabs to save, either all the window or the selected tabs only, and pass them through a callback.
function GetTabsToSave(callback)
{
chrome.tabs.query({ currentWindow: true }, (windowTabs) =>
{
var highlightedTabs = windowTabs.filter(item => item.highlighted);
//If there are more than one selected tab in the window, we set only those aside.
// Otherwise, all the window's tabs get saved.
return callback((highlightedTabs.length > 1 ? highlightedTabs : windowTabs));
});
}
function TogglePane(tab)
{
if (tab.url.startsWith("http")
@@ -43,50 +61,43 @@ function TogglePane(tab)
function ProcessCommand(command)
{
switch(command)
GetTabsToSave((returnedTabs) =>
{
case "set-aside":
SaveCollection();
break;
case "toggle-pane":
chrome.tabs.query(
{
active: true,
currentWindow: true
},
(tabs) => TogglePane(tabs[0])
)
break;
}
tabsToSave = returnedTabs;
switch(command)
{
case "set-aside":
SaveCollection();
break;
case "toggle-pane":
chrome.tabs.query(
{
active: true,
currentWindow: true
},
(tabs) => TogglePane(tabs[0])
)
break;
}
});
}
chrome.browserAction.onClicked.addListener((tab) =>
{
chrome.storage.sync.get({ "setAsideOnClick": false }, values =>
GetTabsToSave((returnedTabs) =>
{
if (values?.setAsideOnClick)
SaveCollection();
else
TogglePane(tab);
tabsToSave = returnedTabs;
chrome.storage.sync.get({ "setAsideOnClick": false }, values =>
{
if (values?.setAsideOnClick)
SaveCollection();
else
TogglePane(tab);
});
});
});
// Adding context menu options
chrome.contextMenus.create(
{
id: "toggle-pane",
contexts: ['all'],
title: chrome.i18n.getMessage("togglePaneContext")
}
);
chrome.contextMenus.create(
{
id: "set-aside",
contexts: ['all'],
title: chrome.i18n.getMessage("setAside")
}
);
var collections = JSON.parse(localStorage.getItem("sets")) || [];
var shortcuts;
chrome.commands.getAll((commands) => shortcuts = commands);
@@ -94,6 +105,27 @@ chrome.commands.getAll((commands) => shortcuts = commands);
chrome.commands.onCommand.addListener(ProcessCommand);
chrome.contextMenus.onClicked.addListener((info) => ProcessCommand(info.menuItemId));
chrome.runtime.onInstalled.addListener((reason) =>
{
chrome.tabs.create({ url: "https://github.com/XFox111/TabsAsideExtension/releases/latest" });
// Adding context menu options
chrome.contextMenus.create(
{
id: "toggle-pane",
contexts: ["browser_action"],
title: chrome.i18n.getMessage("togglePaneContext")
}
);
chrome.contextMenus.create(
{
id: "set-aside",
contexts: ["browser_action"],
title: chrome.i18n.getMessage("setAside")
}
);
});
//We receive a message from the pane aside-script, which means the tabsToSave are already assigned on message reception.
chrome.runtime.onMessage.addListener((message, sender, sendResponse) =>
{
switch (message.command)
@@ -119,6 +151,10 @@ 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(
{
@@ -168,48 +204,45 @@ chrome.tabs.onActivated.addListener(UpdateTheme);
// Set current tabs aside
function SaveCollection()
{
chrome.tabs.query({ currentWindow: true }, (rawTabs) =>
var tabs = tabsToSave.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)
{
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"));
alert(chrome.i18n.getMessage("noTabsToSave"));
return;
}
if (tabs.length < 1)
{
alert(chrome.i18n.getMessage("noTabsToSave"));
return;
}
var collection =
{
timestamp: Date.now(),
tabsCount: tabs.length,
titles: tabs.map(tab => tab.title ?? ""),
links: tabs.map(tab => tab.url ?? ""),
icons: tabs.map(tab => tab.favIconUrl ?? ""),
thumbnails: tabs.map(tab => thumbnails.find(i => i.tabId == tab.id)?.url ?? "")
};
var collection =
{
timestamp: Date.now(),
tabsCount: tabs.length,
titles: tabs.map(tab => tab.title ?? ""),
links: tabs.map(tab => tab.url ?? ""),
icons: tabs.map(tab => tab.favIconUrl ?? ""),
thumbnails: tabs.map(tab => thumbnails.find(i => i.tabId == tab.id)?.url ?? "")
};
var rawData;
if (localStorage.getItem("sets") === null)
rawData = [collection];
else
{
rawData = JSON.parse(localStorage.getItem("sets"));
rawData.unshift(collection);
}
var rawData;
if (localStorage.getItem("sets") === null)
rawData = [collection];
else
{
rawData = JSON.parse(localStorage.getItem("sets"));
rawData.unshift(collection);
}
localStorage.setItem("sets", JSON.stringify(rawData));
localStorage.setItem("sets", JSON.stringify(rawData));
collections = JSON.parse(localStorage.getItem("sets"));
collections = JSON.parse(localStorage.getItem("sets"));
var newTabId;
chrome.tabs.create({}, (tab) =>
{
newTabId = tab.id;
chrome.tabs.remove(rawTabs.filter(i => !i.pinned && i.id != newTabId).map(tab => tab.id));
});
UpdateTheme();
var newTabId;
chrome.tabs.create({}, (tab) =>
{
newTabId = tab.id;
chrome.tabs.remove(tabsToSave.filter(i => !i.pinned && i.id != newTabId).map(tab => tab.id));
});
UpdateTheme();
}
function DeleteCollection(collectionIndex)
@@ -247,6 +280,10 @@ function RestoreCollection(collectionIndex, removeCollection)
});
});
//We added new tabs by restoring a collection, so we refresh the array of tabs ready to be saved.
GetTabsToSave((returnedTabs) =>
tabsToSave = returnedTabs)
if (!removeCollection)
return;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "__MSG_name__",
"version": "1.7.3",
"version": "1.9",
"manifest_version": 2,
"description": "__MSG_description__",
"author": "__MSG_author__",