diff --git a/..TODO/TODO.txt b/..TODO/TODO.txt index 209d79e..3d7ee25 100644 --- a/..TODO/TODO.txt +++ b/..TODO/TODO.txt @@ -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; \ No newline at end of file diff --git a/..files_ForTesting/background.html b/..files_ForTesting/background.html deleted file mode 100644 index 0816c92..0000000 --- a/..files_ForTesting/background.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/..files_ForTesting/init.js b/..files_ForTesting/init.js deleted file mode 100644 index af2398d..0000000 --- a/..files_ForTesting/init.js +++ /dev/null @@ -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); - } -} diff --git a/..files_ForTesting/manifest.json b/..files_ForTesting/manifest.json index 76dcbba..0e7a66c 100644 --- a/..files_ForTesting/manifest.json +++ b/..files_ForTesting/manifest.json @@ -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", "", "storage", "unlimitedStorage", "bookmarks", "tabHide" ], + "permissions": [ "", "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" } \ No newline at end of file diff --git a/..files_firefox/background.html b/..files_firefox/background.html deleted file mode 100644 index c7bbc40..0000000 --- a/..files_firefox/background.html +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/..files_firefox/init.js b/..files_firefox/init.js deleted file mode 100644 index 326732f..0000000 --- a/..files_firefox/init.js +++ /dev/null @@ -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); -} \ No newline at end of file diff --git a/..files_firefox/manifest.json b/..files_firefox/manifest.json index 4ac47a9..661cf39 100644 --- a/..files_firefox/manifest.json +++ b/..files_firefox/manifest.json @@ -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", "", "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" } \ No newline at end of file diff --git a/..files_opera/background.html b/..files_opera/background.html deleted file mode 100644 index 1d3aa75..0000000 --- a/..files_opera/background.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/..files_opera/init.js b/..files_opera/init.js deleted file mode 100644 index 27fe083..0000000 --- a/..files_opera/init.js +++ /dev/null @@ -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); -} diff --git a/..files_opera/manifest.json b/..files_opera/manifest.json index 4de32b3..c7c72df 100644 --- a/..files_opera/manifest.json +++ b/..files_opera/manifest.json @@ -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" } diff --git a/..files_vivaldi/background.html b/..files_vivaldi/background.html deleted file mode 100644 index 1215d3f..0000000 --- a/..files_vivaldi/background.html +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/..files_vivaldi/init.js b/..files_vivaldi/init.js deleted file mode 100644 index afe0210..0000000 --- a/..files_vivaldi/init.js +++ /dev/null @@ -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); -} diff --git a/..files_vivaldi/manifest.json b/..files_vivaldi/manifest.json index 883d3b5..1220c67 100644 --- a/..files_vivaldi/manifest.json +++ b/..files_vivaldi/manifest.json @@ -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" } diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 34bc0d0..34e47b8 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -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": "" } + + + + + + diff --git a/background.html b/background.html deleted file mode 100644 index 0816c92..0000000 --- a/background.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/background.js b/background.js new file mode 100644 index 0000000..eee9d98 --- /dev/null +++ b/background.js @@ -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; +} diff --git a/bg_ch.js b/bg_ch.js deleted file mode 100644 index 754fe19..0000000 --- a/bg_ch.js +++ /dev/null @@ -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; - } - }); -} \ No newline at end of file diff --git a/bg_ff.js b/bg_ff.js deleted file mode 100644 index 43c44ba..0000000 --- a/bg_ff.js +++ /dev/null @@ -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; - } - }); -} \ No newline at end of file diff --git a/init.js b/init.js deleted file mode 100644 index af2398d..0000000 --- a/init.js +++ /dev/null @@ -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); - } -} diff --git a/legacy.js b/legacy.js deleted file mode 100644 index 93a1aed..0000000 --- a/legacy.js +++ /dev/null @@ -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; - } -} diff --git a/listeners_bg.js b/listeners_bg.js new file mode 100644 index 0000000..840e57f --- /dev/null +++ b/listeners_bg.js @@ -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}); + }); +} \ No newline at end of file diff --git a/manifest.json b/manifest.json index 76dcbba..661cf39 100644 --- a/manifest.json +++ b/manifest.json @@ -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", "", "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" } \ No newline at end of file diff --git a/options.html b/options.html index 0352545..5eee67b 100644 --- a/options.html +++ b/options.html @@ -3,41 +3,41 @@ - - - - - + + + + + - - - + + + - - + + - + - + - +
Tree Tabs

