mirror of
https://github.com/XFox111/TabsAsideExtension.git
synced 2026-07-02 19:52:47 +03:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b83f3bd60 | |||
| 386b4f57d9 | |||
| 3a05ecb722 | |||
| 6a20af4e2f | |||
| 7072b9e87f | |||
| 3f53186bcc | |||
| 40336682aa | |||
| 606c1018e0 | |||
| 1824410db7 | |||
| a2c2d16f88 | |||
| aa94820ac3 | |||
| e39ec05881 | |||
| c7a7d4e40d | |||
| 5f9237bddc | |||
| 17713a29b9 | |||
| b2ba143bea |
@@ -0,0 +1,7 @@
|
||||
Tabs Aside Extension Privacy Policy
|
||||
1. Developers of the extension don't affiliate with Google LLC. or Microsoft Corporation in any way
|
||||
2. This extension doesn't transfer any personal data (data which may be used to track your location or reveal your identity) to any remote or local server
|
||||
3. This extension doesn't share any personal data with third parties
|
||||
4. This extension stores following personal data:
|
||||
- Browser tabs which have been saved for later by user via this extension (if user click "Set current tabs aside" button). This includes titles, favicons and web links
|
||||
5. User can delete all saved personal data by removing this extension from his browser
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
[](https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin)
|
||||
[](https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin)
|
||||
|
||||
[](https://github.com/xfox111/chromiumtabsaside/releases/latest)
|
||||
[](https://github.com/xfox111/chromiumtabsaside/releases/latest)
|
||||
|
||||
[](https://github.com/xfox111/ChromiumTabsAside/issues)
|
||||
[](https://github.com/xfox111/ChromiumTabsAside/commits/master)
|
||||
@@ -29,22 +27,13 @@ Unfortunately, in new Chromium-based Microsoft Edge, the devs decided not to imp
|
||||
|
||||
## Download
|
||||
- [Google Chrome Webstore](https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin)
|
||||
- [Microsoft Edge Add-ons Webstore]() *Available soon*
|
||||
- [Microsoft Edge Add-ons Webstore](https://microsoftedge.microsoft.com/addons/detail/kmnblllmalkiapkfknnlpobmjjdnlhnd)
|
||||
- [GitHub Releases](https://github.com/xfox111/chromiumtabsaside/releases/latest)
|
||||
|
||||
## To-do list
|
||||
- Add ability to backup and restore saved tabs
|
||||
- Add ability to share collections
|
||||
- Add ability to add collections to bookmarks
|
||||
- Add ability to sync saved tabs across different devices
|
||||
- Add saved tabs thumbnails
|
||||
- Add ability to reorder tabs inside collections
|
||||
- Add ability to restore collections without removing them from the pane
|
||||
- Add more languages (probably engage auto translator)
|
||||
- Code cleanup
|
||||
- Fix appearance on some websites
|
||||
## 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
|
||||
|
||||
## Copyrights
|
||||
> ©2020 Michael "XFox" Gordeev
|
||||
|
||||
Licensed under [MIT License](https://opensource.org/licenses/MIT)
|
||||
Licensed under [MIT License](https://opensource.org/licenses/MIT)
|
||||
|
||||
+6
-30
@@ -31,11 +31,15 @@
|
||||
<button title="Options"></button>
|
||||
|
||||
<nav>
|
||||
<!-- <p>
|
||||
<input type="checkbox" id="discardOnRestore" oncha/>
|
||||
<label for="discardOnRestore">Load tabs on restore</label>
|
||||
</p> -->
|
||||
<div>
|
||||
<button value="https://github.com/xfox111/ChromiumTabsAside">Visit GitHub page</button>
|
||||
<button value="https://chrome.google.com/webstore/category/extensions">Leave feedback</button>
|
||||
<button value="https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin">Leave feedback</button>
|
||||
<button value="https://buymeacoffee.com/xfox111">Buy me a coffee!</button>
|
||||
<button hidden>Backup saved tabs</button>
|
||||
<!-- <button hidden>Backup saved tabs</button> -->
|
||||
</div>
|
||||
<p>
|
||||
<small>v1.0</small><br />
|
||||
@@ -50,34 +54,6 @@
|
||||
|
||||
<section>
|
||||
<h2>You have no aside tabs</h1>
|
||||
|
||||
<!--<div>
|
||||
<div>
|
||||
<span>Tabs: $(tabsCount)</span>
|
||||
<small>$(timestamp)</small>
|
||||
|
||||
<a>Restore tabs</a>
|
||||
|
||||
<div>
|
||||
<button title="More..."></button>
|
||||
<nav>
|
||||
<button>Add tabs to favorites</button>
|
||||
<button>Share tabs</button>
|
||||
</nav>
|
||||
</div>
|
||||
<button title="Remove collection"></button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div title="Tab title caption">
|
||||
<div>
|
||||
<div></div>
|
||||
<span>$(title)</span>
|
||||
<button title="Remove tab from collection"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
</section>
|
||||
</aside>
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
<button title="Options"></button>
|
||||
|
||||
<nav>
|
||||
<!-- <p>
|
||||
<input type="checkbox" id="discardOnRestore"/>
|
||||
<label for="discardOnRestore">Load tabs on restore</label>
|
||||
</p> -->
|
||||
<div>
|
||||
<button value="https://github.com/xfox111/ChromiumTabsAside">Visit GitHub page</button>
|
||||
<button value="https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin">Leave feedback</button>
|
||||
|
||||
+4
-7
@@ -162,15 +162,10 @@
|
||||
line-height: initial !important;
|
||||
}
|
||||
|
||||
.tabsAside.pane > section > div > div:first-child > div
|
||||
{
|
||||
display: none !important; /* TODO: Implement this menu */
|
||||
}
|
||||
|
||||
.tabsAside.pane > section > div > div:first-child > div > nav
|
||||
{
|
||||
width: 200px !important;
|
||||
margin-top: 10px !important;
|
||||
width: 250px !important;
|
||||
margin-top: 40px !important;
|
||||
right: 50px !important;
|
||||
}
|
||||
|
||||
@@ -196,6 +191,8 @@
|
||||
|
||||
background-color: #c2c2c2 !important;
|
||||
background-image: url("chrome-extension://__MSG_@@extension_id__/images/tab_thumbnail.png");
|
||||
background-size: cover !important;
|
||||
background-position-x: center !important;
|
||||
|
||||
display: inline-grid !important;
|
||||
grid-template-rows: 1fr auto !important;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
{
|
||||
font-family: 'Segoe UI', 'Segoe MDL2 Assets' !important;
|
||||
color: #0078d7 !important;
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
.tabsAside a:hover
|
||||
{
|
||||
@@ -108,6 +109,7 @@
|
||||
cursor: pointer !important;
|
||||
background-color: transparent !important;
|
||||
border: none !important;
|
||||
box-sizing: border-box !important;
|
||||
|
||||
font-size: medium !important;
|
||||
text-align: start !important;
|
||||
|
||||
+59
-7
@@ -37,6 +37,26 @@ else
|
||||
|
||||
document.querySelector(".tabsAside .saveTabs").onclick = SetTabsAside;
|
||||
|
||||
document.querySelector("nav > p > small").textContent = chrome.runtime.getManifest()["version"];
|
||||
|
||||
/* var loadOnRestoreCheckbox = document.querySelector("nav > p > input[type=checkbox]");
|
||||
chrome.runtime.sendMessage(
|
||||
{
|
||||
command: "getDiscardOption"
|
||||
},
|
||||
function(loadOnRestore)
|
||||
{
|
||||
loadOnRestoreCheckbox.checked = loadOnRestore;
|
||||
}
|
||||
);
|
||||
loadOnRestoreCheckbox.addEventListener("click", function ()
|
||||
{
|
||||
chrome.runtime.sendMessage(
|
||||
{
|
||||
command: "toggleDiscard"
|
||||
}
|
||||
);
|
||||
}); */
|
||||
|
||||
document.querySelectorAll(".tabsAside.pane > header nav button").forEach(i =>
|
||||
{
|
||||
@@ -98,6 +118,27 @@ function InitializeStandalone()
|
||||
|
||||
document.querySelector(".tabsAside .saveTabs").onclick = SetTabsAside;
|
||||
|
||||
document.querySelector("nav > p > small").textContent = chrome.runtime.getManifest()["version"];
|
||||
|
||||
/* var loadOnRestoreCheckbox = document.querySelector("nav > p > input[type=checkbox]");
|
||||
chrome.runtime.sendMessage(
|
||||
{
|
||||
command: "getDiscardOption"
|
||||
},
|
||||
function(loadOnRestore)
|
||||
{
|
||||
loadOnRestoreCheckbox.checked = loadOnRestore;
|
||||
}
|
||||
);
|
||||
loadOnRestoreCheckbox.addEventListener("click", function ()
|
||||
{
|
||||
chrome.runtime.sendMessage(
|
||||
{
|
||||
command: "toggleDiscard"
|
||||
}
|
||||
);
|
||||
}); */
|
||||
|
||||
document.querySelectorAll(".tabsAside.pane > header nav button").forEach(i =>
|
||||
{
|
||||
i.onclick = function () { window.open(i.value, '_blank'); };
|
||||
@@ -123,7 +164,7 @@ function AddCollection(collection)
|
||||
for (var i = 0; i < collection.links.length; i++)
|
||||
{
|
||||
rawTabs +=
|
||||
"<div title='" + collection.titles[i] + "'>" +
|
||||
"<div title='" + collection.titles[i] + "'" + ((collection.thumbnails && collection.thumbnails[i]) ? " style='background-image: url(" + collection.thumbnails[i] + ")'" : "") + ">" +
|
||||
"<span value='" + collection.links[i] + "'></span>" +
|
||||
"<div>" +
|
||||
"<div" + ((collection.icons[i] == 0 || collection.icons[i] == null) ? "" : " style='background-image: url(\"" + collection.icons[i] + "\")'") + "></div>" +
|
||||
@@ -141,8 +182,9 @@ function AddCollection(collection)
|
||||
"<div>" +
|
||||
"<button title='More...'></button>" +
|
||||
"<nav>" +
|
||||
"<button>Add tabs to favorites</button>" +
|
||||
"<button>Share tabs</button>" +
|
||||
"<button>Restore without removing</button>" +
|
||||
// "<button hidden>Add tabs to favorites</button>" +
|
||||
// "<button hidden>Share tabs</button>" +
|
||||
"</nav>" +
|
||||
"</div>" +
|
||||
"<button title='Remove collection'></button>" +
|
||||
@@ -156,9 +198,15 @@ function AddCollection(collection)
|
||||
i.onclick = function () { RestoreTabs(i.parentElement.parentElement) };
|
||||
});
|
||||
|
||||
list.querySelectorAll("nav button:first-child").forEach(i =>
|
||||
{
|
||||
i.onclick = function () { RestoreTabs(i.parentElement.parentElement.parentElement.parentElement, false) };
|
||||
});
|
||||
|
||||
list.querySelectorAll("div > div:last-child > div > span").forEach(i =>
|
||||
{
|
||||
i.onclick = function () {
|
||||
i.onclick = function ()
|
||||
{
|
||||
chrome.runtime.sendMessage(
|
||||
{
|
||||
command: "openTab",
|
||||
@@ -173,14 +221,14 @@ function AddCollection(collection)
|
||||
i.onclick = function () { RemoveTabs(i.parentElement.parentElement) };
|
||||
});
|
||||
|
||||
document.querySelectorAll(".tabsAside.pane > section > div > div:first-child > div > nav > button:first-child").forEach(i =>
|
||||
/*document.querySelectorAll(".tabsAside.pane > section > div > div:first-child > div > nav > button:first-child").forEach(i =>
|
||||
{
|
||||
i.onclick = function () { AddToFavorites(i.parentElement.parentElement.parentElement.parentElement) };
|
||||
});
|
||||
document.querySelectorAll(".tabsAside.pane > section > div > div:first-child > div > nav > button:last-child").forEach(i =>
|
||||
{
|
||||
i.onclick = function () { ShareTabs(i.parentElement.parentElement.parentElement.parentElement) };
|
||||
});
|
||||
});*/
|
||||
|
||||
document.querySelectorAll(".tabsAside.pane > section > div > div:last-child > div > div > button").forEach(i =>
|
||||
{
|
||||
@@ -193,15 +241,19 @@ function SetTabsAside()
|
||||
chrome.runtime.sendMessage({ command: "saveTabs" });
|
||||
}
|
||||
|
||||
function RestoreTabs(collectionData)
|
||||
function RestoreTabs(collectionData, removeCollection = true)
|
||||
{
|
||||
chrome.runtime.sendMessage(
|
||||
{
|
||||
command: "restoreTabs",
|
||||
removeCollection: removeCollection,
|
||||
collectionIndex: Array.prototype.slice.call(collectionData.parentElement.children).indexOf(collectionData) - 1
|
||||
},
|
||||
function ()
|
||||
{
|
||||
if (!removeCollection)
|
||||
return;
|
||||
|
||||
if (collectionData.parentElement.children.length < 3)
|
||||
{
|
||||
RemoveElement(collectionData);
|
||||
|
||||
+82
-12
@@ -1,8 +1,8 @@
|
||||
chrome.browserAction.onClicked.addListener(function (tab)
|
||||
{
|
||||
if (tab.url.startsWith("http")
|
||||
&& !tab.url.includes("chrome.google.com")
|
||||
&& !tab.url.includes("microsoftedge.microsoft.com"))
|
||||
&& !tab.url.includes("chrome.google.com")
|
||||
&& !tab.url.includes("microsoftedge.microsoft.com"))
|
||||
{
|
||||
chrome.tabs.insertCSS(
|
||||
{
|
||||
@@ -129,7 +129,7 @@ chrome.runtime.onMessage.addListener(function (message, sender, sendResponse)
|
||||
SaveCollection();
|
||||
break;
|
||||
case "restoreTabs":
|
||||
RestoreCollection(message.collectionIndex);
|
||||
RestoreCollection(message.collectionIndex, message.removeCollection);
|
||||
sendResponse();
|
||||
break;
|
||||
case "deleteTabs":
|
||||
@@ -146,6 +146,15 @@ chrome.runtime.onMessage.addListener(function (message, sender, sendResponse)
|
||||
case "share":
|
||||
ShareTabs(message.collectionIndex);
|
||||
break;
|
||||
case "toggleDiscard":
|
||||
if (localStorage.getItem("loadOnRestore") == "true")
|
||||
localStorage.setItem("loadOnRestore", false);
|
||||
else
|
||||
localStorage.setItem("loadOnRestore", true);
|
||||
break;
|
||||
case "getDiscardOption":
|
||||
sendResponse(localStorage.getItem("loadOnRestore") == "false" ? false : true);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -169,9 +178,15 @@ chrome.tabs.onReplaced.addListener(UpdateTheme);
|
||||
|
||||
function SaveCollection()
|
||||
{
|
||||
chrome.tabs.query({ currentWindow: true }, function (tabs)
|
||||
chrome.tabs.query({ currentWindow: true }, function (rawTabs)
|
||||
{
|
||||
tabs = tabs.filter(i => !i.url.startsWith("chrome-extension") && !i.url.endsWith("TabsAside.html"));
|
||||
var tabs = rawTabs.filter(i => !(i.url.startsWith("chrome-extension") && i.url.endsWith("TabsAside.html")) && !i.pinned && !i.url.includes("//newtab"));
|
||||
|
||||
if (tabs.length < 1)
|
||||
{
|
||||
alert("No tabs available to save");
|
||||
return;
|
||||
}
|
||||
|
||||
var collection =
|
||||
{
|
||||
@@ -179,8 +194,8 @@ function SaveCollection()
|
||||
tabsCount: tabs.length,
|
||||
titles: tabs.map(tab => tab.title ?? ""),
|
||||
links: tabs.map(tab => tab.url ?? ""),
|
||||
icons: tabs.map(tab => tab.favIconUrl ?? "")//,
|
||||
//tumbnails: tabs.map(tab => chrome.tabs.captureVisibleTab)
|
||||
icons: tabs.map(tab => tab.favIconUrl ?? ""),
|
||||
thumbnails: tabs.map(tab => thumbnails.find(i => i.tabId == tab.id)?.url ?? "")
|
||||
};
|
||||
|
||||
var rawData;
|
||||
@@ -196,8 +211,10 @@ function SaveCollection()
|
||||
|
||||
collections = JSON.parse(localStorage.getItem("sets"));
|
||||
|
||||
chrome.tabs.create({});
|
||||
chrome.tabs.remove(tabs.map(tab => tab.id));
|
||||
var newTabId;
|
||||
chrome.tabs.create({}, function(tab) { newTabId = tab.id; });
|
||||
|
||||
chrome.tabs.remove(rawTabs.filter(i => !i.url.startsWith("chrome-extension") && !i.url.endsWith("TabsAside.html") && !i.pinned && i.id != newTabId).map(tab => tab.id));
|
||||
});
|
||||
|
||||
UpdateTheme();
|
||||
@@ -211,7 +228,7 @@ function DeleteCollection(collectionIndex)
|
||||
UpdateTheme();
|
||||
}
|
||||
|
||||
function RestoreCollection(collectionIndex)
|
||||
function RestoreCollection(collectionIndex, removeCollection)
|
||||
{
|
||||
collections[collectionIndex].links.forEach(i =>
|
||||
{
|
||||
@@ -219,9 +236,25 @@ function RestoreCollection(collectionIndex)
|
||||
{
|
||||
url: i,
|
||||
active: false
|
||||
});
|
||||
}/* , function (tab)
|
||||
{
|
||||
if (localStorage.getItem("loadOnRestore") == "false" ? true : false)
|
||||
{
|
||||
setTimeout(function()
|
||||
{
|
||||
chrome.tabs.get(tab.id, function(tab1)
|
||||
{
|
||||
console.log(tab.url);
|
||||
chrome.tabs.discard(tab1.id);
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
} */);
|
||||
});
|
||||
|
||||
if (!removeCollection)
|
||||
return;
|
||||
|
||||
collections = collections.filter(i => i != collections[collectionIndex]);
|
||||
localStorage.setItem("sets", JSON.stringify(collections));
|
||||
|
||||
@@ -279,4 +312,41 @@ function RemoveTab(collectionIndex, tabIndex)
|
||||
localStorage.setItem("sets", JSON.stringify(collections));
|
||||
|
||||
UpdateTheme();
|
||||
}
|
||||
}
|
||||
|
||||
var thumbnails = [];
|
||||
|
||||
function AppendThumbnail(tabId, cahngeInfo, tab)
|
||||
{
|
||||
if (!tab.active || !tab.url.startsWith("http"))
|
||||
return;
|
||||
|
||||
chrome.tabs.captureVisibleTab(
|
||||
{
|
||||
format: "jpeg",
|
||||
quality: 1
|
||||
},
|
||||
function (dataUrl)
|
||||
{
|
||||
if (!dataUrl)
|
||||
{
|
||||
console.log("Failed to retrieve thumbnail");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Thumbnail retrieved");
|
||||
var item = thumbnails.find(i => i.tabId == tabId);
|
||||
if (item)
|
||||
item.url = dataUrl;
|
||||
else
|
||||
thumbnails.unshift(
|
||||
{
|
||||
tabId: tabId,
|
||||
url: dataUrl
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
chrome.tabs.onUpdated.addListener(AppendThumbnail);
|
||||
+2
-3
@@ -1,15 +1,14 @@
|
||||
{
|
||||
"name": "Tabs Aside",
|
||||
"version": "1.1",
|
||||
"version": "1.3.1",
|
||||
"manifest_version": 2,
|
||||
"description": "Classic Microsoft Edge \"Tabs Aside\" feature for Chromium browsers",
|
||||
"author": "Michael \"XFox\" Gordeev",
|
||||
"default_locale": "en",
|
||||
"permissions":
|
||||
[
|
||||
"tabs",
|
||||
"unlimitedStorage",
|
||||
"activeTab"
|
||||
"<all_urls>"
|
||||
],
|
||||
|
||||
"icons":
|
||||
|
||||
Reference in New Issue
Block a user