bump to 1.7.0

This commit is contained in:
karol@jagiello.it 2018-07-03 20:36:38 +02:00
parent 195f0fa4ff
commit 48dccfecd6
44 changed files with 3679 additions and 3285 deletions

View File

@ -1,33 +1,58 @@
CHANGES:
1. shortcut to open TreeTabs Sidebar is now F1
2. log does not preserve any personal data (urls) for GDPR law
NEW:
1. you can now drag&drop entire group to another window
2. tree structure is tracked in background (excluded closing tabs)
3. added alt+w shortcut to close a tree of tabs
4. creating folder will now prompt for a new name
5. search for *audible, *muted, *unloaded, *loaded tabs! Just write *audible in search box!
FIXES:
deny Drag&drop tab to root of folders
"Never show close button" option was breaking theme preview/editor
closing pinned tabs did not resize area of pinned tabs, leaving empty space below
added "bookmark" menu for single tab
clone pinned tab was added as not pinned (only in Firefox)
Shortcut changed to Ctrl+F2
export session file has now date as a name
1. import window was not showing up
2. export group and export session had file extension in name
3. pin tree had bug in setting class
FEATURES TO DO
opt.promote_children_in_first_child true, to work from background! also for message.command == "tab_detached"
manager: add save/import/export window
discard on import group and import session
Shift + mouse scroll to switch between groups
unread tabs
instruction to add popup
line for children hierarchy (like at the beggining)
"undo close" as a possible action with middle click on empty space
return to the first tab with mousewheel when we are at the bottom list (loop) - "mousewheel scroll on the last tab allow to return to the first one"
mute icon config option (disable animation)
FIREFOX CONTAINERS
DRAG&DROP TO ANOTHER WINDOW OF THE ENTIRE GROUP
undo close to restore trees (will work ONLY in firefox)
Close tab on Middle mouse click and not On Middle mouse down
Split Pin size in theme
unread state?
Unread Tabs Color/Style
automatic different color for each tree
add groups scrolling arrows
add textbox for ungrouped name in options
option for scrollbar on the left
unread state?
menu: copy urls of the selected tabs
menu: bookmark selected tabs/tree
@ -44,16 +69,14 @@ maybe filter tabs on search
font size
hibernate group
double click on tab actions selection like double click to be able to expand child tab.
I want you to be able to display the tab number count on the right end
I want you to be able to display the tab number count on the right end
customizable menu
import session to unload tabs immediately
bind groups to FF containers
Unread Tabs Color/Style
Give back group color (like it was before)
@ -64,8 +87,6 @@ folders collapsed by default or make this optional
when actived tab located in folder, all tabs operation related with creating new tab (such as clone of tab in folder, new tab) must work only in current folder.
New tab in selected folder!
separate option for close folder (close or promote children)
menu: unload tabs in folders
@ -81,7 +102,7 @@ Accept BCH (BitcoinCash) donations as the FEES make it FAR more palatable to don
- Like many other commenters suggested, it would be wonderful to see some indication of the container a tab was opened in, if any. Getting an option to directly be able to chose to open a new tab in a container would also be very useful.
I don't understand those from comments
I DON'T UNDERSTAND THOSE FROM COMMENTS
- add possibility open all tabs in folder in new left tab group with deleting this folder;
- for economy memory your tabs must to makings (html code) during activating left tab group or during unfold folders/trees;
- real FF tabs must creating and linking only after activate your tabs;

View File

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/></head>
<body></body>
<script type="text/javascript" src="../scripts/global.js"></script>
<script type="text/javascript" src="../legacy.js"></script>
<script type="text/javascript" src="../bg_ch.js"></script>
<script type="text/javascript" src="../bg_ff.js"></script>
<script type="text/javascript" src="../init.js"></script>
</html>

View File

@ -1,16 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
document.addEventListener("DOMContentLoaded", Init(), false);
function Init() {
if (browserId == "F") {
FirefoxMessageListeners();
FirefoxStart(0);
} else {
// ConvertLegacyStorage();
ChromeMessageListeners();
ChromeLoadTabs(0);
}
}

View File

@ -2,7 +2,7 @@
"manifest_version": 2,
"default_locale": "en",
"background": {
"page": "background.html",
"scripts": [ "listeners_bg.js", "scripts/common.js", "background.js" ],
"persistent": true
},
"name": "Tree Tabs",
@ -14,7 +14,7 @@
"19": "icons/16.png",
"16": "icons/16.png"
},
"permissions": [ "tabs", "sessions", "<all_urls>", "storage", "unlimitedStorage", "bookmarks", "tabHide" ],
"permissions": [ "<all_urls>", "tabs", "sessions", "storage", "unlimitedStorage", "bookmarks", "tabHide" ],
"sidebar_action": {
"default_icon": {
@ -39,5 +39,11 @@
"page": "options.html",
"open_in_tab": true
},
"commands": {
"close_tree": {
"suggested_key": { "default": "Alt+W" },
"description": "close tree"
}
},
"version": "100"
}

View File

@ -1,8 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/></head>
<body></body>
<script type="text/javascript" src="../scripts/global.js"></script>
<script type="text/javascript" src="../bg_ff.js"></script>
<script type="text/javascript" src="../init.js"></script>
</html>

View File

@ -1,12 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
document.addEventListener("DOMContentLoaded", Init(), false);
function Init() {
setTimeout(function() {
FirefoxMessageListeners();
FirefoxStart(0);
}, 500);
}

View File

@ -2,7 +2,7 @@
"manifest_version": 2,
"default_locale": "en",
"background": {
"page": "background.html",
"scripts": [ "listeners_bg.js", "scripts/common.js", "background.js" ],
"persistent": true
},
"name": "Tree Tabs",
@ -14,7 +14,7 @@
"19": "icons/16.png",
"16": "icons/16.png"
},
"permissions": [ "tabs", "sessions", "<all_urls>", "storage", "unlimitedStorage", "bookmarks", "tabHide" ],
"permissions": [ "tabs", "sessions", "storage", "unlimitedStorage", "bookmarks", "tabHide" ],
"sidebar_action": {
"default_icon": {
"16": "icons/16.png",
@ -30,8 +30,12 @@
},
"commands": {
"_execute_browser_action": {
"suggested_key": { "default": "Ctrl+F2" },
"suggested_key": { "default": "F1" },
"description": "toggle Tree Tabs"
},
"close_tree": {
"suggested_key": { "default": "Alt+W" },
"description": "close tree"
}
},
"applications": {
@ -44,5 +48,5 @@
"page": "options.html",
"open_in_tab": true
},
"version": "1.6.0"
"version": "1.7.0"
}

View File

@ -1,9 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/></head>
<body></body>
<script type="text/javascript" src="../scripts/global.js"></script>
<script type="text/javascript" src="../legacy.js"></script>
<script type="text/javascript" src="../bg_ch.js"></script>
<script type="text/javascript" src="../init.js"></script>
</html>

View File

@ -1,11 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
document.addEventListener("DOMContentLoaded", Init(), false);
function Init() {
ConvertLegacyStorage();
ChromeMessageListeners();
ChromeLoadTabs(0);
}

View File

@ -3,7 +3,7 @@
"minimum_opera_version": "42",
"default_locale": "en",
"background": {
"page": "background.html",
"scripts": [ "listeners_bg.js", "scripts/common.js", "background.js" ],
"persistent": true
},
"name": "Tree Tabs",
@ -25,5 +25,11 @@
"default_title": "Tree Tabs"
},
"options_page": "options.html",
"version": "1.6.0"
"commands": {
"close_tree": {
"suggested_key": { "default": "Alt+W" },
"description": "close tree"
}
},
"version": "1.6.1"
}

View File

@ -1,8 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/></head>
<body></body>
<script type="text/javascript" src="../scripts/global.js"></script>
<script type="text/javascript" src="../bg_ch.js"></script>
<script type="text/javascript" src="../init.js"></script>
</html>

View File

@ -1,10 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
document.addEventListener("DOMContentLoaded", Init(), false);
function Init() {
ChromeMessageListeners();
ChromeLoadTabs(0);
}

View File

@ -2,7 +2,7 @@
"manifest_version": 2,
"default_locale": "en",
"background": {
"page": "background.html",
"scripts": [ "listeners_bg.js", "scripts/common.js", "background.js" ],
"persistent": true
},
"name": "Tree Tabs",
@ -19,5 +19,11 @@
"page": "options.html",
"open_in_tab": false
},
"version": "1.6.0"
"commands": {
"close_tree": {
"suggested_key": { "default": "Alt+W" },
"description": "close tree"
}
},
"version": "1.7.0"
}

View File

@ -251,8 +251,7 @@
"options_vivaldi": {
"message": " Vivaldi "
},
@ -297,16 +296,16 @@
"message": "never"
},
"options_move_on_url_change_from_empty": {
"message": "when URL changes in Home tab (only Home tab created externally, for example, ctrl+t shortcut)"
"message": "when URL changes in Home tab (only Home tabs created by ctrl+t shortcut)"
},
"options_move_on_url_change_from_empty_b": {
"message": "when URL changes in Home tab"
"message": "when URL changes in any Home tab"
},
"options_move_on_url_change_all_new": {
"message": "when tab is created with a matching URL"
},
"options_move_on_url_change_always": {
"message": "always when URL changes to a matching pattern"
"message": "whenever URL changes to a matching pattern"
},
"options_always_show_close": {
@ -392,16 +391,16 @@
"options_append_child_tab": {
"message": "Append children tabs at the"
"message": "Place children tabs"
},
"options_append_child_tab_top": {
"message": "top (reverse hierarchy)"
"message": "at the top (reverse hierarchy)"
},
"options_append_child_tab_bottom": {
"message": "bottom"
"message": " at the bottom"
},
"options_append_child_tab_after_active": {
"message": "after active"
"options_append_child_tab_after": {
"message": "after parent (no automatic tree)"
},
"options_append_orphan_tab": {
@ -440,7 +439,7 @@
},
"options_append_child_tab_after_limit": {
"message": "Once reached tree depth, place tab on the same level, but"
"message": "Once reached maximum tree depth, place tab on the same level, but"
},
"options_append_child_tab_after_limit_top": {
"message": "at the top"
@ -1125,8 +1124,276 @@
"manager_window_load_icon": {
"message": "Load"
},
"options_Remove_button": {
"message": "Remove"
},
"add_tab_group_regex": {
"message": "Add"
},
"tab_title_font_color": {
"message": ""
},
"tab_background": {
"message": ""
},
"tab_border": {
"message": ""
},
"tab_hover_title_font_color": {
"message": ""
},
"tab_hover_background": {
"message": ""
},
"tab_hover_border": {
"message": ""
},
"tab_selected_title_font_color": {
"message": ""
},
"tab_selected_background": {
"message": ""
},
"tab_selected_border": {
"message": ""
},
"tab_selected_hover_title_font_color": {
"message": ""
},
"tab_selected_hover_background": {
"message": ""
},
"tab_selected_hover_border": {
"message": ""
},
"tab_active_title_font_color": {
"message": ""
},
"tab_active_background": {
"message": ""
},
"tab_active_border": {
"message": ""
},
"tab_active_hover_title_font_color": {
"message": ""
},
"tab_active_hover_background": {
"message": ""
},
"tab_active_hover_border": {
"message": ""
},
"tab_active_selected_title_font_color": {
"message": ""
},
"tab_active_selected_background": {
"message": ""
},
"tab_active_selected_border": {
"message": ""
},
"tab_selected_active_hover_title_font_color": {
"message": ""
},
"tab_selected_active_hover_background": {
"message": ""
},
"tab_selected_active_hover_border": {
"message": ""
},
"tab_discarded_title_font_color": {
"message": ""
},
"tab_discarded_background": {
"message": ""
},
"tab_discarded_border": {
"message": ""
},
"tab_discarded_hover_title_font_color": {
"message": ""
},
"tab_discarded_hover_background": {
"message": ""
},
"tab_discarded_hover_border": {
"message": ""
},
"tab_selected_discarded_title_font_color": {
"message": ""
},
"tab_selected_discarded_background": {
"message": ""
},
"tab_selected_discarded_border": {
"message": ""
},
"tab_selected_discarded_hover_title_font_color": {
"message": ""
},
"tab_selected_discarded_hover_background": {
"message": ""
},
"tab_selected_discarded_hover_border": {
"message": ""
},
"tab_filtered_title_font_color": {
"message": ""
},
"tab_filtered_background": {
"message": ""
},
"tab_filtered_border": {
"message": ""
},
"tab_filtered_hover_title_font_color": {
"message": ""
},
"tab_filtered_hover_background": {
"message": ""
},
"tab_filtered_hover_border": {
"message": ""
},
"tab_filtered_active_title_font_color": {
"message": ""
},
"tab_filtered_active_background": {
"message": ""
},
"tab_filtered_active_border": {
"message": ""
},
"tab_filtered_active_hover_title_font_color": {
"message": ""
},
"tab_filtered_active_hover_background": {
"message": ""
},
"tab_filtered_active_hover_border": {
"message": ""
},
"tab_filtered_selected_title_font_color": {
"message": ""
},
"tab_filtered_selected_background": {
"message": ""
},
"tab_filtered_selected_border": {
"message": ""
},
"tab_filtered_selected_hover_title_font_color": {
"message": ""
},
"tab_filtered_selected_hover_background": {
"message": ""
},
"tab_filtered_selected_hover_border": {
"message": ""
},
"tab_filtered_selected_active_title_font_color": {
"message": ""
},
"tab_filtered_selected_active_background": {
"message": ""
},
"tab_filtered_selected_active_border": {
"message": ""
},
"tab_filtered_selected_active_hover_title_font_color": {
"message": ""
},
"tab_filtered_selected_active_hover_background": {
"message": ""
},
"tab_filtered_selected_active_hover_border": {
"message": ""
},
"tab_filtered_highlighted_search_title_font_color": {
"message": ""
},
"tab_filtered_highlighted_search_background": {
"message": ""
},
"tab_filtered_highlighted_search_border": {
"message": ""
},
"tab_filtered_highlighted_search_hover_title_font_color": {
"message": ""
},
"tab_filtered_highlighted_search_hover_background": {
"message": ""
},
"tab_filtered_highlighted_search_hover_border": {
"message": ""
},
"tab_filtered_active_highlighted_search_title_font_color": {
"message": ""
},
"tab_filtered_active_highlighted_search_background": {
"message": ""
},
"tab_filtered_active_highlighted_search_border": {
"message": ""
},
"tab_filtered_active_highlighted_search_hover_title_font_color": {
"message": ""
},
"tab_filtered_active_highlighted_search_hover_background": {
"message": ""
},
"tab_filtered_active_highlighted_search_hover_border": {
"message": ""
},
"tab_filtered_selected_highlighted_search_title_font_color": {
"message": ""
},
"tab_filtered_selected_highlighted_search_background": {
"message": ""
},
"tab_filtered_selected_highlighted_search_border": {
"message": ""
},
"tab_filtered_selected_highlighted_search_hover_title_font_color": {
"message": ""
},
"tab_filtered_selected_highlighted_search_hover_background": {
"message": ""
},
"tab_filtered_selected_highlighted_search_hover_border": {
"message": ""
},
"tab_filtered_selected_active_highlighted_search_title_font_color": {
"message": ""
},
"tab_filtered_selected_active_highlighted_search_background": {
"message": ""
},
"tab_filtered_selected_active_highlighted_search_border": {
"message": ""
},
"tab_filtered_selected_active_highlighted_search_hover_title_font_color": {
"message": ""
},
"tab_filtered_selected_active_highlighted_search_hover_background": {
"message": ""
},
"tab_filtered_selected_active_highlighted_search_hover_border": {
"message": ""
}

View File

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/></head>
<body></body>
<script type="text/javascript" src="../scripts/global.js"></script>
<script type="text/javascript" src="../legacy.js"></script>
<script type="text/javascript" src="../bg_ch.js"></script>
<script type="text/javascript" src="../bg_ff.js"></script>
<script type="text/javascript" src="../init.js"></script>
</html>

614
background.js Normal file
View File

@ -0,0 +1,614 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// START BACKGROUND SCRIPT /////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
document.addEventListener("DOMContentLoaded", function() {
if (browserId == "F") {
setTimeout(function() {
StartBackgroundListeners();
QuantumStart(0);
}, 500);
} else {
StartBackgroundListeners();
ChromiumLoadTabs(0);
}
});
////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// BACKGROUND FUNCTIONS /////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
function pushlog(log) {
b.debug.push(log);
if (b.debug.length > 100) {
b.debug.splice(0, 1);
}
console.log(log);
b.schedule_save++;
}
function ReplaceParents(oldTabId, newTabId) {
for (let tabId in b.tabs) {
if (b.tabs[tabId].parent == oldTabId) {
b.tabs[tabId].parent = newTabId;
}
}
}
async function DiscardTab(tabId) {
let DiscardTimeout = 0;
let Discard = setInterval(function() {
chrome.tabs.get(tabId, function(tab) {
if ((tab.favIconUrl != undefined && tab.favIconUrl != "" && tab.title != undefined && tab.title != "") || tab.status == "complete" || tab.audible) {
chrome.tabs.discard(tab.id);
clearInterval(Discard);
}
if (DiscardTimeout > 300) {
clearInterval(Discard);
}
});
DiscardTimeout++;
}, 2000);
}
async function DiscardWindow(windowId) {
let DiscardTimeout = 0;
let DiscardedTabs = 0;
let Discard = setInterval(function() {
chrome.windows.get(windowId, {populate: true}, function(w) {
for (let i = 0; i < w.tabs.length; i++) {
if (w.tabs[i].discarded == false && w.tabs[i].active == false) {
if ((w.tabs[i].favIconUrl != undefined && w.tabs[i].favIconUrl != "" && w.tabs[i].title != undefined && w.tabs[i].title != "") || w.tabs[i].status == "complete" || tab.audible) {
chrome.tabs.discard(w.tabs[i].id);
DiscardedTabs++;
}
}
}
if (DiscardedTabs == w.tabs.length) {
clearInterval(Discard);
}
});
if (DiscardTimeout > 300) {
clearInterval(Discard);
}
DiscardTimeout++;
}, 5000);
}
function GetTabGroupId(tabId, windowId) {
let groupId = "tab_list";
if (tabId == undefined || windowId == undefined || b.windows[windowId] == undefined || b.tabs[tabId] == undefined) {
return groupId;
}
let parent = b.tabs[tabId].parent;
while (parent) {
if (isNaN(parent) == false && b.tabs[parent]) {
parent = b.tabs[parent].parent;
} else {
if (parent.match("tab_list|g_|f_") == null && b.tabs[parent]) {
parent = b.tabs[parent].parent;
} else {
if (parent.match("f_") != null && b.windows[windowId].folders[parent]) {
parent = b.windows[windowId].folders[parent].parent;
} else {
if (parent.match("pin_list|tab_list|g_") != null) {
groupId = parent;
parent = false;
} else {
parent = false;
}
}
}
}
}
return groupId;
}
function GetTabParents(tabId) {
let Parents = [];
if (tabId == undefined) {
return Parents;
}
if (b.tabs[tabId] == undefined) {
return Parents;
}
while (b.tabs[tabId].parent != "" && b.tabs[b.tabs[tabId].parent] != undefined) {
if (b.tabs[b.tabs[tabId].parent]) {
Parents.push(b.tabs[tabId].parent);
}
tabId = b.tabs[tabId].parent;
}
return Parents;
}
function GetChildren(parentId) {
let Children = [];
for (let tId in b.tabs) {
if (b.tabs[tId].parent == parentId) {
Children.push(parseInt(tId));
}
}
for (let i = 0; i < Children.length-1; i++) {
for (let j = i+1; j < Children.length; j++) {
if (b.tabs[Children[i]].index > b.tabs[Children[j]].index) {
let swap = Children[i];
Children[i] = Children[j];
Children[j] = swap;
}
}
}
return Children;
}
function AppendTabToGroupOnRegexMatch(tabId, windowId, url) {
let TabGroupId = GetTabGroupId(tabId, windowId);
for (let i = 0; i < opt.tab_group_regexes.length; i++) {
let regexPair = opt.tab_group_regexes[i];
if (url.match(regexPair[0])) {
let groupId = FindGroupIdByName(regexPair[1], b.windows[windowId].groups);
let groupName = regexPair[1];
if (groupId === null) { // no group
let newGroupID = "";
while (newGroupID == "") {
newGroupID = "g_"+GenerateRandomID();
for (let wId in b.windows) {
for (let gId in b.windows[wId].groups) {
console.log("check if group id exists");
if (gId == newGroupID) {
newGroupID = "";
console.log("yup, redo");
}
}
}
}
groupId = newGroupID;
b.windows[windowId].groups[groupId] = {id: groupId, index: 999, active_tab: 0, prev_active_tab: 0, active_tab_ttid: "", name: groupName, font: ""};
chrome.runtime.sendMessage({command: "append_group", groupId: groupId, group_name: groupName, font_color: "", windowId: windowId});
}
if (TabGroupId != groupId && groupId != null) {
b.tabs[tabId].parent = groupId;
setTimeout(function() {
chrome.runtime.sendMessage({command: "append_tab_to_group", tabId: tabId, groupId: groupId, windowId: windowId});
}, 100);
}
break;
}
}
return b.tabs[tabId].parent;
}
function FindGroupIdByName(name, groups) {
for (let groupId in groups) {
if (!groups.hasOwnProperty(groupId)) {
continue;
}
if (groups[groupId].name === name) {
return groupId;
}
}
return null;
}
////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// QUANTUM //////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
function QuantumStart(retry) {
chrome.windows.getAll({windowTypes: ["normal"], populate: true}, function(w) {
if (w[0].tabs.length == 1 && (w[0].tabs[0].url == "about:blank" || w[0].tabs[0].url == "about:sessionrestore")) {
setTimeout(function() {
QuantumStart(retry+1);
}, 2000);
} else {
QuantumLoadTabs(0);
if (retry > 0) {
chrome.runtime.sendMessage({command: "reload_sidebar"});
}
setTimeout(function() {
b.schedule_save = 0;
}, 2000);
}
});
}
function QuantumLoadTabs(retry) {
chrome.windows.getAll({windowTypes: ["normal"], populate: true}, function(w) {
chrome.storage.local.get(null, function(storage) {
// LOAD PREFERENCES
GetCurrentPreferences(storage);
// CACHED COUNTS AND STUFF
// let b.tt_ids = {};
let tabs_matched = 0;
let tabs_count = 0;
for (let wIndex = 0; wIndex < w.length; wIndex++) {
tabs_count += w[wIndex].tabs.length;
}
let lastWinId = w[w.length-1].id;
let lastTabId = w[w.length-1].tabs[w[w.length-1].tabs.length-1].id;
let WinCount = w.length;
if (opt.debug == true) {
if (storage.debug_log != undefined) {
b.debug = storage.debug_log;
}
if (retry == 0) {
pushlog("TreeTabs background start");
}
}
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
let winIndex = wIndex;
let winId = w[winIndex].id;
let tabsCount = w[winIndex].tabs.length;
// LOAD TTID FROM FIREFOX GET WINDOW VALUE
let win = Promise.resolve(browser.sessions.getWindowValue(winId, "TTdata")).then(function(WindowData) {
if (opt.skip_load == false && WindowData != undefined) {
b.windows[winId] = Object.assign({}, WindowData);
} else {
QuantumAppendWinTTId(winId);
}
for (let tIndex = 0; tIndex < tabsCount; tIndex++) {
let tab = w[winIndex].tabs[tIndex];
let tabIndex = tIndex;
let tabId = w[winIndex].tabs[tabIndex].id;
let tabPinned = w[winIndex].tabs[tabIndex].pinned;
if (tab.active) {
b.windows[winId].activeTabId[0] = tabId;
b.windows[winId].activeTabId[1] = tabId;
}
// LOAD TTID FROM FIREFOX GET TAB VALUE
let tt_tab = Promise.resolve(browser.sessions.getTabValue(tabId, "TTdata")).then(function(TabData) {
if (opt.skip_load == false && TabData != undefined) {
b.tabs[tabId] = Object.assign({}, TabData);
b.tt_ids[b.tabs[tabId].ttid] = tabId;
tabs_matched++;
} else {
QuantumAppendTabTTId(tab);
}
// IF ON LAST TAB AND LAST WINDOW, START MATCHING LOADED DATA
if (tabId == lastTabId && winId == lastWinId) {
// OK, DONE, NOW REPLACE OLD PARENTS IDS WITH THIS SESSION IDS
for (let ThisSessonTabId in b.tabs) {
if (b.tabs[ThisSessonTabId].parent_ttid != "" && b.tt_ids[b.tabs[ThisSessonTabId].parent_ttid] != undefined) {
b.tabs[ThisSessonTabId].parent = b.tt_ids[b.tabs[ThisSessonTabId].parent_ttid];
}
}
// OK, SAME THING FOR ACTIVE TABS IN GROUPS
for (let ThisSessonWinId in b.windows) {
for (let group in b.windows[ThisSessonWinId].groups) {
if (b.tt_ids[b.windows[ThisSessonWinId].groups[group].active_tab_ttid] != undefined) {
b.windows[ThisSessonWinId].groups[group].active_tab = b.tt_ids[b.windows[ThisSessonWinId].groups[group].active_tab_ttid];
}
if (b.tt_ids[b.windows[ThisSessonWinId].groups[group].prev_active_tab_ttid] != undefined) {
b.windows[ThisSessonWinId].groups[group].prev_active_tab = b.tt_ids[b.windows[ThisSessonWinId].groups[group].prev_active_tab_ttid];
}
}
}
if (opt.debug){ pushlog("QuantumLoadTabs, retry: "+retry); pushlog("Current windows count is: "+w.length); pushlog("Current tabs count is: "+tabs_count); pushlog("Matching tabs: "+tabs_matched); pushlog("Current windows:"); pushlog(w); }
// will try to find tabs for 3 times
if (opt.skip_load == true || retry > 2 || (tabs_matched > tabs_count*0.5)) {
b.running = true;
QuantumAutoSaveData();
QuantumStartListeners();
delete DefaultToolbar; delete DefaultTheme; delete DefaultPreferences;
} else {
if (opt.debug){
pushlog("Attempt "+retry+" failed, matched tabs was below 50%");
}
setTimeout(function() {
QuantumLoadTabs(retry+1);
}, 2000);
}
}
});
}
});
}
});
});
}
// save every second if there is anything to save obviously
async function QuantumAutoSaveData() {
setInterval(function() {
if (b.schedule_save > 1) {
b.schedule_save = 1;
}
if (b.running && b.schedule_save > 0 && Object.keys(b.tabs).length > 1) {
chrome.windows.getAll({windowTypes: ['normal'], populate: true}, function(w) {
let WinCount = w.length;
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
let winId = w[wIndex].id;
if (b.windows[winId] != undefined && b.windows[winId].ttid != undefined && b.windows[winId].group_bar != undefined && b.windows[winId].search_filter != undefined && b.windows[winId].active_shelf != undefined && b.windows[winId].active_group != undefined && b.windows[winId].groups != undefined && b.windows[winId].folders != undefined) {
browser.sessions.setWindowValue(winId, "TTdata", b.windows[winId] );
}
let TabsCount = w[wIndex].tabs.length;
for (let tabIndex = 0; tabIndex < TabsCount; tabIndex++) {
let tabId = w[wIndex].tabs[tabIndex].id;
if (b.tabs[tabId] != undefined && b.tabs[tabId].ttid != undefined && b.tabs[tabId].parent != undefined && b.tabs[tabId].index != undefined && b.tabs[tabId].expand != undefined) {
browser.sessions.setTabValue( tabId, "TTdata", b.tabs[tabId] );
}
}
}
b.schedule_save--;
});
}
if (opt.debug == true) { chrome.storage.local.set({debug_log: b.debug}); }
}, 1000);
}
function QuantumGenerateNewWindowID() {
let newID = "";
while (newID == "") {
newID = "w_"+GenerateRandomID();
for (let wId in b.windows) {
if (wId == newID) {
newID = "";
}
}
}
return newID;
}
function QuantumGenerateNewTabID() {
let newID = "";
while (newID == "") {
newID = "t_"+GenerateRandomID();
for (let tId in b.tabs) {
if (tId == newID) {
newID = "";
}
}
}
return newID;
}
function QuantumAppendTabTTId(tab) {
let NewTTTabId = QuantumGenerateNewTabID();
if (b.tabs[tab.id] != undefined) {
b.tabs[tab.id].ttid = NewTTTabId;
} else {
b.tabs[tab.id] = {ttid: NewTTTabId, parent: (b.windows[tab.windowId] ? b.windows[tab.windowId].active_group : "tab_list"), parent_ttid: "", index: tab.index, expand: ""};
}
b.tt_ids[NewTTTabId] = tab.id;
return NewTTTabId;
// if (b.schedule_save > 0) browser.sessions.setTabValue( tab.id, "TTdata", b.tabs[tab.id] );
}
function QuantumAppendWinTTId(windowId) {
let NewTTWindowId = QuantumGenerateNewWindowID();
if (b.windows[windowId] != undefined) {
b.windows[windowId].ttid = NewTTWindowId;
} else {
b.windows[windowId] = {activeTabId: [0,0], ttid: NewTTWindowId, group_bar: opt.groups_toolbar_default, search_filter: "url", active_shelf: "", active_group: "tab_list", groups: {tab_list: {id: "tab_list", index: 0, active_tab: 0, active_tab_ttid: "", prev_active_tab: 0, prev_active_tab_ttid: "", name: labels.ungrouped_group, font: ""}}, folders: {}};
}
// if (b.schedule_save > 0) browser.sessions.setWindowValue( windowId, "TTdata", b.windows[windowId] );
}
////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// CHROMIUM /////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
function ChromiumLoadTabs(retry) {
chrome.windows.getAll({windowTypes: ['normal'], populate: true}, function(w) {
chrome.storage.local.get(null, function(storage) {
// LOAD PREFERENCES
GetCurrentPreferences(storage);
// load tabs and windows from storage
let refTabs = {};
let tabs_matched = 0;
let w_count = storage.w_count ? storage.w_count : 0;
let t_count = storage.t_count ? storage.t_count : 0;
let LoadedWindows = storage.windows ? storage.windows : [];
let LoadedTabs = storage.tabs ? storage.tabs : [];
let CurrentTabsCount = 0;
for (let wIndex = 0; wIndex < w.length; wIndex++) {
CurrentTabsCount += w[wIndex].tabs.length;
}
let bak = (1 + retry) <= 3 ? (1 + retry) : 3;
if (opt.skip_load == false) {
// if loaded tabs mismatch by 50%, then try to load back
if (LoadedTabs.length < t_count*0.5) {
LoadedTabs = storage["tabs_BAK"+bak] ? storage["tabs_BAK"+bak] : [];
}
// if loaded windows mismatch, then try to load back
if (LoadedWindows.length < w_count) {
LoadedWindows = storage["windows_BAK"+bak] ? storage["windows_BAK"+bak] : [];
}
} else {
tabs_matched = CurrentTabsCount;
}
if (opt.debug == true) {
if (storage.debug_log != undefined) {
b.debug = storage.debug_log;
}
if (retry == 0) {
pushlog("TreeTabs background start");
}
}
// CACHED COUNTS
let WinCount = w.length;
let LoadedWinCount = LoadedWindows.length;
let LoadedTabsCount = LoadedTabs.length;
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
if (w[wIndex].tabs[0].url != "chrome://videopopout/") { // this is for opera for their extra video popup, which is weirdly queried as a "normal" window
let winId = w[wIndex].id;
let url1 = w[wIndex].tabs[0].url;
let url2 = w[wIndex].tabs[w[wIndex].tabs.length-1].url;
ChromiumAddWindowData(winId);
if (opt.skip_load == false) {
for (let LwIndex = 0; LwIndex < LoadedWinCount; LwIndex++) {
if (LoadedWindows[LwIndex].url1 == url1 || LoadedWindows[LwIndex].url2 == url2) {
if (LoadedWindows[LwIndex].group_bar) { b.windows[winId].group_bar = LoadedWindows[LwIndex].group_bar; }
if (LoadedWindows[LwIndex].search_filter) { b.windows[winId].search_filter = LoadedWindows[LwIndex].search_filter; }
if (LoadedWindows[LwIndex].active_shelf) { b.windows[winId].active_shelf = LoadedWindows[LwIndex].active_shelf; }
if (LoadedWindows[LwIndex].active_group) { b.windows[winId].active_group = LoadedWindows[LwIndex].active_group; }
if (Object.keys(LoadedWindows[LwIndex].groups).length > 0) { b.windows[winId].groups = Object.assign({}, LoadedWindows[LwIndex].groups); }
if (Object.keys(LoadedWindows[LwIndex].folders).length > 0) { b.windows[winId].folders = Object.assign({}, LoadedWindows[LwIndex].folders); }
LoadedWindows[LwIndex].url1 = "";
LoadedWindows[LwIndex].url2 = "";
break;
}
}
}
}
}
// add new hashes for current tabs
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
let TabsCount = w[wIndex].tabs.length;
for (let tabIndex = 0; tabIndex < TabsCount; tabIndex++) {
ChromiumHashURL(w[wIndex].tabs[tabIndex]);
if (w[wIndex].tabs[tabIndex].active) {
b.windows[w[wIndex].id].activeTabId[0] = w[wIndex].tabs[tabIndex].id;
b.windows[w[wIndex].id].activeTabId[1] = w[wIndex].tabs[tabIndex].id;
}
}
}
// compare saved tabs from storage to current session tabs, but can be skipped if set in options
if (opt.skip_load == false && LoadedTabs.length > 0) {
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
let TabsCount = w[wIndex].tabs.length;
for (let tabIndex = 0; tabIndex < TabsCount; tabIndex++) {
for (let LtabIndex = 0; LtabIndex < LoadedTabsCount; LtabIndex++) {
let tabId = w[wIndex].tabs[tabIndex].id;
if (LoadedTabs[LtabIndex].hash == b.tabs[tabId].hash && refTabs[LoadedTabs[LtabIndex].id] == undefined) {
refTabs[LoadedTabs[LtabIndex].id] = tabId;
if (LoadedTabs[LtabIndex].parent) { b.tabs[tabId].parent = LoadedTabs[LtabIndex].parent; }
if (LoadedTabs[LtabIndex].index) { b.tabs[tabId].index = LoadedTabs[LtabIndex].index; }
if (LoadedTabs[LtabIndex].expand) { b.tabs[tabId].expand = LoadedTabs[LtabIndex].expand; }
LoadedTabs[LtabIndex].hash = undefined;
tabs_matched++;
break;
}
}
}
}
// replace parents tabIds for new ones, for that purpose refTabs was made before
for (let tabId in b.tabs) {
if (refTabs[b.tabs[tabId].parent] != undefined) {
b.tabs[tabId].parent = refTabs[b.tabs[tabId].parent];
}
}
// replace active tab ids for each group using refTabs
for (let windowId in b.windows) {
for (let group in b.windows[windowId].groups) {
if (refTabs[b.windows[windowId].groups[group].active_tab]) {
b.windows[windowId].groups[group].active_tab = refTabs[b.windows[windowId].groups[group].active_tab];
}
if (refTabs[b.windows[windowId].groups[group].prev_active_tab]) {
b.windows[windowId].groups[group].prev_active_tab = refTabs[b.windows[windowId].groups[group].prev_active_tab];
}
}
}
}
if (opt.debug){
pushlog("ChromiumLoadTabs, retry: "+retry); pushlog("Current windows count is: "+w.length); pushlog("Saved windows count is: "+LoadedWindows.length); pushlog("Current tabs count is: "+CurrentTabsCount);
pushlog("Loaded tabs count is: "+LoadedTabsCount); pushlog("Matching tabs: "+tabs_matched); pushlog("Current windows:"); pushlog(w);
}
// will loop trying to find tabs
if (opt.skip_load || retry >= 5 || (tabs_matched > t_count*0.5)) {
b.running = true;
ChromiumAutoSaveData(0, 1000); ChromiumAutoSaveData(1, 300000); ChromiumAutoSaveData(2, 600000); ChromiumAutoSaveData(3, 1800000);
ChromiumStartListeners();
delete DefaultToolbar; delete DefaultTheme; delete DefaultPreferences;
b.schedule_save = -1; // 2 operations must be made to start saving data
} else {
if (opt.debug){
pushlog("Attempt "+retry+" failed, matched tabs was below 50%");
}
setTimeout(function() {
ChromiumLoadTabs(retry+1);
}, 5000);
}
});
});
}
async function ChromiumAutoSaveData(BAK, LoopTimer) {
setInterval(function() {
if (b.schedule_save > 1 || BAK > 0) {
b.schedule_save = 1;
}
if (b.running && b.schedule_save > 0 && Object.keys(b.tabs).length > 1) {
chrome.windows.getAll({windowTypes: ['normal'], populate: true}, function(w) {
let WinCount = w.length;
let t_count = 0;
let counter = 0;
let Windows = [];
let Tabs = [];
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
t_count += w[wIndex].tabs.length;
}
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
let winId = w[wIndex].id;
if (b.windows[winId] != undefined && b.windows[winId].group_bar != undefined && b.windows[winId].search_filter != undefined && b.windows[winId].active_shelf != undefined && b.windows[winId].active_group != undefined && b.windows[winId].groups != undefined && b.windows[winId].folders != undefined) {
Windows.push({ url1: w[wIndex].tabs[0].url, url2: w[wIndex].tabs[w[wIndex].tabs.length-1].url, group_bar: b.windows[winId].group_bar, search_filter: b.windows[winId].search_filter, active_shelf: b.windows[winId].active_shelf, active_group: b.windows[winId].active_group, groups: b.windows[winId].groups, folders: b.windows[winId].folders });
}
let TabsCount = w[wIndex].tabs.length;
for (let tabIndex = 0; tabIndex < TabsCount; tabIndex++) {
let tabId = w[wIndex].tabs[tabIndex].id;
if (b.tabs[tabId] != undefined && b.tabs[tabId].hash != undefined && b.tabs[tabId].parent != undefined && b.tabs[tabId].index != undefined && b.tabs[tabId].expand != undefined) {
Tabs.push({ id: tabId, hash: b.tabs[tabId].hash, parent: b.tabs[tabId].parent, index: b.tabs[tabId].index, expand: b.tabs[tabId].expand });
counter++;
}
}
if (counter == t_count) {
chrome.storage.local.set({t_count: t_count});
chrome.storage.local.set({w_count: WinCount});
if (BAK == 0) { chrome.storage.local.set({windows: Windows}); chrome.storage.local.set({tabs: Tabs}); }
if (BAK == 1) { chrome.storage.local.set({windows_BAK1: Windows}); chrome.storage.local.set({tabs_BAK1: Tabs}); chrome.runtime.sendMessage({command: "backup_available", bak: 1}); }
if (BAK == 2) { chrome.storage.local.set({windows_BAK2: Windows}); chrome.storage.local.set({tabs_BAK2: Tabs}); chrome.runtime.sendMessage({command: "backup_available", bak: 2}); }
if (BAK == 3) { chrome.storage.local.set({windows_BAK3: Windows}); chrome.storage.local.set({tabs_BAK3: Tabs}); chrome.runtime.sendMessage({command: "backup_available", bak: 3}); }
}
}
b.schedule_save--;
});
}
if (opt.debug == true) { chrome.storage.local.set({debug_log: b.debug}); }
}, LoopTimer);
}
function ChromiumAddWindowData(winId) {
b.windows[winId] = {activeTabId: [0,0], group_bar: opt.groups_toolbar_default, search_filter: "url", active_shelf: "", active_group: "tab_list", groups: {tab_list: {id: "tab_list", index: 0, active_tab: 0, prev_active_tab: 0, name: labels.ungrouped_group, font: ""}}, folders: {}};
}
function ChromiumHashURL(tab) {
if (b.tabs[tab.id] == undefined) { b.tabs[tab.id] = {hash: 0, parent: tab.pinned ? "pin_list" : (b.windows[tab.windowId] ? b.windows[tab.windowId].active_group : "tab_list"), index: (Object.keys(b.tabs).length + 1), expand: "n"}; }
let hash = 0;
for (let charIndex = 0; charIndex < tab.url.length; charIndex++) {
hash += tab.url.charCodeAt(charIndex);
}
b.tabs[tab.id].hash = hash;
}

460
bg_ch.js
View File

@ -1,460 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
function ChromeLoadTabs(retry) {
chrome.windows.getAll({windowTypes: ['normal'], populate: true}, function(w) {
chrome.storage.local.get(null, function(storage) {
// LOAD PREFERENCES
GetCurrentPreferences(storage);
// load tabs and windows from storage
let refTabs = {};
let tabs_matched = 0;
let w_count = storage.w_count ? storage.w_count : 0;
let t_count = storage.t_count ? storage.t_count : 0;
let LoadedWindows = storage.windows ? storage.windows : [];
let LoadedTabs = storage.tabs ? storage.tabs : [];
let bak = (1 + retry) <= 3 ? (1 + retry) : 3;
// if loaded tabs mismatch by 50%, then try to load back
if (LoadedTabs.length < t_count*0.5) {
LoadedTabs = storage["tabs_BAK"+bak] ? storage["tabs_BAK"+bak] : [];
}
// if loaded windows mismatch, then try to load back
if (LoadedWindows.length < w_count) {
LoadedWindows = storage["windows_BAK"+bak] ? storage["windows_BAK"+bak] : [];
}
if (opt.debug == true) {
if (storage.debug_log != undefined) {
debug = storage.debug_log;
}
if (retry == 0) {
pushlog("TreeTabs background start");
}
}
// CACHED COUNTS
let WinCount = w.length;
let LoadedWinCount = LoadedWindows.length;
let LoadedTabsCount = LoadedTabs.length;
let CurrentTabsCount = 0;
for (let wIndex = 0; wIndex < w.length; wIndex++) {
CurrentTabsCount += w[wIndex].tabs.length;
}
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
if (w[wIndex].tabs[0].url != "chrome://videopopout/") { // this is for opera for their extra video popup, which is weirdly queried as a "normal" window
let winId = w[wIndex].id;
let url1 = w[wIndex].tabs[0].url;
let url2 = w[wIndex].tabs[w[wIndex].tabs.length-1].url;
windows[winId] = {group_bar: opt.groups_toolbar_default, search_filter: "url", active_shelf: "", active_group: "tab_list", groups: {tab_list: {id: "tab_list", index: 0, active_tab: 0, prev_active_tab: 0, name: caption_ungrouped_group, font: ""}}, folders: {}};
for (let LwIndex = 0; LwIndex < LoadedWinCount; LwIndex++) {
if (LoadedWindows[LwIndex].url1 == url1 || LoadedWindows[LwIndex].url2 == url2) {
if (LoadedWindows[LwIndex].group_bar) { windows[winId].group_bar = LoadedWindows[LwIndex].group_bar; }
if (LoadedWindows[LwIndex].search_filter) { windows[winId].search_filter = LoadedWindows[LwIndex].search_filter; }
if (LoadedWindows[LwIndex].active_shelf) { windows[winId].active_shelf = LoadedWindows[LwIndex].active_shelf; }
if (LoadedWindows[LwIndex].active_group) { windows[winId].active_group = LoadedWindows[LwIndex].active_group; }
if (Object.keys(LoadedWindows[LwIndex].groups).length > 0) { windows[winId].groups = Object.assign({}, LoadedWindows[LwIndex].groups); }
if (Object.keys(LoadedWindows[LwIndex].folders).length > 0) { windows[winId].folders = Object.assign({}, LoadedWindows[LwIndex].folders); }
LoadedWindows[LwIndex].url1 = "";
LoadedWindows[LwIndex].url2 = "";
break;
}
}
}
}
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
let TabsCount = w[wIndex].tabs.length;
for (let tabIndex = 0; tabIndex < TabsCount; tabIndex++) {
ChromeHashURL(w[wIndex].tabs[tabIndex]);
}
}
if (opt.skip_load == false && LoadedTabs.length > 0) { // compare saved tabs from storage to current session tabs, but can be skipped if set in options
for (let wIndex = 0; wIndex < WinCount; wIndex++) { // match loaded tabs
let TabsCount = w[wIndex].tabs.length;
for (let tabIndex = 0; tabIndex < TabsCount; tabIndex++) {
for (let LtabIndex = 0; LtabIndex < LoadedTabsCount; LtabIndex++) {
let tabId = w[wIndex].tabs[tabIndex].id;
if (LoadedTabs[LtabIndex].hash == tabs[tabId].hash && refTabs[LoadedTabs[LtabIndex].id] == undefined) {
refTabs[LoadedTabs[LtabIndex].id] = tabId;
if (LoadedTabs[LtabIndex].parent) { tabs[tabId].parent = LoadedTabs[LtabIndex].parent; }
if (LoadedTabs[LtabIndex].index) { tabs[tabId].index = LoadedTabs[LtabIndex].index; }
if (LoadedTabs[LtabIndex].expand) { tabs[tabId].expand = LoadedTabs[LtabIndex].expand; }
LoadedTabs[LtabIndex].hash = undefined;
tabs_matched++;
break;
}
}
}
}
// replace parents tabIds for new ones, for that purpose refTabs was made before
for (let tabId in tabs) {
if (refTabs[tabs[tabId].parent] != undefined) {
tabs[tabId].parent = refTabs[tabs[tabId].parent];
}
}
}
// replace active tab ids for each group using refTabs
for (let windowId in windows) {
for (let group in windows[windowId].groups) {
if (refTabs[windows[windowId].groups[group].active_tab]) {
windows[windowId].groups[group].active_tab = refTabs[windows[windowId].groups[group].active_tab];
}
if (refTabs[windows[windowId].groups[group].prev_active_tab]) {
windows[windowId].groups[group].prev_active_tab = refTabs[windows[windowId].groups[group].prev_active_tab];
}
}
}
if (opt.debug){
pushlog("ChromeLoadTabs, retry: "+retry);
pushlog("Current windows count is: "+w.length);
pushlog("Saved windows count is: "+LoadedWindows.length);
pushlog("Current tabs count is: "+CurrentTabsCount);
pushlog("Loaded tabs count is: "+LoadedTabsCount);
pushlog("Matching tabs: "+tabs_matched);
pushlog("Current windows:");
pushlog(w);
}
// will loop trying to find tabs
if (opt.skip_load == true || retry >= 5 || (tabs_matched > t_count*0.5)) {
running = true;
ChromeAutoSaveData(0, 1000);
ChromeAutoSaveData(1, 300000);
ChromeAutoSaveData(2, 600000);
ChromeAutoSaveData(3, 1800000);
ChromeListeners();
delete schedule_update_data;
delete schedule_rearrange_tabs;
delete DragNodeClass;
delete DragOverTimer;
delete DragTreeDepth;
delete menuItemNode;
delete CurrentWindowId;
delete SearchIndex;
delete active_group;
delete browserId;
delete bggroups;
delete bgfolders;
delete caption_clear_filter;
delete caption_loading;
delete caption_searchbox;
delete DefaultToolbar;
delete DefaultTheme;
delete DefaultPreferences;
delete newTabUrl;
delete EmptyTabs;
delete tt_ids;
schedule_save = -1; // 2 operations must be made to start saving data
} else {
if (opt.debug){
pushlog("Attempt "+retry+" failed, matched tabs was below 50%");
}
setTimeout(function() {
ChromeLoadTabs(retry+1);
}, 5000);
}
});
});
}
// You maybe are asking yourself why I save tabs in array? It's because, instead of, keeping 2 index numbers (one for browser tabs on top and one for my index in tree), it's easier to just arrange them in order and save it in localstorage.
// Another reason is that Object does not preserve order in chrome, I've been told that in Firefox it is. But I can't trust that.
async function ChromeAutoSaveData(BAK, LoopTimer) {
setInterval(function() {
if (schedule_save > 1 || BAK > 0) {
schedule_save = 1;
}
if (running && schedule_save > 0 && Object.keys(tabs).length > 1) {
chrome.windows.getAll({windowTypes: ['normal'], populate: true}, function(w) {
let WinCount = w.length;
let t_count = 0;
let counter = 0;
let Windows = [];
let Tabs = [];
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
t_count += w[wIndex].tabs.length;
}
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
let winId = w[wIndex].id;
if (windows[winId] != undefined && windows[winId].group_bar != undefined && windows[winId].search_filter != undefined && windows[winId].active_shelf != undefined && windows[winId].active_group != undefined && windows[winId].groups != undefined && windows[winId].folders != undefined) {
Windows.push({url1: w[wIndex].tabs[0].url, url2: w[wIndex].tabs[w[wIndex].tabs.length-1].url, group_bar: windows[winId].group_bar, search_filter: windows[winId].search_filter, active_shelf: windows[winId].active_shelf, active_group: windows[winId].active_group, groups: windows[winId].groups, folders: windows[winId].folders});
}
let TabsCount = w[wIndex].tabs.length;
for (let tabIndex = 0; tabIndex < TabsCount; tabIndex++) {
let tabId = w[wIndex].tabs[tabIndex].id;
if (tabs[tabId] != undefined && tabs[tabId].hash != undefined && tabs[tabId].parent != undefined && tabs[tabId].index != undefined && tabs[tabId].expand != undefined) {
Tabs.push({id: tabId, hash: tabs[tabId].hash, parent: tabs[tabId].parent, index: tabs[tabId].index, expand: tabs[tabId].expand});
counter++;
}
}
if (counter == t_count) {
chrome.storage.local.set({t_count: t_count});
chrome.storage.local.set({w_count: WinCount});
if (BAK == 0) {
chrome.storage.local.set({windows: Windows});
chrome.storage.local.set({tabs: Tabs});
}
if (BAK == 1) {
chrome.storage.local.set({windows_BAK1: Windows});
chrome.storage.local.set({tabs_BAK1: Tabs});
chrome.runtime.sendMessage({command: "backup_available", bak: 1});
}
if (BAK == 2) {
chrome.storage.local.set({windows_BAK2: Windows});
chrome.storage.local.set({tabs_BAK2: Tabs});
chrome.runtime.sendMessage({command: "backup_available", bak: 2});
}
if (BAK == 3) {
chrome.storage.local.set({windows_BAK3: Windows});
chrome.storage.local.set({tabs_BAK3: Tabs});
chrome.runtime.sendMessage({command: "backup_available", bak: 3});
}
}
}
schedule_save--;
});
}
if (opt.debug == true) {
chrome.storage.local.set({debug_log: debug});
}
}, LoopTimer);
}
function ChromeHashURL(tab) {
if (tabs[tab.id] == undefined) {
tabs[tab.id] = {hash: 0, parent: tab.pinned ? "pin_list" : (windows[tab.windowId] ? windows[tab.windowId].active_group : "tab_list"), index: tab.index, expand: "n"};
}
let hash = 0;
for (let charIndex = 0; charIndex < tab.url.length; charIndex++) {
hash += tab.url.charCodeAt(charIndex);
}
tabs[tab.id].hash = hash;
}
function ReplaceParents(oldTabId, newTabId) {
for (let tabId in tabs) {
if (tabs[tabId].parent == oldTabId) {
tabs[tabId].parent = newTabId;
}
}
}
function ChromeListeners() { // start all listeners
chrome.tabs.onCreated.addListener(function(tab) {
ChromeHashURL(tab);
chrome.runtime.sendMessage({command: "tab_created", windowId: tab.windowId, tabId: tab.id});
schedule_save++;
});
chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
setTimeout(function() { chrome.runtime.sendMessage({command: "tab_removed", windowId: removeInfo.windowId, tabId: tabId}); },5);
delete tabs[tabId];
schedule_save++;
});
chrome.tabs.onAttached.addListener(function(tabId, attachInfo) {
chrome.tabs.get(tabId, function(tab) {
chrome.runtime.sendMessage({command: "tab_attached", windowId: attachInfo.newWindowId, tab: tab, tabId: tabId, ParentId: tabs[tabId].parent});
});
schedule_save++;
});
chrome.tabs.onDetached.addListener(function(tabId, detachInfo) {
chrome.runtime.sendMessage({command: "tab_detached", windowId: detachInfo.oldWindowId, tabId: tabId});
schedule_save++;
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (tabs[tabId] == undefined || changeInfo.url != undefined) {
ChromeHashURL(tab);
}
if (changeInfo.pinned != undefined) {
schedule_save++;
}
if (changeInfo.pinned == true) {
tabs[tabId].parent = "pin_list";
}
if (changeInfo.title != undefined && !tab.active) {
chrome.runtime.sendMessage({command: "tab_attention", windowId: tab.windowId, tabId: tabId});
}
chrome.runtime.sendMessage({command: "tab_updated", windowId: tab.windowId, tab: tab, tabId: tabId, changeInfo: changeInfo});
});
chrome.tabs.onMoved.addListener(function(tabId, moveInfo) {
schedule_save++;
});
chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) {
chrome.tabs.get(addedTabId, function(tab) {
if (addedTabId == removedTabId) {
chrome.runtime.sendMessage({command: "tab_updated", windowId: tab.windowId, tab: tab, tabId: tab.id, changeInfo: {status: tab.status, url: tab.url, title: tab.title, audible: tab.audible, mutedInfo: tab.mutedInfo}});
} else {
ReplaceParents(tabId, tab.id);
if (tabs[removedTabId]) {
tabs[addedTabId] = tabs[removedTabId];
} else {
ChromeHashURL(tab);
}
chrome.runtime.sendMessage({command: "tab_removed", windowId: tab.windowId, tabId: removedTabId});
chrome.runtime.sendMessage({command: "tab_attached", windowId: tab.windowId, tab: tab, tabId: addedTabId});
delete tabs[removedTabId];
}
schedule_save++;
});
});
chrome.tabs.onActivated.addListener(function(activeInfo) {
chrome.runtime.sendMessage({command: "tab_activated", windowId: activeInfo.windowId, tabId: activeInfo.tabId});
});
chrome.windows.onCreated.addListener(function(window) {
windows[window.id] = {group_bar: opt.groups_toolbar_default, search_filter: "url", active_shelf: "", active_group: "tab_list", groups: {tab_list: {id: "tab_list", index: 0, active_tab: 0, prev_active_tab: 0, name: caption_ungrouped_group, font: ""}}, folders: {}};
schedule_save++;
});
chrome.windows.onRemoved.addListener(function(windowId) {
delete windows[windowId];
schedule_save++;
});
chrome.runtime.onSuspend.addListener(function() {
running = false;
});
}
function ChromeMessageListeners() {
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message.command == "reload") {
window.location.reload();
return;
}
if (message.command == "get_windows") {
sendResponse(windows);
return;
}
if (message.command == "get_folders") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].folders);
}
return;
}
if (message.command == "save_folders") {
if (windows[message.windowId]) {
windows[message.windowId].folders = Object.assign({}, message.folders);
schedule_save++;
}
return;
}
if (message.command == "get_groups") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].groups);
}
return;
}
if (message.command == "save_groups") {
if (windows[message.windowId]) {
windows[message.windowId].groups = Object.assign({}, message.groups);
schedule_save++;
}
return;
}
if (message.command == "set_active_group") {
if (windows[message.windowId]) {
windows[message.windowId].active_group = message.active_group;
schedule_save++;
}
return;
}
if (message.command == "get_active_group") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].active_group);
}
return;
}
if (message.command == "set_search_filter") {
if (windows[message.windowId]) {
windows[message.windowId].search_filter = message.search_filter;
schedule_save++;
}
return;
}
if (message.command == "get_search_filter") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].search_filter);
}
return;
}
if (message.command == "set_active_shelf") {
if (windows[message.windowId]) {
windows[message.windowId].active_shelf = message.active_shelf;
schedule_save++;
}
return;
}
if (message.command == "get_active_shelf") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].active_shelf);
}
return;
}
if (message.command == "set_group_bar") {
if (windows[message.windowId]) {
windows[message.windowId].group_bar = message.group_bar;
schedule_save++;
}
return;
}
if (message.command == "get_group_bar") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].group_bar);
}
return;
}
if (message.command == "get_browser_tabs") {
sendResponse(tabs);
return;
}
if (message.command == "is_bg_ready") {
sendResponse(running);
return;
}
if (message.command == "update_tab") {
if (tabs[message.tabId]) {
if (message.tab.index) {
tabs[message.tabId].index = message.tab.index;
}
if (message.tab.expand) {
tabs[message.tabId].expand = message.tab.expand;
}
if (message.tab.parent) {
tabs[message.tabId].parent = message.tab.parent;
}
schedule_save++;
}
return;
}
if (message.command == "update_all_tabs") {
for (let i = 0; i < message.pins.length; i++) {
if (tabs[message.pins[i].id]) {
tabs[message.pins[i].id].parent = "pin_list";
tabs[message.pins[i].id].expand = "";
tabs[message.pins[i].id].index = message.pins[i].index;
}
}
for (let j = 0; j < message.tabs.length; j++) {
if (tabs[message.tabs[j].id]) {
tabs[message.tabs[j].id].parent = message.tabs[j].parent;
tabs[message.tabs[j].id].expand = message.tabs[j].expand;
tabs[message.tabs[j].id].index = message.tabs[j].index;
}
}
schedule_save++;
return;
}
if (message.command == "debug") {
pushlog(message.log);
return;
}
});
}

525
bg_ff.js
View File

@ -1,525 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
function FirefoxStart(retry) {
chrome.windows.getAll({windowTypes: ["normal"], populate: true}, function(w) {
if (w[0].tabs.length == 1 && (w[0].tabs[0].url == "about:blank" || w[0].tabs[0].url == "about:sessionrestore")) {
setTimeout(function() {
FirefoxStart(retry+1);
}, 2000);
} else {
FirefoxLoadTabs(0);
if (retry > 0) {
chrome.runtime.sendMessage({command: "reload_sidebar"});
}
setTimeout(function() {
schedule_save = 0;
}, 2000);
}
});
}
function FirefoxLoadTabs(retry) {
chrome.windows.getAll({windowTypes: ["normal"], populate: true}, function(w) {
chrome.storage.local.get(null, function(storage) {
// LOAD PREFERENCES
GetCurrentPreferences(storage);
// CACHED COUNTS AND STUFF
// let tt_ids = {};
let tabs_matched = 0;
let tabs_count = 0;
for (let wIndex = 0; wIndex < w.length; wIndex++) {
tabs_count += w[wIndex].tabs.length;
}
let lastWinId = w[w.length-1].id;
let lastTabId = w[w.length-1].tabs[w[w.length-1].tabs.length-1].id;
let WinCount = w.length;
if (opt.debug == true) {
if (storage.debug_log != undefined) {
debug = storage.debug_log;
}
if (retry == 0) {
pushlog("TreeTabs background start");
}
}
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
let winIndex = wIndex;
let winId = w[winIndex].id;
let tabsCount = w[winIndex].tabs.length;
// LOAD TTID FROM FIREFOX GET WINDOW VALUE
let win = Promise.resolve(browser.sessions.getWindowValue(winId, "TTdata")).then(function(WindowData) {
if (opt.skip_load == false && WindowData != undefined) {
windows[winId] = Object.assign({}, WindowData);
} else {
windows[winId] = {ttid: "", group_bar: opt.groups_toolbar_default, search_filter: "url", active_shelf: "", active_group: "tab_list", groups: {tab_list: {id: "tab_list", index: 0, active_tab: 0, active_tab_ttid: "", prev_active_tab: 0, prev_active_tab_ttid: "", name: caption_ungrouped_group, font: ""}}, folders: {}};
}
for (let tIndex = 0; tIndex < tabsCount; tIndex++) {
let tabIndex = tIndex;
let tabId = w[winIndex].tabs[tabIndex].id;
let tabPinned = w[winIndex].tabs[tabIndex].pinned;
// LOAD TTID FROM FIREFOX GET TAB VALUE
let tab = Promise.resolve(browser.sessions.getTabValue(tabId, "TTdata")).then(function(TabData) {
if (opt.skip_load == false && TabData != undefined) {
tabs[tabId] = Object.assign({}, TabData);
tt_ids[tabs[tabId].ttid] = tabId;
tabs_matched++;
} else {
tabs[tabId] = {ttid: "", parent_ttid: "", parent: tabPinned ? "pin_list" : "tab_list", index: tabIndex, expand: ""};
}
// IF ON LAST TAB AND LAST WINDOW, START MATCHING LOADED DATA
if (tabId == lastTabId && winId == lastWinId) {
for (let ThisSessonWinId in windows) {
if (windows[ThisSessonWinId].ttid == "") {
AppendWinTTId(parseInt(ThisSessonWinId));
}
}
// OK, DONE WITH WINDOWS, START TABS LOOP
for (let ThisSessonTabId in tabs) {
if (tabs[ThisSessonTabId].ttid == "") {
AppendTabTTId(parseInt(ThisSessonTabId));
}
}
// OK, DONE, NOW REPLACE OLD PARENTS IDS WITH THIS SESSION IDS
for (let ThisSessonTabId in tabs) {
if (tt_ids[tabs[ThisSessonTabId].parent_ttid] != undefined) {
tabs[ThisSessonTabId].parent = tt_ids[tabs[ThisSessonTabId].parent_ttid];
}
}
// OK, SAME THING FOR ACTIVE TABS IN GROUPS
for (let ThisSessonWinId in windows) {
for (let group in windows[ThisSessonWinId].groups) {
if (tt_ids[windows[ThisSessonWinId].groups[group].active_tab_ttid] != undefined) {
windows[ThisSessonWinId].groups[group].active_tab = tt_ids[windows[ThisSessonWinId].groups[group].active_tab_ttid];
}
if (tt_ids[windows[ThisSessonWinId].groups[group].prev_active_tab_ttid] != undefined) {
windows[ThisSessonWinId].groups[group].prev_active_tab = tt_ids[windows[ThisSessonWinId].groups[group].prev_active_tab_ttid];
}
}
}
if (opt.debug){
pushlog("FirefoxLoadTabs, retry: "+retry);
pushlog("Current windows count is: "+w.length);
pushlog("Current tabs count is: "+tabs_count);
pushlog("Matching tabs: "+tabs_matched);
pushlog("Current windows:");
pushlog(w);
}
// will try to find tabs for 3 times
if (opt.skip_load == true || retry > 2 || (tabs_matched > tabs_count*0.5)) {
running = true;
FirefoxAutoSaveData();
FirefoxListeners();
delete schedule_update_data;
delete schedule_rearrange_tabs;
delete DragNodeClass;
delete DragOverTimer;
delete DragTreeDepth;
delete menuItemNode;
delete CurrentWindowId;
delete SearchIndex;
delete active_group;
delete browserId;
delete bggroups;
delete bgfolders;
delete caption_clear_filter;
delete caption_loading;
delete caption_searchbox;
delete DefaultToolbar;
delete DefaultTheme;
delete DefaultPreferences;
delete newTabUrl;
delete EmptyTabs;
} else {
if (opt.debug){
pushlog("Attempt "+retry+" failed, matched tabs was below 50%");
}
setTimeout(function() {
FirefoxLoadTabs(retry+1);
}, 2000);
}
}
});
}
});
}
});
});
}
// save every second if there is anything to save obviously
async function FirefoxAutoSaveData() {
setInterval(function() {
if (schedule_save > 1) {
schedule_save = 1;
}
if (running && schedule_save > 0 && Object.keys(tabs).length > 1) {
chrome.windows.getAll({windowTypes: ['normal'], populate: true}, function(w) {
let WinCount = w.length;
for (let wIndex = 0; wIndex < WinCount; wIndex++) {
let winId = w[wIndex].id;
if (windows[winId] != undefined && windows[winId].ttid != undefined && windows[winId].group_bar != undefined && windows[winId].search_filter != undefined && windows[winId].active_shelf != undefined && windows[winId].active_group != undefined && windows[winId].groups != undefined && windows[winId].folders != undefined) {
browser.sessions.setWindowValue(winId, "TTdata", windows[winId] );
}
let TabsCount = w[wIndex].tabs.length;
for (let tabIndex = 0; tabIndex < TabsCount; tabIndex++) {
let tabId = w[wIndex].tabs[tabIndex].id;
if (tabs[tabId] != undefined && tabs[tabId].ttid != undefined && tabs[tabId].parent != undefined && tabs[tabId].index != undefined && tabs[tabId].expand != undefined) {
browser.sessions.setTabValue( tabId, "TTdata", tabs[tabId] );
}
}
}
schedule_save--;
});
}
if (opt.debug == true) {
chrome.storage.local.set({debug_log: debug});
}
}, 1000);
}
function GenerateNewWindowID() {
let newID = "w_"+GenerateRandomID();
let newIdAvailable = true;
for (let windowId in windows) {
if (windows[windowId].ttid == newID) {
newIdAvailable = false;
}
}
if (newIdAvailable) {
return newID;
} else {
GenerateNewWindowID();
}
}
function GenerateNewTabID() {
let newID = "t_"+GenerateRandomID();
let newIdAvailable = true;
// for (let tabId in tabs) {
// if (tabs[tabId].ttid == newID) {
// newIdAvailable = false;
// }
// }
if (tt_ids[newID] != undefined) {
newIdAvailable = false;
}
if (newIdAvailable) {
return newID;
} else {
GenerateNewTabID();
}
}
function AppendTabTTId(tabId) {
let NewTTTabId = GenerateNewTabID();
if (tabs[tabId] != undefined) {
tabs[tabId].ttid = NewTTTabId;
} else {
tabs[tabId] = {ttid: NewTTTabId, parent: "tab_list", parent_ttid: "", index: 0, expand: ""};
}
tt_ids[NewTTTabId] = tabId;
return NewTTTabId;
// if (schedule_save > 0) browser.sessions.setTabValue( tabId, "TTdata", tabs[tabId] );
}
function AppendWinTTId(windowId) {
let NewTTWindowId = GenerateNewWindowID();
if (windows[windowId] != undefined) {
windows[windowId].ttid = NewTTWindowId;
} else {
windows[windowId] = {ttid: NewTTWindowId, group_bar: opt.groups_toolbar_default, search_filter: "url", active_shelf: "", active_group: "tab_list", groups: {tab_list: {id: "tab_list", index: 0, active_tab: 0, active_tab_ttid: "", prev_active_tab: 0, prev_active_tab_ttid: "", name: caption_ungrouped_group, font: ""}}, folders: {}};
}
// if (schedule_save > 0) browser.sessions.setWindowValue( windowId, "TTdata", windows[windowId] );
}
function ReplaceParents(oldTabId, newTabId) {
for (let tabId in tabs) {
if (tabs[tabId].parent == oldTabId) {
tabs[tabId].parent = newTabId;
}
}
}
let DETACHED_TABS___Bug1398272___WTF_ARE_YOU_DOING_MOZILLA = {}; // MOZILLA BUG 1398272
// start all listeners
function FirefoxListeners() {
browser.browserAction.onClicked.addListener(function() {
browser.sidebarAction.setPanel({panel: (browser.extension.getURL("/sidebar.html")) });
browser.sidebarAction.open();
});
chrome.tabs.onCreated.addListener(function(tab) {
let t = Promise.resolve(browser.sessions.getTabValue(tab.id, "TTdata")).then(function(TabData) {
if (TabData != undefined) {
tabs[tab.id] = Object.assign({}, TabData);
let originalParent = TabData.parent_ttid == "" ? undefined : (tt_ids[TabData.parent_ttid] ? tt_ids[TabData.parent_ttid] : TabData.parent_ttid);
chrome.runtime.sendMessage({command: "tab_created", windowId: tab.windowId, tabId: tab.id, parentTabId: originalParent, index: TabData.index});
} else {
AppendTabTTId(tab.id);
chrome.runtime.sendMessage({command: "tab_created", windowId: tab.windowId, tabId: tab.id});
}
schedule_save++;
});
});
chrome.tabs.onAttached.addListener(function(tabId, attachInfo) {
let oldId = tabId;
chrome.tabs.get(oldId, function(tab) {
ReplaceParents(oldId, tab.id);
tt_ids[tabs[oldId].ttid] = tab.id; // MOZILLA BUG 1398272
tabs[tab.id] = tabs[oldId]; // MOZILLA BUG 1398272
DETACHED_TABS___Bug1398272___WTF_ARE_YOU_DOING_MOZILLA[oldId] = tab.id; // MOZILLA BUG 1398272
DETACHED_TABS___Bug1398272___WTF_ARE_YOU_DOING_MOZILLA[tab.id] = oldId; // MOZILLA BUG 1398272
browser.sessions.setTabValue( tab.id, "TTdata", tabs[oldId] ); // MOZILLA BUG 1398272
chrome.runtime.sendMessage({command: "tab_attached", windowId: attachInfo.newWindowId, tab: tab, tabId: tab.id, ParentId: tabs[tab.id].parent});
schedule_save++;
});
});
chrome.tabs.onDetached.addListener(function(tabId, detachInfo) {
chrome.runtime.sendMessage({command: "tab_detached", windowId: detachInfo.oldWindowId, tabId: tabId});
let detachTabId = tabId;
if (DETACHED_TABS___Bug1398272___WTF_ARE_YOU_DOING_MOZILLA[tabId] != undefined) { // MOZILLA BUG 1398272
detachTabId = DETACHED_TABS___Bug1398272___WTF_ARE_YOU_DOING_MOZILLA[tabId]; // MOZILLA BUG 1398272
chrome.runtime.sendMessage({command: "tab_detached", windowId: detachInfo.oldWindowId, tabId: DETACHED_TABS___Bug1398272___WTF_ARE_YOU_DOING_MOZILLA[tabId]}); // MOZILLA BUG 1398272
} // MOZILLA BUG 1398272
});
chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
setTimeout(function() {
if (DETACHED_TABS___Bug1398272___WTF_ARE_YOU_DOING_MOZILLA[tabId] != undefined) { // MOZILLA BUG 1398272
chrome.runtime.sendMessage({command: "tab_removed", windowId: removeInfo.windowId, tabId: DETACHED_TABS___Bug1398272___WTF_ARE_YOU_DOING_MOZILLA[tabId]}); // MOZILLA BUG 1398272
} // MOZILLA BUG 1398272
chrome.runtime.sendMessage({command: "tab_removed", windowId: removeInfo.windowId, tabId: tabId});
}, 5);
// setTimeout(function() {
// delete tabs[tabId];
// },60000);
schedule_save++;
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.pinned == true && tabs[tabId]) {
tabs[tabId].parent = "pin_list";
tabs[tabId].parent_ttid = "";
schedule_save++;
} else {
AppendTabTTId(tabId);
}
if (changeInfo.title != undefined && !tab.active) {
chrome.runtime.sendMessage({command: "tab_attention", windowId: tab.windowId, tabId: tabId});
}
chrome.runtime.sendMessage({command: "tab_updated", windowId: tab.windowId, tab: tab, tabId: tabId, changeInfo: changeInfo});
});
chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) {
chrome.tabs.get(addedTabId, function(tab) {
if (addedTabId == removedTabId) {
chrome.runtime.sendMessage({command: "tab_updated", windowId: tab.windowId, tab: tab, tabId: tab.id, changeInfo: {status: tab.status, url: tab.url, title: tab.title, audible: tab.audible, mutedInfo: tab.mutedInfo}});
} else {
if (tabs[removedTabId]) {
tabs[addedTabId] = tabs[removedTabId];
}
ReplaceParents(tabId, tab.id);
chrome.runtime.sendMessage({command: "tab_removed", windowId: tab.windowId, tabId: removedTabId});
chrome.runtime.sendMessage({command: "tab_attached", windowId: tab.windowId, tab: tab, tabId: addedTabId, ParentId: tabs[addedTabId].parent});
// delete ttid[tabs[removedTabId].ttid];
// delete tabs[removedTabId];
}
setTimeout(function() {
AppendTabTTId(addedTabId);
schedule_save++;
}, 100);
});
});
chrome.tabs.onActivated.addListener(function(activeInfo) {
chrome.runtime.sendMessage({command: "tab_activated", windowId: activeInfo.windowId, tabId: activeInfo.tabId});
});
chrome.windows.onCreated.addListener(function(window) {
let win = Promise.resolve(browser.sessions.getWindowValue(window.id, "TTdata")).then(function(WindowData) {
if (WindowData != undefined) {
windows[window.id] = Object.assign({}, WindowData);
} else {
AppendWinTTId(window.id);
}
schedule_save++;
});
});
chrome.windows.onRemoved.addListener(function(windowId) {
// delete windows[windowId];
schedule_save++;
});
chrome.sessions.onChanged.addListener(function(session) {
chrome.windows.getAll({windowTypes: ['normal'], populate: false}, function(w) {
chrome.tabs.query({}, function(t) {
for (let wiInd = 0; wiInd < w.length; wiInd++) {
if (windows[w[wiInd].id] == undefined) {
chrome.runtime.sendMessage({command: "reload_sidebar"});
window.location.reload();
}
}
for (let tbInd = 0; tbInd < t.length; tbInd++) {
if (tabs[t[tbInd].id] == undefined) {
chrome.runtime.sendMessage({command: "reload_sidebar"});
window.location.reload();
}
}
});
});
});
}
function FirefoxMessageListeners() {
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message.command == "reload") {
window.location.reload();
return;
}
if (message.command == "get_windows") {
sendResponse(windows);
return;
}
if (message.command == "get_folders") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].folders);
}
return;
}
if (message.command == "save_folders") {
if (windows[message.windowId]) {
windows[message.windowId].folders = Object.assign({}, message.folders);
schedule_save++;
}
return;
}
if (message.command == "get_groups") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].groups);
}
return;
}
if (message.command == "save_groups") {
if (windows[message.windowId]) {
windows[message.windowId].groups = Object.assign({}, message.groups);
for (let group in windows[message.windowId].groups) {
if (tabs[windows[message.windowId].groups[group].active_tab]) {
windows[message.windowId].groups[group].active_tab_ttid = tabs[windows[message.windowId].groups[group].active_tab].ttid;
}
if (tabs[windows[message.windowId].groups[group].prev_active_tab]) {
windows[message.windowId].groups[group].prev_active_tab_ttid = tabs[windows[message.windowId].groups[group].prev_active_tab].ttid;
}
}
schedule_save++;
}
return;
}
if (message.command == "set_active_group") {
if (windows[message.windowId]) {
windows[message.windowId].active_group = message.active_group;
schedule_save++;
}
return;
}
if (message.command == "get_active_group") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].active_group);
}
return;
}
if (message.command == "set_search_filter") {
if (windows[message.windowId]) {
windows[message.windowId].search_filter = message.search_filter;
schedule_save++;
}
return;
}
if (message.command == "get_search_filter") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].search_filter);
}
return;
}
if (message.command == "set_active_shelf") {
if (windows[message.windowId]) {
windows[message.windowId].active_shelf = message.active_shelf;
schedule_save++;
}
return;
}
if (message.command == "get_active_shelf") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].active_shelf);
}
return;
}
if (message.command == "set_group_bar") {
if (windows[message.windowId]) {
windows[message.windowId].group_bar = message.group_bar;
schedule_save++;
}
return;
}
if (message.command == "get_group_bar") {
if (windows[message.windowId]) {
sendResponse(windows[message.windowId].group_bar);
}
return;
}
if (message.command == "get_browser_tabs") {
sendResponse(tabs);
return;
}
if (message.command == "is_bg_ready") {
sendResponse(running);
return;
}
if (message.command == "update_tab") {
if (tabs[message.tabId]) {
if (message.tab.index) {
tabs[message.tabId].index = message.tab.index;
}
if (message.tab.expand) {
tabs[message.tabId].expand = message.tab.expand;
}
if (message.tab.parent) {
tabs[message.tabId].parent = message.tab.parent;
if (tabs[message.tab.parent]) {
tabs[message.tabId].parent_ttid = tabs[message.tab.parent].ttid;
} else {
tabs[message.tabId].parent_ttid = "";
}
}
schedule_save++;
}
return;
}
if (message.command == "update_all_tabs") {
for (let i = 0; i < message.pins.length; i++) {
if (tabs[message.pins[i].id]) {
tabs[message.pins[i].id].parent = "pin_list";
tabs[message.pins[i].id].parent_ttid = "";
tabs[message.pins[i].id].expand = "";
tabs[message.pins[i].id].index = message.pins[i].index;
}
}
for (let j = 0; j < message.tabs.length; j++) {
if (tabs[message.tabs[j].id]) {
tabs[message.tabs[j].id].parent = message.tabs[j].parent;
tabs[message.tabs[j].id].expand = message.tabs[j].expand;
tabs[message.tabs[j].id].index = message.tabs[j].index;
if (tabs[message.tabs[j].parent]) {
tabs[message.tabs[j].id].parent_ttid = tabs[message.tabs[j].parent].ttid;
} else {
tabs[message.tabs[j].id].parent_ttid = "";
}
}
}
schedule_save++;
return;
}
if (message.command == "debug") {
pushlog(message.log);
return;
}
});
}

16
init.js
View File

@ -1,16 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
document.addEventListener("DOMContentLoaded", Init(), false);
function Init() {
if (browserId == "F") {
FirefoxMessageListeners();
FirefoxStart(0);
} else {
// ConvertLegacyStorage();
ChromeMessageListeners();
ChromeLoadTabs(0);
}
}

201
legacy.js
View File

@ -1,201 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
if (localStorage.getItem("t0") != null){
LoadV015(0);
}
function OldHashTab(tab){
if (tabs[tab.id] == undefined){
tabs[tab.id] = {ttid: "", hash: 0, h: 0, parent: tab.pinned ? "pin_list" : "tab_list", index: tab.index, expand: ""};
}
var hash = 0;
if (tab.url.length === 0){
return 0;
}
for (var i = 0; i < tab.url.length; i++){
hash = (hash << 5)-hash;
hash = hash+tab.url.charCodeAt(i);
hash |= 0;
}
tabs[tab.id].h = hash;
}
function LoadV015(retry){
var loaded_options = {};
for (var parameter in DefaultPreferences) {
opt[parameter] = DefaultPreferences[parameter];
}
// set loaded options
if (localStorage.getItem("current_options") !== null){
loaded_options = JSON.parse(localStorage["current_options"]);
}
for (var parameter in opt) {
if (loaded_options[parameter] != undefined && opt[parameter] != undefined){
opt[parameter] = loaded_options[parameter];
}
}
SavePreferences();
if (localStorage.getItem("current_options") !== null){
localStorage.removeItem("current_options");
}
chrome.tabs.query({windowType: "normal"}, function(qtabs){
// create current tabs object
qtabs.forEach(function(Tab){
OldHashTab(Tab);
});
var reference_tabs = {};
var tabs_to_save = [];
var tabs_matched = 0;
// compare saved tabs from storage to current session tabs, but can be skipped if set in options
qtabs.forEach(function(Tab){
for (var t = 0; t < 9999; t++){
if (localStorage.getItem("t"+t) !== null){
var LoadedTab = JSON.parse(localStorage["t"+t]);
if (LoadedTab[1] === tabs[Tab.id].h && reference_tabs[LoadedTab[0]] == undefined){
reference_tabs[LoadedTab[0]] = Tab.id;
tabs[Tab.id].parent = LoadedTab[2];
tabs[Tab.id].index = LoadedTab[3];
tabs[Tab.id].expand = LoadedTab[4];
tabs_matched++;
break;
}
} else {
break;
}
}
});
// replace parents tabIds to new ones, for that purpose reference_tabs was made before
for (var tabId in tabs){
if (reference_tabs[tabs[tabId].parent] != undefined){
tabs[tabId].parent = reference_tabs[tabs[tabId].parent];
}
}
// create new hashes
qtabs.forEach(function(Tab){
ChromeHashURL(Tab);
});
qtabs.forEach(function(Tab){
tabs_to_save.push({id: Tab.id, hash: tabs[Tab.id].hash, parent: tabs[Tab.id].parent, index: tabs[Tab.id].index, expand: tabs[Tab.id].expand});
});
localStorage["t_count"] = JSON.stringify(qtabs.length);
localStorage["tabs"] = JSON.stringify(tabs_to_save);
for (var t = 0; t < 9999; t++){
if (localStorage.getItem("t"+t) !== null){
localStorage.removeItem("t"+t);
}
}
ConvertLegacyStorage();
});
}
function ConvertLegacyStorage() {
if (localStorage.getItem("current_theme") != null || localStorage.getItem("preferences") != null || localStorage.getItem("tabs") != null || localStorage.getItem("windows") != null) {
let current_theme = "";
if (localStorage.getItem("current_theme") != null) {
current_theme = localStorage["current_theme"];
}
let LSthemes = [];
if (localStorage.getItem("themes") != null) {
LSthemes = LoadData("themes", []);
}
SLThemes = {};
LSthemes.forEach(function(themeName) {
let them = LoadData("theme"+themeName, {"TabsSizeSetNumber": 2, "ToolbarShow": true, "toolbar": DefaultToolbar});
SLThemes[themeName] = them;
});
let LSpreferences = Object.assign({}, DefaultPreferences);
if (localStorage.getItem("preferences") != null) {
LSpreferences = LoadData("preferences", {});
}
let LStabs = {};
if (localStorage.getItem("tabs") != null) {
LStabs = LoadData("tabs", {});
}
let LSwindows = {};
if (localStorage.getItem("windows") != null) {
LSwindows = LoadData("windows", {});
}
let LStabs_BAK1 = {};
if (localStorage.getItem("tabs_BAK1") != null) {
LStabs_BAK1 = LoadData("tabs_BAK1", {});
}
let LStabs_BAK2 = {};
if (localStorage.getItem("tabs_BAK2") != null) {
LStabs_BAK2 = LoadData("tabs_BAK2", {});
}
let LStabs_BAK3 = {};
if (localStorage.getItem("tabs_BAK3") != null) {
LStabs_BAK3 = LoadData("tabs_BAK3", {});
}
let LSwindows_BAK1 = {};
if (localStorage.getItem("windows_BAK1") != null) {
LSwindows_BAK1 = LoadData("windows_BAK1", {});
}
let LSwindows_BAK2 = {};
if (localStorage.getItem("windows_BAK2") != null) {
LSwindows_BAK2 = LoadData("windows_BAK2", {});
}
let LSwindows_BAK3 = {};
if (localStorage.getItem("windows_BAK3") != null) {
LSwindows_BAK3 = LoadData("windows_BAK3", {});
}
let LSt_count = 0;
if (localStorage.getItem("t_count") != null) {
LSt_count = LoadData("t_count", {});
}
let LSw_count = 0;
if (localStorage.getItem("w_count") != null) {
LSw_count = LoadData("w_count", {});
}
chrome.storage.local.set({tabs: LStabs});
chrome.storage.local.set({windows: LSwindows});
chrome.storage.local.set({tabs_BAK1: LStabs_BAK1});
chrome.storage.local.set({tabs_BAK2: LStabs_BAK2});
chrome.storage.local.set({tabs_BAK3: LStabs_BAK3});
chrome.storage.local.set({windows_BAK1: LSwindows_BAK1});
chrome.storage.local.set({windows_BAK2: LSwindows_BAK2});
chrome.storage.local.set({windows_BAK3: LSwindows_BAK3});
chrome.storage.local.set({t_count: LSt_count});
chrome.storage.local.set({w_count: LSw_count});
chrome.storage.local.set({preferences: LSpreferences});
chrome.storage.local.set({current_theme: current_theme});
chrome.storage.local.set({themes: SLThemes});
localStorage.clear();
window.location.reload();
}
}
function LoadData(KeyName, ExpectReturnDefaultType) {
var data = ExpectReturnDefaultType;
try {
data = JSON.parse(localStorage[KeyName]);
return data;
} catch(e) {
return ExpectReturnDefaultType;
}
}

703
listeners_bg.js Normal file
View File

@ -0,0 +1,703 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
function StartBackgroundListeners() {
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message.command == "reload") {
window.location.reload();
return;
}
if (message.command == "reload_options") {
opt = Object.assign({}, message.opt);
return;
}
if (message.command == "get_windows") {
sendResponse(b.windows);
return;
}
if (message.command == "get_folders") {
if (b.windows[message.windowId]) {
sendResponse(b.windows[message.windowId].folders);
}
return;
}
if (message.command == "save_folders") {
if (b.windows[message.windowId]) {
b.windows[message.windowId].folders = Object.assign({}, message.folders);
b.schedule_save++;
}
return;
}
if (message.command == "get_groups") {
if (b.windows[message.windowId]) {
sendResponse(b.windows[message.windowId].groups);
}
return;
}
if (message.command == "save_groups" && browserId == "F") {
if (b.windows[message.windowId]) {
b.windows[message.windowId].groups = Object.assign({}, message.groups);
for (let group in b.windows[message.windowId].groups) {
if (b.tabs[b.windows[message.windowId].groups[group].active_tab]) {
b.windows[message.windowId].groups[group].active_tab_ttid = b.tabs[b.windows[message.windowId].groups[group].active_tab].ttid;
}
if (b.tabs[b.windows[message.windowId].groups[group].prev_active_tab]) {
b.windows[message.windowId].groups[group].prev_active_tab_ttid = b.tabs[b.windows[message.windowId].groups[group].prev_active_tab].ttid;
}
}
b.schedule_save++;
}
return;
}
if (message.command == "save_groups" && browserId != "F") {
if (b.windows[message.windowId]) {
b.windows[message.windowId].groups = Object.assign({}, message.groups);
b.schedule_save++;
}
return;
}
if (message.command == "set_active_group") {
if (b.windows[message.windowId]) {
b.windows[message.windowId].active_group = message.active_group;
b.schedule_save++;
}
return;
}
if (message.command == "get_active_group") {
if (b.windows[message.windowId]) {
sendResponse(b.windows[message.windowId].active_group);
}
return;
}
if (message.command == "set_search_filter") {
if (b.windows[message.windowId]) {
b.windows[message.windowId].search_filter = message.search_filter;
b.schedule_save++;
}
return;
}
if (message.command == "get_search_filter") {
if (b.windows[message.windowId]) {
sendResponse(b.windows[message.windowId].search_filter);
}
return;
}
if (message.command == "set_active_shelf") {
if (b.windows[message.windowId]) {
b.windows[message.windowId].active_shelf = message.active_shelf;
b.schedule_save++;
}
return;
}
if (message.command == "get_active_shelf") {
if (b.windows[message.windowId]) {
sendResponse(b.windows[message.windowId].active_shelf);
}
return;
}
if (message.command == "set_group_bar") {
if (b.windows[message.windowId]) {
b.windows[message.windowId].group_bar = message.group_bar;
b.schedule_save++;
}
return;
}
if (message.command == "get_group_bar") {
if (b.windows[message.windowId]) {
sendResponse(b.windows[message.windowId].group_bar);
}
return;
}
if (message.command == "get_browser_tabs") {
sendResponse(b.tabs);
return;
}
if (message.command == "is_bg_ready") {
sendResponse(b.running);
return;
}
if (message.command == "update_tab" && browserId == "F") {
if (b.tabs[message.tabId]) {
if (message.tab.index) {
b.tabs[message.tabId].index = message.tab.index;
}
if (message.tab.expand) {
b.tabs[message.tabId].expand = message.tab.expand;
}
if (message.tab.parent) {
b.tabs[message.tabId].parent = message.tab.parent;
if (b.tabs[message.tab.parent]) {
b.tabs[message.tabId].parent_ttid = b.tabs[message.tab.parent].ttid;
} else {
b.tabs[message.tabId].parent_ttid = "";
}
}
b.schedule_save++;
} else {
b.tabs[tabId] = {ttid: "", parent: message.tab.parent, parent_ttid: "", index: message.tab.index, expand: message.tab.expand};
b.schedule_save++;
}
return;
}
if (message.command == "update_tab" && browserId != "F") {
if (b.tabs[message.tabId]) {
if (message.tab.index) {
b.tabs[message.tabId].index = message.tab.index;
}
if (message.tab.expand) {
b.tabs[message.tabId].expand = message.tab.expand;
}
if (message.tab.parent) {
b.tabs[message.tabId].parent = message.tab.parent;
}
b.schedule_save++;
} else {
b.tabs[tabId] = {hash: 0, parent: message.tab.parent, index: message.tab.index, expand: message.tab.expand};
b.schedule_save++;
}
return;
}
if (message.command == "update_all_tabs" && browserId == "F") {
for (let i = 0; i < message.pins.length; i++) {
if (b.tabs[message.pins[i].id]) {
b.tabs[message.pins[i].id].parent = "pin_list";
b.tabs[message.pins[i].id].parent_ttid = "";
b.tabs[message.pins[i].id].expand = "";
b.tabs[message.pins[i].id].index = message.pins[i].index;
}
}
for (let j = 0; j < message.tabs.length; j++) {
if (b.tabs[message.tabs[j].id]) {
b.tabs[message.tabs[j].id].parent = message.tabs[j].parent;
b.tabs[message.tabs[j].id].expand = message.tabs[j].expand;
b.tabs[message.tabs[j].id].index = message.tabs[j].index;
if (b.tabs[message.tabs[j].parent]) {
b.tabs[message.tabs[j].id].parent_ttid = b.tabs[message.tabs[j].parent].ttid;
} else {
b.tabs[message.tabs[j].id].parent_ttid = "";
}
}
}
b.schedule_save++;
return;
}
if (message.command == "update_all_tabs" && browserId != "F") {
for (let i = 0; i < message.pins.length; i++) {
if (b.tabs[message.pins[i].id]) {
b.tabs[message.pins[i].id].parent = "pin_list";
b.tabs[message.pins[i].id].expand = "";
b.tabs[message.pins[i].id].index = message.pins[i].index;
}
}
for (let j = 0; j < message.tabs.length; j++) {
if (b.tabs[message.tabs[j].id]) {
b.tabs[message.tabs[j].id].parent = message.tabs[j].parent;
b.tabs[message.tabs[j].id].expand = message.tabs[j].expand;
b.tabs[message.tabs[j].id].index = message.tabs[j].index;
}
}
b.schedule_save++;
return;
}
if (message.command == "discard_tab") {
DiscardTab(message.tabId);
return;
}
if (message.command == "discard_window") {
DiscardWindow(message.windowId);
return;
}
if (message.command == "remove_tab_from_empty_tabs") {
setTimeout(function() {
if (b.EmptyTabs.indexOf(message.tabId) != -1) {
b.EmptyTabs.splice(b.EmptyTabs.indexOf(message.tabId), 1);
}
}, 100);
return;
}
if (message.command == "debug") {
pushlog(message.log);
return;
}
});
}
function QuantumStartListeners() {
browser.browserAction.onClicked.addListener(function() {
browser.sidebarAction.setPanel({panel: (browser.extension.getURL("/sidebar.html")) });
browser.sidebarAction.open();
});
chrome.tabs.onCreated.addListener(function(tab) {
let t = Promise.resolve(browser.sessions.getTabValue(tab.id, "TTdata")).then(function(TabData) {
if (TabData != undefined) {
b.tabs[tab.id] = Object.assign({}, TabData);
let originalParent = TabData.parent_ttid == "" ? undefined : (b.tt_ids[TabData.parent_ttid] ? b.tt_ids[TabData.parent_ttid] : TabData.parent_ttid);
chrome.runtime.sendMessage({command: "tab_created", windowId: tab.windowId, tabId: tab.id, tab: tab, ParentId: originalParent, InsertAfterId: undefined, Append: undefined});
} else {
QuantumAppendTabTTId(tab);
OnMessageTabCreated(tab.id);
}
});
});
chrome.tabs.onAttached.addListener(function(tabId, attachInfo) {
let oldId = tabId;
chrome.tabs.get(oldId, function(tab) {
ReplaceParents(oldId, tab.id);
chrome.runtime.sendMessage({command: "tab_attached", windowId: attachInfo.newWindowId, tab: tab, tabId: tab.id, ParentId: b.tabs[tab.id].parent});
b.schedule_save++;
});
});
chrome.tabs.onDetached.addListener(function(tabId, detachInfo) {
chrome.runtime.sendMessage({command: "tab_detached", windowId: detachInfo.oldWindowId, tabId: tabId});
});
chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
if (b.EmptyTabs.indexOf(tabId) != -1) {
b.EmptyTabs.splice(b.EmptyTabs.indexOf(tabId), 1);
}
setTimeout(function() {
chrome.runtime.sendMessage({command: "tab_removed", windowId: removeInfo.windowId, tabId: tabId});
}, 5);
// setTimeout(function() {
// delete b.tabs[tabId];
// },60000);
b.schedule_save++;
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.pinned == true) {
if (b.tabs[tabId]) {
b.tabs[tabId].parent = "pin_list";
b.tabs[tabId].parent_ttid = "";
b.schedule_save++;
}
}
if (changeInfo.pinned == false) {
if (b.tabs[tabId]) {
b.tabs[tabId].parent = "tab_list";
b.tabs[tabId].parent_ttid = "";
b.schedule_save++;
}
}
if (changeInfo.url != undefined) { // if set to append when url changes and matches pre-set group
if (opt.move_tabs_on_url_change == "always" || ((opt.move_tabs_on_url_change == "from_empty" || opt.move_tabs_on_url_change == "from_empty_b") && b.EmptyTabs.indexOf(tabId) != -1)) {
AppendTabToGroupOnRegexMatch(tabId, tab.windowId, changeInfo.url);
}
if (changeInfo.url != b.newTabUrl && b.EmptyTabs.indexOf(tabId) != -1) {
b.EmptyTabs.splice(b.EmptyTabs.indexOf(tabId), 1);
}
}
if (changeInfo.title != undefined && !tab.active) {
chrome.runtime.sendMessage({command: "tab_attention", windowId: tab.windowId, tabId: tabId});
}
chrome.runtime.sendMessage({command: "tab_updated", windowId: tab.windowId, tab: tab, tabId: tabId, changeInfo: changeInfo});
});
chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) {
chrome.tabs.get(addedTabId, function(tab) {
if (addedTabId == removedTabId) {
chrome.runtime.sendMessage({command: "tab_updated", windowId: tab.windowId, tab: tab, tabId: tab.id, changeInfo: {status: tab.status, url: tab.url, title: tab.title, audible: tab.audible, mutedInfo: tab.mutedInfo}});
} else {
if (b.tabs[removedTabId]) {
b.tabs[addedTabId] = b.tabs[removedTabId];
}
ReplaceParents(tabId, tab.id);
chrome.runtime.sendMessage({command: "tab_removed", windowId: tab.windowId, tabId: removedTabId});
chrome.runtime.sendMessage({command: "tab_attached", windowId: tab.windowId, tab: tab, tabId: addedTabId, ParentId: b.tabs[addedTabId].parent});
// delete ttid[b.tabs[removedTabId].ttid];
// delete b.tabs[removedTabId];
}
setTimeout(function() {
QuantumAppendTabTTId(tab);
b.schedule_save++;
}, 100);
});
});
chrome.tabs.onActivated.addListener(function(activeInfo) {
if (b.windows[activeInfo.windowId]) {
if (b.windows[activeInfo.windowId].activeTabId[1] != activeInfo.tabId) {
b.windows[activeInfo.windowId].activeTabId[0] = b.windows[activeInfo.windowId].activeTabId[1];
b.windows[activeInfo.windowId].activeTabId[1] = activeInfo.tabId;
}
}
chrome.runtime.sendMessage({command: "tab_activated", windowId: activeInfo.windowId, tabId: activeInfo.tabId});
b.schedule_save++;
});
chrome.windows.onCreated.addListener(function(window) {
let win = Promise.resolve(browser.sessions.getWindowValue(window.id, "TTdata")).then(function(WindowData) {
if (WindowData != undefined) {
b.windows[window.id] = Object.assign({}, WindowData);
} else {
QuantumAppendWinTTId(window.id);
}
b.schedule_save++;
});
});
chrome.windows.onRemoved.addListener(function(windowId) {
// delete b.windows[windowId];
b.schedule_save++;
});
// chrome.sessions.onChanged.addListener(function(session) {
// chrome.windows.getAll({windowTypes: ['normal'], populate: false}, function(w) {
// chrome.tabs.query({}, function(t) {
// for (let wiInd = 0; wiInd < w.length; wiInd++) {
// if (b.windows[w[wiInd].id] == undefined) {
// chrome.runtime.sendMessage({command: "reload_sidebar"});
// window.location.reload();
// }
// }
// for (let tbInd = 0; tbInd < t.length; tbInd++) {
// if (b.tabs[t[tbInd].id] == undefined) {
// chrome.runtime.sendMessage({command: "reload_sidebar"});
// window.location.reload();
// }
// }
// });
// });
// });
}
function ChromiumStartListeners() { // start all listeners
chrome.tabs.onCreated.addListener(function(tab) {
ChromiumHashURL(tab);
OnMessageTabCreated(tab.id);
});
chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
if (b.EmptyTabs.indexOf(tabId) != -1) {
b.EmptyTabs.splice(b.EmptyTabs.indexOf(tabId), 1);
}
setTimeout(function() { chrome.runtime.sendMessage({command: "tab_removed", windowId: removeInfo.windowId, tabId: tabId}); },5);
delete b.tabs[tabId];
b.schedule_save++;
});
chrome.tabs.onAttached.addListener(function(tabId, attachInfo) {
chrome.tabs.get(tabId, function(tab) {
chrome.runtime.sendMessage({command: "tab_attached", windowId: attachInfo.newWindowId, tab: tab, tabId: tabId, ParentId: b.tabs[tabId].parent});
});
b.schedule_save++;
});
chrome.tabs.onDetached.addListener(function(tabId, detachInfo) {
chrome.runtime.sendMessage({command: "tab_detached", windowId: detachInfo.oldWindowId, tabId: tabId});
b.schedule_save++;
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (b.tabs[tabId] == undefined || changeInfo.url != undefined) {
ChromiumHashURL(tab);
}
if (changeInfo.pinned != undefined) {
if (changeInfo.pinned == true) {
b.tabs[tabId].parent = "pin_list";
}
if (changeInfo.pinned == false) {
b.tabs[tabId].parent = "tab_list";
}
b.schedule_save++;
}
if (changeInfo.url != undefined) { // if set to append when url changes and matches pre-set group
if (opt.move_tabs_on_url_change == "always" || ((opt.move_tabs_on_url_change == "from_empty" || opt.move_tabs_on_url_change == "from_empty_b") && b.EmptyTabs.indexOf(tabId) != -1)) {
AppendTabToGroupOnRegexMatch(tabId, tab.windowId, changeInfo.url);
}
if (changeInfo.url != b.newTabUrl && b.EmptyTabs.indexOf(tabId) != -1) {
b.EmptyTabs.splice(b.EmptyTabs.indexOf(tabId), 1);
}
}
if (changeInfo.title != undefined && !tab.active) {
chrome.runtime.sendMessage({command: "tab_attention", windowId: tab.windowId, tabId: tabId});
}
chrome.runtime.sendMessage({command: "tab_updated", windowId: tab.windowId, tab: tab, tabId: tabId, changeInfo: changeInfo});
});
chrome.tabs.onMoved.addListener(function(tabId, moveInfo) {
b.schedule_save++;
});
chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) {
chrome.tabs.get(addedTabId, function(tab) {
if (addedTabId == removedTabId) {
chrome.runtime.sendMessage({command: "tab_updated", windowId: tab.windowId, tab: tab, tabId: tab.id, changeInfo: {status: tab.status, url: tab.url, title: tab.title, audible: tab.audible, mutedInfo: tab.mutedInfo}});
} else {
ReplaceParents(tabId, tab.id);
if (b.tabs[removedTabId]) {
b.tabs[addedTabId] = b.tabs[removedTabId];
} else {
ChromiumHashURL(tab);
}
chrome.runtime.sendMessage({command: "tab_removed", windowId: tab.windowId, tabId: removedTabId});
chrome.runtime.sendMessage({command: "tab_attached", windowId: tab.windowId, tab: tab, tabId: addedTabId});
delete b.tabs[removedTabId];
}
b.schedule_save++;
});
});
chrome.tabs.onActivated.addListener(function(activeInfo) {
if (b.windows[activeInfo.windowId]) {
if (b.windows[activeInfo.windowId].activeTabId[1] != activeInfo.tabId) {
b.windows[activeInfo.windowId].activeTabId[0] = b.windows[activeInfo.windowId].activeTabId[1];
b.windows[activeInfo.windowId].activeTabId[1] = activeInfo.tabId;
}
}
chrome.runtime.sendMessage({command: "tab_activated", windowId: activeInfo.windowId, tabId: activeInfo.tabId});
b.schedule_save++;
});
chrome.windows.onCreated.addListener(function(window) {
ChromiumAddWindowData(window.id);
// b.windows[window.id] = {group_bar: opt.groups_toolbar_default, search_filter: "url", active_shelf: "", active_group: "tab_list", groups: {tab_list: {id: "tab_list", index: 0, active_tab: 0, prev_active_tab: 0, name: labels.ungrouped_group, font: ""}}, folders: {}};
b.schedule_save++;
});
chrome.windows.onRemoved.addListener(function(windowId) {
delete b.windows[windowId];
b.schedule_save++;
});
chrome.runtime.onSuspend.addListener(function() {
b.running = false;
});
}
function OnMessageTabCreated(tabId) {
chrome.tabs.get(tabId, function(NewTab) { // get tab again as reported tab's url is empty! Also for some reason firefox sends tab with "active == false" even if tab is active (THIS IS POSSIBLY A NEW BUG IN FF 60!)
let ParentId;
let AfterId;
let append;
if (b.windows[NewTab.windowId] && NewTab.active) {
b.windows[NewTab.windowId].groups[b.windows[NewTab.windowId].active_group].active_tab = NewTab.id;
}
if (NewTab.url == b.newTabUrl) {
b.EmptyTabs.push(tabId);
}
if (NewTab.pinned) {
let PinTabs = GetChildren("pin_list");
b.tabs[NewTab.id].parent = "pin_list";
b.tabs[NewTab.id].index = NewTab.index;
if (browserId == "F") {
b.tabs[NewTab.id].parent_ttid = "";
}
for (let i = PinTabs.indexOf(NewTab.openerTabId)+1; i < PinTabs.length; i++) { // shift next siblings indexes
b.tabs[PinTabs[i]].index += 1;
}
} else {
if (opt.append_orphan_tab == "as_child" && opt.orphaned_tabs_to_ungrouped == false) {
// let atb = NewTab.active ? 0 : 1;
NewTab.openerTabId = b.windows[NewTab.windowId].activeTabId[NewTab.active ? 0 : 1];
}
if (NewTab.openerTabId) { // child case
let OpenerSiblings = GetChildren(b.tabs[NewTab.openerTabId].parent);
if (opt.append_child_tab == "after") { // place tabs flat
b.tabs[NewTab.id].parent = b.tabs[NewTab.openerTabId].parent;
if (browserId == "F") {
b.tabs[NewTab.id].parent_ttid = b.tabs[NewTab.openerTabId].parent_ttid;
}
b.tabs[NewTab.id].index = b.tabs[NewTab.openerTabId].index+1;
for (let i = OpenerSiblings.indexOf(NewTab.openerTabId)+1; i < OpenerSiblings.length; i++) { // shift next siblings indexes
b.tabs[OpenerSiblings[i]].index += 1;
}
AfterId = NewTab.openerTabId;
} else {
if (opt.max_tree_depth == 0) { // place tabs flat if limit is set to 0
b.tabs[NewTab.id].parent = b.tabs[NewTab.openerTabId].parent;
if (browserId == "F"){
b.tabs[NewTab.id].parent_ttid = b.tabs[NewTab.openerTabId].parent_ttid;
}
if (opt.append_child_tab_after_limit == "after") { // max tree depth, place tab after parent
b.tabs[NewTab.id].index = b.tabs[NewTab.openerTabId].index+1;
for (let i = OpenerSiblings.indexOf(NewTab.openerTabId)+1; i < OpenerSiblings.length; i++) { // shift next siblings indexes
b.tabs[OpenerSiblings[i]].index += 1;
}
AfterId = NewTab.openerTabId;
}
if (opt.append_child_tab_after_limit == "top" && opt.append_child_tab != "after") { // max tree depth, place tab on top (above parent)
b.tabs[NewTab.id].index = 0;
for (let i = 0; i < OpenerSiblings.length; i++) { // shift all siblings indexes
b.tabs[OpenerSiblings[i]].index += 1;
}
ParentId = b.tabs[NewTab.id].parent;
}
if (opt.append_child_tab_after_limit == "bottom" && opt.append_child_tab != "after") { // max tree depth, place tab on bottom (below parent)
if (OpenerSiblings.length > 0) {
b.tabs[NewTab.id].index = b.tabs[OpenerSiblings[OpenerSiblings.length-1]].index+1;
} else {
b.tabs[NewTab.id].index = 1;
}
ParentId = b.tabs[NewTab.id].parent;
append = true;
}
} else {
let Parents = GetTabParents(NewTab.openerTabId);
let OpenerChildren = GetChildren(NewTab.openerTabId);
if (opt.max_tree_depth < 0 || (opt.max_tree_depth > 0 && Parents.length < opt.max_tree_depth)) { // append to tree on top and bottom
b.tabs[NewTab.id].parent = NewTab.openerTabId;
if (browserId == "F"){
b.tabs[NewTab.id].parent_ttid = b.tabs[NewTab.openerTabId].ttid;
}
if (opt.append_child_tab == "top") { // place child tab at the top (reverse hierarchy)
b.tabs[NewTab.id].index = 0;
for (let i = 0; i < OpenerChildren.length; i++) { // shift all siblings indexes
b.tabs[OpenerChildren[i]].index += 1;
}
ParentId = b.tabs[NewTab.id].parent;
}
if (opt.append_child_tab == "bottom") { // place child tab at the bottom
if (OpenerChildren.length > 0) {
b.tabs[NewTab.id].index = b.tabs[OpenerChildren[OpenerChildren.length-1]].index+1;
} else {
b.tabs[NewTab.id].index = 0;
}
ParentId = b.tabs[NewTab.id].parent;
append = true;
}
} else {
if (opt.max_tree_depth > 0 && Parents.length >= opt.max_tree_depth) { // if reached depth limit of the tree
b.tabs[NewTab.id].parent = b.tabs[NewTab.openerTabId].parent;
if (browserId == "F"){
b.tabs[NewTab.id].parent_ttid = b.tabs[NewTab.openerTabId].parent_ttid;
}
if (opt.append_child_tab_after_limit == "after") { // tab will append after opener
b.tabs[NewTab.id].index = b.tabs[NewTab.openerTabId].index+1;
for (let i = OpenerSiblings.indexOf(NewTab.openerTabId)+1; i < OpenerSiblings.length; i++) { // shift next siblings indexes
b.tabs[OpenerSiblings[i]].index += 1;
}
AfterId = NewTab.openerTabId;
}
if (opt.append_child_tab_after_limit == "top") { // tab will append on top
b.tabs[NewTab.id].index = 0;
for (let i = 0; i < OpenerChildren.length; i++) { // shift all siblings indexes
b.tabs[OpenerChildren[i]].index += 1;
}
ParentId = b.tabs[NewTab.id].parent;
}
if (opt.append_child_tab_after_limit == "bottom") { // tab will append on bottom
if (OpenerSiblings.length > 0) {
b.tabs[NewTab.id].index = b.tabs[OpenerSiblings[OpenerSiblings.length-1]].index+1;
} else {
b.tabs[NewTab.id].index = 1;
}
ParentId = b.tabs[NewTab.id].parent;
append = true;
}
}
}
}
}
} else { // orphan tab
if (opt.orphaned_tabs_to_ungrouped == true) { // if set to append orphan tabs to ungrouped group
let TabListTabs = GetChildren("tab_list");
b.tabs[NewTab.id].index = b.tabs[TabListTabs[TabListTabs.length-1]].index+1;
ParentId = "tab_list";
append = true;
// chrome.runtime.sendMessage({command: "set_active_group", windowId: NewTab.windowId, groupId: "tab_list"});
} else {
if (opt.append_orphan_tab == "after_active") {
let activeTabId = b.windows[NewTab.windowId].activeTabId[1] != NewTab.id ? b.windows[NewTab.windowId].activeTabId[1] : b.windows[NewTab.windowId].activeTabId[0];
// console.log(b.tabs[activeTabId].index);
if (b.tabs[activeTabId]) {
let ActiveSiblings = GetChildren(b.tabs[activeTabId].parent);
b.tabs[NewTab.id].parent = b.tabs[activeTabId].parent;
b.tabs[NewTab.id].index = b.tabs[activeTabId].index+1;
for (let i = ActiveSiblings.indexOf(activeTabId)+1; i < ActiveSiblings.length; i++) { // shift next siblings indexes
// let prev = b.tabs[ActiveSiblings[i]].index;
b.tabs[ActiveSiblings[i]].index += 1;
// console.log(prev + " " + b.tabs[ActiveSiblings[i]].index );
}
if (browserId == "F"){
b.tabs[NewTab.id].parent_ttid = b.tabs[activeTabId].parent_ttid;
}
AfterId = activeTabId;
} else { // FAIL, no active tab!
let GroupTabs = GetChildren(b.windows[NewTab.windowId].active_group);
b.tabs[NewTab.id].parent = b.windows[NewTab.windowId].active_group;
if (browserId == "F"){
b.tabs[NewTab.id].parent_ttid = "";
}
if (GroupTabs.length > 0) {
b.tabs[NewTab.id].index = b.tabs[GroupTabs[GroupTabs.length-1]].index+1;
} else {
b.tabs[NewTab.id].index = 0;
}
ParentId = b.windows[NewTab.windowId].active_group;
}
// console.log(b.tabs[NewTab.id].index);
}
if (opt.append_orphan_tab == "top") {
let GroupTabs = GetChildren(b.windows[NewTab.windowId].active_group);
b.tabs[NewTab.id].parent = b.windows[NewTab.windowId].active_group;
if (browserId == "F"){
b.tabs[NewTab.id].parent_ttid = "";
}
b.tabs[NewTab.id].index = 0;
for (let i = 0; i < GroupTabs.length; i++) { // shift all tabs indexes in group
b.tabs[GroupTabs[i]].index += 1;
}
ParentId = b.windows[NewTab.windowId].active_group;
}
if (opt.append_orphan_tab == "bottom") {
let GroupTabs = GetChildren(b.windows[NewTab.windowId].active_group);
b.tabs[NewTab.id].parent = b.windows[NewTab.windowId].active_group;
if (browserId == "F"){
b.tabs[NewTab.id].parent_ttid = "";
}
if (GroupTabs.length > 0) {
b.tabs[NewTab.id].index = b.tabs[GroupTabs[GroupTabs.length-1]].index+1;
} else {
b.tabs[NewTab.id].index = 0;
}
ParentId = b.windows[NewTab.windowId].active_group;
append = true;
}
}
}
if (opt.move_tabs_on_url_change === "all_new") {
setTimeout(function() {
chrome.tabs.get(NewTab.id, function(CheckTabsUrl) {
AppendTabToGroupOnRegexMatch(CheckTabsUrl.id, CheckTabsUrl.windowId, CheckTabsUrl.url);
});
}, 100);
}
}
setTimeout(function() {
b.schedule_save++;
}, 500);
chrome.runtime.sendMessage({command: "tab_created", windowId: NewTab.windowId, tabId: NewTab.id, tab: NewTab, ParentId: ParentId, InsertAfterId: AfterId, Append: append});
});
}

View File

@ -2,7 +2,7 @@
"manifest_version": 2,
"default_locale": "en",
"background": {
"page": "background.html",
"scripts": [ "listeners_bg.js", "scripts/common.js", "background.js" ],
"persistent": true
},
"name": "Tree Tabs",
@ -14,8 +14,7 @@
"19": "icons/16.png",
"16": "icons/16.png"
},
"permissions": [ "tabs", "sessions", "<all_urls>", "storage", "unlimitedStorage", "bookmarks", "tabHide" ],
"permissions": [ "tabs", "sessions", "storage", "unlimitedStorage", "bookmarks", "tabHide" ],
"sidebar_action": {
"default_icon": {
"16": "icons/16.png",
@ -29,6 +28,16 @@
"browser_action": {
"default_icon": "icons/24.png"
},
"commands": {
"_execute_browser_action": {
"suggested_key": { "default": "F1" },
"description": "toggle Tree Tabs"
},
"close_tree": {
"suggested_key": { "default": "Alt+W" },
"description": "close tree"
}
},
"applications": {
"gecko": {
"id": "TreeTabs@jagiello.it",
@ -39,5 +48,5 @@
"page": "options.html",
"open_in_tab": true
},
"version": "100"
"version": "1.7.0"
}

View File

@ -3,41 +3,41 @@
<head>
<meta charset="utf-8"/>
<title></title>
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_0.css" id="sizes_preset_0" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_1.css" id="sizes_preset_1" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_2.css" id="sizes_preset_2" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_3.css" id="sizes_preset_3" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_4.css" id="sizes_preset_4" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_0.css" id="sizes_preset_0" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_1.css" id="sizes_preset_1" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_2.css" id="sizes_preset_2" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_3.css" id="sizes_preset_3" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_4.css" id="sizes_preset_4" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_tabs_margin_0.css" id="tabs_margin_0" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_tabs_margin_1.css" id="tabs_margin_1" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_tabs_margin_2.css" id="tabs_margin_2" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_0.css" id="tabs_margin_0" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_1.css" id="tabs_margin_1" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_2.css" id="tabs_margin_2" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_colors.css" id="theme_colors" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme.css" id="theme" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_colors.css" id="theme_colors" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme.css" id="theme" />
<link type="text/css" rel="stylesheet" media="all" href="../options/options.css" id="main_body_css" />
<link type="text/css" rel="stylesheet" media="all" href="options/options.css" id="main_body_css" />
<style rel="stylesheet"> #red_higlights_go_here { background-color: transparent; } </style>
<link type="text/css" rel="stylesheet" media="all" href="../options/options overwrite.css" id="overwrite" />
<link type="text/css" rel="stylesheet" media="all" href="options/options overwrite.css" id="overwrite" />
</head>
<body id="body">
<body id="body" class="options_body">
<div style="width:850px; align:left;"><span style="width:100%; font-size:20px; display:inline-block; text-align:center; ">Tree Tabs</span></div>
<br>
<fieldset class="field" id="field_vivaldi">
<fieldset class="field" id="field_vivaldi" style="display:none;">
<legend class="label" id="options_vivaldi"></legend>
<table>
<tr>
<td class="label" id="opt_url_for_web_panel"></td>
<td><input style="position:relative;width:450px;left:8px;" type="text" id="url_for_web_panel" value="test"></input></td>
<td><div style="position:relative; width:20px; height: 20px; left:8px; background-size: 20px 20px; background-image: url(../options/options_copy_icon.png);" id="copy_vivaldi_url_for_web_panel" ></div></td>
<td><input style="position:relative;width:450px;left:8px;" type="text" id="url_for_web_panel" value=""></input></td>
<td><div style="position:relative; width:20px; height: 20px; left:8px; background-size: 20px 20px; background-image: url(options/options_copy_icon.png);" id="copy_vivaldi_url_for_web_panel" ></div></td>
</tr>
</table>
</fieldset>
@ -201,7 +201,15 @@
<select id="append_child_tab">
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_top" value="top"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_bottom" value="bottom"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_active" value="after_active"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after" value="after"></option>
</select>
</li>
<li id="append_child_tab_after_limit_dropdown">
<label class="label" id="options_append_child_tab_after_limit"></label>
<select id="append_child_tab_after_limit">
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_top" value="top"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_after" value="after"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_bottom" value="bottom"></option>
</select>
</li>
<li>
@ -223,14 +231,6 @@
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_browser" value="browser"></option>
</select>
</li>
<li>
<label class="label" id="options_append_child_tab_after_limit"></label>
<select id="append_child_tab_after_limit">
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_top" value="top"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_after" value="after"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_bottom" value="bottom"></option>
</select>
</li>
<li>
<label class="label" id="options_tab_group_regex"></label><br>
<br><span class="regexLabel">
@ -240,7 +240,7 @@
<label class="label" id="option_tab_group" style="width:200px"></label>
</span>
<div id="tab_group_regexes"></div>
<input class="set_button theme_buttons" type="button" id="add_tab_group_regex" style="margin:6px;" value="Add">
<button class="set_button" type="button" id="add_tab_group_regex" style="margin:6px;"></button>
</li>
<li>
<label class="label" id="options_move_on_url_change"></label>
@ -813,16 +813,16 @@
<input type="color" id="color_picker" style="position:absolute; left:-1000px; top:-1000px; width:1px; height:1px; overflow:hidden;">
<div id="DragImage" style="display: none; width:0px; height:0px;"></div>
<script type="text/javascript" src="../scripts/global.js"></script>
<script type="text/javascript" src="../scripts/utils.js"></script>
<script type="text/javascript" src="../scripts/toolbar.js"></script>
<script type="text/javascript" src="../scripts/tabs.js"></script>
<script type="text/javascript" src="../scripts/groups.js"></script>
<script type="text/javascript" src="../scripts/folders.js"></script>
<script type="text/javascript" src="../scripts/theme.js"></script>
<script type="text/javascript" src="../options/refresh.js"></script>
<script type="text/javascript" src="../options/sample_tabs.js"></script>
<script type="text/javascript" src="../options/options.js"></script>
<script type="text/javascript" src="scripts/common.js"></script>
<script type="text/javascript" src="scripts/utils.js"></script>
<script type="text/javascript" src="scripts/toolbar.js"></script>
<script type="text/javascript" src="scripts/tabs.js"></script>
<script type="text/javascript" src="scripts/groups.js"></script>
<script type="text/javascript" src="scripts/folders.js"></script>
<script type="text/javascript" src="scripts/theme.js"></script>
<script type="text/javascript" src="options/sample_tabs.js"></script>
<script type="text/javascript" src="options/options.js"></script>
<div id="donate"></div>

View File

@ -7,10 +7,7 @@
var current_theme = "";
var themes = [];
var SelectedTheme = Object.assign({}, DefaultTheme);
var dragged_button;
active_group = "tab_list";
var dragged_button = {id: ""};
// options for all drop down menus
let DropDownList = ["dbclick_folder", "midclick_folder", "midclick_tab", "dbclick_group", "midclick_group", "dbclick_tab", "append_child_tab", "append_child_tab_after_limit", "append_orphan_tab", "after_closing_active_tab", "move_tabs_on_url_change"];
@ -19,6 +16,10 @@ document.addEventListener("DOMContentLoaded", function() {
document.title = "Tree Tabs";
chrome.storage.local.get(null, function(storage) {
AppendGroupToList("tab_list", labels.ungrouped_group, "", false);
AppendGroupToList("tab_list2", labels.noname_group, "", false);
AppendSampleTabs();
GetCurrentPreferences(storage);
if (storage["themes"]) {
@ -45,9 +46,6 @@ document.addEventListener("DOMContentLoaded", function() {
RefreshFields();
SetEvents();
AppendGroupToList("tab_list", caption_ungrouped_group, "", false);
AppendGroupToList("tab_list2", caption_noname_group, "", false);
AppendSampleTabs();
setTimeout(function() {
document.querySelectorAll(".on").forEach(function(s){
@ -93,7 +91,7 @@ function AddRegexPair() {
deleteButton.type = "button";
deleteButton.style.width = '75px';
deleteButton.className = "set_button theme_buttons";
deleteButton.value = "Remove";
deleteButton.value = chrome.i18n.getMessage("options_Remove_button");
deleteButton.onclick = function() { regexes.removeChild(outer); }
outer.appendChild(deleteButton);
@ -142,6 +140,7 @@ function GetOptions(storage) {
break;
}
}
RefreshFields();
}
for (let i = 0; i < opt.tab_group_regexes.length; i++) {
@ -638,9 +637,10 @@ function SetEvents() {
for (let i = 0; i < DropDownList.length; i++) {
document.getElementById(DropDownList[i]).onchange = function(event) {
opt[this.id] = this.value;
SavePreferences();
RefreshFields();
setTimeout(function() {
chrome.runtime.sendMessage({command: "reload_sidebar"});
SavePreferences();
// chrome.runtime.sendMessage({command: "reload_sidebar"});
}, 50);
}
}
@ -648,9 +648,8 @@ function SetEvents() {
// set tabs tree depth option
document.getElementById("max_tree_depth").oninput = function(event) {
opt.max_tree_depth = parseInt(this.value);
SavePreferences();
setTimeout(function() {
chrome.runtime.sendMessage({command: "reload_sidebar"});
SavePreferences();
}, 50);
}
@ -892,7 +891,7 @@ function SetEvents() {
// ----------------------EXPORT DEBUG LOG---------------------------------------------------------------------------------
document.getElementById("options_export_debug").onclick = function(event) {if (event.which == 1) {
chrome.storage.local.get(null, function(storage) {
SaveFile("TreeTabs", "log", storage);
SaveFile("TreeTabs", "log", storage.debug_log);
});
}}
@ -930,6 +929,7 @@ function SetEvents() {
location.reload();
}, 100);
}}
}
function RemoveToolbarEditEvents() {
@ -1003,6 +1003,74 @@ function copyStringToClipboard(string) {
}
// shrink or expand theme field
function RefreshFields() {
if (document.getElementById("theme_list").options.length == 0) {
document.getElementById("field_theme").style.height = "45px";
} else {
document.getElementById("field_theme").style.height = "";
}
if (browserId == "F") {
document.querySelectorAll("#scrollbar_size_indicator, #scrollbar_thumb, #scrollbar_thumb_hover, #scrollbar_track").forEach(function(s){
s.style.display = "none";
});
} else {
document.querySelectorAll("#firefox_option_hide_other_groups_tabs_firefox").forEach(function(s){
s.style.display = "none";
});
}
if (browserId == "V") {
let WebPanelUrlBox = document.getElementById("url_for_web_panel");
WebPanelUrlBox.value = (chrome.runtime.getURL("sidebar.html"));
WebPanelUrlBox.setAttribute("readonly", true);
document.getElementById("field_vivaldi").style.display = "block";
}
if (document.getElementById("show_toolbar").checked) {
document.querySelectorAll("#options_available_buttons, #sample_toolbar_block, #options_reset_toolbar_button").forEach(function(s){
s.style.display = "";
});
document.getElementById("options_toolbar_look").style.display = "";
document.getElementById("field_show_toolbar").style.height = "";
} else{
document.querySelectorAll("#options_available_buttons, #sample_toolbar_block, #options_reset_toolbar_button").forEach(function(s){
s.style.display = "none";
});
document.getElementById("options_toolbar_look").style.display = "none";
document.getElementById("field_show_toolbar").style.height = "6";
}
if (document.getElementById("append_child_tab").value == "after") {
document.getElementById("append_child_tab_after_limit_dropdown").style.display = "none";
document.getElementById("options_append_orphan_tab_as_child").style.display = "none";
if (opt.append_child_tab == "after" && opt.append_orphan_tab == "as_child") {
opt.append_orphan_tab = "after_active";
document.getElementById("append_orphan_tab").value = "after_active";
SavePreferences();
}
} else {
document.getElementById("append_child_tab_after_limit_dropdown").style.display = "";
document.getElementById("options_append_orphan_tab_as_child").style.display = "";
}
}
function RefreshGUI() {
let button_filter_type = document.getElementById("button_filter_type");
if (button_filter_type != null) {
button_filter_type.classList.add("url");
button_filter_type.classList.remove("title");
}
if (document.querySelector(".on") != null) {
document.getElementById("toolbar").style.height = "53px";
} else {
document.getElementById("toolbar").style.height = "26px";
}
}
// dummy functions
function BindTabsSwitchingToMouseWheel() {}
function GetFaviconAndTitle() {}

View File

@ -1,53 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
// shrink or expand theme field
function RefreshFields() {
if (document.getElementById("theme_list").options.length == 0) {
document.getElementById("field_theme").style.height = "45px";
} else {
document.getElementById("field_theme").style.height = "";
}
if (browserId == "F") {
document.querySelectorAll("#scrollbar_size_indicator, #scrollbar_thumb, #scrollbar_thumb_hover, #scrollbar_track").forEach(function(s){
s.style.display = "none";
});
} else {
document.getElementById("firefox_option_hide_other_groups_tabs_firefox").style.display = "none";
}
if (browserId == "V") {
let WebPanelUrlBox = document.getElementById("url_for_web_panel");
WebPanelUrlBox.value = (chrome.runtime.getURL("sidebar.html"));
WebPanelUrlBox.setAttribute("readonly", true);
} else{
document.getElementById("field_vivaldi").style.display = "none";
}
if (document.getElementById("show_toolbar").checked) {
document.querySelectorAll("#options_available_buttons, #sample_toolbar_block, #options_reset_toolbar_button").forEach(function(s){
s.style.display = "";
});
document.getElementById("options_toolbar_look").style.display = "";
document.getElementById("field_show_toolbar").style.height = "";
} else{
document.querySelectorAll("#options_available_buttons, #sample_toolbar_block, #options_reset_toolbar_button").forEach(function(s){
s.style.display = "none";
});
document.getElementById("options_toolbar_look").style.display = "none";
document.getElementById("field_show_toolbar").style.height = "6";
}
}
function RefreshGUI() {
let button_filter_type = document.getElementById("button_filter_type");
if (button_filter_type != null) {
button_filter_type.classList.add("url");
button_filter_type.classList.remove("title");
}
if (document.querySelector(".on") != null) {
document.getElementById("toolbar").style.height = "53px";
} else {
document.getElementById("toolbar").style.height = "26px";
}
}

View File

@ -3,128 +3,128 @@
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
function AppendSampleTabs() {
// folders
AddNewFolder("f_folder1", "cftab_list", labels.noname_group, 0, "o", "o", false);
AddNewFolder("f_folder2", "f_folder1", labels.noname_group, 0, "c", "c", false);
AddNewFolder("f_folder3", "f_folder1", labels.noname_group, 0, "c", "c", false);
// pins
AppendTab({id: 0, pinned: true}, false, false, false, true, false, false, false, true, false, false);
AppendTab({id: 1, pinned: true, active: false}, false, false, false, true, false, false, false, true, false, false);
AppendTab({id: 10, pinned: true, active: false}, false, false, false, true, false, false, false, true, false, false);
AppendTab({tab: {id: 0, pinned: true, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true});
AppendTab({tab: {id: 1, pinned: true, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true});
AppendTab({tab: {id: 10, pinned: true, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true});
document.getElementById("10").classList.add("attention");
// regular tabs
AppendTab({id: 2, pinned: false}, false, false, false, true, false, false, false, true, false, true);
AppendTab({tab: {id: 2, pinned: false, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true, addCounter: true});
document.getElementById("tab_title2").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal");
AppendTab({id: 11, pinned: false}, "2", false, false, true, false, false, false, false, false, false);
AppendTab({tab: {id: 11, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true});
document.getElementById("tab_title11").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal_hover");
document.getElementById("tab_header11").classList.add("tab_header_hover");
document.getElementById("tab_header11").classList.add("close_show");
AppendTab({id: 12, pinned: false}, "2", false, false, true, false, false, "selected_tab", false, false, false);
AppendTab({tab: {id: 12, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab"});
document.getElementById("tab_title12").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal_selected");
AppendTab({id: 13, pinned: false}, "2", false, false, true, false, false, "selected_tab", false, false, false);
AppendTab({tab: {id: 13, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab"});
document.getElementById("tab_title13").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal_selected_hover");
document.getElementById("tab_header13").classList.add("tab_header_hover")
document.getElementById("tab_header13").classList.add("close_show");
document.getElementById("close13").classList.add("close_hover");
// regular active tabs
AppendTab({id: 3, pinned: false}, "2", false, false, true, false, false, "active_tab", false, false, false);
AppendTab({tab: {id: 3, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "active_tab"});
document.getElementById("tab_title3").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active");
AppendTab({id: 15, pinned: false}, "2", false, false, true, false, false, "active_tab", false, false, false);
AppendTab({tab: {id: 15, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "active_tab"});
document.getElementById("tab_title15").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active_hover");
document.getElementById("tab_header15").classList.add("tab_header_hover");
AppendTab({id: 14, pinned: false}, "2", false, false, true, false, false, "c selected_tab active_tab", false, false, false);
AppendTab({tab: {id: 14, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "c selected_tab active_tab"});
document.getElementById("tab_title14").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active_selected");
AppendTab({id: 16, pinned: false}, "2", false, false, true, false, false, "c selected_tab active_tab", false, false, false);
AppendTab({tab: {id: 16, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "c selected_tab active_tab"});
document.getElementById("tab_title16").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active_selected_hover");
document.getElementById("tab_header16").classList.add("tab_header_hover");
document.getElementById("exp16").classList.add("hover");
// discarded tabs
AppendTab({id: 5, pinned: false, discarded: true}, false, false, false, true, false, false, false, false, false, false);
AppendTab({tab: {id: 5, pinned: false, active: false, discarded: true}, Append: true, SkipSetActive: true, SkipSetEvents: true});
document.getElementById("tab_title5").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded");
AppendTab({id: 17, pinned: false, discarded: true}, "5", false, false, true, false, false, false, false, false, false);
AppendTab({tab: {id: 17, pinned: false, active: false, discarded: true}, ParentId: "5", Append: true, SkipSetActive: true, SkipSetEvents: true});
document.getElementById("tab_title17").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded_hover");
document.getElementById("tab_header17").classList.add("tab_header_hover");
AppendTab({id: 19, pinned: false, discarded: true}, "5", false, false, true, false, false, "selected_tab highlighted_drop_target after", false, false, false);
AppendTab({tab: {id: 19, pinned: false, active: false, discarded: true}, ParentId: "5", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab highlighted_drop_target after"});
document.getElementById("tab_title19").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded_selected");
AppendTab({id: 20, pinned: false, discarded: true}, "5", false, false, true, false, false, "selected_tab", false, false, false);
AppendTab({tab: {id: 20, pinned: false, active: false, discarded: true}, ParentId: "5", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab"});
document.getElementById("tab_title20").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded_selected_hover");
document.getElementById("tab_header20").classList.add("tab_header_hover");
// search result
AppendTab({id: 6, pinned: false}, false, false, false, true, false, false, "filtered", false, false, false);
AppendTab({tab: {id: 6, pinned: false, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered"});
document.getElementById("tab_title6").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result");
AppendTab({id: 21, pinned: false}, "6", false, false, true, false, false, "filtered", false, false, false);
AppendTab({tab: {id: 21, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered"});
document.getElementById("tab_title21").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_hover");
document.getElementById("tab_header21").classList.add("tab_header_hover");
AppendTab({id: 22, pinned: false}, "6", false, false, true, false, false, "filtered active_tab", false, false, false);
AppendTab({tab: {id: 22, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered active_tab"});
document.getElementById("tab_title22").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_active");
AppendTab({id: 23, pinned: false}, "6", false, false, true, false, false, "filtered active_tab", false, false, false);
AppendTab({tab: {id: 23, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered active_tab"});
document.getElementById("tab_title23").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_active_hover");
document.getElementById("tab_header23").classList.add("tab_header_hover");
// search result selected
AppendTab({id: 8, pinned: false}, "6", false, false, true, false, false, "selected_tab filtered", false, false, false);
AppendTab({tab: {id: 8, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered"});
document.getElementById("tab_title8").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected");
AppendTab({id: 18, pinned: false}, "6", false, false, true, false, false, "selected_tab filtered", false, false, false);
AppendTab({tab: {id: 18, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered"});
document.getElementById("tab_title18").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected_hover");
document.getElementById("tab_header18").classList.add("tab_header_hover");
AppendTab({id: 25, pinned: false}, "6", false, false, true, false, false, "selected_tab filtered active_tab", false, false, false);
AppendTab({tab: {id: 25, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered active_tab"});
document.getElementById("tab_title25").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected_active");
AppendTab({id: 26, pinned: false}, "6", false, false, true, false, false, "selected_tab filtered active_tab", false, false, false);
AppendTab({tab: {id: 26, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered active_tab"});
document.getElementById("tab_title26").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected_active_hover");
document.getElementById("tab_header26").classList.add("tab_header_hover");
// search result highlighted
AppendTab({id: 30, pinned: false}, false, false, false, true, false, false, "filtered highlighted_search", false, false, false);
AppendTab({tab: {id: 30, pinned: false, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search"});
document.getElementById("tab_title30").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted");
AppendTab({id: 31, pinned: false}, "30", false, false, true, false, false, "filtered highlighted_search", false, false, false);
AppendTab({tab: {id: 31, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search"});
document.getElementById("tab_title31").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_hover");
document.getElementById("tab_header31").classList.add("tab_header_hover");
AppendTab({id: 32, pinned: false}, "30", false, false, true, false, false, "filtered highlighted_search active_tab", false, false, false);
AppendTab({tab: {id: 32, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search active_tab"});
document.getElementById("tab_title32").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_active");
AppendTab({id: 33, pinned: false}, "30", false, false, true, false, false, "filtered highlighted_search active_tab", false, false, false);
AppendTab({tab: {id: 33, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search active_tab"});
document.getElementById("tab_title33").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_active_hover");
document.getElementById("tab_header33").classList.add("tab_header_hover");
AppendTab({id: 34, pinned: false}, "30", false, false, true, false, false, "selected_tab filtered highlighted_search", false, false, false);
AppendTab({tab: {id: 34, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered highlighted_search"});
document.getElementById("tab_title34").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected");
AppendTab({id: 35, pinned: false}, "30", false, false, true, false, false, "selected_tab filtered highlighted_search", false, false, false);
AppendTab({tab: {id: 35, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered highlighted_search"});
document.getElementById("tab_title35").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected_hover");
document.getElementById("tab_header35").classList.add("tab_header_hover");
AppendTab({id: 36, pinned: false}, "30", false, false, true, false, false, "selected_tab filtered highlighted_search active_tab", false, false, false);
AppendTab({tab: {id: 36, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered highlighted_search active_tab"});
document.getElementById("tab_title36").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected_active");
AppendTab({id: 37, pinned: false}, "30", false, false, true, false, false, "selected_tab filtered highlighted_search active_tab", false, false, false);
AppendTab({tab: {id: 37, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered highlighted_search active_tab"});
document.getElementById("tab_title37").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected_active_hover");
document.getElementById("tab_header37").classList.add("tab_header_hover");
AddNewFolder("f_folder1", "cftab_list", caption_noname_group, 0, "o", "o", false);
AddNewFolder("f_folder2", "f_folder1", caption_noname_group, 0, "c", "c", false);
AddNewFolder("f_folder3", "f_folder1", caption_noname_group, 0, "c", "c", false);
document.getElementById("_tab_list").classList.add("active_group");

View File

@ -2,11 +2,12 @@
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
function ExportGroup(groupId, filename, save_to_manager) {
let GroupToSave = { group: bggroups[groupId], folders: {}, tabs: [] };
let GroupToSave = { group: tt.groups[groupId], folders: {}, tabs: [] };
document.querySelectorAll("#" + groupId + " .folder").forEach(function(s) {
if (bgfolders[s.id]) {
GroupToSave.folders[s.id] = bgfolders[s.id];
if (tt.folders[s.id]) {
GroupToSave.folders[s.id] = tt.folders[s.id];
}
});
let Tabs = document.querySelectorAll("#" + groupId + " .tab");
@ -50,7 +51,6 @@ function ExportGroup(groupId, filename, save_to_manager) {
}
}
}
function ImportGroup(recreate_group, save_to_manager) {
@ -93,7 +93,6 @@ function AddGroupToStorage(group, add_to_manager) {
}
}
if (opt.debug) {
// log("f: AddGroupToStorage, group: "+JSON.stringify(group)+", add_to_manager: "+add_to_manager);
log("f: AddGroupToStorage, add_to_manager: "+add_to_manager);
}
});
@ -128,6 +127,11 @@ function RecreateGroup(LoadedGroup) {
NewGroupTabs.appendChild(nt);
}
}, 1000);
if (browserId != "O") {
chrome.runtime.sendMessage({command: "discard_tab", tabId: new_tab.id});
}
}
if (NewTabs.length == LoadedGroup.tabs.length - 1) {
setTimeout(function() {
@ -143,13 +147,13 @@ function RecreateGroup(LoadedGroup) {
}
});
setTimeout(function() {
RearrangeTreeStructure({}, NewFolders, NewTabs);
RcreateTreeStructure({}, NewFolders, NewTabs);
}, 1000);
setTimeout(function() {
RearrangeTreeStructure({}, NewFolders, NewTabs);
RcreateTreeStructure({}, NewFolders, NewTabs);
}, 2000);
setTimeout(function() {
RearrangeTreeStructure({}, NewFolders, NewTabs);
RcreateTreeStructure({}, NewFolders, NewTabs);
}, 5000);
}, 2000);
}
@ -157,7 +161,6 @@ function RecreateGroup(LoadedGroup) {
});
if (opt.debug) {
// log("f: RecreateGroup, LoadedGroup: "+JSON.stringify(LoadedGroup)+", NewFolders: "+JSON.stringify(NewFolders)+", NewTabs: "+JSON.stringify(NewTabs));
log("f: RecreateGroup");
}
@ -165,14 +168,14 @@ function RecreateGroup(LoadedGroup) {
function ExportSession(name, save_to_file, save_to_manager, save_to_autosave_manager) {
chrome.windows.getAll({ windowTypes: ['normal'], populate: true }, function(w) {
chrome.runtime.sendMessage({ command: "get_browser_tabs" }, function(response) {
let tabs = Object.assign({}, response);
chrome.runtime.sendMessage({ command: "get_windows" }, function(response) {
let windows = Object.assign({}, response);
chrome.windows.getAll({ windowTypes: ['normal'], populate: true }, function(win) {
chrome.runtime.sendMessage({ command: "get_browser_tabs" }, function(t) {
let tabs = Object.assign({}, t);
chrome.runtime.sendMessage({ command: "get_windows" }, function(w) {
let windows = Object.assign({}, w);
let warn = true;
let ExportWindows = [];
w.forEach(function(CWin) {
win.forEach(function(CWin) {
if (CWin.tabs.length > 0) {
windows[CWin.id]["id"] = CWin.id;
windows[CWin.id]["tabs"] = [];
@ -195,7 +198,6 @@ function ExportSession(name, save_to_file, save_to_manager, save_to_autosave_man
}
if (opt.debug) {
// log("f: ExportSession, name: "+name+", session: "+JSON.stringify(ExportWindows)+", save_to_file: "+save_to_file+", save_to_manager: "+save_to_manager+", save_to_autosave_manager: "+save_to_autosave_manager);
log("f: ExportSession, name: "+name+", save_to_file: "+save_to_file+", save_to_manager: "+save_to_manager+", save_to_autosave_manager: "+save_to_autosave_manager);
}
@ -217,7 +219,6 @@ function ImportSession(recreate_session, save_to_manager, merge_session) {
let LoadedSession = JSON.parse(data);
if (opt.debug) {
// log("f: ImportSession, session: "+data+", recreate_session: "+recreate_session+", merge_session: "+merge_session);
log("f: ImportSession, recreate_session: "+recreate_session+", merge_session: "+merge_session);
}
@ -253,7 +254,6 @@ function AddSessionToStorage(session, name, add_to_manager) {
}
if (opt.debug) {
// log("f: AddSessionToStorage, name: "+name+", add_to_manager: "+add_to_manager+", session: "+JSON.stringify(session));
log("f: AddSessionToStorage, name: "+name+", add_to_manager: "+add_to_manager);
}
});
@ -276,19 +276,16 @@ function AddAutosaveSessionToStorage(session, name) {
}
if (opt.debug) {
// log("f: AddAutosaveSessionToStorage, name: "+name+", session: "+JSON.stringify(session));
log("f: AddAutosaveSessionToStorage, name: "+name);
}
});
}
function RecreateSession(LoadedSession) {
let RefsTabs = {};
if (opt.debug) {
// log("f: RecreateSession, session: "+JSON.stringify(LoadedSession));
log("f: RecreateSession");
}
@ -296,83 +293,95 @@ function RecreateSession(LoadedSession) {
let NewTabs = [];
let urls = [];
(LWin.tabs).forEach(function(Tab) {
urls.push(Tab.url);
NewTabs.push(Tab);
urls.push(Tab.url);
NewTabs.push(Tab);
});
chrome.windows.create({ url: urls }, function(new_window) {
for (let tInd = 0; tInd < new_window.tabs.length; tInd++) {
RefsTabs[NewTabs[tInd].id] = new_window.tabs[tInd].id;
NewTabs[tInd].id = new_window.tabs[tInd].id;
chrome.windows.create({ url: urls /* , discarded: true */ }, function(new_window) {
chrome.runtime.sendMessage({command: "save_groups", windowId: new_window.id, groups: LWin.groups});
chrome.runtime.sendMessage({command: "save_folders", windowId: new_window.id, folders: LWin.folders});
for (let tInd = 0; tInd < new_window.tabs.length; tInd++) {
RefsTabs[NewTabs[tInd].id] = new_window.tabs[tInd].id;
NewTabs[tInd].id = new_window.tabs[tInd].id;
}
for (let tInd = 0; tInd < new_window.tabs.length; tInd++) {
if (RefsTabs[NewTabs[tInd].parent] != undefined) {
NewTabs[tInd].parent = RefsTabs[NewTabs[tInd].parent];
}
for (let tInd = 0; tInd < new_window.tabs.length; tInd++) {
if (RefsTabs[NewTabs[tInd].parent] != undefined) {
NewTabs[tInd].parent = RefsTabs[NewTabs[tInd].parent];
}
}
for (let tInd = 0; tInd < new_window.tabs.length; tInd++) {
if (NewTabs[tInd].parent == "pin_list") {
chrome.tabs.update(new_window.tabs[tInd].id, { pinned: true });
}
let HaveResponse;
let GiveUp = 0;
var Append = setInterval(function() {
chrome.runtime.sendMessage({ command: "remote_update", groups: LWin.groups, folders: LWin.folders, tabs: NewTabs, windowId: new_window.id }, function(response) {
HaveResponse = response;
});
if (HaveResponse || GiveUp > 900) {
clearInterval(Append);
}
GiveUp++;
}, 2000);
chrome.runtime.sendMessage({command: "update_tab", tabId: new_window.tabs[tInd].id, tab: {index: NewTabs[tInd].index, expand: NewTabs[tInd].expand, parent: NewTabs[tInd].parent}});
// if (browserId != "O") {
// chrome.runtime.sendMessage({command: "discard_tab", tabId: new_window.tabs[tInd].id});
// }
}
if (browserId != "O") {
setTimeout(function() {
chrome.runtime.sendMessage({command: "discard_window", windowId: new_window.id});
}, urls.length * 300);
}
});
});
}
function RearrangeTreeStructure(groups, folders, tabs) { // groups and folders are in object, just like bggroups and bgfolders, but tabs are in array of bgtreetabs objects
// groups and folders are in object, just like tt.groups and tt.folders, but tabs are in array of treetabs objects
function RcreateTreeStructure(groups, folders, tabs) {
if (opt.debug) {
log("f: RearrangeTreeStructure");
log("f: RcreateTreeStructure");
}
chrome.tabs.query({ currentWindow: true }, function(ChromeTabs) {
if (groups && Object.keys(groups).length > 0) {
for (var group in groups) {
bggroups[groups[group].id] = Object.assign({}, groups[group]);
}
AppendGroups(bggroups);
ShowStatusBar({show: true, spinner: true, message: "Quick check and recreating structure..."});
if (groups && Object.keys(groups).length > 0) {
for (var group in groups) {
tt.groups[groups[group].id] = Object.assign({}, groups[group]);
}
if (folders && Object.keys(folders).length > 0) {
for (var folder in folders) {
bgfolders[folders[folder].id] = Object.assign({}, folders[folder]);
}
AppendFolders(bgfolders);
AppendGroups(tt.groups);
}
if (folders && Object.keys(folders).length > 0) {
for (var folder in folders) {
tt.folders[folders[folder].id] = Object.assign({}, folders[folder]);
}
let bgtabs = {};
tabs.forEach(function(Tab) {
if (Tab.parent == "pin_list") {
chrome.tabs.update(Tab.id, { pinned: true });
}
AppendFolders(tt.folders);
}
let bgtabs = {};
tabs.forEach(function(Tab) {
if (Tab.parent == "pin_list") {
chrome.tabs.update(Tab.id, { pinned: true });
}
if (Tab.parent != "") {
let tb = document.getElementById(Tab.id);
let tbp = document.getElementById("ct" + Tab.parent);
if (tb != null && tbp != null) {
if (tb && tbp) {
tbp.appendChild(tb);
if (Tab.expand != "") {
tb.classList.add(Tab.expand);
}
}
bgtabs[Tab.id] = { index: Tab.index, parent: Tab.parent, expand: Tab.expand };
});
RearrangeTreeTabs(ChromeTabs, bgtabs, true);
RearrangeFolders(true);
UpdateBgGroupsOrder();
setTimeout(function() {
RefreshExpandStates();
RefreshCounters();
schedule_update_data++;
SaveFolders();
}, 1000);
}
});
RearrangeTreeTabs(bgtabs, false);
RearrangeFolders(true);
UpdateBgGroupsOrder();
setTimeout(function() {
RefreshExpandStates();
RefreshCounters();
tt.schedule_update_data++;
SaveFolders();
}, 3000);
// ShowStatusBar({show: true, spinner: true, message: "Sorting"});
// ShowStatusBar(false, "Wait just a little more...");
}
function ImportMergeTabs(LoadedSession) {
if (opt.debug) {
// log("f: ImportMergeTabs, session: "+JSON.stringify(LoadedSession));
log("f: ImportMergeTabs");
}
let RefsWins = {};
@ -380,27 +389,34 @@ function ImportMergeTabs(LoadedSession) {
for (let LWI = 0; LWI < LoadedSession.length; LWI++) { // clear previous window ids
LoadedSession[LWI].id = "";
}
ShowStatusBar({show: true, spinner: true, message: "Loaded Tree structure..."});
chrome.windows.getAll({ windowTypes: ['normal'], populate: true }, function(cw) {
for (let CWI = 0; CWI < cw.length; CWI++) { // loop Windows
for (let LWI = 0; LWI < LoadedSession.length; LWI++) { // loop Loaded Windows
let tabsMatch = 0;
for (let CTI = 0; CTI < cw[CWI].tabs.length; CTI++) { // loop Tabs of each Current Window
for (let LTI = 0; LTI < LoadedSession[LWI].tabs.length; LTI++) { // loop Tabs of each Loaded Window
if (cw[CWI].tabs[CTI].url == LoadedSession[LWI].tabs[LTI].url) {
RefsTabs[LoadedSession[LWI].tabs[LTI].id] = cw[CWI].tabs[CTI].id;
LoadedSession[LWI].tabs[LTI].id = cw[CWI].tabs[CTI].id;
LoadedSession[LWI].tabs[LTI].url = "";
tabsMatch++;
break;
for (let CWI = 0; CWI < cw.length; CWI++) { // Current Windows
for (let LWI = 0; LWI < LoadedSession.length; LWI++) { // Loaded Windows
if (LoadedSession[LWI].id == "") {
let tabsMatch = 0;
for (let CTI = 0; CTI < cw[CWI].tabs.length; CTI++) { // loop Tabs of CWI Window
for (let LTI = 0; LTI < LoadedSession[LWI].tabs.length; LTI++) { // loop Tabs of Loaded Window
if (cw[CWI].tabs[CTI].url == LoadedSession[LWI].tabs[LTI].url) {
RefsTabs[LoadedSession[LWI].tabs[LTI].id] = cw[CWI].tabs[CTI].id;
LoadedSession[LWI].tabs[LTI].id = cw[CWI].tabs[CTI].id;
LoadedSession[LWI].tabs[LTI].url = "";
tabsMatch++;
break;
}
}
}
}
if (opt.debug) {
log("f: ImportMergeTabs, tabsMatch: "+tabsMatch);
}
if (tabsMatch > LoadedSession[LWI].tabs.length * 0.6) {
LoadedSession[LWI].id = cw[CWI].id;
break;
if (opt.debug) {
log("f: ImportMergeTabs, tabsMatch: "+tabsMatch);
}
if (tabsMatch > LoadedSession[LWI].tabs.length * 0.6) {
LoadedSession[LWI].id = cw[CWI].id;
break;
}
}
}
}
@ -418,68 +434,122 @@ function ImportMergeTabs(LoadedSession) {
NewTabs.push(Tab);
});
chrome.windows.create({ url: urls }, function(new_window) {
chrome.runtime.sendMessage({command: "save_groups", windowId: new_window.id, groups: w.groups});
chrome.runtime.sendMessage({command: "save_folders", windowId: new_window.id, folders: w.folders});
for (let tInd = 0; tInd < new_window.tabs.length; tInd++) {
RefsTabs[NewTabs[tInd].id] = new_window.tabs[tInd].id;
NewTabs[tInd].id = new_window.tabs[tInd].id;
}
for (let tInd = 0; tInd < new_window.tabs.length; tInd++) {
if (RefsTabs[NewTabs[tInd].parent] != undefined) {
NewTabs[tInd].parent = RefsTabs[NewTabs[tInd].parent];
if (NewTabs[tInd]) {
RefsTabs[NewTabs[tInd].id] = new_window.tabs[tInd].id;
NewTabs[tInd].id = new_window.tabs[tInd].id;
}
}
let HaveResponse;
let GiveUp = 0;
var Append = setInterval(function() {
chrome.runtime.sendMessage({ command: "remote_update", groups: w.groups, folders: w.folders, tabs: NewTabs, windowId: new_window.id }, function(response) {
HaveResponse = response;
});
if (HaveResponse || GiveUp > 900) {
clearInterval(Append);
}
GiveUp++;
}, 2000);
});
} else { // window exists, lets add missing tabs
if (opt.debug) {
log("f: ImportMergeTabs, window exists");
}
let NewTabs = [];
(w.tabs).forEach(function(Tab) {
if (Tab.url != "") { // missing tab, lets make one
chrome.tabs.create({ url: Tab.url, windowId: w.id }, function(tab) {
Tab.id = tab.id;
RefsTabs[tab.id] = tab.id;
NewTabs.push(Tab);
});
} else {
NewTabs.push(Tab);
}
});
setTimeout(function() {
for (let tInd = 0; tInd < NewTabs.length; tInd++) {
if (RefsTabs[NewTabs[tInd].parent] != undefined) {
NewTabs[tInd].parent = RefsTabs[NewTabs[tInd].parent];
}
}
}, 4000);
setTimeout(function() {
if (w.id == CurrentWindowId) {
RearrangeTreeStructure(w.groups, w.folders, NewTabs);
} else {
let HaveResponse;
let GiveUp = 0;
var Append = setInterval(function() {
chrome.runtime.sendMessage({ command: "remote_update", groups: w.groups, folders: w.folders, tabs: NewTabs, windowId: w.id }, function(response) {
HaveResponse = response;
});
if (HaveResponse || GiveUp > 900) {
clearInterval(Append);
}
GiveUp++;
}, 2000);
for (let tInd = 0; tInd < new_window.tabs.length; tInd++) {
if (NewTabs[tInd].parent == "pin_list") {
chrome.tabs.update(new_window.tabs[tInd].id, { pinned: true });
}
chrome.runtime.sendMessage({command: "update_tab", tabId: new_window.tabs[tInd].id, tab: {index: NewTabs[tInd].index, expand: NewTabs[tInd].expand, parent: NewTabs[tInd].parent}});
}
}, 6000);
let done = 3;
var Append = setInterval(function() {
chrome.runtime.sendMessage({command: "remote_update", groups: w.groups, folders: w.folders, tabs: NewTabs, windowId: w.id });
if (done < 0) { clearInterval(Append); }
done--;
}, 2000);
});
} else { // window exists, lets add missing tabs
let NewTabs = [];
let RefsTabs = {};
chrome.runtime.sendMessage({command: "get_folders", windowId: w.id}, function(f) {
chrome.runtime.sendMessage({command: "get_groups", windowId: w.id}, function(g) {
if (Object.keys(w.groups).length > 0) {
for (var group in w.groups) {
if (group != "" && group != "undefined" && w.groups[group] != undefined) {
g[w.groups[group].id] = Object.assign({}, w.groups[group]);
}
}
}
if (Object.keys(w.folders).length > 0) {
for (var folder in w.folders) {
if (folder != "" && folder != "undefined" && w.folders[folder] != undefined) {
w.folders[w.folders[folder].id] = Object.assign({}, w.folders[folder]);
}
}
}
if (Object.keys(g).length > 0) {
for (var groupId in g) {
w.groups[groupId] = Object.assign({}, g[groupId]);
}
}
if (Object.keys(f).length > 0) {
for (var folderId in f) {
w.folders[folderId] = Object.assign({}, f[folderId]);
}
}
chrome.runtime.sendMessage({command: "save_groups", windowId: w.id, groups: g});
chrome.runtime.sendMessage({command: "save_folders", windowId: w.id, folders: f});
chrome.runtime.sendMessage({ command: "remote_update", groups: w.groups, folders: w.folders, tabs: [], windowId: w.id });
if (w.id == tt.CurrentWindowId) {
RcreateTreeStructure(w.groups, w.folders, []);
}
(w.tabs).forEach(function(Tab) {
if (Tab.url != "") { // missing tab, lets make one
chrome.tabs.create({ url: Tab.url, pinned: (Tab.parent == "pin_list" ? true : false), windowId: w.id }, function(tab) {
RefsTabs[Tab.id] = tab.id;
Tab.id = tab.id;
NewTabs.push(Tab);
chrome.runtime.sendMessage({command: "update_tab", tabId: tab.id, tab: {index: Tab.index, expand: Tab.expand, parent: Tab.parent}});
});
} else {
NewTabs.push(Tab);
}
});
setTimeout(function() {
ShowStatusBar({show: true, spinner: true, message: "Finding reference tabs..."});
for (let tInd = 0; tInd < NewTabs.length; tInd++) {
if (RefsTabs[NewTabs[tInd].parent] != undefined) {
NewTabs[tInd].parent = RefsTabs[NewTabs[tInd].parent];
}
}
}, 4000);
setTimeout(function() {
for (let tInd = 0; tInd < NewTabs.length; tInd++) {
chrome.runtime.sendMessage({command: "update_tab", tabId: NewTabs[tInd].id, tab: {index: NewTabs[tInd].index, expand: NewTabs[tInd].expand, parent: NewTabs[tInd].parent}});
}
let done = 10;
var Append = setInterval(function() {
ShowStatusBar({show: true, spinner: true, message: "Finding other windows to add tabs..."});
if (w.id == tt.CurrentWindowId) {
RcreateTreeStructure(w.groups, w.folders, NewTabs);
} else {
chrome.runtime.sendMessage({command: "remote_update", groups: w.groups, folders: w.folders, tabs: NewTabs, windowId: w.id });
}
if (done < 0) {
ShowStatusBar({show: true, spinner: false, message: "All done.", hideTimeout: 2000});
clearInterval(Append);
}
done--;
}, 500);
}, 6000);
});
});
}
});
});
@ -488,13 +558,16 @@ function ImportMergeTabs(LoadedSession) {
function StartAutoSaveSession() {
if (opt.autosave_interval > 0 && opt.autosave_max_to_keep > 0) {
AutoSaveSession = setInterval(function() {
tt.AutoSaveSession = setInterval(function() {
if (opt.debug) {
log("f: AutoSaveSession, loop time is: "+opt.autosave_interval);
}
let d = new Date();
ExportSession((d.toLocaleString().replace("/", ".").replace("/", ".").replace(":", "").replace(":", "")), false, false, true);
let newName = d.toLocaleString().replace("/", ".").replace("/", ".").replace(":", "").replace(":", "");
ExportSession(newName, false, false, true);
ShowStatusBar({show: true, spinner: false, message: "Autosave: "+newName, hideTimeout: 1000});
if (document.getElementById("manager_window").style.top != "-500px") {
chrome.storage.local.get(null, function(storage) {

View File

@ -1,411 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
// ********** CHROME EVENTS ***************
function StartChromeListeners() {
if (browserId == "F") {
browser.browserAction.onClicked.addListener(function(tab) {
if (tab.windowId == CurrentWindowId) {
browser.sidebarAction.close();
}
});
}
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message.command == "backup_available") {
if (opt.debug) {
log("message to sidebar "+CurrentWindowId+": message: "+message.command);
}
let BAKbutton = document.getElementById("button_load_bak"+message.bak);
if (BAKbutton != null) {
BAKbutton.classList.remove("disabled");
}
}
if (message.command == "drag_drop") {
if (opt.debug) {
log("message to sidebar "+CurrentWindowId+": message: "+message.command);
}
CleanUpDragClasses();
DragNodeClass = message.DragNodeClass;
DragTreeDepth = Object.assign(0, message.DragTreeDepth);
}
if (message.command == "dragend") {
if (opt.debug) {
log("message to sidebar "+CurrentWindowId+": message: "+message.command);
}
CleanUpDragClasses();
EmptyDragAndDrop();
}
if (message.command == "remove_folder") {
if (opt.debug) {
log("message to sidebar "+CurrentWindowId+": message: "+message.command+" folderId: "+message.folderId);
}
RemoveFolder(message.folderId);
}
if (message.command == "reload_sidebar") {
if (opt.debug) {
log("message to sidebar "+CurrentWindowId+": message: "+message.command);
}
window.location.reload();
}
if (message.command == "reload_options") {
if (opt.debug) {
log("message to sidebar "+CurrentWindowId+": message: "+message.command);
}
opt = Object.assign({}, message.opt);
setTimeout(function() {
RestorePinListRowSettings();
}, 100);
}
if (message.command == "reload_toolbar") {
if (opt.debug) {
log("message to sidebar "+CurrentWindowId+": message: "+message.command);
}
opt = Object.assign({}, message.opt);
if (opt.show_toolbar) {
RemoveToolbar();
RecreateToolbar(message.toolbar);
SetToolbarEvents(false, true, true, "mousedown");
RestoreToolbarShelf();
RestoreToolbarSearchFilter();
} else {
RemoveToolbar();
}
RefreshGUI();
}
if (message.command == "reload_theme") {
if (opt.debug) {
log("message to sidebar "+CurrentWindowId+": message: "+message.command);
}
RestorePinListRowSettings();
ApplyTheme(message.theme);
}
if (message.windowId == CurrentWindowId) {
// I WANT TO MOVE THIS LOGIC TO THE BACKGROUND SCRIPT!
if (message.command == "tab_created") {
chrome.tabs.get(message.tabId, function(NewTab) { // get tab again as reported tab's url is empty! Also for some reason firefox sends tab with "active == false" even if tab is active (THIS IS POSSIBLY A NEW BUG IN FF 60.01!)
if (opt.debug) {
log("chrome event: tab_created: "+message.tabId);
}
if (opt.move_tabs_on_url_change == "from_empty_b" && NewTab.url == newTabUrl) {
EmptyTabs.push(message.tabId);
}
if (document.getElementById(message.tabId) == null) {
if (opt.move_tabs_on_url_change == "from_empty" && NewTab.url == newTabUrl) {
EmptyTabs.push(message.tabId);
}
if (message.parentTabId != undefined) {
AppendTab(NewTab, message.parentTabId, false, false, true, message.index, true, false, false, true, false);
} else {
if (opt.append_orphan_tab == "as_child" && NewTab.openerTabId == undefined && document.querySelector("#"+active_group+" .active_tab")) {
if (opt.debug) {
log("tab_created: as_child, ignores orphan case, appending tab as child");
}
NewTab.openerTabId = document.querySelector("#"+active_group+" .active_tab").id;
}
if (NewTab.openerTabId) { // child case
if (opt.append_child_tab == "after_active") {
if (opt.debug) {
log("tab_created: child case, tab will append after active, openerTabId: "+NewTab.openerTabId);
}
AppendTab(NewTab, false, false, document.querySelector("#"+active_group+" .active_tab") != null ? document.querySelector("#"+active_group+" .active_tab").id : false, false, false, true, false, false, true, false);
} else {
let Parents = GetParentsByClass(document.getElementById(NewTab.openerTabId), "tab");
if (opt.max_tree_depth < 0 || (opt.max_tree_depth > 0 && Parents.length < opt.max_tree_depth)) { // append to tree
if (opt.append_child_tab == "top") {
if (opt.debug) {
log("tab_created: child case, in tree limit, tab will append on top, openerTabId: "+NewTab.openerTabId);
}
AppendTab(NewTab, NewTab.openerTabId, false, false, (NewTab.pinned ? true : false), false, true, false, false, true, false);
}
if (opt.append_child_tab == "bottom") {
if (opt.debug) {
log("tab_created: child case, in tree limit, tab will append on bottom, openerTabId: "+NewTab.openerTabId);
}
AppendTab(NewTab, NewTab.openerTabId, false, false, true, false, true, false, false, true, false);
}
}
if (opt.max_tree_depth > 0 && Parents.length >= opt.max_tree_depth) { // if reached depth limit of the tree
if (opt.debug) {
log("tab_created: child case, surpassed tree limit, openerTabId: "+NewTab.openerTabId);
}
if (opt.append_child_tab_after_limit == "after") {
if (opt.debug) {
log("tab_created: tab will append after active, openerTabId: "+NewTab.openerTabId);
}
AppendTab(NewTab, false, false, NewTab.openerTabId, true, false, true, false, false, true, false);
}
if (opt.append_child_tab_after_limit == "top") {
if (opt.debug) {
log("tab_created: tab will append on top, openerTabId: "+NewTab.openerTabId);
}
AppendTab(NewTab, document.getElementById(NewTab.openerTabId).parentNode.parentNode.id, false, false, (NewTab.pinned ? true : false), false, true, false, false, true, false);
}
if (opt.append_child_tab_after_limit == "bottom") {
if (opt.debug) {
log("tab_created: tab will append on bottom, openerTabId: "+NewTab.openerTabId);
}
AppendTab(NewTab, document.getElementById(NewTab.openerTabId).parentNode.parentNode.id, false, false, true, false, true, false, false, true, false);
}
}
}
if (opt.max_tree_depth == 0) { // place tabs flat
if (opt.debug) {
log("tab_created: max_tree_depth is 0, tabs are placed on the same level");
}
if (opt.append_child_tab_after_limit == "after") {
if (opt.debug) {
log("tab_created: tab will append after active");
}
AppendTab(NewTab, false, false, NewTab.openerTabId, false, false, true, false, false, true, false);
}
if (opt.append_child_tab_after_limit == "top") {
if (opt.debug) {
log("tab_created: tab will append on top");
}
AppendTab(NewTab, false, false, false, false, false, true, false, false, true, false);
}
if (opt.append_child_tab_after_limit == "bottom") {
if (opt.debug) {
log("tab_created: tab will append on bottom");
}
AppendTab(NewTab, false, false, false, true, false, true, false, false, true, false);
}
}
} else { // orphan case
// if set to append orphan tabs to ungrouped group
// if tab is still not present, basically, not opened by OpenNewTab(), it will switch to ungrouped group
// if (opt.orphaned_tabs_to_ungrouped === true && document.getElementById(message.tabId) == null && !NewTab.pinned) {
if (opt.orphaned_tabs_to_ungrouped === true && !NewTab.pinned) {
if (opt.debug) {
log("tab_created: orphan case, orphaned tab goes to ungrouped");
}
if (active_group != "tab_list") {
SetActiveGroup("tab_list", false, false);
}
}
if (opt.append_orphan_tab == "after_active") {
if (opt.debug) {
log("tab_created: orphan case, appending tab after active");
}
AppendTab(NewTab, false, false, (document.querySelector("#"+active_group+" .active_tab") != null ? document.querySelector("#"+active_group+" .active_tab").id : undefined), (NewTab.pinned ? true : false), false, true, false, false, true, false);
}
if (opt.append_orphan_tab == "top") {
if (opt.debug) {
log("tab_created: orphan case, appending tab on top");
}
AppendTab(NewTab, false, false, false, false, false, true, false, false, true, false);
}
if (opt.append_orphan_tab == "bottom" || opt.append_orphan_tab == "as_child") {
if (opt.debug) {
log("tab_created: orphan case, appending tab on bottom");
}
AppendTab(NewTab, false, false, false, true, false, true, false, false, true, false);
}
}
}
if (opt.move_tabs_on_url_change === "all_new") {
AppendTabToGroupOnRegexMatch(message.tabId, NewTab.url);
}
if (NewTab.openerTabId) { // check if openerTabId is defined, if it's in DOM and if it's closed, then change it to open
let openerTab = document.querySelector(".c[id='"+NewTab.openerTabId+"']");
if (openerTab != null) {
openerTab.classList.remove("c");
openerTab.classList.add("o");
}
}
if (opt.syncro_tabbar_tabs_order) {
let tabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s){
return parseInt(s.id);
});
chrome.tabs.move(message.tabId, {index: tabIds.indexOf(message.tabId)});
}
RefreshExpandStates();
setTimeout(function() {
schedule_update_data++;
}, 500);
setTimeout(function() {
RefreshCounters();
RefreshGUI();
},50);
}
});
return;
}
if (message.command == "tab_attached") {
if (opt.debug) {
log("chrome event: "+message.command+", tabId: "+message.tabId+", tab is pinned: "+message.tab.pinned+", ParentId: "+message.ParentId);
}
AppendTab(message.tab, message.ParentId, false, false, true, false, true, false, false, true, false);
RefreshGUI();
return;
}
if (message.command == "tab_detached") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
}
let ctDetachedParent = document.getElementById(message.tabId).childNodes[1];
if (ctDetachedParent != null) {
if (opt.promote_children_in_first_child == true && ctDetachedParent.childNodes.length > 1) {
let ctNewParent = document.getElementById(ctDetachedParent.firstChild.id).childNodes[1];
ctDetachedParent.parentNode.parentNode.insertBefore(ctDetachedParent.firstChild, ctDetachedParent.parentNode);
while (ctDetachedParent.firstChild) {
ctNewParent.appendChild(ctDetachedParent.firstChild);
}
} else {
while (ctDetachedParent.firstChild) {
ctDetachedParent.parentNode.parentNode.insertBefore(ctDetachedParent.firstChild, ctDetachedParent.parentNode);
}
}
}
RemoveTabFromList(message.tabId);
setTimeout(function() {
schedule_update_data++;
}, 300);
RefreshGUI();
return;
}
if (message.command == "tab_removed") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
}
if (EmptyTabs.indexOf(message.tabId) != -1) {
EmptyTabs.splice(EmptyTabs.indexOf(message.tabId), 1);
}
let mTab = document.getElementById(message.tabId);
if (mTab != null) {
let ctParent = mTab.childNodes[1];
if (opt.debug) {
log("tab_removed, promote children: " +opt.promote_children);
}
if (opt.promote_children == true) {
if (opt.promote_children_in_first_child == true && ctParent.childNodes.length > 1) {
let ctNewParent = document.getElementById(ctParent.firstChild.id).childNodes[1];
ctParent.parentNode.parentNode.insertBefore(ctParent.firstChild, ctParent.parentNode);
while (ctParent.firstChild) {
ctNewParent.appendChild(ctParent.firstChild);
}
} else {
while (ctParent.firstChild) {
ctParent.parentNode.parentNode.insertBefore(ctParent.firstChild, ctParent.parentNode);
}
}
} else {
document.querySelectorAll("[id='"+message.tabId+"'] .tab").forEach(function(s) {
chrome.tabs.remove(parseInt(s.id));
});
}
RemoveTabFromList(message.tabId);
RefreshExpandStates();
setTimeout(function() {
schedule_update_data++;
}, 300);
RefreshGUI();
RefreshCounters();
}
return;
}
if (message.command == "tab_activated") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
}
SetActiveTab(message.tabId, true);
return;
}
if (message.command == "tab_attention") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
}
SetAttentionIcon(message.tabId);
return;
}
if (message.command == "tab_updated") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId+ ", changeInfo: "+JSON.stringify(message.changeInfo));
// log(message.changeInfo);
}
if (message.changeInfo.favIconUrl != undefined || message.changeInfo.url != undefined) {
setTimeout(function() {
GetFaviconAndTitle(message.tabId, true);
}, 100);
}
if (message.changeInfo.title != undefined) {
setTimeout(function() {
GetFaviconAndTitle(message.tabId, true);
}, 1000);
}
if (message.changeInfo.audible != undefined || message.changeInfo.mutedInfo != undefined) {
RefreshMediaIcon(message.tabId);
}
if (message.changeInfo.discarded != undefined) {
RefreshDiscarded(message.tabId);
}
if (message.changeInfo.pinned != undefined) {
let updateTab = document.getElementById(message.tabId);
if (updateTab != null) {
if (message.tab.pinned && updateTab.classList.contains("pin") == false) {
SetTabClass(message.tabId, true);
schedule_update_data++;
}
if (!message.tab.pinned && updateTab.classList.contains("tab") == false) {
SetTabClass(message.tabId, false);
schedule_update_data++;
}
}
RefreshExpandStates();
}
// if set to append when url changes and matches pre-set group
if (message.changeInfo.url != undefined && message.changeInfo.url != newTabUrl) {
// if (((opt.move_tabs_on_url_change == "from_empty" || opt.move_tabs_on_url_change == "from_empty_b") && EmptyTabs.indexOf(message.tabId) != -1) || opt.move_tabs_on_url_change == "always") {
if (EmptyTabs.indexOf(message.tabId) != -1 || opt.move_tabs_on_url_change == "always") {
AppendTabToGroupOnRegexMatch(message.tabId, message.changeInfo.url);
}
if (EmptyTabs.indexOf(message.tabId) != -1) {
EmptyTabs.splice(EmptyTabs.indexOf(message.tabId), 1);
}
}
return;
}
if (message.command == "remote_update") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
log(message);
}
RearrangeTreeStructure(message.groups, message.folders, message.tabs);
sendResponse(true);
return;
}
}
});
}

128
scripts/common.js Normal file
View File

@ -0,0 +1,128 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
// GLOBAL VARIABLES
let browserId = navigator.userAgent.match("Opera|OPR") !== null ? "O" : (navigator.userAgent.match("Vivaldi") !== null ? "V" : (navigator.userAgent.match("Firefox") !== null ? "F" : "C" ))
let opt = {};
let labels = {
clear_filter: chrome.i18n.getMessage("caption_clear_filter"),
loading: chrome.i18n.getMessage("caption_loading"),
searchbox: chrome.i18n.getMessage("caption_searchbox"),
ungrouped_group: chrome.i18n.getMessage("caption_ungrouped_group"),
noname_group: chrome.i18n.getMessage("caption_noname_group")
};
// BACKGROUND VARIABLES
let b = {
debug: [],
running: false,
schedule_save: -999,
windows: {},
tabs: {},
tt_ids: {},
EmptyTabs: [],
newTabUrl: browserId == "F" ? "about:newtab" : "chrome://startpage/"
};
// DEFAULTS NEEDED FOR START AND FOR OPTIONS PAGE
const DefaultToolbar = {
toolbar_main: ["button_new", "button_pin", "button_undo", "button_search", "button_tools", "button_groups", "button_backup", "button_folders"],
toolbar_search: ["button_filter_type", "filter_search_go_prev", "filter_search_go_next"],
toolbar_shelf_tools: (browserId == "F" ? ["button_manager_window", "button_options", "button_unload", "button_detach", "button_reboot"] : ["button_manager_window", "button_options", "button_bookmarks", "button_downloads", "button_history", "button_settings", "button_extensions", "button_unload", "button_detach", "button_reboot"]),
toolbar_shelf_groups: ["button_groups_toolbar_hide", "button_new_group", "button_remove_group", "button_edit_group", "button_import_group", "button_export_group"],
toolbar_shelf_backup: (browserId == "F" ? ["button_import_bak", "button_import_merge_bak", "button_export_bak"] : ["button_import_bak", "button_import_merge_bak", "button_export_bak", "button_load_bak1", "button_load_bak2", "button_load_bak3"]),
toolbar_shelf_folders: ["button_new_folder", "button_remove_folder", "button_edit_folder"]
};
const DefaultTheme = {
ToolbarShow: true,
ColorsSet: {},
TabsSizeSetNumber: 2,
TabsMargins: "2",
theme_name: "untitled",
theme_version: 4
};
const DefaultPreferences = {
hide_other_groups_tabs_firefox: false,
show_toolbar: true,
skip_load: false,
pin_list_multi_row: true,
always_show_close: false,
never_show_close: false,
allow_pin_close: false,
append_child_tab: "bottom",
append_child_tab_after_limit: "after",
append_orphan_tab: "bottom",
after_closing_active_tab: "below_seek_in_parent",
collapse_other_trees: false,
open_tree_on_hover: true,
promote_children: true,
promote_children_in_first_child: true,
max_tree_depth: -1,
max_tree_drag_drop: true,
max_tree_drag_drop_folders: false,
switch_with_scroll: false,
syncro_tabbar_tabs_order: true,
show_counter_groups: true,
show_counter_tabs: true,
show_counter_tabs_hints: true,
groups_toolbar_default: true,
syncro_tabbar_groups_tabs_order: true,
midclick_tab: "close_tab",
dbclick_tab: "new_tab",
dbclick_group: "new_tab",
// dbclick_group_bar: "new_group",
midclick_group: "nothing",
midclick_folder: "nothing",
dbclick_folder: "rename_folder",
debug: false,
orphaned_tabs_to_ungrouped: false,
tab_group_regexes: [],
move_tabs_on_url_change: "never",
autosave_max_to_keep: 5,
autosave_interval: 15
};
// SIDEBAR VARIABLES
// let active_group = "tab_list";
let tt = {
CurrentWindowId: 0,
active_group: "tab_list",
groups: {},
folders: {},
schedule_update_data: 0,
schedule_rearrange_tabs: 0,
DragNodeClass: "",
DragTreeDepth: 0,
DragOverId: "",
menuItemNode: undefined,
SearchIndex: 0,
DragOverTimer: undefined,
AutoSaveSession: undefined
};
// GLOBAL FUNCTIONS
function GenerateRandomID(){
let letters = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","K","L","M","N","O","P","R","S","T","Q","U","V","W","Y","Z","a","b","c","d","e","f","g","h","i","k","l","m","n","o","p","r","s","t","q","u","v","w","y","z"];
let random = ""; for (let letter = 0; letter < 6; letter++ ) {random += letters[Math.floor(Math.random() * letters.length)];} return random;
}
function GetCurrentPreferences(storage) {
opt = Object.assign({}, DefaultPreferences);
if (storage["preferences"]) {
for (let parameter in storage["preferences"]) {
if (opt[parameter] != undefined) {
opt[parameter] = storage["preferences"][parameter];
// legacy, changed from "after_active" to "after", because it is a parent tab, not necessarily an active tab
if (parameter == "append_child_tab" && storage["preferences"][parameter] == "after_active") {
opt[parameter] = "after";
}
}
}
}
}

View File

@ -49,7 +49,6 @@ function SetEvents() {
if (event.which == 1) {
RemoveHeadersHoverClass();
}
}
// CONFIRM EDIT FOLDER
@ -118,7 +117,7 @@ function SetEvents() {
}
PinList.ondragover = function(event) {
// PIN,TAB==>PINLIST
if (event.target.id == "pin_list" && DragNodeClass == "tab" && this.classList.contains("highlighted_drop_target") == false) {
if (event.target.id == "pin_list" && tt.DragNodeClass == "tab" && this.classList.contains("highlighted_drop_target") == false) {
RemoveHighlight();
this.classList.add("highlighted_drop_target");
}
@ -147,6 +146,13 @@ function SetEvents() {
document.getElementById(this.getAttribute("PickColor")).style.backgroundColor = this.value;
}
document.getElementById("group_list").ondragleave = function(event) {
if (opt.open_tree_on_hover) {
clearTimeout(tt.DragOverTimer);
tt.DragOverId = "";
}
}
// CATCH KEYBOARD GLOBAL KEYS
@ -158,8 +164,8 @@ function SetEvents() {
s.classList.add("selected_tab");
});
}
if (document.querySelector("#"+active_group+" .tab>.tab_header_hover") != null) {
let rootId = document.querySelector("#"+active_group+" .tab>.tab_header_hover").parentNode.parentNode.parentNode.id;
if (document.querySelector("#"+tt.active_group+" .tab>.tab_header_hover") != null) {
let rootId = document.querySelector("#"+tt.active_group+" .tab>.tab_header_hover").parentNode.parentNode.parentNode.id;
document.querySelectorAll("#ct"+rootId+">.tab").forEach(function(s){
s.classList.add("selected_tab");
});
@ -172,8 +178,8 @@ function SetEvents() {
s.classList.toggle("selected_tab");
});
}
if (document.querySelector("#"+active_group+" .tab>.tab_header_hover") != null) {
let rootId = document.querySelector("#"+active_group+" .tab>.tab_header_hover").parentNode.parentNode.parentNode.id;
if (document.querySelector("#"+tt.active_group+" .tab>.tab_header_hover") != null) {
let rootId = document.querySelector("#"+tt.active_group+" .tab>.tab_header_hover").parentNode.parentNode.parentNode.id;
document.querySelectorAll("#ct"+rootId+">.tab").forEach(function(s){
s.classList.toggle("selected_tab");
});
@ -188,6 +194,12 @@ function SetEvents() {
if (event.altKey && event.which == 71) {
GroupsToolbarToggle();
}
// new folder
// if (event.which == 91 && event.which == 71) {
// let FolderId = AddNewFolder({SetEvents: true});
// ShowRenameFolderDialog(FolderId);
// }
RefreshGUI();
}
@ -197,20 +209,16 @@ function SetEvents() {
log("drag over: "+event.target.id);
}
event.preventDefault();
if (event.target.parentNode.classList.contains("c") && event.target.parentNode.classList.contains("dragged_tree") == false) {
if (DragOverTimer && opt.open_tree_on_hover) {
event.target.parentNode.classList.add("o");
event.target.parentNode.classList.remove("c");
DragOverTimer = false;
}
}
}
document.ondrop = function(event) {
if (opt.debug) {
log("dropped on window: "+CurrentWindowId);
log("dropped on window: "+tt.CurrentWindowId);
}
let Class = event.dataTransfer.getData("Class") ? event.dataTransfer.getData("Class") : "";
let Group = event.dataTransfer.getData("Group") ? JSON.parse(event.dataTransfer.getData("Group")) : {};
let DraggedTabNode = event.dataTransfer.getData("DraggedTabNode") ? event.dataTransfer.getData("DraggedTabNode") : false;
let TabsIds = event.dataTransfer.getData("TabsIds") ? JSON.parse(event.dataTransfer.getData("TabsIds")) : [];
let TabsIdsParents = event.dataTransfer.getData("TabsIdsParents") ? JSON.parse(event.dataTransfer.getData("TabsIdsParents")) : [];
let TabsIdsSelected = event.dataTransfer.getData("TabsIdsSelected") ? JSON.parse(event.dataTransfer.getData("TabsIdsSelected")) : [];
@ -219,59 +227,46 @@ function SetEvents() {
let SourceWindowId = event.dataTransfer.getData("SourceWindowId") ? JSON.parse(event.dataTransfer.getData("SourceWindowId")) : 0;
let target = document.querySelector(".highlighted_drop_target");
event.preventDefault();
let ActiveGroup = document.getElementById(tt.active_group);
let Scroll = ActiveGroup.scrollTop;
clearTimeout(tt.DragOverTimer);
tt.DragOverId = "";
if (SourceWindowId == CurrentWindowId) {
DropToTarget(target, TabsIdsSelected, TabsIds, TabsIdsParents, Folders, FoldersSelected);
event.preventDefault();
if (SourceWindowId == tt.CurrentWindowId) {
if (Class == "group") {
DropToTarget({Class: Class, DraggedTabNode: DraggedTabNode, TargetNode: target, TabsIds: [], TabsIdsSelected: [], TabsIdsParents: [], Folders: {}, FoldersSelected: [], Group: Group, Scroll: Scroll});
} else {
DropToTarget({Class: Class, DraggedTabNode: DraggedTabNode, TargetNode: target, TabsIds: TabsIds, TabsIdsSelected: TabsIdsSelected, TabsIdsParents: TabsIdsParents, Folders: Folders, FoldersSelected: FoldersSelected, Group: Group, Scroll: Scroll});
}
} else {
FreezeSelected();
if (Object.keys(Group).length > 0) {
tt.groups[Group.id] = Object.assign({}, Group);
AppendGroupToList(Group.id, Group.name, Group.font, true);
}
if (Object.keys(Folders).length > 0) {
let SelectedFolders = Object.assign([], FoldersSelected);
for (var folder in Folders) {
AddNewFolder(folder, Folders[folder].parent, Folders[folder].name, Folders[folder].index, Folders[folder].expand, (FoldersSelected.indexOf(folder) != -1 ? "selected_folder" : undefined), true);
chrome.runtime.sendMessage({ command: "remove_folder", folderId: Folders[folder].id });
for (var folderId in Folders) {
AddNewFolder({folderId: folderId, ParentId: Folders[folderId].parent, Name: Folders[folderId].name, Index: Folders[folderId].index, ExpandState: Folders[folderId].expand, AdditionalClass: (FoldersSelected.indexOf(folderId) != -1 ? "selected_folder" : undefined), SetEvents: true});
chrome.runtime.sendMessage({ command: "remove_folder", folderId: folderId });
}
}
let counter = 0;
if (TabsIds.length == 0) {
DropToTarget(target, TabsIdsSelected, TabsIds, TabsIdsParents, Folders, FoldersSelected);
} else {
(TabsIds).forEach(function(TabId) {
if (opt.debug) {
log("DragAndDrop: will now move tab: "+TabId);
}
chrome.tabs.move(TabId, { windowId: CurrentWindowId, index: -1 }, function(MovedTab) {
if (browserId == "F") { // MOZILLA BUG 1398272
let MovedTabId = MovedTab[0] != undefined ? MovedTab[0].id : (MovedTab.id != undefined ? MovedTab.id : TabId); // MOZILLA BUG 1398272
if ((TabsIdsParents).indexOf("ct"+TabsIds[counter]) != -1) { // MOZILLA BUG 1398272
TabsIdsParents[(TabsIdsParents).indexOf("ct"+TabsIds[counter])] = "ct"+MovedTabId; // MOZILLA BUG 1398272
} // MOZILLA BUG 1398272
if ((TabsIdsSelected).indexOf(TabsIds[counter]) != -1) { // MOZILLA BUG 1398272
TabsIdsSelected[(TabsIdsSelected).indexOf(TabsIds[counter])] = MovedTabId; // MOZILLA BUG 1398272
} // MOZILLA BUG 1398272
TabsIds[counter] = MovedTabId; // MOZILLA BUG 1398272
} // MOZILLA BUG 1398272
counter++;
if (counter == TabsIds.length) {
setTimeout(function() {
(TabsIdsSelected).forEach(function(selectedTabId) {
let selectedTab = document.getElementById(selectedTabId);
if (selectedTab != null) {
selectedTab.classList.add("selected_temporarly");
selectedTab.classList.add("selected_tab");
}
});
DropToTarget(target, TabsIdsSelected, TabsIds, TabsIdsParents, Folders, FoldersSelected);
}, 200);
}
});
});
if (opt.debug) {
log("DragAndDrop: will now move tabs");
}
chrome.tabs.move(TabsIds, { windowId: tt.CurrentWindowId, index: -1 }, function(MovedTab) {
setTimeout(function() {
DropToTarget({Class: Class, DraggedTabNode: DraggedTabNode, TargetNode: target, TabsIds: TabsIds, TabsIdsSelected: TabsIdsSelected, TabsIdsParents: TabsIdsParents, Folders: Folders, FoldersSelected: FoldersSelected, Group: Group, Scroll: Scroll});
chrome.runtime.sendMessage({ command: "remove_group", groupId: Group.id });
}, 2000);
});
}
}
@ -280,25 +275,27 @@ function SetEvents() {
if (opt.debug) {
log("global dragleave");
}
if (event.target.classList) {
if (event.target.classList.contains("drag_enter_center")) {
DragOverTimer = false;
}
}
RemoveHighlight();
if (opt.open_tree_on_hover) {
clearTimeout(tt.DragOverTimer);
tt.DragOverId = "";
}
}
document.ondragend = function(event) {
if (opt.open_tree_on_hover) {
clearTimeout(tt.DragOverTimer);
tt.DragOverId = "";
}
// log("document dragend");
// DETACHING TEMPORARILY DISABLED PLEASE USE MENU OR TOOLBAR!
// if (DragAndDrop.ComesFromWindowId == CurrentWindowId && DragAndDrop.DroppedToWindowId == 0) {
// if (DragAndDrop.ComesFromWindowId == tt.CurrentWindowId && DragAndDrop.DroppedToWindowId == 0) {
// if ((browserId == "F" && ( event.screenX < event.view.mozInnerScreenX || event.screenX > (event.view.mozInnerScreenX + window.innerWidth) || event.screenY < event.view.mozInnerScreenY || event.screenY > (event.view.mozInnerScreenY + window.innerHeight)))|| (browserId != "F" && (event.pageX < 0 || event.pageX > window.outerWidth || event.pageY < 0 || event.pageY > window.outerHeight))) {
// log("dragged outside sidebar");
// if (DragNodeClass == "tab") {
// if (tt.DragNodeClass == "tab") {
// Detach(DragAndDrop.TabsIds, {});
// }
// if (DragNodeClass == "folder") {
// if (tt.DragNodeClass == "folder") {
// Detach(DragAndDrop.TabsIds, DragAndDrop.Folders);
// setTimeout(function() {
// SaveFolders();
@ -354,108 +351,95 @@ function RemoveHeadersHoverClass() {
function DropToTarget(TargetNode, TabsIdsSelected, TabsIds, TabsIdsParents, Folders, FoldersSelected) {
if (TargetNode != null) {
function DropToTarget(p) { // Class: ("group", "tab", "folder"), DraggedTabNode: TabId, TargetNode: query node, TabsIdsSelected: arr of selected tabIds, TabsIds: arr of tabIds, TabsIdsParents: arr of parent tabIds, Folders: object with folders objects, FoldersSelected: arr of selected folders ids, Group: groupId, Scroll: bool
if (p.TargetNode != null) {
if (opt.debug) {
log("f: DropToTarget, TargetNode: "+TargetNode.id+", TabsIdsSelected: "+JSON.stringify(TabsIdsSelected)+", TabsIds: "+JSON.stringify(TabsIds)+", TabsIdsParents: "+JSON.stringify(TabsIdsParents)+", Folders: "+JSON.stringify(Folders)+", FoldersSelected: "+JSON.stringify(FoldersSelected) );
log("f: DropToTarget, DragNodeClass: "+p.Class+", TargetNode: "+p.TargetNode.id+", TabsIdsSelected: "+JSON.stringify(p.TabsIdsSelected)+", TabsIds: "+JSON.stringify(p.TabsIds)+", TabsIdsParents: "+JSON.stringify(p.TabsIdsParents)+", Folders: "+JSON.stringify(p.Folders)+", FoldersSelected: "+JSON.stringify(p.FoldersSelected) );
}
// let Append;
let ActiveGroup = document.getElementById(tt.active_group);
let pinTabs = false;
let SelectedTabsAppendTarget;
let FoldersSelectedAppendTarget;
if (DragNodeClass == "tab") {
if (TargetNode.classList.contains("pin")) {
if (p.Class == "tab") {
if (p.TargetNode.classList.contains("pin")) {
pinTabs = true;
if (TargetNode.classList.contains("before")) {
TabsIds.forEach(function(tabId){
InsterBeforeNode(document.getElementById(tabId), TargetNode);
if (p.TargetNode.classList.contains("before")) {
p.TabsIds.forEach(function(tabId){
InsterBeforeNode(document.getElementById(tabId), p.TargetNode);
});
}
if (TargetNode.classList.contains("after")) {
for (let i = TabsIds.length-1; i >= 0; i--) {
InsterAfterNode(document.getElementById(TabsIds[i]), TargetNode);
if (p.TargetNode.classList.contains("after")) {
for (let i = p.TabsIds.length-1; i >= 0; i--) {
InsterAfterNode(document.getElementById(p.TabsIds[i]), p.TargetNode);
}
}
}
if (TargetNode.classList.contains("tab")) {
if (TargetNode.classList.contains("before")) {
TabsIdsSelected.forEach(function(tabId){
InsterBeforeNode(document.getElementById(tabId), TargetNode);
if (p.TargetNode.classList.contains("tab")) {
if (p.TargetNode.classList.contains("before")) {
p.TabsIdsSelected.forEach(function(tabId){
InsterBeforeNode(document.getElementById(tabId), p.TargetNode);
});
}
if (TargetNode.classList.contains("after")) {
for (let i = TabsIdsSelected.length-1; i >= 0; i--) {
InsterAfterNode(document.getElementById(TabsIdsSelected[i]), TargetNode);
if (p.TargetNode.classList.contains("after")) {
for (let i = p.TabsIdsSelected.length-1; i >= 0; i--) {
InsterAfterNode(document.getElementById(p.TabsIdsSelected[i]), p.TargetNode);
}
}
if (TargetNode.classList.contains("inside")) {
TabsIdsSelected.forEach(function(tabId){
AppendToNode(document.getElementById(tabId), TargetNode.childNodes[1]);
});
if (p.TargetNode.classList.contains("inside")) {
SelectedTabsAppendTarget = p.TargetNode.childNodes[1];
}
ActiveGroup.scrollTop = p.Scroll;
}
if (TargetNode.id == "pin_list") {
if (p.TargetNode.id == "pin_list") {
pinTabs = true;
TabsIds.forEach(function(tabId){
AppendToNode(document.getElementById(tabId), TargetNode);
});
SelectedTabsAppendTarget = p.TargetNode;
}
if (TargetNode.classList.contains("group")) {
TabsIdsSelected.forEach(function(tabId){
AppendToNode(document.getElementById(tabId), TargetNode.childNodes[1]);
});
if (p.TargetNode.classList.contains("group")) {
SelectedTabsAppendTarget = p.TargetNode.childNodes[1];
ActiveGroup.scrollTop = p.Scroll;
}
if (TargetNode.classList.contains("folder")) {
TabsIdsSelected.forEach(function(tabId){
AppendToNode(document.getElementById(tabId), TargetNode.childNodes[2]);
});
if (p.TargetNode.classList.contains("folder")) {
SelectedTabsAppendTarget = p.TargetNode.childNodes[2];
ActiveGroup.scrollTop = p.Scroll;
}
if (TargetNode.classList.contains("group_button")) { // dropped on group button (group list)
TabsIdsSelected.forEach(function(tabId){
AppendToNode(document.getElementById(tabId), document.getElementById("ct" + (TargetNode.id.substr(1))));
});
if (p.TargetNode.classList.contains("group_button")) { // dropped on group button (group list)
SelectedTabsAppendTarget = document.getElementById("ct" + (p.TargetNode.id.substr(1)));
}
}
if (DragNodeClass == "folder") {
if (TargetNode.classList.contains("folder")) { // dropped on folder
if (TargetNode.classList.contains("before")) {
FoldersSelected.forEach(function(folderId){
InsterBeforeNode(document.getElementById(folderId), TargetNode);
if (p.Class == "folder") {
if (p.TargetNode.classList.contains("folder")) { // dropped on folder
if (p.TargetNode.classList.contains("before")) {
p.FoldersSelected.forEach(function(folderId){
InsterBeforeNode(document.getElementById(folderId), p.TargetNode);
});
}
if (TargetNode.classList.contains("after")) {
for(let i = FoldersSelected.length-1; i >= 0; i--) {
InsterAfterNode(document.getElementById(FoldersSelected[i]), TargetNode);
if (p.TargetNode.classList.contains("after")) {
for(let i = p.FoldersSelected.length-1; i >= 0; i--) {
InsterAfterNode(document.getElementById(p.FoldersSelected[i]), p.TargetNode);
}
}
if (TargetNode.classList.contains("inside")) {
FoldersSelected.forEach(function(folderId){
AppendToNode(document.getElementById(folderId), TargetNode.childNodes[1]);
});
if (p.TargetNode.classList.contains("inside")) {
FoldersSelectedAppendTarget = p.TargetNode.childNodes[1];
}
ActiveGroup.scrollTop = p.Scroll;
}
if (TargetNode.classList.contains("group")) {
FoldersSelected.forEach(function(folderId){
AppendToNode(document.getElementById(folderId), TargetNode.childNodes[0]);
});
if (p.TargetNode.classList.contains("group")) {
FoldersSelectedAppendTarget = p.TargetNode.childNodes[0];
ActiveGroup.scrollTop = p.Scroll;
}
if (TargetNode.classList.contains("group_button")) { // dropped on group button (group list)
FoldersSelected.forEach(function(folderId){
AppendToNode(document.getElementById(folderId), document.getElementById("cf" + TargetNode.id.substr(1)));
});
if (p.TargetNode.classList.contains("group_button")) { // dropped on group button (group list)
FoldersSelectedAppendTarget = document.getElementById("cf" + p.TargetNode.id.substr(1));
}
setTimeout(function() {
@ -463,74 +447,130 @@ function DropToTarget(TargetNode, TabsIdsSelected, TabsIds, TabsIdsParents, Fold
}, 600);
}
if (TargetNode.classList.contains("group_button") && (DragNodeClass == "tab" || DragNodeClass == "folder")) {
if (p.TargetNode.classList.contains("group_button") && (p.Class == "tab" || p.Class == "folder")) {
chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) {
let Tab = document.getElementById(activeTab[0].id);
if (Tab != null && TabsIds.indexOf(activeTab[0].id) != -1) {
SetActiveGroup(TargetNode.id.substr(1), false, false);
if (Tab != null && p.TabsIds.indexOf(activeTab[0].id) != -1) {
SetActiveGroup(p.TargetNode.id.substr(1), false, false);
SetActiveTab(activeTab[0].id, true);
}
});
}
if (DragNodeClass == "group") {
if (TargetNode.classList.contains("before")) {
InsterBeforeNode(document.querySelector(".dragged_group_button"), TargetNode);
if (p.Class == "group") {
if (p.TargetNode.classList.contains("before")) {
InsterBeforeNode(document.getElementById("_"+p.Group.id), p.TargetNode);
}
if (TargetNode.classList.contains("after")) {
InsterAfterNode(document.querySelector(".dragged_group_button"), TargetNode);
if (p.TargetNode.classList.contains("after")) {
InsterAfterNode(document.getElementById("_"+p.Group.id), p.TargetNode);
}
UpdateBgGroupsOrder();
RearrangeGroupsLists();
if (opt.syncro_tabbar_groups_tabs_order) {
schedule_rearrange_tabs++;
tt.schedule_rearrange_tabs++;
}
}
SetMultiTabsClass(TabsIds, pinTabs);
// SetMultiTabsClass(TabsIdsSelected, pinTabs);
if (FoldersSelectedAppendTarget) {
p.FoldersSelected.forEach(function(folderId){
AppendToNode(document.getElementById(folderId), FoldersSelectedAppendTarget);
});
}
if (SelectedTabsAppendTarget) {
p.TabsIdsSelected.forEach(function(tabId){
AppendToNode(document.getElementById(tabId), SelectedTabsAppendTarget);
});
}
// recheck new structure
if (TabsIds.length) {
for (var ind = 0; ind < TabsIds.length; ind++) {
if (TabsIdsSelected.indexOf(TabsIds[ind]) == -1) {
let Tab = document.getElementById(TabsIds[ind]);
let TabParent = document.getElementById(TabsIdsParents[ind]);
if (TabParent != null && TabParent.id != Tab.parentNode.id) {
TabParent.appendChild(Tab);
if (Object.keys(p.Folders).length > 0) {
for (var folderId in p.Folders) {
if (p.FoldersSelected.indexOf(folderId) == -1) {
let Folder = document.getElementById(folderId);
if (Folder != null && Folder.parentNode.id != "cf" + p.Folders[folderId].parent) {
let FolderParent = document.getElementById("cf" + p.Folders[folderId].parent);
if (FolderParent != null) {
FolderParent.appendChild(Folder);
}
}
}
}
}
if (p.TabsIds.length) {
if (pinTabs) {
for (var ind = 0; ind < p.TabsIds.length; ind++) {
let Tab = document.getElementById(p.TabsIds[ind]);
if (Tab != null && Tab.parentNode.id != "pin_list") {
document.getElementById("pin_list").appendChild(Tab);
}
}
} else {
for (var ind = 0; ind < p.TabsIds.length; ind++) {
if (p.TabsIdsSelected.indexOf(p.TabsIds[ind]) == -1) {
let Tab = document.getElementById(p.TabsIds[ind]);
let TabParent = document.getElementById(p.TabsIdsParents[ind]);
if (TabParent != null && Tab != null && TabParent.id != Tab.parentNode.id) {
TabParent.appendChild(Tab);
}
}
}
}
}
if (opt.syncro_tabbar_tabs_order && TabsIds[0] != undefined) {
SetMultiTabsClass(p.TabsIds, pinTabs);
p.TabsIdsSelected.forEach(function(selectedTabId) {
let selectedTab = document.getElementById(selectedTabId);
if (selectedTab != null) {
selectedTab.classList.add("selected_tab");
}
});
if (p.DraggedTabNode) {
let tabNode = document.getElementById(p.DraggedTabNode);
if (tabNode != null) {
tabNode.classList.add("selected_temporarly");
}
}
if (opt.syncro_tabbar_tabs_order && p.TabsIds[0] != undefined) {
let tabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s){
return parseInt(s.id);
});
if (opt.debug) {
log( "f: DropToTarget, will Syncro tabbar tabs order, TabsIds array is:"+JSON.stringify(TabsIds) );
log( "f: DropToTarget, will Syncro tabbar tabs order, TabsIds array is:"+JSON.stringify(p.TabsIds) );
}
chrome.tabs.move(TabsIds, {index: tabIds.indexOf(TabsIds[0])});
chrome.tabs.move(p.TabsIds, {index: tabIds.indexOf(p.TabsIds[0])});
setTimeout(function() {
schedule_rearrange_tabs++;
tt.schedule_rearrange_tabs++;
}, 500);
}
}
KeepOnlyOneActiveTabInGroup();
DragOverTimer = false;
setTimeout(function() {
RefreshExpandStates();
RefreshCounters();
schedule_update_data++;
tt.schedule_update_data++;
RefreshGUI();
EmptyDragAndDrop();
if (opt.debug) {
log("DropToTarget END");
}
}, 300);
}, 500);
setTimeout(function() {
CleanUpDragClasses();
@ -539,6 +579,7 @@ function DropToTarget(TargetNode, TabsIdsSelected, TabsIds, TabsIdsParents, Fold
}
function FreezeSelected() {
document.querySelectorAll(".selected_tab").forEach(function(s){
if (opt.debug) {
@ -584,19 +625,18 @@ function CleanUpDragClasses() {
document.querySelectorAll(".folder_header").forEach(function(s){
s.classList.remove("folder_header_hover");
});
document.querySelectorAll(".dragged_group_button").forEach(function(s){
s.classList.remove("dragged_group_button");
});
document.querySelectorAll(".dragged_tree").forEach(function(s){
s.classList.remove("dragged_tree");
});
document.querySelectorAll(".dragged_parents").forEach(function(s){
s.classList.remove("dragged_parents");
});
}
function EmptyDragAndDrop() {
if (opt.debug) {
log("f: EmptyDragAndDrop, reset DragOverTimer and removing DragNodeClass...");
log("f: EmptyDragAndDrop and removing DragNodeClass...");
}
DragOverTimer = false;
DragNodeClass = "";
DragTreeDepth = 0;
tt.DragNodeClass = "";
tt.DragTreeDepth = 0;
}

View File

@ -2,13 +2,13 @@
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
function AddNewFolder(folderId, ParentId, Name, Index, ExpandState, AdditionalClass, SetEvents) {
var newId = folderId ? folderId : GenerateNewFolderID();
bgfolders[newId] = { id: newId, parent: (ParentId ? ParentId : ""), index: (Index ? Index : 0), name: (Name ? Name : caption_noname_group), expand: (ExpandState ? ExpandState : "") };
function AddNewFolder(p) { // folderId: string, ParentId: string, Name: string, Index: int, ExpandState: ("o","c"), AdditionalClass: string, SetEvents: bool
let newId = p.folderId ? p.folderId : GenerateNewFolderID();
tt.folders[newId] = { id: newId, parent: (p.ParentId ? p.ParentId : ""), index: (p.Index ? p.Index : 0), name: (p.Name ? p.Name : labels.noname_group), expand: (p.ExpandState ? p.ExpandState : "") };
if (opt.debug) {
log("f: AddNewFolder, folder: "+JSON.stringify(bgfolders[newId]));
log("f: AddNewFolder, folder: "+JSON.stringify(tt.folders[newId]));
}
AppendFolder(newId, caption_noname_group, (ParentId ? ParentId : ""), undefined, SetEvents, AdditionalClass);
AppendFolder(newId, labels.noname_group, (p.ParentId ? p.ParentId : ""), undefined, p.SetEvents, p.AdditionalClass);
SaveFolders();
RefreshCounters();
RefreshExpandStates();
@ -17,23 +17,24 @@ function AddNewFolder(folderId, ParentId, Name, Index, ExpandState, AdditionalCl
function AppendFolder(folderId, Name, ParentId, Expand, SetEvents, AdditionalClass) {
if (opt.debug) {
log("f: AppendFolder, folder: "+JSON.stringify(bgfolders[folderId]));
log("f: AppendFolder, folder: "+JSON.stringify(tt.folders[folderId]));
}
let ClassList = "folder ";
if (AdditionalClass != undefined) {
ClassList = ClassList + AdditionalClass;
}
if (document.getElementById(folderId) == null) {
var fd = document.createElement("div"); fd.className = ClassList; if (Expand) { fd.className += Expand } fd.id = folderId; // FOLDER
var fh = document.createElement("div"); fh.className = (opt.always_show_close && !opt.never_show_close) ? "folder_header close_show" : "folder_header"; fh.id = "folder_header"+folderId; if (SetEvents) {fh.draggable = true;} fd.appendChild(fh); // HEADER
var ex = document.createElement("div"); ex.className = "folder_icon"; ex.id = "fop"+folderId; fh.appendChild(ex);
var ft = document.createElement("div"); ft.className = "folder_title"; ft.id = "folder_title"+folderId; ft.textContent = Name; fh.appendChild(ft); // TITLE
var cf = document.createElement("div"); cf.className = "children_folders"; cf.id = "cf"+folderId; fd.appendChild(cf);
var ct = document.createElement("div"); ct.className = "children_tabs"; ct.id = "ct"+folderId; fd.appendChild(ct);
var di = document.createElement("div"); di.className = "drag_indicator"; di.id = "di"+folderId; fd.appendChild(di); // DROP TARGET INDICATOR
let fd = document.createElement("div"); fd.className = ClassList; if (Expand) { fd.className += Expand } fd.id = folderId; // FOLDER
let fh = document.createElement("div"); fh.className = (opt.always_show_close && !opt.never_show_close) ? "folder_header close_show" : "folder_header"; fh.id = "folder_header"+folderId; if (SetEvents) {fh.draggable = true;} fd.appendChild(fh); // HEADER
let ex = document.createElement("div"); ex.className = "folder_icon"; ex.id = "fop"+folderId; fh.appendChild(ex);
let ft = document.createElement("div"); ft.className = "folder_title"; ft.id = "folder_title"+folderId; ft.textContent = Name; fh.appendChild(ft); // TITLE
let cf = document.createElement("div"); cf.className = "children_folders"; cf.id = "cf"+folderId; fd.appendChild(cf);
let ct = document.createElement("div"); ct.className = "children_tabs"; ct.id = "ct"+folderId; fd.appendChild(ct);
let di = document.createElement("div"); di.className = "drag_indicator"; di.id = "di"+folderId; fd.appendChild(di); // DROP TARGET INDICATOR
let cl = undefined;
if (!opt.never_show_close) {
var cl = document.createElement("div"); cl.className = "close"; cl.id = "close"+folderId; fh.appendChild(cl); // CLOSE BUTTON
var ci = document.createElement("div"); ci.className = "close_img"; ci.id = "close_img"+folderId; cl.appendChild(ci);
cl = document.createElement("div"); cl.className = "close"; cl.id = "close"+folderId; fh.appendChild(cl); // CLOSE BUTTON
let ci = document.createElement("div"); ci.className = "close_img"; ci.id = "close_img"+folderId; cl.appendChild(ci);
}
if (SetEvents) {
@ -83,7 +84,7 @@ function AppendFolder(folderId, Name, ParentId, Expand, SetEvents, AdditionalCla
}
}
if (!opt.never_show_close) {
if (!opt.never_show_close && cl) {
cl.onmousedown = function(event) {
event.stopImmediatePropagation();
if (event.which != 3) {
@ -146,18 +147,26 @@ function AppendFolder(folderId, Name, ParentId, Expand, SetEvents, AdditionalCla
this.classList.remove("close_show");
}
}
fh.ondragleave = function(event) {
RemoveHighlight();
}
fh.ondragover = function(event) {
FolderDragOver(this, event);
}
fh.ondragenter = function(event) {
DragOverTimer = false;
setTimeout(function() {
DragOverTimer = true;
}, 1000);
if (opt.open_tree_on_hover && tt.DragOverId != this.id) {
if (this.parentNode.classList.contains("c") && this.parentNode.classList.contains("dragged_tree") == false) {
clearTimeout(tt.DragOverTimer);
tt.DragOverId = this.id;
let This = this;
tt.DragOverTimer = setTimeout(function() {
if (tt.DragOverId == This.id) {
This.parentNode.classList.add("o");
This.parentNode.classList.remove("c");
}
}, 1500);
}
}
}
ex.onmousedown = function(event) {
@ -175,7 +184,7 @@ function AppendFolder(folderId, Name, ParentId, Expand, SetEvents, AdditionalCla
}
}
if (ParentId == "" || ParentId == undefined || document.getElementById("cf"+ParentId) == null) {
document.getElementById("cf"+active_group).appendChild(fd);
document.getElementById("cf"+tt.active_group).appendChild(fd);
} else {
document.getElementById("cf"+ParentId).appendChild(fd);
}
@ -183,22 +192,24 @@ function AppendFolder(folderId, Name, ParentId, Expand, SetEvents, AdditionalCla
}
function GenerateNewFolderID() {
var newID = "f_"+GenerateRandomID();
if (document.getElementById(newID) == null) {
return newID;
} else {
GenerateNewFolderID();
let newID = "";
while (newID == "") {
newID = "f_"+GenerateRandomID();
if (document.getElementById(newID) != null) {
newID = "";
}
}
return newID;
}
function AppendFolders(Folders) {
if (opt.debug) {
log("f: AppendFolders, Folders: "+JSON.stringify(Folders));
}
for (var folderId in Folders) {
for (let folderId in Folders) {
AppendFolder(folderId, Folders[folderId].name, Folders[folderId].parent, Folders[folderId].expand, true, undefined);
}
for (var folderId in Folders) {
for (let folderId in Folders) {
let f = document.getElementById(folderId);
let parent = document.getElementById("cf"+Folders[folderId].parent);
if (f != null && parent != null && Folders[folderId].parent != f.parentNode.parentNode.id) {
@ -209,11 +220,11 @@ function AppendFolders(Folders) {
function SaveFolders() {
document.querySelectorAll(".folder").forEach(function(s){
bgfolders[s.id].parent = s.parentNode.parentNode.id;
bgfolders[s.id].index = Array.from(s.parentNode.children).indexOf(s);
bgfolders[s.id].expand = (s.classList.contains("c") ? "c" : (s.classList.contains("o") ? "o" : ""));
tt.folders[s.id].parent = s.parentNode.parentNode.id;
tt.folders[s.id].index = Array.from(s.parentNode.children).indexOf(s);
tt.folders[s.id].expand = (s.classList.contains("c") ? "c" : (s.classList.contains("o") ? "o" : ""));
});
chrome.runtime.sendMessage({command: "save_folders", folders: bgfolders, windowId: CurrentWindowId});
chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId});
}
function RearrangeFolders(first_loop) {
@ -221,16 +232,16 @@ function RearrangeFolders(first_loop) {
log("f: RearrangeFolders");
}
document.querySelectorAll(".folder").forEach(function(s){
if (bgfolders[s.id] && s.parentNode.childNodes[bgfolders[s.id].index]) {
if (tt.folders[s.id] && s.parentNode.childNodes[tt.folders[s.id].index]) {
let Ind = Array.from(s.parentNode.children).indexOf(s);
if (Ind > bgfolders[s.id].index) {
InsterBeforeNode(s, s.parentNode.childNodes[bgfolders[s.id].index]);
if (Ind > tt.folders[s.id].index) {
InsterBeforeNode(s, s.parentNode.childNodes[tt.folders[s.id].index]);
} else {
InsterAfterNode(s, s.parentNode.childNodes[bgfolders[s.id].index]);
InsterAfterNode(s, s.parentNode.childNodes[tt.folders[s.id].index]);
}
}
let newInd = Array.from(s.parentNode.children).indexOf(s);
if (bgfolders[s.id] && newInd != bgfolders[s.id].index && first_loop) {
if (tt.folders[s.id] && newInd != tt.folders[s.id].index && first_loop) {
RearrangeFolders(false);
}
});
@ -274,34 +285,25 @@ function RemoveFolder(FolderId) {
});
document.querySelectorAll("#"+FolderId+" .folder").forEach(function(s){
delete bgfolders[s.id];
delete tt.folders[s.id];
});
}
folder.parentNode.removeChild(folder);
delete bgfolders[FolderId];
delete tt.folders[FolderId];
RefreshExpandStates();
chrome.runtime.sendMessage({command: "save_folders", folders: bgfolders, windowId: CurrentWindowId});
chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId});
}
}
// function SetActiveFolder(FolderId) {
// let folder = document.getElementById(FolderId);
// if (folder != null) {
// document.querySelectorAll(".selected_folder").forEach(function(s){
// s.classList.remove("selected_folder");
// });
// folder.classList.add("selected_folder");
// }
// }
function ShowRenameFolderDialog(FolderId) { // Rename folder popup
if (opt.debug) {
log("f: ShowRenameFolderDialog, folderId "+FolderId);
}
HideRenameDialogs();
if (bgfolders[FolderId]) {
if (tt.folders[FolderId]) {
let name = document.getElementById("folder_edit_name");
name.value = bgfolders[FolderId].name;
name.value = tt.folders[FolderId].name;
let folderEditDialog = document.getElementById("folder_edit");
folderEditDialog.setAttribute("FolderId", FolderId);
folderEditDialog.style.display = "block";
@ -318,13 +320,13 @@ function FolderRenameConfirm() { // when pressed OK in folder popup
let name = document.getElementById("folder_edit_name");
let FolderId = document.getElementById("folder_edit").getAttribute("FolderId");
// name.value = name.value.replace(/[\f\n\r\v\t\<\>\+\-\(\)\.\,\;\:\~\/\|\?\@\!\"\'\£\$\%\&\^\#\=\*\[\]]?/gi, "");
bgfolders[FolderId].name = name.value;
tt.folders[FolderId].name = name.value;
document.getElementById("folder_title" + FolderId).textContent = name.value;
HideRenameDialogs();
if (opt.debug) {
log("f: FolderRenameConfirm, folderId "+FolderId+", name: "+name.value);
}
chrome.runtime.sendMessage({command: "save_folders", folders: bgfolders, windowId: CurrentWindowId});
chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId});
RefreshCounters();
}
@ -332,7 +334,7 @@ function DeselectFolders() {
if (opt.debug) {
log("f: DeselectFolders");
}
document.querySelectorAll("#"+active_group+" .selected_folder").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .selected_folder").forEach(function(s){
s.classList.remove("selected_folder");
});
}
@ -345,7 +347,8 @@ function ActionClickFolder(FolderNode, bgOption) {
ShowRenameFolderDialog(FolderNode.id);
}
if (bgOption == "new_folder") {
AddNewFolder(undefined, FolderNode.id, undefined, undefined, undefined, undefined, true);
let FolderId = AddNewFolder({ParentId: FolderNode.id, SetEvents: true});
ShowRenameFolderDialog(FolderId);
}
if (bgOption == "new_tab") {
OpenNewTab(false, FolderNode.id);
@ -372,11 +375,11 @@ function FolderStartDrag(Node, event) {
event.stopPropagation();
event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0);
event.dataTransfer.setData("text", "");
event.dataTransfer.setData("SourceWindowId", CurrentWindowId);
event.dataTransfer.setData("SourceWindowId", tt.CurrentWindowId);
CleanUpDragClasses();
EmptyDragAndDrop();
DragNodeClass = "folder";
tt.DragNodeClass = "folder";
let TabsIds = [];
let TabsIdsParents = [];
@ -386,7 +389,7 @@ function FolderStartDrag(Node, event) {
if (Node.parentNode.classList.contains("selected_folder")) {
document.querySelectorAll(".group:not(#"+active_group+") .selected_folder").forEach(function(s){
document.querySelectorAll(".group:not(#"+tt.active_group+") .selected_folder").forEach(function(s){
s.classList.add("selected_folder_frozen");
s.classList.remove("selected_folder");
});
@ -402,15 +405,15 @@ function FolderStartDrag(Node, event) {
s.classList.add("dragged_tree");
});
if (opt.max_tree_drag_drop_folders) {
if (opt.max_tree_drag_drop_folders || opt.max_tree_depth >= 0) {
document.querySelectorAll(".dragged_tree .folder").forEach(function(s){
let parents = GetParentsByClass(s.parentNode, "dragged_tree");
if (parents.length > DragTreeDepth) {
DragTreeDepth = parents.length;
if (parents.length > tt.DragTreeDepth) {
tt.DragTreeDepth = parents.length;
}
});
} else {
DragTreeDepth = -1;
tt.DragTreeDepth = -1;
}
// REST OF SELECTED FOLDERS+TABS THAT WILL BE DRAGGED
@ -418,12 +421,12 @@ function FolderStartDrag(Node, event) {
s.classList.add("dragged_tree");
});
document.querySelectorAll("#"+active_group+" .selected_folder").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .selected_folder").forEach(function(s){
FoldersSelected.push(s.id);
Folders[s.id] = Object.assign({}, bgfolders[s.id]);
Folders[s.id] = Object.assign({}, tt.folders[s.id]);
let Fchildren = document.querySelectorAll("#cf"+s.id+" .folder");
Fchildren.forEach(function(fc){
Folders[fc.id] = Folders[fc.id] = Object.assign({}, bgfolders[fc.id]);
Folders[fc.id] = Folders[fc.id] = Object.assign({}, tt.folders[fc.id]);
});
let Tchildren = document.querySelectorAll("#ct"+s.id+" .tab");
Tchildren.forEach(function(tc){
@ -431,17 +434,24 @@ function FolderStartDrag(Node, event) {
TabsIdsParents.push(tc.parentNode.id);
});
});
let DraggedFolderParents = GetParentsByClass(Node, "folder");
DraggedFolderParents.forEach(function(s){
s.classList.add("dragged_parents");
});
event.dataTransfer.setData("Class", "folder");
event.dataTransfer.setData("TabsIds", JSON.stringify(TabsIds));
event.dataTransfer.setData("TabsIdsParents", JSON.stringify(TabsIdsParents));
event.dataTransfer.setData("Folders", JSON.stringify(TabsIds));
event.dataTransfer.setData("Folders", JSON.stringify(Folders));
event.dataTransfer.setData("FoldersSelected", JSON.stringify(FoldersSelected));
chrome.runtime.sendMessage({
command: "drag_drop",
DragNodeClass: "folder",
DragTreeDepth: DragTreeDepth
DragTreeDepth: tt.DragTreeDepth
});
}
@ -451,10 +461,11 @@ function FolderDragOver(Node, event) {
}
if (Node.parentNode.classList.contains("dragged_tree") == false) {
let P = (GetParentsByClass(Node, "folder")).length + DragTreeDepth;
let PGroup = Node.parentNode.parentNode.parentNode.classList.contains("group");
let PDepth = (GetParentsByClass(Node, "folder")).length + tt.DragTreeDepth;
let PIsGroup = Node.parentNode.parentNode.parentNode.classList.contains("group");
let PIsDraggedParents = Node.parentNode.classList.contains("dragged_parents");
if (DragNodeClass == "folder" && Node.parentNode.classList.contains("before") == false && event.layerY < Node.clientHeight/3 && (P <= opt.max_tree_depth+1 || opt.max_tree_depth<0 || PGroup || opt.max_tree_drag_drop_folders == false)) {
if (tt.DragNodeClass == "folder" && Node.parentNode.classList.contains("before") == false && event.layerY < Node.clientHeight/3 && (PDepth <= opt.max_tree_depth+1 || opt.max_tree_depth < 0 || PIsGroup || PIsDraggedParents || opt.max_tree_drag_drop_folders == false)) {
RemoveHighlight();
Node.parentNode.classList.remove("inside");
Node.parentNode.classList.remove("after");
@ -462,7 +473,7 @@ function FolderDragOver(Node, event) {
Node.parentNode.classList.add("highlighted_drop_target");
}
if (DragNodeClass == "folder" && Node.parentNode.classList.contains("inside") == false && event.layerY > Node.clientHeight/3 && event.layerY <= 2*(Node.clientHeight/3) && (P <= opt.max_tree_depth || opt.max_tree_depth<0 || opt.max_tree_drag_drop_folders == false)) {
if (tt.DragNodeClass == "folder" && Node.parentNode.classList.contains("inside") == false && event.layerY > Node.clientHeight/3 && event.layerY <= 2*(Node.clientHeight/3) && (PDepth <= opt.max_tree_depth || opt.max_tree_depth < 0 || PIsDraggedParents || opt.max_tree_drag_drop_folders == false)) {
RemoveHighlight();
Node.parentNode.classList.remove("before");
Node.parentNode.classList.remove("after");
@ -470,7 +481,7 @@ function FolderDragOver(Node, event) {
Node.parentNode.classList.add("highlighted_drop_target");
}
if (DragNodeClass == "folder" && Node.parentNode.classList.contains("after") == false && Node.parentNode.classList.contains("o") == false && event.layerY > 2*(Node.clientHeight/3) && (P <= opt.max_tree_depth+1 || opt.max_tree_depth<0 || PGroup || opt.max_tree_drag_drop_folders == false)) {
if (tt.DragNodeClass == "folder" && Node.parentNode.classList.contains("after") == false && Node.parentNode.classList.contains("o") == false && event.layerY > 2*(Node.clientHeight/3) && (PDepth <= opt.max_tree_depth+1 || opt.max_tree_depth < 0 || PIsGroup || PIsDraggedParents || opt.max_tree_drag_drop_folders == false)) {
RemoveHighlight();
Node.parentNode.classList.remove("inside");
Node.parentNode.classList.remove("before");
@ -478,7 +489,7 @@ function FolderDragOver(Node, event) {
Node.parentNode.classList.add("highlighted_drop_target");
}
if (DragNodeClass == "tab" && Node.parentNode.classList.contains("inside") == false && (P <= opt.max_tree_depth || opt.max_tree_depth<0 || opt.max_tree_drag_drop_folders == false)) {
if (tt.DragNodeClass == "tab" && Node.parentNode.classList.contains("inside") == false && (PDepth <= opt.max_tree_depth || opt.max_tree_depth < 0 || PIsDraggedParents || opt.max_tree_drag_drop_folders == false)) {
RemoveHighlight();
Node.parentNode.classList.remove("before");
Node.parentNode.classList.remove("after");

View File

@ -1,201 +0,0 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
// ********** GLOBAL VARIABLES FOR BACKGROUND, OPTIONS AND SIDEBAR ***************
// BACKGROUND VARIABLES
let debug = [];
var running = false;
var schedule_save = -999;
var windows = {};
var tabs = {};
var tt_ids = {};
// SIDEBAR VARIABLES
var AutoSaveSession;
var schedule_update_data = 0;
var schedule_rearrange_tabs = 0;
var DragNodeClass = "";
var DragOverTimer = true;
var DragTreeDepth = 0;
var menuItemNode;
var CurrentWindowId = 0;
var SearchIndex = 0;
var active_group = "tab_list";
var opt = {};
var browserId = navigator.userAgent.match("Opera|OPR") !== null ? "O" : ( navigator.userAgent.match("Vivaldi") !== null ? "V" : (navigator.userAgent.match("Firefox") !== null ? "F" : "C" ) );
var newTabUrl = browserId == "F" ? "about:newtab" : "chrome://startpage/";
var EmptyTabs = [];
var bggroups = {};
var bgfolders = {};
var caption_clear_filter = chrome.i18n.getMessage("caption_clear_filter");
var caption_loading = chrome.i18n.getMessage("caption_loading");
var caption_searchbox = chrome.i18n.getMessage("caption_searchbox");
var caption_ungrouped_group = chrome.i18n.getMessage("caption_ungrouped_group");
var caption_noname_group = chrome.i18n.getMessage("caption_noname_group");
// DEFAULTS NEEDED FOR START AND FOR OPTIONS PAGE
const DefaultToolbar = {
"toolbar_main": ["button_new", "button_pin", "button_undo", "button_search", "button_tools", "button_groups", "button_backup", "button_folders"],
"toolbar_search": ["button_filter_type", "filter_search_go_prev", "filter_search_go_next"],
"toolbar_shelf_tools": (browserId == "F" ? ["button_manager_window", "button_options", "button_unload", "button_detach", "button_reboot"] : ["button_manager_window", "button_options", "button_bookmarks", "button_downloads", "button_history", "button_settings", "button_extensions", "button_unload", "button_detach", "button_reboot"]),
"toolbar_shelf_groups": ["button_groups_toolbar_hide", "button_new_group", "button_remove_group", "button_edit_group", "button_import_group", "button_export_group"],
"toolbar_shelf_backup": (browserId == "F" ? ["button_import_bak", "button_import_merge_bak", "button_export_bak"] : ["button_import_bak", "button_import_merge_bak", "button_export_bak", "button_load_bak1", "button_load_bak2", "button_load_bak3"]),
"toolbar_shelf_folders": ["button_new_folder", "button_remove_folder", "button_edit_folder"]
};
const DefaultTheme = {
"ToolbarShow": true,
"ColorsSet": {},
"TabsSizeSetNumber": 2,
"TabsMargins": "2",
"theme_name": "untitled",
"theme_version": 4,
};
const DefaultPreferences = {
"hide_other_groups_tabs_firefox": false,
"show_toolbar": true,
"skip_load": false,
"pin_list_multi_row": true,
"always_show_close": false,
"never_show_close": false,
"allow_pin_close": false,
"append_child_tab": "bottom",
"append_child_tab_after_limit": "after",
"append_orphan_tab": "bottom",
"after_closing_active_tab": "below_seek_in_parent",
"collapse_other_trees": false,
"open_tree_on_hover": true,
"promote_children": true,
"promote_children_in_first_child": true,
"max_tree_depth": -1,
// "max_tree_depth_folders": 0,
"max_tree_drag_drop": true,
"max_tree_drag_drop_folders": false,
"switch_with_scroll": false,
"syncro_tabbar_tabs_order": true,
"show_counter_groups": true,
"show_counter_tabs": true,
"show_counter_tabs_hints": true,
"groups_toolbar_default": true,
"syncro_tabbar_groups_tabs_order": true,
"midclick_tab": "close_tab",
"dbclick_tab": "new_tab",
"dbclick_group": "new_tab",
"midclick_group": "nothing",
"midclick_folder": "nothing",
"dbclick_folder": "rename_folder",
"debug": false,
"orphaned_tabs_to_ungrouped": false,
"tab_group_regexes": [],
"move_tabs_on_url_change": "never",
"autosave_max_to_keep": 5,
"autosave_interval": 15
};
// ******************* GLOBAL FUNCTIONS ************************
// generate random id
function GenerateRandomID(){
var letters = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","K","L","M","N","O","P","R","S","T","Q","U","V","W","Y","Z","a","b","c","d","e","f","g","h","i","k","l","m","n","o","p","r","s","t","q","u","v","w","y","z"];
var random = ""; for (var letter = 0; letter < 6; letter++ ) {random += letters[Math.floor(Math.random() * letters.length)];} return random;
}
function GetCurrentPreferences(storage) {
opt = Object.assign({}, DefaultPreferences);
if (storage["preferences"]) {
for (var parameter in storage["preferences"]) {
if (opt[parameter] != undefined) {
opt[parameter] = storage["preferences"][parameter];
}
}
}
}
function LoadDefaultPreferences() {
opt = Object.assign({}, DefaultPreferences);
}
function GetCurrentTheme(storage) {
if (storage["current_theme"] && storage["themes"] && storage["themes"][storage["current_theme"]]) {
let theme = storage["themes"][storage["current_theme"]];
let correctedTheme = CheckTheme(theme);
if (correctedTheme.theme_version < 4 && storage["preferences"].show_toolbar == undefined) {
opt.show_toolbar = correctedTheme.ToolbarShow;
SavePreferences();
}
return correctedTheme;
} else {
return DefaultTheme;
}
}
function GetCurrentToolbar(storage) {
if (storage["toolbar"]) {
return storage["toolbar"];
} else {
return DefaultToolbar;
}
}
function SavePreferences() {
chrome.storage.local.set({preferences: opt});
chrome.runtime.sendMessage({command: "reload_options", opt: opt});
}
function ShowOpenFileDialog(extension) {
let body = document.getElementById("body");
let inp = document.createElement("input");
inp.id = "file_import";
inp.type = "file";
inp.accept = extension;
inp.style.display = "none";
body.appendChild(inp);
setTimeout(function() {
inp.click();
}, 10);
return inp;
}
function SaveFile(filename, extension, data) {
let file = new File([JSON.stringify(data)], filename+"."+extension, {type: "text/"+extension+";charset=utf-8"} );
let body = document.getElementById("body");
let savelink = document.createElement("a");
savelink.href = URL.createObjectURL(file);
savelink.fileSize = file.size;
savelink.target = "_blank";
savelink.style.display = "none";
savelink.type = "file";
savelink.download = filename+"."+extension;
body.appendChild(savelink);
setTimeout(function() {
savelink.click();
setTimeout(function() {
savelink.parentNode.removeChild(savelink);
}, 60000);
}, 10);
}
function log(log) {
if (opt.debug) {
chrome.runtime.sendMessage({command: "debug", log: log});
}
}
function pushlog(log) {
debug.push(log);
if (debug.length > 100) {
debug.splice(0, 1);
}
console.log(log);
schedule_save++;
}

View File

@ -5,18 +5,14 @@
// ********** GROUPS FUNCTIONS ***************
function SaveGroups() {
chrome.runtime.sendMessage({command: "save_groups", groups: bggroups, windowId: CurrentWindowId});
chrome.runtime.sendMessage({command: "save_groups", groups: tt.groups, windowId: tt.CurrentWindowId});
}
function AppendGroups(Groups) {
if (opt.debug) {
log("f: AppendGroups, Groups: "+JSON.stringify(Groups));
}
// let GroupList = document.getElementById("group_list");
// let scroll = GroupList.scrollTop;
AppendGroupToList("tab_list", caption_ungrouped_group, "", true);
AppendGroupToList("tab_list", labels.ungrouped_group, "", true);
for (var group in Groups) {
AppendGroupToList(Groups[group].id, Groups[group].name, Groups[group].font, true);
if (document.querySelectorAll(".group").length == Object.keys(Groups).length) {
@ -34,16 +30,16 @@ function RearrangeGroupsButtons(first_loop) {
}
document.querySelectorAll(".group_button").forEach(function(s){
let groupId = (s.id).substr(1);
if (bggroups[groupId]) {
if (s.parentNode.childNodes[bggroups[groupId].index] != undefined) {
if (tt.groups[groupId]) {
if (s.parentNode.childNodes[tt.groups[groupId].index] != undefined) {
let Ind = Array.from(s.parentNode.children).indexOf(s);
if (Ind > bggroups[groupId].index) {
InsterBeforeNode(s, s.parentNode.childNodes[bggroups[groupId].index]);
if (Ind > tt.groups[groupId].index) {
InsterBeforeNode(s, s.parentNode.childNodes[tt.groups[groupId].index]);
} else {
InsterAfterNode(s, s.parentNode.childNodes[bggroups[groupId].index]);
InsterAfterNode(s, s.parentNode.childNodes[tt.groups[groupId].index]);
}
let newInd = Array.from(s.parentNode.children).indexOf(s);
if (newInd != bggroups[groupId].index && first_loop) {
if (newInd != tt.groups[groupId].index && first_loop) {
RearrangeGroupsButtons(false);
}
}
@ -55,7 +51,7 @@ function RearrangeGroupsLists() {
if (opt.debug) {
log("f: RearrangeGroupsLists");
}
let activegroup = document.getElementById(active_group);
let activegroup = document.getElementById(tt.active_group);
let scroll = activegroup.scrollTop;
let groups = document.getElementById("groups");
document.querySelectorAll(".group_button").forEach(function(s){
@ -98,7 +94,7 @@ function AppendGroupToList(groupId, group_name, font_color, SetEvents) {
}
if (browserId == "V") {
chrome.windows.getCurrent({populate: false}, function(window) {
if (CurrentWindowId != window.id) {
if (tt.CurrentWindowId != window.id && window.focused) {
location.reload();
}
});
@ -106,11 +102,19 @@ function AppendGroupToList(groupId, group_name, font_color, SetEvents) {
}
grp.ondragover = function(event) {
// PIN,TAB==>GROUP
if (event.target.id == this.id && (DragNodeClass == "tab" || DragNodeClass == "folder")) {
if (event.target.id == this.id && (tt.DragNodeClass == "tab" || tt.DragNodeClass == "folder")) {
RemoveHighlight();
this.classList.add("highlighted_drop_target");
}
// tt.DragOverId = this.id;
}
// grp.ondragenter = function(event) {
// console.log("clearTimeout");
// if (opt.open_tree_on_hover) {
// clearTimeout(tt.DragOverTimer);
// }
// }
// DOUBLE CLICK ACTION
grp.ondblclick = function(event) {
if (event.target.id == this.id) {
@ -146,7 +150,6 @@ function AppendGroupToList(groupId, group_name, font_color, SetEvents) {
// SHOW GROUP MENU
gbn.onmousedown = function(event) {
// event.stopImmediatePropagation();
if (event.which == 3) {
ShowFGroupMenu(document.getElementById(this.id.substr(1)), event);
}
@ -161,101 +164,59 @@ function AppendGroupToList(groupId, group_name, font_color, SetEvents) {
// DRAGGING GROUPS
gbn.ondragstart = function(event) { // DRAG START
event.stopPropagation();
event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0);
event.dataTransfer.setData("text", "");
event.dataTransfer.setData("SourceWindowId", CurrentWindowId);
CleanUpDragClasses();
EmptyDragAndDrop();
DragNodeClass = "group";
this.classList.add("dragged_group_button");
GroupStartDrag(this, event);
}
gbn.ondragover = function(event) {
GroupButtonDragOver(this, event);
}
// scroll groups
// $(document).on("mousedown", "#scroll_group_up, #scroll_group_down", function(event) {
// IOKeys.LMB = true;
// ScrollGroupList($(this).is("#scroll_group_up"));
// });
// $(document).on("mouseleave", "#scroll_group_up, #scroll_group_down", function(event) {
// IOKeys.LMB = false;
// });
gbn.ondragenter = function(event) {
// console.log("gbn.ondragenter");
if (opt.open_tree_on_hover) {
if (this.classList.contains("active") == false && tt.DragNodeClass != "group") {
clearTimeout(tt.DragOverTimer);
let This = this;
tt.DragOverTimer = setTimeout(function() {
SetActiveGroup(This.id.substr(1), false, false);
}, 1500);
}
}
}
// gbn.ondragleave = function(event) {
// console.log("gbn.ondragleave");
// if (opt.open_tree_on_hover) {
// clearTimeout(tt.DragOverTimer);
// }
// }
}
}
RefreshGUI();
}
function GenerateNewGroupID(){
let newID = "g_"+GenerateRandomID();
if (document.getElementById(newID) == null) {
return newID;
} else {
GenerateNewGroupID();
let newID = "";
while (newID == "") {
newID = "g_"+GenerateRandomID();
if (document.getElementById(newID) != null) {
newID = "";
}
}
return newID;
}
function AddNewGroup(Name, FontColor) {
let newId = GenerateNewGroupID();
bggroups[newId] = { id: newId, index: 0, active_tab: 0, prev_active_tab: 0, active_tab_ttid: "", name: (Name ? Name : caption_noname_group), font: (FontColor ? FontColor : "") };
tt.groups[newId] = { id: newId, index: 0, active_tab: 0, prev_active_tab: 0, active_tab_ttid: "", name: (Name ? Name : labels.noname_group), font: (FontColor ? FontColor : "") };
if (opt.debug) {
log("f: AddNewGroup, groupId: "+newId+", Name: "+Name+", FontColor: "+FontColor);
}
AppendGroupToList(newId, bggroups[newId].name, bggroups[newId].font, true);
AppendGroupToList(newId, tt.groups[newId].name, tt.groups[newId].font, true);
UpdateBgGroupsOrder();
return newId;
}
function FindGroupIdByName(name) {
if (opt.debug) {
log("f: FindGroupIdByName: "+name);
}
for (let key in bggroups) {
if (!bggroups.hasOwnProperty(key)) {
continue;
}
if (bggroups[key].name === name) {
return key;
}
}
return null;
}
function AppendTabToGroupOnRegexMatch(tabId, url) {
if (opt.debug) {
log("f: AppendTabToGroupOnRegexMatch, tabId: "+tabId+", url: "+url);
}
let Tab = document.getElementById(tabId);
if (Tab != null && Tab.classList.contains("tab")) {
let TabGroup = GetParentsByClass(Tab, "group");
for (let i = 0; i < opt.tab_group_regexes.length; i++) {
let regexPair = opt.tab_group_regexes[i];
if (url.match(regexPair[0])) {
let groupId = FindGroupIdByName(regexPair[1]);
if (groupId === null) {
groupId = AddNewGroup(regexPair[1]);
}
if (TabGroup.length > 0 && TabGroup[0].id !== groupId) {
let newParent = document.getElementById("ct" + groupId);
newParent.appendChild(Tab);
SetActiveGroup(groupId, true, true);
SetActiveTabInGroup(groupId, Tab.id);
chrome.tabs.update(tabId, { active: true });
}
break;
}
}
}
}
// remove group, delete tabs if close_tabs is true
function GroupRemove(groupId, close_tabs) {
if (close_tabs) {
@ -269,20 +230,24 @@ function GroupRemove(groupId, close_tabs) {
} else {
let TabListFolders = document.getElementById("cftab_list");
let GroupFolders = document.getElementById("cf"+groupId);
while (GroupFolders.firstChild) {
TabListFolders.appendChild(GroupFolders.firstChild);
if (GroupFolders != null) {
while (GroupFolders.firstChild) {
TabListFolders.appendChild(GroupFolders.firstChild);
}
}
let TabListTabs = document.getElementById("cttab_list");
let GroupTabs = document.getElementById("ct"+groupId);
while (GroupTabs.firstChild) {
TabListTabs.appendChild(GroupTabs.firstChild);
if (GroupTabs != null) {
while (GroupTabs.firstChild) {
TabListTabs.appendChild(GroupTabs.firstChild);
}
}
RefreshExpandStates();
RefreshCounters();
}
if (groupId != "tab_list") {
delete bggroups[groupId];
if (groupId == active_group) {
delete tt.groups[groupId];
if (groupId == tt.active_group) {
if (document.getElementById("_"+groupId).previousSibling) {
SetActiveGroup((document.getElementById("_"+groupId).previousSibling.id).substr(1), true, true);
} else {
@ -294,30 +259,43 @@ function GroupRemove(groupId, close_tabs) {
}
}
let group = document.getElementById(groupId);
group.parentNode.removeChild(group);
if (group != null) {
group.parentNode.removeChild(group);
}
let groupButton = document.getElementById("_"+groupId);
groupButton.parentNode.removeChild(groupButton);
if (groupButton != null) {
groupButton.parentNode.removeChild(groupButton);
}
}
SaveGroups();
schedule_update_data++;
tt.schedule_update_data++;
}
function UpdateBgGroupsOrder() {
document.querySelectorAll(".group_button").forEach(function(s){
if (bggroups[(s.id).substr(1)]) {
bggroups[(s.id).substr(1)].index = Array.from(s.parentNode.children).indexOf(s);
if (tt.groups[(s.id).substr(1)]) {
tt.groups[(s.id).substr(1)].index = Array.from(s.parentNode.children).indexOf(s);
}
});
SaveGroups();
}
function KeepOnlyOneActiveTabInGroup() {
let active_tabs = document.querySelectorAll("#"+tt.active_group+" .active_tab");
if (active_tabs.length > 1) {
chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) {
SetActiveTab(activeTab[0].id, false);
});
}
}
function SetActiveGroup(groupId, switch_to_active_in_group, scroll_to_active) {
if (opt.debug) {
log("f: SetActiveGroup, groupId: "+groupId+", switch_to_active_in_group: "+switch_to_active_in_group+", scroll_to_active: "+scroll_to_active);
}
let group = document.getElementById(groupId);
if (group != null) {
active_group = groupId;
tt.active_group = groupId;
document.querySelectorAll(".group_button").forEach(function(s){
s.classList.remove("active_group");
});
@ -336,6 +314,7 @@ function SetActiveGroup(groupId, switch_to_active_in_group, scroll_to_active) {
if (scroll_to_active){
ScrollToTab(activeTab.id);
}
KeepOnlyOneActiveTabInGroup();
}
if (groupId == "tab_list") {
document.querySelectorAll("#button_remove_group, #button_edit_group").forEach(function(s){
@ -346,7 +325,7 @@ function SetActiveGroup(groupId, switch_to_active_in_group, scroll_to_active) {
s.classList.remove("disabled");
});
}
chrome.runtime.sendMessage({command: "set_active_group", active_group: groupId, windowId: CurrentWindowId});
chrome.runtime.sendMessage({command: "set_active_group", active_group: groupId, windowId: tt.CurrentWindowId});
RefreshExpandStates();
RefreshCounters();
@ -361,19 +340,17 @@ function SetActiveGroup(groupId, switch_to_active_in_group, scroll_to_active) {
browser.tabs.hide(HideTabIds);
browser.tabs.show(ShowTabIds);
}
}
}
function SetActiveTabInGroup(groupId, tabId) {
if (document.querySelector("#"+groupId+" [id='"+tabId+"']") != null && bggroups[groupId] != undefined) {
if (groupId != active_group) {
if (document.querySelector("#"+groupId+" [id='"+tabId+"']") != null && tt.groups[groupId] != undefined) {
if (groupId != tt.active_group) {
SetActiveGroup(groupId, false, true);
}
if (bggroups[groupId]) {
bggroups[groupId].prev_active_tab = bggroups[groupId].active_tab;
bggroups[groupId].active_tab = parseInt(tabId);
if (tt.groups[groupId]) {
tt.groups[groupId].prev_active_tab = tt.groups[groupId].active_tab;
tt.groups[groupId].active_tab = parseInt(tabId);
}
SaveGroups();
}
@ -382,9 +359,9 @@ function SetActiveTabInGroup(groupId, tabId) {
// Edit group popup
function ShowGroupEditWindow(groupId) {
HideRenameDialogs();
if (bggroups[groupId]) {
if (tt.groups[groupId]) {
let name = document.getElementById("group_edit_name");
name.value = bggroups[groupId].name;
name.value = tt.groups[groupId].name;
let groupEditDialog = document.getElementById("group_edit");
groupEditDialog.setAttribute("groupId", groupId);
groupEditDialog.style.display = "block";
@ -393,7 +370,7 @@ function ShowGroupEditWindow(groupId) {
groupEditDialog.style.left = "";
let DefaultGroupButtonFontColor = window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color");
let GroupEditFont = document.getElementById("group_edit_font");
GroupEditFont.style.backgroundColor = (bggroups[groupId].font == "" ? DefaultGroupButtonFontColor : "#"+bggroups[groupId].font);
GroupEditFont.style.backgroundColor = (tt.groups[groupId].font == "" ? DefaultGroupButtonFontColor : "#"+tt.groups[groupId].font);
setTimeout(function(){
document.getElementById("group_edit_name").select();
},5);
@ -403,15 +380,15 @@ function ShowGroupEditWindow(groupId) {
// when pressed OK in group popup
function GroupEditConfirm() {
let groupId = document.getElementById("group_edit").getAttribute("groupId");
if (bggroups[groupId]) {
if (tt.groups[groupId]) {
let GroupEditName = document.getElementById("group_edit_name");
// GroupEditName.value = GroupEditName.value.replace(/[\f\n\r\v\t\<\>\+\-\(\)\.\,\;\:\~\/\|\?\@\!\"\'\£\$\%\&\^\#\=\*\[\]]?/gi, "");
bggroups[groupId].name = GroupEditName.value;
tt.groups[groupId].name = GroupEditName.value;
let GroupEditFont = document.getElementById("group_edit_font");
let DefaultGroupButtonFontColor = window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color");
let ThisGroupButtonFontColor = RGBtoHex(GroupEditFont.style.backgroundColor);
if ("#"+ThisGroupButtonFontColor != DefaultGroupButtonFontColor) {
bggroups[groupId].font = ThisGroupButtonFontColor;
tt.groups[groupId].font = ThisGroupButtonFontColor;
document.getElementById("_gte"+groupId).style.color = "#"+ThisGroupButtonFontColor;
}
HideRenameDialogs();
@ -421,7 +398,7 @@ function GroupEditConfirm() {
}
function RestoreStateOfGroupsToolbar() {
chrome.runtime.sendMessage({command: "get_group_bar", windowId: CurrentWindowId}, function(response) {
chrome.runtime.sendMessage({command: "get_group_bar", windowId: tt.CurrentWindowId}, function(response) {
let toolbarGroups = document.getElementById("toolbar_groups");
if (response == true) {
toolbarGroups.style.display = "inline-block";
@ -444,12 +421,12 @@ function GroupsToolbarToggle() {
toolbarGroups.style.display = "none";
toolbarGroups.style.width = "0px";
toolbarGroups.style.borderRight = "none";
chrome.runtime.sendMessage({command: "set_group_bar", group_bar: false, windowId: CurrentWindowId});
chrome.runtime.sendMessage({command: "set_group_bar", group_bar: false, windowId: tt.CurrentWindowId});
} else {
toolbarGroups.style.display = "inline-block";
toolbarGroups.style.width = "19px";
toolbarGroups.style.borderRight = "1px solid var(--group_list_borders)";
chrome.runtime.sendMessage({command: "set_group_bar", group_bar: true, windowId: CurrentWindowId});
chrome.runtime.sendMessage({command: "set_group_bar", group_bar: true, windowId: tt.CurrentWindowId});
}
RefreshGUI();
}
@ -464,7 +441,7 @@ function ActionClickGroup(Node, bgOption) {
}
}
if (bgOption == "activate_previous_active") {
chrome.tabs.update(parseInt(bggroups[active_group].prev_active_tab), {active: true});
chrome.tabs.update(parseInt(tt.groups[tt.active_group].prev_active_tab), {active: true});
}
if (bgOption == "undo_close_tab") {
chrome.sessions.getRecentlyClosed( null, function(sessions) {
@ -481,33 +458,46 @@ function ActionClickGroup(Node, bgOption) {
// SET ACTIVE TAB FOR EACH GROUP
function SetActiveTabInEachGroup() {
chrome.tabs.query({currentWindow: true, active: true}, function(tabs) {
SetActiveTab(tabs[0].id);
chrome.runtime.sendMessage({command: "get_active_group", windowId: CurrentWindowId}, function(response) {
if (response) {
SetActiveGroup(response, false, true);
for (var group in bggroups) {
let ActiveInGroup = document.querySelector("#"+group+" [id='"+bggroups[group].active_tab+"']");
if (ActiveInGroup != null) {
ActiveInGroup.classList.add("active_tab");
if (tabs.length) {
SetActiveTab(tabs[0].id);
chrome.runtime.sendMessage({command: "get_active_group", windowId: tt.CurrentWindowId}, function(response) {
if (response) {
SetActiveGroup(response, false, true);
for (var group in tt.groups) {
let ActiveInGroup = document.querySelector("#"+group+" [id='"+tt.groups[group].active_tab+"']");
if (ActiveInGroup != null) {
ActiveInGroup.classList.add("active_tab");
}
}
}
if (tabs[0].pinned) {
let ActiveTabinActiveGroup = document.querySelectorAll("#"+active_group+" .active_tab");
if (ActiveTabinActiveGroup != null) {
ActiveTabinActiveGroup.forEach(function(s){
s.classList.remove("active_tab");
});
if (tabs[0].pinned) {
let ActiveTabinActiveGroup = document.querySelectorAll("#"+tt.active_group+" .active_tab");
if (ActiveTabinActiveGroup != null) {
ActiveTabinActiveGroup.forEach(function(s){
s.classList.remove("active_tab");
});
}
}
} else {
SetActiveGroup("tab_list", false, true);
}
} else {
SetActiveGroup("tab_list", false, true);
}
});
});
}
});
}
// function ActionClickGroup(GroupNode, bgOption) {
// if (opt.debug) {
// log("f: ActionClickGroup, GroupId "+GroupNode.id+", bgOption: "+bgOption);
// }
// if (bgOption == "rename_folder") {
// ShowRenameFolderDialog(FolderNode.id);
// }
// }
function GroupButtonDragOver(Node, event) {
if (Node.classList.contains("inside") == false && (DragNodeClass == "tab" || DragNodeClass == "folder")) {
if (Node.classList.contains("inside") == false && (tt.DragNodeClass == "tab" || tt.DragNodeClass == "folder")) {
RemoveHighlight();
Node.classList.remove("before");
Node.classList.remove("after");
@ -515,7 +505,7 @@ function GroupButtonDragOver(Node, event) {
Node.classList.add("highlighted_drop_target");
}
if (Node.classList.contains("before") == false && event.layerY < Node.clientHeight/2 && DragNodeClass == "group") {
if (Node.classList.contains("before") == false && event.layerY < Node.clientHeight/2 && tt.DragNodeClass == "group") {
RemoveHighlight();
Node.classList.add("before");
Node.classList.remove("after");
@ -523,7 +513,7 @@ function GroupButtonDragOver(Node, event) {
Node.classList.add("highlighted_drop_target");
}
if (Node.classList.contains("after") == false && event.layerY > Node.clientHeight/2 && DragNodeClass == "group") {
if (Node.classList.contains("after") == false && event.layerY > Node.clientHeight/2 && tt.DragNodeClass == "group") {
RemoveHighlight();
Node.classList.remove("before");
Node.classList.add("after");
@ -532,52 +522,53 @@ function GroupButtonDragOver(Node, event) {
}
}
function GroupStartDrag(Node, event) {
if (opt.debug) {
log("f: GroupStartDrag, GroupId "+Node.id);
}
event.stopPropagation();
event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0);
event.dataTransfer.setData("text", "");
event.dataTransfer.setData("SourceWindowId", tt.CurrentWindowId);
CleanUpDragClasses();
EmptyDragAndDrop();
tt.DragNodeClass = "group";
let Group = Object.assign({}, tt.groups[Node.id.substr(1)]);
let TabsIds = [];
let TabsIdsParents = [];
let Folders = {};
// function AppendTabsToGroup(p) {
// }
document.querySelectorAll("#"+Node.id.substr(1)+" .tab").forEach(function(s){
TabsIds.push(parseInt(s.id));
TabsIdsParents.push(s.parentNode.id);
});
// direction == true goes up, false goes down
// function ScrollGroupList(direction) {
// if (direction) {
// $("#group_list").scrollTop($("#group_list").scrollTop()-3);
// }
// if (!direction) {
// $("#group_list").scrollTop($("#group_list").scrollTop()+3);
// }
// if (IOKeys.LMB) {
// setTimeout(function() { ScrollGroupList(direction); },10);
// }
// }
document.querySelectorAll("#"+Node.id.substr(1)+" .folder").forEach(function(s){
Folders[s.id] = Object.assign({}, tt.folders[s.id]);
});
// function ScrollToGroup(groupId) {
// if ($("#"+groupId).offset().top-$("#group_list").offset().top < 1) {
// $("#group_list").scrollTop($("#group_list").scrollTop()+$("#"+groupId).offset().top-$("#group_list").offset().top-1);
// } else {
// if ($("#"+groupId).offset().top+$("#"+groupId).outerHeight()+1 > $("#group_list").offset().top+$("#group_list").innerHeight()) {
// $("#group_list").scrollTop($("#group_list").scrollTop()+$("#"+groupId).offset().top-$("#group_list").offset().top-$("#group_list").innerHeight()+$("#"+groupId).outerHeight()-1);
// }
// }
// }
// console.log(Group);
// console.log(TabsIds);
// console.log(TabsIdsParents);
// console.log(Folders);
// let Group = document.getElementById(Node.id.substr(1));
// "Move to group" popup
// function ShowMoveToGroupWindow(x, y) {
// $(".move_to_group_menu_entry").remove();
// bggroups.forEach(function(group) {
// if (vt.ActiveGroup != group.g) {
// var li = document.createElement("li");
// li.id = "move_to_"+group.g;
// li.className = "menu_item move_to_group_menu_entry";
// li.innerHTML = group.n;
// $("#move_to_group_menu")[0].appendChild(li);
// }
// });
// if (x >= $(window).width()-$("#tabs_menu").outerWidth()) {
// x = $(window).width()-$("#tabs_menu").outerWidth();
// }
// if (y >= $(window).height()-$("#move_to_group_menu").outerHeight()-20) {
// y = $(window).height()-$("#move_to_group_menu").outerHeight();
// }
// $("#move_to_group_menu").css({"display": "block", "top": y-24, "left": x-20});
// }
event.dataTransfer.setData("Class", "group");
event.dataTransfer.setData("Group", JSON.stringify(Group));
event.dataTransfer.setData("TabsIds", JSON.stringify(TabsIds));
event.dataTransfer.setData("TabsIdsParents", JSON.stringify(TabsIdsParents));
event.dataTransfer.setData("Folders", JSON.stringify(Folders));
chrome.runtime.sendMessage({
command: "drag_drop",
DragNodeClass: "group",
DragTreeDepth: 0
});
}

306
scripts/listeners.js Normal file
View File

@ -0,0 +1,306 @@
// Copyright (c) 2017 kroppy. All rights reserved.
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/
function StartSidebarListeners() {
if (browserId == "F") {
browser.browserAction.onClicked.addListener(function(tab) {
if (tab.windowId == tt.CurrentWindowId) {
browser.sidebarAction.close();
}
});
}
chrome.commands.onCommand.addListener(function(command) {
chrome.windows.getCurrent({populate: false}, function(window) {
if (window.id == tt.CurrentWindowId && window.focused) {
chrome.tabs.query({windowId: tt.CurrentWindowId, active: true}, function(tabs) {
let tabsArr = [];
document.querySelectorAll("[id='"+tabs[0].id+"'] .tab, [id='"+tabs[0].id+"']").forEach(function(s){
tabsArr.push(parseInt(s.id));
if (s.childNodes[1].childNodes.length > 0) {
document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){
tabsArr.push(parseInt(t.id));
});
}
});
CloseTabs(tabsArr);
});
}
});
});
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message.command == "backup_available") {
if (opt.debug) {
log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command);
}
let BAKbutton = document.getElementById("button_load_bak"+message.bak);
if (BAKbutton != null) {
BAKbutton.classList.remove("disabled");
}
return;
}
if (message.command == "drag_drop") {
if (opt.debug) {
log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command);
}
CleanUpDragClasses();
tt.DragNodeClass = message.DragNodeClass;
tt.DragTreeDepth = message.DragTreeDepth;
return;
}
if (message.command == "dragend") {
if (opt.debug) {
log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command);
}
CleanUpDragClasses();
EmptyDragAndDrop();
return;
}
if (message.command == "remove_folder") {
if (opt.debug) {
log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command+" folderId: "+message.folderId);
}
RemoveFolder(message.folderId);
return;
}
if (message.command == "remove_group") {
if (opt.debug) {
log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command+" groupId: "+message.groupId);
}
setTimeout(function() {
GroupRemove(message.groupId, false);
}, 2000);
return;
}
if (message.command == "reload_sidebar") {
if (opt.debug) {
log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command);
}
window.location.reload();
return;
}
if (message.command == "reload_options") {
if (opt.debug) {
log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command);
}
opt = Object.assign({}, message.opt);
setTimeout(function() {
RestorePinListRowSettings();
}, 100);
return;
}
if (message.command == "reload_toolbar") {
if (opt.debug) {
log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command);
}
opt = Object.assign({}, message.opt);
if (opt.show_toolbar) {
RemoveToolbar();
RecreateToolbar(message.toolbar);
SetToolbarEvents(false, true, true, "mousedown");
RestoreToolbarShelf();
RestoreToolbarSearchFilter();
} else {
RemoveToolbar();
}
RefreshGUI();
return;
}
if (message.command == "reload_theme") {
if (opt.debug) {
log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command);
}
RestorePinListRowSettings();
ApplyTheme(message.theme);
return;
}
if (message.windowId == tt.CurrentWindowId) {
if (message.command == "append_group") {
if (tt.groups[message.groupId] == undefined) {
tt.groups[message.groupId] = {id: message.groupId, index: Object.keys(tt.groups).length, active_tab: 0, prev_active_tab: 0, active_tab_ttid: "", name: message.group_name, font: message.font_color};
AppendGroupToList(message.groupId, message.group_name, message.font_color, true);
}
return;
}
if (message.command == "append_tab_to_group") {
let Group = document.getElementById("ct"+message.groupId);
let Tab = document.getElementById(message.tabId);
if (Group && Tab) {
Group.appendChild(Tab);
SetActiveGroup(message.groupId, false, true);
}
return;
}
if (message.command == "tab_created") {
AppendTab({tab: message.tab, ParentId: message.ParentId, InsertAfterId: message.InsertAfterId, Append: message.Append, Scroll: true});
RefreshExpandStates();
setTimeout(function() {
RefreshCounters();
RefreshGUI();
},50);
if (opt.syncro_tabbar_tabs_order) {
let tabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s){
return parseInt(s.id);
});
chrome.tabs.move(message.tab.id, {index: tabIds.indexOf(message.tab.id)});
}
setTimeout(function() {
tt.schedule_update_data++;
}, 1000);
return;
}
if (message.command == "tab_attached") {
if (opt.debug) {
log("chrome event: "+message.command+", tabId: "+message.tabId+", tab is pinned: "+message.tab.pinned+", ParentId: "+message.ParentId);
}
AppendTab({tab: message.tab, ParentId: message.ParentId, Append: true, SkipSetActive: true, SkipMediaIcon: true});
RefreshGUI();
return;
}
if (message.command == "tab_detached") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
}
let Tab = document.getElementById(message.tabId);
if (Tab != null) {
let ctDetachedParent = Tab.childNodes[1];
if (opt.promote_children_in_first_child == true && ctDetachedParent.childNodes.length > 1) {
let ctNewParent = document.getElementById(ctDetachedParent.firstChild.id).childNodes[1];
ctDetachedParent.parentNode.parentNode.insertBefore(ctDetachedParent.firstChild, ctDetachedParent.parentNode);
while (ctDetachedParent.firstChild) {
ctNewParent.appendChild(ctDetachedParent.firstChild);
}
} else {
while (ctDetachedParent.firstChild) {
ctDetachedParent.parentNode.parentNode.insertBefore(ctDetachedParent.firstChild, ctDetachedParent.parentNode);
}
}
}
RemoveTabFromList(message.tabId);
setTimeout(function() {
tt.schedule_update_data++;
}, 300);
RefreshGUI();
return;
}
if (message.command == "tab_removed") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
}
let mTab = document.getElementById(message.tabId);
if (mTab != null) {
let ctParent = mTab.childNodes[1];
if (opt.debug) {
log("tab_removed, promote children: " +opt.promote_children);
}
if (opt.promote_children == true) {
if (opt.promote_children_in_first_child == true && ctParent.childNodes.length > 1) {
let ctNewParent = document.getElementById(ctParent.firstChild.id).childNodes[1];
ctParent.parentNode.parentNode.insertBefore(ctParent.firstChild, ctParent.parentNode);
while (ctParent.firstChild) {
ctNewParent.appendChild(ctParent.firstChild);
}
} else {
while (ctParent.firstChild) {
ctParent.parentNode.parentNode.insertBefore(ctParent.firstChild, ctParent.parentNode);
}
}
} else {
document.querySelectorAll("[id='"+message.tabId+"'] .tab").forEach(function(s) {
chrome.tabs.remove(parseInt(s.id));
});
}
RemoveTabFromList(message.tabId);
RefreshExpandStates();
setTimeout(function() {
tt.schedule_update_data++;
}, 300);
RefreshGUI();
RefreshCounters();
}
return;
}
if (message.command == "tab_activated") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
}
SetActiveTab(message.tabId, true);
return;
}
if (message.command == "tab_attention") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
}
SetAttentionIcon(message.tabId);
return;
}
if (message.command == "tab_updated") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
// + ", changeInfo: "+JSON.stringify(message.changeInfo));
// log(message.changeInfo);
}
if (message.changeInfo.favIconUrl != undefined || message.changeInfo.url != undefined) {
setTimeout(function() {
GetFaviconAndTitle(message.tabId, true);
}, 100);
}
if (message.changeInfo.title != undefined) {
setTimeout(function() {
GetFaviconAndTitle(message.tabId, true);
}, 1000);
}
if (message.changeInfo.audible != undefined || message.changeInfo.mutedInfo != undefined) {
RefreshMediaIcon(message.tabId);
}
if (message.changeInfo.discarded != undefined) {
RefreshDiscarded(message.tabId);
// RefreshMediaIcon(message.tabId);
}
if (message.changeInfo.pinned != undefined) {
let updateTab = document.getElementById(message.tabId);
if (updateTab != null) {
if (message.tab.pinned && updateTab.classList.contains("pin") == false) {
SetTabClass(message.tabId, true);
tt.schedule_update_data++;
}
if (!message.tab.pinned && updateTab.classList.contains("tab") == false) {
SetTabClass(message.tabId, false);
tt.schedule_update_data++;
}
}
RefreshExpandStates();
}
return;
}
// if (message.command == "set_active_group") {
// SetActiveGroup(message.groupId, false, false);
// return;
// }
if (message.command == "remote_update") {
if (opt.debug) {
log("chrome event: "+message.command+ ", tabId: " + message.tabId);
log(message);
}
RcreateTreeStructure(message.groups, message.folders, message.tabs);
sendResponse(true);
tt.schedule_update_data++;
return;
}
}
});
}

View File

@ -83,7 +83,7 @@ function AddGroupToManagerList(hibernated_group) {
if (event.which == 1) {
let HibernategGroupIndex = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode);
chrome.storage.local.get(null, function(storage) {
let filename = storage.hibernated_groups[HibernategGroupIndex].group.name == "" ? caption_noname_group : storage.hibernated_groups[HibernategGroupIndex].group.name;
let filename = storage.hibernated_groups[HibernategGroupIndex].group.name == "" ? labels.noname_group : storage.hibernated_groups[HibernategGroupIndex].group.name;
SaveFile(filename, "tt_group", storage.hibernated_groups[HibernategGroupIndex]);
});
}
@ -166,7 +166,7 @@ function AddSessionToManagerList(saved_session) {
let saved_session = this.parentNode;
let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session);
chrome.storage.local.get(null, function(storage) {
let filename = storage.saved_sessions[SessionIndex].name == "" ? caption_noname_group : storage.saved_sessions[SessionIndex].name;
let filename = storage.saved_sessions[SessionIndex].name == "" ? labels.noname_group : storage.saved_sessions[SessionIndex].name;
SaveFile(filename, "tt_session", storage.saved_sessions[SessionIndex].session);
});
}
@ -326,9 +326,9 @@ function SetManagerEvents() {
}
document.getElementById("manager_window_button_hibernate_group").onmousedown = function(event) {
if (event.which == 1) {
ExportGroup(active_group, false, true);
ExportGroup(tt.active_group, false, true);
setTimeout(function() {
GroupRemove(active_group, true);
GroupRemove(tt.active_group, true);
}, 100);
setTimeout(function() {
OpenManagerWindow();
@ -366,7 +366,7 @@ function SetManagerEvents() {
autosessions_save_timer.oninput = function(event) {
opt.autosave_interval = parseInt(this.value);
SavePreferences();
clearInterval(AutoSaveSession);
clearInterval(tt.AutoSaveSession);
StartAutoSaveSession();
}

View File

@ -23,7 +23,7 @@ function ShowMenu(MenuNode, event) {
function ShowTabMenu(TabNode, event) {
HideMenus();
menuItemNode = TabNode;
tt.menuItemNode = TabNode;
// $(".menu").hide(0);
// MUTE TABS
@ -77,7 +77,7 @@ function ShowTabMenu(TabNode, event) {
function ShowFolderMenu(FolderNode, event) {
HideMenus();
menuItemNode = FolderNode;
tt.menuItemNode = FolderNode;
document.querySelectorAll("#menu_mute_tab, #menu_unmute_tab, #separator_unlo, #menu_unload, #menu_new_tab, #menu_new_folder, #separator_renf, #menu_rename_folder, #menu_delete_folder, #separator_bkt, #menu_bookmark_tree, #separator_expaa, #menu_expand_all, #menu_collapse_all, #menu_new_group, #separator_tts, #menu_manager_window, #menu_treetabs_settings").forEach(function(s){
s.style.display = "";
@ -94,7 +94,7 @@ function ShowFolderMenu(FolderNode, event) {
}
function ShowFGlobalMenu(event) {
menuItemNode = event.target;
tt.menuItemNode = event.target;
HideMenus();
@ -106,12 +106,12 @@ function ShowFGlobalMenu(event) {
function ShowFGroupMenu(GroupNode, event) {
HideMenus();
menuItemNode = GroupNode;
tt.menuItemNode = GroupNode;
document.querySelectorAll("#menu_new_group, #menu_rename_group, #menu_delete_group, #menu_delete_group_tabs_close, #separator_gunlo, #menu_groups_unload, #separator_gbk, #separator_tts, #menu_bookmark_group, #separator_tts, #menu_groups_hibernate, #menu_manager_window, #menu_treetabs_settings").forEach(function(s){
s.style.display = "";
});
if (menuItemNode.id == "tab_list") {
if (tt.menuItemNode.id == "tab_list") {
document.querySelectorAll("#menu_groups_hibernate, #menu_rename_group, #menu_delete_group, #menu_delete_group_tabs_close").forEach(function(s){
s.style.display = "none";
});
@ -125,8 +125,8 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("pin")) {
OpenNewTab(true, menuItemNode.id);
if (tt.menuItemNode.classList.contains("pin")) {
OpenNewTab(true, tt.menuItemNode.id);
} else {
OpenNewTab(true, undefined);
}
@ -138,16 +138,16 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("folder")) {
OpenNewTab(false, menuItemNode.id);
if (tt.menuItemNode.classList.contains("folder")) {
OpenNewTab(false, tt.menuItemNode.id);
} else {
if (menuItemNode.classList.contains("pin")) {
OpenNewTab(true, menuItemNode.id);
if (tt.menuItemNode.classList.contains("pin")) {
OpenNewTab(true, tt.menuItemNode.id);
} else {
if (menuItemNode.classList.contains("tab")) {
OpenNewTab(false, menuItemNode.id);
if (tt.menuItemNode.classList.contains("tab")) {
OpenNewTab(false, tt.menuItemNode.id);
} else {
OpenNewTab(false, active_group);
OpenNewTab(false, tt.active_group);
}
}
}
@ -160,12 +160,12 @@ function SetMenu() {
m.onmousedown = function(event) {
event.stopPropagation();
if (event.which == 1) {
if (menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { pinned: (menuItemNode.classList.contains("tab")) });
if (tt.menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { pinned: (tt.menuItemNode.classList.contains("tab")) });
});
} else {
chrome.tabs.update(parseInt(menuItemNode.id), { pinned: (menuItemNode.classList.contains("tab")) });
chrome.tabs.update(parseInt(tt.menuItemNode.id), { pinned: (tt.menuItemNode.classList.contains("tab")) });
}
HideMenus();
}
@ -176,12 +176,12 @@ function SetMenu() {
m.onmousedown = function(event) {
event.stopPropagation();
if (event.which == 1) {
if (menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
if (tt.menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
DuplicateTab(s);
});
} else {
DuplicateTab(menuItemNode);
DuplicateTab(tt.menuItemNode);
}
HideMenus();
}
@ -193,9 +193,9 @@ function SetMenu() {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("selected_tab")) {
if (tt.menuItemNode.classList.contains("selected_tab")) {
let tabsArr = [];
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
tabsArr.push(parseInt(s.id));
if (s.childNodes[1].childNodes.length > 0) {
document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){
@ -205,7 +205,7 @@ function SetMenu() {
});
Detach(tabsArr);
} else {
Detach([parseInt(menuItemNode.id)]);
Detach([parseInt(tt.menuItemNode.id)]);
}
HideMenus();
}
@ -216,12 +216,12 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
if (tt.menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
chrome.tabs.reload(parseInt(s.id));
});
} else {
chrome.tabs.reload(parseInt(menuItemNode.id));
chrome.tabs.reload(parseInt(tt.menuItemNode.id));
}
HideMenus();
}
@ -232,10 +232,10 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("pin") || menuItemNode.classList.contains("tab")) {
if (menuItemNode.classList.contains("selected_tab")) {
if (tt.menuItemNode.classList.contains("pin") || tt.menuItemNode.classList.contains("tab")) {
if (tt.menuItemNode.classList.contains("selected_tab")) {
let tabsArr = [];
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
tabsArr.push(parseInt(s.id));
if (s.childNodes[1].childNodes.length > 0) {
document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){
@ -245,12 +245,12 @@ function SetMenu() {
});
DiscardTabs(tabsArr);
} else {
DiscardTabs([parseInt(menuItemNode.id)]);
DiscardTabs([parseInt(tt.menuItemNode.id)]);
}
}
if (menuItemNode.classList.contains("folder")) {
if (tt.menuItemNode.classList.contains("folder")) {
let tabsArr = [];
document.querySelectorAll("#"+menuItemNode.id+" .tab").forEach(function(s){
document.querySelectorAll("#"+tt.menuItemNode.id+" .tab").forEach(function(s){
tabsArr.push(parseInt(s.id));
});
DiscardTabs(tabsArr);
@ -264,9 +264,9 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("selected_tab")) {
if (tt.menuItemNode.classList.contains("selected_tab")) {
let tabsArr = [];
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
tabsArr.push(parseInt(s.id));
if (s.childNodes[1].childNodes.length > 0) {
document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){
@ -276,7 +276,7 @@ function SetMenu() {
});
CloseTabs(tabsArr);
} else {
CloseTabs([parseInt(menuItemNode.id)]);
CloseTabs([parseInt(tt.menuItemNode.id)]);
}
HideMenus();
}
@ -287,17 +287,17 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("pin") || menuItemNode.classList.contains("tab")) {
if (menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
if (tt.menuItemNode.classList.contains("pin") || tt.menuItemNode.classList.contains("tab")) {
if (tt.menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { muted: true });
});
} else {
chrome.tabs.update(parseInt(menuItemNode.id), { muted: true });
chrome.tabs.update(parseInt(tt.menuItemNode.id), { muted: true });
}
}
if (menuItemNode.classList.contains("folder")) {
document.querySelectorAll("#"+menuItemNode.id+" .tab").forEach(function(s){
if (tt.menuItemNode.classList.contains("folder")) {
document.querySelectorAll("#"+tt.menuItemNode.id+" .tab").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { muted: true });
});
}
@ -310,7 +310,7 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
document.querySelectorAll("[id='"+menuItemNode.id+"'], [id='"+menuItemNode.id+"'] .tab").forEach(function(s){
document.querySelectorAll("[id='"+tt.menuItemNode.id+"'], [id='"+tt.menuItemNode.id+"'] .tab").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { muted: true });
});
HideMenus();
@ -322,17 +322,17 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("pin") || menuItemNode.classList.contains("tab")) {
if (menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
if (tt.menuItemNode.classList.contains("pin") || tt.menuItemNode.classList.contains("tab")) {
if (tt.menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { muted: false });
});
} else {
chrome.tabs.update(parseInt(menuItemNode.id), { muted: false });
chrome.tabs.update(parseInt(tt.menuItemNode.id), { muted: false });
}
}
if (menuItemNode.classList.contains("folder")) {
document.querySelectorAll("#"+menuItemNode.id+" .tab").forEach(function(s){
if (tt.menuItemNode.classList.contains("folder")) {
document.querySelectorAll("#"+tt.menuItemNode.id+" .tab").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { muted: false });
});
}
@ -345,7 +345,7 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
document.querySelectorAll("[id='"+menuItemNode.id+"'], [id='"+menuItemNode.id+"'] .tab").forEach(function(s){
document.querySelectorAll("[id='"+tt.menuItemNode.id+"'], [id='"+tt.menuItemNode.id+"'] .tab").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { muted: false });
});
HideMenus();
@ -358,12 +358,12 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin:not(.selected_tab), #"+active_group+" .tab:not(.selected_tab)").forEach(function(s){
if (tt.menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin:not(.selected_tab), #"+tt.active_group+" .tab:not(.selected_tab)").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { muted: true });
});
} else {
document.querySelectorAll(".pin:not([id='"+menuItemNode.id+"']), #"+active_group+" .tab:not([id='"+menuItemNode.id+"'])").forEach(function(s){
document.querySelectorAll(".pin:not([id='"+tt.menuItemNode.id+"']), #"+tt.active_group+" .tab:not([id='"+tt.menuItemNode.id+"'])").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { muted: true });
});
}
@ -378,12 +378,12 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin:not(.selected_tab), #"+active_group+" .tab:not(.selected_tab)").forEach(function(s){
if (tt.menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin:not(.selected_tab), #"+tt.active_group+" .tab:not(.selected_tab)").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { muted: false });
});
} else {
document.querySelectorAll(".pin:not([id='"+menuItemNode.id+"']), #"+active_group+" .tab:not([id='"+menuItemNode.id+"'])").forEach(function(s){
document.querySelectorAll(".pin:not([id='"+tt.menuItemNode.id+"']), #"+tt.active_group+" .tab:not([id='"+tt.menuItemNode.id+"'])").forEach(function(s){
chrome.tabs.update(parseInt(s.id), { muted: false });
});
}
@ -414,18 +414,24 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("folder")) {
AddNewFolder(undefined, menuItemNode.id, undefined, undefined, undefined, undefined, true);
if (tt.menuItemNode.classList.contains("folder")) {
let FolderId = AddNewFolder({ParentId: tt.menuItemNode.id, SetEvents: true});
tt.menuItemNode.classList.remove("c");
tt.menuItemNode.classList.add("o");
ShowRenameFolderDialog(FolderId);
} else {
if (menuItemNode.classList.contains("tab")) {
let folders = GetParentsByClass(menuItemNode, "folder");
if (tt.menuItemNode.classList.contains("tab")) {
let folders = GetParentsByClass(tt.menuItemNode, "folder");
if (folders.length > 0) {
AddNewFolder(undefined, folders[0].id, undefined, undefined, undefined, undefined, true);
let FolderId = AddNewFolder({ParentId: folders[0].id, SetEvents: true});
ShowRenameFolderDialog(FolderId);
} else {
AddNewFolder(undefined, undefined, undefined, undefined, undefined, undefined, true);
let FolderId = AddNewFolder({SetEvents: true});
ShowRenameFolderDialog(FolderId);
}
} else {
AddNewFolder(undefined, undefined, undefined, undefined, undefined, undefined, true);
let FolderId = AddNewFolder({SetEvents: true});
ShowRenameFolderDialog(FolderId);
}
}
HideMenus();
@ -438,13 +444,14 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
document.querySelectorAll("[id='"+menuItemNode.id+"'], [id='"+menuItemNode.id+"'] .folder.c, [id='"+menuItemNode.id+"'] .tab.c").forEach(function(s){
document.querySelectorAll("[id='"+tt.menuItemNode.id+"'], [id='"+tt.menuItemNode.id+"'] .folder.c, [id='"+tt.menuItemNode.id+"'] .tab.c").forEach(function(s){
s.classList.add("o");
s.classList.remove("c");
});
schedule_update_data++;
tt.schedule_update_data++;
HideMenus();
SaveFolders();
}
}
}
@ -453,12 +460,13 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
document.querySelectorAll("[id='"+menuItemNode.id+"'], [id='"+menuItemNode.id+"'] .folder.c, [id='"+menuItemNode.id+"'] .tab.c").forEach(function(s){
document.querySelectorAll("[id='"+tt.menuItemNode.id+"'], [id='"+tt.menuItemNode.id+"'] .folder.c, [id='"+tt.menuItemNode.id+"'] .tab.c").forEach(function(s){
s.classList.add("c");
s.classList.remove("o");
});
schedule_update_data++;
tt.schedule_update_data++;
HideMenus();
SaveFolders();
}
}
}
@ -467,12 +475,13 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
document.querySelectorAll("#"+active_group+" .folder.c, #"+active_group+" .tab.c").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .folder.c, #"+tt.active_group+" .tab.c").forEach(function(s){
s.classList.add("o");
s.classList.remove("c");
});
schedule_update_data++;
tt.schedule_update_data++;
HideMenus();
SaveFolders();
}
}
}
@ -481,12 +490,13 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
document.querySelectorAll("#"+active_group+" .folder.o, #"+active_group+" .tab.o").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .folder.o, #"+tt.active_group+" .tab.o").forEach(function(s){
s.classList.add("c");
s.classList.remove("o");
});
schedule_update_data++;
tt.schedule_update_data++;
HideMenus();
SaveFolders();
}
}
}
@ -499,7 +509,7 @@ function SetMenu() {
event.stopPropagation();
let tabsArr = [];
document.querySelectorAll("[id='"+menuItemNode.id+"'] .tab, [id='"+menuItemNode.id+"']").forEach(function(s){
document.querySelectorAll("[id='"+tt.menuItemNode.id+"'] .tab, [id='"+tt.menuItemNode.id+"']").forEach(function(s){
tabsArr.push(parseInt(s.id));
if (s.childNodes[1].childNodes.length > 0) {
document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){
@ -517,7 +527,7 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
ShowRenameFolderDialog(menuItemNode.id);
ShowRenameFolderDialog(tt.menuItemNode.id);
HideMenus();
}
}
@ -528,12 +538,12 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
if (menuItemNode.classList.contains("selected_folder")) {
document.querySelectorAll("#"+menuItemNode.id+" .selected_folder, #"+menuItemNode.id).forEach(function(s){
if (tt.menuItemNode.classList.contains("selected_folder")) {
document.querySelectorAll("#"+tt.menuItemNode.id+" .selected_folder, #"+tt.menuItemNode.id).forEach(function(s){
RemoveFolder(s.id);
});
} else {
RemoveFolder(menuItemNode.id);
RemoveFolder(tt.menuItemNode.id);
}
HideMenus();
}
@ -545,8 +555,8 @@ function SetMenu() {
if (event.which == 1) {
event.stopPropagation();
let tabsArr = [];
if (menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin:not(.selected_tab), #"+active_group+" .tab:not(.selected_tab)").forEach(function(s){
if (tt.menuItemNode.classList.contains("selected_tab")) {
document.querySelectorAll(".pin:not(.selected_tab), #"+tt.active_group+" .tab:not(.selected_tab)").forEach(function(s){
let children = document.querySelectorAll("[id='"+s.id+"'] .selected_tab");
if (children.length == 0 || opt.promote_children) {
tabsArr.push(parseInt(s.id));
@ -554,10 +564,10 @@ function SetMenu() {
});
CloseTabs(tabsArr);
} else {
if (menuItemNode.classList.contains("tab")) {
document.getElementById(active_group).appendChild(menuItemNode);
if (tt.menuItemNode.classList.contains("tab")) {
document.getElementById(tt.active_group).appendChild(tt.menuItemNode);
}
document.querySelectorAll(".pin:not([id='"+menuItemNode.id+"']), #"+active_group+" .tab:not([id='"+menuItemNode.id+"'])").forEach(function(s){
document.querySelectorAll(".pin:not([id='"+tt.menuItemNode.id+"']), #"+tt.active_group+" .tab:not([id='"+tt.menuItemNode.id+"'])").forEach(function(s){
tabsArr.push(parseInt(s.id));
});
@ -572,7 +582,7 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
Bookmark(menuItemNode);
Bookmark(tt.menuItemNode);
HideMenus();
}
}
@ -583,7 +593,7 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
ShowGroupEditWindow(menuItemNode.id);
ShowGroupEditWindow(tt.menuItemNode.id);
HideMenus();
}
}
@ -593,7 +603,7 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
GroupRemove(menuItemNode.id, false);
GroupRemove(tt.menuItemNode.id, false);
HideMenus();
}
}
@ -604,7 +614,7 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
GroupRemove(menuItemNode.id, true);
GroupRemove(tt.menuItemNode.id, true);
HideMenus();
}
}
@ -616,7 +626,7 @@ function SetMenu() {
if (event.which == 1) {
event.stopPropagation();
let tabsArr = [];
document.querySelectorAll("[id='"+menuItemNode.id+"'] .tab").forEach(function(s){
document.querySelectorAll("[id='"+tt.menuItemNode.id+"'] .tab").forEach(function(s){
tabsArr.push(parseInt(s.id));
});
DiscardTabs(tabsArr);
@ -639,10 +649,10 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
ExportGroup(menuItemNode.id, false, true);
ExportGroup(tt.menuItemNode.id, false, true);
HideMenus();
setTimeout(function() {
GroupRemove(menuItemNode.id, true);
GroupRemove(tt.menuItemNode.id, true);
}, 100);
}
}
@ -653,7 +663,7 @@ function SetMenu() {
m.onmousedown = function(event) {
if (event.which == 1) {
event.stopPropagation();
Bookmark(menuItemNode);
Bookmark(tt.menuItemNode);
HideMenus();
}
}
@ -680,23 +690,6 @@ function SetMenu() {
}
}
});
// move tabs to group
// $(document).on("mousedown", "#menu_detach_tab_to_new_group, .move_to_group_menu_entry", function(event) {
// var tabsIds
// if ($(this).is("#menu_detach_tab_to_new_group")) {
// bg.dt.DropToGroup = AddNewGroup(575757);
// GetColorFromMiddlePixel(vt.menuItemId, bg.dt.DropToGroup);
// } else {
// bg.dt.DropToGroup = this.id.substr(8);
// }
// AppendTabsToGroup({tabsIds: DragAndDrop.tabsIds, groupId: bg.dt.DropToGroup, SwitchTabIfHasActive: true, insertAfter: true, RemoveClass: "selected_tab", moveTabs: true});
// });
}

View File

@ -58,14 +58,14 @@ async function RefreshGUI() {
document.querySelectorAll(".group").forEach(function(s){
let groupLabel = document.getElementById("_gte"+s.id);
if (groupLabel) {
groupLabel.textContent = (bggroups[s.id] ? bggroups[s.id].name : caption_noname_group) + " (" + document.querySelectorAll("#"+s.id+" .tab").length + ")";
groupLabel.textContent = (tt.groups[s.id] ? tt.groups[s.id].name : labels.noname_group) + " (" + document.querySelectorAll("#"+s.id+" .tab").length + ")";
}
});
} else {
document.querySelectorAll(".group").forEach(function(s){
let groupLabel = document.getElementById("_gte"+s.id);
if (groupLabel) {
groupLabel.textContent = bggroups[s.id] ? bggroups[s.id].name : caption_noname_group;
groupLabel.textContent = tt.groups[s.id] ? tt.groups[s.id].name : labels.noname_group;
}
});
}
@ -74,25 +74,17 @@ async function RefreshGUI() {
});
let groups = document.getElementById("groups");
let groupsHeight = document.body.clientHeight - toolbarHeight - pin_listHeight;
let groupsWidth = document.body.clientWidth - toolbar_groupsWidth - 1;
groups.style.top = toolbarHeight + pin_listHeight + "px";
groups.style.left = toolbar_groupsWidth + "px";
groups.style.height = groupsHeight + "px";
groups.style.width = (document.body.clientWidth - toolbar_groupsWidth - 1) + "px";
// let total = ManagerWindowGroupsListHeight + ManagerWindowSessionsListHeight;
// if (total > document.body.clientHeight - 200) {
// let cut = (total - (document.body.clientHeight - 200))/2;
// ManagerWindowGroupsList.style.height = ManagerWindowGroupsListHeight - cut + "px";
// ManagerWindowSessionsList.style.height = ManagerWindowSessionsListHeight - cut + "px";
// } else {
// ManagerWindowGroupsList.style.height = ManagerWindowGroupsListHeight + "px";
// ManagerWindowSessionsList.style.height = ManagerWindowSessionsListHeight + "px";
// }
// ManagerWindow.style.height = ManagerWindowGroupsList.clientHeight + ManagerWindowSessionsList.clientHeight + 300 + "px";
groups.style.width = groupsWidth + "px";
// let bottom_floating_buttons = document.getElementById("status_bar");
// let active_group_tabs = document.getElementById("ct"+tt.active_group);
// bottom_floating_buttons.style.left = toolbar_groupsWidth + "px";
// bottom_floating_buttons.style.width = toolbar_groupsWidth + active_group_tabs.clientWidth + "px";
let PanelList = document.querySelector(".mw_pan_on>.manager_window_list");
@ -110,27 +102,9 @@ async function RefreshGUI() {
PanelList.style.height = MaxAllowedHeight - ManagerWindowPanelButtonsHeight + "px";
}
// if (ManagerWindowSessionsListHeight > document.body.clientHeight - 300) {
// ManagerWindowSessionsList.style.height = document.body.clientHeight - 300 + "px";
// } else {
// ManagerWindowSessionsList.style.height = ManagerWindowSessionsListHeight + "px";
// }
let ManagerWindow = document.getElementById("manager_window");
// ManagerWindow.style.height = PanelListHeight.clientHeight + 700 + "px";
ManagerWindow.style.height = PanelList.clientHeight + ManagerWindowPanelButtonsHeight + 56 + "px";
}
// set discarded class
@ -143,6 +117,8 @@ function RefreshDiscarded(tabId) {
t.classList.add("discarded");
} else {
t.classList.remove("discarded");
t.classList.remove("audible");
t.classList.remove("muted");
}
}
});
@ -163,15 +139,15 @@ function RefreshMediaIcon(tabId) {
if (t != null) {
chrome.tabs.get(parseInt(tabId), function(tab) {
if (tab) {
if (tab.mutedInfo.muted) {
if (tab.mutedInfo.muted && !tab.discarded) {
t.classList.remove("audible");
t.classList.add("muted");
}
if (!tab.mutedInfo.muted && tab.audible) {
if (!tab.mutedInfo.muted && tab.audible && !tab.discarded) {
t.classList.remove("muted");
t.classList.add("audible");
}
if (!tab.mutedInfo.muted && !tab.audible) {
if ((!tab.mutedInfo.muted && !tab.audible) || tab.discarded) {
t.classList.remove("audible");
t.classList.remove("muted");
}
@ -202,48 +178,62 @@ function VivaldiRefreshMediaIcons() {
}, 2000);
}
async function LoadFavicon(tabId, Img, TryUrls, TabHeaderNode, i) {
if (TabHeaderNode){
Img.src = TryUrls[i];
Img.onload = function() {
TabHeaderNode.style.backgroundImage = "url(" + TryUrls[i] + ")";
if (browserId == "F") { // cache Firefox favicon - solution for bug with empty favicons in unloaded tabs
browser.sessions.setTabValue(tabId, "CachedFaviconUrl", TryUrls[i]);
}
};
Img.onerror = function() {
if (i < TryUrls.length) {
LoadFavicon(tabId, Img, TryUrls, TabHeaderNode, (i+1));
}
}
}
}
async function GetFaviconAndTitle(tabId, addCounter) {
let t = document.getElementById(tabId);
if (t != null) {
let CachedFavicon;
if (browserId == "F") {
let ttf = Promise.resolve(browser.sessions.getTabValue(tabId, "CachedFaviconUrl")).then(function(FaviconUrl) {
CachedFavicon = FaviconUrl;
});
}
chrome.tabs.get(parseInt(tabId), function(tab) {
if (tab){
let title = tab.title ? tab.title : tab.url;
let tHeader = t.childNodes[0];
let tTitle = tHeader.childNodes[1];
if (tab.status == "complete") {
if (tab.status == "complete" || tab.discarded) {
t.classList.remove("loading");
// change title
tTitle.textContent = title;
tHeader.title = title;
tHeader.setAttribute("tabTitle", title);
// compatibility with various Tab suspender extensions
if (tab.favIconUrl != undefined && tab.favIconUrl.match("data:image/png;base64") != null) {
tHeader.style.backgroundImage = "url(" + tab.favIconUrl + ")";
} else {
// case for internal pages, favicons don't have access, but can be loaded from url
if (tab.url.match("opera://|vivaldi://|browser://|chrome://|chrome-extension://") != null) {
tHeader.style.backgroundImage = "url(chrome://favicon/" + tab.url + ")";
} else {
// change favicon
let img = new Image();
img.src = tab.favIconUrl;
img.onload = function() {
tHeader.style.backgroundImage = "url(" + tab.favIconUrl + ")";
};
img.onerror = function() {
tHeader.style.backgroundImage = ((tab.url == "" || browserId == "F") ? "url(./theme/icon_empty.svg)" : ("url(chrome://favicon/" + tab.url + ")"));
// "url(" + tab.url + ")"
}
}
let Img = new Image();
if (browserId != "F") {
CachedFavicon = "chrome://favicon/"+tab.url;
}
let TryCases = [tab.favIconUrl, CachedFavicon, , "./theme/icon_empty.svg"];
LoadFavicon(tabId, Img, TryCases, tHeader, 0);
}
if (tab.status == "loading") {
title = tab.title ? tab.title : caption_loading;
if (tab.status == "loading" && tab.discarded == false) {
title = tab.title ? tab.title : labels.loading;
t.classList.add("loading");
tHeader.style.backgroundImage = "";
tHeader.title = caption_loading;
tHeader.setAttribute("tabTitle", caption_loading);
tTitle.textContent = caption_loading;
tHeader.title = labels.loading;
tHeader.setAttribute("tabTitle", labels.loading);
tTitle.textContent = labels.loading;
setTimeout(function() {
if (document.getElementById(tab.id) != null) GetFaviconAndTitle(tab.id, addCounter);
}, 1000);
@ -258,7 +248,7 @@ async function GetFaviconAndTitle(tabId, addCounter) {
// refresh open closed trees states
async function RefreshExpandStates() {
document.querySelectorAll("#"+active_group+" .folder").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .folder").forEach(function(s){
if (s.childNodes[1].children.length == 0 && s.childNodes[2].children.length == 0) {
s.classList.remove("o");
s.classList.remove("c");
@ -268,7 +258,7 @@ async function RefreshExpandStates() {
}
}
});
document.querySelectorAll("#"+active_group+" .tab").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .tab").forEach(function(s){
if (s.childNodes[1].children.length == 0) {
s.classList.remove("o");
s.classList.remove("c");
@ -282,14 +272,14 @@ async function RefreshExpandStates() {
async function RefreshCounters() {
if (opt.show_counter_tabs || opt.show_counter_tabs_hints) {
document.querySelectorAll("#"+active_group+" .tab").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .tab").forEach(function(s){
let title = s.childNodes[0].getAttribute("tabTitle");
if (title != null) {
s.childNodes[0].title = title;
s.childNodes[0].childNodes[1].textContent =title;
}
});
document.querySelectorAll("#"+active_group+" .o.tab, #"+active_group+" .c.tab").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .o.tab, #"+tt.active_group+" .c.tab").forEach(function(s){
let title = s.childNodes[0].getAttribute("tabTitle");
if (opt.show_counter_tabs && title != null) {
s.childNodes[0].childNodes[1].textContent = ("("+ document.querySelectorAll("[id='" + s.id + "'] .tab").length +") ") + title;
@ -300,12 +290,12 @@ async function RefreshCounters() {
});
document.querySelectorAll("#"+active_group+" .folder").forEach(function(s){
if (opt.show_counter_tabs && bgfolders[s.id]) {
s.childNodes[0].childNodes[1].textContent = ("("+ document.querySelectorAll("[id='" + s.id + "'] .tab").length +") ") + bgfolders[s.id].name;
document.querySelectorAll("#"+tt.active_group+" .folder").forEach(function(s){
if (opt.show_counter_tabs && tt.folders[s.id]) {
s.childNodes[0].childNodes[1].textContent = ("("+ document.querySelectorAll("[id='" + s.id + "'] .tab").length +") ") + tt.folders[s.id].name;
}
if (opt.show_counter_tabs_hints && bgfolders[s.id]) {
s.childNodes[0].title = ("("+ document.querySelectorAll("[id='" + s.id + "'] .tab").length +") ") + bgfolders[s.id].name;
if (opt.show_counter_tabs_hints && tt.folders[s.id]) {
s.childNodes[0].title = ("("+ document.querySelectorAll("[id='" + s.id + "'] .tab").length +") ") + tt.folders[s.id].name;
}
});
}
@ -313,7 +303,7 @@ async function RefreshCounters() {
async function RefreshTabCounter(tabId) {
let t = document.getElementById(tabId);
if (t.childNodes[0]) {
if (t != null && t.childNodes[0]) {
let title = t.childNodes[0].getAttribute("tabTitle");
if (t != null && title != null) {
if (t.classList.contains("o") || t.classList.contains("c")) {

View File

@ -11,10 +11,10 @@ async function UpdateData() {
}
setInterval(function() {
if (schedule_update_data > 1) {
schedule_update_data = 1;
if (tt.schedule_update_data > 1) {
tt.schedule_update_data = 1;
}
if (schedule_update_data > 0) {
if (tt.schedule_update_data > 0) {
let PinInd = 0;
let pins_data = [];
document.querySelectorAll(".pin").forEach(function(pin){
@ -27,83 +27,94 @@ async function UpdateData() {
tabs_data.push({id: tab.id, parent: tab.parentNode.parentNode.id, index: Array.from(tab.parentNode.children).indexOf(tab), expand: (tab.classList.contains("c") ? "c" : (tab.classList.contains("o") ? "o" : ""))});
});
chrome.runtime.sendMessage({command: "update_all_tabs", pins: pins_data, tabs: tabs_data});
schedule_update_data--;
}
}, 2000);
}
function RearrangeBrowserTabs() {
if (opt.debug) {
log("f: RearrangeBrowserTabs");
}
setInterval(function() {
if (schedule_rearrange_tabs > 0) {
schedule_rearrange_tabs--;
let tabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s){
return parseInt(s.id);
});
RearrangeBrowserTabsLoop(tabIds, tabIds.length-1);
tt.schedule_update_data--;
}
}, 1000);
}
async function RearrangeBrowserTabsLoop(tabIds, tabIndex) {
async function RearrangeBrowserTabs() {
setInterval(function() {
if (tt.schedule_rearrange_tabs > 0) {
tt.schedule_rearrange_tabs--;
if (opt.debug) {
log("f: RearrangeBrowserTabs");
}
chrome.tabs.query({currentWindow: true}, function(tabs) {
let ttTabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s){
return parseInt(s.id);
});
let tabIds = Array.prototype.map.call(tabs, function(t){
return t.id;
});
RearrangeBrowserTabsLoop(ttTabIds, tabIds, ttTabIds.length-1);
});
}
}, 1000);
}
async function RearrangeBrowserTabsLoop(ttTabIds, tabIds, tabIndex) {
if (opt.debug) {
log("f: RearrangeBrowserTabsLoop");
}
if (tabIndex >= 0 && schedule_rearrange_tabs == 0){
chrome.tabs.get(tabIds[tabIndex], function(tab) {
if (tab && tabIndex != tab.index) {
chrome.tabs.move(tabIds[tabIndex], {index: tabIndex});
}
RearrangeBrowserTabsLoop( tabIds, (tabIndex-1) );
});
if (tabIndex >= 0 && tt.schedule_rearrange_tabs == 0){
if (ttTabIds[tabIndex] != tabIds[tabIndex]) {
chrome.tabs.move(ttTabIds[tabIndex], {index: tabIndex});
}
setTimeout(function() {
RearrangeBrowserTabsLoop(ttTabIds, tabIds, (tabIndex-1));
}, 0);
}
}
function RearrangeTreeTabs(tabs, bgtabs, first_loop) {
tabs.forEach(function(Tab) {
let t = document.getElementById(Tab.id);
if (bgtabs[Tab.id] && t != null && t.parentNode.childNodes[bgtabs[Tab.id].index]) {
let tInd = Array.from(t.parentNode.children).indexOf(t);
if (tInd > bgtabs[Tab.id].index) {
InsterBeforeNode(t, t.parentNode.childNodes[bgtabs[Tab.id].index]);
} else {
InsterAfterNode(t, t.parentNode.childNodes[bgtabs[Tab.id].index]);
}
let newtInd = Array.from(t.parentNode.children).indexOf(t);
if (bgtabs[Tab.id] && newtInd != bgtabs[Tab.id].index && first_loop) {
RearrangeTreeTabs(tabs, bgtabs, false);
function RearrangeTreeTabs(bgtabs, show_finish_in_status) {
if (opt.debug) {
log("f: RearrangeTreeTabs");
}
ShowStatusBar({show: true, spinner: true, message: "Rearranging tabs and folders"});
document.querySelectorAll(".pin, .tab").forEach(function(tab){
if (bgtabs[tab.id]) {
let Sibling = tab.nextElementSibling;
while (Sibling) {
if (bgtabs[Sibling.id]) {
if (bgtabs[tab.id].index > bgtabs[Sibling.id].index ) {
InsterAfterNode(tab, Sibling);
}
}
Sibling = Sibling.nextElementSibling ? Sibling.nextElementSibling : false;
}
}
if (show_finish_in_status){
ShowStatusBar({show: true, spinner: false, message: "Rearranging: done.", hideTimeout: 1000});
}
});
}
function AppendTab(tab, ParentId, InsertBeforeId, InsertAfterId, Append, Index, SetEvents, AdditionalClass, SkipSetActive, Scroll, addCounter) {
if (document.getElementById(tab.id) != null) {
GetFaviconAndTitle(tab.id, addCounter);
function AppendTab(p) { // tab: chrome tab object, ParentId: int or string, InsertBeforeId: int or string, InsertAfterId: int or string, Append: bool, SkipSetEvents: bool, AdditionalClass: string, SkipSetActive: bool, Scroll: bool, addCounter: bool, SkipMediaIcon: bool
if (document.getElementById(p.tab.id) != null) {
GetFaviconAndTitle(p.tab.id, p.addCounter);
return;
}
var ClassList = tab.pinned ? "pin" : "tab";
if (tab.discarded) {
let ClassList = p.tab.pinned ? "pin" : "tab";
if (p.tab.discarded) {
ClassList = ClassList + " discarded";
}
if (AdditionalClass != false) {
ClassList = ClassList +" "+ AdditionalClass;
if (p.AdditionalClass) {
ClassList = ClassList +" "+ p.AdditionalClass;
}
var tb = document.createElement("div"); tb.className = ClassList; tb.id = tab.id; // TAB
var th = document.createElement("div"); th.className = (opt.always_show_close && !opt.never_show_close) ? "tab_header close_show" : "tab_header"; th.id = "tab_header"+tab.id; if (SetEvents) {th.draggable = true;} tb.appendChild(th); // HEADER
var ex = document.createElement("div"); ex.className = "expand"; ex.id = "exp"+tab.id; th.appendChild(ex); // EXPAND ARROW
var tt = document.createElement("div"); tt.className = "tab_title"; tt.id = "tab_title"+tab.id; th.appendChild(tt); // TITLE
let tb = document.createElement("div"); tb.className = ClassList; tb.id = p.tab.id; // TAB
let tbh = document.createElement("div"); tbh.className = (opt.always_show_close && !opt.never_show_close) ? "tab_header close_show" : "tab_header"; tbh.id = "tab_header"+p.tab.id; if (!p.SkipSetEvents) {tbh.draggable = true;} tb.appendChild(tbh); // HEADER
let tbe = document.createElement("div"); tbe.className = "expand"; tbe.id = "exp"+p.tab.id; tbh.appendChild(tbe); // EXPAND ARROW
let tbt = document.createElement("div"); tbt.className = "tab_title"; tbt.id = "tab_title"+p.tab.id; tbh.appendChild(tbt); // TITLE
let cl = undefined;
if (!opt.never_show_close) {
var cl = document.createElement("div"); cl.className = "close"; cl.id = "close"+tab.id; th.appendChild(cl); // CLOSE BUTTON
var ci = document.createElement("div"); ci.className = "close_img"; ci.id = "close_img"+tab.id; cl.appendChild(ci);
cl = document.createElement("div"); cl.className = "close"; cl.id = "close"+p.tab.id; tbh.appendChild(cl); // CLOSE BUTTON
let ci = document.createElement("div"); ci.className = "close_img"; ci.id = "close_img"+p.tab.id; cl.appendChild(ci);
}
var mi = document.createElement("div"); mi.className = "tab_mediaicon"; mi.id = "tab_mediaicon"+tab.id; th.appendChild(mi);
var ct = document.createElement("div"); ct.className = "children_tabs"; ct.id = "ct"+tab.id; tb.appendChild(ct);
var di = document.createElement("div"); di.className = "drag_indicator"; di.id = "di"+tab.id; tb.appendChild(di); // DROP TARGET INDICATOR
let mi = document.createElement("div"); mi.className = "tab_mediaicon"; mi.id = "tab_mediaicon"+p.tab.id; tbh.appendChild(mi);
let ct = document.createElement("div"); ct.className = "children_tabs"; ct.id = "ct"+p.tab.id; tb.appendChild(ct);
let di = document.createElement("div"); di.className = "drag_indicator"; di.id = "di"+p.tab.id; tb.appendChild(di); // DROP TARGET INDICATOR
if (SetEvents) {
if (!p.SkipSetEvents) {
ct.onclick = function(event) {
if (event.target == this && event.which == 1) {
DeselectFolders();
@ -126,7 +137,7 @@ function AppendTab(tab, ParentId, InsertBeforeId, InsertAfterId, Append, Index,
ActionClickGroup(this.parentNode, opt.dbclick_group);
}
}
ex.onmousedown = function(event) {
tbe.onmousedown = function(event) {
if (document.getElementById("main_menu").style.top != "-1000px") {
HideMenus();
}
@ -134,14 +145,14 @@ function AppendTab(tab, ParentId, InsertBeforeId, InsertAfterId, Append, Index,
EventExpandBox(this.parentNode.parentNode);
}
}
ex.onmouseenter = function(event) {
tbe.onmouseenter = function(event) {
this.classList.add("hover");
}
ex.onmouseleave = function(event) {
tbe.onmouseleave = function(event) {
this.classList.remove("hover");
}
if (!opt.never_show_close) {
if (!opt.never_show_close && cl) {
cl.onmousedown = function(event) {
event.stopImmediatePropagation();
if (event.which != 3) {
@ -156,7 +167,7 @@ function AppendTab(tab, ParentId, InsertBeforeId, InsertAfterId, Append, Index,
}
}
th.onclick = function(event) {
tbh.onclick = function(event) {
event.stopImmediatePropagation();
if (document.getElementById("main_menu").style.top != "-1000px") {
HideMenus();
@ -167,16 +178,16 @@ function AppendTab(tab, ParentId, InsertBeforeId, InsertAfterId, Append, Index,
}
}
}
th.ondblclick = function(event) {
tbh.ondblclick = function(event) {
if (event.target.classList && event.target.classList.contains("tab_header")) {
ActionClickTab(this.parentNode, opt.dbclick_tab);
}
}
th.onmousedown = function(event) {
tbh.onmousedown = function(event) {
if (browserId == "V") {
chrome.windows.getCurrent({populate: false}, function(window) {
if (CurrentWindowId != window.id) {
if (tt.CurrentWindowId != window.id && window.focused) {
location.reload();
}
});
@ -194,13 +205,13 @@ function AppendTab(tab, ParentId, InsertBeforeId, InsertAfterId, Append, Index,
}
}
th.onmouseover = function(event) {
tbh.onmouseover = function(event) {
this.classList.add("tab_header_hover");
if (opt.never_show_close == false && opt.always_show_close == false) {
this.classList.add("close_show");
}
}
th.onmouseleave = function(event) {
tbh.onmouseleave = function(event) {
this.classList.remove("tab_header_hover");
if (opt.never_show_close == false && opt.always_show_close == false) {
this.classList.remove("close_show");
@ -209,26 +220,33 @@ function AppendTab(tab, ParentId, InsertBeforeId, InsertAfterId, Append, Index,
th.ondragstart = function(event) { // DRAG START
tbh.ondragstart = function(event) { // DRAG START
TabStartDrag(this.parentNode, event);
}
th.ondragenter = function(event) {
tbh.ondragenter = function(event) {
this.classList.remove("tab_header_hover");
DragOverTimer = false;
setTimeout(function() {
DragOverTimer = true;
}, 1000);
}
th.ondragleave = function(event) {
tbh.ondragleave = function(event) {
RemoveHighlight();
}
th.ondragover = function(event) {
tbh.ondragover = function(event) {
TabDragOver(this, event);
if (opt.open_tree_on_hover && tt.DragOverId != this.id) {
if (this.parentNode.classList.contains("c") && this.parentNode.classList.contains("dragged_tree") == false) {
clearTimeout(tt.DragOverTimer);
tt.DragOverId = this.id;
let This = this;
tt.DragOverTimer = setTimeout(function() {
if (tt.DragOverId == This.id) {
This.parentNode.classList.add("o");
This.parentNode.classList.remove("c");
}
}, 1500);
}
}
}
mi.onmousedown = function(event) {
@ -244,59 +262,57 @@ function AppendTab(tab, ParentId, InsertBeforeId, InsertAfterId, Append, Index,
}
let parent;
if (tab.pinned) {
if (p.tab.pinned) {
parent = document.getElementById("pin_list");
} else {
if (ParentId == false || ParentId == undefined || document.getElementById(ParentId) == null || document.querySelector(".pin[id='"+ParentId+"']") != null || ParentId == "pin_list") {
parent = document.getElementById("ct"+active_group);
if (p.ParentId == false || p.ParentId == undefined || document.getElementById(p.ParentId) == null || document.querySelector(".pin[id='"+p.ParentId+"']") != null || p.ParentId == "pin_list") {
parent = document.getElementById("ct"+tt.active_group);
} else {
parent = document.getElementById("ct"+ParentId);
parent = document.getElementById("ct"+p.ParentId);
if (parent.children.length == 0) {
parent.parentNode.classList.add("o");
parent.parentNode.classList.remove("c");
}
}
}
if (Append && parent) {
if (p.Append && parent) {
parent.appendChild(tb);
}
if (!Append && parent) {
if (!p.Append && parent) {
parent.prepend(tb);
}
if (InsertBeforeId) {
let Before = document.getElementById(InsertBeforeId);
if (p.InsertBeforeId) {
let Before = document.getElementById(p.InsertBeforeId);
if (Before != null) {
if ((tab.pinned && Before.classList.contains("pin")) || (tab.pinned == false && Before.classList.contains("tab"))) {
if ((p.tab.pinned && Before.classList.contains("pin")) || (p.tab.pinned == false && Before.classList.contains("tab"))) {
Before.parentNode.insertBefore(tb, Before);
}
}
}
if (InsertAfterId) {
let After = document.getElementById(InsertAfterId);
if (p.InsertAfterId) {
let After = document.getElementById(p.InsertAfterId);
if (After != null) {
if ((tab.pinned && After.classList.contains("pin")) || (tab.pinned == false && After.classList.contains("tab"))) {
if ((p.tab.pinned && After.classList.contains("pin")) || (p.tab.pinned == false && After.classList.contains("tab"))) {
InsterAfterNode(tb, After);
}
}
}
if (Index) {
if (tb.parentNode.childNodes.length >= Index) {
tb.parentNode.insertBefore(tb, tb.parentNode.childNodes[Index]);
} else {
tb.parentNode.appendChild(tb);
}
GetFaviconAndTitle(p.tab.id, p.addCounter);
if (!p.SkipMediaIcon) {
RefreshMediaIcon(p.tab.id);
}
GetFaviconAndTitle(tab.id, addCounter);
RefreshMediaIcon(tab.id);
if (tab.active && SkipSetActive == false) {
SetActiveTab(tab.id);
if (p.tab.active && !p.SkipSetActive) {
SetActiveTab(p.tab.id);
}
if (Scroll) {
ScrollToTab(tab.id);
if (p.Scroll) {
ScrollToTab(p.tab.id);
}
return tb;
}
function RemoveTabFromList(tabId) {
if (opt.debug) {
log("f: RemoveTabFromList, tabId: "+tabId);
@ -309,7 +325,7 @@ function RemoveTabFromList(tabId) {
function SetTabClass(tabId, pin) {
let PinList = document.getElementById("pin_list");
let GroupList = document.getElementById("ct"+active_group);
let GroupList = document.getElementById("ct"+tt.active_group);
let Tab = document.getElementById(tabId);
if (Tab != null) {
if (pin) {
@ -323,9 +339,9 @@ function SetTabClass(tabId, pin) {
if (document.getElementById("ct"+tabId).childNodes.length > 0) { // flatten out children
let tabs = document.querySelectorAll("#ct"+tabId+" .pin, #ct"+tabId+" .tab");
for (let i = tabs.length-1; i >= 0; i--) {
tabs[i].remove("tab");
tabs[i].remove("o");
tabs[i].remove("c");
tabs[i].classList.remove("tab");
tabs[i].classList.remove("o");
tabs[i].classList.remove("c");
tabs[i].classList.add("pin");
InsterAfterNode(tabs[i], Tab);
chrome.tabs.update(parseInt(tabs[i].id), {pinned: true});
@ -352,6 +368,7 @@ function SetTabClass(tabId, pin) {
function SetMultiTabsClass(TabsIds, pin) {
TabsIds.forEach(function(tabId){
SetTabClass(tabId, pin);
chrome.tabs.update(parseInt(tabId), {pinned: pin});
});
}
@ -373,8 +390,8 @@ function SetActiveTab(tabId, switchToGroup) {
document.querySelectorAll(".selected_folder").forEach(function(s){
s.classList.remove("selected_folder");
});
// document.querySelectorAll(".pin, #"+active_group+" .tab"+(TabGroup.length ? ", #"+TabGroup[0].id+" .tab" : "")).forEach(function(s){
document.querySelectorAll(".pin, #"+active_group+" .tab").forEach(function(s){
// document.querySelectorAll(".pin, #"+tt.active_group+" .tab"+(TabGroup.length ? ", #"+TabGroup[0].id+" .tab" : "")).forEach(function(s){
document.querySelectorAll(".pin, #"+tt.active_group+" .tab").forEach(function(s){
s.classList.remove("active_tab");
s.classList.remove("selected_tab");
s.classList.remove("selected_last");
@ -396,12 +413,12 @@ function ScrollToTab(tabId) {
if (Tab.getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().left < 0) {
document.getElementById("pin_list").scrollLeft = document.getElementById("pin_list").scrollLeft + Tab.getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().left - 2;
} else {
if (Tab.getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().left > document.getElementById(active_group).getBoundingClientRect().width - document.querySelector(".tab_header").getBoundingClientRect().width) {
if (Tab.getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().left > document.getElementById(tt.active_group).getBoundingClientRect().width - document.querySelector(".tab_header").getBoundingClientRect().width) {
document.getElementById("pin_list").scrollLeft = document.getElementById("pin_list").scrollLeft + Tab.getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().width + document.querySelector(".tab_header").getBoundingClientRect().width + 2;
}
}
}
if (Tab.classList.contains("tab") && document.querySelector("#"+active_group+" [id='"+tabId+"']") != null) {
if (Tab.classList.contains("tab") && document.querySelector("#"+tt.active_group+" [id='"+tabId+"']") != null) {
let Parents = GetParentsByClass(Tab, "c");
if (Parents.length > 0) {
Parents.forEach(function(s){
@ -409,11 +426,11 @@ function ScrollToTab(tabId) {
s.classList.add("o");
});
}
if (Tab.getBoundingClientRect().top - document.getElementById(active_group).getBoundingClientRect().top < 0) {
document.getElementById(active_group).scrollTop = document.getElementById(active_group).scrollTop + Tab.getBoundingClientRect().top - document.getElementById(active_group).getBoundingClientRect().top - 2;
if (Tab.getBoundingClientRect().top - document.getElementById(tt.active_group).getBoundingClientRect().top < 0) {
document.getElementById(tt.active_group).scrollTop = document.getElementById(tt.active_group).scrollTop + Tab.getBoundingClientRect().top - document.getElementById(tt.active_group).getBoundingClientRect().top - 2;
} else {
if (Tab.getBoundingClientRect().top - document.getElementById(active_group).getBoundingClientRect().top > document.getElementById(active_group).getBoundingClientRect().height - document.querySelector(".tab_header").getBoundingClientRect().height) {
document.getElementById(active_group).scrollTop = document.getElementById(active_group).scrollTop + Tab.getBoundingClientRect().top - document.getElementById(active_group).getBoundingClientRect().top - document.getElementById(active_group).getBoundingClientRect().height + document.querySelector(".tab_header").getBoundingClientRect().height + 10;
if (Tab.getBoundingClientRect().top - document.getElementById(tt.active_group).getBoundingClientRect().top > document.getElementById(tt.active_group).getBoundingClientRect().height - document.querySelector(".tab_header").getBoundingClientRect().height) {
document.getElementById(tt.active_group).scrollTop = document.getElementById(tt.active_group).scrollTop + Tab.getBoundingClientRect().top - document.getElementById(tt.active_group).getBoundingClientRect().top - document.getElementById(tt.active_group).getBoundingClientRect().height + document.querySelector(".tab_header").getBoundingClientRect().height + 10;
}
}
}
@ -424,7 +441,7 @@ function Detach(tabsIds, Folders) {
if (opt.debug) {
log("f: Detach");
}
chrome.windows.get(CurrentWindowId, {populate : true}, function(window) {
chrome.windows.get(tt.CurrentWindowId, {populate : true}, function(window) {
if (window.tabs.length == 1 || tabsIds.length == 0) {
return;
}
@ -438,62 +455,27 @@ function Detach(tabsIds, Folders) {
let Indexes = [];
let Parents = [];
let Expands = [];
let NewIds = []; // MOZILLA BUG 1398272
let NewTabs = [];
let Ind = 0;
tabsIds.forEach(function(tabId) {
let tab = document.getElementById(tabId);
NewIds.push(tabId); // MOZILLA BUG 1398272
Indexes.push(Array.from(tab.parentNode.children).indexOf(tab));
Parents.push(tab.parentNode.parentNode.id);
Expands.push( (tab.classList.contains("c") ? "c" : (tab.classList.contains("o") ? "o" : "")) );
});
chrome.windows.create({tabId: tabsIds[0], state:window.state}, function(new_window) {
tabsIds.forEach(function(tabId) {
chrome.tabs.move(tabId, {windowId: new_window.id, index:-1}, function(MovedTab) {
if (browserId == "F") { // MOZILLA BUG 1398272
if (Ind == 0) { // MOZILLA BUG 1398272
NewIds[Ind] = new_window.tabs[0].id; // MOZILLA BUG 1398272
} else { // MOZILLA BUG 1398272
NewIds[Ind] = MovedTab[0].id; // MOZILLA BUG 1398272
} // MOZILLA BUG 1398272
NewTabs.push({id: NewIds[Ind], index: Indexes[Ind], parent: ((tabsIds.indexOf(parseInt(Parents[Ind])) != -1) ? NewIds[tabsIds.indexOf(parseInt(Parents[Ind]))] : Parents[Ind]), expand: Expands[Ind]}); // MOZILLA BUG 1398272
} else { // MOZILLA BUG 1398272
NewTabs.push({id: tabsIds[Ind], index: Indexes[Ind], parent: Parents[Ind], expand: Expands[Ind]}); // PUSH TAB FROM INDEX
} // MOZILLA BUG 1398272
Ind++;
if (Ind >= Parents.length-1) {
// chrome.tabs.remove(new_window.tabs[0].id, null);
let Confirmations = 0;
let GiveUpLimit = 600;
if (opt.debug) {
log("Detach - Remote Append and Update Loop, waiting for confirmations after attach tabs");
}
var Append = setInterval(function() {
chrome.windows.get(new_window.id, function(confirm_new_window) {
chrome.runtime.sendMessage({command: "remote_update", groups: {}, folders: Folders, tabs: NewTabs, windowId: new_window.id}, function(response) {
if (response) {
Confirmations++;
}
});
GiveUpLimit--;
if (opt.debug) {
log("Detach -> Attach in new window confirmed: "+Confirmations+" times. If sidebar is not open in new window this loop will give up in: "+GiveUpLimit+" seconds");
}
if (Confirmations > 2 || GiveUpLimit < 0 || confirm_new_window == undefined) {
clearInterval(Append);
}
});
}, 1000);
if (Folders && Object.keys(Folders).length > 0) {
for (var folder in Folders) {
RemoveFolder(Folders[folder].id);
}
}
tabsIds.splice(0, 1);
chrome.tabs.move(tabsIds, {windowId: new_window.id, index:-1}, function(MovedTabs) {
if (Folders && Object.keys(Folders).length > 0) {
for (let folder in Folders) {
RemoveFolder(Folders[folder].id);
}
});
}
});
});
});
@ -509,9 +491,9 @@ function CloseTabs(tabsIds) {
Tab.classList.add("will_be_closed");
}
});
let activeTab = document.querySelector(".pin.active_tab, #"+active_group+" .tab.active_tab");
let activeTab = document.querySelector(".pin.active_tab, #"+tt.active_group+" .tab.active_tab");
if (activeTab != null && tabsIds.indexOf(parseInt(activeTab.id)) != -1) {
SwitchActiveTabBeforeClose(active_group);
SwitchActiveTabBeforeClose(tt.active_group);
}
tabsIds.forEach(function(tabId) {
let tab = document.getElementById(tabId);
@ -529,7 +511,7 @@ function CloseTabs(tabsIds) {
}
function DiscardTabs(tabsIds) {
var delay = 100;
let delay = 100;
let tabNode = document.getElementById(tabsIds[0]);
if (tabNode == null || tabNode.classList.contains("discarded") || tabNode.classList.contains("active_tab")) {
delay = 5;
@ -619,10 +601,10 @@ function ActivateNextTabBeforeClose() {
}
}
let will_be_closed = document.querySelectorAll("#"+active_group+" .will_be_closed");
let activeTab = will_be_closed.length > 0 ? will_be_closed[will_be_closed.length-1] : document.querySelector("#"+active_group+" .tab.active_tab");
let will_be_closed = document.querySelectorAll("#"+tt.active_group+" .will_be_closed");
let activeTab = will_be_closed.length > 0 ? will_be_closed[will_be_closed.length-1] : document.querySelector("#"+tt.active_group+" .tab.active_tab");
if (activeTab != null && document.querySelectorAll("#"+active_group+" .tab:not(.will_be_closed)").length > 1) {
if (activeTab != null && document.querySelectorAll("#"+tt.active_group+" .tab:not(.will_be_closed)").length > 1) {
if (opt.promote_children && activeTab.childNodes[1].firstChild != null) {
chrome.tabs.update(parseInt(activeTab.childNodes[1].firstChild.id), { active: true });
} else {
@ -655,10 +637,10 @@ function ActivatePrevTabBeforeClose() {
}
}
let will_be_closed = document.querySelectorAll("#"+active_group+" .will_be_closed");
let activeTab = will_be_closed.length > 0 ? will_be_closed[0] : document.querySelector("#"+active_group+" .tab.active_tab");
let will_be_closed = document.querySelectorAll("#"+tt.active_group+" .will_be_closed");
let activeTab = will_be_closed.length > 0 ? will_be_closed[0] : document.querySelector("#"+tt.active_group+" .tab.active_tab");
if (activeTab != null && document.querySelectorAll("#"+active_group+" .tab:not(.will_be_closed)").length > 1) {
if (activeTab != null && document.querySelectorAll("#"+tt.active_group+" .tab:not(.will_be_closed)").length > 1) {
if (opt.promote_children && activeTab.childNodes[1].firstChild != null) {
chrome.tabs.update(parseInt(activeTab.childNodes[1].firstChild.id), { active: true });
} else {
@ -691,10 +673,10 @@ function ActivateNextTab(allow_reverse) {
}
}
let will_be_closed = document.querySelectorAll("#"+active_group+" .will_be_closed");
let activeTab = will_be_closed.length > 0 ? will_be_closed[will_be_closed.length-1] : document.querySelector("#"+active_group+" .tab.active_tab");
let will_be_closed = document.querySelectorAll("#"+tt.active_group+" .will_be_closed");
let activeTab = will_be_closed.length > 0 ? will_be_closed[will_be_closed.length-1] : document.querySelector("#"+tt.active_group+" .tab.active_tab");
if (activeTab != null && document.querySelectorAll("#"+active_group+" .tab").length > 1) {
if (activeTab != null && document.querySelectorAll("#"+tt.active_group+" .tab").length > 1) {
let FirstChild = activeTab.childNodes[1].firstChild;
if (FirstChild != null) {
chrome.tabs.update(parseInt(FirstChild.id), { active: true });
@ -733,10 +715,10 @@ function ActivatePrevTab(allow_reverse) {
}
}
let will_be_closed = document.querySelectorAll("#"+active_group+" .will_be_closed");
let activeTab = will_be_closed.length > 0 ? will_be_closed[0] : document.querySelector("#"+active_group+" .tab.active_tab");
let will_be_closed = document.querySelectorAll("#"+tt.active_group+" .will_be_closed");
let activeTab = will_be_closed.length > 0 ? will_be_closed[0] : document.querySelector("#"+tt.active_group+" .tab.active_tab");
if (activeTab != null && document.querySelectorAll("#"+active_group+" .tab").length > 1) {
if (activeTab != null && document.querySelectorAll("#"+tt.active_group+" .tab").length > 1) {
let pSchildren = activeTab.previousSibling != null ? document.querySelectorAll("#ct"+activeTab.previousSibling.id+" .tab") : null;
if (activeTab.previousSibling != null && pSchildren.length > 0) {
chrome.tabs.update(parseInt(pSchildren[pSchildren.length-1].id), { active: true });
@ -761,18 +743,19 @@ function OpenNewTab(pin, parentId) {
if (pin) {
chrome.tabs.create({pinned: true}, function(tab) {
if (parentId) {
AppendTab(tab, "pin_list", false, parentId, true, false, true, false, false, true, false);
schedule_update_data++;
AppendTab({tab: tab, ParentId: "pin_list", InsertAfterId: parentId, Append: true, Scroll: true});
tt.schedule_update_data++;
}
newTabUrl = tab.url;
});
} else {
chrome.tabs.create({}, function(tab) {
if (parentId) {
AppendTab(tab, parentId, false, false, (opt.append_orphan_tab == "top" ? false : true), false, true, false, false, true, false);
schedule_update_data++;
AppendTab({tab: tab, ParentId: parentId, Append: (opt.append_orphan_tab == "top" ? false : true), Scroll: true});
tt.schedule_update_data++;
}
if (opt.move_tabs_on_url_change == "from_empty") {
chrome.runtime.sendMessage({command: "remove_tab_from_empty_tabs", tabId: tab.id});
}
newTabUrl = tab.url;
});
}
}
@ -788,7 +771,7 @@ function DuplicateTab(SourceTabNode) {
}
InsterAfterNode(DupTab, SourceTabNode);
RefreshExpandStates();
schedule_update_data++;
tt.schedule_update_data++;
RefreshCounters();
clearInterval(DupRetry);
}
@ -803,7 +786,7 @@ function DuplicateTab(SourceTabNode) {
}
function DeselectTabs() {
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
s.classList.remove("selected_tab");
s.classList.remove("selected_last");
});
@ -830,13 +813,13 @@ function EventExpandBox(Node) {
if (opt.collapse_other_trees) {
let thisTreeTabs = GetParentsByClass(Node.childNodes[0], "tab"); // start from tab's first child, instead of tab, important to include clicked tab as well
let thisTreeFolders = GetParentsByClass(Node.childNodes[0], "folder");
document.querySelectorAll("#"+active_group+" .o.tab").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .o.tab").forEach(function(s){
s.classList.remove("o");
s.classList.add("c");
chrome.runtime.sendMessage({ command: "update_tab", tabId: parseInt(s.id), tab: { expand: "c" } });
});
document.querySelectorAll("#"+active_group+" .o.folder").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .o.folder").forEach(function(s){
s.classList.remove("o");
s.classList.add("c");
});
@ -873,14 +856,14 @@ function EventExpandBox(Node) {
function EventSelectTab(event, TabNode) {
DeselectFolders();
if (event.shiftKey) { // SET SELECTION WITH SHIFT
let activeTab = document.querySelector("#"+active_group+" .selected_tab.selected_last");
let activeTab = document.querySelector("#"+tt.active_group+" .selected_tab.selected_last");
if (activeTab == null) {
activeTab = document.querySelector(".pin.active_tab, #"+active_group+" .tab.active_tab");
activeTab = document.querySelector(".pin.active_tab, #"+tt.active_group+" .tab.active_tab");
}
if (activeTab != null && TabNode.parentNode.id == activeTab.parentNode.id) {
if (!event.ctrlKey) {
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
s.classList.remove("selected_frozen");
s.classList.remove("selected_temporarly");
s.classList.remove("selected_tab");
@ -936,11 +919,17 @@ function ActionClickTab(TabNode, bgOption) {
chrome.tabs.reload(parseInt(TabNode.id));
}
if (bgOption == "unload_tab") {
SwitchActiveTabBeforeClose(active_group);
DiscardTabs([parseInt(TabNode.id)]);
if (TabNode.classList.contains("active_tab")) {
SwitchActiveTabBeforeClose(tt.active_group);
setTimeout(function() {
DiscardTabs([parseInt(TabNode.id)]);
}, 500);
} else {
DiscardTabs([parseInt(TabNode.id)]);
}
}
if (bgOption == "activate_previous_active" && TabNode.classList.contains("active_tab")) {
chrome.tabs.update(parseInt(bggroups[active_group].prev_active_tab), {active: true});
chrome.tabs.update(parseInt(tt.groups[tt.active_group].prev_active_tab), {active: true});
}
}
@ -952,24 +941,24 @@ function TabStartDrag(Node, event) {
event.stopPropagation();
event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0);
event.dataTransfer.setData("text", "");
event.dataTransfer.setData("SourceWindowId", CurrentWindowId);
event.dataTransfer.setData("SourceWindowId", tt.CurrentWindowId);
CleanUpDragClasses();
EmptyDragAndDrop();
DragNodeClass = "tab";
tt.DragNodeClass = "tab";
let TabsIds = [];
let TabsIdsParents = [];
let TabsIdsSelected = [];
if (Node.classList.contains("selected_tab")) {
document.querySelectorAll(".group:not(#"+active_group+") .selected_tab").forEach(function(s){
document.querySelectorAll(".group:not(#"+tt.active_group+") .selected_tab").forEach(function(s){
s.classList.add("selected_frozen");
s.classList.remove("selected_tab");
s.classList.remove("selected_last");
});
document.querySelectorAll("#pin_list .selected_tab, .group#"+active_group+" .selected_tab").forEach(function(s){
document.querySelectorAll("#pin_list .selected_tab, .group#"+tt.active_group+" .selected_tab").forEach(function(s){
TabsIdsSelected.push(parseInt(s.id));
});
} else {
@ -977,21 +966,23 @@ function TabStartDrag(Node, event) {
Node.classList.add("selected_temporarly");
Node.classList.add("selected_tab");
TabsIdsSelected.push(parseInt(Node.id));
event.dataTransfer.setData("DraggedTabNode", Node.id);
}
document.querySelectorAll("[id='"+Node.id+"'], [id='"+Node.id+"'] .tab").forEach(function(s){
s.classList.add("dragged_tree");
});
if (opt.max_tree_drag_drop) {
if (opt.max_tree_drag_drop || opt.max_tree_depth >= 0) {
document.querySelectorAll(".dragged_tree .tab").forEach(function(s){
let parents = GetParentsByClass(s.parentNode, "dragged_tree");
if (parents.length > DragTreeDepth) {
DragTreeDepth = parents.length;
if (parents.length > tt.DragTreeDepth) {
tt.DragTreeDepth = parents.length;
}
});
} else {
DragTreeDepth = -1;
tt.DragTreeDepth = -1;
}
// REST OF SELECTED TABS THAT WILL BE DRAGGED
@ -1000,9 +991,21 @@ function TabStartDrag(Node, event) {
TabsIds.push(parseInt(s.id));
TabsIdsParents.push(s.parentNode.id);
});
let DraggedFolderParents = GetParentsByClass(Node, "folder");
DraggedFolderParents.forEach(function(s){
s.classList.add("dragged_parents");
});
let DraggedParents = GetParentsByClass(Node, "tab");
DraggedParents.forEach(function(s){
s.classList.add("dragged_parents");
});
DragAndDropData = {TabsIds: TabsIds, TabsIdsParents: TabsIdsParents, TabsIdsSelected: TabsIdsSelected};
event.dataTransfer.setData("Class", "tab");
event.dataTransfer.setData("TabsIds", JSON.stringify(TabsIds));
event.dataTransfer.setData("TabsIdsParents", JSON.stringify(TabsIdsParents));
event.dataTransfer.setData("TabsIdsSelected", JSON.stringify(TabsIdsSelected));
@ -1010,12 +1013,17 @@ function TabStartDrag(Node, event) {
chrome.runtime.sendMessage({
command: "drag_drop",
DragNodeClass: "tab",
DragTreeDepth: DragTreeDepth
DragTreeDepth: tt.DragTreeDepth
});
if (opt.debug) {
log("f: TabStartDrag, Node: "+Node.id+", TabsIdsSelected: "+JSON.stringify(TabsIdsSelected)+", TabsIds: "+JSON.stringify(TabsIds)+", TabsIdsParents: "+JSON.stringify(TabsIdsParents) );
}
}
function TabDragOver(Node, event) {
if (DragNodeClass == "tab" && Node.parentNode.classList.contains("dragged_tree") == false) {
if (tt.DragNodeClass == "tab" && Node.parentNode.classList.contains("dragged_tree") == false) {
if (Node.parentNode.classList.contains("pin")) {
if (Node.parentNode.classList.contains("before") == false && event.layerX < Node.clientWidth/2) {
@ -1033,10 +1041,11 @@ function TabDragOver(Node, event) {
}
if (Node.parentNode.classList.contains("tab")) {
let P = (GetParentsByClass(Node, "tab")).length + DragTreeDepth;
let PGroup = Node.parentNode.parentNode.parentNode.classList.contains("group");
if (Node.parentNode.classList.contains("before") == false && event.layerY < Node.clientHeight/3 && (P <= opt.max_tree_depth+1 || opt.max_tree_depth<0 || PGroup || opt.max_tree_drag_drop == false)) {
let PDepth = (GetParentsByClass(Node, "tab")).length + tt.DragTreeDepth;
let PIsGroup = Node.parentNode.parentNode.parentNode.classList.contains("group");
let PIsDraggedParents = Node.parentNode.classList.contains("dragged_parents");
if (Node.parentNode.classList.contains("before") == false && event.layerY < Node.clientHeight/3 && (PDepth <= opt.max_tree_depth+1 || opt.max_tree_depth < 0 || PIsGroup || PIsDraggedParents || opt.max_tree_drag_drop == false)) {
RemoveHighlight();
Node.parentNode.classList.remove("inside");
Node.parentNode.classList.remove("after");
@ -1045,7 +1054,7 @@ function TabDragOver(Node, event) {
}
if (Node.parentNode.classList.contains("inside") == false && event.layerY > Node.clientHeight/3 && event.layerY <= 2*(Node.clientHeight/3) && (P <= opt.max_tree_depth || opt.max_tree_depth<0 || opt.max_tree_drag_drop == false)) {
if (Node.parentNode.classList.contains("inside") == false && event.layerY > Node.clientHeight/3 && event.layerY <= 2*(Node.clientHeight/3) && (PDepth <= opt.max_tree_depth || opt.max_tree_depth < 0 || PIsDraggedParents || opt.max_tree_drag_drop == false)) {
RemoveHighlight();
Node.parentNode.classList.remove("before");
Node.parentNode.classList.remove("after");
@ -1054,7 +1063,7 @@ function TabDragOver(Node, event) {
}
if (Node.parentNode.classList.contains("after") == false && Node.parentNode.classList.contains("o") == false && event.layerY > 2*(Node.clientHeight/3) && (P <= opt.max_tree_depth+1 || opt.max_tree_depth<0 || PGroup || opt.max_tree_drag_drop == false)) {
if (Node.parentNode.classList.contains("after") == false && Node.parentNode.classList.contains("o") == false && event.layerY > 2*(Node.clientHeight/3) && (PDepth <= opt.max_tree_depth+1 || opt.max_tree_depth < 0 || PIsGroup || PIsDraggedParents || opt.max_tree_drag_drop == false)) {
RemoveHighlight();
Node.parentNode.classList.remove("inside");
Node.parentNode.classList.remove("before");

View File

@ -33,9 +33,9 @@ function ApplyTheme(theme) {
ApplyTabsMargins(theme["TabsMargins"]);
RefreshGUI();
for (var groupId in bggroups) {
for (var groupId in tt.groups) {
let groupTitle = document.getElementById("_gte"+groupId);
if (groupTitle != null && bggroups[groupId].font == "") {
if (groupTitle != null && tt.groups[groupId].font == "") {
groupTitle.style.color = "";
}
}
@ -88,6 +88,28 @@ function ApplyTabsMargins(size){
}
}
function GetCurrentToolbar(storage) {
if (storage["toolbar"]) {
return storage["toolbar"];
} else {
return DefaultToolbar;
}
}
function GetCurrentTheme(storage) {
if (storage["current_theme"] && storage["themes"] && storage["themes"][storage["current_theme"]]) {
let theme = storage["themes"][storage["current_theme"]];
let correctedTheme = CheckTheme(theme);
if (correctedTheme.theme_version < 4 && storage["preferences"].show_toolbar == undefined) {
opt.show_toolbar = correctedTheme.ToolbarShow;
SavePreferences();
}
return correctedTheme;
} else {
return DefaultTheme;
}
}
// OPTIONS PAGE
function LoadTheme(ThemeId, reloadInSidebar) {

View File

@ -6,7 +6,7 @@
// RESTORE LAST USED SEARCH TYPE (URL OR TITLE) IN TOOLBAR SEARCH
function RestoreToolbarSearchFilter() {
chrome.runtime.sendMessage({command: "get_search_filter", windowId: CurrentWindowId}, function(response) {
chrome.runtime.sendMessage({command: "get_search_filter", windowId: tt.CurrentWindowId}, function(response) {
let ButtonFilter = document.getElementById("button_filter_type");
if (response == "url") {
ButtonFilter.classList.add("url");
@ -20,9 +20,9 @@ function RestoreToolbarSearchFilter() {
// RESTORE LAST ACTIVE SHELF (SEARCH, TOOLS, GROUPS, SESSION OR FOLDER) IN TOOLBAR
function RestoreToolbarShelf() {
chrome.runtime.sendMessage({command: "get_active_shelf", windowId: CurrentWindowId}, function(response) {
chrome.runtime.sendMessage({command: "get_active_shelf", windowId: tt.CurrentWindowId}, function(response) {
let filterBox = document.getElementById("filter_box");
filterBox.setAttribute("placeholder", caption_searchbox);
filterBox.setAttribute("placeholder", labels.searchbox);
filterBox.style.opacity = "1";
document.querySelectorAll(".on").forEach(function(s){
@ -103,7 +103,7 @@ function ShelfToggle(mousebutton, button, toolbarId, SendMessage) {
s.classList.add("hidden");
});
document.getElementById(toolbarId).classList.remove("hidden");
chrome.runtime.sendMessage({command: "set_active_shelf", active_shelf: SendMessage, windowId: CurrentWindowId});
chrome.runtime.sendMessage({command: "set_active_shelf", active_shelf: SendMessage, windowId: tt.CurrentWindowId});
document.querySelectorAll(".on:not(#"+button.id+")").forEach(function(s){
s.classList.remove("on");
});
@ -158,7 +158,7 @@ function RecreateToolbar(NewToolbar) {
SearchInput.classList = "text_input";
SearchInput.id = "filter_box";
SearchInput.type = "text";
SearchInput.placeholder = caption_searchbox;
SearchInput.placeholder = labels.searchbox;
SearchBox.appendChild(SearchInput);
let ClearX = document.createElement("div");
@ -308,14 +308,14 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "button_new") {
s.onclick = function(event) {
if (event.which == 1) {
OpenNewTab(false, active_group);
OpenNewTab(false, tt.active_group);
}
}
s.onmousedown = function(event) {
// DUPLICATE TAB
if (event.which == 2) {
event.preventDefault();
let activeTab = document.querySelector("#"+active_group+" .active_tab") != null ? document.querySelector("#"+active_group+" .active_tab") : document.querySelector(".pin.active_tab") != null ? document.querySelector(".pin.active_tab") : null;
let activeTab = document.querySelector("#"+tt.active_group+" .active_tab") != null ? document.querySelector("#"+tt.active_group+" .active_tab") : document.querySelector(".pin.active_tab") != null ? document.querySelector(".pin.active_tab") : null;
if (activeTab != null) {
DuplicateTab(activeTab);
}
@ -339,7 +339,7 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "button_pin") {
s.onmousedown = function(event) {
if (event.which == 1) {
let Tabs = document.querySelectorAll(".pin.active_tab, .pin.selected_tab, #"+active_group+" .active_tab, #"+active_group+" .selected_tab");
let Tabs = document.querySelectorAll(".pin.active_tab, .pin.selected_tab, #"+tt.active_group+" .active_tab, #"+tt.active_group+" .selected_tab");
Tabs.forEach(function(s){
chrome.tabs.update(parseInt(s.id), { pinned: Tabs[0].classList.contains("tab") });
})
@ -369,15 +369,15 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
}
// MOVE TAB TO NEW WINDOW (DETACH)
if (s.id == "button_detach" || s.id == "button_move") {
if (s.id == "button_detach" || s.id == "button_move") { // move is legacy name of detach button
s.onmousedown = function(event) {
if (event.which == 1) {
if (document.querySelectorAll("#"+active_group+" .selected_folder").length > 0){
if (document.querySelectorAll("#"+tt.active_group+" .selected_folder").length > 0){
let detach = GetSelectedFolders();
Detach(detach.TabsIds, detach.Folders);
} else {
let tabsArr = [];
document.querySelectorAll(".pin.selected_tab, .pin.active_tab, #"+active_group+" .selected_tab, #"+active_group+" .active_tab").forEach(function(s){
document.querySelectorAll(".pin.selected_tab, .pin.active_tab, #"+tt.active_group+" .selected_tab, #"+tt.active_group+" .active_tab").forEach(function(s){
tabsArr.push(parseInt(s.id));
if (s.childNodes[1].childNodes.length > 0) {
document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){
@ -395,18 +395,18 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "filter_search_go_prev") {
s.onmousedown = function(event) {
if (event.which == 1) {
let filtered = document.querySelectorAll("#"+active_group+" .tab.filtered");
let filtered = document.querySelectorAll("#"+tt.active_group+" .tab.filtered");
if (filtered.length > 0) {
document.querySelectorAll(".highlighted_search").forEach(function(s){
s.classList.remove("highlighted_search");
});
if (SearchIndex == 0) {
SearchIndex = filtered.length-1;
if (tt.SearchIndex == 0) {
tt.SearchIndex = filtered.length-1;
} else {
SearchIndex--;
tt.SearchIndex--;
}
filtered[SearchIndex].classList.add("highlighted_search");
ScrollToTab(filtered[SearchIndex].id);
filtered[tt.SearchIndex].classList.add("highlighted_search");
ScrollToTab(filtered[tt.SearchIndex].id);
}
}
}
@ -416,18 +416,18 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "filter_search_go_next") {
s.onmousedown = function(event) {
if (event.which == 1) {
let filtered = document.querySelectorAll("#"+active_group+" .tab.filtered");
let filtered = document.querySelectorAll("#"+tt.active_group+" .tab.filtered");
if (filtered.length > 0) {
document.querySelectorAll(".highlighted_search").forEach(function(s){
s.classList.remove("highlighted_search");
});
if (SearchIndex == filtered.length-1) {
SearchIndex = 0;
if (tt.SearchIndex == filtered.length-1) {
tt.SearchIndex = 0;
} else {
SearchIndex++;
tt.SearchIndex++;
}
filtered[SearchIndex].classList.add("highlighted_search");
ScrollToTab(filtered[SearchIndex].id);
filtered[tt.SearchIndex].classList.add("highlighted_search");
ScrollToTab(filtered[tt.SearchIndex].id);
}
}
}
@ -465,8 +465,8 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "button_remove_group") {
s.onmousedown = function(event) {
if (event.which == 1) {
if (active_group != "tab_list") {
GroupRemove(active_group, event.shiftKey);
if (tt.active_group != "tab_list") {
GroupRemove(tt.active_group, event.shiftKey);
}
}
}
@ -478,8 +478,8 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "button_edit_group") {
s.onmousedown = function(event) {
if (event.which == 1) {
if (active_group != "tab_list") {
ShowGroupEditWindow(active_group);
if (tt.active_group != "tab_list") {
ShowGroupEditWindow(tt.active_group);
}
}
}
@ -489,7 +489,7 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "button_export_group") {
s.onmousedown = function(event) {
if (event.which == 1) {
ExportGroup(active_group, bggroups[active_group].name+".tt_group", false);
ExportGroup(tt.active_group, tt.groups[tt.active_group].name, false);
}
}
}
@ -510,7 +510,8 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "button_new_folder") {
s.onmousedown = function(event) {
if (event.which == 1) {
AddNewFolder(undefined, undefined, undefined, undefined, undefined, undefined, true);
let FolderId = AddNewFolder({SetEvents: true});
ShowRenameFolderDialog(FolderId);
}
}
}
@ -519,8 +520,8 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "button_edit_folder") {
s.onmousedown = function(event) {
if (event.which == 1) {
if (document.querySelectorAll("#"+active_group+" .selected_folder").length > 0) {
ShowRenameFolderDialog(document.querySelectorAll("#"+active_group+" .selected_folder")[0].id);
if (document.querySelectorAll("#"+tt.active_group+" .selected_folder").length > 0) {
ShowRenameFolderDialog(document.querySelectorAll("#"+tt.active_group+" .selected_folder")[0].id);
}
}
}
@ -529,7 +530,7 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "button_remove_folder") {
s.onmousedown = function(event) {
if (event.which == 1) {
document.querySelectorAll("#"+active_group+" .selected_folder").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .selected_folder").forEach(function(s){
RemoveFolder(s.id);
});
}
@ -539,9 +540,9 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (s.id == "button_unload" || s.id == "button_discard") {
s.onmousedown = function(event) {
if (event.which == 1) {
if (document.querySelectorAll(".pin.selected_tab:not(.active_tab), #"+active_group+" .selected_tab:not(.active_tab)").length > 0) {
if (document.querySelectorAll(".pin.selected_tab:not(.active_tab), #"+tt.active_group+" .selected_tab:not(.active_tab)").length > 0) {
DiscardTabs(
Array.prototype.map.call(document.querySelectorAll(".pin:not(.active_tab), #"+active_group+" .selected_tab:not(.active_tab)"), function(s){
Array.prototype.map.call(document.querySelectorAll(".pin:not(.active_tab), #"+tt.active_group+" .selected_tab:not(.active_tab)"), function(s){
return parseInt(s.id);
})
);
@ -571,7 +572,7 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
s.onmousedown = function(event) {
if (event.which == 1) {
let d = new Date();
ExportSession((d.toLocaleString().replace("/", ".").replace("/", ".").replace(":", "").replace(":", ""))+".tt_session", true, false, false);
ExportSession((d.toLocaleString().replace("/", ".").replace("/", ".").replace(":", "").replace(":", "")), true, false, false);
}
}
}
@ -595,11 +596,11 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
if (this.classList.contains("url")) {
this.classList.remove("url");
this.classList.add("title");
chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "title", windowId: CurrentWindowId});
chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "title", windowId: tt.CurrentWindowId});
} else {
this.classList.remove("title");
this.classList.add("url");
chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "url", windowId: CurrentWindowId});
chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "url", windowId: tt.CurrentWindowId});
}
FindTab(document.getElementById("filter_box").value);
}

View File

@ -5,57 +5,98 @@
function RecheckFirefox() {
chrome.tabs.query({pinned: false, currentWindow: true}, function(tabs) {
let last_tabId = tabs[tabs.length-1].id;
let p = [];
let p_tt = [];
let t_ref = {};
let t_ind = 0;
let ok = 0;
let ti = 0;
let tc = tabs.length;
for (ti = 0; ti < tc; ti++) {
let tabId = tabs[ti].id;
p.push("");
p_tt.push("");
let t = Promise.resolve(browser.sessions.getTabValue(tabId, "TTdata")).then(function(TabData) {
if (TabData != undefined) {
t_ref[TabData.ttid] = tabs[t_ind].id;
p_tt[t_ind] = TabData.parent_ttid;
p[t_ind] = TabData.parent;
}
t_ind++;
if (tabId == last_tabId) {
let i = 0;
for (i = 0; i < p.length; i++) {
if (t_ref[p_tt[i]]) {
p[i] = t_ref[p_tt[i]];
}
if (tabs.length > 1) {
let last_tabId = tabs[tabs.length-1].id;
let p = [];
let p_tt = [];
let t_ref = {};
let t_ind = 0;
let ok = 0;
let ti = 0;
let tc = tabs.length;
for (ti = 0; ti < tc; ti++) {
let tabId = tabs[ti].id;
p.push("");
p_tt.push("");
let t = Promise.resolve(browser.sessions.getTabValue(tabId, "TTdata")).then(function(TabData) {
if (TabData != undefined) {
t_ref[TabData.ttid] = tabs[t_ind].id;
p_tt[t_ind] = TabData.parent_ttid;
p[t_ind] = TabData.parent;
}
for (i = 0; i < p.length; i++) {
let Tab = document.getElementById(tabs[i].id);
if (Tab && p[i] == Tab.parentNode.parentNode.id) {
ok++;
t_ind++;
if (tabId == last_tabId) {
let i = 0;
for (i = 0; i < p.length; i++) {
if (t_ref[p_tt[i]]) {
p[i] = t_ref[p_tt[i]];
}
}
for (i = 0; i < p.length; i++) {
let Tab = document.getElementById(tabs[i].id);
if (Tab && p[i] == Tab.parentNode.parentNode.id) {
ok++;
}
}
if (ok < tabs.length*0.5) {
if (opt.debug) {
log("emergency reload");
}
chrome.storage.local.set({emergency_reload: true});
chrome.runtime.sendMessage({command: "reload"});
chrome.runtime.sendMessage({command: "reload_sidebar"});
location.reload();
} else {
if (opt.debug) {
log("f: RecheckFirefox, ok");
}
}
}
if (ok < tabs.length*0.5) {
if (opt.debug) {
log("emergency reload");
}
chrome.storage.local.set({emergency_reload: true});
chrome.runtime.sendMessage({command: "reload"});
chrome.runtime.sendMessage({command: "reload_sidebar"});
location.reload();
} else {
if (opt.debug) {
log("f: RecheckFirefox, ok");
}
}
}
});
});
}
}
});
}
function SavePreferences() {
chrome.storage.local.set({preferences: opt});
chrome.runtime.sendMessage({command: "reload_options", opt: opt});
}
function LoadDefaultPreferences() {
opt = Object.assign({}, DefaultPreferences);
}
function ShowOpenFileDialog(extension) {
let body = document.getElementById("body");
let inp = document.createElement("input");
inp.id = "file_import";
inp.type = "file";
inp.accept = extension;
inp.style.display = "none";
body.appendChild(inp);
inp.click();
return inp;
}
function SaveFile(filename, extension, data) {
let file = new File([JSON.stringify(data)], filename+"."+extension, {type: "text/"+extension+";charset=utf-8"} );
let body = document.getElementById("body");
let savelink = document.createElement("a");
savelink.href = URL.createObjectURL(file);
savelink.fileSize = file.size;
savelink.target = "_blank";
savelink.style.display = "none";
savelink.type = "file";
savelink.download = filename+"."+extension;
body.appendChild(savelink);
setTimeout(function() {
savelink.click();
setTimeout(function() {
savelink.parentNode.removeChild(savelink);
}, 60000);
}, 10);
}
function AppendToNode(Node, AppendNode) {
if (Node != null && AppendNode != null) {
@ -86,6 +127,7 @@ function HideRenameDialogs() {
s.style.left = "-500px";
});
}
function GetParentsByClass(Node, Class) {
let Parents = [];
let ParentNode = Node;
@ -97,6 +139,7 @@ function GetParentsByClass(Node, Class) {
}
return Parents;
}
function GetParentsBy2Classes(Node, ClassA, ClassB) {
let Parents = [];
let ParentNode = Node;
@ -129,12 +172,12 @@ function GetSelectedFolders() {
}
let res = {Folders: {}, FoldersSelected: [], TabsIds: [], TabsIdsParents: []};
document.querySelectorAll("#"+active_group+" .selected_folder").forEach(function(s){
document.querySelectorAll("#"+tt.active_group+" .selected_folder").forEach(function(s){
res.FoldersSelected.push(s.id);
res.Folders[s.id] = Object.assign({}, bgfolders[s.id]);
res.Folders[s.id] = Object.assign({}, tt.folders[s.id]);
let Fchildren = document.querySelectorAll("#cf"+s.id+" .folder");
Fchildren.forEach(function(fc){
res.Folders[fc.id] = Object.assign({}, bgfolders[fc.id]);
res.Folders[fc.id] = Object.assign({}, tt.folders[fc.id]);
});
let Tchildren = document.querySelectorAll("#ct"+s.id+" .tab");
Tchildren.forEach(function(tc){
@ -146,23 +189,13 @@ function GetSelectedFolders() {
}
function GetSelectedTabs() {
// let res = {urls: [], TabsIds: [], TabsIdsParents: [], TabsIdsSelected: []};
let res = {TabsIds: [], TabsIdsParents: [], TabsIdsSelected: []};
document.querySelectorAll(".pin.selected_tab, #"+active_group+" .selected_tab").forEach(function(s){
// chrome.tabs.get(parseInt(s.id), function(tab) {
// res.urls.push(tab.url);
// });
document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){
res.TabsIds.push(parseInt(s.id));
res.TabsIdsParents.push(s.parentNode.id);
res.TabsIdsSelected.push(parseInt(s.id));
let Tchildren = document.querySelectorAll("#ct"+s.id+" .tab");
Tchildren.forEach(function(tc){
// chrome.tabs.get(parseInt(tc.id), function(tab) {
// res.urls.push(tab.url);
// });
res.TabsIds.push(parseInt(tc.id));
res.TabsIdsParents.push(tc.parentNode.id);
});
@ -171,9 +204,6 @@ function GetSelectedTabs() {
}
function FindTab(input) { // find and select tabs
let ButtonFilterClear = document.getElementById("button_filter_clear");
document.querySelectorAll(".filtered, .highlighted_search").forEach(function(s){
@ -189,83 +219,49 @@ function FindTab(input) { // find and select tabs
return;
} else {
ButtonFilterClear.style.opacity = "1";
ButtonFilterClear.title = caption_clear_filter;
ButtonFilterClear.title = labels.clear_filter;
}
SearchIndex = 0;
tt.SearchIndex = 0;
let FilterType = document.getElementById("button_filter_type");
let searchUrl = FilterType.classList.contains("url");
let searchTitle = FilterType.classList.contains("title");
chrome.tabs.query({windowId: CurrentWindowId, pinned: false}, function(tabs) {
let query = {windowId: tt.CurrentWindowId, pinned: false};
if (input == "*audible") {
query = {windowId: tt.CurrentWindowId, discarded: false, audible: true, muted: false, pinned: false};
}
if (input == "*muted") {
query = {windowId: tt.CurrentWindowId, discarded: false, muted: true, pinned: false};
}
if (input == "*unloaded") {
query = {windowId: tt.CurrentWindowId, discarded: true, pinned: false};
}
if (input == "*loaded") {
query = {windowId: tt.CurrentWindowId, discarded: false, pinned: false};
}
chrome.tabs.query(query, function(tabs) {
tabs.forEach(function(Tab) {
if (searchUrl) {
if (Tab.url.toLowerCase().match(input.toLowerCase())) {
document.getElementById(Tab.id).classList.add("filtered");
document.getElementById(Tab.id).classList.add("selected_tab");
if (input == "*audible" || input == "*muted" || input == "*unloaded" || input == "*loaded") {
document.getElementById(Tab.id).classList.add("filtered");
document.getElementById(Tab.id).classList.add("selected_tab");
} else {
if (searchUrl) {
if (Tab.url.toLowerCase().match(input.toLowerCase())) {
document.getElementById(Tab.id).classList.add("filtered");
document.getElementById(Tab.id).classList.add("selected_tab");
}
}
}
if (searchTitle) {
if (Tab.title.toLowerCase().match(input.toLowerCase())) {
document.getElementById(Tab.id).classList.add("filtered");
document.getElementById(Tab.id).classList.add("selected_tab");
if (searchTitle) {
if (Tab.title.toLowerCase().match(input.toLowerCase())) {
document.getElementById(Tab.id).classList.add("filtered");
document.getElementById(Tab.id).classList.add("selected_tab");
}
}
}
});
});
}
// sort tabs main function
// function SortTabs() {
// if ($(".tab").find(":visible:first")[0]){
// chrome.tabs.query({windowId: vt.windowId}, function(tabs){
// tabs.sort(function(tab_a, tab_b){
// return SplitUrl(tab_a).localeCompare( SplitUrl(tab_b) );
// });
// var first_tabId;
// if ($(".selected:visible")[0]){
// first_tabId = parseInt($(".selected:visible")[0].id);
// } else {
// first_tabId = parseInt($(".tab").find(":visible:first")[0].parentNode.id);
// }
// chrome.tabs.get(first_tabId, function(tab){
// var new_index = tab.index;
// tabs.forEach(function(Tab){
// // sort selected when more than 1 tab is selected
// if (($(".selected:visible").length > 1 && $("#"+Tab.id).is(":visible") && !Tab.pinned && $("#"+Tab.id).is(".selected")) || ($(".selected:visible").length < 2 && $("#"+Tab.id).is(":visible") && !Tab.pinned)){
// chrome.tabs.move(Tab.id, {"index": new_index});
// new_index++;
// }
// });
// });
// if (bg.opt.scroll_to_active){
// setTimeout(function(){
// ScrollTabList($(".active:visible")[0].id);
// },1000);
// }
// });
// }
// }
// sort tabs sub function
// function SplitUrl(tab) {
// var tmp_url = new URL(tab.url);
// if (tmp_url.protocol != "http:"){
// tmp_url.protocol == "http:";
// }
// var url_parts = [];
// if (tab.pinned){
// url_parts.push("#"+tab.index);
// } else {
// url_parts.push("~");
// }
// var parts = tmp_url.host.split(".");
// parts.reverse();
// if (parts.length > 1){
// parts = parts.slice(1);
// }
// parts.join(".");
// url_parts.push(parts);
// url_parts.push(tab.title.toLowerCase());
// return url_parts.join(" ! ");
// }
function Bookmark(rootNode) {
let ToolbarId = browserId == "F" ? "toolbar_____" : "1";
@ -302,12 +298,12 @@ function Bookmark(rootNode) {
}
if (rootNode.classList.contains("folder") || rootNode.classList.contains("group")) {
let rootName = caption_noname_group;
if (rootNode.classList.contains("folder") && bgfolders[rootNode.id]) {
rootName = bgfolders[rootNode.id].name;
let rootName = labels.noname_group;
if (rootNode.classList.contains("folder") && tt.folders[rootNode.id]) {
rootName = tt.folders[rootNode.id].name;
}
if (rootNode.classList.contains("group") && bggroups[rootNode.id]) {
rootName = bggroups[rootNode.id].name;
if (rootNode.classList.contains("group") && tt.groups[rootNode.id]) {
rootName = tt.groups[rootNode.id].name;
}
chrome.bookmarks.create({parentId: TreeTabsId, title: rootName}, function(root) {
@ -315,10 +311,10 @@ function Bookmark(rootNode) {
let folders = document.querySelectorAll("#cf"+rootNode.id+" .folder");
folders.forEach(function(s){
if (bgfolders[s.id]) {
if (tt.folders[s.id]) {
let ttId = s.id;
chrome.bookmarks.create({parentId: root.id, title: bgfolders[ttId].name}, function(Bkfolder) {
foldersRefs[ttId] = {ttid: ttId, id: Bkfolder.id, ttparent: bgfolders[ttId].parent, parent: root.id};
chrome.bookmarks.create({parentId: root.id, title: tt.folders[ttId].name}, function(Bkfolder) {
foldersRefs[ttId] = {ttid: ttId, id: Bkfolder.id, ttparent: tt.folders[ttId].parent, parent: root.id};
let elemInd = 0;
if (ttId == folders[folders.length-1].id) {
@ -370,4 +366,36 @@ function Bookmark(rootNode) {
}
});
});
}
function ShowStatusBar(p) { // show, spinner, message
let status_bar = document.getElementById("status_bar");
let busy_spinner = document.getElementById("busy_spinner");
let status_message = document.getElementById("status_message");
if (p.show) {
status_bar.style.display = "block";
status_message.textContent = p.message;
if (p.spinner) {
busy_spinner.style.opacity = "1";
} else {
busy_spinner.style.opacity = "0";
}
} else {
busy_spinner.style.opacity = "0";
status_message.textContent = "";
status_bar.style.display = "none";
}
if (p.hideTimeout) {
setTimeout(function() {
busy_spinner.style.opacity = "0";
status_message.textContent = "";
status_bar.style.display = "none";
}, p.hideTimeout);
}
}
function log(log) {
if (opt.debug) {
chrome.runtime.sendMessage({command: "debug", log: log});
}
}

View File

@ -18,21 +18,21 @@
-webkit-user-drag:none;
}
</style>
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_0.css" id="sizes_preset_0" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_1.css" id="sizes_preset_1" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_2.css" id="sizes_preset_2" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_3.css" id="sizes_preset_3" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_4.css" id="sizes_preset_4" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_0.css" id="sizes_preset_0" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_1.css" id="sizes_preset_1" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_2.css" id="sizes_preset_2" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_3.css" id="sizes_preset_3" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_4.css" id="sizes_preset_4" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_tabs_margin_0.css" id="tabs_margin_0" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_tabs_margin_1.css" id="tabs_margin_1" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_tabs_margin_2.css" id="tabs_margin_2" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_0.css" id="tabs_margin_0" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_1.css" id="tabs_margin_1" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_2.css" id="tabs_margin_2" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_colors.css" id="theme_colors" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme.css" id="theme" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_manager.css" id="manager" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_colors.css" id="theme_colors" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme.css" id="theme" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_manager.css" id="manager" />
</head>
<body id="body" class="sidebar_body">
<body id="body" class="sidebar_body" oncontextmenu="return false;">
<div id="DragImage" style="display: none; width:0px; height:0px;"></div>
@ -111,6 +111,13 @@
</div>
</ul>
<div id="status_bar">
<div id="new_tab_floating_button_img"></div>
<div id="status_message"></div>
<div id="busy_spinner"></div>
</div>
<ul class="menu" id="main_menu">
<li class="menu_item" id="menu_new_pin"></li>
@ -207,23 +214,25 @@
</div>
-->
<script type="text/javascript" src="../scripts/global.js"></script>
<script type="text/javascript" src="../scripts/theme.js"></script>
<script type="text/javascript" src="../scripts/toolbar.js"></script>
<script type="text/javascript" src="../scripts/chrome.js"></script>
<script type="text/javascript" src="../scripts/refresh.js"></script>
<script type="text/javascript" src="../scripts/utils.js"></script>
<script type="text/javascript" src="scripts/common.js"></script>
<script type="text/javascript" src="scripts/listeners.js"></script>
<script type="text/javascript" src="../scripts/backup.js"></script>
<script type="text/javascript" src="../scripts/tabs.js"></script>
<script type="text/javascript" src="../scripts/folders.js"></script>
<script type="text/javascript" src="../scripts/groups.js"></script>
<script type="text/javascript" src="../scripts/menu.js"></script>
<script type="text/javascript" src="../scripts/manager.js"></script>
<script type="text/javascript" src="scripts/utils.js"></script>
<script type="text/javascript" src="scripts/theme.js"></script>
<script type="text/javascript" src="scripts/toolbar.js"></script>
<script type="text/javascript" src="scripts/refresh.js"></script>
<script type="text/javascript" src="scripts/backup.js"></script>
<script type="text/javascript" src="scripts/tabs.js"></script>
<script type="text/javascript" src="scripts/folders.js"></script>
<script type="text/javascript" src="scripts/groups.js"></script>
<script type="text/javascript" src="scripts/menu.js"></script>
<script type="text/javascript" src="scripts/manager.js"></script>
<script type="text/javascript" src="sidebar.js"></script>
<script type="text/javascript" src="../scripts/events.js"></script>
<script type="text/javascript" src="scripts/events.js"></script>
</body>

View File

@ -6,6 +6,7 @@ document.addEventListener("DOMContentLoaded", Run(), false);
function Run() {
ShowStatusBar({show: true, spinner: true, message: "Starting up"});
chrome.runtime.sendMessage({command: "is_bg_ready"}, function(response) {
if (response == true) {
Initialize();
@ -18,10 +19,9 @@ function Run() {
}
function Initialize() {
chrome.tabs.query({currentWindow: true}, function(tabs) {
CurrentWindowId = tabs[0].windowId;
chrome.windows.getCurrent({populate: true}, function(window) {
tt.CurrentWindowId = window.id;
let tabs = window.tabs;
chrome.storage.local.get(null, function(storage) {
GetCurrentPreferences(storage);
@ -34,40 +34,40 @@ function Initialize() {
RestoreToolbarSearchFilter();
}
chrome.runtime.sendMessage({command: "get_browser_tabs"}, function(response) {
let bgtabs = Object.assign({}, response);
chrome.runtime.sendMessage({command: "get_folders", windowId: CurrentWindowId}, function(response) {
bgfolders = Object.assign({}, response);
chrome.runtime.sendMessage({command: "get_groups", windowId: CurrentWindowId}, function(response) {
bggroups = Object.assign({}, response);
chrome.runtime.sendMessage({command: "get_browser_tabs"}, function(bgtabs) {
chrome.runtime.sendMessage({command: "get_folders", windowId: tt.CurrentWindowId}, function(f) {
tt.folders = Object.assign({}, f);
chrome.runtime.sendMessage({command: "get_groups", windowId: tt.CurrentWindowId}, function(g) {
tt.groups = Object.assign({}, g);
// APPEND GROUPS
AppendGroups(bggroups);
AppendGroups(tt.groups);
// APPEND FOLDERS
AppendFolders(bgfolders);
AppendFolders(tt.folders);
// APPEND TABS
let ti = 0;
let tc = tabs.length;
let ttTabs = [];
for (ti = 0; ti < tc; ti++) {
AppendTab(tabs[ti], false, false, false, true, false, true, false, true, false, false);
ttTabs.push(AppendTab({ tab: tabs[ti], Append: true, SkipSetActive: true, AdditionalClass: (bgtabs[tabs[ti].id].expand != "" ? bgtabs[tabs[ti].id].expand : undefined) }));
}
for (ti = 0; ti < tc; ti++) {
if (bgtabs[tabs[ti].id] && !tabs[ti].pinned) {
let TabParent = document.getElementById("ct"+bgtabs[tabs[ti].id].parent) ;
if (TabParent != null && document.querySelector("[id='"+tabs[ti].id+"'] #ct"+bgtabs[tabs[ti].id].parent) == null) {
TabParent.appendChild(document.getElementById(tabs[ti].id));
if (opt.skip_load == false) {
for (ti = 0; ti < tc; ti++) {
if (bgtabs[tabs[ti].id] && !tabs[ti].pinned) {
let TabParent = document.getElementById("ct"+bgtabs[tabs[ti].id].parent);
if (TabParent != null && document.querySelector("[id='"+tabs[ti].id+"'] #ct"+bgtabs[tabs[ti].id].parent) == null) {
TabParent.appendChild(ttTabs[ti]);
}
}
}
}
for (ti = 0; ti < tc; ti++) {
if (bgtabs[tabs[ti].id] && !tabs[ti].pinned && bgtabs[tabs[ti].id].expand != "") {
document.getElementById(tabs[ti].id).classList.add(bgtabs[tabs[ti].id].expand);
}
}
// SET ACTIVE TAB FOR EACH GROUP
// SET ACTIVE TAB FOR EACH GROUP, REARRENGE EVERYTHING AND START BROWSER LISTENERS
SetActiveTabInEachGroup();
RearrangeTreeTabs(tabs, bgtabs, true);
RearrangeFolders(true);
StartChromeListeners();
RearrangeTreeTabs(bgtabs, true);
StartSidebarListeners();
SetMenu();
SetEvents();
SetManagerEvents();
@ -83,6 +83,7 @@ function Initialize() {
if (browserId == "V") {
VivaldiRefreshMediaIcons();
}
setTimeout(function() {
RefreshExpandStates();
RefreshCounters();
@ -91,14 +92,10 @@ function Initialize() {
RecheckFirefox();
}
}, 1000);
ShowStatusBar({show: true, spinner: false, message: "Ready.", hideTimeout: 2000});
setTimeout(function() {
UpdateData();
delete debug;
delete running;
delete schedule_save;
delete windows;
delete tabs;
delete tt_ids;
delete b;
delete DefaultToolbar;
delete DefaultTheme;
delete DefaultPreferences;
@ -107,9 +104,9 @@ function Initialize() {
}
}, 5000);
if (browserId != "F") {
if (Object.keys(storage["windows_BAK1"]).length > 0 && document.getElementById("button_load_bak1") != null) { document.getElementById("button_load_bak1").classList.remove("disabled"); }
if (Object.keys(storage["windows_BAK2"]).length > 0 && document.getElementById("button_load_bak2") != null) { document.getElementById("button_load_bak2").classList.remove("disabled"); }
if (Object.keys(storage["windows_BAK3"]).length > 0 && document.getElementById("button_load_bak3") != null) { document.getElementById("button_load_bak3").classList.remove("disabled"); }
if (storage.windows_BAK1 && Object.keys(storage["windows_BAK1"]).length > 0 && document.getElementById("button_load_bak1") != null) { document.getElementById("button_load_bak1").classList.remove("disabled"); }
if (storage.windows_BAK2 && Object.keys(storage["windows_BAK2"]).length > 0 && document.getElementById("button_load_bak2") != null) { document.getElementById("button_load_bak2").classList.remove("disabled"); }
if (storage.windows_BAK3 && Object.keys(storage["windows_BAK3"]).length > 0 && document.getElementById("button_load_bak3") != null) { document.getElementById("button_load_bak3").classList.remove("disabled"); }
}
});
});

View File

@ -41,6 +41,53 @@ div {
#status_bar {
background-color: var(--button_background);
border-top: 1px solid var(--toolbar_border_bottom);
display: float;
position: absolute;
width: 100%;
height: 11px;
bottom: 0;
left: 0px;
background-size: 8px 8px;
z-index: 999999999;
}
#busy_spinner {
position: absolute;
width: 11px;
height: 11px;
top: 0px;
left: 4px;
background-size: 11px 11px;
background-image: url(../theme/loading.svg);
pointer-events: none;
transition: opacity 5ms ease-in-out;
}
#status_message {
position: absolute;
top: -1px;
left: 20px;
height: 10x;
width: calc(100% - 20px);
font-family: Arial, Helvetica, "Nimbus Sans L", "Liberation Sans", FreeSans, Sans-serif;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
font-size: 9px;
pointer-events: none;
color:var(--tab_title_font_color);
font-style:var(--tab_title_font_style);
font-weight:var(--tab_title_font_weight);
}
/* MAIN TOOLBAR BUTTONS */
@ -482,6 +529,7 @@ div {
position: relative;
display: block;
vertical-align: top;
top: 0px;
left: 0px;
width: 1000px;
height: 100%;
@ -501,8 +549,16 @@ div {
font-weight: bold;
color: var(--group_list_default_font_color);
background: transparent;
pointer-events: none;
}
/*
.group_button:first-child {
margin-top: 14px;
}
*/
.group_button:last-child {
margin-bottom: 14px;
}
.group_button {
position: relative;
left: -1px;
@ -857,7 +913,7 @@ div {
}
.group>.children_tabs>:last-child {
margin-bottom: 12px;
margin-bottom: 16px;
}
@ -1212,11 +1268,10 @@ div {
display: block;
top: -1px;
left: 0px;
width: calc(100% - 2px);
width: 17px;
height: 100%;
border: 1px solid var(--drag_indicator);
}
.group_button.before.highlighted_drop_target>.drag_indicator {
display: block;
top: -1px;
@ -1240,8 +1295,6 @@ div {
/* MEDIA */
@keyframes blinking2 {