-
+ @@ -201,7 +201,15 @@ + +
  • + +
  • @@ -223,14 +231,6 @@
  • -
  • - - -


  • @@ -240,7 +240,7 @@
    - +
  • @@ -813,16 +813,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/options/options.js b/options/options.js index eb9d431..53d549b 100644 --- a/options/options.js +++ b/options/options.js @@ -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() {} diff --git a/options/refresh.js b/options/refresh.js deleted file mode 100644 index d0cbb92..0000000 --- a/options/refresh.js +++ /dev/null @@ -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"; - } -} - diff --git a/options/sample_tabs.js b/options/sample_tabs.js index e7b802d..80b259e 100644 --- a/options/sample_tabs.js +++ b/options/sample_tabs.js @@ -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"); diff --git a/scripts/backup.js b/scripts/backup.js index eb2d3f0..f71d13b 100644 --- a/scripts/backup.js +++ b/scripts/backup.js @@ -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) { diff --git a/scripts/chrome.js b/scripts/chrome.js deleted file mode 100644 index 2112ad0..0000000 --- a/scripts/chrome.js +++ /dev/null @@ -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; - } - } - - }); -} \ No newline at end of file diff --git a/scripts/common.js b/scripts/common.js new file mode 100644 index 0000000..a0f62ea --- /dev/null +++ b/scripts/common.js @@ -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"; + } + } + } + } +} diff --git a/scripts/events.js b/scripts/events.js index eb538bf..b03c6b2 100644 --- a/scripts/events.js +++ b/scripts/events.js @@ -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; } \ No newline at end of file diff --git a/scripts/folders.js b/scripts/folders.js index c61de8d..66330c0 100644 --- a/scripts/folders.js +++ b/scripts/folders.js @@ -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"); diff --git a/scripts/global.js b/scripts/global.js deleted file mode 100644 index d2aadfa..0000000 --- a/scripts/global.js +++ /dev/null @@ -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++; -} \ No newline at end of file diff --git a/scripts/groups.js b/scripts/groups.js index 4f01c50..02fbb88 100644 --- a/scripts/groups.js +++ b/scripts/groups.js @@ -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 + }); + +} diff --git a/scripts/listeners.js b/scripts/listeners.js new file mode 100644 index 0000000..cc12862 --- /dev/null +++ b/scripts/listeners.js @@ -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; + } + } + }); +} \ No newline at end of file diff --git a/scripts/manager.js b/scripts/manager.js index 6f3b2f0..5f3c399 100644 --- a/scripts/manager.js +++ b/scripts/manager.js @@ -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(); } diff --git a/scripts/menu.js b/scripts/menu.js index 1b5e120..02f6034 100644 --- a/scripts/menu.js +++ b/scripts/menu.js @@ -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}); - // }); - - - } \ No newline at end of file diff --git a/scripts/refresh.js b/scripts/refresh.js index e4f9dfb..86683ed 100644 --- a/scripts/refresh.js +++ b/scripts/refresh.js @@ -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")) { diff --git a/scripts/tabs.js b/scripts/tabs.js index 870d097..36f71ef 100644 --- a/scripts/tabs.js +++ b/scripts/tabs.js @@ -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"); diff --git a/scripts/theme.js b/scripts/theme.js index 39b324a..8f87f2a 100644 --- a/scripts/theme.js +++ b/scripts/theme.js @@ -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) { diff --git a/scripts/toolbar.js b/scripts/toolbar.js index f69b1fa..e240151 100644 --- a/scripts/toolbar.js +++ b/scripts/toolbar.js @@ -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); } diff --git a/scripts/utils.js b/scripts/utils.js index 8f6a8b8..6d7adf4 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -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}); + } } \ No newline at end of file diff --git a/sidebar.html b/sidebar.html index 440d0fd..6e20670 100644 --- a/sidebar.html +++ b/sidebar.html @@ -18,21 +18,21 @@ -webkit-user-drag:none; } - - - - - + + + + + - - - + + + - - - + + + - + @@ -111,6 +111,13 @@ + + +
    +
    +
    +
    +