diff --git a/..TODO/TODO.txt b/..TODO/TODO.txt
index 3d7ee25..5e15a48 100644
--- a/..TODO/TODO.txt
+++ b/..TODO/TODO.txt
@@ -1,19 +1,50 @@
+WITH NEW API:
+REDO SIDEBAR INITIALIZE ok!
+
+
+
+
+RECHECK CLOSE TABS - activeTab query (works)
+
+FINISH BACKGROUND LISTENERS (ORPHAN CASE) YAYYYYYY PROBABLY DONE!
+FINISH EVENTS - DROP (MAYBE DONE?)
+REDO START DRAG OF GROUP TAB AND FOLDER (MAYBE there)
+REDO DRAG OVER PIN_LIST AND GROUP (DONE!)
+REDO CloseTabs (looks fine, more testing needed)
+RECHECK SetTabClass (looks fine, more testing needed)
+FINISH BACKUP MERGE and recreate group and session, REDO load group, coooooz' not work (done, testing needed)
+REDO DETACH TAB!!! (maybe done)
+
+
+
+
+REVAMP MENU
+REVAMP TOOLBAR FUNCTIONS
+FIX ADD NEW FOLDER (from toolbar and from menu - add insertAfterID to new folder function)
+
+
+REDO PROMOTE TABS IN LISTENERS IN: tab_removed AND tab_detached
+
+
+ADD LINKS TO OPTIONS PAGE AND ADD RED COMMENTS
+ADD PRESETS FOR OPTIONS
+
+
+
+
+
+
+
+
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!
+1. mute icon config option (disable animation)
+2. "TURN OFF DIMMING" OF AUDIO AND FOR ATTENTION
+3. you can now drop folders between tabs, but only if root is folder or group
-FIXES:
-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
+
+FIXED:
+"Close other" doesn't respect pinned tabs.
@@ -36,7 +67,6 @@ line for children hierarchy (like at the beggining)
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
@@ -102,7 +132,40 @@ 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.
+
+Option to change the color of the icon indicating that a tab is a source of audio. (separated for playing and muted)
+
+
+
+
+
+
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
+- real FF tabs must creating and linking only after activate your tabs;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/..Themes/A Dark Colorized Theme - Preview.png b/..Themes/A Dark Colorized Theme - Preview.png
new file mode 100644
index 0000000..a65a580
Binary files /dev/null and b/..Themes/A Dark Colorized Theme - Preview.png differ
diff --git a/..Themes/A Dark Colorized Theme.tt_theme b/..Themes/A Dark Colorized Theme.tt_theme
new file mode 100644
index 0000000..1dab3ca
--- /dev/null
+++ b/..Themes/A Dark Colorized Theme.tt_theme
@@ -0,0 +1 @@
+{"ToolbarShow":true,"ColorsSet":{"tab_background":"#155128","children_padding_left":"19px","tab_header_border_radius":"8px","pin_list_background":"#1f2427","tab_title_font_color":"#dfdfdf","group_list_button_hover_background":"#1f2427","close_hover_background":"#2e3a45","expand_closed_background":"#f8f8f8","tab_discarded_background":"#4a2629","tab_list_background":"#1f2427","group_list_background":"#1f2427","tab_border":"#1f2427","tab_active_background":"#206a71","tab_active_title_font_color":"#f8f8f8","tab_discarded_border":"#1f2427","tab_hover_background":"#155128","tab_hover_title_font_color":"#dfdfdf","tab_hover_border":"#ffffff","tab_selected_background":"#207b3e","tab_selected_title_font_weight":"normal","tab_selected_title_font_color":"#5bff5b","tab_selected_hover_title_font_color":"#5bff5b","tab_selected_hover_background":"#207b3e","tab_active_hover_background":"#206a71","tab_active_selected_background":"#35b3bd","tab_selected_active_hover_background":"#35b3bd","group_list_default_font_color":"#339bf3","group_list_borders":"#566570","tab_active_hover_title_font_color":"#f8f8f8","tab_active_selected_title_font_color":"#003f5e","tab_selected_active_hover_title_font_color":"#003f5e","tab_discarded_hover_background":"#4a2629","tab_selected_discarded_background":"#6d3a40","tab_selected_discarded_hover_background":"#6d3a40","tab_discarded_hover_border":"#ffffff","tab_selected_discarded_border":"#1f2427","tab_active_title_font_weight":"bold","tab_discarded_hover_title_font_color":"#acacb0","tab_active_border":"#1f2427","tab_selected_border":"#1f2427","tab_active_selected_border":"#1f2427","tab_selected_discarded_hover_border":"#ffffff","tab_selected_hover_border":"#ffffff","pin_list_border_bottom":"#414c54","filter_box_border":"#a1a5a8","toolbar_border_bottom":"#7e8f9c","close_hover_border":"#2e3a45","close_x":"#c5c5c7","button_hover_background":"#2e3a45","button_background":"#1f2427","toolbar_background":"#1f2427","button_border":"#1f2427","button_hover_border":"#568aab","tab_active_hover_border":"#ffffff","button_icons":"#c5c5c7","button_icons_hover":"#1791c2","expand_hover_background":"#f8f8f8","tab_discarded_title_font_color":"#acacb0","expand_open_background":"#f8f8f8","tabs_menu_hover_background":"#1f2427","tab_selected_active_hover_border":"#ffffff","attention_background":"#70486c","attention_border":"#e126bb","tab_filtered_hover_background":"#1f2427","tab_filtered_hover_title_font_color":"#c2b917","tab_filtered_hover_border":"#ffff00","tab_filtered_active_background":"#1f2427","tab_filtered_active_title_font_color":"#f8f8f8","tab_filtered_active_border":"#aba656","tab_filtered_active_hover_title_font_color":"#f8f8f8","tab_filtered_active_hover_border":"#ffff00","tab_filtered_active_hover_background":"#1f2427","tab_filtered_background":"#1f2427","tab_filtered_border":"#ffff00","tab_filtered_title_font_color":"#c2b917","tab_filtered_selected_border":"#aba656","tab_filtered_selected_active_border":"#aba656","tab_filtered_selected_background":"#4f4f00","tab_filtered_selected_title_font_color":"#ffff00","tab_filtered_selected_hover_title_font_color":"#ffff00","tab_filtered_selected_active_title_font_color":"#f8f8f8","tab_filtered_selected_active_hover_title_font_color":"#f8f8f8","tab_filtered_selected_active_background":"#4f4f00","tab_filtered_selected_hover_background":"#4f4f00","tab_filtered_selected_active_hover_background":"#4f4f00","tab_filtered_selected_hover_border":"#ffff00","tab_filtered_selected_active_hover_border":"#ffff00","tab_filtered_highlighted_search_background":"#1f2427","tab_filtered_highlighted_search_title_font_color":"#c11815","tab_filtered_highlighted_search_border":"#aa5656","tab_filtered_highlighted_search_hover_title_font_color":"#c11815","tab_filtered_highlighted_search_hover_background":"#1f2427","tab_filtered_highlighted_search_hover_border":"#ff0000","tab_filtered_active_highlighted_search_background":"#1f2427","tab_filtered_active_highlighted_search_hover_background":"#1f2427","tab_filtered_selected_highlighted_search_background":"#330000","tab_filtered_selected_highlighted_search_hover_background":"#330000","tab_filtered_selected_active_highlighted_search_background":"#330000","tab_filtered_selected_active_highlighted_search_hover_background":"#330000","tab_filtered_selected_highlighted_search_border":"#ab5668","tab_filtered_selected_active_highlighted_search_border":"#ab5668","tab_filtered_active_highlighted_search_border":"#aa5656","tab_filtered_active_highlighted_search_hover_border":"#ff0000","tab_filtered_selected_highlighted_search_hover_border":"#ff0000","tab_filtered_selected_active_highlighted_search_hover_border":"#ff0000","tab_filtered_active_highlighted_search_title_font_color":"#f8f8f8","tab_filtered_active_highlighted_search_hover_title_font_color":"#f8f8f8","tab_filtered_selected_highlighted_search_title_font_color":"#c11815","tab_filtered_selected_highlighted_search_hover_title_font_color":"#c11815","tab_filtered_selected_active_highlighted_search_title_font_color":"#f8f8f8","tab_filtered_selected_active_highlighted_search_hover_title_font_color":"#f8f8f8","tab_selected_title_font_style":"normal","tab_selected_hover_title_font_style":"normal","tab_active_selected_title_font_style":"normal","tab_selected_active_hover_title_font_style":"normal","tab_selected_discarded_title_font_style":"normal","tab_selected_discarded_hover_title_font_style":"normal","tab_filtered_selected_title_font_style":"normal","tab_filtered_selected_hover_title_font_style":"normal","tab_filtered_selected_active_title_font_style":"normal","tab_filtered_selected_active_hover_title_font_style":"normal","tab_filtered_selected_highlighted_search_title_font_style":"normal","tab_filtered_selected_highlighted_search_hover_title_font_style":"normal","tab_filtered_selected_active_highlighted_search_title_font_style":"normal","tab_filtered_selected_active_highlighted_search_hover_title_font_style":"normal","tab_selected_discarded_hover_title_font_color":"#ff5e62","tabs_menu_background":"#1f2427","tabs_menu_font":"#c5c5c7","tabs_menu_hover_border":"#568aab","tabs_menu_separator":"#1f2427","tabs_menu_border":"#414c54","filter_clear_icon":"#000000","filter_box_background":"#fafafa","filter_box_font":"#000000","tab_active_title_font_style":"normal","tab_active_hover_title_font_style":"normal","tab_selected_discarded_title_font_color":"#ff5e62","tab_filtered_title_font_weight":"normal","tab_filtered_hover_title_font_weight":"normal","tab_filtered_active_hover_title_font_weight":"bold","tab_filtered_selected_title_font_weight":"normal","tab_filtered_selected_hover_title_font_weight":"normal","tab_filtered_selected_active_title_font_weight":"bold","tab_filtered_selected_active_hover_title_font_weight":"bold","tab_filtered_active_title_font_weight":"bold","tab_filtered_highlighted_search_title_font_weight":"normal","tab_filtered_highlighted_search_hover_title_font_weight":"normal","tab_filtered_active_highlighted_search_title_font_weight":"bold","tab_filtered_active_highlighted_search_hover_title_font_weight":"bold","tab_filtered_selected_highlighted_search_title_font_weight":"normal","tab_filtered_selected_highlighted_search_hover_title_font_weight":"normal","tab_filtered_selected_active_highlighted_search_title_font_weight":"bold","tab_filtered_selected_active_highlighted_search_hover_title_font_weight":"bold","tab_title_font_weight":"normal","tab_hover_title_font_weight":"normal","tab_selected_hover_title_font_weight":"normal","tab_active_hover_title_font_weight":"bold","tab_active_selected_title_font_weight":"bold","tab_selected_active_hover_title_font_weight":"bold","tab_discarded_title_font_weight":"normal","tab_discarded_hover_title_font_weight":"normal","tab_selected_discarded_title_font_weight":"normal","tab_selected_discarded_hover_title_font_weight":"normal","tab_title_font_style":"normal","tab_hover_title_font_style":"normal","tab_discarded_title_font_style":"normal","tab_discarded_hover_title_font_style":"normal","tab_filtered_title_font_style":"normal","tab_filtered_hover_title_font_style":"normal","tab_filtered_active_title_font_style":"normal","tab_filtered_active_hover_title_font_style":"normal","tab_filtered_highlighted_search_title_font_style":"normal","tab_filtered_highlighted_search_hover_title_font_style":"normal","tab_filtered_active_highlighted_search_title_font_style":"normal","tab_filtered_active_highlighted_search_hover_title_font_style":"normal"},"TabsSizeSetNumber":1,"TabsMargins":"0","theme_name":"dark_colorized","theme_version":3,"toolbar":"
","unused_buttons":""}
\ No newline at end of file
diff --git a/..Themes/Dark and blue (by Compilenix).png b/..Themes/Dark and blue (by Compilenix).png
new file mode 100644
index 0000000..128071d
Binary files /dev/null and b/..Themes/Dark and blue (by Compilenix).png differ
diff --git a/..Themes/Dark and blue (by Compilenix).tt_theme b/..Themes/Dark and blue (by Compilenix).tt_theme
new file mode 100644
index 0000000..6ce2f85
--- /dev/null
+++ b/..Themes/Dark and blue (by Compilenix).tt_theme
@@ -0,0 +1 @@
+{"ToolbarShow":true,"ColorsSet":{"tab_border":"#2b2b2b","tab_hover_border":"#575757","tab_discarded_hover_border":"#575757","tab_discarded_border":"#2b2b2b","tabs_menu_hover_border":"#2196f3","tabs_menu_hover_background":"#323232","close_hover_border":"#323232","tab_selected_border":"#2196f3","tab_selected_hover_border":"#2196f3","tab_active_border":"#2196f3","tab_discarded_background":"#323232","tab_background":"#222222","tab_discarded_hover_title_font_color":"#ffffff","tab_selected_discarded_title_font_color":"#ffffff","tab_selected_discarded_hover_title_font_color":"#ffffff","tab_title_font_color":"#ffffff","tab_hover_title_font_color":"#ffffff","tab_selected_title_font_color":"#ffffff","tab_selected_hover_title_font_color":"#ffffff","tab_active_title_font_color":"#ffffff","tab_active_hover_title_font_color":"#ffffff","tab_active_selected_title_font_color":"#ffffff","tab_selected_active_hover_title_font_color":"#ffffff","tab_filtered_title_font_color":"#ffffff","tab_filtered_hover_title_font_color":"#ffffff","tab_filtered_active_title_font_color":"#ffffff","tab_filtered_active_hover_title_font_color":"#ffffff","tab_filtered_selected_title_font_color":"#ffffff","tab_filtered_selected_hover_title_font_color":"#ffffff","tab_filtered_selected_active_title_font_color":"#ffffff","tab_filtered_selected_active_hover_title_font_color":"#ffffff","tab_filtered_highlighted_search_title_font_color":"#ffffff","tab_filtered_highlighted_search_hover_title_font_color":"#ffffff","tab_filtered_active_highlighted_search_title_font_color":"#ffffff","tab_filtered_active_highlighted_search_hover_title_font_color":"#ffffff","tab_filtered_selected_highlighted_search_title_font_color":"#ffffff","tab_filtered_selected_highlighted_search_hover_title_font_color":"#ffffff","tab_filtered_selected_active_highlighted_search_title_font_color":"#ffffff","tab_filtered_selected_active_highlighted_search_hover_title_font_color":"#ffffff","tab_filtered_background":"#f8ea45","tab_filtered_active_background":"#f8ea45","tab_filtered_selected_background":"#b4e817","tab_filtered_selected_hover_background":"#96c113","tab_filtered_selected_active_background":"#b4e817","tab_filtered_selected_active_hover_background":"#96c113","tab_filtered_selected_hover_border":"#aaaaaa","tab_filtered_selected_active_hover_border":"#aaaaaa","tab_filtered_selected_border":"#aaaaaa","tab_filtered_selected_active_border":"#aaaaaa","tab_filtered_border":"#aaaaaa","tab_filtered_active_border":"#aaaaaa","tab_filtered_hover_border":"#aaaaaa","tab_filtered_active_hover_border":"#aaaaaa","tab_filtered_highlighted_search_background":"#ffa500","tab_filtered_highlighted_search_border":"#aaaaaa","tab_filtered_active_highlighted_search_border":"#aaaaaa","tab_filtered_active_highlighted_search_background":"#ffa500","tab_filtered_selected_highlighted_search_background":"#ffa500","tab_filtered_selected_highlighted_search_border":"#aaaaaa","tab_filtered_selected_active_highlighted_search_background":"#ffa500","tab_filtered_selected_active_highlighted_search_border":"#aaaaaa","tab_filtered_highlighted_search_hover_background":"#d78b00","tab_filtered_highlighted_search_hover_border":"#aaaaaa","tab_filtered_active_highlighted_search_hover_background":"#d78b00","tab_filtered_active_highlighted_search_hover_border":"#aaaaaa","tab_filtered_selected_highlighted_search_hover_background":"#d78b00","tab_filtered_selected_highlighted_search_hover_border":"#aaaaaa","tab_filtered_selected_active_highlighted_search_hover_background":"#d78b00","tab_filtered_selected_active_highlighted_search_hover_border":"#aaaaaa","children_padding_left":"13px","tab_list_background":"#222222","tab_selected_active_hover_title_font_style":"italic","tab_selected_active_hover_title_font_weight":"bold","tab_active_title_font_weight":"bold","tab_active_hover_title_font_weight":"bold","tab_hover_background":"#323232","tab_discarded_hover_background":"#323232","tab_header_border_radius":"0px","group_list_borders":"#575757","group_list_default_font_color":"#ffffff","group_list_background":"#222222","tab_title_font_weight":"normal","tab_selected_background":"#104773","tab_selected_hover_background":"#104773","tab_active_background":"#104773","tab_active_hover_background":"#104773","tab_active_selected_background":"#104773","tab_selected_active_hover_background":"#104773","tab_selected_discarded_background":"#323232","tab_selected_discarded_hover_background":"#323232","tab_active_hover_border":"#2196f3","tab_active_selected_border":"#2196f3","tab_selected_active_hover_border":"#2196f3","tab_selected_discarded_hover_border":"#2196f3","tab_selected_discarded_border":"#2196f3","drag_indicator":"#2196f3","attention_border":"#ed1c24","attention_background":"#ed1c24","close_hover_x":"#ed1c24","close_hover_background":"#3f3f3f","pin_list_border_bottom":"#aaaaaa","pin_list_background":"#323232","filter_box_background":"#222223","filter_box_font":"#ffffff","filter_box_border":"#323232","filter_clear_icon":"#7d7d7d","close_x":"#7d7d7d","toolbar_background":"#323232","toolbar_border_bottom":"#323232","button_background":"#323232","button_hover_background":"#323232","button_on_background":"#323232","button_border":"#323232","button_hover_border":"#323232","toolbar_shelf_background":"#323232","button_shelf_background":"#323232","button_shelf_icons_hover":"#cccccc","button_shelf_border":"#323232","button_shelf_hover_border":"#323232","button_shelf_hover_background":"#323232","button_icons_hover":"#cccccc","button_shelf_icons":"#808080","button_icons":"#808080","button_on_icons":"#cccccc","tab_discarded_title_font_color":"#7e7e7e","tabs_menu_background":"#222222","tabs_menu_font":"#ffffff","tabs_menu_border":"#575757","tabs_menu_separator":"#2196f3"},"TabsSizeSetNumber":4,"TabsMargins":"1","theme_name":"Dark and blue (by Compilenix)","theme_version":4}
\ No newline at end of file
diff --git a/..Themes/DarkFox.tt_theme b/..Themes/DarkFox.tt_theme
new file mode 100644
index 0000000..f71c23a
--- /dev/null
+++ b/..Themes/DarkFox.tt_theme
@@ -0,0 +1 @@
+{"ToolbarShow":true,"ColorsSet":{"group_list_button_hover_background":"#000000","tab_list_background":"#1e1e1e","group_list_background":"#1e1e1e","attention_background":"#ffd6ce","pin_list_background":"#000000","tab_background":"#363d45","tab_hover_border":"#000000","tab_border":"#000000","tab_title_font_style":"normal","tab_title_font_color":"#b7b7b7","close_x":"#7d7d7d","tab_hover_background":"#717171","tab_hover_title_font_color":"#ffffff","tab_discarded_background":"#4c4c4c","tab_discarded_title_font_color":"#000000","tab_header_border_radius":"0px","children_padding_left":"7px","tab_discarded_border":"#4c4c4c","button_background":"#1e1e1e","toolbar_background":"#1e1e1e","button_on_background":"#808080","button_icons":"#808080","button_icons_hover":"#ffffff","button_on_icons":"#000000","button_border":"#1e1e1e","button_hover_border":"#808080","filter_box_font":"#ffffff","filter_box_background":"#000000","filter_box_border":"#000000","filter_clear_icon":"#ffffff","toolbar_shelf_background":"#1e1e1e","toolbar_border_bottom":"#808080","button_shelf_background":"#1e1e1e","button_shelf_border":"#1e1e1e","group_list_borders":"#323232"},"TabsSizeSetNumber":3,"TabsMargins":"2","theme_name":"DarkFox","theme_version":4}
\ No newline at end of file
diff --git a/..Themes/Light and blue (by Compilenix).tt_theme b/..Themes/Light and blue (by Compilenix).tt_theme
new file mode 100644
index 0000000..ccc5f76
--- /dev/null
+++ b/..Themes/Light and blue (by Compilenix).tt_theme
@@ -0,0 +1 @@
+{"ToolbarShow":true,"ColorsSet":{"tab_border":"#d2d2d2","tab_hover_border":"#797979","tab_discarded_hover_border":"#797979","tab_discarded_border":"#d2d2d2","tabs_menu_hover_border":"#d7d7d7","tabs_menu_hover_background":"#d7d7d7","close_hover_border":"#bfbfbf","tab_selected_border":"#70c0e7","tab_selected_hover_border":"#70c0e7","tab_active_border":"#70c0e7","tab_discarded_background":"#fafafa","tab_background":"#fafafa","tab_discarded_title_font_color":"#353535","tab_discarded_hover_title_font_color":"#353535","tab_selected_discarded_title_font_color":"#353535","tab_selected_discarded_hover_title_font_color":"#353535","tab_title_font_color":"#353535","tab_hover_title_font_color":"#353535","tab_selected_title_font_color":"#353535","tab_selected_hover_title_font_color":"#353535","tab_active_title_font_color":"#353535","tab_active_hover_title_font_color":"#353535","tab_active_selected_title_font_color":"#353535","tab_selected_active_hover_title_font_color":"#353535","tab_filtered_title_font_color":"#353535","tab_filtered_hover_title_font_color":"#353535","tab_filtered_active_title_font_color":"#353535","tab_filtered_active_hover_title_font_color":"#353535","tab_filtered_selected_title_font_color":"#353535","tab_filtered_selected_hover_title_font_color":"#353535","tab_filtered_selected_active_title_font_color":"#353535","tab_filtered_selected_active_hover_title_font_color":"#353535","tab_filtered_highlighted_search_title_font_color":"#353535","tab_filtered_highlighted_search_hover_title_font_color":"#353535","tab_filtered_active_highlighted_search_title_font_color":"#353535","tab_filtered_active_highlighted_search_hover_title_font_color":"#353535","tab_filtered_selected_highlighted_search_title_font_color":"#353535","tab_filtered_selected_highlighted_search_hover_title_font_color":"#353535","tab_filtered_selected_active_highlighted_search_title_font_color":"#353535","tab_filtered_selected_active_highlighted_search_hover_title_font_color":"#353535","tab_filtered_background":"#f8ea45","tab_filtered_active_background":"#f8ea45","tab_filtered_selected_background":"#b4e817","tab_filtered_selected_hover_background":"#96c113","tab_filtered_selected_active_background":"#b4e817","tab_filtered_selected_active_hover_background":"#96c113","tab_filtered_selected_hover_border":"#797979","tab_filtered_selected_active_hover_border":"#797979","tab_filtered_selected_border":"#797979","tab_filtered_selected_active_border":"#797979","tab_filtered_border":"#797979","tab_filtered_active_border":"#797979","tab_filtered_hover_border":"#797979","tab_filtered_active_hover_border":"#797979","tab_filtered_highlighted_search_background":"#ffa500","tab_filtered_highlighted_search_border":"#797979","tab_filtered_active_highlighted_search_border":"#797979","tab_filtered_active_highlighted_search_background":"#ffa500","tab_filtered_selected_highlighted_search_background":"#ffa500","tab_filtered_selected_highlighted_search_border":"#797979","tab_filtered_selected_active_highlighted_search_background":"#ffa500","tab_filtered_selected_active_highlighted_search_border":"#797979","tab_filtered_highlighted_search_hover_background":"#d78b00","tab_filtered_highlighted_search_hover_border":"#797979","tab_filtered_active_highlighted_search_hover_background":"#d78b00","tab_filtered_active_highlighted_search_hover_border":"#797979","tab_filtered_selected_highlighted_search_hover_background":"#d78b00","tab_filtered_selected_highlighted_search_hover_border":"#797979","tab_filtered_selected_active_highlighted_search_hover_background":"#d78b00","tab_filtered_selected_active_highlighted_search_hover_border":"#797979","children_padding_left":"13px","tab_list_background":"#fafafa","tab_selected_active_hover_title_font_style":"italic","tab_selected_active_hover_title_font_weight":"bold","tab_active_title_font_weight":"bold","tab_active_hover_title_font_weight":"bold","tab_hover_background":"#e6e6e6","tab_discarded_hover_background":"#e6e6e6","tab_header_border_radius":"0px","attention_background":"#ed1c24","attention_border":"#ed1c24","close_hover_x":"#ed1c24","close_hover_background":"#bfbfbf","close_x":"#7d7d7d","filter_box_font":"#353535"},"TabsSizeSetNumber":4,"TabsMargins":"0","theme_name":"Light and blue (by Compilenix)","theme_version":4}
\ No newline at end of file
diff --git a/..Themes/Quantum (by InavL).tt_theme b/..Themes/Quantum (by InavL).tt_theme
new file mode 100644
index 0000000..348ef95
--- /dev/null
+++ b/..Themes/Quantum (by InavL).tt_theme
@@ -0,0 +1 @@
+{"ToolbarShow":true,"ColorsSet":{"children_padding_left":"9px","tab_header_border_radius":"2px","expand_closed_background":"#464646","folder_icon_open":"#282828","tab_background":"#343232","tab_discarded_background":"#343232","tab_discarded_border":"#000000","tab_active_background":"#3c3939","attention_background":"#2c2c2c","tab_list_background":"#343232","tab_border":"#000000","tab_active_border":"#000000","close_hover_background":"#504b4b","tab_active_title_font_weight":"normal","tab_hover_background":"#504b4b","tab_active_hover_background":"#504b4b","tab_discarded_hover_background":"#504b4b","tab_discarded_hover_border":"#000000","tab_hover_border":"#000000","tab_active_title_font_color":"#7e7e7e","tab_title_font_color":"#7e7e7e","tab_active_selected_title_font_color":"#7e7e7e","tab_active_hover_title_font_color":"#7e7e7e","tab_selected_active_hover_title_font_color":"#7e7e7e","tab_hover_title_font_color":"#7e7e7e","tab_selected_title_font_color":"#7e7e7e","tab_selected_hover_title_font_color":"#7e7e7e","tab_active_selected_background":"#343232","tab_selected_active_hover_background":"#343232","tab_selected_discarded_background":"#343232","tab_selected_discarded_hover_background":"#343232","tab_selected_background":"#423e3e","tab_selected_hover_background":"#3c3939","tab_selected_border":"#000000","tab_selected_hover_border":"#000000","tab_active_hover_border":"#000000","tab_active_selected_border":"#000000","tab_selected_active_hover_border":"#000000","tab_selected_discarded_border":"#000000","tab_selected_discarded_hover_border":"#000000","tabs_menu_background":"#343232","tabs_menu_font":"#7e7e7e","tabs_menu_separator":"#000000","drag_indicator":"#c0c0c0","tabs_menu_hover_border":"#000000","tabs_menu_border":"#000000","tabs_menu_hover_background":"#343232","pin_list_background":"#343232","filter_box_background":"#504b4b","toolbar_background":"#343232","toolbar_shelf_background":"#343232","button_shelf_background":"#343232","button_background":"#343232","button_on_background":"#504b4b","button_shelf_hover_background":"#504b4b","button_hover_background":"#504b4b","button_border":"#343232","filter_box_border":"#343232","toolbar_border_bottom":"#343232","button_shelf_border":"#343232","button_shelf_hover_border":"#000000","button_hover_border":"#000000","group_list_button_hover_background":"#504b4b","group_list_background":"#343232","group_list_default_font_color":"#808080","group_list_borders":"#000000","close_hover_border":"#504b4b","tab_active_hover_title_font_weight":"normal","tab_active_selected_title_font_weight":"normal","tab_selected_active_hover_title_font_weight":"normal","expand_hover_background":"#ffffff","expand_open_background":"#919191"},"TabsSizeSetNumber":3,"TabsMargins":"0","theme_name":"Quantum","theme_version":4}
\ No newline at end of file
diff --git a/..Themes/Quantum dark dracula.tt_theme b/..Themes/Quantum dark dracula.tt_theme
new file mode 100644
index 0000000..16c759f
--- /dev/null
+++ b/..Themes/Quantum dark dracula.tt_theme
@@ -0,0 +1 @@
+{"ToolbarShow":true,"ColorsSet":{"attention_background":"#ff5555","attention_border":"#ff5555","button_background":"#282a36","button_border":"#44475a","button_hover_background":"#ff79c6","button_hover_border":"#44475a","button_icons":"#f8f8f2","button_icons_hover":"#f8f8f2","button_on_background":"#44475a","button_on_icons":"#f8f8f2","button_shelf_background":"#44475a","button_shelf_border":"#44475a","button_shelf_hover_background":"#44475a","button_shelf_hover_border":"#ff79c6","button_shelf_icons":"#bebebe","button_shelf_icons_hover":"#bebebe","children_padding_left":"11px","close_hover_background":"#ff5555","close_hover_border":"#f8f8f2","close_hover_x":"#f9f9fa","close_x":"#f9f9fa","drag_indicator":"#b5b5b5","expand_closed_background":"#6272a4","expand_hover_background":"#8be9fd","expand_open_background":"#bd93f9","filter_box_background":"#282a36","filter_box_border":"#ff79c6","filter_box_font":"#f8f8f2","filter_clear_icon":"#f8f8f2","folder_icon_closed":"#6272a4","folder_icon_hover":"#bd93f9","folder_icon_open":"#8be9fd","group_list_background":"#282a36","group_list_borders":"#44475a","group_list_button_hover_background":"#6272a4","group_list_default_font_color":"#f8f8f2","pin_list_background":"#282a36","pin_list_border_bottom":"#44475a","scrollbar_height":"11px","scrollbar_thumb":"#525049","scrollbar_thumb_hover":"#2b2a26","scrollbar_track":"#45443f","scrollbar_width":"12px","tab_active_background":"#ff79c6","tab_active_border":"#44475a","tab_active_hover_background":"#f8f8f2","tab_active_hover_border":"#0a84ff","tab_active_hover_title_font_color":"#282a36","tab_active_hover_title_font_weight":"bold","tab_active_selected_background":"#3f7ebe","tab_active_selected_border":"#0a84ff","tab_active_selected_title_font_color":"#e8e8e8","tab_active_selected_title_font_weight":"normal","tab_active_title_font_color":"#282a36","tab_active_title_font_weight":"bold","tab_background":"#282a36","tab_border":"#44475a","tab_discarded_background":"#282a36","tab_discarded_border":"#323234","tab_discarded_hover_background":"#44475a","tab_discarded_hover_border":"#515151","tab_discarded_hover_title_font_color":"#bd93f9","tab_filtered":"#827e00","tab_filtered_active_border":"#d2cb00","tab_filtered_active_highlighted_search_border":"#ed9900","tab_filtered_active_highlighted_search_hover_border":"#ea9800","tab_filtered_active_hover_border":"#d2cb00","tab_filtered_active_hover_title_font_color":"#919191","tab_filtered_active_hover_title_font_weight":"normal","tab_filtered_active_title_font_color":"#919191","tab_filtered_active_title_font_weight":"normal","tab_filtered_border":"#e8e000","tab_filtered_highlighted":"#b37400","tab_filtered_highlighted_search_border":"#ed9900","tab_filtered_highlighted_search_hover_border":"#ea9800","tab_filtered_hover_border":"#d2cb00","tab_filtered_selected":"#0f8079","tab_filtered_selected_active":"#1299a9","tab_filtered_selected_active_border":"#0f8079","tab_filtered_selected_active_highlighted_search_border":"#ed9900","tab_filtered_selected_active_highlighted_search_hover_background":"#c68100","tab_filtered_selected_active_highlighted_search_hover_border":"#ea9800","tab_filtered_selected_active_hover_border":"#0d6d67","tab_filtered_selected_active_hover_title_font_color":"#cfcfcf","tab_filtered_selected_active_hover_title_font_weight":"normal","tab_filtered_selected_active_title_font_color":"#cfcfcf","tab_filtered_selected_active_title_font_weight":"normal","tab_filtered_selected_border":"#0f8079","tab_filtered_selected_highlighted_search_border":"#ed9900","tab_filtered_selected_highlighted_search_hover_border":"#ea9800","tab_filtered_selected_hover_border":"#0d6d67","tab_header_border_radius":"0px","tab_hover_background":"#f1fa8c","tab_hover_border":"#515151","tab_hover_title_font_color":"#282a36","tab_hover_title_font_weight":"normal","tab_list_background":"#282a36","tab_selected_active_hover_background":"#356a9f","tab_selected_active_hover_border":"#359aff","tab_selected_active_hover_title_font_color":"#e8e8e8","tab_selected_active_hover_title_font_weight":"normal","tab_selected_background":"#ff79c6","tab_selected_border":"#44475a","tab_selected_discarded_background":"#2e5c8b","tab_selected_discarded_border":"#2e5c8b","tab_selected_discarded_hover_background":"#25496d","tab_selected_discarded_hover_border":"#336699","tab_selected_discarded_title_font_color":"#9e9e9e","tab_selected_hover_background":"#356a9f","tab_selected_hover_border":"#4d88c4","tab_selected_hover_title_font_color":"#c7c7c7","tab_selected_hover_title_font_weight":"bold","tab_selected_title_font_color":"#f8f8f2","tab_selected_title_font_weight":"normal","tab_title":"#adadad","tab_title_active":"#cacaca","tab_title_discarded":"#7e7e7e","tab_title_font_color":"#f8f8f2","tab_title_font_style":"normal","tab_title_font_weight":"normal","tabs_menu_background":"#282a36","tabs_menu_border":"#6272a4","tabs_menu_font":"#f8f8f2","tabs_menu_hover_background":"#ff79c6","tabs_menu_hover_border":"#f8f8f2","tabs_menu_separator":"#44475a","toolbar_background":"#282a36","toolbar_border_bottom":"#44475a","toolbar_shelf_background":"#4a4a4f","tab_discarded_title_font_color":"#6272a4","tab_selected_hover_title_font_style":"italic"},"TabsSizeSetNumber":2,"TabsMargins":"1","theme_name":"Quantum dark","theme_version":4}
\ No newline at end of file
diff --git a/..Themes/Tree Tabs themes-20180520T124855Z-001.zip b/..Themes/Tree Tabs themes-20180520T124855Z-001.zip
new file mode 100644
index 0000000..1296019
Binary files /dev/null and b/..Themes/Tree Tabs themes-20180520T124855Z-001.zip differ
diff --git a/..Themes/Tree Tabs themes-20180705T201201Z-001.zip b/..Themes/Tree Tabs themes-20180705T201201Z-001.zip
new file mode 100644
index 0000000..b7fa566
Binary files /dev/null and b/..Themes/Tree Tabs themes-20180705T201201Z-001.zip differ
diff --git a/..Themes/TreeTabsCcustomThemeV4.tt_theme b/..Themes/TreeTabsCcustomThemeV4.tt_theme
new file mode 100644
index 0000000..d795796
--- /dev/null
+++ b/..Themes/TreeTabsCcustomThemeV4.tt_theme
@@ -0,0 +1 @@
+{"ToolbarShow":true,"ColorsSet":{"attention_background":"#ff5555","attention_border":"#ff5555","button_background":"#ffddbc","button_border":"#44475a","button_hover_background":"#ffff80","button_hover_border":"#44475a","button_icons":"#000000","button_icons_hover":"#000000","button_on_background":"#ffa500","button_on_icons":"#000000","button_shelf_background":"#ffddbc","button_shelf_border":"#44475a","button_shelf_hover_background":"#ffff80","button_shelf_hover_border":"#ff79c6","button_shelf_icons":"#000000","button_shelf_icons_hover":"#000000","children_padding_left":"16px","close_hover_background":"#ffff80","close_hover_border":"#ff8080","close_hover_x":"#ff8080","close_x":"#ff8080","drag_indicator":"#ffddbc","expand_closed_background":"#ff8080","expand_hover_background":"#ff8080","expand_open_background":"#ff8080","filter_box_background":"#ffff80","filter_box_border":"#ff79c6","filter_box_font":"#000000","filter_clear_icon":"#ff8080","folder_icon_closed":"#ff0000","folder_icon_hover":"#ff8080","folder_icon_open":"#ff0000","group_list_background":"#ffddbc","group_list_borders":"#44475a","group_list_button_hover_background":"#ffddbc","group_list_default_font_color":"#f8f8f2","pin_list_background":"#ffddbc","pin_list_border_bottom":"#44475a","scrollbar_height":"11px","scrollbar_thumb":"#525049","scrollbar_thumb_hover":"#2b2a26","scrollbar_track":"#45443f","scrollbar_width":"12px","tab_active_background":"#ff79c6","tab_active_border":"#44475a","tab_active_hover_background":"#ffff80","tab_active_hover_border":"#0a84ff","tab_active_hover_title_font_color":"#282a36","tab_active_hover_title_font_weight":"bold","tab_active_selected_background":"#ffddbc","tab_active_selected_border":"#0a84ff","tab_active_selected_title_font_color":"#000000","tab_active_selected_title_font_weight":"normal","tab_active_title_font_color":"#282a36","tab_active_title_font_weight":"normal","tab_background":"#ffddbc","tab_border":"#44475a","tab_discarded_background":"#ffddbc","tab_discarded_border":"#323234","tab_discarded_hover_background":"#ffff80","tab_discarded_hover_border":"#515151","tab_discarded_hover_title_font_color":"#000000","tab_filtered":"#827e00","tab_filtered_active_border":"#d2cb00","tab_filtered_active_highlighted_search_border":"#ed9900","tab_filtered_active_highlighted_search_hover_border":"#ea9800","tab_filtered_active_hover_border":"#d2cb00","tab_filtered_active_hover_title_font_color":"#000000","tab_filtered_active_hover_title_font_weight":"normal","tab_filtered_active_title_font_color":"#000000","tab_filtered_active_title_font_weight":"normal","tab_filtered_border":"#e8e000","tab_filtered_highlighted":"#b37400","tab_filtered_highlighted_search_border":"#ed9900","tab_filtered_highlighted_search_hover_border":"#ea9800","tab_filtered_hover_border":"#d2cb00","tab_filtered_selected":"#0f8079","tab_filtered_selected_active":"#1299a9","tab_filtered_selected_active_border":"#0f8079","tab_filtered_selected_active_highlighted_search_border":"#ed9900","tab_filtered_selected_active_highlighted_search_hover_background":"#ffff80","tab_filtered_selected_active_highlighted_search_hover_border":"#ea9800","tab_filtered_selected_active_hover_border":"#0d6d67","tab_filtered_selected_active_hover_title_font_color":"#000000","tab_filtered_selected_active_hover_title_font_weight":"normal","tab_filtered_selected_active_title_font_color":"#000000","tab_filtered_selected_active_title_font_weight":"normal","tab_filtered_selected_border":"#0f8079","tab_filtered_selected_highlighted_search_border":"#ed9900","tab_filtered_selected_highlighted_search_hover_border":"#ea9800","tab_filtered_selected_hover_border":"#0d6d67","tab_header_border_radius":"4px","tab_hover_background":"#f1fa8c","tab_hover_border":"#515151","tab_hover_title_font_color":"#282a36","tab_hover_title_font_weight":"normal","tab_list_background":"#ffddbc","tab_selected_active_hover_background":"#ffff80","tab_selected_active_hover_border":"#359aff","tab_selected_active_hover_title_font_color":"#000000","tab_selected_active_hover_title_font_weight":"normal","tab_selected_background":"#ff79c6","tab_selected_border":"#44475a","tab_selected_discarded_background":"#ffddbc","tab_selected_discarded_border":"#2e5c8b","tab_selected_discarded_hover_background":"#ffff80","tab_selected_discarded_hover_border":"#336699","tab_selected_discarded_title_font_color":"#000000","tab_selected_hover_background":"#ffff80","tab_selected_hover_border":"#4d88c4","tab_selected_hover_title_font_color":"#000000","tab_selected_hover_title_font_weight":"bold","tab_selected_title_font_color":"#000000","tab_selected_title_font_weight":"normal","tab_title":"#adadad","tab_title_active":"#cacaca","tab_title_discarded":"#7e7e7e","tab_title_font_color":"#000000","tab_title_font_style":"normal","tab_title_font_weight":"bold","tabs_menu_background":"#ffddbc","tabs_menu_border":"#6272a4","tabs_menu_font":"#000000","tabs_menu_hover_background":"#ff79c6","tabs_menu_hover_border":"#000000","tabs_menu_separator":"#44475a","toolbar_background":"#ffddbc","toolbar_border_bottom":"#44475a","toolbar_shelf_background":"#ffddbc","tab_discarded_title_font_color":"#000000","tab_selected_hover_title_font_style":"italic","tab_discarded_title_font_weight":"normal","tab_filtered_selected_background":"#80ffff","tab_filtered_selected_hover_background":"#ffff80","tab_filtered_selected_active_background":"#80ffff","tab_filtered_selected_active_hover_background":"#ffff80","tab_filtered_background":"#80ffff","tab_filtered_active_background":"#80ffff","tab_filtered_hover_background":"#ffff80","tab_filtered_active_hover_background":"#ffff80","tab_filtered_highlighted_search_hover_background":"#ffff80","tab_filtered_active_highlighted_search_hover_background":"#ffff80","tab_filtered_selected_highlighted_search_hover_background":"#ffff80","tab_selected_discarded_hover_title_font_color":"#000000","tab_filtered_active_highlighted_search_title_font_weight":"normal","tab_filtered_active_highlighted_search_hover_title_font_weight":"normal","tab_filtered_selected_active_highlighted_search_title_font_weight":"normal","tab_filtered_selected_active_highlighted_search_hover_title_font_weight":"normal"},"TabsSizeSetNumber":3,"TabsMargins":"1","theme_name":"Tree Tabs Custom","theme_version":4}
\ No newline at end of file
diff --git a/..Themes/Vivaldi Human v2.tt_theme b/..Themes/Vivaldi Human v2.tt_theme
new file mode 100644
index 0000000..b2a1034
--- /dev/null
+++ b/..Themes/Vivaldi Human v2.tt_theme
@@ -0,0 +1 @@
+{"ToolbarShow":true,"ColorsSet":{"attention_background":"#cf4010","attention_border":"#cf4010","button_background":"#3b3a35","button_border":"#3b3a35","button_hover_background":"#35342f","button_hover_border":"#35342f","button_icons":"#9e9e9e","button_icons_hover":"#9e9e9e","button_on_background":"#494843","button_on_icons":"#9e9e9e","button_shelf_background":"#494843","button_shelf_border":"#494843","button_shelf_hover_background":"#41403b","button_shelf_hover_border":"#41403b","button_shelf_icons":"#9e9e9e","button_shelf_icons_hover":"#9e9e9e","children_padding_left":"11px","close_hover_background":"#656460","close_hover_border":"#656460","close_hover_x":"#fbfcfe","close_x":"#dddddd","drag_indicator":"#ffa500","expand_closed_background":"#dbdbdb","expand_hover_background":"#f08e60","expand_open_background":"#9e9e9e","filter_box_background":"#35342f","filter_box_border":"#2b2a26","filter_box_font":"#adadad","filter_clear_icon":"#adadad","folder_icon_closed":"#818181","folder_icon_hover":"#f08e60","folder_icon_open":"#9e9e9e","group_list_background":"#3b3a35","group_list_borders":"#2b2a26","group_list_button_hover_background":"#35342f","group_list_default_font_color":"#b1b1b1","pin_list_background":"#494843","pin_list_border_bottom":"#292929","scrollbar_height":"11px","scrollbar_thumb":"#525049","scrollbar_thumb_hover":"#2b2a26","scrollbar_track":"#45443f","scrollbar_width":"12px","tab_active_background":"#52514b","tab_active_border":"#ed773d","tab_active_hover_background":"#52514b","tab_active_hover_border":"#ef835f","tab_active_hover_title_font_color":"#ef835f","tab_active_hover_title_font_weight":"normal","tab_active_selected_background":"#52514b","tab_active_selected_border":"#3f7ebe","tab_active_selected_title_font_color":"#3f7ebe","tab_active_selected_title_font_weight":"normal","tab_active_title_font_color":"#ed773d","tab_active_title_font_weight":"normal","tab_background":"#52514b","tab_border":"#52514b","tab_discarded_background":"#52514b","tab_discarded_border":"#52514b","tab_discarded_hover_background":"#52514b","tab_discarded_hover_border":"#605e57","tab_discarded_hover_title_font_color":"#999999","tab_filtered":"#827e00","tab_filtered_active_border":"#d2cb00","tab_filtered_active_highlighted_search_border":"#ed9900","tab_filtered_active_highlighted_search_hover_border":"#c68100","tab_filtered_active_hover_border":"#b9b500","tab_filtered_active_hover_title_font_color":"#b9b500","tab_filtered_active_hover_title_font_weight":"normal","tab_filtered_active_title_font_color":"#d2cb00","tab_filtered_active_title_font_weight":"normal","tab_filtered_border":"#e8e000","tab_filtered_highlighted":"#b37400","tab_filtered_highlighted_search_border":"#ed9900","tab_filtered_highlighted_search_hover_border":"#c68100","tab_filtered_hover_border":"#b9b500","tab_filtered_selected":"#0f8079","tab_filtered_selected_active":"#1299a9","tab_filtered_selected_active_border":"#0f8079","tab_filtered_selected_active_highlighted_search_border":"#abd618","tab_filtered_selected_active_highlighted_search_hover_background":"#4d4b46","tab_filtered_selected_active_highlighted_search_hover_border":"#abd618","tab_filtered_selected_active_hover_border":"#119791","tab_filtered_selected_active_hover_title_font_color":"#119791","tab_filtered_selected_active_hover_title_font_weight":"normal","tab_filtered_selected_active_title_font_color":"#0f8079","tab_filtered_selected_active_title_font_weight":"normal","tab_filtered_selected_border":"#0f8079","tab_filtered_selected_highlighted_search_border":"#abd618","tab_filtered_selected_highlighted_search_hover_border":"#abd618","tab_filtered_selected_hover_border":"#119791","tab_header_border_radius":"0px","tab_hover_background":"#52514b","tab_hover_border":"#858278","tab_hover_title_font_color":"#cacaca","tab_hover_title_font_weight":"normal","tab_list_background":"#494843","tab_selected_active_hover_background":"#52514b","tab_selected_active_hover_border":"#6c9dce","tab_selected_active_hover_title_font_color":"#6c9dce","tab_selected_active_hover_title_font_weight":"normal","tab_selected_background":"#52514b","tab_selected_border":"#3f7ebe","tab_selected_discarded_background":"#52514b","tab_selected_discarded_border":"#3f7ebe","tab_selected_discarded_hover_background":"#52514b","tab_selected_discarded_hover_border":"#6c9dce","tab_selected_discarded_title_font_color":"#9e9e9e","tab_selected_hover_background":"#52514b","tab_selected_hover_border":"#6699cc","tab_selected_hover_title_font_color":"#cacaca","tab_selected_hover_title_font_weight":"normal","tab_selected_title_font_color":"#c1c1c1","tab_selected_title_font_weight":"normal","tab_title":"#adadad","tab_title_active":"#cacaca","tab_title_discarded":"#7e7e7e","tab_title_font_color":"#c1c1c1","tab_title_font_style":"normal","tab_title_font_weight":"normal","tabs_menu_background":"#494843","tabs_menu_border":"#3b3a35","tabs_menu_font":"#bfbfbf","tabs_menu_hover_background":"#52514b","tabs_menu_hover_border":"#858278","tabs_menu_separator":"#3b3a35","toolbar_background":"#3b3a35","toolbar_border_bottom":"#2b2a26","toolbar_shelf_background":"#494843","tab_filtered_background":"#52514b","tab_filtered_active_background":"#52514b","tab_filtered_active_hover_background":"#52514b","tab_filtered_highlighted_search_hover_background":"#52514b","tab_filtered_active_highlighted_search_hover_background":"#52514b","tab_filtered_hover_background":"#4d4b46","tab_filtered_highlighted_search_background":"#52514b","tab_filtered_active_highlighted_search_background":"#52514b","tab_filtered_selected_highlighted_search_background":"#52514b","tab_filtered_selected_active_highlighted_search_background":"#52514b","tab_filtered_selected_highlighted_search_hover_background":"#4d4b46","tab_filtered_active_highlighted_search_hover_title_font_weight":"normal","tab_filtered_active_highlighted_search_title_font_weight":"normal","tab_filtered_active_highlighted_search_title_font_color":"#ed9900","tab_filtered_active_highlighted_search_hover_title_font_color":"#ed9900","tab_filtered_selected_active_highlighted_search_title_font_color":"#abd618","tab_filtered_selected_active_highlighted_search_hover_title_font_color":"#abd618","tab_filtered_selected_active_highlighted_search_hover_title_font_weight":"normal","tab_filtered_selected_active_highlighted_search_title_font_weight":"normal","tab_filtered_selected_active_hover_background":"#52514b","tab_filtered_selected_hover_background":"#52514b","tab_filtered_selected_background":"#52514b","tab_filtered_selected_active_background":"#52514b","tab_filtered_selected_highlighted_search_title_font_color":"#b5b5b5","tab_filtered_selected_highlighted_search_hover_title_font_color":"#b5b5b5","tab_filtered_highlighted_search_title_font_color":"#b5b5b5","tab_filtered_highlighted_search_hover_title_font_color":"#b5b5b5","tab_filtered_title_font_color":"#b5b5b5","tab_filtered_hover_title_font_color":"#b5b5b5","tab_filtered_selected_title_font_color":"#b5b5b5","tab_filtered_selected_hover_title_font_color":"#b5b5b5","tab_discarded_title_font_color":"#8c8c8c","tab_filtered_hover_title_font_weight":"normal","tab_filtered_highlighted_search_title_font_weight":"normal","tab_selected_discarded_hover_title_font_color":"#999999"},"TabsSizeSetNumber":1,"TabsMargins":"2","theme_name":"Vivaldi Human v2","theme_version":4}
\ No newline at end of file
diff --git a/..files_ForTesting/manifest.json b/..files_ForTesting/manifest.json
index 0e7a66c..65ed9e0 100644
--- a/..files_ForTesting/manifest.json
+++ b/..files_ForTesting/manifest.json
@@ -2,7 +2,7 @@
"manifest_version": 2,
"default_locale": "en",
"background": {
- "scripts": [ "listeners_bg.js", "scripts/common.js", "background.js" ],
+ "scripts": [ "global.js", "./scripts/preferences.js", "background_firefox.js", "background_opera.js", "background_vivaldi.js", "background.js" ],
"persistent": true
},
"name": "Tree Tabs",
@@ -36,7 +36,7 @@
}
},
"options_ui": {
- "page": "options.html",
+ "page": "options/options.html",
"open_in_tab": true
},
"commands": {
@@ -45,5 +45,5 @@
"description": "close tree"
}
},
- "version": "100"
+ "version": "1.8.6"
}
\ No newline at end of file
diff --git a/..files_firefox/manifest.json b/..files_firefox/manifest.json
index f212733..754c56d 100644
--- a/..files_firefox/manifest.json
+++ b/..files_firefox/manifest.json
@@ -2,7 +2,7 @@
"manifest_version": 2,
"default_locale": "en",
"background": {
- "scripts": [ "listeners_bg.js", "scripts/common.js", "background.js" ],
+ "scripts": [ "global.js", "./scripts/preferences.js", "background_firefox.js", "background_opera.js", "background_vivaldi.js", "background.js" ],
"persistent": true
},
"name": "Tree Tabs",
@@ -41,12 +41,12 @@
"applications": {
"gecko": {
"id": "TreeTabs@jagiello.it",
- "strict_min_version": "57.0"
+ "strict_min_version": "63.0"
}
},
"options_ui": {
- "page": "options.html",
+ "page": "options/options.html",
"open_in_tab": true
},
- "version": "1.7.2"
+ "version": "1.8.7"
}
\ No newline at end of file
diff --git a/..files_opera/manifest.json b/..files_opera/manifest.json
index 37cfb4e..8aa6480 100644
--- a/..files_opera/manifest.json
+++ b/..files_opera/manifest.json
@@ -3,7 +3,7 @@
"minimum_opera_version": "42",
"default_locale": "en",
"background": {
- "scripts": [ "listeners_bg.js", "scripts/common.js", "background.js" ],
+ "scripts": [ "global.js", "./scripts/preferences.js", "background_firefox.js", "background_opera.js", "background_vivaldi.js", "background.js" ],
"persistent": true
},
"name": "Tree Tabs",
@@ -24,12 +24,12 @@
"default_panel": "sidebar.html",
"default_title": "Tree Tabs"
},
- "options_page": "options.html",
+ "options_page": "options/options.html",
"commands": {
"close_tree": {
"suggested_key": { "default": "Alt+W" },
"description": "close tree"
}
},
- "version": "1.7.2"
+ "version": "1.8.6"
}
diff --git a/..files_vivaldi/manifest.json b/..files_vivaldi/manifest.json
index 2f02911..e58c349 100644
--- a/..files_vivaldi/manifest.json
+++ b/..files_vivaldi/manifest.json
@@ -2,7 +2,7 @@
"manifest_version": 2,
"default_locale": "en",
"background": {
- "scripts": [ "listeners_bg.js", "scripts/common.js", "background.js" ],
+ "scripts": [ "global.js", "./scripts/preferences.js", "background_firefox.js", "background_opera.js", "background_vivaldi.js", "background.js" ],
"persistent": true
},
"name": "Tree Tabs",
@@ -16,7 +16,7 @@
},
"permissions": [ "tabs", "sessions", "", "storage", "unlimitedStorage", "bookmarks" ],
"options_ui": {
- "page": "options.html",
+ "page": "options/options.html",
"open_in_tab": false
},
"commands": {
@@ -25,5 +25,5 @@
"description": "close tree"
}
},
- "version": "1.7.2"
+ "version": "1.8.6"
}
diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index cf69c75..73fb09f 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -1,1437 +1 @@
-{
- "extensionName": {
- "message": "Tree Tabs"
- },
- "extDesc": {
- "message": "Manage your tabs in the sidebar!"
- },
- "OpenSidebar": {
- "message": "Open Tree Tabs"
- },
-
-
- "button_new": {
- "message": "Press left mouse button to open new tab. \nPress middle mouse button to clone the active tab. \nPress right mouse button to scroll the list to the active tab."
- },
- "button_pin": {
- "message": "Pin / Unpin current tab"
- },
- "button_undo": {
- "message": "Reopen last closed"
- },
- "button_reboot": {
- "message": "Reload Tree Tabs. Try this in case your tree hierarchy is lost after restart."
- },
- "button_detach": {
- "message": "Detach tab"
- },
- "button_move": {
- "message": "Detach tab"
- },
- "button_search": {
- "message": "Search tabs"
- },
- "button_tools": {
- "message": "Tools"
- },
- "button_groups": {
- "message": "Groups"
- },
- "filter_search_go_prev": {
- "message": "Previous search result"
- },
- "filter_search_go_next": {
- "message": "Next search result"
- },
- "button_bookmarks": {
- "message": "Unsorted bookmarks"
- },
- "button_downloads": {
- "message": "Downloads"
- },
- "button_history": {
- "message": "History"
- },
- "button_settings": {
- "message": "Settings"
- },
- "button_options": {
- "message": "Tree Tabs settings"
- },
- "button_extensions": {
- "message": "Extensions"
- },
- "button_unload": {
- "message": "Unload tabs"
- },
- "button_discard": {
- "message": "Unload tabs"
- },
- "button_filter_type": {
- "message": "Search titles or urls"
- },
-
-
-
-
-
- "button_groups_toolbar_hide": {
- "message": "Hide/Show Groups toolbar"
- },
- "button_new_group": {
- "message": "New group"
- },
- "button_remove_group": {
- "message": "Remove group.\nHold shift key to close tabs from this group"
- },
- "button_edit_group": {
- "message": "Rename group"
- },
-
- "button_import_group": {
- "message": "Import group"
- },
- "button_export_group": {
- "message": "Export group"
- },
-
- "button_backup": {
- "message": "Session"
- },
- "button_import_bak": {
- "message": "Import session"
- },
- "button_import_merge_bak": {
- "message": "Import and merge session.\nImporter will try to match current tabs with those from saved session, instead of opening a new window."
- },
- "button_export_bak": {
- "message": "Export session"
- },
- "button_load_bak1": {
- "message": "EMERGENCY if lost groupings: Load latest internal backup (autosave is made every 5 minutes)"
- },
- "button_load_bak2": {
- "message": "EMERGENCY if lost groupings: Load previous to latest internal backup (autosave is made every 10 minutes)"
- },
- "button_load_bak3": {
- "message": "EMERGENCY if lost groupings: Load oldest internal backup (autosave is made every 30 minutes)"
- },
-
-
- "button_folders": {
- "message": "Folders"
- },
- "button_new_folder": {
- "message": "New folder"
- },
- "button_remove_folder": {
- "message": "Remove selected folder/s"
- },
- "button_edit_folder": {
- "message": "Rename folder"
- },
-
-
-
-
-
-
- "menu_expand_all": {
- "message": "Expand all trees"
- },
- "menu_collapse_all": {
- "message": "Collapse all trees"
- },
- "menu_expand_tree": {
- "message": "Expand tree"
- },
- "menu_collapse_tree": {
- "message": "Collapse tree"
- },
- "menu_new_tab": {
- "message": "New tab"
- },
- "menu_new_pin": {
- "message": "New pinned tab"
- },
- "menu_duplicate_tab": {
- "message": "Duplicate"
- },
- "menu_detach_tab": {
- "message": "Detach"
- },
- "menu_reload_tab": {
- "message": "Reload"
- },
- "menu_pin_tab": {
- "message": "Pin"
- },
- "menu_mute_tab": {
- "message": "Mute"
- },
- "menu_mute_tree": {
- "message": "Mute tree"
- },
- "menu_unmute_tree": {
- "message": "Unmute tree"
- },
- "menu_unmute_tab": {
- "message": "Unmute"
- },
- "menu_mute_other": {
- "message": "Mute other"
- },
- "menu_unmute_other": {
- "message": "Unmute other"
- },
- "menu_unpin_tab": {
- "message": "Unpin"
- },
- "menu_close_tree": {
- "message": "Close tree"
- },
- "menu_close": {
- "message": "Close"
- },
- "menu_close_other": {
- "message": "Close other"
- },
- "menu_undo_close_tab": {
- "message": "Undo close"
- },
- "menu_treetabs_settings": {
- "message": "Settings"
- },
- "menu_unload": {
- "message": "Unload"
- },
-
- "menu_bookmark_tree": {
- "message": "Bookmark"
- },
-
-
-
- "menu_new_folder": {
- "message": "New folder"
- },
- "menu_rename_folder": {
- "message": "Rename folder"
- },
- "menu_delete_folder": {
- "message": "Delete"
- },
-
- "menu_new_group": {
- "message": "New group"
- },
- "menu_rename_group": {
- "message": "Rename"
- },
- "menu_delete_group": {
- "message": "Delete"
- },
- "menu_delete_group_tabs_close": {
- "message": "Delete with tabs"
- },
-
- "menu_groups_unload": {
- "message": "Unload"
- },
-
- "menu_bookmark_group": {
- "message": "Bookmark"
- },
- "menu_groups_hibernate": {
- "message": "Hibernate"
- },
- "menu_group_tabs_close": {
- "message": "Close tabs"
- },
-
-
-
-
-
-
-
- "options_vivaldi": {
- "message": " Vivaldi "
- },
- "opt_url_for_web_panel": {
- "message": "Url for the Web Panel"
- },
- "options_pinned": {
- "message": " Pinned tabs bar "
- },
- "options_pin_list_multi_row": {
- "message": "Multi row list"
- },
- "option_allow_pin_close": {
- "message": "Allow to close pinned tabs"
- },
- "options_tabs": {
- "message": " Tabs "
- },
- "options_syncro_tabbar_tabs_order": {
- "message": "Synchronize browser tabs order with Tree Tabs, tabs can be unresponsive for a second after drag&drop. This option is needed for correct ctrl+tab switching. You can disable this option if you don't use keyboard shortcuts."
- },
- "options_switch_with_scroll": {
- "message": "Switch tabs with mouse wheel"
- },
-
- "options_tab_group_regex": {
- "message": "Tab group assignments (Items matching the given pattern will be moved to the designated group. Pattern accepts regular expressions.)"
- },
- "option_tab_match": {
- "message": "Pattern"
- },
- "option_tab_group": {
- "message": "Group"
- },
- "options_orphaned_tabs_to_ungrouped": {
- "message": "Always place orphan tabs in the 'ungrouped' group"
- },
- "options_move_on_url_change": {
- "message": "Move tabs that match regexes"
- },
- "options_move_on_url_change_never": {
- "message": "never"
- },
- "options_move_on_url_change_from_empty": {
- "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 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": "whenever URL changes to a matching pattern"
- },
-
- "options_always_show_close": {
- "message": "Show close button on all tabs and folders"
- },
- "options_never_show_close": {
- "message": "Never show close button (option above will be ignored)"
- },
- "options_collapse_other_trees": {
- "message": "Automatically collapse other trees on expand"
- },
- "options_open_tree_on_hover": {
- "message": "Auto expand collapsed trees when dragging and holding for a second over them"
- },
- "options_promote_children": {
- "message": "Promote children on close, if disabled, when closing the parent of a tree structure, all tabs and folders will be closed (be careful, because undo close tab will not recover the trees structure)"
- },
-
- "options_promote_children_in_first_child": {
- "message": "Promote first child as a parent"
- },
-
- "options_skip_load": {
- "message": "Discard tree structure after browser's restart, this option is for those who don't use browser's session. Basically it disables loading database at startup."
- },
-
-
- "options_midclick_tab": {
- "message": "Action for middle mouse click on tab"
- },
- "options_dbclick_tab": {
- "message": "Action for double click on tab"
- },
-
- "options_action_tab_none": {
- "message": "nothing"
- },
- "options_action_tab_new": {
- "message": "open new tab"
- },
- "options_action_tab_expand_collapse": {
- "message": "expand/collapse tree"
- },
- "options_action_tab_close": {
- "message": "close tab"
- },
- "options_action_tab_reload": {
- "message": "reload tab"
- },
- "options_action_tab_unload": {
- "message": "unload tab"
- },
- "options_action_tab_activate_previous_active": {
- "message": "go back to previous active tab (works only on unpinned tabs)"
- },
- "options_action_tab_undo_close": {
- "message": "reopen last closed tab"
- },
-
-
-
-
- "options_midclick_group": {
- "message": "Action for middle click on empty space on the left side or below the tabs"
- },
- "options_dbclick_group": {
- "message": "Action for double click on empty space on the left side or below the tabs"
- },
- "options_action_group_none": {
- "message": "nothing"
- },
- "options_action_group_new": {
- "message": "open new tab"
- },
- "options_action_group_activate_previous_active": {
- "message": "go back to previous active tab (works only on unpinned tabs)"
- },
- "options_action_group_undo_close_tab": {
- "message": "reopen last closed tab"
- },
-
-
-
-
- "options_append_child_tab": {
- "message": "Place children tabs"
- },
- "options_append_child_tab_top": {
- "message": "at the top (reverse hierarchy)"
- },
- "options_append_child_tab_bottom": {
- "message": " at the bottom"
- },
- "options_append_child_tab_after": {
- "message": "after parent tab (no automatic tree)"
- },
-
- "options_append_orphan_tab": {
- "message": "Append orphan tabs"
- },
- "options_append_orphan_tab_top": {
- "message": "at the top of the group"
- },
- "options_append_orphan_tab_after_active": {
- "message": "after active tab"
- },
- "options_append_orphan_tab_bottom": {
- "message": "at the bottom of the group"
- },
- "options_append_orphan_tab_as_child": {
- "message": "treat as active's tab child"
- },
-
- "options_toolbar_new_tab": {
- "message": "Toolbar + (new tab button) should append tab"
- },
- "options_toolbar_new_tab_as_regular_orphan": {
- "message": "as a regular orphan tab (option above)"
- },
- "options_toolbar_new_tab_root_of_group": {
- "message": "at the bottom of the group"
- },
-
-
-
- "options_after_closing_active_tab": {
- "message": "After closing active tab,"
- },
- "options_after_closing_active_tab_go_up": {
- "message": "activate tab above"
- },
- "options_after_closing_active_tab_go_down": {
- "message": "activate tab below"
- },
- "options_after_closing_active_tab_go_up_seek_in_parent": {
- "message": "activate tab above if on the same level"
- },
- "options_after_closing_active_tab_go_down_seek_in_parent": {
- "message": "activate tab below if on the same level"
- },
- "options_after_closing_active_tab_go_browser": {
- "message": "let browser activate tab"
- },
-
- "options_append_child_tab_after_limit": {
- "message": "Once reached maximum tree depth, place tab on the same level, but"
- },
- "options_append_child_tab_after_limit_top": {
- "message": "at the top"
- },
- "options_append_child_tab_after_limit_after": {
- "message": "after parent"
- },
- "options_append_child_tab_after_limit_bottom": {
- "message": "at the bottom"
- },
- "options_show_counter_tabs": {
- "message": "Show children tabs count on tabs and folders titles"
- },
- "options_show_counter_tabs_hints": {
- "message": "Show children tabs count in tabs and folders hints"
- },
-
- "options_max_tree_depth": {
- "message": "Maximum tree depth: set it to -1 for unlimited branches, 0 for flat tabs placement (no trees), any number above 0 will be its maximum"
- },
- "options_max_tree_drag_drop": {
- "message": "Limit Drag&Drop to tree's maximum depth, so you can't drop tabs beyond maximum depth"
- },
- "options_max_tree_drag_drop_folders": {
- "message": "Limit Drag&Drop to tree's maximum depth, so you can't drop folders beyond maximum depth"
- },
-
-
-
- "options_groups": {
- "message": "Groups"
- },
-
- "options_show_counter_groups": {
- "message": "Show tabs count on groups"
- },
-
- "options_groups_toolbar_default": {
- "message": "Show groups toolbar in new windows"
- },
- "options_syncro_tabbar_groups_tabs_order": {
- "message": "Synchronize browser tabs order after drag&drop of the group tabs. Tabs will sort for a long time, if browser has a lot of tabs open. This option is needed for correct ctrl+tab switching. You can disable this option if you don't use keyboard shortcuts."
- },
-
- "options_hide_other_groups_tabs_firefox": {
- "message": "Show Firefox tabs from current group only. Requires change in about:config, find 'extensions.webextensions.tabhide.enabled' and set it to true."
- },
-
-
-
-
- "options_folders": {
- "message": "Folders"
- },
-
-
- "options_midclick_folder": {
- "message": "Action for middle mouse click on folder"
- },
- "options_dbclick_folder": {
- "message": "Action for double click on folder"
- },
-
- "options_action_folder_none": {
- "message": "nothing"
- },
- "options_action_folder_rename": {
- "message": "rename folder"
- },
- "options_action_folder_new_folder": {
- "message": "open new folder"
- },
- "options_action_folder_new_tab": {
- "message": "open new tab"
- },
- "options_action_folder_expand_collapse": {
- "message": "expand/collapse tree"
- },
- "options_action_folder_close": {
- "message": "close folder"
- },
- "options_action_folder_unload": {
- "message": "unload tabs in folder"
- },
-
-
-
-
-
-
-
-
-
-
- "options_global": {
- "message": "Global"
- },
-
-
-
- "options_theme": {
- "message": "Theme"
- },
-
-
-
- "options_rename_theme_button": {
- "message": "Rename"
- },
- "options_add_theme_button": {
- "message": "Add new"
- },
- "options_remove_theme_button": {
- "message": "Remove"
- },
- "options_import_theme_button": {
- "message": "Import"
- },
- "options_export_theme_button": {
- "message": "Export"
- },
- "options_share_theme_link": {
- "message": "Get more!"
- },
-
-
-
-
-
-
-
- "options_toolbar": {
- "message": " Toolbar "
- },
- "options_available_buttons": {
- "message": "Drag and drop buttons to arrange them, drop to the green box, buttons you don't want to use"
- },
-
- "options_reset_toolbar_button": {
- "message": "Reset toolbar"
- },
-
- "options_export_debug": {
- "message": "Export log file"
- },
- "options_print_debug": {
- "message": "Load log from file"
- },
-
-
- "options_toolbar_look": {
- "message": " Toolbar's look "
- },
-
-
- "hint_orphan_tab": {
- "message": "Orphan tab is a tab opened from an external source, which can be:"
- },
- "hint_ctrl_t": {
- "message": "ctrl+t shortcut"
- },
- "hint_from_pin": {
- "message": "link that opens new tab from pinned tab"
- },
- "hint_from_bookmark": {
- "message": "bookmark"
- },
- "hint_from_external_link": {
- "message": "external link"
- },
- "hint_from_popup": {
- "message": "popup opened as a tab (settings in browser, popup blocker or similar)"
- },
- "hint_explained_new_tab_settings": {
- "message": "+ button in Tree Tabs toolbar, places new tabs in the root of the active group, unless set differently."
- },
- "hint_explained_orphan_after_active_settings": {
- "message": "If 'Append orphan tabs' is set to 'after active' and active tab is not in active group, tab will append to the root of the active group instead. But only if sidebar is open."
- },
-
-
-
- "button_background": {
- "message": "Toolbar buttons background"
- },
- "button_hover_background": {
- "message": "Toolbar buttons background, on mouse hover"
- },
- "button_on_background": {
- "message": "Toolbar active buttons background"
- },
-
-
- "button_icons": {
- "message": "Toolbar buttons icon color"
- },
- "button_icons_hover": {
- "message": "Toolbar buttons icon color, on mouse hover"
- },
- "button_on_icons": {
- "message": "Toolbar active buttons icon color"
- },
- "button_border": {
- "message": "Toolbar buttons border color"
- },
- "button_hover_border": {
- "message": "Toolbar buttons border color, on mouse hover"
- },
-
-
- "filter_box_font": {
- "message": "Search box, font color"
- },
- "filter_box_background": {
- "message": "Search box, font background color"
- },
- "filter_box_border": {
- "message": "Search box, border color"
- },
- "filter_clear_icon": {
- "message": "Clear search result x button color"
- },
-
-
- "toolbar_background": {
- "message": "Toolbar background color"
- },
- "toolbar_shelf_background": {
- "message": "Toolbar's shelf background color"
- },
- "toolbar_border_bottom": {
- "message": "Toolbar borders color"
- },
-
-
-
- "button_shelf_background": {
- "message": "Toolbar's shelf buttons background color"
- },
- "button_shelf_hover_background": {
- "message": "Toolbar's shelf buttons background color, on mouse hover"
- },
- "button_shelf_icons": {
- "message": "Toolbar's shelf buttons icon color"
- },
- "button_shelf_icons_hover": {
- "message": "Toolbar's shelf buttons icon color, on mouse hover"
- },
- "button_shelf_border": {
- "message": "Toolbar's shelf buttons border color"
- },
- "button_shelf_hover_border": {
- "message": "Toolbar's shelf buttons border color, on mouse hover"
- },
-
-
-
-
-
-
-
-
-
- "options_theme_tabs": {
- "message": " Tabs look "
- },
-
-
-
- "options_tabs_margin_overlap": {
- "message": "Tabs spacing:\nOverlap 1px, best for themes with borders"
- },
- "options_tabs_margin_0": {
- "message": "Tabs spacing:\nNo spacing, best for flat look"
- },
- "options_tabs_margin_1": {
- "message": "Tabs spacing:\nDefault, 1px between tabs"
- },
-
-
-
-
- "options_tab_list_scrollbar_width_down": {
- "message": "Decrease scrollbars width"
- },
- "options_tab_list_scrollbar_width_up": {
- "message": "Increase scrollbars width"
- },
- "options_tab_list_scrollbar_height_down": {
- "message": "Decrease scrollbars height"
- },
- "options_tab_list_scrollbar_height_up": {
- "message": "Increase scrollbars height"
- },
-
-
-
- "options_tabs_indentation_down": {
- "message": "Decrease tabs indentation"
- },
- "options_tabs_indentation_up": {
- "message": "Increase tabs indentation"
- },
-
-
- "options_tabs_roundness_down": {
- "message": "Make tabs corners more square"
- },
- "options_tabs_roundness_up": {
- "message": "Make tabs rounder"
- },
-
-
- "options_tabs_size_down": {
- "message": "Decrease tabs size"
- },
- "options_tabs_size_up": {
- "message": "Increase tabs size"
- },
-
-
-
- "options_theme_tabs_sample_text_normal": {
- "message": "Normal"
- },
- "options_theme_tabs_sample_text_normal_hover": {
- "message": "Normal, mouse hover over"
- },
- "options_theme_tabs_sample_text_normal_selected": {
- "message": "Normal selected"
- },
- "options_theme_tabs_sample_text_normal_selected_hover": {
- "message": "Normal selected, mouse hover over"
- },
- "options_theme_tabs_sample_text_active": {
- "message": "Active"
- },
- "options_theme_tabs_sample_text_active_hover": {
- "message": "Active, mouse hover over"
- },
- "options_theme_tabs_sample_text_active_selected": {
- "message": "Active and selected"
- },
- "options_theme_tabs_sample_text_active_selected_hover": {
- "message": "Active and selected, mouse hover over"
- },
-
- "options_theme_tabs_sample_text_discarded": {
- "message": "Unloaded (discarded)"
- },
- "options_theme_tabs_sample_text_discarded_hover": {
- "message": "Unloaded, mouse hover over"
- },
- "options_theme_tabs_sample_text_discarded_selected": {
- "message": "Unloaded and selected"
- },
- "options_theme_tabs_sample_text_discarded_selected_hover": {
- "message": "Unloaded and selected, mouse hover over"
- },
-
- "options_theme_tabs_sample_text_search_result": {
- "message": "Search result"
- },
- "options_theme_tabs_sample_text_search_result_hover": {
- "message": "Search result, mouse hover over"
- },
- "options_theme_tabs_sample_text_search_result_active": {
- "message": "Search result active"
- },
- "options_theme_tabs_sample_text_search_result_active_hover": {
- "message": "Search result active, mouse hover over"
- },
-
- "options_theme_tabs_sample_text_search_result_selected": {
- "message": "Search result selected"
- },
- "options_theme_tabs_sample_text_search_result_selected_hover": {
- "message": "Search result selected, mouse hover over"
- },
- "options_theme_tabs_sample_text_search_result_selected_active": {
- "message": "Search result selected, active"
- },
- "options_theme_tabs_sample_text_search_result_selected_active_hover": {
- "message": "Search result selected, active, mouse hover over"
- },
-
-
-
- "options_theme_tabs_sample_text_search_result_highlighted": {
- "message": "Search result highlighted"
- },
- "options_theme_tabs_sample_text_search_result_highlighted_hover": {
- "message": "Search result highlighted, mouse hover over"
- },
- "options_theme_tabs_sample_text_search_result_highlighted_active": {
- "message": "Search result highlighted, active"
- },
- "options_theme_tabs_sample_text_search_result_highlighted_active_hover": {
- "message": "Search result highlighted, active, mouse hover over"
- },
-
-
- "options_theme_tabs_sample_text_search_result_highlighted_selected": {
- "message": "Search result highlighted, selected"
- },
- "options_theme_tabs_sample_text_search_result_highlighted_selected_hover": {
- "message": "Search result highlighted, selected, mouse hover over"
- },
- "options_theme_tabs_sample_text_search_result_highlighted_selected_active": {
- "message": "Search result highlighted, selected, active"
- },
- "options_theme_tabs_sample_text_search_result_highlighted_selected_active_hover": {
- "message": "Search result highlighted, selected, active, mouse hover over"
- },
-
-
-
-
-
-
- "attention_background": {
- "message": "Tabs blinking for attention, background color"
- },
- "attention_border": {
- "message": "Tabs blinking for attention, border color"
- },
- "pin_list_border_bottom": {
- "message": "Pinned tabs list, border at the bottom color"
- },
- "pin_list_background": {
- "message": "Pinned tabs list, background color"
- },
-
-
- "folder_icon_open": {
- "message": "Open folder icon"
- },
- "folder_icon_closed": {
- "message": "Empty or closed folder icon"
- },
- "folder_icon_hover": {
- "message": "Folder icon on mouse hover"
- },
-
-
- "expand_open_background": {
- "message": "Open tree indicator"
- },
- "expand_closed_background": {
- "message": "Closed tree indicator"
- },
- "expand_hover_background": {
- "message": "Tree indicator on mouse hover"
- },
-
-
- "group_list_button_hover_background": {
- "message": "Group on mouse hover"
- },
- "group_list_borders": {
- "message": "Group list border"
- },
- "group_list_default_font_color": {
- "message": "Group list default font color"
- },
-
- "group_list_background": {
- "message": "Group list background color"
- },
- "tab_list_background": {
- "message": "Tabs background color"
- },
-
-
- "drag_indicator": {
- "message": "Drag&Drop indicator"
- },
-
-
-
-
-
-
- "close_x": {
- "message": "x inside the close button"
- },
- "close_hover_x": {
- "message": "x inside the close button, on mouse hover"
- },
- "close_hover_border": {
- "message": "close button border, on mouse hover"
- },
- "close_hover_background": {
- "message": "close button box color, on mouse hover"
- },
-
-
-
- "scrollbar_thumb": {
- "message": "Scrollbar thumb"
- },
- "scrollbar_thumb_hover": {
- "message": "Scrollbar thumb, on mouse hover"
- },
- "scrollbar_track": {
- "message": "Scrollbar track"
- },
-
-
-
-
-
- "options_example_menu_item": {
- "message": "menu item"
- },
- "options_menu": {
- "message": " Menu "
- },
-
-
- "tabs_menu_hover_border": {
- "message": "menu item border, on mouse hover"
- },
- "tabs_menu_hover_background": {
- "message": "menu item background, on mouse hover"
- },
- "tabs_menu_separator": {
- "message": "menu separator"
- },
- "tabs_menu_font": {
- "message": "menu text color"
- },
- "tabs_menu_border": {
- "message": "menu border"
- },
- "tabs_menu_background": {
- "message": "menu background"
- },
-
-
-
-
-
-
-
-
-
-
-
- "options_there_is_a_theme_with_this_name": {
- "message": "Theme with this name already exists, try a new name"
- },
- "options_theme_name_cannot_be_empty": {
- "message": "Theme name cannot be empty, enter some name"
- },
- "options_no_theme_to_export": {
- "message": "No theme to export, maybe add a new one :)"
- },
- "options_loaded_theme_older_version": {
- "message": "Looks like loaded theme was saved in older version of the extension, some colors or options might be missing"
- },
- "options_loaded_theme_newer_version": {
- "message": "Looks like loaded theme was saved in a newer version of the extension, can't load!"
- },
-
-
-
-
-
-
-
-
-
-
-
-
-
- "options_vivaldi_copied_url": {
- "message": "Web Panel Url has been copied to clipboard, add a new Web Panel and paste url."
- },
- "options_copied_wallet_address": {
- "message": "Wallet address has been copied to clipboard"
- },
-
-
- "options_clear_data": {
- "message": "Sidebar is not loading? Reset! ATTENTION! All options and saved Themes will be lost!"
- },
-
-
- "options_development": {
- "message": "Development"
- },
- "options_debug": {
- "message": "Debug"
- },
-
-
-
-
-
-
-
-
-
-
-
- "group_edit_button_cancel": {
- "message": "Cancel"
- },
-
- "group_edit_button_confirm": {
- "message": "Ok"
- },
-
-
-
- "folder_edit_button_cancel": {
- "message": "Cancel"
- },
-
- "folder_edit_button_confirm": {
- "message": "Ok"
- },
-
-
- "manager_window_button_label_import_group": {
- "message": "Import group"
- },
-
- "manager_window_button_label_import_session": {
- "message": "Import session"
- },
- "manager_window_button_label_save_current_session": {
- "message": "Save current session"
- },
-
-
-
-
-
-
-
- "caption_ungrouped_group": {
- "message": "Ungrouped"
- },
- "caption_noname_group": {
- "message": "untitled"
- },
-
- "caption_clear_filter": {
- "message": "Clear search results"
- },
- "caption_loading": {
- "message": "Loading..."
- },
- "caption_searchbox": {
- "message": " Search tabs..."
- },
-
- "manager_window_header_title": {
- "message": "Manager"
- },
-
- "menu_manager_window": {
- "message": "Open manager"
- },
-
- "button_manager_window": {
- "message": "Open manager window"
- },
-
- "manager_window_groups_button": {
- "message": "Hibernated groups"
- },
- "manager_window_sessions_button": {
- "message": "Saved sessions"
- },
- "manager_window_autosave_button": {
- "message": "Auto saved sessions"
- },
- "manager_window_button_label_hibernate_group": {
- "message": "Hibernate current group"
- },
-
- "manager_window_autosessions_maximum_saves_label": {
- "message": "Number of autosaves to keep:"
- },
-
- "manager_window_autosessions_save_timer_label": {
- "message": "Autosave every (minutes):"
- },
-
- "manager_window_delete_icon": {
- "message": "Remove"
- },
-
- "manager_window_savetofile_icon": {
- "message": "Save to file"
- },
- "manager_window_merge_icon": {
- "message": "Load and merge"
- },
-
- "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": ""
- }
-
-
-
-
-
-
-
-
-
-
-}
+{"extensionName":{"message":"Tree Tabs"},"extDesc":{"message":"Manage your tabs in the sidebar!"},"OpenSidebar":{"message":"Open Tree Tabs"},"button_new":{"message":"Press left mouse button to open new tab. \nPress middle mouse button to clone the active tab. \nPress right mouse button to scroll the list to the active tab."},"button_pin":{"message":"Pin / Unpin current tab"},"button_undo":{"message":"Reopen last closed"},"button_reboot":{"message":"Reload Tree Tabs. Try this in case your tree hierarchy is lost after restart."},"button_detach":{"message":"Detach tab"},"button_move":{"message":"Detach tab"},"button_search":{"message":"Search tabs"},"button_tools":{"message":"Tools"},"button_groups":{"message":"Groups"},"filter_search_go_prev":{"message":"Previous search result"},"filter_search_go_next":{"message":"Next search result"},"button_bookmarks":{"message":"Unsorted bookmarks"},"button_downloads":{"message":"Downloads"},"button_history":{"message":"History"},"button_settings":{"message":"Settings"},"button_options":{"message":"Tree Tabs settings"},"button_extensions":{"message":"Extensions"},"button_unload":{"message":"Unload tabs"},"button_discard":{"message":"Unload tabs"},"button_filter_type":{"message":"Search titles or urls"},"button_groups_toolbar_hide":{"message":"Hide/Show Groups toolbar"},"button_new_group":{"message":"New group"},"button_remove_group":{"message":"Remove group.\nHold shift key to close tabs from this group"},"button_edit_group":{"message":"Rename group"},"button_import_group":{"message":"Import group"},"button_export_group":{"message":"Export group"},"button_backup":{"message":"Session"},"button_import_bak":{"message":"Import session"},"button_import_merge_bak":{"message":"Import and merge session.\nImporter will try to match current tabs with those from saved session, instead of opening a new window."},"button_export_bak":{"message":"Export session"},"button_load_bak1":{"message":"EMERGENCY if lost groupings: Load latest internal backup (autosave is made every 5 minutes)"},"button_load_bak2":{"message":"EMERGENCY if lost groupings: Load previous to latest internal backup (autosave is made every 10 minutes)"},"button_load_bak3":{"message":"EMERGENCY if lost groupings: Load oldest internal backup (autosave is made every 30 minutes)"},"button_folders":{"message":"Folders"},"button_new_folder":{"message":"New folder"},"button_remove_folder":{"message":"Remove selected folder/s"},"button_edit_folder":{"message":"Rename folder"},"menu_expand_all":{"message":"Expand all trees"},"menu_collapse_all":{"message":"Collapse all trees"},"menu_expand_tree":{"message":"Expand tree"},"menu_collapse_tree":{"message":"Collapse tree"},"menu_new_tab":{"message":"New tab"},"menu_new_pin":{"message":"New pinned tab"},"menu_duplicate_tab":{"message":"Duplicate"},"menu_detach_tab":{"message":"Detach"},"menu_reload_tab":{"message":"Reload"},"menu_pin_tab":{"message":"Pin"},"menu_mute_tab":{"message":"Mute"},"menu_mute_tree":{"message":"Mute tree"},"menu_unmute_tree":{"message":"Unmute tree"},"menu_unmute_tab":{"message":"Unmute"},"menu_mute_other":{"message":"Mute other"},"menu_unmute_other":{"message":"Unmute other"},"menu_unpin_tab":{"message":"Unpin"},"menu_close_tree":{"message":"Close tree"},"menu_close":{"message":"Close"},"menu_close_other":{"message":"Close other"},"menu_undo_close_tab":{"message":"Undo close"},"menu_treetabs_settings":{"message":"Settings"},"menu_unload":{"message":"Unload"},"menu_bookmark_tree":{"message":"Bookmark"},"menu_new_folder":{"message":"New folder"},"menu_rename_folder":{"message":"Rename folder"},"menu_delete_folder":{"message":"Delete"},"menu_new_group":{"message":"New group"},"menu_rename_group":{"message":"Rename"},"menu_delete_group":{"message":"Delete"},"menu_delete_group_tabs_close":{"message":"Delete with tabs"},"menu_groups_unload":{"message":"Unload"},"menu_bookmark_group":{"message":"Bookmark"},"menu_groups_hibernate":{"message":"Hibernate"},"menu_group_tabs_close":{"message":"Close tabs"},"status_bar_rearranging_tabs":{"message":"Rearranging tabs and folders"},"status_bar_rearranging_finished":{"message":"Rearranging: done."},"status_bar_loaded_tree_structure":{"message":"Loaded Tree structure..."},"status_bar_finding_ref_tabs":{"message":"Finding reference tabs..."},"status_bar_finding_other_windows":{"message":"Finding other windows to add tabs..."},"status_bar_all_done":{"message":"All done."},"status_bar_autosave":{"message":"Autosave: "},"status_bar_quick_check_recreate_structure":{"message":"Quick check and recreating structure..."},"options_vivaldi":{"message":" Vivaldi "},"opt_url_for_web_panel":{"message":"Url for the Web Panel"},"options_pinned":{"message":" Pinned tabs bar "},"options_pin_list_multi_row":{"message":"Multi row list"},"option_allow_pin_close":{"message":"Allow to close pinned tabs"},"option_pin_attention_blinking":{"message":"Blink pinned tabs that ask for attention"},"option_audio_blinking":{"message":"Blink audio indicator"},"options_tabs":{"message":" Tabs "},"options_syncro_tabbar_tabs_order":{"message":"Synchronize browser tabs order with Tree Tabs, tabs can be unresponsive for a second after drag&drop. This option is needed for correct ctrl+tab switching. You can disable this option if you don't use keyboard shortcuts."},"options_switch_with_scroll":{"message":"Switch tabs with mouse wheel"},"options_tab_group_regex":{"message":"Tab group assignments (Items matching the given pattern will be moved to the designated group. Pattern accepts regular expressions.)"},"option_tab_match":{"message":"Pattern"},"option_tab_group":{"message":"Group"},"options_orphaned_tabs_to_ungrouped":{"message":"Always place orphan tabs in the 'ungrouped' group"},"options_move_on_url_change":{"message":"Move tabs that match regexes"},"options_move_on_url_change_never":{"message":"never"},"options_move_on_url_change_from_empty":{"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 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":"whenever URL changes to a matching pattern"},"options_always_show_close":{"message":"Show close button on all tabs and folders"},"options_never_show_close":{"message":"Never show close button (option above will be ignored)"},"options_collapse_other_trees":{"message":"Automatically collapse other trees on expand"},"options_open_tree_on_hover":{"message":"Auto expand collapsed trees when dragging and holding for a second over them"},"options_promote_children":{"message":"Promote children on close, if disabled, when closing the parent of a tree structure, all tabs and folders will be closed (be careful, because undo close tab will not recover the trees structure)"},"options_promote_children_in_first_child":{"message":"Promote first child as a parent"},"options_skip_load":{"message":"Discard tree structure after browser's restart, this option is for those who don't use browser's session. Basically it disables loading database at startup."},"options_midclick_tab":{"message":"Action for middle mouse click on tab"},"options_dbclick_tab":{"message":"Action for double click on tab"},"options_action_tab_none":{"message":"nothing"},"options_action_tab_new":{"message":"open new tab"},"options_action_tab_expand_collapse":{"message":"expand/collapse tree"},"options_action_tab_close":{"message":"close tab"},"options_action_tab_reload":{"message":"reload tab"},"options_action_tab_unload":{"message":"unload tab"},"options_action_tab_activate_previous_active":{"message":"go back to previous active tab (works only on unpinned tabs)"},"options_action_tab_undo_close":{"message":"reopen last closed tab"},"options_midclick_group":{"message":"Action for middle click on empty space on the left side or below the tabs"},"options_dbclick_group":{"message":"Action for double click on empty space on the left side or below the tabs"},"options_action_group_none":{"message":"nothing"},"options_action_group_new":{"message":"open new tab"},"options_action_group_activate_previous_active":{"message":"go back to previous active tab (works only on unpinned tabs)"},"options_action_group_undo_close_tab":{"message":"reopen last closed tab"},"options_append_pinned_tab":{"message":"Place pinned tabs"},"options_append_pinned_tab_first":{"message":"as first"},"options_append_pinned_tab_after":{"message":"after opener, or active"},"options_append_pinned_tab_last":{"message":"as last"},"options_append_child_tab":{"message":"Place children tabs"},"options_append_child_tab_top":{"message":"at the top (reverse hierarchy)"},"options_append_child_tab_bottom":{"message":" at the bottom"},"options_append_child_tab_after":{"message":"after parent tab (no automatic tree)"},"options_append_orphan_tab":{"message":"Append orphan tabs"},"options_append_orphan_tab_top":{"message":"at the top of the group"},"options_append_orphan_tab_after_active":{"message":"after active tab"},"options_append_orphan_tab_bottom":{"message":"at the bottom of the group"},"options_append_orphan_tab_as_child":{"message":"treat as active's tab child"},"options_append_orphan_tab_active_parent_top":{"message":"at the same level as active tab, but on top"},"options_append_orphan_tab_active_parent_bottom":{"message":"at the same level as active tab, but on bottom"},"options_toolbar_new_tab":{"message":"Toolbar + (new tab button) should append tab"},"options_toolbar_new_tab_as_regular_orphan":{"message":"as a regular orphan tab (option above)"},"options_toolbar_new_tab_root_of_group":{"message":"at the bottom of the group"},"options_after_closing_active_tab":{"message":"After closing active tab,"},"options_after_closing_active_tab_go_up":{"message":"activate tab above"},"options_after_closing_active_tab_go_down":{"message":"activate tab below"},"options_after_closing_active_tab_go_up_seek_in_parent":{"message":"activate tab above if on the same level"},"options_after_closing_active_tab_go_down_seek_in_parent":{"message":"activate tab below if on the same level"},"options_after_closing_active_tab_go_browser":{"message":"let browser activate tab"},"options_append_child_tab_after_limit":{"message":"Once reached maximum tree depth, place tab on the same level, but"},"options_append_child_tab_after_limit_top":{"message":"at the top"},"options_append_child_tab_after_limit_after":{"message":"after parent"},"options_append_child_tab_after_limit_bottom":{"message":"at the bottom"},"options_show_counter_tabs":{"message":"Show children tabs count on tabs and folders titles"},"options_show_counter_tabs_hints":{"message":"Show children tabs count in tabs and folders hints"},"options_max_tree_depth":{"message":"Maximum tree depth: set it to -1 for unlimited branches, 0 for flat tabs placement (no trees), any number above 0 will be its maximum"},"options_max_tree_drag_drop":{"message":"Limit Drag&Drop to tree's maximum depth, so you can't drop tabs beyond maximum depth"},"options_groups":{"message":"Groups"},"options_show_counter_groups":{"message":"Show tabs count on groups"},"options_groups_toolbar_default":{"message":"Show groups toolbar in new windows"},"options_syncro_tabbar_groups_tabs_order":{"message":"Synchronize browser tabs order after drag&drop of the group tabs. Tabs will sort for a long time, if browser has a lot of tabs open. This option is needed for correct ctrl+tab switching. You can disable this option if you don't use keyboard shortcuts."},"options_hide_other_groups_tabs_firefox":{"message":"Show Firefox tabs from current group only. Requires change in about:config, find 'extensions.webextensions.tabhide.enabled' and set it to true."},"options_folders":{"message":"Folders"},"options_midclick_folder":{"message":"Action for middle mouse click on folder"},"options_dbclick_folder":{"message":"Action for double click on folder"},"options_action_folder_none":{"message":"nothing"},"options_action_folder_rename":{"message":"rename folder"},"options_action_folder_new_folder":{"message":"open new folder"},"options_action_folder_new_tab":{"message":"open new tab"},"options_action_folder_expand_collapse":{"message":"expand/collapse tree"},"options_action_folder_close":{"message":"close folder"},"options_action_folder_unload":{"message":"unload tabs in folder"},"options_global":{"message":"Global"},"options_theme":{"message":"Theme"},"options_rename_theme_button":{"message":"Rename"},"options_add_theme_button":{"message":"Add new"},"options_remove_theme_button":{"message":"Remove"},"options_import_theme_button":{"message":"Import"},"options_export_theme_button":{"message":"Export"},"options_share_theme_link":{"message":"Get more!"},"options_toolbar":{"message":" Toolbar "},"options_available_buttons":{"message":"Drag and drop buttons to arrange them, drop to the green box, buttons you don't want to use"},"options_reset_toolbar_button":{"message":"Reset toolbar"},"options_export_debug":{"message":"Export log file"},"options_print_debug":{"message":"Load log from file"},"options_toolbar_look":{"message":" Toolbar's look "},"hint_orphan_tab":{"message":"Orphan tab is a tab opened from an external source, which can be:"},"hint_ctrl_t":{"message":"ctrl+t shortcut"},"hint_from_pin":{"message":"link that opens new tab from pinned tab"},"hint_from_bookmark":{"message":"bookmark"},"hint_from_external_link":{"message":"external link"},"hint_from_popup":{"message":"popup opened as a tab (settings in browser, popup blocker or anything that redirects popups to new tabs)"},"hint_explained_new_tab_settings":{"message":"+ button in the Tree Tabs toolbar"},"hint_explained_orphan_after_active_settings":{"message":"If set to 'after active tab' and active tab is not in current group, tab will append to the root of the active group instead."},"button_background":{"message":"Toolbar buttons background"},"button_hover_background":{"message":"Toolbar buttons background, on mouse hover"},"button_on_background":{"message":"Toolbar active buttons background"},"button_icons":{"message":"Toolbar buttons icon color"},"button_icons_hover":{"message":"Toolbar buttons icon color, on mouse hover"},"button_on_icons":{"message":"Toolbar active buttons icon color"},"button_border":{"message":"Toolbar buttons border color"},"button_hover_border":{"message":"Toolbar buttons border color, on mouse hover"},"filter_box_font":{"message":"Search box, font color"},"filter_box_background":{"message":"Search box, font background color"},"filter_box_border":{"message":"Search box, border color"},"filter_clear_icon":{"message":"Clear search result x button color"},"toolbar_background":{"message":"Toolbar background color"},"toolbar_shelf_background":{"message":"Toolbar's shelf background color"},"toolbar_border_bottom":{"message":"Toolbar borders color"},"button_shelf_background":{"message":"Toolbar's shelf buttons background color"},"button_shelf_hover_background":{"message":"Toolbar's shelf buttons background color, on mouse hover"},"button_shelf_icons":{"message":"Toolbar's shelf buttons icon color"},"button_shelf_icons_hover":{"message":"Toolbar's shelf buttons icon color, on mouse hover"},"button_shelf_border":{"message":"Toolbar's shelf buttons border color"},"button_shelf_hover_border":{"message":"Toolbar's shelf buttons border color, on mouse hover"},"options_theme_tabs":{"message":" Tabs look "},"options_tabs_margin_overlap":{"message":"Tabs spacing:\nOverlap 1px, best for themes with borders"},"options_tabs_margin_0":{"message":"Tabs spacing:\nNo spacing, best for flat look"},"options_tabs_margin_1":{"message":"Tabs spacing:\nDefault, 1px between tabs"},"options_tab_list_scrollbar_width_down":{"message":"Decrease scrollbars width"},"options_tab_list_scrollbar_width_up":{"message":"Increase scrollbars width"},"options_tab_list_scrollbar_height_down":{"message":"Decrease scrollbars height"},"options_tab_list_scrollbar_height_up":{"message":"Increase scrollbars height"},"options_tabs_indentation_down":{"message":"Decrease tabs indentation"},"options_tabs_indentation_up":{"message":"Increase tabs indentation"},"options_tabs_roundness_down":{"message":"Make tabs corners more square"},"options_tabs_roundness_up":{"message":"Make tabs rounder"},"options_tabs_size_down":{"message":"Decrease tabs size"},"options_tabs_size_up":{"message":"Increase tabs size"},"options_theme_tabs_sample_text_normal":{"message":"Normal"},"options_theme_tabs_sample_text_normal_hover":{"message":"Normal, mouse hover over"},"options_theme_tabs_sample_text_normal_selected":{"message":"Normal selected"},"options_theme_tabs_sample_text_normal_selected_hover":{"message":"Normal selected, mouse hover over"},"options_theme_tabs_sample_text_active":{"message":"Active"},"options_theme_tabs_sample_text_active_hover":{"message":"Active, mouse hover over"},"options_theme_tabs_sample_text_active_selected":{"message":"Active and selected"},"options_theme_tabs_sample_text_active_selected_hover":{"message":"Active and selected, mouse hover over"},"options_theme_tabs_sample_text_discarded":{"message":"Unloaded (discarded)"},"options_theme_tabs_sample_text_discarded_hover":{"message":"Unloaded, mouse hover over"},"options_theme_tabs_sample_text_discarded_selected":{"message":"Unloaded and selected"},"options_theme_tabs_sample_text_discarded_selected_hover":{"message":"Unloaded and selected, mouse hover over"},"options_theme_tabs_sample_text_search_result":{"message":"Search result"},"options_theme_tabs_sample_text_search_result_hover":{"message":"Search result, mouse hover over"},"options_theme_tabs_sample_text_search_result_active":{"message":"Search result active"},"options_theme_tabs_sample_text_search_result_active_hover":{"message":"Search result active, mouse hover over"},"options_theme_tabs_sample_text_search_result_selected":{"message":"Search result selected"},"options_theme_tabs_sample_text_search_result_selected_hover":{"message":"Search result selected, mouse hover over"},"options_theme_tabs_sample_text_search_result_selected_active":{"message":"Search result selected, active"},"options_theme_tabs_sample_text_search_result_selected_active_hover":{"message":"Search result selected, active, mouse hover over"},"options_theme_tabs_sample_text_search_result_highlighted":{"message":"Search result highlighted"},"options_theme_tabs_sample_text_search_result_highlighted_hover":{"message":"Search result highlighted, mouse hover over"},"options_theme_tabs_sample_text_search_result_highlighted_active":{"message":"Search result highlighted, active"},"options_theme_tabs_sample_text_search_result_highlighted_active_hover":{"message":"Search result highlighted, active, mouse hover over"},"options_theme_tabs_sample_text_search_result_highlighted_selected":{"message":"Search result highlighted, selected"},"options_theme_tabs_sample_text_search_result_highlighted_selected_hover":{"message":"Search result highlighted, selected, mouse hover over"},"options_theme_tabs_sample_text_search_result_highlighted_selected_active":{"message":"Search result highlighted, selected, active"},"options_theme_tabs_sample_text_search_result_highlighted_selected_active_hover":{"message":"Search result highlighted, selected, active, mouse hover over"},"attention_background":{"message":"Tabs blinking for attention, background color"},"attention_border":{"message":"Tabs blinking for attention, border color"},"pin_list_border_bottom":{"message":"Pinned tabs list, border at the bottom color"},"pin_list_background":{"message":"Pinned tabs list, background color"},"folder_icon_open":{"message":"Open folder icon"},"folder_icon_closed":{"message":"Empty or closed folder icon"},"folder_icon_hover":{"message":"Folder icon on mouse hover"},"expand_open_background":{"message":"Open tree indicator"},"expand_closed_background":{"message":"Closed tree indicator"},"expand_hover_background":{"message":"Tree indicator on mouse hover"},"group_list_button_hover_background":{"message":"Group on mouse hover"},"group_list_borders":{"message":"Group list border"},"group_list_default_font_color":{"message":"Group list default font color"},"group_list_background":{"message":"Group list background color"},"tab_list_background":{"message":"Tabs background color"},"drag_indicator":{"message":"Drag&Drop indicator"},"close_x":{"message":"x inside the close button"},"close_hover_x":{"message":"x inside the close button, on mouse hover"},"close_hover_border":{"message":"close button border, on mouse hover"},"close_hover_background":{"message":"close button box color, on mouse hover"},"scrollbar_thumb":{"message":"Scrollbar thumb"},"scrollbar_thumb_hover":{"message":"Scrollbar thumb, on mouse hover"},"scrollbar_track":{"message":"Scrollbar track"},"options_example_menu_item":{"message":"menu item"},"options_menu":{"message":" Menu "},"tabs_menu_hover_border":{"message":"menu item border, on mouse hover"},"tabs_menu_hover_background":{"message":"menu item background, on mouse hover"},"tabs_menu_separator":{"message":"menu separator"},"tabs_menu_font":{"message":"menu text color"},"tabs_menu_border":{"message":"menu border"},"tabs_menu_background":{"message":"menu background"},"options_there_is_a_theme_with_this_name":{"message":"Theme with this name already exists, try a new name"},"options_theme_name_cannot_be_empty":{"message":"Theme name cannot be empty, enter some name"},"options_no_theme_to_export":{"message":"No theme to export, maybe add a new one :)"},"options_loaded_theme_older_version":{"message":"Looks like loaded theme was saved in older version of the extension, some colors or options might be missing"},"options_loaded_theme_newer_version":{"message":"Looks like loaded theme was saved in a newer version of the extension, can't load!"},"options_vivaldi_copied_url":{"message":"Web Panel Url has been copied to clipboard, add a new Web Panel and paste url."},"options_copied_wallet_address":{"message":"Wallet address has been copied to clipboard"},"options_clear_data":{"message":"Sidebar is not loading? Reset! ATTENTION! All options and saved Themes will be lost!"},"options_development":{"message":"Development"},"options_debug":{"message":"Debug"},"group_edit_button_cancel":{"message":"Cancel"},"group_edit_button_confirm":{"message":"Ok"},"folder_edit_button_cancel":{"message":"Cancel"},"folder_edit_button_confirm":{"message":"Ok"},"manager_window_button_label_import_group":{"message":"Import group"},"manager_window_button_label_import_session":{"message":"Import session"},"manager_window_button_label_save_current_session":{"message":"Save current session"},"caption_ungrouped_group":{"message":"Ungrouped"},"caption_noname_group":{"message":"untitled"},"caption_clear_filter":{"message":"Clear search results"},"caption_loading":{"message":"Loading..."},"caption_searchbox":{"message":" Search tabs..."},"manager_window_header_title":{"message":"Manager"},"menu_manager_window":{"message":"Open manager"},"button_manager_window":{"message":"Open manager window"},"manager_window_groups_button":{"message":"Hibernated groups"},"manager_window_sessions_button":{"message":"Saved sessions"},"manager_window_autosave_button":{"message":"Auto saved sessions"},"manager_window_button_label_hibernate_group":{"message":"Hibernate current group"},"manager_window_autosessions_maximum_saves_label":{"message":"Number of autosaves to keep:"},"manager_window_autosessions_save_timer_label":{"message":"Autosave every (minutes):"},"manager_window_delete_icon":{"message":"Remove"},"manager_window_savetofile_icon":{"message":"Save to file"},"manager_window_merge_icon":{"message":"Load and merge"},"manager_window_load_icon":{"message":"Load"},"options_Remove_button":{"message":"Remove"},"add_tab_group_regex":{"message":"Add"},"menu_unload_tree":{"message":"Unload tree"}}
\ No newline at end of file
diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json
index 1e8c132..cb71bfa 100644
--- a/_locales/ru/messages.json
+++ b/_locales/ru/messages.json
@@ -1,444 +1,1437 @@
{
- "button_bookmarks": {
- "message": "Закладки"
- },
- "button_unload": {
- "message": "Выгрузить все вкладки"
- },
- "button_discard": {
- "message": "Выгрузить все вкладки"
- },
- "button_downloads": {
- "message": "Загрузки"
- },
- "button_extensions": {
- "message": "Расширения"
- },
- "button_filter_type": {
- "message": "Поиск заголовков или URL-адресов"
- },
- "button_history": {
- "message": "История"
- },
- "button_move": {
- "message": "Отсоединить текущую вкладку"
- },
- "button_detach": {
- "message": "Отсоединить текущую вкладку"
- },
- "button_new": {
- "message": "ЛКМ - открыть новую вкладку \nСКМ - дублировать активную вкладку \nПКМ - прокрутка списка к активной вкладке"
- },
- "button_options": {
- "message": "Настройки Tree Tabs"
- },
- "button_pin": {
- "message": "Закрепить / Открепить текущую вкладку"
- },
- "button_search": {
- "message": "Поиск вкладок"
- },
- "button_settings": {
- "message": "Настройки браузера"
- },
- "button_tools": {
- "message": "Дополнительные инструменты"
- },
- "button_undo": {
- "message": "Открыть последнюю закрытую вкладку"
- },
- "caption_clear_filter": {
- "message": "Очистить результаты поиска"
- },
- "caption_loading": {
- "message": "Загрузка…"
- },
- "caption_searchbox": {
- "message": " Поиск вкладок…"
- },
- "extDesc": {
- "message": "Управляйте своими вкладками с боковой панели!"
- },
- "extensionName": {
- "message": "Tree Tabs"
- },
- "filter_search_go_next": {
- "message": "Следующий результат поиска"
- },
- "filter_search_go_prev": {
- "message": "Предыдущий результат поиска"
- },
- "option_allow_pin_close": {
- "message": "закрывать закреплённые вкладки из контекстного меню"
- },
- "options_add_theme_button": {
- "message": "Новая"
- },
- "options_always_show_close": {
- "message": "показывать кнопку закрытия на вкладках"
- },
- "options_append_child_tab": {
- "message": "добавлять новые дочерние вкладки"
- },
- "options_append_child_tab_after_limit": {
- "message": "при достижении максимальной глубины дерева, установить вкладку на том же уровне, но"
- },
- "options_append_child_tab_after_limit_after": {
- "message": "после родительской"
- },
- "options_append_child_tab_after_limit_bottom": {
- "message": "ниже предыдущей"
- },
- "options_append_child_tab_after_limit_top": {
- "message": "выше предыдущей"
- },
- "options_append_child_tab_bottom": {
- "message": "ниже предыдущих"
- },
- "options_append_child_tab_top": {
- "message": "выше предыдущих (обратная иерархия)"
- },
- "options_append_orphan_tab": {
- "message": "открывать недавно закрытые вкладки"
- },
- "options_append_orphan_tab_after_active": {
- "message": "после активной вкладки"
- },
- "options_append_orphan_tab_as_child": {
- "message": "как дочерние для активной вкладки"
- },
- "options_after_closing_active_tab": {
- "message": "После закрытия активной вкладки"
- },
- "options_after_closing_active_tab_go_up": {
- "message": "активировать вкладку выше"
- },
- "options_after_closing_active_tab_go_down": {
- "message": "активировать вкладку ниже"
- },
- "options_after_closing_active_tab_go_browser": {
- "message": "активация вкладок согласно настройкам браузера"
- },
- "options_append_orphan_tab_bottom": {
- "message": "в конце списка"
- },
- "options_append_orphan_tab_top": {
- "message": "в начале списка"
- },
- "options_collapse_other_trees": {
- "message": "автоматически сворачивать другие деревья при раскрывании дерева"
- },
+ "extensionName": {
+ "message": "Tree Tabs"
+ },
+ "extDesc": {
+ "message": "Управляйте своими вкладками с боковой панели!"
+ },
+ "OpenSidebar": {
+ "message": "Открыть Tree Tabs"
+ },
+
+
+ "button_new": {
+ "message": "ЛКМ - создать новую вкладку \nСКМ - дублировать активную вкладку \nПКМ - прокрутка списка к активной вкладке"
+ },
+ "button_pin": {
+ "message": "Закрепить / Открепить текущую вкладку"
+ },
+ "button_undo": {
+ "message": "Открыть последнюю закрытую вкладку"
+ },
+ "button_reboot": {
+ "message": "Перезагрузить Tree Tabs. Попробуйте это в случае, если древовидная структура вкладок потеряна после перезапуска."
+ },
+ "button_detach": {
+ "message": "Отсоединить текущую вкладку"
+ },
+ "button_move": {
+ "message": "Отсоединить текущую вкладку"
+ },
+ "button_search": {
+ "message": "Поиск вкладок"
+ },
+ "button_tools": {
+ "message": "Дополнительные инструменты"
+ },
+ "button_groups": {
+ "message": "Группы"
+ },
+ "filter_search_go_prev": {
+ "message": "Предыдущий результат поиска"
+ },
+ "filter_search_go_next": {
+ "message": "Следующий результат поиска"
+ },
+ "button_bookmarks": {
+ "message": "Несортированные закладки"
+ },
+ "button_downloads": {
+ "message": "Загрузки"
+ },
+ "button_history": {
+ "message": "История"
+ },
+ "button_settings": {
+ "message": "Настройки браузера"
+ },
+ "button_options": {
+ "message": "Настройки Tree Tabs"
+ },
+ "button_extensions": {
+ "message": "Расширения"
+ },
+ "button_unload": {
+ "message": "Выгрузить все вкладки"
+ },
+ "button_discard": {
+ "message": "Выгрузить все вкладки"
+ },
+ "button_filter_type": {
+ "message": "Поиск заголовков или URL-адресов"
+ },
+
+
+
+
+
+ "button_groups_toolbar_hide": {
+ "message": "Скрыть /показать панель групп"
+ },
+ "button_new_group": {
+ "message": "Новая группа"
+ },
+ "button_remove_group": {
+ "message": "Удалить группу.\nС зажатой кнопкой Shift закроются все вкладки из этой группы"
+ },
+ "button_edit_group": {
+ "message": "Переименовать группу"
+ },
+
+ "button_import_group": {
+ "message": "Импорт групп"
+ },
+ "button_export_group": {
+ "message": "Экспорт групп"
+ },
+
+ "button_backup": {
+ "message": "Сессия"
+ },
+ "button_import_bak": {
+ "message": "Импорт сессии"
+ },
+ "button_import_merge_bak": {
+ "message": "Импорт и объединение сессии.\nВместо открытия нового окна импортер попытается сопоставить текущие вкладки с вкладками из сохраненного сеанса."
+ },
+ "button_export_bak": {
+ "message": "Экспорт сессии"
+ },
+ "button_load_bak1": {
+ "message": "ПОМОЩЬ при потере групп: Загрузить последнюю внутреннюю резервную копию (автосохранение выполняется каждые 5 минут)"
+ },
+ "button_load_bak2": {
+ "message": "ПОМОЩЬ при потере групп: Загрузить предыдущую внутреннюю резервную копию (автосохранение выполняется каждые 10 минут)"
+ },
+ "button_load_bak3": {
+ "message": "ПОМОЩЬ при потере групп: Загрузить самую раннюю внутреннюю резервную копию (автосохранение выполняется каждые 30 минут)"
+ },
+
+
+ "button_folders": {
+ "message": "Папки"
+ },
+ "button_new_folder": {
+ "message": "Новая папка"
+ },
+ "button_remove_folder": {
+ "message": "Удалить выделенные папки"
+ },
+ "button_edit_folder": {
+ "message": "Переименовать папку"
+ },
+
+
+
+
+
+
+ "menu_expand_all": {
+ "message": "Раскрыть все деревья"
+ },
+ "menu_collapse_all": {
+ "message": "Свернуть все деревья"
+ },
+ "menu_expand_tree": {
+ "message": "Раскрыть дерево"
+ },
+ "menu_collapse_tree": {
+ "message": "Свернуть дерево"
+ },
+ "menu_new_tab": {
+ "message": "Новая вкладка"
+ },
+ "menu_new_pin": {
+ "message": "Новая закреплённая вкладка"
+ },
+ "menu_duplicate_tab": {
+ "message": "Дублировать вкладку"
+ },
+ "menu_detach_tab": {
+ "message": "Отсоединить вкладку"
+ },
+ "menu_reload_tab": {
+ "message": "Обновить вкладку"
+ },
+ "menu_pin_tab": {
+ "message": "Закрепить вкладку"
+ },
+ "menu_mute_tab": {
+ "message": "Выключить звук на вкладке"
+ },
+ "menu_mute_tree": {
+ "message": "Выключить звук на вкладках дерева"
+ },
+ "menu_unmute_tree": {
+ "message": "Включить звук на вкладках дерева"
+ },
+ "menu_unmute_tab": {
+ "message": "Включить звук на вкладке"
+ },
+ "menu_mute_other": {
+ "message": "Выключить звук (на других)"
+ },
+ "menu_unmute_other": {
+ "message": "Включить звук (на других)"
+ },
+ "menu_unpin_tab": {
+ "message": "Открепить вкладку"
+ },
+ "menu_close_tree": {
+ "message": "Закрыть дерево"
+ },
+ "menu_close": {
+ "message": "Закрыть вкладку"
+ },
+ "menu_close_other": {
+ "message": "Закрыть другие вкладки"
+ },
+ "menu_undo_close_tab": {
+ "message": "Отменить закрытие"
+ },
+ "menu_treetabs_settings": {
+ "message": "Настройки Tree Tabs"
+ },
+ "menu_unload": {
+ "message": "Выгрузить вкладку"
+ },
+
+ "menu_bookmark_tree": {
+ "message": "Добавить закладку"
+ },
+
+
+
+ "menu_new_folder": {
+ "message": "Новая папка"
+ },
+ "menu_rename_folder": {
+ "message": "Переименовать папку"
+ },
+ "menu_delete_folder": {
+ "message": "Удалить папку"
+ },
+
+ "menu_new_group": {
+ "message": "Новая группа"
+ },
+ "menu_rename_group": {
+ "message": "Переименовать группу"
+ },
+ "menu_delete_group": {
+ "message": "Удалить группу"
+ },
+ "menu_delete_group_tabs_close": {
+ "message": "Удалить группу с вкладками"
+ },
+
+ "menu_groups_unload": {
+ "message": "Выгрузить группу"
+ },
+
+ "menu_bookmark_group": {
+ "message": "Добавить закладку"
+ },
+ "menu_groups_hibernate": {
+ "message": "Спящий режим"
+ },
+ "menu_group_tabs_close": {
+ "message": "Закрыть вкладки"
+ },
+
+
+
+
+
+
+
+ "options_vivaldi": {
+ "message": " Vivaldi "
+ },
+ "opt_url_for_web_panel": {
+ "message": "Url-адрес для веб-панели"
+ },
+ "options_pinned": {
+ "message": " Панель закреплённых вкладок "
+ },
+ "options_pin_list_multi_row": {
+ "message": "Список закреплённых вкладок в несколько строк"
+ },
+ "option_allow_pin_close": {
+ "message": "Закрывать закреплённые вкладки из контекстного меню"
+ },
+ "options_tabs": {
+ "message": " Вкладки "
+ },
+ "options_syncro_tabbar_tabs_order": {
+ "message": "Синхронизировать порядок вкладок браузера с Tree Tabs после их перетаскивания. Вкладки будут долго сортироваться, если в браузере открыто много вкладок. Эта опция необходима для правильного переключения вкладок с помощью клавиш [Ctrl + Tab]. Вы можете отключить эту опцию, если не используете сочетания клавиш."
+ },
+ "options_switch_with_scroll": {
+ "message": "Переключение вкладок колёсиком мыши"
+ },
+
+ "options_tab_group_regex": {
+ "message": "Распределение вкладок (элементы, соответствующие данному шаблону, будут перемещены в назначенную группу. Шаблон допускает регулярные выражения.)"
+ },
+ "option_tab_match": {
+ "message": "Шаблон"
+ },
+ "option_tab_group": {
+ "message": "Группа"
+ },
+ "options_orphaned_tabs_to_ungrouped": {
+ "message": "Всегда размещать вкладки-сироты в группе «Разгруппированные»"
+ },
+ "options_move_on_url_change": {
+ "message": "Перемещение вкладок, соответствующих регулярным выражениям"
+ },
+ "options_move_on_url_change_never": {
+ "message": "никогда"
+ },
+ "options_move_on_url_change_from_empty": {
+ "message": "при изменении URL-адреса на вкладке «Домашняя» (только вкладки, созданные с помощью сочетания клавиш [Ctrl+T]"
+ },
+ "options_move_on_url_change_from_empty_b": {
+ "message": "при изменении URL-адреса на любой вкладке «Домашняя»"
+ },
+ "options_move_on_url_change_all_new": {
+ "message": "при создании вкладки с соответствующим URL-адресом"
+ },
+ "options_move_on_url_change_always": {
+ "message": "при изменении URL-адреса на соответствующий шаблон"
+ },
+
+ "options_always_show_close": {
+ "message": "Показывать кнопку закрытия на вкладках"
+ },
+ "options_never_show_close": {
+ "message": "Не показывать кнопку закрытия (опция выше будет проигнорирована)"
+ },
+ "options_collapse_other_trees": {
+ "message": "Автоматически сворачивать другие деревья при раскрывании дерева"
+ },
+ "options_open_tree_on_hover": {
+ "message": "Автоматически раскрывать свёрнутые деревья при перетаскивании вкладки с удерживанием курсора над ними"
+ },
+ "options_promote_children": {
+ "message": "Оставлять дочерние вкладки при закрытии родительской. (Если отключено, то при закрытии родительской вкладки все дочерние вкладки дерева будут закрыты. Будьте осторожны, так как отмена закрытия вкладки не восстановит структуру дерева)"
+ },
+
+ "options_promote_children_in_first_child": {
+ "message": "Устанавливать первую дочернюю вкладку как родительскую"
+ },
+
+ "options_skip_load": {
+ "message": "Отменить древовидную структуру после перезапуска браузера. Это предназначено для тех, кто не использует сохранение сессии (опция отключает загрузку базы данных при запуске браузера)"
+ },
+
+
+ "options_midclick_tab": {
+ "message": "Действие для средней кнопки мыши на вкладке"
+ },
+ "options_dbclick_tab": {
+ "message": "Действие для двойного клика на вкладке"
+ },
+
+ "options_action_tab_none": {
+ "message": "ничего"
+ },
+ "options_action_tab_new": {
+ "message": "открыть новую вкладку"
+ },
+ "options_action_tab_expand_collapse": {
+ "message": "раскрыть / свернуть дерево"
+ },
+ "options_action_tab_close": {
+ "message": "закрыть вкладку"
+ },
+ "options_action_tab_reload": {
+ "message": "обновить вкладку"
+ },
+ "options_action_tab_unload": {
+ "message": "выгрузить вкладку"
+ },
+ "options_action_tab_activate_previous_active": {
+ "message": "вернуться к предыдущей активной вкладке (работает только на незакрепленных вкладках)"
+ },
+ "options_action_tab_undo_close": {
+ "message": "открыть последнюю закрытую вкладку"
+ },
+
+
+
+
+ "options_midclick_group": {
+ "message": "Действие для средней кнопки мыши на пустом месте слева или под вкладками"
+ },
+ "options_dbclick_group": {
+ "message": "Действие для двойного клика на пустом месте слева или под вкладками"
+ },
+ "options_action_group_none": {
+ "message": "ничего"
+ },
+ "options_action_group_new": {
+ "message": "открыть новую вкладку"
+ },
+ "options_action_group_activate_previous_active": {
+ "message": "вернуться к предыдущей активной вкладке (работает только на незакрепленных вкладках)"
+ },
+ "options_action_group_undo_close_tab": {
+ "message": "открыть последнюю закрытую вкладку"
+ },
+
+
+
+
+ "options_append_child_tab": {
+ "message": "Расположение дочерних вкладок"
+ },
+ "options_append_child_tab_top": {
+ "message": "выше предыдущих (обратная иерархия)"
+ },
+ "options_append_child_tab_bottom": {
+ "message": "ниже предыдущих"
+ },
+ "options_append_child_tab_after": {
+ "message": "после родительской вкладки"
+ },
+
+ "options_append_orphan_tab": {
+ "message": "Открывать вкладку-сироту"
+ },
+ "options_append_orphan_tab_top": {
+ "message": "в верхней части группы"
+ },
+ "options_append_orphan_tab_after_active": {
+ "message": "после активной вкладки"
+ },
+ "options_append_orphan_tab_bottom": {
+ "message": "в нижней части группы"
+ },
+ "options_append_orphan_tab_as_child": {
+ "message": "как активную дочернюю вкладку"
+ },
+
+ "options_toolbar_new_tab": {
+ "message": "Кнопка [+] на панели интрументов («Создать вкладку») добавляет новую вкладку"
+ },
+ "options_toolbar_new_tab_as_regular_orphan": {
+ "message": "как вкладку-сироту (опция выше)"
+ },
+ "options_toolbar_new_tab_root_of_group": {
+ "message": "в нижнюю часть группы"
+ },
+
+
+
+ "options_after_closing_active_tab": {
+ "message": "После закрытия активной вкладки"
+ },
+ "options_after_closing_active_tab_go_up": {
+ "message": "перейти к вкладке выше"
+ },
+ "options_after_closing_active_tab_go_down": {
+ "message": "перейти к вкладке ниже"
+ },
+ "options_after_closing_active_tab_go_up_seek_in_parent": {
+ "message": "перейти к вкладке выше, если она на том же уровне"
+ },
+ "options_after_closing_active_tab_go_down_seek_in_parent": {
+ "message": "перейти к вкладке ниже, если она на том же уровне"
+ },
+ "options_after_closing_active_tab_go_browser": {
+ "message": "активация вкладок согласно настройкам браузера"
+ },
+
+ "options_append_child_tab_after_limit": {
+ "message": "При достижении максимальной глубины дерева, установить вкладку на том же уровне, но"
+ },
+ "options_append_child_tab_after_limit_top": {
+ "message": "выше предыдущей"
+ },
+ "options_append_child_tab_after_limit_after": {
+ "message": "просле родительской"
+ },
+ "options_append_child_tab_after_limit_bottom": {
+ "message": "ниже предыдущей"
+ },
+ "options_show_counter_tabs": {
+ "message": "Показывать количество дочерних вкладок в заголовках вкладок и папок"
+ },
+ "options_show_counter_tabs_hints": {
+ "message": "Показывать количество дочерних вкладок в подсказках вкладок и папок"
+ },
+
+ "options_max_tree_depth": {
+ "message": "Максимальная глубина дерева (-1 - неограниченное количество ветвей; 0 - отключить древовидную структуру вкладок)"
+ },
+ "options_max_tree_drag_drop": {
+ "message": "Ограничение перетаскивания вкладок до максимальной глубины дерева"
+ },
+ "options_max_tree_drag_drop_folders": {
+ "message": "Ограничение перетаскивания папок до максимальной глубины дерева"
+ },
+
+
+
+ "options_groups": {
+ "message": "Группы"
+ },
+
+ "options_show_counter_groups": {
+ "message": "Показывать количество вкладок в группах"
+ },
+
+ "options_groups_toolbar_default": {
+ "message": "Показывать панель инструментов групп в новых окнах"
+ },
+ "options_syncro_tabbar_groups_tabs_order": {
+ "message": "Синхронизировать порядок вкладок браузера с Tree Tabs после перетаскивания группы вкладок. Вкладки будут долго сортироваться, если в браузере открыто много вкладок. Эта опция необходима для правильного переключения вкладок с помощью клавиш [Ctrl + Tab]. Вы можете отключить эту опцию, если не используете сочетания клавиш."
+ },
+
+ "options_hide_other_groups_tabs_firefox": {
+ "message": "Показывать вкладки Firefox только из текущей группы. Требуется найти в about:config пункт 'extensions.webextensions.tabhide.enabled' и установить его в 'true'."
+ },
+
+
+
+
+ "options_folders": {
+ "message": "Папки"
+ },
+
+
+ "options_midclick_folder": {
+ "message": "Действие для средней кнопки мыши на папке"
+ },
+ "options_dbclick_folder": {
+ "message": "Действие для двойного клика на папке"
+ },
+
+ "options_action_folder_none": {
+ "message": "ничего"
+ },
+ "options_action_folder_rename": {
+ "message": "переименовать папку"
+ },
+ "options_action_folder_new_folder": {
+ "message": "создать новую папку"
+ },
+ "options_action_folder_new_tab": {
+ "message": "создать новую вкладку"
+ },
+ "options_action_folder_expand_collapse": {
+ "message": "раскрыть / свернуть дерево"
+ },
+ "options_action_folder_close": {
+ "message": "закрыть папку"
+ },
+ "options_action_folder_unload": {
+ "message": "выгрузить вкладки в папке"
+ },
+
+
+
+
+
+
+
+
+
+
+ "options_global": {
+ "message": "Основные"
+ },
+
+
+
+ "options_theme": {
+ "message": "Тема"
+ },
+
+
+
+ "options_rename_theme_button": {
+ "message": "Переименовать"
+ },
+ "options_add_theme_button": {
+ "message": "Добавить"
+ },
+ "options_remove_theme_button": {
+ "message": "Удалить"
+ },
+ "options_import_theme_button": {
+ "message": "Импорт"
+ },
+ "options_export_theme_button": {
+ "message": "Экспорт"
+ },
+ "options_share_theme_link": {
+ "message": "Ещё темы!"
+ },
+
+
+
+
+
+
+
+ "options_toolbar": {
+ "message": " Панель инструментов "
+ },
+ "options_available_buttons": {
+ "message": "Настраивайте панель инструментов перетаскиванием элементов. Чтобы скрыть элемент, переместите его на зелёное поле."
+ },
+
+ "options_reset_toolbar_button": {
+ "message": "Сброс"
+ },
+
+ "options_export_debug": {
+ "message": "Экспорт журнала"
+ },
+ "options_print_debug": {
+ "message": "Загрузить журнал"
+ },
+
+
+ "options_toolbar_look": {
+ "message": " Внешний вид панели инструментов "
+ },
+
+
+ "hint_orphan_tab": {
+ "message": "Вкладка-сирота - это вкладка, открытая из внешнего источника следующими способами:"
+ },
+ "hint_ctrl_t": {
+ "message": "комбинацией [Ctrl+T]"
+ },
+ "hint_from_pin": {
+ "message": "ссылкой из закрепленной вкладки"
+ },
+ "hint_from_bookmark": {
+ "message": "из закладок"
+ },
+ "hint_from_external_link": {
+ "message": "по внешней ссылке"
+ },
+ "hint_from_popup": {
+ "message": "если всплывающее окно открывается как вкладка (настройки в браузере, блокировщик всплывающих окон и подобное)"
+ },
+ "hint_explained_new_tab_settings": {
+ "message": "Кнопка [+] в панели инструментов Tree Tabs помещает новые вкладки в корень активной группы, если не установлено иначе."
+ },
+ "hint_explained_orphan_after_active_settings": {
+ "message": "Если для опции «Открывать вкладки-сироты» установлено значение «после активной вкладки», а активная вкладка не находится в активной группе, вкладка добавится к корню активной группы. Но только если боковая панель открыта."
+ },
+
+
+
+ "button_background": {
+ "message": "Цвет кнопок панели инструментов"
+ },
+ "button_hover_background": {
+ "message": "Цвет кнопок панели инструментов при наведении курсора"
+ },
+ "button_on_background": {
+ "message": "Цвет кнопок панели инструментов при нажатии на них"
+ },
+
+
+ "button_icons": {
+ "message": "Цвет иконок кнопок панели инструментов"
+ },
+ "button_icons_hover": {
+ "message": "Цвет иконок кнопок панели инструментов при наведении курсора"
+ },
+ "button_on_icons": {
+ "message": "Цвет иконок кнопок панели инструментов при нажатии на них"
+ },
+ "button_border": {
+ "message": "Цвет рамки кнопок панели инструментов"
+ },
+ "button_hover_border": {
+ "message": "Цвет рамки кнопок панели инструментов при наведении курсора"
+ },
+
+
+ "filter_box_font": {
+ "message": "Цвет шрифта в окне поиска"
+ },
+ "filter_box_background": {
+ "message": "Цвет фона окна поиска"
+ },
+ "filter_box_border": {
+ "message": "Цвет рамки окна поиска"
+ },
+ "filter_clear_icon": {
+ "message": "Цвет кнопки удаления результатов поиска"
+ },
+
+
+ "toolbar_background": {
+ "message": "Цвет панели инструментов"
+ },
+ "toolbar_shelf_background": {
+ "message": "Цвет подложки панели инструментов"
+ },
+ "toolbar_border_bottom": {
+ "message": "Цвет рамки панели инструментов"
+ },
+
+
+
+ "button_shelf_background": {
+ "message": "Цвет кнопок подложки панели инструментов"
+ },
+ "button_shelf_hover_background": {
+ "message": "Цвет кнопок подложки панели инструментов при наведении курсора"
+ },
+ "button_shelf_icons": {
+ "message": "Цвет иконок кнопок подложки панели инструментов"
+ },
+ "button_shelf_icons_hover": {
+ "message": "Цвет иконок кнопок подложки панели инструментов при наведении курсора"
+ },
+ "button_shelf_border": {
+ "message": "Цвет рамки кнопок подложки панели инструментов"
+ },
+ "button_shelf_hover_border": {
+ "message": "Цвет рамки кнопок подложки панели инструментов при наведении курсора"
+ },
+
+
+
+
+
+
+
+
+
+ "options_theme_tabs": {
+ "message": " Внешний вид вкладок "
+ },
+
+
+
+ "options_tabs_margin_overlap": {
+ "message": "Интервал между вкладками:\nПерекрытие в 1px, лучше всего подходит для тем с рамками"
+ },
+ "options_tabs_margin_0": {
+ "message": "Интервал между вкладками:\nБез интервала, лучше всего подходит для плоского внешнего вида"
+ },
+ "options_tabs_margin_1": {
+ "message": "Интервал между вкладками:\nЗначение по умолчанию: 1px между вкладками"
+ },
+
+
+
+
+ "options_tab_list_scrollbar_width_down": {
+ "message": "Уменьшить ширину полосы прокрутки"
+ },
+ "options_tab_list_scrollbar_width_up": {
+ "message": "Увеличить ширину полосы прокрутки"
+ },
+ "options_tab_list_scrollbar_height_down": {
+ "message": "Уменьшить высоту полосы прокрутки"
+ },
+ "options_tab_list_scrollbar_height_up": {
+ "message": "Увеличить высоту полосы прокрутки"
+ },
+
+
+
+ "options_tabs_indentation_down": {
+ "message": "Уменьшить отступ вкладок"
+ },
+ "options_tabs_indentation_up": {
+ "message": "Увеличить отступ вкладок"
+ },
+
+
+ "options_tabs_roundness_down": {
+ "message": "Уменьшить скругление углов вкладок"
+ },
+ "options_tabs_roundness_up": {
+ "message": "Увеличить скругление углов вкладок"
+ },
+
+
+ "options_tabs_size_down": {
+ "message": "Уменьшить размер вкладок"
+ },
+ "options_tabs_size_up": {
+ "message": "Увеличить размер вкладок"
+ },
+
+
+
+ "options_theme_tabs_sample_text_normal": {
+ "message": "Обычная вкладка"
+ },
+ "options_theme_tabs_sample_text_normal_hover": {
+ "message": "Обычная вкладка при наведении курсора"
+ },
+ "options_theme_tabs_sample_text_normal_selected": {
+ "message": "Выделенная вкладка"
+ },
+ "options_theme_tabs_sample_text_normal_selected_hover": {
+ "message": "Выделенная вкладка при наведении курсора"
+ },
+ "options_theme_tabs_sample_text_active": {
+ "message": "Активная вкладка"
+ },
+ "options_theme_tabs_sample_text_active_hover": {
+ "message": "Активная владка при наведении курсора"
+ },
+ "options_theme_tabs_sample_text_active_selected": {
+ "message": "Активная выделенная вкладка"
+ },
+ "options_theme_tabs_sample_text_active_selected_hover": {
+ "message": "Активная выделенная вкладка при наведении курсора"
+ },
+
+ "options_theme_tabs_sample_text_discarded": {
+ "message": "Выгруженная вкладка"
+ },
+ "options_theme_tabs_sample_text_discarded_hover": {
+ "message": "Выгруженная вкладка при наведении курсора"
+ },
+ "options_theme_tabs_sample_text_discarded_selected": {
+ "message": "Выгруженная выделенная вкладка"
+ },
+ "options_theme_tabs_sample_text_discarded_selected_hover": {
+ "message": "Выгруженная выделенная вкладка при наведении курсора"
+ },
+
+ "options_theme_tabs_sample_text_search_result": {
+ "message": "Результат поиска"
+ },
+ "options_theme_tabs_sample_text_search_result_hover": {
+ "message": "Результат поиска при наведении курсора"
+ },
+ "options_theme_tabs_sample_text_search_result_active": {
+ "message": "Активный результат поиска"
+ },
+ "options_theme_tabs_sample_text_search_result_active_hover": {
+ "message": "Активный результат поиска при наведении курсора"
+ },
+
+ "options_theme_tabs_sample_text_search_result_selected": {
+ "message": "Выделенный результат поиска"
+ },
+ "options_theme_tabs_sample_text_search_result_selected_hover": {
+ "message": "Выделенный результат поиска при наведении курсора"
+ },
+ "options_theme_tabs_sample_text_search_result_selected_active": {
+ "message": "Активный выделенный результат поиска"
+ },
+ "options_theme_tabs_sample_text_search_result_selected_active_hover": {
+ "message": "Активный выделенный результат поиска при наведении курсора"
+ },
+
+
+
+ "options_theme_tabs_sample_text_search_result_highlighted": {
+ "message": "Подсвеченный результат поиска"
+ },
+ "options_theme_tabs_sample_text_search_result_highlighted_hover": {
+ "message": "Подсвеченный результат поиска при наведении курсора"
+ },
+ "options_theme_tabs_sample_text_search_result_highlighted_active": {
+ "message": "Активный подсвеченный результат поиска"
+ },
+ "options_theme_tabs_sample_text_search_result_highlighted_active_hover": {
+ "message": "Активный подсвеченный результат поиска при наведении курсора"
+ },
+
+
+ "options_theme_tabs_sample_text_search_result_highlighted_selected": {
+ "message": "Выделенный подсвеченный результат поиска"
+ },
+ "options_theme_tabs_sample_text_search_result_highlighted_selected_hover": {
+ "message": "Выделенный подсвеченный результат поиска при наведении курсора"
+ },
+ "options_theme_tabs_sample_text_search_result_highlighted_selected_active": {
+ "message": "Активный выделенный и подсвеченный результат поиска"
+ },
+ "options_theme_tabs_sample_text_search_result_highlighted_selected_active_hover": {
+ "message": "Активный выделенный и подсвеченный результат поиска при наведении курсора"
+ },
+
+
+
+
+
+
+ "attention_background": {
+ "message": "Цвет мигающих вкладок при предупреждении"
+ },
+ "attention_border": {
+ "message": "Цвет рамки мигающих вкладок при предупреждении"
+ },
+ "pin_list_border_bottom": {
+ "message": "Цвет нижней рамки списка закреплённых вкладок"
+ },
+ "pin_list_background": {
+ "message": "Цвет списка закреплённых вкладок"
+ },
+
+
+ "folder_icon_open": {
+ "message": "Цвет иконки открытой папки"
+ },
+ "folder_icon_closed": {
+ "message": "Цвет иконки пустой или закрытой папки"
+ },
+ "folder_icon_hover": {
+ "message": "Цвет иконки открытой папки при наведении курсора"
+ },
+
+
+ "expand_open_background": {
+ "message": "Цвет иконки открытого дерева"
+ },
+ "expand_closed_background": {
+ "message": "Цвет иконки закрытого дерева"
+ },
+ "expand_hover_background": {
+ "message": "Цвет иконки дерева при наведении курсора"
+ },
+
+
+ "group_list_button_hover_background": {
+ "message": "Цвет группы при наведении курсора"
+ },
+ "group_list_borders": {
+ "message": "Цвет рамки списка групп"
+ },
+ "group_list_default_font_color": {
+ "message": "Цвет шрифта группы по умолчанию"
+ },
+
+ "group_list_background": {
+ "message": "Цвет списка групп"
+ },
+ "tab_list_background": {
+ "message": "Цвет списка вкладок"
+ },
+
+
+ "drag_indicator": {
+ "message": "Цвет индикатора при перетаскивании"
+ },
+
+
+
+
+
+
+ "close_x": {
+ "message": "Цвет иконки закрытия вкладки"
+ },
+ "close_hover_x": {
+ "message": "Цвет иконки закрытия вкладки при наведении курсора"
+ },
+ "close_hover_border": {
+ "message": "Цвет рамки кнопки закрытия вкладки при наведении курсора"
+ },
+ "close_hover_background": {
+ "message": "Цвет кнопки закрытия вкладки при наведении курсора"
+ },
+
+
+
+ "scrollbar_thumb": {
+ "message": "Цвет ползунка полосы прокрутки"
+ },
+ "scrollbar_thumb_hover": {
+ "message": "Цвет ползунка полосы прокрутки при наведении курсора"
+ },
+ "scrollbar_track": {
+ "message": "Цвет полосы прокрутки"
+ },
+
+
+
+
+
+ "options_example_menu_item": {
+ "message": "пункт меню"
+ },
+ "options_menu": {
+ "message": " Меню "
+ },
+
+
+ "tabs_menu_hover_border": {
+ "message": "Цвет рамки пункта меню при наведении курсора"
+ },
+ "tabs_menu_hover_background": {
+ "message": "Цвет пункта меню при наведении курсора"
+ },
+ "tabs_menu_separator": {
+ "message": "Цвет разделителя"
+ },
+ "tabs_menu_font": {
+ "message": "Цвет шрифта пунктов меню"
+ },
+ "tabs_menu_border": {
+ "message": "Цвет рамки меню"
+ },
+ "tabs_menu_background": {
+ "message": "Цвет фона меню"
+ },
+
+
+
+
+
+
+
+
+
+
+
+ "options_there_is_a_theme_with_this_name": {
+ "message": "Тема с таким именем существует, введите новое имя"
+ },
+ "options_theme_name_cannot_be_empty": {
+ "message": "Название темы не может быть пустым, введите имя"
+ },
+ "options_no_theme_to_export": {
+ "message": "Нет темы для экспорта, может быть, добавить новую? :)"
+ },
+ "options_loaded_theme_older_version": {
+ "message": "Вероятно, загруженная тема была сохранена в старой версии расширения, некоторые цвета или параметры могут отсутствовать."
+ },
+ "options_loaded_theme_newer_version": {
+ "message": "Вероятно, загруженная тема была сохранена в новой версии расширения, не удается загрузить!"
+ },
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "options_vivaldi_copied_url": {
+ "message": "Url для веб-панели был скопирован в буфер обмена, добавьте новую веб-панель и вставьте url."
+ },
+ "options_copied_wallet_address": {
+ "message": "Адрес кошелька скопирован в буфер обмена"
+ },
+
+
+ "options_clear_data": {
+ "message": "Боковая панель не загружается? Сброс! ВНИМАНИЕ! Все настройки и сохраненные темы будут потеряны!"
+ },
+
+
+ "options_development": {
+ "message": "Разработка"
+ },
+ "options_debug": {
+ "message": "Отладка"
+ },
+
+
+
+
+
+
+
+
+
+
+
+ "group_edit_button_cancel": {
+ "message": "Отмена"
+ },
+
+ "group_edit_button_confirm": {
+ "message": "Ok"
+ },
+
+
+
+ "folder_edit_button_cancel": {
+ "message": "Отмена"
+ },
+
+ "folder_edit_button_confirm": {
+ "message": "Ok"
+ },
+
+
+ "manager_window_button_label_import_group": {
+ "message": "Импорт группы"
+ },
+
+ "manager_window_button_label_import_session": {
+ "message": "Импорт сессии"
+ },
+ "manager_window_button_label_save_current_session": {
+ "message": "Сохранить текущую сессию"
+ },
+
+
+
+
+
+
+
+ "caption_ungrouped_group": {
+ "message": "Разгруппированные"
+ },
+ "caption_noname_group": {
+ "message": "без названия"
+ },
+
+ "caption_clear_filter": {
+ "message": "Очистить результаты поиска"
+ },
+ "caption_loading": {
+ "message": "Загрузка..."
+ },
+ "caption_searchbox": {
+ "message": "Поиск вкладок..."
+ },
+
+ "manager_window_header_title": {
+ "message": "Менеджер"
+ },
+
+ "menu_manager_window": {
+ "message": "Открыть менеджер"
+ },
+
+ "button_manager_window": {
+ "message": "Открыть окно менеджера"
+ },
+
+ "manager_window_groups_button": {
+ "message": "Спящие группы"
+ },
+ "manager_window_sessions_button": {
+ "message": "Сохранённые сессии"
+ },
+ "manager_window_autosave_button": {
+ "message": "Автосохранённые сессии"
+ },
+ "manager_window_button_label_hibernate_group": {
+ "message": "Усыпить текущую группу"
+ },
+
+ "manager_window_autosessions_maximum_saves_label": {
+ "message": "Количество автосохранений:"
+ },
+
+ "manager_window_autosessions_save_timer_label": {
+ "message": "Автосохранение через (мин.):"
+ },
+
+ "manager_window_delete_icon": {
+ "message": "Удалить"
+ },
+
+ "manager_window_savetofile_icon": {
+ "message": "Сохранить в файл"
+ },
+ "manager_window_merge_icon": {
+ "message": "Загрузить и объединить"
+ },
+
+ "manager_window_load_icon": {
+ "message": "Загрузить"
+ },
+
+ "options_Remove_button": {
+ "message": "Удалить"
+ },
+
+ "add_tab_group_regex": {
+ "message": "Добавить"
+ },
+
+
+ "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": ""
+ }
+
+
+
+
+
+
+
+
+
- "options_color_button_background": {
- "message": " фон кнопки"
- },
- "options_color_button_border": {
- "message": " рамка кнопки"
- },
- "options_color_button_hover_background": {
- "message": " фон при наведении на кнопку"
- },
- "options_color_button_hover_border": {
- "message": " рамка при наведении на кнопку"
- },
- "options_color_button_icons": {
- "message": " иконка кнопки"
- },
- "options_color_close_hover_background": {
- "message": " фон при наведении на кнопку закрытия"
- },
- "options_color_close_hover_border": {
- "message": " рамка при наведении на кнопку закрытия"
- },
- "options_color_close_hover_x": {
- "message": " иконка при наведении на кнопку закрытия"
- },
- "options_color_close_x": {
- "message": " кнопка закрытия [x]"
- },
- "options_color_drag_indicator": {
- "message": " индикатор drag&drop"
- },
- "options_color_expand_closed_background": {
- "message": " фон указателя свёрнутого дерева"
- },
- "options_color_expand_closed_border": {
- "message": " рамка указателя свёрнутого дерева"
- },
- "options_color_expand_lines": {
- "message": " линии ветвей дерева"
- },
- "options_color_expand_open_background": {
- "message": " фон указателя раскрытого дерева"
- },
- "options_color_expand_open_border": {
- "message": " рамка указателя раскрытого дерева"
- },
- "options_color_filter_box_background": {
- "message": " фон окна поиска"
- },
- "options_color_filter_box_border": {
- "message": " рамка окна поиска"
- },
- "options_color_filter_box_font": {
- "message": " шрифт в окне поиска"
- },
- "options_color_filter_clear_icon": {
- "message": " кнопка очистки в окне поиска"
- },
- "options_color_pin_list_background": {
- "message": " фон списка закреплённых вкладок"
- },
- "options_color_pin_list_border_bottom": {
- "message": " разделитель списка закреплённых вкладок"
- },
- "options_color_scrollbar_thumb": {
- "message": " полоса прокрутки"
- },
- "options_color_scrollbar_thumb_hover": {
- "message": " полоса прокрутки при наведении"
- },
- "options_color_scrollbar_track": {
- "message": " фон полосы прокрутки"
- },
- "options_color_tab_background": {
- "message": " фон вкладки"
- },
- "options_color_tab_border": {
- "message": " рамка вкладки"
- },
- "options_color_tab_filtered": {
- "message": " результат поиска"
- },
- "options_color_tab_filtered_highlighted": {
- "message": " выделенный результат поиска"
- },
- "options_color_tab_filtered_selected": {
- "message": " выбранный результат поиска"
- },
- "options_color_tab_filtered_selected_active": {
- "message": " активный результат поиска"
- },
- "options_color_tab_hover_background": {
- "message": " фон при наведении на вкладку"
- },
- "options_color_tab_hover_border": {
- "message": " рамка при наведении на вкладку"
- },
- "options_color_tab_list_background": {
- "message": " фон списка вкладок"
- },
- "options_color_tab_selected_background": {
- "message": " фон активной вкладки"
- },
- "options_color_tab_selected_border": {
- "message": " рамка активной вкладки"
- },
- "options_color_tab_selected_hover_background": {
- "message": " фон при наведении на активную вкладку"
- },
- "options_color_tab_selected_hover_border": {
- "message": " рамка при наведении на активную вкладку"
- },
- "options_color_tab_title": {
- "message": " шрифт заголовка вкладки"
- },
- "options_color_tab_title_active": {
- "message": " шрифт заголовка активной вкладки"
- },
- "options_color_tab_title_discarded": {
- "message": " шрифт заголовка выгруженной вкладки"
- },
- "options_color_tabs_menu_background": {
- "message": " фон"
- },
- "options_color_tabs_menu_border": {
- "message": " рамка"
- },
- "options_color_tabs_menu_font": {
- "message": " шрифт"
- },
- "options_color_tabs_menu_hover_background": {
- "message": " фон при наведении на пункт"
- },
- "options_color_tabs_menu_hover_border": {
- "message": " рамка при наведении на пункт"
- },
- "options_color_tabs_menu_separator": {
- "message": " разделитель"
- },
- "options_color_theme_toolbar_background": {
- "message": " фон панели инструментов"
- },
- "options_color_toolbar_border_bottom": {
- "message": " рамка панели инструментов"
- },
- "options_example_menu_item": {
- "message": "пункт меню"
- },
- "options_export_theme_button": {
- "message": "Экспорт"
- },
- "options_import_theme_button": {
- "message": "Импорт"
- },
- "options_loaded_theme_newer_version": {
- "message": "Похоже, загружаемая тема была сохранена в более новой версии расширения; её невозможно загрузить!"
- },
- "options_loaded_theme_older_version": {
- "message": "Похоже, загружаемая тема была сохранена в более старой версии расширения; некоторые цвета или параметры могут отсутствовать."
- },
- "options_max_tree_depth": {
- "message": "максимальная глубина дерева (-1 - неограниченное количество ветвей; 0 - отключить древовидную структуру вкладок)"
- },
- "options_menu": {
- "message": " Контекстное меню "
- },
- "options_no_theme_to_export": {
- "message": "Нет темы для экспорта, можете добавить новую :)"
- },
- "options_open_tree_on_hover": {
- "message": "автоматически раскрывать свёрнутые деревья при перетаскивании вкладки с удерживанием курсора над ними"
- },
- "options_pin_list_multi_row": {
- "message": "список закреплённых вкладок в несколько строк"
- },
- "options_pinned": {
- "message": " Панель закреплённых вкладок "
- },
- "options_promote_children": {
- "message": "оставлять дочерние вкладки при закрытии родительской. (Если отключено, то при закрытии родительской вкладки все дочерние вкладки дерева будут закрыты. Будьте осторожны, так как отмена закрытия вкладки не восстановит структуру дерева)"
- },
- "options_remove_theme_button": {
- "message": "Удалить"
- },
- "options_rename_theme_button": {
- "message": "Переименовать"
- },
- "options_scrollbar_pin_list": {
- "message": "высота полосы прокрутки закреплённых вкладок"
- },
- "options_scrollbar_tab_list": {
- "message": "ширина полосы прокрутки списка вкладок"
- },
- "options_scrollbars": {
- "message": " Полоса прокрутки "
- },
- "options_skip_load": {
- "message": "отменить древовидную структуру после перезапуска браузера. Это предназначено для тех, кто не использует сохранение сессии (опция отключает загрузку базы данных при запуске браузера)"
- },
- "options_tabs": {
- "message": " Вкладки "
- },
- "options_tabs_size": {
- "message": "Размер вкладок"
- },
- "options_theme": {
- "message": "Тема"
- },
- "options_theme_name_cannot_be_empty": {
- "message": "Введите название темы."
- },
- "options_theme_tabs": {
- "message": " Внешний вид вкладок "
- },
- "options_theme_tabs_sample_text_active_selected": {
- "message": "Активная"
- },
- "options_theme_tabs_sample_text_discarded": {
- "message": "Выгруженная"
- },
- "options_theme_tabs_sample_text_normal": {
- "message": "Обычная"
- },
- "options_theme_tabs_sample_text_search_result": {
- "message": "Результат поиска"
- },
- "options_theme_tabs_sample_text_search_result_highlighted": {
- "message": "Выделенный результат поиска"
- },
- "options_theme_tabs_sample_text_search_result_selected": {
- "message": "Выбранный результат поиска"
- },
- "options_theme_tabs_sample_text_search_result_selected_active": {
- "message": "Активный результат поиска"
- },
- "options_there_is_a_theme_with_this_name": {
- "message": "Такое название темы уже существует, введите новое."
- },
- "options_toolbar": {
- "message": " Панель инструментов "
- },
- "options_available_buttons": {
- "message": "Настраивайте панель управления перетаскиванием элементов. Чтобы скрыть элемент, переместите его на зелёное поле."
- },
- "options_vivaldi": {
- "message": " Vivaldi "
- },
- "opt_url_for_web_panel": {
- "message": "Вставить этот URL в веб-панель"
- },
- "menu_duplicate_tab": {
- "message": "Дублировать вкладку"
- },
- "menu_close": {
- "message": "Закрыть вкладку"
- },
- "menu_close_other": {
- "message": "Закрыть другие вкладки"
- },
- "menu_collapse_all": {
- "message": "Свернуть все деревья"
- },
- "menu_unload": {
- "message": "Выгрузить вкладку"
- },
- "menu_expand_all": {
- "message": "Раскрыть все деревья"
- },
- "menu_detach_tab": {
- "message": "Отсоединить вкладку"
- },
- "menu_mute_tab": {
- "message": "Выключить звук на вкладке"
- },
- "menu_mute_other": {
- "message": "Выключить звук (на других)"
- },
- "menu_new_tab": {
- "message": "Новая вкладка"
- },
- "menu_pin_tab": {
- "message": "Закрепить вкладку"
- },
- "menu_reload_tab": {
- "message": "Обновить вкладку"
- },
- "menu_treetabs_settings": {
- "message": "Настройки Tree Tabs"
- },
- "menu_undo_close_tab": {
- "message": "Отменить закрытие"
- },
- "menu_unmute_tab": {
- "message": "Включить звук на вкладке"
- },
- "menu_unmute_other": {
- "message": "Включить звук (на других)"
- },
- "menu_unpin_tab": {
- "message": "Открепить вкладку"
- },
- "options_active_tab_font_bold": {
- "message": "жирный шрифт для активной вкладки"
- },
- "options_faster_scroll": {
- "message": "Быстрая прокрутка"
- },
- "options_never_show_close": {
- "message": "не показывать кнопку закрытия (опция выше будет проигнорирована)"
- },
- "menu_close_tree": {
- "message": "Закрыть дерево"
- }
}
diff --git a/background.js b/background.js
index 43a590f..1e27fb6 100644
--- a/background.js
+++ b/background.js
@@ -1,616 +1,574 @@
-// 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 /////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////
-
+// BACKGROUND VARIABLES
+let b = {
+ debug: [],
+ bg_running: false,
+ schedule_save: 0,
+ windows: {},
+ tabs: {},
+ tt_ids: {},
+ EmptyTabs: [],
+ newTabUrl: browserId == "F" ? "about:newtab" : "chrome://startpage/",
+ safe_mode: false
+};
+// 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++;
+ 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;
- }
- }
+ 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);
+ 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);
+ 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;
+ 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 GetTabParents(tabId, windowId) {
+ let Parents = [];
+ if (tabId == undefined) return Parents;
+ if (b.tabs[tabId] == undefined) return Parents;
+ let parent = b.tabs[tabId].parent;
+ let escape = 9999;
+ while (escape > 0 && (b.tabs[parent] != undefined || b.windows[windowId].folders[parent])) {
+ if (b.tabs[parent]) {
+ Parents.push(parent);
+ parent = b.tabs[parent].parent;
+ } else {
+ if (b.windows[windowId].folders[parent]) {
+ Parents.push(parent);
+ parent = b.windows[windowId].folders[parent].parent;
+ }
+ }
+ escape--;
+ }
+ 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 GetChildren(TTObj, parentId) { // TTObj is b.tabs or b.windows[winId].folders
+ let Children = [];
+ for (let Id in TTObj) {
+ if (TTObj[Id].parent == parentId) Children.push(Id);
+ }
+ return Children;
}
+function ShiftChildrenIndexes(TabsIdsArray, OpenerIndex, folderIdsArray, windowId) {
+ for (let tabId of TabsIdsArray) { // shift indexes of siblings tabs
+ if (b.tabs[tabId].index > OpenerIndex) b.tabs[tabId].index += 1;
+ }
+ for (let folderId of folderIdsArray) { // shift indexes of siblings folders
+ if (b.windows[windowId].folders[folderId].index > OpenerIndex) b.windows[windowId].folders[folderId].index += 1;
+ }
+}
+
+function UnshiftChildrenIndexes(TabsIdsArray, ClosedIndex, folderIdsArray, windowId) {
+ for (let tabId of TabsIdsArray) { // shift indexes of siblings tabs
+ if (b.tabs[tabId].index > ClosedIndex) b.tabs[tabId].index -= 1;
+ }
+ for (let folderId of folderIdsArray) { // shift indexes of siblings folders
+ if (b.windows[windowId].folders[folderId].index > ClosedIndex) b.windows[windowId].folders[folderId].index -= 1;
+ }
+}
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;
+ 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) {
+ if (gId == newGroupID) newGroupID = "";
+ }
+ }
+ }
+ groupId = newGroupID;
+ b.windows[windowId].groups[groupId] = { id: groupId, index: 999, active_tab: 0, prev_active_tab: 0, 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);
- }
-
- b.windows[winId].activeTabId = 0; // legacy
-
-
- 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 = 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, 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] );
+ for (let groupId in groups) {
+ if (!groups.hasOwnProperty(groupId)) continue;
+ if (groups[groupId].name === name) return groupId;
+ }
+ return null;
}
-////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////// 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 = 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);
- }
- });
- });
+// LISTENERS
+function StartBackgroundListeners() {
+ chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
+ if (message.command == "is_bg_ready") {
+ sendResponse(b.bg_running);
+ return;
+ }
+ 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") {
+ 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 == "update_tab") {
+ 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++;
+ }
+ return;
+ }
+ if (message.command == "update_all_tabs") {
+ for (let pin of message.pins) {
+ if (b.tabs[pin.id]) {
+ b.tabs[pin.id].parent = "pin_list";
+ b.tabs[pin.id].expand = "";
+ b.tabs[pin.id].index = pin.index;
+ }
+ }
+ for (let tab of message.tabs) {
+ if (b.tabs[tab.id]) {
+ b.tabs[tab.id].parent = tab.parent;
+ b.tabs[tab.id].expand = tab.expand;
+ b.tabs[tab.id].index = tab.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;
+ }
+ });
}
-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);
+// NEW TAB
+function OnMessageTabCreated(NewTab, activeTabId) {
+ 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(NewTab.id);
+ }
+
+ if (NewTab.pinned) {
+ let PinTabs = GetChildren(b.tabs, "pin_list");
+ b.tabs[NewTab.id].parent = "pin_list";
+ if (opt.append_pinned_tab == "after") {
+ if (NewTab.openerTabId && b.tabs[NewTab.openerTabId]) { // has opener tab case
+ ShiftChildrenIndexes(PinTabs, b.tabs[NewTab.openerTabId].index, [], NewTab.windowId);
+ b.tabs[NewTab.id].index = NewTab.index;
+ AfterId = NewTab.openerTabId;
+ } else {
+ if (b.tabs[activeTabId]) { // after active case
+ ShiftChildrenIndexes(PinTabs, b.tabs[activeTabId].index, [], NewTab.windowId);
+ AfterId = activeTabId;
+ }
+ }
+ }
+ if (opt.append_pinned_tab == "first") { // as first
+ ShiftChildrenIndexes(PinTabs, -1, [], NewTab.windowId);
+ b.tabs[NewTab.id].index = 0;
+ append = false;
+ }
+ if (opt.append_pinned_tab == "last") { // as last
+ b.tabs[NewTab.id].index = PinTabs.length;
+ append = true;
+ }
+ } else {
+
+ if (opt.append_orphan_tab == "as_child" && opt.orphaned_tabs_to_ungrouped == false) {
+ NewTab.openerTabId = activeTabId;
+ }
+ if (NewTab.openerTabId) { // child case
+ let OpenerSiblingTabs = GetChildren(b.tabs, b.tabs[NewTab.openerTabId].parent);
+ let OpenerSiblingFolders = GetChildren(b.windows[NewTab.windowId].folders, b.tabs[NewTab.openerTabId].parent);
+ if (opt.append_child_tab == "after") { // place tabs flat without automatic tree
+ b.tabs[NewTab.id].parent = b.tabs[NewTab.openerTabId].parent;
+ ShiftChildrenIndexes(OpenerSiblingTabs, b.tabs[NewTab.openerTabId].index, OpenerSiblingFolders, NewTab.windowId);
+ b.tabs[NewTab.id].index = b.tabs[NewTab.openerTabId].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 (opt.append_child_tab_after_limit == "after") { // max tree depth, place tab after parent
+ ShiftChildrenIndexes(OpenerSiblingTabs, b.tabs[NewTab.openerTabId].index, OpenerSiblingFolders, NewTab.windowId);
+ b.tabs[NewTab.id].index = b.tabs[NewTab.openerTabId].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)
+ ShiftChildrenIndexes(OpenerSiblingTabs, -1, OpenerSiblingFolders, NewTab.windowId);
+ b.tabs[NewTab.id].index = 0;
+ ParentId = b.tabs[NewTab.id].parent;
+ append = false;
+ }
+ if (opt.append_child_tab_after_limit == "bottom" && opt.append_child_tab != "after") { // max tree depth, place tab on bottom (below parent)
+ b.tabs[NewTab.id].index = OpenerSiblingTabs.length + OpenerSiblingFolders.length;
+ ParentId = b.tabs[NewTab.id].parent;
+ append = true;
+ }
+
+ } else {
+
+ let Parents = GetTabParents(NewTab.openerTabId, NewTab.windowId);
+ let OpenerChildren = GetChildren(b.tabs, 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 (opt.append_child_tab == "top") { // place child tab at the top (reverse hierarchy)
+ ShiftChildrenIndexes(OpenerSiblingTabs, -1, OpenerSiblingFolders, NewTab.windowId);
+ b.tabs[NewTab.id].index = 0;
+ ParentId = b.tabs[NewTab.id].parent;
+ }
+
+ if (opt.append_child_tab == "bottom") { // place child tab at the bottom
+ b.tabs[NewTab.id].index = OpenerSiblingTabs.length + OpenerSiblingFolders.length;
+ 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 (opt.append_child_tab_after_limit == "after") { // tab will append after opener
+ ShiftChildrenIndexes(OpenerSiblingTabs, b.tabs[NewTab.openerTabId].index, OpenerSiblingFolders, NewTab.windowId);
+ b.tabs[NewTab.id].index = b.tabs[NewTab.openerTabId].index + 1;
+ AfterId = NewTab.openerTabId;
+ }
+ if (opt.append_child_tab_after_limit == "top") { // tab will append on top
+ ShiftChildrenIndexes(OpenerSiblingTabs, -1, OpenerSiblingFolders, NewTab.windowId);
+ b.tabs[NewTab.id].index = 0;
+ ParentId = b.tabs[NewTab.id].parent;
+ }
+ if (opt.append_child_tab_after_limit == "bottom") { // tab will append on bottom
+ b.tabs[NewTab.id].index = OpenerSiblingTabs.length + OpenerSiblingFolders.length;
+ 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(b.tabs, "tab_list");
+ let TabListFolders = GetChildren(b.windows[NewTab.windowId].folders, "tab_list");
+ b.tabs[NewTab.id].index = TabListTabs.length + TabListFolders.length;
+ ParentId = "tab_list";
+ append = true;
+ } else {
+
+
+ if (opt.append_orphan_tab == "after_active" || opt.append_orphan_tab == "active_parent_top" || opt.append_orphan_tab == "active_parent_bottom") {
+
+ if (b.windows[NewTab.windowId] && b.windows[NewTab.windowId].activeTabId) {
+ if (b.tabs[activeTabId]) {
+ let ActiveTabSiblings = GetChildren(b.tabs, b.tabs[activeTabId].parent);
+ let ActiveTabSiblingFolders = GetChildren(b.windows[NewTab.windowId].folders, b.tabs[activeTabId].parent);
+ b.tabs[NewTab.id].parent = b.tabs[activeTabId].parent;
+ if (opt.append_orphan_tab == "after_active") {
+ ShiftChildrenIndexes(ActiveTabSiblings, b.tabs[activeTabId].index, ActiveTabSiblingFolders, NewTab.windowId);
+ b.tabs[NewTab.id].index = b.tabs[activeTabId].index + 1;
+ AfterId = activeTabId;
+ }
+ if (opt.append_orphan_tab == "active_parent_top") {
+ ShiftChildrenIndexes(ActiveTabSiblings, -1, ActiveTabSiblingFolders, NewTab.windowId);
+ b.tabs[NewTab.id].index = 0;
+ ParentId = b.tabs[NewTab.id].parent;
+ }
+ if (opt.append_orphan_tab == "active_parent_bottom") {
+ b.tabs[NewTab.id].index = ActiveTabSiblings.length + ActiveTabSiblingFolders.length;
+ ParentId = b.tabs[NewTab.id].parent;
+ append = true;
+ }
+
+ } else { // FAIL, no active tab!
+ let ActiveGroupTabs = GetChildren(b.tabs, b.windows[NewTab.windowId].active_group);
+ let ActiveGroupFolders = GetChildren(b.windows[NewTab.windowId].folders, b.windows[NewTab.windowId].active_group);
+ b.tabs[NewTab.id].parent = b.windows[NewTab.windowId].active_group;
+ b.tabs[NewTab.id].index = ActiveGroupTabs.length + ActiveGroupFolders.length;
+ ParentId = b.windows[NewTab.windowId].active_group;
+ }
+ } else {
+ b.tabs[NewTab.id].parent = "tab_list";
+ b.tabs[NewTab.id].index = NewTab.index;
+ ParentId = "tab_list";
+ }
+ }
+
+ if (opt.append_orphan_tab == "top") {
+ let ActiveGroupTabs = GetChildren(b.tabs, b.windows[NewTab.windowId].active_group);
+ let ActiveGroupFolders = GetChildren(b.windows[NewTab.windowId].folders, b.tabs[activeTabId].parent);
+ b.tabs[NewTab.id].parent = b.windows[NewTab.windowId].active_group;
+ ShiftChildrenIndexes(ActiveGroupTabs, -1, ActiveGroupFolders, NewTab.windowId);
+ b.tabs[NewTab.id].index = 0;
+ ParentId = b.windows[NewTab.windowId].active_group;
+ }
+
+ if (opt.append_orphan_tab == "bottom") {
+ let ActiveGroupTabs = GetChildren(b.tabs, b.windows[NewTab.windowId].active_group);
+ let ActiveGroupFolders = b.tabs[activeTabId] ? GetChildren(b.windows[NewTab.windowId].folders, b.tabs[activeTabId].parent) : [];
+ b.tabs[NewTab.id].parent = b.windows[NewTab.windowId].active_group;
+ b.tabs[NewTab.id].index = ActiveGroupTabs.length + ActiveGroupFolders.length;
+ ParentId = b.windows[NewTab.windowId].active_group;
+ append = true;
+ }
+ }
+ }
+
+ if (opt.move_tabs_on_url_change === "all_new" && NewTab.pinned == false) {
+ 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 });
}
-function ChromiumAddWindowData(winId) {
- b.windows[winId] = {activeTabId: 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 SafeModeCheck() {
+ setInterval(function() {
+ if (b.safe_mode) {
+ if (browserId == "F") {
+ chrome.windows.getAll({ windowTypes: ["normal"], populate: true }, function(w) {
+ for (win of w) {
+ Promise.resolve(browser.sessions.getWindowValue(win.id, "TTdata")).then(function(WindowData) {
+ if (WindowData != undefined) {
+ chrome.runtime.sendMessage({command: "reload_sidebar"});
+ window.location.reload();
+ }
+ });
+ }
+ });
+ }
+ if (browserId == "O") {
+ chrome.runtime.sendMessage({command: "reload_sidebar"});
+ window.location.reload();
+ }
+ if (browserId == "V") {
+ chrome.runtime.sendMessage({command: "reload_sidebar"});
+ window.location.reload();
+ }
+ }
+ }, 2000);
}
-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;
-}
+
+// START BACKGROUND SCRIPT
+document.addEventListener("DOMContentLoaded", function() {
+ StartBackgroundListeners();
+
+ if (browserId == "F") {
+ QuantumStart();
+ }
+ if (browserId == "O") {
+ OperaStart();
+ }
+ if (browserId == "V") {
+ VivaldiStart();
+ }
+
+});
\ No newline at end of file
diff --git a/background_firefox.js b/background_firefox.js
new file mode 100644
index 0000000..27717ab
--- /dev/null
+++ b/background_firefox.js
@@ -0,0 +1,335 @@
+// QUANTUM
+function QuantumStart() {
+ chrome.storage.local.get(null, function(storage) {
+ chrome.windows.getAll({ windowTypes: ["normal"], populate: true }, function(w) {
+
+ let windows_data = {};
+ let tabs_data = {};
+
+ for (let win of w) {
+ Promise.resolve(browser.sessions.getWindowValue(win.id, "TTdata")).then(function(WindowData) {
+ windows_data[win.id] = WindowData;
+ for (let tab of win.tabs) {
+ Promise.resolve(browser.sessions.getTabValue(tab.id, "TTdata")).then(function(TData) {
+ if (TData != undefined) b.tt_ids[TData.ttid] = tab.id;
+ tabs_data[tab.id] = TData;
+ });
+ }
+ });
+ }
+
+ setTimeout(function() {
+
+ // LOAD PREFERENCES
+ Preferences_GetCurrentPreferences(storage);
+
+ // CACHED COUNTS AND STUFF
+ let tabs_matched = 0;
+ let tabs_count = 0;
+
+ for (let win of w) {
+ tabs_count += win.tabs.length;
+ }
+
+ let lastWinId = w[w.length - 1].id;
+ let lastTabId = w[w.length - 1].tabs[w[w.length - 1].tabs.length - 1].id;
+
+ if (opt.debug == true) {
+ if (storage.debug_log != undefined) b.debug = storage.debug_log;
+ // if (retry == 0) pushlog("TreeTabs background start");
+ }
+
+ for (let win of w) {
+
+ // LOAD TTID FROM FIREFOX GET WINDOW VALUE
+ if (opt.skip_load == false && windows_data[win.id] != undefined) {
+ b.windows[win.id] = Object.assign({}, windows_data[win.id]);
+ } else {
+ QuantumAppendWinTTId(win.id);
+ }
+
+ for (let tab of win.tabs) {
+ // LOAD TTID FROM FIREFOX GET TAB VALUE
+ if (opt.skip_load == false && tabs_data[tab.id] != undefined) {
+ b.tabs[tab.id] = Object.assign({}, tabs_data[tab.id]);
+ tabs_matched++;
+
+ if (tabs_data[tab.id].parent_ttid != undefined && tabs_data[tab.id].parent_ttid != "") { // legacy
+ b.tabs[tab.id].parent = tabs_data[tab.id].parent_ttid; // legacy
+ delete b.tabs[tab.id].parent_ttid; // legacy
+ } // legacy
+
+ } else {
+ QuantumAppendTabTTId(tab);
+ }
+ if (tab.active) b.windows[win.id].activeTabId = tab.id;
+ }
+ }
+
+ // OK, DONE, NOW REPLACE OLD PARENTS IDS WITH THIS SESSION IDS
+ for (let tabId in b.tabs) {
+ if (b.tt_ids[b.tabs[tabId].parent] != undefined) {
+ b.tabs[tabId].parent = b.tt_ids[b.tabs[tabId].parent]; // is tab
+ } else {
+ b.tabs[tabId].parent = b.tabs[tabId].parent; // is not tab
+ }
+ }
+
+ // OK, SAME THING FOR ACTIVE TABS IN GROUPS
+ for (let winId in b.windows) {
+ for (let group in b.windows[winId].groups) {
+ if (b.tt_ids[b.windows[winId].groups[group].active_tab] != undefined) b.windows[winId].groups[group].active_tab = b.tt_ids[b.windows[winId].groups[group].active_tab];
+ if (b.tt_ids[b.windows[winId].groups[group].prev_active_tab] != undefined) b.windows[winId].groups[group].prev_active_tab = b.tt_ids[b.windows[winId].groups[group].prev_active_tab];
+ }
+ }
+
+ if (opt.skip_load == false && tabs_matched < tabs_count*0.5) {
+ b.safe_mode = true;
+ SafeModeCheck();
+ // SAFE MODE IS DISABLED AFTER 10 MINUTES
+ setTimeout(function() {
+ b.safe_mode = false;
+ }, 600000);
+
+ if (opt.debug) pushlog("started in safe mode");
+ }
+
+ b.bg_running = true;
+ QuantumAutoSaveData();
+ QuantumStartListeners();
+ delete DefaultToolbar;
+ delete DefaultTheme;
+ delete DefaultPreferences;
+ delete DefaultMenu;
+ chrome.runtime.sendMessage({ command: "bg_started" });
+
+ if (opt.debug) pushlog("QuantumStart, Current windows count is: " + w.length + "Current tabs count is: " + tabs_count + "Matching tabs: " + tabs_matched);
+
+ }, 1000);
+ });
+ });
+}
+
+// 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.safe_mode == false && b.bg_running && b.schedule_save > 0 && Object.keys(b.tabs).length > 1) {
+ chrome.windows.getAll({ windowTypes: ['normal'], populate: true }, function(w) {
+ for (let win of w) {
+ if (b.windows[win.id] != undefined) {
+ if (b.windows[win.id].ttid != undefined && b.windows[win.id].group_bar != undefined && b.windows[win.id].search_filter != undefined && b.windows[win.id].active_shelf != undefined && b.windows[win.id].active_group != undefined && b.windows[win.id].groups != undefined && b.windows[win.id].folders != undefined) {
+ let windowData = Object.assign({}, b.windows[win.id]);
+ for (let groupId in b.windows[win.id].groups) {
+ if (b.tabs[b.windows[win.id].groups[groupId].active_tab]) windowData.groups[groupId].active_tab = b.tabs[b.windows[win.id].groups[groupId].active_tab].ttid;
+ if (b.tabs[b.windows[win.id].groups[groupId].prev_active_tab]) windowData.groups[groupId].prev_active_tab = b.tabs[b.windows[win.id].groups[groupId].prev_active_tab].ttid;
+ }
+ browser.sessions.setWindowValue(win.id, "TTdata", windowData);
+ }
+ } else {
+ QuantumAppendWinTTId(win.id);
+ }
+
+ for (let tab of win.tabs) {
+ if (b.tabs[tab.id] != undefined) {
+ if (b.tabs[tab.id].ttid != undefined && b.tabs[tab.id].parent != undefined && b.tabs[tab.id].index != undefined && b.tabs[tab.id].expand != undefined) {
+ browser.sessions.setTabValue(tab.id, "TTdata", { ttid: b.tabs[tab.id].ttid, parent: (b.tabs[b.tabs[tab.id].parent] ? b.tabs[b.tabs[tab.id].parent].ttid : b.tabs[tab.id].parent), index: b.tabs[tab.id].index, expand: b.tabs[tab.id].expand });
+ } else {
+ QuantumAppendTabTTId(tab);
+ }
+ }
+ }
+ }
+ 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"), index: tab.index, expand: "" };
+ }
+ b.tt_ids[NewTTTabId] = tab.id;
+ return NewTTTabId;
+}
+
+function QuantumAppendWinTTId(windowId) {
+ let NewTTWindowId = QuantumGenerateNewWindowID();
+ if (b.windows[windowId] != undefined) {
+ b.windows[windowId].ttid = NewTTWindowId;
+ } else {
+ b.windows[windowId] = { activeTabId: 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, prev_active_tab: 0, name: labels.ungrouped_group, font: "" } }, folders: {} };
+ }
+}
+
+
+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) {
+ if (b.windows[tab.windowId] == undefined) {
+ QuantumAppendWinTTId(tab.windowId);
+ }
+ let prevActiveTabId = b.windows[tab.windowId].activeTabId;
+ 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 = b.tt_ids[TabData.parent] ? b.tt_ids[TabData.parent] : TabData.parent;
+ let AfterId = undefined;
+ let append = undefined;
+ if (originalParent) {
+ let originalParentChildren = GetChildren(b.tabs, originalParent);
+ if (TabData.index > 0 && TabData.index < originalParentChildren.length) {
+ for (let i = TabData.index + 1; i < originalParentChildren.length; i++) { // shift next siblings indexes
+ b.tabs[originalParentChildren[i]].index += 1;
+ }
+ AfterId = originalParentChildren[TabData.index];
+ }
+ if (TabData.index == 0) {
+ append = false;
+ }
+ if (TabData.index > originalParentChildren.length) {
+ append = true;
+ }
+ }
+ chrome.runtime.sendMessage({ command: "tab_created", windowId: tab.windowId, tabId: tab.id, tab: tab, ParentId: originalParent, InsertAfterId: AfterId, Append: append });
+ } else {
+ QuantumAppendTabTTId(tab);
+ chrome.tabs.get(tab.id, 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!)
+ if (NewTab) {
+ OnMessageTabCreated(NewTab, prevActiveTabId);
+ }
+ });
+ }
+ });
+ });
+ 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.windows[removeInfo.windowId].activeTabId == tabId) {
+ // chrome.runtime.sendMessage({command: "switch_active_tab", windowId: removeInfo.windowId, tabId: tabId});
+ // }
+ let SiblingTabs = GetChildren(b.tabs, b.tabs[tabId].parent);
+ let SiblingFolders = GetChildren(b.windows[removeInfo.windowId].folders, b.tabs[tabId].parent);
+ UnshiftChildrenIndexes(SiblingTabs, b.tabs[tabId].index, SiblingFolders, removeInfo.windowId);
+ 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.onUpdated.addListener(function(tabId, changeInfo, tab) {
+ if (changeInfo.pinned == true) {
+ if (b.tabs[tabId]) {
+ b.tabs[tabId].parent = "pin_list";
+ b.schedule_save++;
+ }
+ }
+ if (changeInfo.pinned == false) {
+ if (b.tabs[tabId]) {
+ 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 (tab.pinned == false) {
+ 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]) {
+ b.windows[activeInfo.windowId].activeTabId = 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++;
+ });
+}
\ No newline at end of file
diff --git a/background_opera.js b/background_opera.js
new file mode 100644
index 0000000..70278a5
--- /dev/null
+++ b/background_opera.js
@@ -0,0 +1,266 @@
+// OPERA
+function OperaStart() {
+ chrome.windows.getAll({ windowTypes: ['normal'], populate: true }, function(w) {
+ chrome.storage.local.get(null, function(storage) {
+ // LOAD PREFERENCES
+ Preferences_GetCurrentPreferences(storage);
+
+ // load tabs and windows from storage
+ let refTabs = {};
+ let refWins = {};
+ let tabs_matched = 0;
+ let LoadedWindows = storage.windows ? storage.windows : [];
+ let LoadedTabs = storage.tabs ? storage.tabs : [];
+ let CurrentTabsCount = 0;
+ for (let win of w) {
+ CurrentTabsCount += win.tabs.length;
+ }
+
+ if (opt.debug == true) {
+ if (storage.debug_log != undefined) b.debug = storage.debug_log;
+ // if (retry == 0) pushlog("TreeTabs background start");
+ }
+ for (let win of w) {
+ if (win.tabs[0].url != "chrome://videopopout/") { // this is for opera for their extra video popup, which is weirdly queried as a "normal" window
+ let url1 = win.tabs[0].url;
+ let url2 = win.tabs[win.tabs.length - 1].url;
+ OperaAddWindowData(win.id);
+ if (opt.skip_load == false) {
+ for (let loadedWin of LoadedWindows) {
+ if ((loadedWin.url1 == url1 || loadedWin.url2 == url2) && refWins[loadedWin.id] == undefined) {
+ refWins[loadedWin.id] = win.id;
+ if (loadedWin.group_bar) b.windows[win.id].group_bar = loadedWin.group_bar;
+ if (loadedWin.search_filter) b.windows[win.id].search_filter = loadedWin.search_filter;
+ if (loadedWin.active_shelf) b.windows[win.id].active_shelf = loadedWin.active_shelf;
+ if (loadedWin.active_group) b.windows[win.id].active_group = loadedWin.active_group;
+ if (Object.keys(loadedWin.groups).length > 0) b.windows[win.id].groups = Object.assign({}, loadedWin.groups);
+ if (Object.keys(loadedWin.folders).length > 0) b.windows[win.id].folders = Object.assign({}, loadedWin.folders);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // add new hashes for current tabs
+ for (let win of w) {
+ for (let tab of win.tabs) {
+ OperaHashURL(tab);
+ if (tab.active) b.windows[win.id].activeTabId = tab.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 win of w) {
+ for (tab of win.tabs) {
+ for (let loadedTab of LoadedTabs) {
+ if (loadedTab.hash == b.tabs[tab.id].hash && refTabs[loadedTab.id] == undefined) {
+ refTabs[loadedTab.id] = tab.id;
+ if (loadedTab.parent) b.tabs[tab.id].parent = loadedTab.parent;
+ if (loadedTab.index) b.tabs[tab.id].index = loadedTab.index;
+ if (loadedTab.expand) b.tabs[tab.id].expand = loadedTab.expand;
+ 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.skip_load == false && tabs_matched < LoadedTabs.length*0.5) {
+ b.safe_mode = true;
+ SafeModeCheck();
+ if (opt.debug) pushlog("started in safe mode");
+ if (storage.recovered_BAK) {
+ chrome.storage.local.set({ tabs: storage["tabs_BAK"+storage.recovered_BAK] });
+ chrome.storage.local.set({ windows: storage["windows_BAK"+storage.recovered_BAK] });
+ if (storage.recovered_BAK == 3) {
+ chrome.storage.local.remove("recovered_BAK");
+ } else {
+ chrome.storage.local.set({ recovered_BAK: (storage.recovered_BAK+1) });
+ }
+ } else {
+ chrome.storage.local.set({ recovered_BAK: 1 });
+ }
+ } else {
+ chrome.storage.local.remove("recovered_BAK");
+ }
+
+ if (opt.debug) pushlog("OperaStart, Current windows count is: " + w.length + "Saved windows count is: " + LoadedWindows.length + "Current tabs count is: " + CurrentTabsCount + "Loaded tabs count is: " + LoadedTabs.length + "Matching tabs: " + tabs_matched);
+
+ b.bg_running = true;
+ OperaAutoSaveData(0, 1000);
+ OperaAutoSaveData(1, 300000);
+ OperaAutoSaveData(2, 600000);
+ OperaAutoSaveData(3, 1800000);
+ OperaStartListeners();
+ delete DefaultToolbar;
+ delete DefaultTheme;
+ delete DefaultPreferences;
+ delete DefaultMenu;
+ chrome.runtime.sendMessage({ command: "bg_started" });
+ });
+ });
+}
+
+async function OperaAutoSaveData(BAK, LoopTimer) {
+ setInterval(function() {
+ if (b.schedule_save > 1 || BAK > 0) {
+ b.schedule_save = 1;
+ }
+ if (b.bg_running && b.schedule_save > 0 && Object.keys(b.tabs).length > 1) {
+ chrome.windows.getAll({ windowTypes: ['normal'], populate: true }, function(w) {
+ let Windows = [];
+ let Tabs = [];
+
+ for (let win of w) {
+ if (b.windows[win.id] != undefined) {
+ if (b.windows[win.id].group_bar != undefined && b.windows[win.id].search_filter != undefined && b.windows[win.id].active_shelf != undefined && b.windows[win.id].active_group != undefined && b.windows[win.id].groups != undefined && b.windows[win.id].folders != undefined) {
+ Windows.push({ url1: win.tabs[0].url, url2: win.tabs[win.tabs.length - 1].url, group_bar: b.windows[win.id].group_bar, search_filter: b.windows[win.id].search_filter, active_shelf: b.windows[win.id].active_shelf, active_group: b.windows[win.id].active_group, groups: b.windows[win.id].groups, folders: b.windows[win.id].folders });
+ }
+ } else {
+ OperaAddWindowData(win.id);
+ }
+
+ for (let tab of win.tabs) {
+ if (b.tabs[tab.id] != undefined) {
+ if (b.tabs[tab.id].hash != undefined && b.tabs[tab.id].parent != undefined && b.tabs[tab.id].index != undefined && b.tabs[tab.id].expand != undefined) {
+ Tabs.push({ id: tab.id, hash: b.tabs[tab.id].hash, parent: b.tabs[tab.id].parent, index: b.tabs[tab.id].index, expand: b.tabs[tab.id].expand });
+ }
+ } else {
+ OperaHashURL(tab);
+ }
+ }
+ }
+ chrome.storage.local.set((BAK == 0 ? { windows: Windows, tabs: Tabs } : (BAK == 1 ? { windows_BAK1: Windows, tabs_BAK1: Tabs } : (BAK == 2 ? { windows_BAK2: Windows, tabs_BAK2: Tabs } : { windows_BAK3: Windows, tabs_BAK3: Tabs }))));
+ b.schedule_save--;
+ });
+ }
+ if (opt.debug == true) chrome.storage.local.set({ debug_log: b.debug });
+ }, LoopTimer);
+}
+
+function OperaAddWindowData(winId) {
+ b.windows[winId] = { activeTabId: 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 OperaHashURL(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;
+}
+
+function OperaStartListeners() { // start all listeners
+ chrome.tabs.onCreated.addListener(function(tab) {
+ if (b.windows[tab.windowId] == undefined) {
+ OperaAddWindowData(tab.windowId);
+ }
+ let prevActiveTabId = b.windows[tab.windowId].activeTabId;
+ OperaHashURL(tab);
+ OnMessageTabCreated(tab, prevActiveTabId);
+ });
+ chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
+ let SiblingTabs = GetChildren(b.tabs, b.tabs[tabId].parent);
+ let SiblingFolders = GetChildren(b.windows[removeInfo.windowId].folders, b.tabs[tabId].parent);
+ UnshiftChildrenIndexes(SiblingTabs, b.tabs[tabId].index, SiblingFolders, removeInfo.windowId);
+ 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) {
+ OperaHashURL(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 (tab.pinned == false) {
+ 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 {
+ OperaHashURL(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]) {
+ b.windows[activeInfo.windowId].activeTabId = activeInfo.tabId;
+ }
+ chrome.runtime.sendMessage({ command: "tab_activated", windowId: activeInfo.windowId, tabId: activeInfo.tabId });
+ b.schedule_save++;
+ });
+ chrome.windows.onCreated.addListener(function(window) {
+ OperaAddWindowData(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.bg_running = false;
+ });
+}
\ No newline at end of file
diff --git a/background_vivaldi.js b/background_vivaldi.js
new file mode 100644
index 0000000..3346ec6
--- /dev/null
+++ b/background_vivaldi.js
@@ -0,0 +1,377 @@
+// VIVALDI
+function VivaldiLegacyAddWindowData(win) {
+ b.windows[win.id] = { activeTabId: 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 VivaldiLegacyHashURL(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;
+}
+
+function VivaldiStart() {
+ chrome.windows.getAll({ windowTypes: ['normal'], populate: true }, function(w) {
+ chrome.storage.local.get(null, function(storage) {
+ // LOAD PREFERENCES
+ Preferences_GetCurrentPreferences(storage);
+
+ // LEGACY START TO CONVERT DATA
+ if ((storage.data_version == undefined && storage.tabs != undefined) || storage.data_version < 2) {
+ b.safe_mode = true;
+ let refTabs = {};
+ let refWins = {};
+ let tabs_matched = 0;
+ let LoadedWindows = storage.windows ? storage.windows : [];
+ let LoadedTabs = storage.tabs ? storage.tabs : [];
+ let CurrentTabsCount = 0;
+ for (let win of w) {
+ CurrentTabsCount += win.tabs.length;
+ }
+ for (let win of w) {
+ let url1 = win.tabs[0].url;
+ let url2 = win.tabs[win.tabs.length - 1].url;
+ VivaldiLegacyAddWindowData(win);
+ if (opt.skip_load == false) {
+ for (let loadedWin of LoadedWindows) {
+ if ((loadedWin.url1 == url1 || loadedWin.url2 == url2) && refWins[loadedWin.id] == undefined) {
+ refWins[loadedWin.id] = win.id;
+ if (loadedWin.group_bar) b.windows[win.id].group_bar = loadedWin.group_bar;
+ if (loadedWin.search_filter) b.windows[win.id].search_filter = loadedWin.search_filter;
+ if (loadedWin.active_shelf) b.windows[win.id].active_shelf = loadedWin.active_shelf;
+ if (loadedWin.active_group) b.windows[win.id].active_group = loadedWin.active_group;
+ if (Object.keys(loadedWin.groups).length > 0) b.windows[win.id].groups = Object.assign({}, loadedWin.groups);
+ if (Object.keys(loadedWin.folders).length > 0) b.windows[win.id].folders = Object.assign({}, loadedWin.folders);
+ break;
+ }
+ }
+ }
+ }
+ for (let win of w) {
+ for (let tab of win.tabs) {
+ VivaldiLegacyHashURL(tab);
+ if (tab.active) b.windows[win.id].activeTabId = tab.id;
+ }
+ }
+ if (opt.skip_load == false && LoadedTabs.length > 0) {
+ for (let win of w) {
+ for (tab of win.tabs) {
+ for (let loadedTab of LoadedTabs) {
+ if (loadedTab.hash == b.tabs[tab.id].hash && refTabs[loadedTab.id] == undefined) {
+ refTabs[loadedTab.id] = tab.id;
+ if (loadedTab.parent) b.tabs[tab.id].parent = loadedTab.parent;
+ if (loadedTab.index) b.tabs[tab.id].index = loadedTab.index;
+ if (loadedTab.expand) b.tabs[tab.id].expand = loadedTab.expand;
+ tabs_matched++;
+ break;
+ }
+ }
+ }
+ }
+ for (let tabId in b.tabs) {
+ if (refTabs[b.tabs[tabId].parent] != undefined) b.tabs[tabId].parent = refTabs[b.tabs[tabId].parent];
+ }
+ 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];
+ }
+ }
+ }
+ for (let win of w) {
+ if (b.windows[win.id]) b.windows[win.id].ttid = JSON.parse(win.extData).ext_id;
+ for (let tab of win.tabs) {
+ if (b.tabs[tab.id]) b.tabs[tab.id].ttid = JSON.parse(tab.extData).ext_id;
+ }
+ }
+ let Windows = {};
+ let Tabs = {};
+ for (let win of w) {
+ if (b.windows[win.id] != undefined && b.windows[win.id].ttid != undefined && b.windows[win.id].group_bar != undefined && b.windows[win.id].search_filter != undefined && b.windows[win.id].active_shelf != undefined && b.windows[win.id].active_group != undefined && b.windows[win.id].groups != undefined && b.windows[win.id].folders != undefined) {
+ Windows[b.windows[win.id].ttid] = { ttid: b.windows[win.id].ttid, group_bar: b.windows[win.id].group_bar, search_filter: b.windows[win.id].search_filter, active_shelf: b.windows[win.id].active_shelf, active_group: b.windows[win.id].active_group, groups: b.windows[win.id].groups, folders: b.windows[win.id].folders };
+ for (let groupId in b.windows[win.id].groups) {
+ if (b.tabs[b.windows[win.id].groups[groupId].active_tab]) Windows[b.windows[win.id].ttid].groups[groupId].active_tab = b.tabs[b.windows[win.id].groups[groupId].active_tab].ttid;
+ if (b.tabs[b.windows[win.id].groups[groupId].prev_active_tab]) Windows[b.windows[win.id].ttid].groups[groupId].prev_active_tab = b.tabs[b.windows[win.id].groups[groupId].prev_active_tab].ttid;
+ }
+ }
+ for (let tab of win.tabs) {
+ if (b.tabs[tab.id] != undefined && b.tabs[tab.id].ttid != undefined && b.tabs[tab.id].parent != undefined && b.tabs[tab.id].index != undefined && b.tabs[tab.id].expand != undefined) {
+ Tabs[b.tabs[tab.id].ttid] = { ttid: b.tabs[tab.id].ttid, parent: (b.tabs[b.tabs[tab.id].parent] ? b.tabs[b.tabs[tab.id].parent].ttid : b.tabs[tab.id].parent), index: b.tabs[tab.id].index, expand: b.tabs[tab.id].expand };
+ }
+ }
+ }
+ chrome.storage.local.set({ data_version: 2, windows: Windows, tabs: Tabs });
+ chrome.storage.local.remove("t_count");
+ chrome.storage.local.remove("w_count");
+ chrome.runtime.sendMessage({command: "reload_sidebar"});
+ window.location.reload();
+ }
+
+ if (storage.data_version == undefined || storage.data_version == 2) {
+ // load tabs and windows from storage
+ let refTabs = {};
+ let tabs_matched = 0;
+ let LoadedWindows = storage.windows ? storage.windows : {};
+ let LoadedTabs = storage.tabs ? storage.tabs : {};
+
+ // load debug log
+ if (opt.debug == true) {
+ if (storage.debug_log != undefined) b.debug = storage.debug_log;
+ }
+
+ // add data
+ for (let win of w) {
+ VivaldiAddWindowData(win);
+ for (let tab of win.tabs) {
+ VivaldiAddTabData(tab);
+ }
+ }
+
+ // if not skipping loading data
+ if (opt.skip_load == false) {
+
+ for (let win of w) {
+ if (LoadedWindows[b.windows[win.id].ttid] != undefined) {
+ b.windows[win.id] = Object.assign({}, LoadedWindows[b.windows[win.id].ttid]);
+ }
+ for (let tab of win.tabs) {
+ if (LoadedTabs[b.tabs[tab.id].ttid] != undefined) {
+ b.tabs[tab.id] = Object.assign({}, LoadedTabs[b.tabs[tab.id].ttid]);
+ refTabs[b.tabs[tab.id].ttid] = tab.id;
+ tabs_matched++;
+ } else {
+ if (LoadedTabs["_"+tab.index+"_"+b.windows[win.id].ttid] != undefined) {
+ b.tabs[tab.id] = Object.assign({}, LoadedTabs["_"+tab.index+"_"+b.windows[win.id].ttid]);
+ refTabs["_"+tab.index+"_"+b.windows[win.id].ttid] = tab.id;
+ tabs_matched++;
+ }
+ }
+ if (tab.active) b.windows[tab.windowId].activeTabId = tab.id;
+ }
+ }
+
+ // replace ttids to browser tabIds for parents
+ for (let tabId in b.tabs) {
+ if (refTabs[b.tabs[tabId].parent] != undefined) {
+ b.tabs[tabId].parent = refTabs[b.tabs[tabId].parent];
+ }
+ }
+
+ // replace ttids to browser tabIds, but of active tabs in groups
+ for (let winId in b.windows) {
+ for (let group in b.windows[winId].groups) {
+ if (refTabs[b.windows[winId].groups[group].active_tab] != undefined) {
+ b.windows[winId].groups[group].active_tab = refTabs[b.windows[winId].groups[group].active_tab];
+ }
+ if (refTabs[b.windows[winId].groups[group].prev_active_tab] != undefined) {
+ b.windows[winId].groups[group].prev_active_tab = refTabs[b.windows[winId].groups[group].prev_active_tab];
+ }
+ }
+ }
+
+ if (tabs_matched < LoadedTabs.length*0.5) {
+ b.safe_mode = true;
+ SafeModeCheck();
+ if (opt.debug) pushlog("started in safe mode");
+ if (storage.recovered_BAK) {
+ chrome.storage.local.set({ tabs: storage["tabs_BAK"+storage.recovered_BAK] });
+ chrome.storage.local.set({ windows: storage["windows_BAK"+storage.recovered_BAK] });
+ if (storage.recovered_BAK == 3) {
+ chrome.storage.local.remove("recovered_BAK");
+ } else {
+ chrome.storage.local.set({ recovered_BAK: (storage.recovered_BAK+1) });
+ }
+ } else {
+ chrome.storage.local.set({ recovered_BAK: 1 });
+ }
+ } else {
+ chrome.storage.local.remove("recovered_BAK");
+ }
+
+ if (opt.debug) pushlog("VivaldiStart, Current windows count is: " + w.length + "Saved windows count is: " + LoadedWindows.length + "Loaded tabs count is: " + LoadedTabs.length + "Matching tabs: " + tabs_matched);
+
+ }
+ }
+
+ b.bg_running = true;
+ VivaldiAutoSaveData(0, 1000);
+ VivaldiAutoSaveData(1, 300000);
+ VivaldiAutoSaveData(2, 600000);
+ VivaldiAutoSaveData(3, 1800000);
+ VivaldiStartListeners();
+ delete DefaultToolbar;
+ delete DefaultTheme;
+ delete DefaultPreferences;
+ delete DefaultMenu;
+ chrome.runtime.sendMessage({ command: "bg_started" });
+ });
+ });
+}
+
+async function VivaldiAutoSaveData(BAK, LoopTimer) {
+ setInterval(function() {
+ if (b.schedule_save > 1 || BAK > 0) {
+ b.schedule_save = 1;
+ }
+ if (b.bg_running && b.schedule_save > 0 && Object.keys(b.tabs).length > 1) {
+ chrome.windows.getAll({ windowTypes: ['normal'], populate: true }, function(w) {
+ let Windows = {};
+ let Tabs = {};
+ for (let win of w) {
+ if (b.windows[win.id] != undefined) {
+ if (b.windows[win.id].ttid != undefined && b.windows[win.id].group_bar != undefined && b.windows[win.id].search_filter != undefined && b.windows[win.id].active_shelf != undefined && b.windows[win.id].active_group != undefined && b.windows[win.id].groups != undefined && b.windows[win.id].folders != undefined) {
+ Windows[b.windows[win.id].ttid] = { ttid: b.windows[win.id].ttid, group_bar: b.windows[win.id].group_bar, search_filter: b.windows[win.id].search_filter, active_shelf: b.windows[win.id].active_shelf, active_group: b.windows[win.id].active_group, groups: b.windows[win.id].groups, folders: b.windows[win.id].folders };
+ for (let groupId in b.windows[win.id].groups) {
+ if (b.tabs[b.windows[win.id].groups[groupId].active_tab]) Windows[b.windows[win.id].ttid].groups[groupId].active_tab = b.tabs[b.windows[win.id].groups[groupId].active_tab].ttid;
+ if (b.tabs[b.windows[win.id].groups[groupId].prev_active_tab]) Windows[b.windows[win.id].ttid].groups[groupId].prev_active_tab = b.tabs[b.windows[win.id].groups[groupId].prev_active_tab].ttid;
+ }
+ }
+ } else {
+ VivaldiAddWindowData(win);
+ b.schedule_save++;
+ }
+ for (let tab of win.tabs) {
+ if (b.tabs[tab.id] != undefined) {
+ if (b.tabs[tab.id].ttid != undefined && b.tabs[tab.id].parent != undefined && b.tabs[tab.id].index != undefined && b.tabs[tab.id].expand != undefined) {
+ Tabs[b.tabs[tab.id].ttid] = { ttid: b.tabs[tab.id].ttid, parent: (b.tabs[b.tabs[tab.id].parent] ? b.tabs[b.tabs[tab.id].parent].ttid : b.tabs[tab.id].parent), index: b.tabs[tab.id].index, expand: b.tabs[tab.id].expand };
+ }
+ } else {
+ VivaldiAddTabData(tab);
+ }
+ }
+ }
+ chrome.storage.local.set((BAK == 0 ? { windows: Windows, tabs: Tabs } : (BAK == 1 ? { windows_BAK1: Windows, tabs_BAK1: Tabs } : (BAK == 2 ? { windows_BAK2: Windows, tabs_BAK2: Tabs } : { windows_BAK3: Windows, tabs_BAK3: Tabs }))));
+ b.schedule_save--;
+ });
+ }
+ if (opt.debug == true) chrome.storage.local.set({ debug_log: b.debug });
+ }, LoopTimer);
+}
+
+
+function VivaldiAddWindowData(win) {
+ let extData = JSON.parse(win.extData);
+ if (b.windows[win.id] == undefined) b.windows[win.id] = { ttid: (win.extData.match("ext_id") != null ? JSON.parse(win.extData).ext_id : win.index), activeTabId: 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: {} };
+ return b.windows[win.id].ttid;
+}
+
+function VivaldiAddTabData(tab) {
+ if (b.tabs[tab.id] == undefined) {
+ b.tabs[tab.id] = { ttid: "_", 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" };
+ }
+ if (tab.extData.match("ext_id") != null) {
+ b.tabs[tab.id].ttid = JSON.parse(tab.extData).ext_id;
+ b.schedule_save++;
+ } else {
+ b.tabs[tab.id].ttid = "_"+tab.index+"_"+b.windows[tab.windowId].ttid;
+ b.schedule_save++;
+ }
+ return b.tabs[tab.id].ttid;
+}
+
+function VivaldiStartListeners() { // start all listeners
+ chrome.tabs.onCreated.addListener(function(tab) {
+ // VivaldiAddWindowData(tab.windowId);
+ // let extData = tab.extData.match("ext_id") != null ? JSON.parse(tab.extData).ext_id : false;
+ // if (extData) {
+ // for (let tabId in b.tabs) {
+ // if (extData === b.tabs[tabId].ttid) {
+ // b.tabs[tab.id] = b.tabs[tabId];
+ // delete b.tabs[tabId];
+ // break;
+ // }
+ // }
+ // }
+ let prevActiveTabId = b.windows[tab.windowId].activeTabId;
+ VivaldiAddTabData(tab);
+ OnMessageTabCreated(tab, prevActiveTabId);
+ });
+ chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
+ let SiblingTabs = b.tabs[tabId] ? GetChildren(b.tabs, b.tabs[tabId].parent) : [];
+ let SiblingFolders = b.tabs[tabId] ? GetChildren(b.windows[removeInfo.windowId].folders, b.tabs[tabId].parent) : [];
+ UnshiftChildrenIndexes(SiblingTabs, b.tabs[tabId].index, SiblingFolders, removeInfo.windowId);
+ 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 (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 (tab.pinned == false) {
+ 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 {
+ VivaldiAddTabData(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]) {
+ b.windows[activeInfo.windowId].activeTabId = activeInfo.tabId;
+ }
+ chrome.runtime.sendMessage({ command: "tab_activated", windowId: activeInfo.windowId, tabId: activeInfo.tabId });
+ setTimeout(function() {chrome.tabs.query({windowId: activeInfo.windowId}, function(tabs) {for (let tab of tabs) {if ((b.tabs[tab.id].ttid).startsWith("_") || tab.id === activeInfo.tabId) VivaldiAddTabData(tab);}});}, 500);
+ b.schedule_save++;
+ });
+ chrome.windows.onCreated.addListener(function(window) {
+ VivaldiAddWindowData(window);
+ b.schedule_save++;
+ });
+ chrome.windows.onRemoved.addListener(function(windowId) {
+ delete b.windows[windowId];
+ b.schedule_save++;
+ });
+ chrome.runtime.onSuspend.addListener(function() {
+ b.bg_running = false;
+ });
+}
+
diff --git a/global.js b/global.js
new file mode 100644
index 0000000..52b3b7f
--- /dev/null
+++ b/global.js
@@ -0,0 +1,92 @@
+// 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")
+};
+
+// 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 DefaultMenu = {
+ all_entries: [["s_pin","menu_new_pin"],["s_newt","menu_new_tab"],["s_unpt","menu_unpin_tab"],["s_pit","menu_pin_tab"],["s_newf","menu_new_folder"],["s_renf","menu_rename_folder"],["s_delf","menu_delete_folder"],["s_dupt","menu_duplicate_tab"],["s_undclo","menu_undo_close_tab"],["s_bkt","menu_bookmark_tree"],["s_expat","menu_expand_tree"],["s_collt","menu_collapse_tree"],["s_expaa","menu_expand_all"],["s_colla","menu_collapse_all"],["s_deta","menu_detach_tab"],["s_rel","menu_reload_tab"],["s_unlo","menu_unload"],["s_unlt","menu_unload_tree"],["s_clo","menu_close"],["s_clot","menu_close_tree"],["s_cloo","menu_close_other"],["s_mut","menu_mute_tab"],["s_mutt","menu_mute_tree"],["s_unmu","menu_unmute_tab"],["s_unmut","menu_unmute_tree"],["s_mutot","menu_mute_other"],["s_unmutot","menu_unmute_other"],["s_newg","menu_new_group"],["s_reng","menu_rename_group"],["s_delg","menu_delete_group"],["s_delgclo","menu_delete_group_tabs_close"],["s_gunlo","menu_groups_unload"],["s_ghiber","menu_groups_hibernate"],["s_gtbcl","menu_group_tabs_close"],["s_gbk","menu_bookmark_group"],["s_mngr_wnd","menu_manager_window"],["s_tts","menu_treetabs_settings"]],
+ pin: [[ false,true ],[ false,false ],[ true,true ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ true,true ],[ true,true ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ true,true ],[ false,true ],[ false,false ],[ false,false ],[ true,false ],[ false,false ],[ false,true ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ true,true ],[ false,true ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,true ],[ true,true ]],
+ tab: [[ false,false ],[ false,true ],[ true,false ],[ false,true ],[ true,true ],[ false, false ],[ false,false ],[ true,true ],[ true,true ],[ false,true ],[ false,false ],[ false,false ],[ true,true ],[ false,true ],[ true,true ],[ false,true ],[ false,false ],[ false,false ],[ true,true ],[ false,false ],[ false,true ],[ false,false ],[ false, false ],[ false,false ],[ false,false ],[ true,true ],[ false,true ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,true ],[ true,true ]],
+ folder: [[ false,false ],[ false,true ],[ false,false ],[ false,false ],[ false,true ],[ true,true ],[ false,true ],[ false,false ],[ false,false ],[ true,true ],[ false,false ],[ false,false ],[ true,true ],[ false,true ],[ true,true ],[ false,false ],[ true,true ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,true ],[ false,false ],[ false,true ],[ false,false ],[ false,false ],[ false,false ],[ false,true ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,true ],[ true,true ]],
+ global: [[ false,true ],[ false,true ],[ false,false ],[ false,false ],[ false,true ],[ false,false ],[ false,false ],[ false,false ],[ true,true ],[ false,false ],[ false,false ],[ false,false ],[ true,true ],[ false,true ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ true,true ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ true,true ],[ false,true ],[ true,true ]],
+ group: [[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,true ],[ false,true ],[ false,true ],[ false,true ],[ true,true ],[ false,true ],[ true,true ],[ true,true ],[ false,true ],[ true,true ]]
+// name: [[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ],[ false,false ]]
+};
+
+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_attention_blinking: true,
+ audio_blinking: true,
+ pin_list_multi_row: true,
+ append_pinned_tab: "last",
+ 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",
+ append_tab_from_toolbar: "group_root",
+ 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,
+ 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
+};
+
+// 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 < 14; letter++) { random += letters[Math.floor(Math.random() * letters.length)]; }
+ return random;
+}
\ No newline at end of file
diff --git a/listeners_bg.js b/listeners_bg.js
deleted file mode 100644
index 76ba87b..0000000
--- a/listeners_bg.js
+++ /dev/null
@@ -1,716 +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 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 prevActiveTabId = b.windows[tab.windowId].activeTabId;
- b.NewTabsQueue.push(tab.id);
- 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, prevActiveTabId);
- }
- });
- });
- 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]) {
- b.windows[activeInfo.windowId].activeTabId = 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) {
- b.NewTabsQueue.push(tab.id);
- ChromiumHashURL(tab);
- OnMessageTabCreated(tab.id, b.windows[tab.windowId].activeTabId);
- });
- 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]) {
- b.windows[activeInfo.windowId].activeTabId = 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, activeTabId) {
- if (b.NewTabsQueue.length > 0 && b.NewTabsQueue[0] == 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";
- 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;
- }
- b.tabs[NewTab.id].index = NewTab.index;
-
- } else {
-
- if (opt.append_orphan_tab == "as_child" && opt.orphaned_tabs_to_ungrouped == false) {
- NewTab.openerTabId = activeTabId;
- }
-
- 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;
- }
- for (let i = OpenerSiblings.indexOf(NewTab.openerTabId)+1; i < OpenerSiblings.length; i++) { // shift next siblings indexes
- b.tabs[OpenerSiblings[i]].index += 1;
- }
- b.tabs[NewTab.id].index = b.tabs[NewTab.openerTabId].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
- for (let i = OpenerSiblings.indexOf(NewTab.openerTabId)+1; i < OpenerSiblings.length; i++) { // shift next siblings indexes
- b.tabs[OpenerSiblings[i]].index += 1;
- }
- b.tabs[NewTab.id].index = b.tabs[NewTab.openerTabId].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)
- for (let i = 0; i < OpenerSiblings.length; i++) { // shift all siblings indexes
- b.tabs[OpenerSiblings[i]].index += 1;
- }
- b.tabs[NewTab.id].index = 0;
- 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)
- for (let i = 0; i < OpenerChildren.length; i++) { // shift all siblings indexes
- b.tabs[OpenerChildren[i]].index += 1;
- }
- b.tabs[NewTab.id].index = 0;
- 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
- for (let i = OpenerSiblings.indexOf(NewTab.openerTabId)+1; i < OpenerSiblings.length; i++) { // shift next siblings indexes
- b.tabs[OpenerSiblings[i]].index += 1;
- }
- b.tabs[NewTab.id].index = b.tabs[NewTab.openerTabId].index+1;
- AfterId = NewTab.openerTabId;
- }
-
- if (opt.append_child_tab_after_limit == "top") { // tab will append on top
- for (let i = 0; i < OpenerChildren.length; i++) { // shift all siblings indexes
- b.tabs[OpenerChildren[i]].index += 1;
- }
- b.tabs[NewTab.id].index = 0;
- 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;
- } else {
-
- if (opt.append_orphan_tab == "after_active") {
-
- if (b.windows[NewTab.windowId] && b.windows[NewTab.windowId].activeTabId) {
- if (b.tabs[activeTabId]) {
-
- let ActiveSiblings = GetChildren(b.tabs[activeTabId].parent);
- b.tabs[NewTab.id].parent = b.tabs[activeTabId].parent;
- for (let i = ActiveSiblings.indexOf(activeTabId)+1; i < ActiveSiblings.length; i++) { // shift next siblings indexes
- b.tabs[ActiveSiblings[i]].index += 1;
- }
- b.tabs[NewTab.id].index = b.tabs[activeTabId].index+1;
- 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;
- }
- } else {
- b.tabs[NewTab.id].parent = "tab_list";
- if (browserId == "F"){
- b.tabs[NewTab.id].parent_ttid = "";
- }
- b.tabs[NewTab.id].index = NewTab.index;
- ParentId = "tab_list";
- }
- }
-
- 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 = "";
- }
- for (let i = 0; i < GroupTabs.length; i++) { // shift all tabs indexes in group
- b.tabs[GroupTabs[i]].index += 1;
- }
- b.tabs[NewTab.id].index = 0;
- 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});
-
- if (b.NewTabsQueue.indexOf(NewTab.id) != -1) {
- b.NewTabsQueue.splice(b.NewTabsQueue.indexOf(NewTab.id), 1);
- }
-
- });
-
- } else {
- console.log("tab_created in queue");
- setTimeout(function() {
- OnMessageTabCreated(tabId, activeTabId);
- }, 100);
-
- }
-}
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
index 0e7a66c..754c56d 100644
--- a/manifest.json
+++ b/manifest.json
@@ -2,7 +2,7 @@
"manifest_version": 2,
"default_locale": "en",
"background": {
- "scripts": [ "listeners_bg.js", "scripts/common.js", "background.js" ],
+ "scripts": [ "global.js", "./scripts/preferences.js", "background_firefox.js", "background_opera.js", "background_vivaldi.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,21 +28,25 @@
"browser_action": {
"default_icon": "icons/24.png"
},
- "applications": {
- "gecko": {
- "id": "TreeTabs@jagiello.it",
- "strict_min_version": "57.0"
- }
- },
- "options_ui": {
- "page": "options.html",
- "open_in_tab": true
- },
"commands": {
+ "_execute_browser_action": {
+ "suggested_key": { "default": "F1" },
+ "description": "toggle Tree Tabs"
+ },
"close_tree": {
"suggested_key": { "default": "Alt+W" },
"description": "close tree"
}
},
- "version": "100"
+ "applications": {
+ "gecko": {
+ "id": "TreeTabs@jagiello.it",
+ "strict_min_version": "63.0"
+ }
+ },
+ "options_ui": {
+ "page": "options/options.html",
+ "open_in_tab": true
+ },
+ "version": "1.8.7"
}
\ No newline at end of file
diff --git a/options.html b/options.html
deleted file mode 100644
index 09e0531..0000000
--- a/options.html
+++ /dev/null
@@ -1,858 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-