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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Tree Tabs
-
- - - - - - - -
- - - - - - - - - - - - -
-
-
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
    -
  • - - -
  • -
  • - - -
  • -
-
- - - -
- -
    -
  • - - -
  • -
  • - - -
  • -
- - - - - - -
-
-
- - - -
- -
    -
  • - - -
  • -
  • - - -
  • -
- - - - - - - - - - - - - - - - -
-
-
-
-
    -
  • - - -
  • -
  • - - -
  • -
  • - - -
  • -
  • - - -
  • -
  • - - -
  • -
  • -
    -
    - - - - - -
    - -
  • -
  • - - -
  • -
- - - - - - -
- - -
- - - - - - -
-
- -
-

-
    -
  • -
  • -
  • - -
  • -
- - -
- - - -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
- - -
- - - - - - - -
-
- -
-
- - - -
- - - -
- - - - - - - - - - -
-
- -
- - - -
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- -
-
-
- -
-
-
- - - - -
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-
- -
-
- -
- -
- -
-
-
-
-
- -
-
- - - -
-
- -
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- - - -
- -
- - -
- - - - - - - - -
-
- -
- - - - - - - -
-
-
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/options/options.css b/options/options.css index b843ec7..088b8f3 100644 --- a/options/options.css +++ b/options/options.css @@ -425,7 +425,7 @@ ul:not(.menu) li { /* TAB LIST AND SCROLLBAR */ #groups { position: absolute; - height: 850px; + height: calc(100% - var(--pin_height) - 80px); width: calc(771px - var(--scrollbar_width)); top: calc(var(--scrollbar_height) + var(--pin_height) + 33px); left: 40px; @@ -434,7 +434,7 @@ ul:not(.menu) li { #group_scrollbar { position: absolute; - height: 850px; + height: calc(100% - var(--pin_height) - 80px); width: var(--scrollbar_width); top: calc(var(--scrollbar_height) + var(--pin_height) + 33px); left: calc(810px - var(--scrollbar_width)); @@ -602,7 +602,7 @@ ul:not(.menu) li { left: 20px; top: calc(var(--scrollbar_height) + var(--pin_height) + 33px); width: 19px; - height: 850px; + height: calc(100% - var(--pin_height) - 80px); background-color: var(--group_list_background); border-right: 1px solid var(--group_list_borders); overflow: visible; diff --git a/options/options.html b/options/options.html new file mode 100644 index 0000000..dc3a213 --- /dev/null +++ b/options/options.html @@ -0,0 +1,905 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Tree Tabs
+
+ + + + +
+ + + + + + + + + + + + + + + + + +
-
-
-
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + +
-
-
-
-
+
    +
  • + + +
  • +
  • + + +
  • +
+
+ + + +
+ +
    +
  • + + +
  • +
  • + + +
  • +
+ +
+ + + +
+ +
    +
  • + + +
  • +
  • + + +
  • +
+ + + + + + + + + + + + + + + + +
-
-
-
+ +

+
    +
  • +
  • +
  • + +
  • +
  • +
+
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + + +
  • + + + + + + + +
  • + + +
  • +
  • + + +
  • +
  • +
    +
    + + + + + +
    + +
  • +
  • + + +
  • +
+ + + + + + +
+ + -
+ + + + + + +
-
+ + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-
-
-
-
-
-
-
-
-
-
+
+ + +
+ + + + + + + +
+
+ +
+
+ + + +
+ + + +
+ + + + + + + + + + +
+
+ +
+ + + +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+ +
+
+
+ + + + +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+ +
+ +
+
+
+
+
+ +
+
+ + + +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + +
+ +
+ + +
+ + + + + + +
+
+ + +
+ + + + + + + +
+ -
+
+ + +
+ Your language is not available? Can you help? Translate here. +
+ Themes +
+ Forum +
+ Support Email +
+ Report a bug +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/options/options.js b/options/options.js index 43bd70c..9f06ee2 100644 --- a/options/options.js +++ b/options/options.js @@ -1,1081 +1,1266 @@ -// 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/ - // ********** OPTIONS *************** var current_theme = ""; var themes = []; var SelectedTheme = Object.assign({}, DefaultTheme); -var dragged_button = {id: ""}; +var dragged_button = { id: "" }; +let tt = { + CurrentWindowId: 0, + active_group: "tab_list", + tabs: {}, + groups: {}, + folders: {} +}; // options for all drop down menus -let DropDownList = ["dbclick_folder", "midclick_folder", "midclick_tab", "dbclick_group", "midclick_group", "dbclick_tab", "append_child_tab", "append_child_tab_after_limit", "append_orphan_tab", "append_tab_from_toolbar", "after_closing_active_tab", "move_tabs_on_url_change"]; +let DropDownList = ["dbclick_folder", "midclick_folder", "midclick_tab", "dbclick_group", "midclick_group", "dbclick_tab", "append_pinned_tab", "append_child_tab", "append_child_tab_after_limit", "append_orphan_tab", "append_tab_from_toolbar", "after_closing_active_tab", "move_tabs_on_url_change"]; document.addEventListener("DOMContentLoaded", function() { - document.title = "Tree Tabs"; - chrome.storage.local.get(null, function(storage) { - - AppendGroupToList("tab_list", labels.ungrouped_group, "", false); - AppendGroupToList("tab_list2", labels.noname_group, "", false); - AppendSampleTabs(); - - GetCurrentPreferences(storage); + document.title = "Tree Tabs"; + chrome.storage.local.get(null, function(storage) { - if (storage["themes"]) { - for (var themeName in storage["themes"]) { - themes.push(themeName); - } - } - if (storage["current_theme"]) { - current_theme = storage["current_theme"]; - LoadTheme(storage["current_theme"]); - } - + Groups_AppendGroupToList("tab_list", labels.ungrouped_group, "", false); + Groups_AppendGroupToList("tab_list2", labels.noname_group, "", false); + AppendSampleTabs(); - if (storage["unused_buttons"]) { - RecreateToolbarUnusedButtons(storage["unused_buttons"]); - } + Preferences_GetCurrentPreferences(storage); - RecreateToolbar(GetCurrentToolbar(storage)); - SetToolbarEvents(false, false, true, "click"); - AddEditToolbarEditEvents(); + if (storage["themes"]) { + for (var themeName in storage["themes"]) { + themes.push(themeName); + } + } + if (storage["current_theme"]) { + current_theme = storage["current_theme"]; + Theme_LoadTheme(storage["current_theme"]); + } - - GetOptions(storage); - RefreshFields(); - SetEvents(); - - setTimeout(function() { - document.querySelectorAll(".on").forEach(function(s){ - s.classList.remove("on"); - }); - RefreshGUI(); - }, 100); - }); + if (storage["unused_buttons"]) { + Toolbar_RecreateToolbarUnusedButtons(storage["unused_buttons"]); + } + + Toolbar_RecreateToolbar(Theme_GetCurrentToolbar(storage)); + Toolbar_SetToolbarEvents(false, false, true, "click", false, true); + AddEditToolbarEditEvents(); + + + GetOptions(storage); + RefreshFields(); + SetEvents(); + + + setTimeout(function() { + document.querySelectorAll(".on").forEach(function(s) { + s.classList.remove("on"); + }); + RefreshGUI(); + }, 100); + }); }); function SetRegexes() { - let regexes = document.getElementById('tab_group_regexes'); - opt.tab_group_regexes = []; - for (let child of regexes.children) { - var regex = child.children[0].value.trim(); - var groupName = child.children[1].value.trim(); - if (regex !== "" && groupName !== "") { - opt.tab_group_regexes.push([regex, groupName]); - } - } - SavePreferences(); + let regexes = document.getElementById('tab_group_regexes'); + opt.tab_group_regexes = []; + for (let child of regexes.children) { + var regex = child.children[0].value.trim(); + var groupName = child.children[1].value.trim(); + if (regex !== "" && groupName !== "") { + opt.tab_group_regexes.push([regex, groupName]); + } + } + Preferences_SavePreferences(opt); } function AddRegexPair() { - let regexes = document.getElementById('tab_group_regexes'); - let outer = document.createElement("div"); + let regexes = document.getElementById('tab_group_regexes'); + let outer = document.createElement("div"); - let input = document.createElement("input"); - input.type = "text"; - input.style.width = '200px'; - input.onchange = SetRegexes; - input.onkeyup = SetRegexes; - outer.appendChild(input); + let input = document.createElement("input"); + input.type = "text"; + input.style.width = '200px'; + input.onchange = SetRegexes; + input.onkeyup = SetRegexes; + outer.appendChild(input); - input = document.createElement("input"); - input.type = "text"; - input.style.width = '200px'; - input.onchange = SetRegexes; - input.onkeyup = SetRegexes; - outer.appendChild(input); - - let deleteButton = document.createElement("input"); - deleteButton.type = "button"; - deleteButton.style.width = '75px'; - deleteButton.className = "set_button theme_buttons"; - deleteButton.value = chrome.i18n.getMessage("options_Remove_button"); - deleteButton.onclick = function() { regexes.removeChild(outer); } - outer.appendChild(deleteButton); - - regexes.appendChild(outer); - return outer; + input = document.createElement("input"); + input.type = "text"; + input.style.width = '200px'; + input.onchange = SetRegexes; + input.onkeyup = SetRegexes; + outer.appendChild(input); + + let deleteButton = document.createElement("input"); + deleteButton.type = "button"; + deleteButton.style.width = '75px'; + deleteButton.className = "set_button theme_buttons"; + deleteButton.value = chrome.i18n.getMessage("options_Remove_button"); + deleteButton.onclick = function() { regexes.removeChild(outer); } + outer.appendChild(deleteButton); + + regexes.appendChild(outer); + return outer; } // document events function GetOptions(storage) { - // get language labels - document.querySelectorAll(".label, .set_button, .bg_opt_drop_down_menu, .hint_explanation").forEach(function(s){ - s.textContent = chrome.i18n.getMessage(s.id); - }); + // get language labels + document.querySelectorAll(".label, .set_button, .bg_opt_drop_down_menu, .hint_explanation").forEach(function(s) { + s.textContent = chrome.i18n.getMessage(s.id); + }); - // get language for menu labels - document.querySelectorAll(".menu_item").forEach(function(s){ - s.textContent = chrome.i18n.getMessage("options_example_menu_item"); - }); - - // get checkboxes from saved states - document.querySelectorAll(".opt_checkbox").forEach(function(s){ - s.checked = opt[s.id]; - if (s.checked) { - if (s.id == "never_show_close") { - document.getElementById("always_show_close").disabled = true; - } - } else { - if (s.id == "promote_children") { - document.getElementById("promote_children_in_first_child").disabled = true; - } - } - }); - - // get language labels - document.querySelectorAll(".pick_col, #close_x, #close_hover_x, .options_button_minus, .options_button_plus, .tabs_margin_spacing").forEach(function(s){ - s.title = chrome.i18n.getMessage(s.id); - }); - + // get language for menu labels + document.querySelectorAll(".menu_item").forEach(function(s) { + s.textContent = chrome.i18n.getMessage("options_example_menu_item"); + }); - // get options for all drop down menus (loop through all drop down items that are in DropDownList array) - for (let i = 0; i < DropDownList.length; i++) { - let DropDownOption = document.getElementById(DropDownList[i]); - for (let j = 0; j < DropDownOption.options.length; j++) { - if (DropDownOption.options[j].value == opt[DropDownList[i]]) { - DropDownOption.selectedIndex = j; - break; - } - } - RefreshFields(); - } - - for (let i = 0; i < opt.tab_group_regexes.length; i++) { - let regexPair = opt.tab_group_regexes[i]; - let outer = AddRegexPair(); - outer.children[0].value = regexPair[0]; - outer.children[1].value = regexPair[1] - } + // get checkboxes from saved states + document.querySelectorAll(".opt_checkbox").forEach(function(s) { + s.checked = opt[s.id]; + if (s.checked) { + if (s.id == "never_show_close") { + document.getElementById("always_show_close").disabled = true; + } + } else { + if (s.id == "promote_children") { + document.getElementById("promote_children_in_first_child").disabled = true; + } + } + }); - // get options for tabs tree depth option - document.getElementById("max_tree_depth").value = opt.max_tree_depth; + // get language labels + document.querySelectorAll(".pick_col, #close_x, #close_hover_x, .options_button_minus, .options_button_plus, .tabs_margin_spacing").forEach(function(s) { + s.title = chrome.i18n.getMessage(s.id); + }); - // append themes to dropdown menu - let ThemeList = document.getElementById("theme_list"); - for (var i = 0; i < themes.length; i++) { - let theme_name = document.createElement("option"); - theme_name.value = themes[i]; - theme_name.text = storage.themes[themes[i]].theme_name; - ThemeList.add(theme_name); - } - // select current theme in dropdown list - for (var i = 0; i < ThemeList.options.length; i++) { - if (ThemeList.options[i].value == current_theme) { - ThemeList.selectedIndex = i; - break; - } - } + // get options for all drop down menus (loop through all drop down items that are in DropDownList array) + for (let i = 0; i < DropDownList.length; i++) { + let DropDownOption = document.getElementById(DropDownList[i]); + for (let j = 0; j < DropDownOption.options.length; j++) { + if (DropDownOption.options[j].value == opt[DropDownList[i]]) { + DropDownOption.selectedIndex = j; + break; + } + } + RefreshFields(); + } + + for (let i = 0; i < opt.tab_group_regexes.length; i++) { + let regexPair = opt.tab_group_regexes[i]; + let outer = AddRegexPair(); + outer.children[0].value = regexPair[0]; + outer.children[1].value = regexPair[1] + } + + // get options for tabs tree depth option + document.getElementById("max_tree_depth").value = opt.max_tree_depth; + + + // append themes to dropdown menu + let ThemeList = document.getElementById("theme_list"); + for (var i = 0; i < themes.length; i++) { + let theme_name = document.createElement("option"); + theme_name.value = themes[i]; + theme_name.text = storage.themes[themes[i]].theme_name; + ThemeList.add(theme_name); + } + // select current theme in dropdown list + for (var i = 0; i < ThemeList.options.length; i++) { + if (ThemeList.options[i].value == current_theme) { + ThemeList.selectedIndex = i; + break; + } + } } function RemovePreview() { - document.querySelectorAll(".hover_blinking").forEach(function(s){s.classList.remove("hover_blinking");}); - document.querySelectorAll(".hover_border_blinking").forEach(function(s){s.classList.remove("hover_border_blinking");}); - document.querySelectorAll(".red_preview").forEach(function(s){ - s.style.backgroundColor = ""; - s.style.border = ""; - s.style.borderBottom = ""; - s.style.borderRight = ""; - s.style.color = ""; - s.style.animation = ""; - s.style.fontWeight = ""; - s.style.fontStyle = ""; - // s.style.zIndex = ""; - s.classList.remove("red_preview"); - }); + document.querySelectorAll(".hover_blinking").forEach(function(s) { s.classList.remove("hover_blinking"); }); + document.querySelectorAll(".hover_border_blinking").forEach(function(s) { s.classList.remove("hover_border_blinking"); }); + document.querySelectorAll(".red_preview").forEach(function(s) { + s.style.backgroundColor = ""; + s.style.border = ""; + s.style.borderBottom = ""; + s.style.borderRight = ""; + s.style.color = ""; + s.style.animation = ""; + s.style.fontWeight = ""; + s.style.fontStyle = ""; + // s.style.zIndex = ""; + s.classList.remove("red_preview"); + }); } function AddRedStylePreview(Id, style, value, removePreview) { - if (removePreview) RemovePreview(); - let d = document.getElementById(Id); - d.classList.add("red_preview"); - d.style[style] = value; + if (removePreview) RemovePreview(); + let d = document.getElementById(Id); + d.classList.add("red_preview"); + d.style[style] = value; } function AddBlueBackgroundPreview(Id, removePreview) { - if (removePreview) RemovePreview(); - document.getElementById(Id).classList.add("hover_blinking"); + if (removePreview) RemovePreview(); + document.getElementById(Id).classList.add("hover_blinking"); } + function AddBlueBorderPreview(Id, removePreview) { - if (removePreview) RemovePreview(); - document.getElementById(Id).classList.add("hover_border_blinking"); + if (removePreview) RemovePreview(); + document.getElementById(Id).classList.add("hover_border_blinking"); } // document events function SetEvents() { -// --------------------------------DONATIONS----------------------------------------------------------------------------- - - document.getElementById("donate_paypal").onclick = function(event) {if (event.which == 1) { - chrome.tabs.create({url: "https://www.paypal.me/KarolJagiello/1"}); - }} - document.getElementById("donate_litecoin").onclick = function(event) {if (event.which == 1) { - copyStringToClipboard("LdQ1ZH1CgSneBbmmVBFrg5BFDFHZMa6h76"); - alert(chrome.i18n.getMessage("options_copied_wallet_address")); - }} - document.getElementById("donate_bitcoin").onclick = function(event) {if (event.which == 1) { - copyStringToClipboard("19Z8w1RJEcBQpKSdiWa3UTBuKRJUkr96nJ"); - alert(chrome.i18n.getMessage("options_copied_wallet_address")); - }} - document.getElementById("donate_ethereum").onclick = function(event) {if (event.which == 1) { - copyStringToClipboard("0x70B05eAD03bF08220d5aF4E1E868C351bfe145D6"); - alert(chrome.i18n.getMessage("options_copied_wallet_address")); - }} - -// --------------------------------COPY VIVALDI LINK---------------------------------------------------------------------- - - document.getElementById("copy_vivaldi_url_for_web_panel").onclick = function(event) {if (event.which == 1) { - copyStringToClipboard(chrome.runtime.getURL("sidebar.html")); - alert(chrome.i18n.getMessage("options_vivaldi_copied_url")); - }} - -// --------------------------------ADD RED AND BLUE PREVIEWS--------------------------------------------------------------- - // document.body.onmousedown = function(event) { - // if (event.which == 1 && (event.target.id || event.target.classList)) { - // console.log(event.target); - // } - // } - - - document.querySelectorAll("#scrollbar_thumb_hover, #options_tab_list_scrollbar_height_up, #options_tab_list_scrollbar_height_down, #options_tab_list_scrollbar_width_up, #options_tab_list_scrollbar_width_down, .pick_col, .font_weight_normal, .font_weight_bold, .font_style_normal, .font_style_italic, #filter_box_font").forEach(function(s){s.onmouseleave = function(event) { - RemovePreview(); - }}); - - // toolbar buttons - document.getElementById("button_background").onmouseenter = function(event) { - AddRedStylePreview("button_theme_plus", "backgroundColor", "red", true); - } - document.getElementById("button_hover_background").onmouseenter = function(event) { - AddBlueBackgroundPreview("button_theme_plus", true); - } - - document.getElementById("button_on_background").onmouseenter = function(event) { - AddRedStylePreview("button_theme_search", "backgroundColor", "red", true); - } - - document.getElementById("button_icons").onmouseenter = function(event) { - AddRedStylePreview("button_theme_plus_img", "backgroundColor", "red", true); - } - document.getElementById("button_icons_hover").onmouseenter = function(event) { - AddBlueBackgroundPreview("button_theme_plus_img", true); - } - document.getElementById("button_on_icons").onmouseenter = function(event) { - AddRedStylePreview("button_theme_search_img", "backgroundColor", "red", true); - } - - document.getElementById("button_border").onmouseenter = function(event) { - AddRedStylePreview("button_theme_plus", "border", "1px solid red", true); - } - document.getElementById("button_hover_border").onmouseenter = function(event) { - AddBlueBorderPreview("button_theme_plus", true); - } - - - // search box - document.getElementById("filter_box_font").onmouseenter = function(event) { - AddRedStylePreview("filter_box_theme", "color", "red", true); - } - document.getElementById("filter_box_background").onmouseenter = function(event) { - AddRedStylePreview("filter_box_theme", "backgroundColor", "red", true); - } - document.getElementById("filter_box_border").onmouseenter = function(event) { - AddRedStylePreview("filter_box_theme", "border", "1px solid red", true); - } - document.getElementById("filter_clear_icon").onmouseenter = function(event) { - AddRedStylePreview("button_filter_clear_theme", "backgroundColor", "red", true); - } - - // toolbar background - document.getElementById("toolbar_background").onmouseenter = function(event) { - AddRedStylePreview("toolbar_main_theme", "backgroundColor", "red", true); - } - - // shelf toolbar background - document.getElementById("toolbar_shelf_background").onmouseenter = function(event) { - AddRedStylePreview("toolbar_search_input_box_theme", "backgroundColor", "red", true); - } - - // toolbar's border - document.getElementById("toolbar_border_bottom").onmouseenter = function(event) { - AddRedStylePreview("button_theme_search", "border", "1px solid red", true); - AddRedStylePreview("toolbar_main_theme", "borderBottom", "1px solid red"); - AddRedStylePreview("toolbar_theme", "borderBottom", "1px solid red"); - } - - // shelf toolbar buttons - document.getElementById("button_shelf_background").onmouseenter = function(event) { - AddRedStylePreview("button_theme_pen", "backgroundColor", "red", true); - } - document.getElementById("button_shelf_hover_background").onmouseenter = function(event) { - AddBlueBackgroundPreview("button_theme_pen", true); - } - document.getElementById("button_shelf_icons").onmouseenter = function(event) { - AddRedStylePreview("button_theme_pen_img", "backgroundColor", "red", true); - } - document.getElementById("button_shelf_icons_hover").onmouseenter = function(event) { - AddBlueBackgroundPreview("button_theme_pen_img", true); - } - document.getElementById("button_shelf_border").onmouseenter = function(event) { - AddRedStylePreview("button_theme_pen", "border", "1px solid red", true); - } - document.getElementById("button_shelf_hover_border").onmouseenter = function(event) { - AddBlueBorderPreview("button_theme_pen", true); - } - - // pinned tab attention_background - document.getElementById("attention_background").onmouseenter = function(event) { - AddRedStylePreview("tab_header10", "backgroundColor", "red", true); - document.getElementById("tab_header10").style.animation = "none"; - } - - // pinned tab attention_border - document.getElementById("attention_border").onmouseenter = function(event) { - AddRedStylePreview("tab_header10", "border", "1px solid red", true); - document.getElementById("tab_header10").style.animation = "none"; - } - - // pin_list border bottom - document.getElementById("pin_list_border_bottom").onmouseenter = function(event) { - AddRedStylePreview("pin_list", "borderBottom", "1px solid red", true); - } - - // pin_list background - document.getElementById("pin_list_background").onmouseenter = function(event) { - AddRedStylePreview("pin_list", "backgroundColor", "red", true); - } - - - // tab row font_color - document.querySelectorAll(".tab_col.font_color").forEach(function(s){s.onmouseenter = function(event) { - AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "color", "red", true); - }}); - - // tab row font not bold - document.querySelectorAll(".tab_col.font_weight_normal").forEach(function(s){s.onmouseenter = function(event) { - AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "color", "red", true); - AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "fontWeight", "normal", false); - }}); - - // tab row font bold - document.querySelectorAll(".tab_col.font_weight_bold").forEach(function(s){s.onmouseenter = function(event) { - AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "color", "red", true); - AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "fontWeight", "bold", false); - }}); - - // tab row font style normal - document.querySelectorAll(".tab_col.font_style_normal").forEach(function(s){s.onmouseenter = function(event) { - AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "color", "red", true); - AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "fontStyle", "normal", false); - }}); - // tab row font style italic - document.querySelectorAll(".tab_col.font_style_italic").forEach(function(s){s.onmouseenter = function(event) { - AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "color", "red", true); - AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "fontStyle", "italic", false); - }}); - - - // tab border - document.querySelectorAll(".tab_col.color_border").forEach(function(s){s.onmouseenter = function(event) { - AddRedStylePreview("tab_header" + this.parentNode.id.substr(1), "border", "1px solid red", true); - }}); - - // tab background - document.querySelectorAll(".tab_col.color_bucket").forEach(function(s){s.onmouseenter = function(event) { - AddRedStylePreview("tab_header" + this.parentNode.id.substr(1), "backgroundColor", "red", true); - }}); - - // scrollbars hover - document.getElementById("scrollbar_thumb_hover").onmouseenter = function(event) { - AddBlueBackgroundPreview("group_scrollbar_thumb", true); - AddBlueBackgroundPreview("pin_list_scrollbar_thumb"); - } - - // scrollbars thumb - document.getElementById("scrollbar_thumb").onmouseenter = function(event) { - AddRedStylePreview("group_scrollbar_thumb", "backgroundColor", "red", true); - AddRedStylePreview("pin_list_scrollbar_thumb", "backgroundColor", "red"); - } - - - // scrollbars track - document.getElementById("scrollbar_track").onmouseenter = function(event) { - AddRedStylePreview("group_scrollbar", "backgroundColor", "red", true); - AddRedStylePreview("pin_list_scrollbar", "backgroundColor", "red"); - } - - - // tab_list scrollbars - document.querySelectorAll("#options_tab_list_scrollbar_width_up, #options_tab_list_scrollbar_width_down").forEach(function(s){s.onmouseenter = function(event) { - AddRedStylePreview("group_scrollbar", "backgroundColor", "red", true); - AddRedStylePreview("group_scrollbar_thumb", "backgroundColor", "red"); - }}); - - // pin_list scrollbars - document.querySelectorAll("#options_tab_list_scrollbar_height_up, #options_tab_list_scrollbar_height_down").forEach(function(s){s.onmouseenter = function(event) { - AddRedStylePreview("pin_list_scrollbar", "backgroundColor", "red", true); - AddRedStylePreview("pin_list_scrollbar_thumb", "backgroundColor", "red"); - }}); - - - - // folder icon open - document.getElementById("folder_icon_open").onmouseenter = function(event) { - AddRedStylePreview("fopf_folder1", "backgroundColor", "red", true); - } - // folder icon closed - document.getElementById("folder_icon_closed").onmouseenter = function(event) { - AddRedStylePreview("fopf_folder2", "backgroundColor", "red", true); - } - // folder icon hover - document.getElementById("folder_icon_hover").onmouseenter = function(event) { - AddBlueBackgroundPreview("fopf_folder3", true); - } - - - // tab expand closed - document.getElementById("expand_closed_background").onmouseenter = function(event) { - AddRedStylePreview("exp14", "backgroundColor", "red", true); - } - // tab expand hover - document.getElementById("expand_hover_background").onmouseenter = function(event) { - AddBlueBackgroundPreview("exp16", true); - } - // tab expand open - document.getElementById("expand_open_background").onmouseenter = function(event) { - AddRedStylePreview("exp5", "backgroundColor", "red", true); - } - - - - - - // drag indicator - document.getElementById("drag_indicator").onmouseenter = function(event) { - AddRedStylePreview("di19", "borderBottom", "1px solid red", true); - } - - - // close x - document.getElementById("close_x").onmouseenter = function(event) { - AddRedStylePreview("close_img11", "backgroundColor", "red", true); - } - // close x hover - document.getElementById("close_hover_x").onmouseenter = function(event) { - AddBlueBackgroundPreview("close_img13", true); - } - // close border hover - document.getElementById("close_hover_border").onmouseenter = function(event) { - AddBlueBorderPreview("close13", true); - } - // close border hover - document.getElementById("close_hover_background").onmouseenter = function(event) { - AddBlueBackgroundPreview("close13", true); - } - - - - - // group button hover - document.getElementById("group_list_button_hover_background").onmouseenter = function(event) { - AddBlueBackgroundPreview("_tab_list2", true); - } - // group buttons borders - document.getElementById("group_list_borders").onmouseenter = function(event) { - AddRedStylePreview("toolbar_groups_block", "borderRight", "1px solid red", true); - AddRedStylePreview("_tab_list", "border", "1px solid red"); - } - // group buttons font - document.getElementById("group_list_default_font_color").onmouseenter = function(event) { - AddRedStylePreview("_gtetab_list", "color", "red", true); - AddRedStylePreview("_gtetab_list2", "color", "red"); - } - // group list background - document.getElementById("group_list_background").onmouseenter = function(event) { - AddRedStylePreview("toolbar_groups_block", "backgroundColor", "red", true); - } - // tab_list background - document.getElementById("tab_list_background").onmouseenter = function(event) { - AddRedStylePreview("tab_list", "backgroundColor", "red", true); - AddRedStylePreview("_tab_list", "backgroundColor", "red"); - } - - - - - - // menu hover border - document.getElementById("tabs_menu_hover_border").onmouseenter = function(event) { - AddRedStylePreview("menu_hover_sample", "border", "1px solid red", true); - } - // menu hover background - document.getElementById("tabs_menu_hover_background").onmouseenter = function(event) { - AddRedStylePreview("menu_hover_sample", "backgroundColor", "red", true); - } - - // menu separator - document.getElementById("tabs_menu_separator").onmouseenter = function(event) { - AddRedStylePreview("menu_separator1", "backgroundColor", "red", true); - AddRedStylePreview("menu_separator2", "backgroundColor", "red"); - } - - // menu font - document.getElementById("tabs_menu_font").onmouseenter = function(event) { - AddRedStylePreview("menu_hover_sample", "color", "red", true); - AddRedStylePreview("menu_sample1", "color", "red"); - AddRedStylePreview("menu_sample2", "color", "red"); - } - - - // menu border - document.getElementById("tabs_menu_border").onmouseenter = function(event) { - AddRedStylePreview("tabs_menu", "border", "1px solid red", true); - } - - // menu background - document.getElementById("tabs_menu_background").onmouseenter = function(event) { - AddRedStylePreview("tabs_menu", "backgroundColor", "red", true); - } - - - -// --------------------------------------COLOR PICKER--------------------------------------------------------------------- - - // change fonts weight && style - document.querySelectorAll(".font_weight_normal, .font_weight_bold, .font_style_normal, .font_style_italic").forEach(function(s){s.onmousedown = function(event) { - event.stopPropagation(); - // if this.classList.contains("font_weight_normal") || this.classList.contains("font_style_normal") - let FontStyle = "normal"; - if (this.classList.contains("font_weight_bold")) { - FontStyle = "bold"; - } - if (this.classList.contains("font_style_italic")) { - FontStyle = "italic"; - } - SelectedTheme["ColorsSet"][this.id] = FontStyle; - ApplyColorsSet(SelectedTheme["ColorsSet"]); - SaveTheme(document.getElementById("theme_list").value); - }}); - - // show color picker - document.querySelectorAll(".pick_col").forEach(function(s){s.onclick = function(event) {if (event.which == 1) { - RemovePreview(); - event.stopPropagation(); - let bod = document.getElementById("body"); - let color = window.getComputedStyle(bod, null).getPropertyValue("--"+this.id); - let ColorPicker = document.getElementById("color_picker"); - ColorPicker.setAttribute("PickColor", this.id); - ColorPicker.value = color.replace(" ", ""); - ColorPicker.click(); - }}}); - - document.getElementById("color_picker").oninput = function(event) { - let ColorPicker = document.getElementById("color_picker"); - SelectedTheme["ColorsSet"][this.getAttribute("PickColor")] = ColorPicker.value; - ApplyColorsSet(SelectedTheme["ColorsSet"]); - // SaveTheme(document.getElementById("theme_list").value); - } - document.getElementById("color_picker").onchange = function(event) { - SaveTheme(document.getElementById("theme_list").value); - } - - -// ----------------------------------EVENTS FOR CHECKBOXES AND DROPDOWN MENUS--------------------------------------------- - - // set checkbox options on/off and save - document.querySelectorAll(".bg_opt").forEach(function(s){s.onclick = function(event) {if (event.which == 1) { - opt[this.id] = this.checked ? true : false; - if (this.checked) { - if (this.id == "never_show_close") { - document.getElementById("always_show_close").disabled = true; - } - if (this.id == "promote_children") { - document.getElementById("promote_children_in_first_child").disabled = false; - } - } else { - if (this.id == "never_show_close") { - document.getElementById("always_show_close").disabled = false; - } - if (this.id == "promote_children") { - document.getElementById("promote_children_in_first_child").disabled = true; - } - } - SavePreferences(); - if (this.id == "show_toolbar") { - SaveToolbar(); - RefreshFields(); - - - // setTimeout(function() { - // chrome.runtime.sendMessage({command: "reload_toolbar", toolbar: toolbar, opt: opt}); - // }, 300); - } - }}}); - - - // options that need reload - document.onclick = function(event) {if (event.which == 1) { - if (event.target.id == "syncro_tabbar_tabs_order" || event.target.id == "allow_pin_close" || event.target.id == "switch_with_scroll" || event.target.id == "always_show_close" || event.target.id == "never_show_close" || event.target.id == "hide_other_groups_tabs_firefox" || - event.target.id == "collapse_other_trees" || event.target.id == "show_counter_tabs" || event.target.id == "show_counter_tabs_hints" || event.target.id == "syncro_tabbar_tabs_order" || event.target.id == "syncro_tabbar_groups_tabs_order" || event.target.id == "groups_toolbar_default") { - setTimeout(function() { - chrome.runtime.sendMessage({command: "reload_sidebar"}); - }, 50); - } - if (event.target.id == "groups_toolbar_default") { - chrome.runtime.sendMessage({command: "reload"}); - setTimeout(function() { - location.reload(); - }, 300); - } - }} - - // set dropdown menu options - for (let i = 0; i < DropDownList.length; i++) { - document.getElementById(DropDownList[i]).onchange = function(event) { - opt[this.id] = this.value; - RefreshFields(); - setTimeout(function() { - SavePreferences(); - // chrome.runtime.sendMessage({command: "reload_sidebar"}); - }, 50); - } - } - - // set tabs tree depth option - document.getElementById("max_tree_depth").oninput = function(event) { - opt.max_tree_depth = parseInt(this.value); - setTimeout(function() { - SavePreferences(); - }, 50); - } - - // set toolbar on/off and show/hide all toolbar options - // document.getElementById("show_toolbar").onclick = function(event) {if (event.which == 1) { - // SelectedTheme.ToolbarShow = this.checked ? true : false; - // RefreshFields(); - // SaveTheme(document.getElementById("theme_list").value); - // }} - - -// ------------------------------OTHER----------------------------------------------------------------------------------- - - // block system dragging - document.ondrop = function(event) { - event.preventDefault(); - } - document.ondragover = function(event) { - event.preventDefault(); - } - -// ------------------------------ADD REGEX FILTER------------------------------------------------------------------------- - - document.getElementById("add_tab_group_regex").onclick = AddRegexPair; - -// ----------------------------RESET TOOLBAR BUTTON----------------------------------------------------------------------- - - document.getElementById("options_reset_toolbar_button").onclick = function(event) {if (event.which == 1) { - - SetToolbarEvents(true, false, false, ""); - RemoveToolbarEditEvents(); - - - let unused_buttons = document.getElementById("toolbar_unused_buttons"); - while(unused_buttons.hasChildNodes()) { - unused_buttons.removeChild(unused_buttons.firstChild); - } - - RemoveToolbar(); - RecreateToolbar(DefaultToolbar); - SetToolbarEvents(false, false, true, "click"); - AddEditToolbarEditEvents(); - - SaveToolbar(); - - - }} - - -// --------------------------------------THEME BUTTONS-------------------------------------------------------------------- - - - // add new theme preset button - document.getElementById("options_add_theme_button").onclick = function(event) {if (event.which == 1) { - AddNewTheme(); - }} - - // remove theme preset button - document.getElementById("options_remove_theme_button").onclick = function(event) {if (event.which == 1) { - DeleteSelectedTheme(); - }} - - // select theme from list - document.getElementById("theme_list").onchange = function(event) { - LoadTheme(this.value, true); - chrome.storage.local.set({current_theme: this.value}); - } - - // import theme preset button - document.getElementById("options_import_theme_button").onclick = function(event) {if (event.which == 1) { - let inputFile = ShowOpenFileDialog(".tt_theme"); - inputFile.onchange = function(event) { - ImportTheme(); - } - }} - - // export theme preset button - document.getElementById("options_export_theme_button").onclick = function(event) {if (event.which == 1) { - let ThemeList = document.getElementById("theme_list"); - if (ThemeList.options.length == 0) { - alert(chrome.i18n.getMessage("options_no_theme_to_export")); - } else { - SaveFile(ThemeList.options[ThemeList.selectedIndex].text, "tt_theme", SelectedTheme); - } - }} - - // rename theme preset button - document.getElementById("options_rename_theme_button").onclick = function(event) {if (event.which == 1) { - RenameSelectedTheme(); - }} - // get themes - document.getElementById("options_share_theme_link").onclick = function(event) {if (event.which == 1) { - chrome.tabs.create({url: "https://drive.google.com/drive/folders/0B3jXQpRtOfvSelFrTEVHZEx3Nms?usp=sharing"}); - }} - - -// -------------------------------INDENTATION ADJUSTMENT------------------------------------------------------------------ - - // change tabs size preset(down) - document.getElementById("options_tabs_indentation_down").onmousedown = function(event) { - let bod = document.getElementById("body"); - var indentation = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--children_padding_left")).replace("p","").replace("x","")); - if (indentation > 0) { - indentation--; - SelectedTheme["ColorsSet"]["children_padding_left"] = indentation+"px"; - ApplyColorsSet(SelectedTheme["ColorsSet"]); - SaveTheme(document.getElementById("theme_list").value); - } - } - - // change tabs size preset(up) - document.getElementById("options_tabs_indentation_up").onmousedown = function(event) { - let bod = document.getElementById("body"); - var indentation = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--children_padding_left")).replace("p","").replace("x","")); - if (indentation < 50) { - indentation++; - SelectedTheme["ColorsSet"]["children_padding_left"] = indentation+"px"; - ApplyColorsSet(SelectedTheme["ColorsSet"]); - SaveTheme(document.getElementById("theme_list").value); - } - } - - -// --------------------------TABS ROUNDNESS ADJUSTMENT-------------------------------------------------------------------- - - // change tabs roundness preset(down) - document.getElementById("options_tabs_roundness_down").onmousedown = function(event) { - let bod = document.getElementById("body"); - var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--tab_header_border_radius").replace("p","").replace("x",""))); - if (border_radius > 0) { - border_radius--; - SelectedTheme["ColorsSet"]["tab_header_border_radius"] = border_radius+"px"; - ApplyColorsSet(SelectedTheme["ColorsSet"]); - SaveTheme(document.getElementById("theme_list").value); - } - } - - // change tabs roundness preset(up) - document.getElementById("options_tabs_roundness_up").onmousedown = function(event) { - let bod = document.getElementById("body"); - var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--tab_header_border_radius")).replace("p","").replace("x","")); - if (border_radius < 25) { - border_radius++; - SelectedTheme["ColorsSet"]["tab_header_border_radius"] = border_radius+"px"; - ApplyColorsSet(SelectedTheme["ColorsSet"]); - SaveTheme(document.getElementById("theme_list").value); - } - } - -// -------------------------------SIZE ADJUSTMENT------------------------------------------------------------------------- - - // set tabs margins - document.getElementById("tabs_margin_spacing").onchange = function(event) { - let size = "0"; - if (this[1].checked) { - size = "1"; - } else { - if (this[2].checked) { - size = "2"; - } - } - SelectedTheme["TabsMargins"] = size; - ApplyTabsMargins(size); - SaveTheme(document.getElementById("theme_list").value); - } - - - // change tabs size preset(down) - document.getElementById("options_tabs_size_down").onmousedown = function(event) { - if (SelectedTheme["TabsSizeSetNumber"] > 0) { - SelectedTheme["TabsSizeSetNumber"]--; - ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]); - SaveTheme(document.getElementById("theme_list").value); - } - } - - // change tabs size preset(up) - document.getElementById("options_tabs_size_up").onmousedown = function(event) { - if (SelectedTheme["TabsSizeSetNumber"] < 4) { - SelectedTheme["TabsSizeSetNumber"]++; - ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]); - SaveTheme(document.getElementById("theme_list").value); - } - } - - -// -------------------------------TABS SCROLLBAR SIZE ADJUSTMENT---------------------------------------------------------- - - // change tab list scrollbar preset(down) - document.getElementById("options_tab_list_scrollbar_width_down").onmousedown = function(event) { - let bod = document.getElementById("body"); - var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--scrollbar_width").replace("p","").replace("x",""))); - if (border_radius > 0) { - border_radius--; - SelectedTheme["ColorsSet"]["scrollbar_width"] = border_radius+"px"; - ApplyColorsSet(SelectedTheme["ColorsSet"]); - SaveTheme(document.getElementById("theme_list").value); - } - } - - // change tab list scrollbar preset(up) - document.getElementById("options_tab_list_scrollbar_width_up").onmousedown = function(event) { - let bod = document.getElementById("body"); - var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--scrollbar_width")).replace("p","").replace("x","")); - if (border_radius < 20) { - border_radius++; - SelectedTheme["ColorsSet"]["scrollbar_width"] = border_radius+"px"; - ApplyColorsSet(SelectedTheme["ColorsSet"]); - SaveTheme(document.getElementById("theme_list").value); - } - } - - // change pin list scrollbar preset(down) - document.getElementById("options_tab_list_scrollbar_height_down").onmousedown = function(event) { - let bod = document.getElementById("body"); - var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--scrollbar_height").replace("p","").replace("x",""))); - if (border_radius > 0) { - border_radius--; - SelectedTheme["ColorsSet"]["scrollbar_height"] = border_radius+"px"; - ApplyColorsSet(SelectedTheme["ColorsSet"]); - SaveTheme(document.getElementById("theme_list").value); - } - } - - // change pin list scrollbar preset(up) - document.getElementById("options_tab_list_scrollbar_height_up").onmousedown = function(event) { - let bod = document.getElementById("body"); - var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--scrollbar_height")).replace("p","").replace("x","")); - if (border_radius < 20) { - border_radius++; - SelectedTheme["ColorsSet"]["scrollbar_height"] = border_radius+"px"; - ApplyColorsSet(SelectedTheme["ColorsSet"]); - SaveTheme(document.getElementById("theme_list").value); - } - } - - - -// ----------------------EXPORT DEBUG LOG--------------------------------------------------------------------------------- - document.getElementById("options_export_debug").onclick = function(event) {if (event.which == 1) { - chrome.storage.local.get(null, function(storage) { - SaveFile("TreeTabs", "log", storage.debug_log); - }); - }} - -// ----------------------IMPORT DEBUG LOG---------------------------------------------------------------------------- - document.getElementById("options_print_debug").onclick = function(event) {if (event.which == 1) { - let inputFile = ShowOpenFileDialog(".log"); - inputFile.onchange = function(event) { - let file = document.getElementById("file_import"); - let fr = new FileReader(); - if (file.files[0] == undefined) return; - fr.readAsText(file.files[file.files.length - 1]); - fr.onload = function() { - let data = fr.result; - file.parentNode.removeChild(file); - let LoadedData = JSON.parse(data); - // LoadedData.forEach(function(d){ - // console.log(d); - // }); - // LoadedData.forEach(function(d){ - console.log(LoadedData); - // }); - } - } - - }} - -// ----------------------CLEAR DATA BUTTON-------------------------------------------------------------------------------- - - // clear data - document.getElementById("options_clear_data").onclick = function(event) {if (event.which == 1) { - chrome.storage.local.clear(); - setTimeout(function() { - chrome.runtime.sendMessage({command: "reload"}); - chrome.runtime.sendMessage({command: "reload_sidebar"}); - location.reload(); - }, 100); - }} + // --------------------------------DONATIONS----------------------------------------------------------------------------- + + document.getElementById("donate_paypal").onclick = function(event) { + if (event.which == 1) { + chrome.tabs.create({ url: "https://www.paypal.me/KarolJagiello/1" }); + } + } + document.getElementById("donate_litecoin").onclick = function(event) { + if (event.which == 1) { + copyStringToClipboard("LdQ1ZH1CgSneBbmmVBFrg5BFDFHZMa6h76"); + alert(chrome.i18n.getMessage("options_copied_wallet_address")); + } + } + document.getElementById("donate_bitcoin").onclick = function(event) { + if (event.which == 1) { + copyStringToClipboard("19Z8w1RJEcBQpKSdiWa3UTBuKRJUkr96nJ"); + alert(chrome.i18n.getMessage("options_copied_wallet_address")); + } + } + document.getElementById("donate_ethereum").onclick = function(event) { + if (event.which == 1) { + copyStringToClipboard("0x70B05eAD03bF08220d5aF4E1E868C351bfe145D6"); + alert(chrome.i18n.getMessage("options_copied_wallet_address")); + } + } + + // --------------------------------COPY VIVALDI LINK---------------------------------------------------------------------- + + document.getElementById("copy_vivaldi_url_for_web_panel").onclick = function(event) { + if (event.which == 1) { + copyStringToClipboard(chrome.runtime.getURL("sidebar.html")); + alert(chrome.i18n.getMessage("options_vivaldi_copied_url")); + } + } + + // --------------------------------ADD RED AND BLUE PREVIEWS--------------------------------------------------------------- + // document.body.onmousedown = function(event) { + // if (event.which == 1 && (event.target.id || event.target.classList)) { + // console.log(event.target); + // } + // } + + + document.querySelectorAll("#scrollbar_thumb_hover, #options_tab_list_scrollbar_height_up, #options_tab_list_scrollbar_height_down, #options_tab_list_scrollbar_width_up, #options_tab_list_scrollbar_width_down, .pick_col, .font_weight_normal, .font_weight_bold, .font_style_normal, .font_style_italic, #filter_box_font").forEach(function(s) { + s.onmouseleave = function(event) { + RemovePreview(); + } + }); + + // toolbar buttons + document.getElementById("button_background").onmouseenter = function(event) { + AddRedStylePreview("button_theme_plus", "backgroundColor", "red", true); + } + document.getElementById("button_hover_background").onmouseenter = function(event) { + AddBlueBackgroundPreview("button_theme_plus", true); + } + + document.getElementById("button_on_background").onmouseenter = function(event) { + AddRedStylePreview("button_theme_search", "backgroundColor", "red", true); + } + + document.getElementById("button_icons").onmouseenter = function(event) { + AddRedStylePreview("button_theme_plus_img", "backgroundColor", "red", true); + } + document.getElementById("button_icons_hover").onmouseenter = function(event) { + AddBlueBackgroundPreview("button_theme_plus_img", true); + } + document.getElementById("button_on_icons").onmouseenter = function(event) { + AddRedStylePreview("button_theme_search_img", "backgroundColor", "red", true); + } + + document.getElementById("button_border").onmouseenter = function(event) { + AddRedStylePreview("button_theme_plus", "border", "1px solid red", true); + } + document.getElementById("button_hover_border").onmouseenter = function(event) { + AddBlueBorderPreview("button_theme_plus", true); + } + + + // search box + document.getElementById("filter_box_font").onmouseenter = function(event) { + AddRedStylePreview("filter_box_theme", "color", "red", true); + } + document.getElementById("filter_box_background").onmouseenter = function(event) { + AddRedStylePreview("filter_box_theme", "backgroundColor", "red", true); + } + document.getElementById("filter_box_border").onmouseenter = function(event) { + AddRedStylePreview("filter_box_theme", "border", "1px solid red", true); + } + document.getElementById("filter_clear_icon").onmouseenter = function(event) { + AddRedStylePreview("button_filter_clear_theme", "backgroundColor", "red", true); + } + + // toolbar background + document.getElementById("toolbar_background").onmouseenter = function(event) { + AddRedStylePreview("toolbar_main_theme", "backgroundColor", "red", true); + } + + // shelf toolbar background + document.getElementById("toolbar_shelf_background").onmouseenter = function(event) { + AddRedStylePreview("toolbar_search_input_box_theme", "backgroundColor", "red", true); + } + + // toolbar's border + document.getElementById("toolbar_border_bottom").onmouseenter = function(event) { + AddRedStylePreview("button_theme_search", "border", "1px solid red", true); + AddRedStylePreview("toolbar_main_theme", "borderBottom", "1px solid red"); + AddRedStylePreview("toolbar_theme", "borderBottom", "1px solid red"); + } + + // shelf toolbar buttons + document.getElementById("button_shelf_background").onmouseenter = function(event) { + AddRedStylePreview("button_theme_pen", "backgroundColor", "red", true); + } + document.getElementById("button_shelf_hover_background").onmouseenter = function(event) { + AddBlueBackgroundPreview("button_theme_pen", true); + } + document.getElementById("button_shelf_icons").onmouseenter = function(event) { + AddRedStylePreview("button_theme_pen_img", "backgroundColor", "red", true); + } + document.getElementById("button_shelf_icons_hover").onmouseenter = function(event) { + AddBlueBackgroundPreview("button_theme_pen_img", true); + } + document.getElementById("button_shelf_border").onmouseenter = function(event) { + AddRedStylePreview("button_theme_pen", "border", "1px solid red", true); + } + document.getElementById("button_shelf_hover_border").onmouseenter = function(event) { + AddBlueBorderPreview("button_theme_pen", true); + } + + // pinned tab attention_background + document.getElementById("attention_background").onmouseenter = function(event) { + AddRedStylePreview("tab_header_10", "backgroundColor", "red", true); + document.getElementById("tab_header_10").style.animation = "none"; + } + + // pinned tab attention_border + document.getElementById("attention_border").onmouseenter = function(event) { + AddRedStylePreview("tab_header_10", "border", "1px solid red", true); + document.getElementById("tab_header_10").style.animation = "none"; + } + + // pin_list border bottom + document.getElementById("pin_list_border_bottom").onmouseenter = function(event) { + AddRedStylePreview("pin_list", "borderBottom", "1px solid red", true); + } + + // pin_list background + document.getElementById("pin_list_background").onmouseenter = function(event) { + AddRedStylePreview("pin_list", "backgroundColor", "red", true); + } + + + // tab row font_color + document.querySelectorAll(".tab_col.font_color").forEach(function(s) { + s.onmouseenter = function(event) { + AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "color", "red", true); + } + }); + + // tab row font not bold + document.querySelectorAll(".tab_col.font_weight_normal").forEach(function(s) { + s.onmouseenter = function(event) { + AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "color", "red", true); + AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "fontWeight", "normal", false); + } + }); + + // tab row font bold + document.querySelectorAll(".tab_col.font_weight_bold").forEach(function(s) { + s.onmouseenter = function(event) { + AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "color", "red", true); + AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "fontWeight", "bold", false); + } + }); + + // tab row font style normal + document.querySelectorAll(".tab_col.font_style_normal").forEach(function(s) { + s.onmouseenter = function(event) { + AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "color", "red", true); + AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "fontStyle", "normal", false); + } + }); + // tab row font style italic + document.querySelectorAll(".tab_col.font_style_italic").forEach(function(s) { + s.onmouseenter = function(event) { + AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "color", "red", true); + AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "fontStyle", "italic", false); + } + }); + + + // tab border + document.querySelectorAll(".tab_col.color_border").forEach(function(s) { + s.onmouseenter = function(event) { + AddRedStylePreview("tab_header_" + this.parentNode.id.substr(1), "border", "1px solid red", true); + } + }); + + // tab background + document.querySelectorAll(".tab_col.color_bucket").forEach(function(s) { + s.onmouseenter = function(event) { + AddRedStylePreview("tab_header_" + this.parentNode.id.substr(1), "backgroundColor", "red", true); + } + }); + + // scrollbars hover + document.getElementById("scrollbar_thumb_hover").onmouseenter = function(event) { + AddBlueBackgroundPreview("group_scrollbar_thumb", true); + AddBlueBackgroundPreview("pin_list_scrollbar_thumb"); + } + + // scrollbars thumb + document.getElementById("scrollbar_thumb").onmouseenter = function(event) { + AddRedStylePreview("group_scrollbar_thumb", "backgroundColor", "red", true); + AddRedStylePreview("pin_list_scrollbar_thumb", "backgroundColor", "red"); + } + + + // scrollbars track + document.getElementById("scrollbar_track").onmouseenter = function(event) { + AddRedStylePreview("group_scrollbar", "backgroundColor", "red", true); + AddRedStylePreview("pin_list_scrollbar", "backgroundColor", "red"); + } + + + // tab_list scrollbars + document.querySelectorAll("#options_tab_list_scrollbar_width_up, #options_tab_list_scrollbar_width_down").forEach(function(s) { + s.onmouseenter = function(event) { + AddRedStylePreview("group_scrollbar", "backgroundColor", "red", true); + AddRedStylePreview("group_scrollbar_thumb", "backgroundColor", "red"); + } + }); + + // pin_list scrollbars + document.querySelectorAll("#options_tab_list_scrollbar_height_up, #options_tab_list_scrollbar_height_down").forEach(function(s) { + s.onmouseenter = function(event) { + AddRedStylePreview("pin_list_scrollbar", "backgroundColor", "red", true); + AddRedStylePreview("pin_list_scrollbar_thumb", "backgroundColor", "red"); + } + }); + + + + // folder icon open + document.getElementById("folder_icon_open").onmouseenter = function(event) { + AddRedStylePreview("folder_expand_f_folder1", "backgroundColor", "red", true); + } + // folder icon closed + document.getElementById("folder_icon_closed").onmouseenter = function(event) { + AddRedStylePreview("folder_expand_f_folder2", "backgroundColor", "red", true); + } + // folder icon hover + document.getElementById("folder_icon_hover").onmouseenter = function(event) { + AddBlueBackgroundPreview("folder_expand_f_folder3", true); + } + + + // tab expand closed + document.getElementById("expand_closed_background").onmouseenter = function(event) { + AddRedStylePreview("exp_14", "backgroundColor", "red", true); + } + // tab expand hover + document.getElementById("expand_hover_background").onmouseenter = function(event) { + AddBlueBackgroundPreview("exp_16", true); + } + // tab expand open + document.getElementById("expand_open_background").onmouseenter = function(event) { + AddRedStylePreview("exp_5", "backgroundColor", "red", true); + } + + + + + + // drag indicator + document.getElementById("drag_indicator").onmouseenter = function(event) { + AddRedStylePreview("drag_indicator_19", "borderBottom", "1px solid red", true); + } + + + // close x + document.getElementById("close_x").onmouseenter = function(event) { + AddRedStylePreview("close_img_11", "backgroundColor", "red", true); + } + // close x hover + document.getElementById("close_hover_x").onmouseenter = function(event) { + AddBlueBackgroundPreview("close_img_13", true); + } + // close border hover + document.getElementById("close_hover_border").onmouseenter = function(event) { + AddBlueBorderPreview("close_13", true); + } + // close border hover + document.getElementById("close_hover_background").onmouseenter = function(event) { + AddBlueBackgroundPreview("close_13", true); + } + + + + + // group button hover + document.getElementById("group_list_button_hover_background").onmouseenter = function(event) { + AddBlueBackgroundPreview("_tab_list2", true); + } + // group buttons borders + document.getElementById("group_list_borders").onmouseenter = function(event) { + AddRedStylePreview("toolbar_groups_block", "borderRight", "1px solid red", true); + AddRedStylePreview("_tab_list", "border", "1px solid red"); + } + // group buttons font + document.getElementById("group_list_default_font_color").onmouseenter = function(event) { + AddRedStylePreview("_gtetab_list", "color", "red", true); + AddRedStylePreview("_gtetab_list2", "color", "red"); + } + // group list background + document.getElementById("group_list_background").onmouseenter = function(event) { + AddRedStylePreview("toolbar_groups_block", "backgroundColor", "red", true); + } + // tab_list background + document.getElementById("tab_list_background").onmouseenter = function(event) { + AddRedStylePreview("tab_list", "backgroundColor", "red", true); + AddRedStylePreview("_tab_list", "backgroundColor", "red"); + } + + + + + + // menu hover border + document.getElementById("tabs_menu_hover_border").onmouseenter = function(event) { + AddRedStylePreview("menu_hover_sample", "border", "1px solid red", true); + } + // menu hover background + document.getElementById("tabs_menu_hover_background").onmouseenter = function(event) { + AddRedStylePreview("menu_hover_sample", "backgroundColor", "red", true); + } + + // menu separator + document.getElementById("tabs_menu_separator").onmouseenter = function(event) { + AddRedStylePreview("menu_separator1", "backgroundColor", "red", true); + AddRedStylePreview("menu_separator2", "backgroundColor", "red"); + } + + // menu font + document.getElementById("tabs_menu_font").onmouseenter = function(event) { + AddRedStylePreview("menu_hover_sample", "color", "red", true); + AddRedStylePreview("menu_sample1", "color", "red"); + AddRedStylePreview("menu_sample2", "color", "red"); + } + + + // menu border + document.getElementById("tabs_menu_border").onmouseenter = function(event) { + AddRedStylePreview("tabs_menu", "border", "1px solid red", true); + } + + // menu background + document.getElementById("tabs_menu_background").onmouseenter = function(event) { + AddRedStylePreview("tabs_menu", "backgroundColor", "red", true); + } + + + + // --------------------------------------COLOR PICKER--------------------------------------------------------------------- + + // change fonts weight && style + document.querySelectorAll(".font_weight_normal, .font_weight_bold, .font_style_normal, .font_style_italic").forEach(function(s) { + s.onmousedown = function(event) { + event.stopPropagation(); + // if this.classList.contains("font_weight_normal") || this.classList.contains("font_style_normal") + let FontStyle = "normal"; + if (this.classList.contains("font_weight_bold")) { + FontStyle = "bold"; + } + if (this.classList.contains("font_style_italic")) { + FontStyle = "italic"; + } + SelectedTheme["ColorsSet"][this.id] = FontStyle; + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + }); + + // show color picker + document.querySelectorAll(".pick_col").forEach(function(s) { + s.onclick = function(event) { + if (event.which == 1) { + RemovePreview(); + event.stopPropagation(); + let bod = document.getElementById("body"); + let color = window.getComputedStyle(bod, null).getPropertyValue("--" + this.id); + let ColorPicker = document.getElementById("color_picker"); + ColorPicker.setAttribute("PickColor", this.id); + ColorPicker.value = color.replace(" ", ""); + ColorPicker.click(); + } + } + }); + + document.getElementById("color_picker").oninput = function(event) { + let ColorPicker = document.getElementById("color_picker"); + SelectedTheme["ColorsSet"][this.getAttribute("PickColor")] = ColorPicker.value; + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + // Theme_SaveTheme(document.getElementById("theme_list").value); + } + document.getElementById("color_picker").onchange = function(event) { + Theme_SaveTheme(document.getElementById("theme_list").value); + } + + + // ----------------------------------EVENTS FOR CHECKBOXES AND DROPDOWN MENUS--------------------------------------------- + + // set checkbox options on/off and save + document.querySelectorAll(".bg_opt").forEach(function(s) { + s.onclick = function(event) { + if (event.which == 1) { + opt[this.id] = this.checked ? true : false; + if (this.checked) { + if (this.id == "never_show_close") { + document.getElementById("always_show_close").disabled = true; + } + if (this.id == "promote_children") { + document.getElementById("promote_children_in_first_child").disabled = false; + } + } else { + if (this.id == "never_show_close") { + document.getElementById("always_show_close").disabled = false; + } + if (this.id == "promote_children") { + document.getElementById("promote_children_in_first_child").disabled = true; + } + } + Preferences_SavePreferences(opt); + if (this.id == "show_toolbar") { + Toolbar_SaveToolbar(); + RefreshFields(); + + + // setTimeout(function() { + // chrome.runtime.sendMessage({command: "reload_toolbar", toolbar: toolbar, opt: opt}); + // }, 300); + } + } + } + }); + + + // options that need reload + document.onclick = function(event) { + if (event.which == 1) { + if (event.target.id == "syncro_tabbar_tabs_order" || event.target.id == "allow_pin_close" || event.target.id == "switch_with_scroll" || event.target.id == "always_show_close" || event.target.id == "never_show_close" || event.target.id == "hide_other_groups_tabs_firefox" || + event.target.id == "collapse_other_trees" || event.target.id == "show_counter_tabs" || event.target.id == "show_counter_tabs_hints" || event.target.id == "syncro_tabbar_tabs_order" || event.target.id == "syncro_tabbar_groups_tabs_order" || event.target.id == "groups_toolbar_default") { + setTimeout(function() { + chrome.runtime.sendMessage({ command: "reload_sidebar" }); + }, 50); + } + if (event.target.id == "groups_toolbar_default") { + chrome.runtime.sendMessage({ command: "reload" }); + setTimeout(function() { + location.reload(); + }, 300); + } + } + } + + // set dropdown menu options + for (let i = 0; i < DropDownList.length; i++) { + document.getElementById(DropDownList[i]).onchange = function(event) { + opt[this.id] = this.value; + RefreshFields(); + setTimeout(function() { + Preferences_SavePreferences(opt); + // chrome.runtime.sendMessage({command: "reload_sidebar"}); + }, 50); + } + } + + // set tabs tree depth option + document.getElementById("max_tree_depth").oninput = function(event) { + opt.max_tree_depth = parseInt(this.value); + setTimeout(function() { + Preferences_SavePreferences(opt); + }, 50); + } + + // set toolbar on/off and show/hide all toolbar options + // document.getElementById("show_toolbar").onclick = function(event) {if (event.which == 1) { + // SelectedTheme.ToolbarShow = this.checked ? true : false; + // RefreshFields(); + // Theme_SaveTheme(document.getElementById("theme_list").value); + // }} + + + // ------------------------------OTHER----------------------------------------------------------------------------------- + + // block system dragging + document.ondrop = function(event) { + event.preventDefault(); + } + document.ondragover = function(event) { + event.preventDefault(); + } + + // ------------------------------ADD REGEX FILTER------------------------------------------------------------------------- + + document.getElementById("add_tab_group_regex").onclick = AddRegexPair; + + // ----------------------------RESET TOOLBAR BUTTON----------------------------------------------------------------------- + + document.getElementById("options_reset_toolbar_button").onclick = function(event) { + if (event.which == 1) { + + Toolbar_SetToolbarEvents(true, false, false, "", false, false); + RemoveToolbarEditEvents(); + + + let unused_buttons = document.getElementById("toolbar_unused_buttons"); + while (unused_buttons.hasChildNodes()) { + unused_buttons.removeChild(unused_buttons.firstChild); + } + + Toolbar_RemoveToolbar(); + Toolbar_RecreateToolbar(DefaultToolbar); + Toolbar_SetToolbarEvents(false, false, true, "click", false, true); + AddEditToolbarEditEvents(); + + Toolbar_SaveToolbar(); + + + } + } + + + // --------------------------------------THEME BUTTONS-------------------------------------------------------------------- + + + // add new theme preset button + document.getElementById("options_add_theme_button").onclick = function(event) { + if (event.which == 1) { + Theme_AddNewTheme(); + } + } + + // remove theme preset button + document.getElementById("options_remove_theme_button").onclick = function(event) { + if (event.which == 1) { + Theme_DeleteSelectedTheme(); + } + } + + // select theme from list + document.getElementById("theme_list").onchange = function(event) { + Theme_LoadTheme(this.value, true); + chrome.storage.local.set({ current_theme: this.value }); + } + + // import theme preset button + document.getElementById("options_import_theme_button").onclick = function(event) { + if (event.which == 1) { + let inputFile = File_ShowOpenFileDialog(".tt_theme"); + inputFile.onchange = function(event) { + Theme_ImportTheme(); + } + } + } + + // export theme preset button + document.getElementById("options_export_theme_button").onclick = function(event) { + if (event.which == 1) { + let ThemeList = document.getElementById("theme_list"); + if (ThemeList.options.length == 0) { + alert(chrome.i18n.getMessage("options_no_theme_to_export")); + } else { + File_SaveFile(ThemeList.options[ThemeList.selectedIndex].text, "tt_theme", SelectedTheme); + } + } + } + + // rename theme preset button + document.getElementById("options_rename_theme_button").onclick = function(event) { + if (event.which == 1) { + Theme_RenameSelectedTheme(); + } + } + // get themes + document.getElementById("options_share_theme_link").onclick = function(event) { + if (event.which == 1) { + chrome.tabs.create({ url: "https://drive.google.com/drive/folders/0B3jXQpRtOfvSelFrTEVHZEx3Nms?usp=sharing" }); + } + } + + + // -------------------------------INDENTATION ADJUSTMENT------------------------------------------------------------------ + + // change tabs size preset(down) + document.getElementById("options_tabs_indentation_down").onmousedown = function(event) { + let bod = document.getElementById("body"); + var indentation = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--children_padding_left")).replace("p", "").replace("x", "")); + if (indentation > 0) { + indentation--; + SelectedTheme["ColorsSet"]["children_padding_left"] = indentation + "px"; + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + } + + // change tabs size preset(up) + document.getElementById("options_tabs_indentation_up").onmousedown = function(event) { + let bod = document.getElementById("body"); + var indentation = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--children_padding_left")).replace("p", "").replace("x", "")); + if (indentation < 50) { + indentation++; + SelectedTheme["ColorsSet"]["children_padding_left"] = indentation + "px"; + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + } + + + // --------------------------TABS ROUNDNESS ADJUSTMENT-------------------------------------------------------------------- + + // change tabs roundness preset(down) + document.getElementById("options_tabs_roundness_down").onmousedown = function(event) { + let bod = document.getElementById("body"); + var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--tab_header_border_radius").replace("p", "").replace("x", ""))); + if (border_radius > 0) { + border_radius--; + SelectedTheme["ColorsSet"]["tab_header_border_radius"] = border_radius + "px"; + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + } + + // change tabs roundness preset(up) + document.getElementById("options_tabs_roundness_up").onmousedown = function(event) { + let bod = document.getElementById("body"); + var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--tab_header_border_radius")).replace("p", "").replace("x", "")); + if (border_radius < 25) { + border_radius++; + SelectedTheme["ColorsSet"]["tab_header_border_radius"] = border_radius + "px"; + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + } + + // -------------------------------SIZE ADJUSTMENT------------------------------------------------------------------------- + + // set tabs margins + document.getElementById("tabs_margin_spacing").onchange = function(event) { + let size = "0"; + if (this[1].checked) { + size = "1"; + } else { + if (this[2].checked) { + size = "2"; + } + } + SelectedTheme["TabsMargins"] = size; + Theme_ApplyTabsMargins(size); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + + + // change tabs size preset(down) + document.getElementById("options_tabs_size_down").onmousedown = function(event) { + if (SelectedTheme["TabsSizeSetNumber"] > 0) { + SelectedTheme["TabsSizeSetNumber"]--; + Theme_ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + } + + // change tabs size preset(up) + document.getElementById("options_tabs_size_up").onmousedown = function(event) { + if (SelectedTheme["TabsSizeSetNumber"] < 5) { + SelectedTheme["TabsSizeSetNumber"]++; + Theme_ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + } + + + // -------------------------------TABS SCROLLBAR SIZE ADJUSTMENT---------------------------------------------------------- + + // change tab list scrollbar preset(down) + document.getElementById("options_tab_list_scrollbar_width_down").onmousedown = function(event) { + let bod = document.getElementById("body"); + var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--scrollbar_width").replace("p", "").replace("x", ""))); + if (border_radius > 0) { + border_radius--; + SelectedTheme["ColorsSet"]["scrollbar_width"] = border_radius + "px"; + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + } + + // change tab list scrollbar preset(up) + document.getElementById("options_tab_list_scrollbar_width_up").onmousedown = function(event) { + let bod = document.getElementById("body"); + var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--scrollbar_width")).replace("p", "").replace("x", "")); + if (border_radius < 20) { + border_radius++; + SelectedTheme["ColorsSet"]["scrollbar_width"] = border_radius + "px"; + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + } + + // change pin list scrollbar preset(down) + document.getElementById("options_tab_list_scrollbar_height_down").onmousedown = function(event) { + let bod = document.getElementById("body"); + var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--scrollbar_height").replace("p", "").replace("x", ""))); + if (border_radius > 0) { + border_radius--; + SelectedTheme["ColorsSet"]["scrollbar_height"] = border_radius + "px"; + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + } + + // change pin list scrollbar preset(up) + document.getElementById("options_tab_list_scrollbar_height_up").onmousedown = function(event) { + let bod = document.getElementById("body"); + var border_radius = parseInt((window.getComputedStyle(bod, null).getPropertyValue("--scrollbar_height")).replace("p", "").replace("x", "")); + if (border_radius < 20) { + border_radius++; + SelectedTheme["ColorsSet"]["scrollbar_height"] = border_radius + "px"; + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + Theme_SaveTheme(document.getElementById("theme_list").value); + } + } + + + + // ----------------------EXPORT DEBUG LOG--------------------------------------------------------------------------------- + document.getElementById("options_export_debug").onclick = function(event) { + if (event.which == 1) { + chrome.storage.local.get(null, function(storage) { + File_SaveFile("TreeTabs", "log", storage.debug_log); + }); + } + } + + // ----------------------IMPORT DEBUG LOG---------------------------------------------------------------------------- + document.getElementById("options_print_debug").onclick = function(event) { + if (event.which == 1) { + let inputFile = File_ShowOpenFileDialog(".log"); + inputFile.onchange = function(event) { + let file = document.getElementById("file_import"); + let fr = new FileReader(); + if (file.files[0] == undefined) return; + fr.readAsText(file.files[file.files.length - 1]); + fr.onload = function() { + let data = fr.result; + file.parentNode.removeChild(file); + let LoadedData = JSON.parse(data); + // LoadedData.forEach(function(d) { + // console.log(d); + // }); + // LoadedData.forEach(function(d) { + console.log(LoadedData); + // }); + } + } + + } + } + + // ----------------------CLEAR DATA BUTTON-------------------------------------------------------------------------------- + + // clear data + document.getElementById("options_clear_data").onclick = function(event) { + if (event.which == 1) { + chrome.storage.local.clear(); + setTimeout(function() { + chrome.runtime.sendMessage({ command: "reload" }); + chrome.runtime.sendMessage({ command: "reload_sidebar" }); + location.reload(); + }, 100); + } + } } function RemoveToolbarEditEvents() { - document.querySelectorAll("#button_filter_clear").forEach(function(s){ - s.style.opacity = "0"; - }); - document.querySelectorAll(".button").forEach(function(s){ - s.removeAttribute("draggable"); - }); + document.querySelectorAll("#button_filter_clear").forEach(function(s) { + s.style.opacity = "0"; + }); + document.querySelectorAll(".button").forEach(function(s) { + s.removeAttribute("draggable"); + }); } // ----------------------EDIT TOOLBAR------------------------------------------------------------------------------------- function AddEditToolbarEditEvents() { - document.querySelectorAll("#button_filter_clear").forEach(function(s){ - s.style.opacity = "1"; - }); + document.querySelectorAll("#button_filter_clear").forEach(function(s) { + s.style.opacity = "1"; + }); - document.querySelectorAll("#toolbar_main .button_img, #toolbar_shelf_tools .button_img, #toolbar_shelf_groups .button_img, #toolbar_shelf_backup .button_img, #toolbar_shelf_folders .button_img").forEach(function(s){ - s.setAttribute("draggable", true); - s.onmousedown = function(event) { - if (event.which == 1) { - dragged_button = document.getElementById(this.parentNode.id); - } - } - s.ondragstart = function(event) { - event.dataTransfer.setData(" "," "); - event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0); - } - // move (flip) buttons - s.ondragenter = function(event) { - if ((dragged_button.id == "button_tools" || dragged_button.id == "button_search" || dragged_button.id == "button_groups" || dragged_button.id == "button_backup" || dragged_button.id == "button_folders") && this.parentNode.parentNode.classList.contains("toolbar_shelf")) { - return; - } - let dragged_buttonIndex = Array.from(dragged_button.parentNode.children).indexOf(dragged_button); - let Index = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode); - - if (Index <= dragged_buttonIndex) { - InsterBeforeNode(dragged_button, this.parentNode); - } else { - InsterAfterNode(dragged_button, this.parentNode); - } - } - // save toolbar - s.ondragend = function(event) { - RemoveToolbarEditEvents(); - SaveToolbar(); - AddEditToolbarEditEvents(); - } - }); - - - document.querySelectorAll("#toolbar_main, .toolbar_shelf:not(#toolbar_search), #toolbar_unused_buttons").forEach(function(s){s.ondragenter = function(event) { - if ((dragged_button.id == "button_tools" || dragged_button.id == "button_search" || dragged_button.id == "button_groups" || dragged_button.id == "button_backup" || dragged_button.id == "button_folders") && this.classList.contains("toolbar_shelf")) { - return; - } - if (dragged_button.parentNode.id != this.id) { - this.appendChild(dragged_button); - } + document.querySelectorAll("#toolbar_main .button_img, #toolbar_shelf_tools .button_img, #toolbar_shelf_groups .button_img, #toolbar_shelf_backup .button_img, #toolbar_shelf_folders .button_img").forEach(function(s) { + s.setAttribute("draggable", true); + s.onmousedown = function(event) { + if (event.which == 1) { + dragged_button = document.getElementById(this.parentNode.id); + } + } + s.ondragstart = function(event) { + event.dataTransfer.setData(" ", " "); + event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0); + } + // move (flip) buttons + s.ondragenter = function(event) { + if ((dragged_button.id == "button_tools" || dragged_button.id == "button_search" || dragged_button.id == "button_groups" || dragged_button.id == "button_backup" || dragged_button.id == "button_folders") && this.parentNode.parentNode.classList.contains("toolbar_shelf")) { + return; + } + let dragged_buttonIndex = Array.from(dragged_button.parentNode.children).indexOf(dragged_button); + let Index = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode); - }}); + if (Index <= dragged_buttonIndex) { + DOM_InsterBeforeNode(dragged_button, this.parentNode); + } else { + DOM_InsterAfterNode(dragged_button, this.parentNode); + } + } + // save toolbar + s.ondragend = function(event) { + RemoveToolbarEditEvents(); + Toolbar_SaveToolbar(); + AddEditToolbarEditEvents(); + } + }); + + + document.querySelectorAll("#toolbar_main, .toolbar_shelf:not(#toolbar_search), #toolbar_unused_buttons").forEach(function(s) { + s.ondragenter = function(event) { + if ((dragged_button.id == "button_tools" || dragged_button.id == "button_search" || dragged_button.id == "button_groups" || dragged_button.id == "button_backup" || dragged_button.id == "button_folders") && this.classList.contains("toolbar_shelf")) { + return; + } + if (dragged_button.parentNode.id != this.id) { + this.appendChild(dragged_button); + } + + } + }); } function copyStringToClipboard(string) { - function handler (event){ - event.clipboardData.setData('text/plain', string); - event.preventDefault(); - document.removeEventListener('copy', handler, true); - } - document.addEventListener('copy', handler, true); - document.execCommand('copy'); + function handler(event) { + event.clipboardData.setData('text/plain', string); + event.preventDefault(); + document.removeEventListener('copy', handler, true); + } + document.addEventListener('copy', handler, true); + document.execCommand('copy'); } // shrink or expand theme field function RefreshFields() { - if (document.getElementById("theme_list").options.length == 0) { - document.getElementById("field_theme").style.height = "45px"; - } else { - document.getElementById("field_theme").style.height = ""; - } - if (browserId == "F") { - document.querySelectorAll("#scrollbar_size_indicator, #scrollbar_thumb, #scrollbar_thumb_hover, #scrollbar_track").forEach(function(s){ - s.style.display = "none"; - }); - } else { - document.querySelectorAll("#firefox_option_hide_other_groups_tabs_firefox").forEach(function(s){ - s.style.display = "none"; - }); - } - if (browserId == "V") { - let WebPanelUrlBox = document.getElementById("url_for_web_panel"); - WebPanelUrlBox.value = (chrome.runtime.getURL("sidebar.html")); - WebPanelUrlBox.setAttribute("readonly", true); - document.getElementById("field_vivaldi").style.display = "block"; - } - if (document.getElementById("show_toolbar").checked) { - document.querySelectorAll("#options_available_buttons, #sample_toolbar_block, #options_reset_toolbar_button").forEach(function(s){ - s.style.display = ""; - }); - document.getElementById("options_toolbar_look").style.display = ""; - document.getElementById("field_show_toolbar").style.height = ""; - } else{ - document.querySelectorAll("#options_available_buttons, #sample_toolbar_block, #options_reset_toolbar_button").forEach(function(s){ - s.style.display = "none"; - }); - document.getElementById("options_toolbar_look").style.display = "none"; - document.getElementById("field_show_toolbar").style.height = "6"; - } - - - if (document.getElementById("append_child_tab").value == "after") { - document.getElementById("append_child_tab_after_limit_dropdown").style.display = "none"; - document.getElementById("options_append_orphan_tab_as_child").style.display = "none"; + if (document.getElementById("theme_list").options.length == 0) { + document.getElementById("field_theme").style.height = "45px"; + } else { + document.getElementById("field_theme").style.height = ""; + } + if (browserId == "F") { + document.querySelectorAll("#scrollbar_size_indicator, #scrollbar_thumb, #scrollbar_thumb_hover, #scrollbar_track").forEach(function(s) { + s.style.display = "none"; + }); + } else { + document.querySelectorAll("#firefox_option_hide_other_groups_tabs_firefox").forEach(function(s) { + s.style.display = "none"; + }); + } + if (browserId == "V") { + let WebPanelUrlBox = document.getElementById("url_for_web_panel"); + WebPanelUrlBox.value = (chrome.runtime.getURL("sidebar.html")); + WebPanelUrlBox.setAttribute("readonly", true); + document.getElementById("field_vivaldi").style.display = "block"; + } + if (document.getElementById("show_toolbar").checked) { + document.querySelectorAll("#options_available_buttons, #sample_toolbar_block, #options_reset_toolbar_button").forEach(function(s) { + s.style.display = ""; + }); + document.getElementById("options_toolbar_look").style.display = ""; + document.getElementById("field_show_toolbar").style.height = ""; + } else { + document.querySelectorAll("#options_available_buttons, #sample_toolbar_block, #options_reset_toolbar_button").forEach(function(s) { + s.style.display = "none"; + }); + document.getElementById("options_toolbar_look").style.display = "none"; + document.getElementById("field_show_toolbar").style.height = "6"; + } - if (opt.append_child_tab == "after" && opt.append_orphan_tab == "as_child") { - opt.append_orphan_tab = "after_active"; - document.getElementById("append_orphan_tab").value = "after_active"; - SavePreferences(); - } - - } else { - document.getElementById("append_child_tab_after_limit_dropdown").style.display = ""; - document.getElementById("options_append_orphan_tab_as_child").style.display = ""; - } + + if (document.getElementById("append_child_tab").value == "after") { + document.getElementById("append_child_tab_after_limit_dropdown").style.display = "none"; + document.getElementById("options_append_orphan_tab_as_child").style.display = "none"; + + if (opt.append_child_tab == "after" && opt.append_orphan_tab == "as_child") { + opt.append_orphan_tab = "after_active"; + document.getElementById("append_orphan_tab").value = "after_active"; + Preferences_SavePreferences(opt); + } + + } else { + document.getElementById("append_child_tab_after_limit_dropdown").style.display = ""; + document.getElementById("options_append_orphan_tab_as_child").style.display = ""; + } } function RefreshGUI() { - let button_filter_type = document.getElementById("button_filter_type"); - if (button_filter_type != null) { - button_filter_type.classList.add("url"); - button_filter_type.classList.remove("title"); - } - if (document.querySelector(".on") != null) { - document.getElementById("toolbar").style.height = "53px"; - } else { - document.getElementById("toolbar").style.height = "26px"; - } + let button_filter_type = document.getElementById("button_filter_type"); + if (button_filter_type != null) { + button_filter_type.classList.add("url"); + button_filter_type.classList.remove("title"); + } + if (document.querySelector(".on") != null) { + document.getElementById("toolbar").style.height = "53px"; + } else { + document.getElementById("toolbar").style.height = "26px"; + } } +function AppendSampleTabs() { + + // folders + Folders_AddNewFolder({ folderId: "f_folder1", ParentId: "°tab_list", Name: labels.noname_group, Index: 0, ExpandState: "o", SkipSetEvents: true, AdditionalClass: "o" }); + Folders_AddNewFolder({ folderId: "f_folder2", ParentId: "f_folder1", Name: labels.noname_group, Index: 0, ExpandState: "c", SkipSetEvents: true, AdditionalClass: "c" }); + Folders_AddNewFolder({ folderId: "f_folder3", ParentId: "f_folder1", Name: labels.noname_group, Index: 0, ExpandState: "c", SkipSetEvents: true, AdditionalClass: "c" }); -// dummy functions -function BindTabsSwitchingToMouseWheel() {} -function GetFaviconAndTitle() {} -function RefreshMediaIcon() {} -function SetActiveTab() {} -function RefreshCounters() {} -function RefreshExpandStates() {} -function Loadi18n() {} \ No newline at end of file + // pins + tt.tabs["0"] = new Tabs_ttTab({ tab: { id: 0, pinned: true, active: false }, Append: true, SkipSetActive: true, SkipSetEvents: true, SkipFavicon: true, SkipMediaIcon: true }); + tt.tabs["1"] = new Tabs_ttTab({ tab: { id: 1, pinned: true, active: false }, Append: true, SkipSetActive: true, SkipSetEvents: true, SkipFavicon: true, SkipMediaIcon: true }); + tt.tabs["10"] = new Tabs_ttTab({ tab: { id: 10, pinned: true, active: false }, Append: true, SkipSetActive: true, SkipSetEvents: true, SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("10").classList.add("attention"); + + // regular tabs + tt.tabs["2"] = new Tabs_ttTab({ tab: { id: 2, pinned: false, active: false }, Append: true, SkipSetActive: true, SkipSetEvents: true, addCounter: true, SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_2").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal"); + + tt.tabs["11"] = new Tabs_ttTab({ tab: { id: 11, pinned: false, active: false }, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_11").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal_hover"); + document.getElementById("tab_header_11").classList.add("tab_header_hover"); + document.getElementById("tab_header_11").classList.add("close_show"); + + tt.tabs["12"] = new Tabs_ttTab({ tab: { id: 12, pinned: false, active: false }, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_12").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal_selected"); + + tt.tabs["13"] = new Tabs_ttTab({ tab: { id: 13, pinned: false, active: false }, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_13").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal_selected_hover"); + document.getElementById("tab_header_13").classList.add("tab_header_hover") + document.getElementById("tab_header_13").classList.add("close_show"); + document.getElementById("close_13").classList.add("close_hover"); + + // regular active tabs + tt.tabs["3"] = new Tabs_ttTab({ tab: { id: 3, pinned: false, active: false }, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_3").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active"); + + tt.tabs["15"] = new Tabs_ttTab({ tab: { id: 15, pinned: false, active: false }, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_15").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active_hover"); + document.getElementById("tab_header_15").classList.add("tab_header_hover"); + + tt.tabs["14"] = new Tabs_ttTab({ tab: { id: 14, pinned: false, active: false }, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "c selected active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_14").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active_selected"); + + tt.tabs["16"] = new Tabs_ttTab({ tab: { id: 16, pinned: false, active: false }, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "c selected active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_16").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active_selected_hover"); + document.getElementById("tab_header_16").classList.add("tab_header_hover"); + document.getElementById("exp_16").classList.add("hover"); + + // discarded tabs + tt.tabs["5"] = new Tabs_ttTab({ tab: { id: 5, pinned: false, active: false, discarded: true }, Append: true, SkipSetActive: true, SkipSetEvents: true, SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_5").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded"); + + tt.tabs["17"] = new Tabs_ttTab({ tab: { id: 17, pinned: false, active: false, discarded: true }, ParentId: "5", Append: true, SkipSetActive: true, SkipSetEvents: true, SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_17").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded_hover"); + document.getElementById("tab_header_17").classList.add("tab_header_hover"); + + tt.tabs["19"] = new Tabs_ttTab({ tab: { id: 19, pinned: false, active: false, discarded: true }, ParentId: "5", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected highlighted_drop_target after", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_19").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded_selected"); + + tt.tabs["20"] = new Tabs_ttTab({ tab: { id: 20, pinned: false, active: false, discarded: true }, ParentId: "5", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_20").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded_selected_hover"); + document.getElementById("tab_header_20").classList.add("tab_header_hover"); + + // search result + tt.tabs["6"] = new Tabs_ttTab({ tab: { id: 6, pinned: false, active: false }, Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_6").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result"); + + tt.tabs["21"] = new Tabs_ttTab({ tab: { id: 21, pinned: false, active: false }, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_21").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_hover"); + document.getElementById("tab_header_21").classList.add("tab_header_hover"); + + tt.tabs["22"] = new Tabs_ttTab({ tab: { id: 22, pinned: false, active: false }, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_22").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_active"); + + tt.tabs["23"] = new Tabs_ttTab({ tab: { id: 23, pinned: false, active: false }, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_23").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_active_hover"); + document.getElementById("tab_header_23").classList.add("tab_header_hover"); + + + // search result selected + tt.tabs["8"] = new Tabs_ttTab({ tab: { id: 8, pinned: false, active: false }, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected filtered", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_8").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected"); + + tt.tabs["18"] = new Tabs_ttTab({ tab: { id: 18, pinned: false, active: false }, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected filtered", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_18").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected_hover"); + document.getElementById("tab_header_18").classList.add("tab_header_hover"); + + tt.tabs["25"] = new Tabs_ttTab({ tab: { id: 25, pinned: false, active: false }, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected filtered active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_25").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected_active"); + + + tt.tabs["26"] = new Tabs_ttTab({ tab: { id: 26, pinned: false, active: false }, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected filtered active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_26").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected_active_hover"); + document.getElementById("tab_header_26").classList.add("tab_header_hover"); + + // search result highlighted + tt.tabs["30"] = new Tabs_ttTab({ tab: { id: 30, pinned: false, active: false }, Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_30").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted"); + + tt.tabs["31"] = new Tabs_ttTab({ tab: { id: 31, pinned: false, active: false }, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_31").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_hover"); + document.getElementById("tab_header_31").classList.add("tab_header_hover"); + + tt.tabs["32"] = new Tabs_ttTab({ tab: { id: 32, pinned: false, active: false }, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_32").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_active"); + + tt.tabs["33"] = new Tabs_ttTab({ tab: { id: 33, pinned: false, active: false }, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_33").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_active_hover"); + document.getElementById("tab_header_33").classList.add("tab_header_hover"); + + tt.tabs["34"] = new Tabs_ttTab({ tab: { id: 34, pinned: false, active: false }, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected filtered highlighted_search", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_34").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected"); + + tt.tabs["35"] = new Tabs_ttTab({ tab: { id: 35, pinned: false, active: false }, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected filtered highlighted_search", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_35").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected_hover"); + document.getElementById("tab_header_35").classList.add("tab_header_hover"); + + tt.tabs["36"] = new Tabs_ttTab({ tab: { id: 36, pinned: false, active: false }, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected filtered highlighted_search active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_36").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected_active"); + + tt.tabs["37"] = new Tabs_ttTab({ tab: { id: 37, pinned: false, active: false }, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected filtered highlighted_search active_tab", SkipFavicon: true, SkipMediaIcon: true }); + document.getElementById("tab_title_37").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected_active_hover"); + document.getElementById("tab_header_37").classList.add("tab_header_hover"); + + document.getElementById("_tab_list").classList.add("active_group"); + +} \ No newline at end of file diff --git a/options/options overwrite.css b/options/options_overwrite.css similarity index 100% rename from options/options overwrite.css rename to options/options_overwrite.css diff --git a/options/sample_tabs.js b/options/sample_tabs.js deleted file mode 100644 index ac3d56d..0000000 --- a/options/sample_tabs.js +++ /dev/null @@ -1,131 +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 AppendSampleTabs() { - - // folders - AddNewFolder({folderId: "f_folder1", ParentId: "cftab_list", Name: labels.noname_group, Index: 0, ExpandState: "o", AdditionalClass: "o"}); - AddNewFolder({folderId: "f_folder2", ParentId: "f_folder1", Name: labels.noname_group, Index: 0, ExpandState: "c", AdditionalClass: "c"}); - AddNewFolder({folderId: "f_folder3", ParentId: "f_folder1", Name: labels.noname_group, Index: 0, ExpandState: "c", AdditionalClass: "c"}); - - - // pins - AppendTab({tab: {id: 0, pinned: true, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true}); - AppendTab({tab: {id: 1, pinned: true, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true}); - AppendTab({tab: {id: 10, pinned: true, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true}); - document.getElementById("10").classList.add("attention"); - - // regular tabs - AppendTab({tab: {id: 2, pinned: false, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true, addCounter: true}); - document.getElementById("tab_title2").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal"); - - AppendTab({tab: {id: 11, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true}); - document.getElementById("tab_title11").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal_hover"); - document.getElementById("tab_header11").classList.add("tab_header_hover"); - document.getElementById("tab_header11").classList.add("close_show"); - - AppendTab({tab: {id: 12, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab"}); - document.getElementById("tab_title12").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal_selected"); - - AppendTab({tab: {id: 13, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab"}); - document.getElementById("tab_title13").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_normal_selected_hover"); - document.getElementById("tab_header13").classList.add("tab_header_hover") - document.getElementById("tab_header13").classList.add("close_show"); - document.getElementById("close13").classList.add("close_hover"); - - // regular active tabs - AppendTab({tab: {id: 3, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "active_tab"}); - document.getElementById("tab_title3").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active"); - - AppendTab({tab: {id: 15, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "active_tab"}); - document.getElementById("tab_title15").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active_hover"); - document.getElementById("tab_header15").classList.add("tab_header_hover"); - - AppendTab({tab: {id: 14, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "c selected_tab active_tab"}); - document.getElementById("tab_title14").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active_selected"); - - AppendTab({tab: {id: 16, pinned: false, active: false}, ParentId: "2", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "c selected_tab active_tab"}); - document.getElementById("tab_title16").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_active_selected_hover"); - document.getElementById("tab_header16").classList.add("tab_header_hover"); - document.getElementById("exp16").classList.add("hover"); - - // discarded tabs - AppendTab({tab: {id: 5, pinned: false, active: false, discarded: true}, Append: true, SkipSetActive: true, SkipSetEvents: true}); - document.getElementById("tab_title5").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded"); - - AppendTab({tab: {id: 17, pinned: false, active: false, discarded: true}, ParentId: "5", Append: true, SkipSetActive: true, SkipSetEvents: true}); - document.getElementById("tab_title17").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded_hover"); - document.getElementById("tab_header17").classList.add("tab_header_hover"); - - AppendTab({tab: {id: 19, pinned: false, active: false, discarded: true}, ParentId: "5", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab highlighted_drop_target after"}); - document.getElementById("tab_title19").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded_selected"); - - AppendTab({tab: {id: 20, pinned: false, active: false, discarded: true}, ParentId: "5", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab"}); - document.getElementById("tab_title20").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_discarded_selected_hover"); - document.getElementById("tab_header20").classList.add("tab_header_hover"); - - // search result - AppendTab({tab: {id: 6, pinned: false, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered"}); - document.getElementById("tab_title6").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result"); - - AppendTab({tab: {id: 21, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered"}); - document.getElementById("tab_title21").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_hover"); - document.getElementById("tab_header21").classList.add("tab_header_hover"); - - AppendTab({tab: {id: 22, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered active_tab"}); - document.getElementById("tab_title22").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_active"); - - AppendTab({tab: {id: 23, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered active_tab"}); - document.getElementById("tab_title23").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_active_hover"); - document.getElementById("tab_header23").classList.add("tab_header_hover"); - - - // search result selected - AppendTab({tab: {id: 8, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered"}); - document.getElementById("tab_title8").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected"); - - AppendTab({tab: {id: 18, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered"}); - document.getElementById("tab_title18").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected_hover"); - document.getElementById("tab_header18").classList.add("tab_header_hover"); - - AppendTab({tab: {id: 25, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered active_tab"}); - document.getElementById("tab_title25").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected_active"); - - - AppendTab({tab: {id: 26, pinned: false, active: false}, ParentId: "6", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered active_tab"}); - document.getElementById("tab_title26").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_selected_active_hover"); - document.getElementById("tab_header26").classList.add("tab_header_hover"); - - // search result highlighted - AppendTab({tab: {id: 30, pinned: false, active: false}, Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search"}); - document.getElementById("tab_title30").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted"); - - AppendTab({tab: {id: 31, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search"}); - document.getElementById("tab_title31").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_hover"); - document.getElementById("tab_header31").classList.add("tab_header_hover"); - - AppendTab({tab: {id: 32, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search active_tab"}); - document.getElementById("tab_title32").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_active"); - - AppendTab({tab: {id: 33, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "filtered highlighted_search active_tab"}); - document.getElementById("tab_title33").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_active_hover"); - document.getElementById("tab_header33").classList.add("tab_header_hover"); - - AppendTab({tab: {id: 34, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered highlighted_search"}); - document.getElementById("tab_title34").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected"); - - AppendTab({tab: {id: 35, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered highlighted_search"}); - document.getElementById("tab_title35").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected_hover"); - document.getElementById("tab_header35").classList.add("tab_header_hover"); - - AppendTab({tab: {id: 36, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered highlighted_search active_tab"}); - document.getElementById("tab_title36").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected_active"); - - AppendTab({tab: {id: 37, pinned: false, active: false}, ParentId: "30", Append: true, SkipSetActive: true, SkipSetEvents: true, AdditionalClass: "selected_tab filtered highlighted_search active_tab"}); - document.getElementById("tab_title37").textContent = chrome.i18n.getMessage("options_theme_tabs_sample_text_search_result_highlighted_selected_active_hover"); - document.getElementById("tab_header37").classList.add("tab_header_hover"); - - document.getElementById("_tab_list").classList.add("active_group"); - -} \ No newline at end of file diff --git a/scripts/backup.js b/scripts/backup.js deleted file mode 100644 index 4743b11..0000000 --- a/scripts/backup.js +++ /dev/null @@ -1,580 +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 ExportGroup(groupId, filename, save_to_manager) { - let GroupToSave = { group: tt.groups[groupId], folders: {}, tabs: [] }; - document.querySelectorAll("#" + groupId + " .folder").forEach(function(s) { - if (tt.folders[s.id]) { - GroupToSave.folders[s.id] = tt.folders[s.id]; - } - }); - let Tabs = document.querySelectorAll("#" + groupId + " .tab"); - if (Tabs.length > 0) { - let lastId = parseInt(Tabs[Tabs.length - 1].id); - Tabs.forEach(function(s) { - chrome.tabs.get(parseInt(s.id), function(tab) { - if ((tab.url).startsWith("www") || (tab.url).startsWith("http") || (tab.url).startsWith("ftp")) { - (GroupToSave.tabs).push({ - id: tab.id, - parent: s.parentNode.parentNode.id, - index: Array.from(s.parentNode.children).indexOf(s), - expand: (s.classList.contains("c") ? "c" : (s.classList.contains("o") ? "o" : "")), - url: tab.url - }); - } - if (tab.id == lastId) { - if (filename) { - SaveFile(filename, "tt_group", GroupToSave); - } - if (save_to_manager) { - AddGroupToStorage(GroupToSave, true); - } - - if (opt.debug) { - log("f: ExportGroup, filename: "+filename+", groupId: "+groupId+", save_to_manager: "+save_to_manager); - } - } - }); - }); - } else { - if (filename) { - SaveFile(filename, "tt_group", GroupToSave); - } - if (save_to_manager) { - AddGroupToStorage(GroupToSave, true); - } - - if (opt.debug) { - log("f: ExportGroup, filename: "+filename+", groupId: "+groupId+", save_to_manager: "+save_to_manager); - } - - } -} - -function ImportGroup(recreate_group, save_to_manager) { - let file = document.getElementById("file_import"); - let fr = new FileReader(); - if (file.files[0] == undefined) return; - fr.readAsText(file.files[0]); - fr.onload = function() { - let data = fr.result; - let group = JSON.parse(data); - file.parentNode.removeChild(file); - if (recreate_group) { - RecreateGroup(group); - } - if (save_to_manager) { - AddGroupToStorage(group, true); - } - - if (opt.debug) { - log("f: ImportGroup, recreate_group: "+recreate_group+", save_to_manager: "+save_to_manager); - } - } -} - -function AddGroupToStorage(group, add_to_manager) { - chrome.storage.local.get(null, function(storage) { - if (storage["hibernated_groups"] == undefined) { - let hibernated_groups = []; - hibernated_groups.push(group); - chrome.storage.local.set({ hibernated_groups: hibernated_groups }); - if (add_to_manager) { - AddGroupToManagerList(group); - } - } else { - let hibernated_groups = storage["hibernated_groups"]; - hibernated_groups.push(group); - chrome.storage.local.set({ hibernated_groups: hibernated_groups }); - if (add_to_manager) { - AddGroupToManagerList(group); - } - } - if (opt.debug) { - log("f: AddGroupToStorage, add_to_manager: "+add_to_manager); - } - }); -} - - -function RecreateGroup(LoadedGroup) { - let NewFolders = {}; - let RefsTabs = {}; - let NewTabs = []; - let NewGroupId = AddNewGroup(LoadedGroup.group.name, LoadedGroup.group.font); - SetActiveGroup(NewGroupId, false, false); - for (var folder in LoadedGroup.folders) { - let newId = GenerateNewFolderID(); - NewFolders[folder] = { id: newId, parent: NewGroupId, index: (LoadedGroup.folders[folder].index), name: (LoadedGroup.folders[folder].name), expand: (LoadedGroup.folders[folder].expand) }; - } - for (var folder in NewFolders) { - if (NewFolders[LoadedGroup.folders[folder].parent]) { - NewFolders[folder].parent = NewFolders[LoadedGroup.folders[folder].parent].id; - } - } - (LoadedGroup.tabs).forEach(function(Tab) { - chrome.tabs.create({ url: Tab.url, active: false }, function(new_tab) { - if (new_tab) { - RefsTabs[Tab.id] = new_tab.id; - Tab.id = new_tab.id; - NewTabs.push(Tab); - setTimeout(function() { - let nt = document.getElementById(new_tab.id); - let NewGroupTabs = document.getElementById("ct" + NewGroupId); - if (nt != null && NewGroupTabs != null) { - NewGroupTabs.appendChild(nt); - } - }, 1000); - - if (browserId != "O") { - chrome.runtime.sendMessage({command: "discard_tab", tabId: new_tab.id}); - } - - } - if (NewTabs.length == LoadedGroup.tabs.length - 1) { - setTimeout(function() { - NewTabs.forEach(function(LTab) { - if (LTab.parent == LoadedGroup.group.id) { - LTab.parent = NewGroupId; - } - if (NewFolders[LTab.parent]) { - LTab.parent = NewFolders[LTab.parent].id; - } - if (RefsTabs[LTab.parent]) { - LTab.parent = RefsTabs[LTab.parent]; - } - }); - setTimeout(function() { - RcreateTreeStructure({}, NewFolders, NewTabs); - }, 1000); - setTimeout(function() { - RcreateTreeStructure({}, NewFolders, NewTabs); - }, 2000); - setTimeout(function() { - RcreateTreeStructure({}, NewFolders, NewTabs); - }, 5000); - }, 2000); - } - }); - }); - - if (opt.debug) { - log("f: RecreateGroup"); - } - -} - - -function ExportSession(name, save_to_file, save_to_manager, save_to_autosave_manager) { - chrome.windows.getAll({ windowTypes: ['normal'], populate: true }, function(win) { - chrome.runtime.sendMessage({ command: "get_browser_tabs" }, function(t) { - let tabs = Object.assign({}, t); - chrome.runtime.sendMessage({ command: "get_windows" }, function(w) { - let windows = Object.assign({}, w); - let warn = true; - let ExportWindows = []; - win.forEach(function(CWin) { - if (CWin.tabs.length > 0) { - windows[CWin.id]["id"] = CWin.id; - windows[CWin.id]["tabs"] = []; - CWin.tabs.forEach(function(CTab) { - if ((CTab.url).startsWith("www") || (CTab.url).startsWith("http") || (CTab.url).startsWith("ftp")) { - windows[CWin.id]["tabs"].push({ id: CTab.id, url: CTab.url, parent: tabs[CTab.id].parent, index: tabs[CTab.id].index, expand: tabs[CTab.id].expand }); - } - }); - ExportWindows.push(windows[CWin.id]); - } - }); - if (save_to_file) { - SaveFile(name, "tt_session", ExportWindows); - } - if (save_to_manager) { - AddSessionToStorage(ExportWindows, name, true); - } - if (save_to_autosave_manager) { - AddAutosaveSessionToStorage(ExportWindows, name) - } - - if (opt.debug) { - log("f: ExportSession, name: "+name+", save_to_file: "+save_to_file+", save_to_manager: "+save_to_manager+", save_to_autosave_manager: "+save_to_autosave_manager); - } - - }); - }); - }); -} - -function ImportSession(recreate_session, save_to_manager, merge_session) { - let file = document.getElementById("file_import"); - let fr = new FileReader(); - if (file.files[0] == undefined) return; - fr.readAsText(file.files[file.files.length - 1]); - - fr.onload = function() { - let data = fr.result; - file.parentNode.removeChild(file); - - let LoadedSession = JSON.parse(data); - - if (opt.debug) { - log("f: ImportSession, recreate_session: "+recreate_session+", merge_session: "+merge_session); - } - - if (recreate_session) { - RecreateSession(LoadedSession); - } - if (merge_session) { - ImportMergeTabs(LoadedSession); - } - if (save_to_manager) { - AddSessionToStorage(LoadedSession, (file.files[file.files.length - 1].name).replace(".tt_session", ""), true); - } - } -} - -function AddSessionToStorage(session, name, add_to_manager) { - chrome.storage.local.get(null, function(storage) { - if (storage.saved_sessions == undefined) { - let saved_sessions = []; - saved_sessions.push({ name: name, session: session }); - chrome.storage.local.set({ saved_sessions: saved_sessions }); - if (add_to_manager) { - AddSessionToManagerList(saved_sessions[saved_sessions.length - 1]); - } - } else { - let saved_sessions = storage.saved_sessions; - saved_sessions.push({ name: name, session: session }); - - chrome.storage.local.set({ saved_sessions: saved_sessions }); - if (add_to_manager) { - AddSessionToManagerList(saved_sessions[saved_sessions.length - 1]); - } - } - - if (opt.debug) { - log("f: AddSessionToStorage, name: "+name+", add_to_manager: "+add_to_manager); - } - }); - -} - -function AddAutosaveSessionToStorage(session, name) { - chrome.storage.local.get(null, function(storage) { - if (storage.saved_sessions_automatic == undefined) { - let s = []; - s.push({ name: name, session: session }); - chrome.storage.local.set({ saved_sessions_automatic: s }); - } else { - let s = storage.saved_sessions_automatic; - s.unshift({ name: name, session: session }); - if (s[opt.autosave_max_to_keep]) { - s.splice(opt.autosave_max_to_keep, (s.length - opt.autosave_max_to_keep)); - } - chrome.storage.local.set({ saved_sessions_automatic: s }); - } - - if (opt.debug) { - log("f: AddAutosaveSessionToStorage, name: "+name); - } - }); -} - - -function RecreateSession(LoadedSession) { - let RefsTabs = {}; - - if (opt.debug) { - log("f: RecreateSession"); - } - - LoadedSession.forEach(function(LWin) { - let NewTabs = []; - let urls = []; - (LWin.tabs).forEach(function(Tab) { - urls.push(Tab.url); - NewTabs.push(Tab); - }); - - chrome.windows.create({ url: urls /* , discarded: true */ }, function(new_window) { - chrome.runtime.sendMessage({command: "save_groups", windowId: new_window.id, groups: LWin.groups}); - chrome.runtime.sendMessage({command: "save_folders", windowId: new_window.id, folders: LWin.folders}); - - for (let tInd = 0; tInd < new_window.tabs.length; tInd++) { - RefsTabs[NewTabs[tInd].id] = new_window.tabs[tInd].id; - NewTabs[tInd].id = new_window.tabs[tInd].id; - } - for (let tInd = 0; tInd < new_window.tabs.length; tInd++) { - if (RefsTabs[NewTabs[tInd].parent] != undefined) { - NewTabs[tInd].parent = RefsTabs[NewTabs[tInd].parent]; - } - } - for (let tInd = 0; tInd < new_window.tabs.length; tInd++) { - if (NewTabs[tInd].parent == "pin_list") { - chrome.tabs.update(new_window.tabs[tInd].id, { pinned: true }); - } - chrome.runtime.sendMessage({command: "update_tab", tabId: new_window.tabs[tInd].id, tab: {index: NewTabs[tInd].index, expand: NewTabs[tInd].expand, parent: NewTabs[tInd].parent}}); - - // if (browserId != "O") { - // chrome.runtime.sendMessage({command: "discard_tab", tabId: new_window.tabs[tInd].id}); - // } - } - - if (browserId != "O") { - setTimeout(function() { - chrome.runtime.sendMessage({command: "discard_window", windowId: new_window.id}); - }, urls.length * 300); - } - - }); - }); -} - -// groups and folders are in object, just like tt.groups and tt.folders, but tabs are in array of treetabs objects -function RcreateTreeStructure(groups, folders, tabs) { - if (opt.debug) { - log("f: RcreateTreeStructure"); - } - - ShowStatusBar({show: true, spinner: true, message: "Quick check and recreating structure..."}); - if (groups && Object.keys(groups).length > 0) { - for (var group in groups) { - tt.groups[groups[group].id] = Object.assign({}, groups[group]); - } - AppendGroups(tt.groups); - } - if (folders && Object.keys(folders).length > 0) { - for (var folder in folders) { - tt.folders[folders[folder].id] = Object.assign({}, folders[folder]); - } - AppendFolders(tt.folders); - } - let bgtabs = {}; - tabs.forEach(function(Tab) { - if (Tab.parent == "pin_list") { - chrome.tabs.update(Tab.id, { pinned: true }); - } - if (Tab.parent != "") { - let tb = document.getElementById(Tab.id); - let tbp = document.getElementById("ct" + Tab.parent); - if (tb && tbp) { - tbp.appendChild(tb); - if (Tab.expand != "") { - tb.classList.add(Tab.expand); - } - } - bgtabs[Tab.id] = { index: Tab.index, parent: Tab.parent, expand: Tab.expand }; - } - }); - RearrangeTreeTabs(bgtabs, false); - RearrangeFolders(true); - UpdateBgGroupsOrder(); - setTimeout(function() { - RefreshExpandStates(); - RefreshCounters(); - tt.schedule_update_data++; - SaveFolders(); - }, 3000); - // ShowStatusBar({show: true, spinner: true, message: "Sorting"}); - // ShowStatusBar(false, "Wait just a little more..."); -} - -function ImportMergeTabs(LoadedSession) { - if (opt.debug) { - log("f: ImportMergeTabs"); - } - let RefsWins = {}; - let RefsTabs = {}; - for (let LWI = 0; LWI < LoadedSession.length; LWI++) { // clear previous window ids - LoadedSession[LWI].id = ""; - } - ShowStatusBar({show: true, spinner: true, message: "Loaded Tree structure..."}); - chrome.windows.getAll({ windowTypes: ['normal'], populate: true }, function(cw) { - for (let CWI = 0; CWI < cw.length; CWI++) { // Current Windows - - for (let LWI = 0; LWI < LoadedSession.length; LWI++) { // Loaded Windows - - if (LoadedSession[LWI].id == "") { - - let tabsMatch = 0; - for (let CTI = 0; CTI < cw[CWI].tabs.length; CTI++) { // loop Tabs of CWI Window - for (let LTI = 0; LTI < LoadedSession[LWI].tabs.length; LTI++) { // loop Tabs of Loaded Window - if (cw[CWI].tabs[CTI].url == LoadedSession[LWI].tabs[LTI].url) { - RefsTabs[LoadedSession[LWI].tabs[LTI].id] = cw[CWI].tabs[CTI].id; - LoadedSession[LWI].tabs[LTI].id = cw[CWI].tabs[CTI].id; - LoadedSession[LWI].tabs[LTI].url = ""; - tabsMatch++; - break; - } - } - } - if (opt.debug) { - log("f: ImportMergeTabs, tabsMatch: "+tabsMatch); - } - if (tabsMatch > LoadedSession[LWI].tabs.length * 0.6) { - LoadedSession[LWI].id = cw[CWI].id; - break; - } - - } - } - } - - LoadedSession.forEach(function(w) { - if (w.id == "") { // missing window, lets make one - if (opt.debug) { - log("f: ImportMergeTabs, missing window"); - } - - let NewTabs = []; - let urls = []; - (w.tabs).forEach(function(Tab) { - urls.push(Tab.url); - NewTabs.push(Tab); - }); - chrome.windows.create({ url: urls }, function(new_window) { - chrome.runtime.sendMessage({command: "save_groups", windowId: new_window.id, groups: w.groups}); - chrome.runtime.sendMessage({command: "save_folders", windowId: new_window.id, folders: w.folders}); - - for (let tInd = 0; tInd < new_window.tabs.length; tInd++) { - if (NewTabs[tInd]) { - RefsTabs[NewTabs[tInd].id] = new_window.tabs[tInd].id; - NewTabs[tInd].id = new_window.tabs[tInd].id; - } - } - for (let tInd = 0; tInd < NewTabs.length; tInd++) { - if (RefsTabs[NewTabs[tInd].parent] != undefined) { - NewTabs[tInd].parent = RefsTabs[NewTabs[tInd].parent]; - } - } - - for (let tInd = 0; tInd < new_window.tabs.length; tInd++) { - if (NewTabs[tInd].parent == "pin_list") { - chrome.tabs.update(new_window.tabs[tInd].id, { pinned: true }); - } - chrome.runtime.sendMessage({command: "update_tab", tabId: new_window.tabs[tInd].id, tab: {index: NewTabs[tInd].index, expand: NewTabs[tInd].expand, parent: NewTabs[tInd].parent}}); - } - - - let done = 3; - var Append = setInterval(function() { - chrome.runtime.sendMessage({command: "remote_update", groups: w.groups, folders: w.folders, tabs: NewTabs, windowId: w.id }); - if (done < 0) { clearInterval(Append); } - done--; - }, 2000); - }); - } else { // window exists, lets add missing tabs - let NewTabs = []; - let RefsTabs = {}; - - chrome.runtime.sendMessage({command: "get_folders", windowId: w.id}, function(f) { - chrome.runtime.sendMessage({command: "get_groups", windowId: w.id}, function(g) { - if (Object.keys(w.groups).length > 0) { - for (var group in w.groups) { - if (group != "" && group != "undefined" && w.groups[group] != undefined) { - g[w.groups[group].id] = Object.assign({}, w.groups[group]); - } - } - } - if (Object.keys(w.folders).length > 0) { - for (var folder in w.folders) { - if (folder != "" && folder != "undefined" && w.folders[folder] != undefined) { - w.folders[w.folders[folder].id] = Object.assign({}, w.folders[folder]); - } - } - } - - if (Object.keys(g).length > 0) { - for (var groupId in g) { - w.groups[groupId] = Object.assign({}, g[groupId]); - } - } - if (Object.keys(f).length > 0) { - for (var folderId in f) { - w.folders[folderId] = Object.assign({}, f[folderId]); - } - } - - chrome.runtime.sendMessage({command: "save_groups", windowId: w.id, groups: g}); - chrome.runtime.sendMessage({command: "save_folders", windowId: w.id, folders: f}); - chrome.runtime.sendMessage({ command: "remote_update", groups: w.groups, folders: w.folders, tabs: [], windowId: w.id }); - - if (w.id == tt.CurrentWindowId) { - RcreateTreeStructure(w.groups, w.folders, []); - } - - (w.tabs).forEach(function(Tab) { - if (Tab.url != "") { // missing tab, lets make one - chrome.tabs.create({ url: Tab.url, pinned: (Tab.parent == "pin_list" ? true : false), windowId: w.id }, function(tab) { - RefsTabs[Tab.id] = tab.id; - Tab.id = tab.id; - NewTabs.push(Tab); - chrome.runtime.sendMessage({command: "update_tab", tabId: tab.id, tab: {index: Tab.index, expand: Tab.expand, parent: Tab.parent}}); - }); - } else { - NewTabs.push(Tab); - } - }); - - setTimeout(function() { - ShowStatusBar({show: true, spinner: true, message: "Finding reference tabs..."}); - for (let tInd = 0; tInd < NewTabs.length; tInd++) { - if (RefsTabs[NewTabs[tInd].parent] != undefined) { - NewTabs[tInd].parent = RefsTabs[NewTabs[tInd].parent]; - } - } - }, 4000); - - setTimeout(function() { - for (let tInd = 0; tInd < NewTabs.length; tInd++) { - chrome.runtime.sendMessage({command: "update_tab", tabId: NewTabs[tInd].id, tab: {index: NewTabs[tInd].index, expand: NewTabs[tInd].expand, parent: NewTabs[tInd].parent}}); - } - let done = 10; - var Append = setInterval(function() { - ShowStatusBar({show: true, spinner: true, message: "Finding other windows to add tabs..."}); - - if (w.id == tt.CurrentWindowId) { - RcreateTreeStructure(w.groups, w.folders, NewTabs); - } else { - chrome.runtime.sendMessage({command: "remote_update", groups: w.groups, folders: w.folders, tabs: NewTabs, windowId: w.id }); - } - if (done < 0) { - ShowStatusBar({show: true, spinner: false, message: "All done.", hideTimeout: 2000}); - clearInterval(Append); - } - done--; - }, 500); - }, 6000); - - }); - }); - - } - }); - }); -} - - -function StartAutoSaveSession() { - if (opt.autosave_interval > 0 && opt.autosave_max_to_keep > 0) { - tt.AutoSaveSession = setInterval(function() { - if (opt.debug) { - log("f: AutoSaveSession, loop time is: "+opt.autosave_interval); - } - - let d = new Date(); - let newName = d.toLocaleString().replace("/", ".").replace("/", ".").replace(":", "꞉").replace(":", "꞉"); - ExportSession(newName, false, false, true); - - ShowStatusBar({show: true, spinner: false, message: "Autosave: "+newName, hideTimeout: 1500}); - - if (document.getElementById("manager_window").style.top != "-500px") { - chrome.storage.local.get(null, function(storage) { - ReAddSessionAutomaticToManagerList(storage); - }); - } - - }, opt.autosave_interval * 60000); - } -} \ No newline at end of file diff --git a/scripts/bookmark.js b/scripts/bookmark.js new file mode 100644 index 0000000..db943bd --- /dev/null +++ b/scripts/bookmark.js @@ -0,0 +1,80 @@ +function Bookmark(rootNode) { + let ToolbarId = browserId == "F" ? "toolbar_____" : "1"; + chrome.bookmarks.get(ToolbarId, function(list) { + chrome.bookmarks.search("TreeTabs", function(list) { + let TreeTabsId; + for (var elem in list) { + if (list[elem].parentId == ToolbarId) { + TreeTabsId = list[elem].id; + break; + } + } + if (TreeTabsId == undefined) { + chrome.bookmarks.create({parentId: ToolbarId, title: "TreeTabs"}, function(TreeTabsNew) { + TreeTabsId = TreeTabsNew.id; + }); + Bookmark(rootNode); + return; + } else { + let Tabs = document.querySelectorAll("#°" + rootNode.id + " .tab"); + if (rootNode.classList.contains("tab")) { + if (Tabs.length > 0) { + chrome.tabs.get(parseInt(rootNode.id), function(tab) { + if (tab) { + chrome.bookmarks.create({parentId: TreeTabsId, title: tab.title}, function(root) { + let TabNodes = document.querySelectorAll("[id='" + rootNode.id + "'], [id='" + rootNode.id + "'] .tab"); + for (let s of TabNodes) { + chrome.tabs.get(parseInt(s.id), function(tab) { + if (tab) chrome.bookmarks.create({parentId: root.id, title: tab.title, url: tab.url}); + }); + } + }); + } + }); + } else { + chrome.tabs.get(parseInt(rootNode.id), function(tab) { + if (tab) chrome.bookmarks.create({parentId: TreeTabsId, title: tab.title, url: tab.url}); + }); + } + } + if (rootNode.classList.contains("folder") || rootNode.classList.contains("group")) { + let rootName = labels.noname_group; + if (rootNode.classList.contains("folder") && tt.folders[rootNode.id]) rootName = tt.folders[rootNode.id].name; + if (rootNode.classList.contains("group") && tt.groups[rootNode.id]) rootName = tt.groups[rootNode.id].name; + chrome.bookmarks.create({parentId: TreeTabsId, title: rootName}, function(root) { + let Nodes = {}; + let folders = document.querySelectorAll("#°" + rootNode.id + " .folder"); + for (let f of folders) { + if (tt.folders[f.id]) { + chrome.bookmarks.create({parentId: root.id, title: tt.folders[f.id].name}, function(Bkfolder) { + Nodes[f.id] = {ttid: f.id, id: Bkfolder.id, ttparent: tt.folders[f.id].parent, parent: root.id}; + if (Object.keys(Nodes).length == folders.length) { + for (var elem in Nodes) { + if (Nodes[Nodes[elem].ttparent]) Nodes[Nodes[elem].ttid].parent = Nodes[Nodes[elem].ttparent].id; + } + for (var elem in Nodes) { + chrome.bookmarks.move(Nodes[elem].id, {parentId: Nodes[elem].parent}, function(BkFinalfolder) {}); + } + } + }); + } + } + setTimeout(function() { + let reverse_tabs = Array.from(Tabs).reverse(); + for (let t of reverse_tabs) { + chrome.tabs.get(parseInt(t.id), function(tab) { + if (tab) chrome.bookmarks.create({parentId: (Nodes[t.parentNode.parentNode.id] ? Nodes[t.parentNode.parentNode.id].id : root.id), title: tab.title, url: tab.url}); + }); + } + // Array.from(Tabs).reverse().forEach(function(t) { + // chrome.tabs.get(parseInt(t.id), function(tab) { + // if (tab) chrome.bookmarks.create({parentId: (Nodes[t.parentNode.parentNode.id] ? Nodes[t.parentNode.parentNode.id].id : root.id), title: tab.title, url: tab.url}); + // }); + // }); + }, 3000); + }); + } + } + }); + }); +} diff --git a/scripts/common.js b/scripts/common.js deleted file mode 100644 index 6e7a49e..0000000 --- a/scripts/common.js +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2017 kroppy. All rights reserved. -// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license -// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/ - -// GLOBAL VARIABLES -let browserId = navigator.userAgent.match("Opera|OPR") !== null ? "O" : (navigator.userAgent.match("Vivaldi") !== null ? "V" : (navigator.userAgent.match("Firefox") !== null ? "F" : "C" )) -let opt = {}; - -let labels = { - clear_filter: chrome.i18n.getMessage("caption_clear_filter"), - loading: chrome.i18n.getMessage("caption_loading"), - searchbox: chrome.i18n.getMessage("caption_searchbox"), - ungrouped_group: chrome.i18n.getMessage("caption_ungrouped_group"), - noname_group: chrome.i18n.getMessage("caption_noname_group") -}; - -// BACKGROUND VARIABLES -let b = { - debug: [], - running: false, - schedule_save: -999, - windows: {}, - tabs: {}, - tt_ids: {}, - NewTabsQueue: [], - EmptyTabs: [], - newTabUrl: browserId == "F" ? "about:newtab" : "chrome://startpage/" -}; - -// DEFAULTS NEEDED FOR START AND FOR OPTIONS PAGE -const DefaultToolbar = { - toolbar_main: ["button_new", "button_pin", "button_undo", "button_search", "button_tools", "button_groups", "button_backup", "button_folders"], - toolbar_search: ["button_filter_type", "filter_search_go_prev", "filter_search_go_next"], - toolbar_shelf_tools: (browserId == "F" ? ["button_manager_window", "button_options", "button_unload", "button_detach", "button_reboot"] : ["button_manager_window", "button_options", "button_bookmarks", "button_downloads", "button_history", "button_settings", "button_extensions", "button_unload", "button_detach", "button_reboot"]), - toolbar_shelf_groups: ["button_groups_toolbar_hide", "button_new_group", "button_remove_group", "button_edit_group", "button_import_group", "button_export_group"], - toolbar_shelf_backup: (browserId == "F" ? ["button_import_bak", "button_import_merge_bak", "button_export_bak"] : ["button_import_bak", "button_import_merge_bak", "button_export_bak", "button_load_bak1", "button_load_bak2", "button_load_bak3"]), - toolbar_shelf_folders: ["button_new_folder", "button_remove_folder", "button_edit_folder"] -}; - -const DefaultTheme = { - ToolbarShow: true, - ColorsSet: {}, - TabsSizeSetNumber: 2, - TabsMargins: "2", - theme_name: "untitled", - theme_version: 4 -}; - -const DefaultPreferences = { - hide_other_groups_tabs_firefox: false, - show_toolbar: true, - skip_load: false, - pin_list_multi_row: true, - always_show_close: false, - never_show_close: false, - allow_pin_close: false, - append_child_tab: "bottom", - append_child_tab_after_limit: "after", - append_orphan_tab: "bottom", - after_closing_active_tab: "below_seek_in_parent", - 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, - max_tree_drag_drop_folders: false, - switch_with_scroll: false, - syncro_tabbar_tabs_order: true, - show_counter_groups: true, - show_counter_tabs: true, - show_counter_tabs_hints: true, - groups_toolbar_default: true, - syncro_tabbar_groups_tabs_order: true, - midclick_tab: "close_tab", - dbclick_tab: "new_tab", - dbclick_group: "new_tab", - // dbclick_group_bar: "new_group", - midclick_group: "nothing", - midclick_folder: "nothing", - dbclick_folder: "rename_folder", - debug: false, - orphaned_tabs_to_ungrouped: false, - tab_group_regexes: [], - move_tabs_on_url_change: "never", - autosave_max_to_keep: 5, - autosave_interval: 15 -}; - -// SIDEBAR VARIABLES -// let active_group = "tab_list"; - -let tt = { - CurrentWindowId: 0, - active_group: "tab_list", - groups: {}, - folders: {}, - schedule_update_data: 0, - schedule_rearrange_tabs: 0, - DragNodeClass: "", - DragTreeDepth: 0, - DragOverId: "", - menuItemNode: undefined, - SearchIndex: 0, - DragOverTimer: undefined, - AutoSaveSession: undefined -}; - -// GLOBAL FUNCTIONS -function GenerateRandomID(){ - let letters = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","K","L","M","N","O","P","R","S","T","Q","U","V","W","Y","Z","a","b","c","d","e","f","g","h","i","k","l","m","n","o","p","r","s","t","q","u","v","w","y","z"]; - let random = ""; for (let letter = 0; letter < 6; letter++ ) {random += letters[Math.floor(Math.random() * letters.length)];} return random; -} - -function GetCurrentPreferences(storage) { - opt = Object.assign({}, DefaultPreferences); - if (storage["preferences"]) { - for (let parameter in storage["preferences"]) { - if (opt[parameter] != undefined) { - opt[parameter] = storage["preferences"][parameter]; - - // legacy, changed from "after_active" to "after", because it is a parent tab, not necessarily an active tab - if (parameter == "append_child_tab" && storage["preferences"][parameter] == "after_active") { - opt[parameter] = "after"; - } - } - } - } -} diff --git a/scripts/dom.js b/scripts/dom.js new file mode 100644 index 0000000..dde82d1 --- /dev/null +++ b/scripts/dom.js @@ -0,0 +1,720 @@ +function DOM_SetEvents() { + if (opt.debug) Utils_log("f: SetEvents, adding global events."); + let PinList = document.getElementById("pin_list"); + if (!opt.switch_with_scroll) { + PinList.onmousewheel = function(event) { + let pinList = document.getElementById("pin_list"); + let direction = (event.wheelDelta > 0 || event.detail < 0) ? -1 : 1; + let speed = 0.1; + for (let t = 1; t < 40; t++) { + setTimeout(function() { + if (t < 30) { + speed = speed + 0.1; // accelerate + } else { + speed = speed - 0.3; // decelerate + } + pinList.scrollLeft = pinList.scrollLeft + (direction * speed); + }, t); + } + } + } + window.addEventListener('contextmenu', function(event) { + if (event.target.classList.contains("text_input") == false && opt.debug == false) { + event.preventDefault(); + event.stopPropagation(); + event.stopImmediatePropagation(); + return false; + } + }, false); + document.getElementById("body").addEventListener('contextmenu', function(event) { + if (event.target.classList.contains("text_input") == false && opt.debug == false) { + event.preventDefault(); + event.stopPropagation(); + event.stopImmediatePropagation(); + return false; + } + }, false); + document.body.onresize = function(event) { + DOM_RefreshGUI(); + } + document.body.onmousedown = function(event) { + if (event.which == 2) event.preventDefault(); + if (event.which == 1 && event.target.classList.contains("menu_item") == false) Menu_HideMenus(); + event.stopImmediatePropagation(); + if (event.which == 1) DOM_RemoveHeadersHoverClass(); + } + document.getElementById("folder_edit_confirm").onmousedown = function(event) { + if (event.which == 1) Folders_FolderRenameConfirm(); + } + document.getElementById("folder_edit_discard").onmousedown = function(event) { + if (event.which == 1) DOM_HideRenameDialogs(); + } + document.getElementById("group_edit_confirm").onmousedown = function(event) { + if (event.which == 1) Groups_GroupEditConfirm(); + } + document.getElementById("group_edit_discard").onmousedown = function(event) { + if (event.which == 1) DOM_HideRenameDialogs(); + } + document.getElementById("folder_edit_name").onkeydown = function(event) { + if (event.keyCode == 13) Folders_FolderRenameConfirm(); + if (event.which == 27) DOM_HideRenameDialogs(); + } + document.getElementById("group_edit_name").onkeydown = function(event) { + if (event.keyCode == 13) Groups_GroupEditConfirm(); + if (event.which == 27) DOM_HideRenameDialogs(); + } + PinList.onclick = function(event) { + if (event.which == 1 && event.target == this) { + if (opt.pin_list_multi_row || (opt.pin_list_multi_row == false && event.clientY < (this.childNodes[0].getBoundingClientRect().height + this.getBoundingClientRect().top))) DOM_Deselect(); + } + } + PinList.onmousedown = function(event) { + if (event.which == 1 && event.target == this) { + if (opt.pin_list_multi_row || (opt.pin_list_multi_row == false && event.clientY < (this.childNodes[0].getBoundingClientRect().height + this.getBoundingClientRect().top))) Menu_HideMenus(); + } + if (event.which == 2 && event.target == this) Groups_ActionClickGroup(this, opt.midclick_group); + if (event.which == 3 && event.target == this) Menu_ShowFGlobalMenu(event); + } + PinList.ondragover = function(event) { + if (event.target.id == "pin_list" && tt.DraggingGroup == false && (tt.DraggingPin || tt.DraggingTab || tt.DraggingFolder) && this.classList.contains("highlighted_drop_target") == false) { + DOM_RemoveHighlight(); + this.classList.add("highlighted_drop_target"); + } + } + PinList.ondblclick = function(event) { + if (event.target == this) Groups_ActionClickGroup(this, opt.dbclick_group); + } + document.getElementById("group_edit_font").onclick = function(event) { + if (event.which == 1) { + event.stopPropagation(); + let ColorPicker = document.getElementById("color_picker"); + ColorPicker.setAttribute("PickColor", this.id); + ColorPicker.value = "#" + Utils_RGBtoHex(this.style.backgroundColor); + ColorPicker.focus(); + ColorPicker.click(); + } + } + document.getElementById("color_picker").oninput = function(event) { + document.getElementById(this.getAttribute("PickColor")).style.backgroundColor = this.value; + } + document.getElementById("group_list").ondragleave = function(event) { + if (opt.open_tree_on_hover) { + clearTimeout(tt.DragOverTimer); + tt.DragOverId = ""; + } + } + document.body.onkeydown = function(event) { + if (event.ctrlKey && event.which == 65) { // ctrl+a to select all + if (document.querySelector(".pin>.tab_header_hover") != null) { + let query = document.querySelectorAll(".pin"); + for (let s of query) { + s.classList.add("selected"); + } + } + if (document.querySelectorAll("#" + tt.active_group + " .tab>.tab_header_hover, #" + tt.active_group + " .folder>.folder_header_hover").length > 0) { + let rootId = document.querySelectorAll("#" + tt.active_group + " .tab>.tab_header_hover, #" + tt.active_group + " .folder>.folder_header_hover")[0].parentNode.parentNode.parentNode.id; + let query = document.querySelectorAll("#°" + rootId + ">.folder, #°" + rootId + ">.tab"); + for (let s of query) { + s.classList.add("selected"); + } + } + } + if (event.ctrlKey && event.which == 73) { // ctrl+i to invert selection + if (document.querySelector(".pin>.tab_header_hover") != null) { + let query = document.querySelectorAll(".pin"); + for (let s of query) { + s.classList.toggle("selected"); + } + } + if (document.querySelectorAll("#" + tt.active_group + " .tab>.tab_header_hover, #" + tt.active_group + " .folder>.folder_header_hover").length > 0) { + let rootId = document.querySelectorAll("#" + tt.active_group + " .tab>.tab_header_hover, #" + tt.active_group + " .folder>.folder_header_hover")[0].parentNode.parentNode.parentNode.id; + let query = document.querySelectorAll("#°" + rootId + ">.folder, #°" + rootId + ">.tab"); + for (let s of query) { + s.classList.toggle("selected"); + } + } + } + if (event.which == 27) DOM_Deselect(); // esc to unselect tabs and folders + if (event.altKey && event.which == 71) Groups_GroupsToolbarToggle(); // alt+g to toggle group bar + if (event.which == 192 || event.which == 70) { // new folder + if (tt.pressed_keys.indexOf(event.which) == -1) tt.pressed_keys.push(event.which); + if (tt.pressed_keys.indexOf(192) != -1 && tt.pressed_keys.indexOf(70) != -1) { + let FolderId = Folders_AddNewFolder({}); + Folders_ShowRenameFolderDialog(FolderId); + } + } + DOM_RefreshGUI(); + } + + document.body.onkeyup = function(event) { + if (tt.pressed_keys.indexOf(event.which) != -1) tt.pressed_keys.splice(tt.pressed_keys.indexOf(event.which), 1); + } + document.body.ondragover = function(event) { + if (opt.debug) Utils_log("drag over: " + event.target.id); + event.preventDefault(); + } + document.ondrop = function(event) { + if (opt.debug) Utils_log("dropped on window: " + tt.CurrentWindowId); + let Nodes = event.dataTransfer.getData("Nodes") ? JSON.parse(event.dataTransfer.getData("Nodes")) : []; + let NodesTypes = event.dataTransfer.getData("NodesTypes") ? JSON.parse(event.dataTransfer.getData("NodesTypes")) : {DraggingGroup: false, DraggingPin: false, DraggingTab: false, DraggingFolder: false}; + let Group = event.dataTransfer.getData("Group") ? JSON.parse(event.dataTransfer.getData("Group")) : {}; + let SourceWindowId = event.dataTransfer.getData("SourceWindowId") ? JSON.parse(event.dataTransfer.getData("SourceWindowId")) : 0; + let target = document.querySelector(".highlighted_drop_target"); + let where = target ? (target.classList.contains("before") ? "before" : (target.classList.contains("after") ? "after" : "inside")) : ""; + let ActiveGroup = document.getElementById(tt.active_group); + let Scroll = ActiveGroup.scrollTop; + clearTimeout(tt.DragOverTimer); + tt.DragOverId = ""; + tt.Dragging = false; + chrome.runtime.sendMessage({command: "drag_end"}); + event.preventDefault(); + if (SourceWindowId == tt.CurrentWindowId) { + DOM_DropToTarget({NodesTypes: NodesTypes, Nodes: Nodes, TargetNode: target, where: where, Group: Group, Scroll: Scroll}); + } else { + DOM_FreezeSelection(); + if (NodesTypes.DraggingGroup) { + tt.groups[Group.id] = Object.assign({}, Group); + Groups_AppendGroupToList(Group.id, Group.name, Group.font, true); + } + let TabsIds = []; + for (let i = 0; i < Nodes.length; i++) { + if (Nodes[i].NodeClass == "folder") { + Folders_AddNewFolder({folderId: Nodes[i].id, ParentId: Nodes[i].parent, Name: Nodes[i].name, Index: Nodes[i].index, ExpandState: Nodes[i].expand}); + chrome.runtime.sendMessage({command: "remove_folder", folderId: Nodes[i].id}); + } + if (Nodes[i].NodeClass == "pin") { + chrome.tabs.update(parseInt(Nodes[i].id), {pinned: false}); + TabsIds.push(parseInt(Nodes[i].id)); + } + if (Nodes[i].NodeClass == "tab") TabsIds.push(parseInt(Nodes[i].id)); + } + chrome.tabs.move(TabsIds, {windowId: tt.CurrentWindowId, index: -1}, function(MovedTab) { + let Stop = 500; + let DropNodes = setInterval(function() { + Stop--; + let all_ok = true; + for (let i = 0; i < Nodes.length; i++) { + if (document.getElementById(Nodes[i].id) == null) all_ok = false; + } + DOM_DropToTarget({NodesTypes: NodesTypes, Nodes: Nodes, TargetNode: target, where: where, Group: Group, Scroll: Scroll}); + if (NodesTypes.DraggingGroup) chrome.runtime.sendMessage({command: "remove_group", groupId: Group.id}); + if (all_ok || Stop < 0) { + setTimeout(function() { + clearInterval(DropNodes); + }, 300); + } + }, 100); + }); + } + } + document.ondragleave = function(event) { + if (opt.debug) Utils_log("global dragleave"); + DOM_RemoveHighlight(); + if (opt.open_tree_on_hover) { + clearTimeout(tt.DragOverTimer); + tt.DragOverId = ""; + } + } + document.ondragend = function(event) { + if (opt.debug) Utils_log("drag_end"); + let Nodes = event.dataTransfer.getData("Nodes") ? JSON.parse(event.dataTransfer.getData("Nodes")) : []; + let NodesTypes = event.dataTransfer.getData("NodesTypes") ? JSON.parse(event.dataTransfer.getData("NodesTypes")) : {DraggingGroup: false, DraggingPin: false, DraggingTab: false, DraggingFolder: false}; + let Group = event.dataTransfer.getData("Group") ? JSON.parse(event.dataTransfer.getData("Group")) : {}; + setTimeout(function() { + if (tt.Dragging && ((browserId == "F" && ( event.screenX < event.view.mozInnerScreenX || event.screenX > (event.view.mozInnerScreenX + window.innerWidth) || event.screenY < event.view.mozInnerScreenY || event.screenY > (event.view.mozInnerScreenY + window.innerHeight))) || (browserId != "F" && (event.pageX < 0 || event.pageX > window.outerWidth || event.pageY < 0 || event.pageY > window.outerHeight)))) Tabs_Detach(Nodes, NodesTypes, Group); + DOM_CleanUpDragAndDrop(); + tt.Dragging = false; + chrome.runtime.sendMessage({command: "drag_end"}); + }, 300); + if (opt.open_tree_on_hover) { + clearTimeout(tt.DragOverTimer); + tt.DragOverId = ""; + } + } +} + +function DOM_BindTabsSwitchingToMouseWheel(Id) { + if (opt.debug) Utils_log("f: BindTabsSwitchingToMouseWheel, binding tabs switch to group: " + Id); + document.getElementById(Id).onwheel = function(event) { + event.preventDefault(); + let prev = event.deltaY < 0; + if (prev) { + Tabs_ActivatePrevTab(true); + } else { + Tabs_ActivateNextTab(true); + } + } +} + +function DOM_InsertDropToTarget(p) { + if (p.AppendToTarget) { + for (let i = 0; i < p.Nodes.length; i++) { + let Node = document.getElementById(p.Nodes[i].id); + if (Node != null) { + if (p.Nodes[i].selected) { + DOM_AppendToNode(Node, p.TargetNode); + Node.classList.add("selected"); + if (p.Nodes[i].temporary) Node.classList.add("selected_temporarly"); + } else { + if (Node.parentNode.id != p.Nodes[i].parent) DOM_AppendToNode(Node, document.getElementById(p.Nodes[i].parent)); + } + } + } + } + if (p.BeforeTarget) { + for (i = 0; i < p.Nodes.length; i++) { + let Node = document.getElementById(p.Nodes[i].id); + if (Node != null) { + if (p.Nodes[i].selected) { + DOM_InsterBeforeNode(Node, p.TargetNode); + Node.classList.add("selected"); + if (p.Nodes[i].temporary) Node.classList.add("selected_temporarly"); + } else { + if (Node.parentNode.id != p.Nodes[i].parent) DOM_AppendToNode(Node, document.getElementById(p.Nodes[i].parent)); + } + } + } + } + if (p.AfterTarget) { + let i = p.after ? (p.Nodes.length - 1) : 0; + for (i = p.Nodes.length - 1; i >= 0; i--) { + let Node = document.getElementById(p.Nodes[i].id); + if (Node != null) { + if (p.Nodes[i].selected) { + DOM_InsterAfterNode(Node, p.TargetNode); + Node.classList.add("selected"); + if (p.Nodes[i].temporary) Node.classList.add("selected_temporarly"); + } else { + if (Node.parentNode.id != p.Nodes[i].parent) DOM_AppendToNode(Node, document.getElementById(p.Nodes[i].parent)); + } + } + } + } +} + +function DOM_New(type, parent, parameters, style) { + let NewElement = document.createElement(type); + for (param in parameters) { + NewElement[param] = parameters[param]; + } + for (param in style) { + NewElement.style[param] = style[param]; + } + if (parent) parent.appendChild(NewElement); + return NewElement; +} + +async function DOM_SetStyle(node, style) { + for (param in style) { + node.style[param] = style[param]; + } +} + +function DOM_SetClasses(node, add, remove, toggle) { + let Ind = 0; + for (Ind = 0; Ind < add.length; Ind++) { + node.classList.add(add[Ind]); + } + for (Ind = 0; Ind < remove.length; Ind++) { + node.classList.remove(remove[Ind]); + } + for (Ind = 0; Ind < toggle.length; Ind++) { + node.classList.toggle(toggle[Ind]); + } +} + +function DOM_DropToTarget(p) { // Class: ("group", "tab", "folder"), DraggedTabNode: TabId, TargetNode: query node, TabsIdsSelected: arr of selected tabIds, TabsIds: arr of tabIds, TabsIdsParents: arr of parent tabIds, Folders: object with folders objects, FoldersSelected: arr of selected folders ids, Group: groupId, Scroll: bool + if (p.TargetNode != null) { + let pinTabs = false; + if (p.NodesTypes.DraggingPin || p.NodesTypes.DraggingTab || p.NodesTypes.DraggingFolder) { + if (p.TargetNode.classList.contains("pin") || p.TargetNode.classList.contains("tab") || p.TargetNode.classList.contains("folder")) { + if (p.TargetNode.classList.contains("pin")) pinTabs = true; + if (p.where == "inside") DOM_InsertDropToTarget({TargetNode: p.TargetNode.childNodes[1], AppendToTarget: true, Nodes: p.Nodes}); // PINS NEVER HAVE INSIDE, SO WILL BE IGNORED + if (p.where == "before") DOM_InsertDropToTarget({TargetNode: p.TargetNode, BeforeTarget: true, Nodes: p.Nodes}); + if (p.where == "after") DOM_InsertDropToTarget({TargetNode: p.TargetNode, AfterTarget: true, Nodes: p.Nodes}); + } + if (p.TargetNode.id == "pin_list") { + DOM_InsertDropToTarget({TargetNode: p.TargetNode, AppendToTarget: true, Nodes: p.Nodes}); + pinTabs = true; + } + if (p.TargetNode.classList.contains("group")) DOM_InsertDropToTarget({TargetNode: p.TargetNode.childNodes[0], AppendToTarget: true, Nodes: p.Nodes}); + if (p.TargetNode.classList.contains("group_button")) { + let group = document.getElementById("°" + p.TargetNode.id.substr(1)); + DOM_InsertDropToTarget({TargetNode: group, Nodes: p.Nodes, AppendToTarget: true}); + } + setTimeout(function() {Folders_SaveFolders();}, 600); + } + if (p.NodesTypes.DraggingGroup) { + if (p.where == "before") DOM_InsterBeforeNode(document.getElementById("_" + p.Group.id), p.TargetNode); + if (p.where == "after") DOM_InsterAfterNode(document.getElementById("_" + p.Group.id), p.TargetNode); + Groups_UpdateBgGroupsOrder(); + Groups_RearrangeGroupsLists(); + } + for (i = 0; i < p.Nodes.length; i++) { + if (p.Nodes[i].NodeClass == "pin" || p.Nodes[i].NodeClass == "tab") { + if (tt.tabs[p.Nodes[i].id]) { + if (tt.tabs[p.Nodes[i].id].Node.classList.contains("pin") != pinTabs) { + tt.tabs[p.Nodes[i].id].SetTabClass(pinTabs); + tt.tabs[p.Nodes[i].id].pinned = pinTabs; + chrome.tabs.update(parseInt(p.Nodes[i].id), {pinned: pinTabs}); + } + } + } + } + if (opt.syncro_tabbar_tabs_order) { + let tabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s) {return parseInt(s.id);}); + for (i = 0; i < p.Nodes.length; i++) { + if (p.Nodes[i].NodeClass == "pin" || p.Nodes[i].NodeClass == "tab") chrome.tabs.move(parseInt(p.Nodes[i].id), {index: tabIds.indexOf(parseInt(p.Nodes[i].id))}); + } + setTimeout(function() {tt.schedule_rearrange_tabs++;}, 500); + } + } + Groups_KeepOnlyOneActiveTabInGroup(); + DOM_RefreshExpandStates(); + DOM_RefreshCounters(); + setTimeout(function() { + DOM_RemoveHighlight(); + }, 100); + setTimeout(function() { + if (opt.syncro_tabbar_groups_tabs_order) tt.schedule_rearrange_tabs++; + // DOM_RefreshExpandStates(); + // DOM_RefreshCounters(); + tt.schedule_update_data++; + DOM_RefreshGUI(); + DOM_CleanUpDragAndDrop(); + if (opt.debug) Utils_log("DropToTarget END"); + }, 500); +} + +function DOM_AppendToNode(Node, AppendNode) { + if (Node != null && AppendNode != null) AppendNode.appendChild(Node); +} + +function DOM_InsterBeforeNode(Node, BeforeNode) { + if (Node != null && BeforeNode != null) BeforeNode.parentNode.insertBefore(Node, BeforeNode); +} + +function DOM_InsterAfterNode(Node, AfterNode) { + if (Node != null && AfterNode != null) { + if (AfterNode.nextSibling != null) { + AfterNode.parentNode.insertBefore(Node, AfterNode.nextSibling); + } else { + AfterNode.parentNode.appendChild(Node); + } + } +} + +function DOM_PromoteChildrenToFirstChild(Node) { + let NewParent = Node.childNodes[1].firstChild.childNodes[1]; + Node.childNodes[1].parentNode.parentNode.insertBefore(Node.childNodes[1].firstChild, Node.childNodes[1].parentNode); + while (Node.childNodes[1].firstChild) { + NewParent.appendChild(Node.childNodes[1].firstChild); + } +} + +function DOM_GetAllParents(Node) { + let Parents = []; + let ParentNode = Node.parentNode; + while (ParentNode.parentNode != null) { + Parents.push(ParentNode.parentNode); + ParentNode = ParentNode.parentNode; + } + return Parents; +} + +function DOM_GetParentsByClass(Node, Class) { + let Parents = []; + let ParentNode = Node; + if (ParentNode == null) return Parents; + while (ParentNode.parentNode != null) { + if (ParentNode.parentNode.classList != undefined && ParentNode.parentNode.classList.contains(Class)) Parents.push(ParentNode.parentNode); + ParentNode = ParentNode.parentNode; + } + return Parents; +} + +function DOM_GetParentsBy2Classes(Node, ClassA, ClassB) { + let Parents = []; + let ParentNode = Node; + while (ParentNode.parentNode != null) { + if (ParentNode.parentNode.classList != undefined && ParentNode.parentNode.classList.contains(ClassA) && ParentNode.parentNode.classList.contains(ClassB)) Parents.push(ParentNode.parentNode); + ParentNode = ParentNode.parentNode; + } + return Parents; +} + +function DOM_HideRenameDialogs() { + let query = document.querySelectorAll(".edit_dialog"); + for (let s of query) { + DOM_SetStyle(s, {display: "none", top: "-500px", left: "-500px"}); + } +} + +function DOM_EventExpandBox(Node) { + if (Node.classList.contains("o")) { + Node.classList.remove("o"); Node.classList.add("c"); + if (Node.classList.contains("tab")) chrome.runtime.sendMessage({command: "update_tab", tabId: parseInt(Node.id), tab: {expand: "c"}}); + if (Node.classList.contains("folder")) Folders_SaveFolders(); + } else { + if (Node.classList.contains("c")) { + if (opt.collapse_other_trees) { + let thisTreeTabs = DOM_GetParentsByClass(Node.childNodes[0], "tab"); // start from tab's first child, instead of tab, important to include clicked tab as well + let thisTreeFolders = DOM_GetParentsByClass(Node.childNodes[0], "folder"); + let query = document.querySelectorAll("#" + tt.active_group + " .o.tab"); + for (let s of query) { + DOM_SetClasses(s, ["c"], ["o"], []); + chrome.runtime.sendMessage({command: "update_tab", tabId: parseInt(s.id), tab: {expand: "c"}}); + } + query = document.querySelectorAll("#" + tt.active_group + " .o.folder"); + for (let s of query) { + DOM_SetClasses(s, ["c"], ["o"], []); + } + for (let s of thisTreeTabs) { + DOM_SetClasses(s, ["o"], ["c"], []); + chrome.runtime.sendMessage({command: "update_tab", tabId: parseInt(s.id), tab: {expand: "o"}}); + } + for (let s of thisTreeFolders) { + DOM_SetClasses(s, ["o"], ["c"], []); + } + Folders_SaveFolders(); + if (Node.classList.contains("tab") && tt.tabs[Node.id]) tt.tabs[Node.id].ScrollToTab(); + } else { + DOM_SetClasses(Node, ["o"], ["c"], []); + if (Node.classList.contains("tab")) chrome.runtime.sendMessage({command: "update_tab", tabId: parseInt(Node.id), tab: {expand: "o"}}); + if (Node.classList.contains("folder")) Folders_SaveFolders(); + } + } + } +} + +function DOM_Select(event, TabNode) { + if (event.shiftKey) { // SET SELECTION WITH SHIFT + let LastSelected = document.querySelector("#" + tt.active_group + " .selected.selected_last"); + if (LastSelected == null) LastSelected = document.querySelector(".pin.active_tab, #" + tt.active_group + " .tab.active_tab"); + if (LastSelected != null && TabNode.parentNode.id == LastSelected.parentNode.id) { + if (!event.ctrlKey) { + let query = document.querySelectorAll(".pin.selected, #" + tt.active_group + " .selected"); + for (let s of query) { + DOM_SetClasses(s, [], ["selected_frozen", "selected_temporarly", "selected", "selected_last"], []); + } + } + let ChildrenArray = Array.from(TabNode.parentNode.children); + let activeTabIndex = ChildrenArray.indexOf(LastSelected); + let thisTabIndex = ChildrenArray.indexOf(TabNode); + let fromIndex = thisTabIndex >= activeTabIndex ? activeTabIndex : thisTabIndex; + let toIndex = thisTabIndex >= activeTabIndex ? thisTabIndex : activeTabIndex; + for (let i = fromIndex; i <= toIndex; i++) { + LastSelected.parentNode.childNodes[i].classList.add("selected"); + if (i == toIndex && event.ctrlKey) LastSelected.parentNode.childNodes[i].classList.add("selected_last"); + } + } + } + if (event.ctrlKey && !event.shiftKey) { // TOGGLE SELECTION WITH CTRL + TabNode.classList.toggle("selected"); + if (TabNode.classList.contains("selected")) { + let query = document.querySelectorAll(".selected_last"); + for (let s of query) { + s.classList.remove("selected_last"); + } + TabNode.classList.add("selected_last"); + } else { + TabNode.classList.remove("selected_last"); + } + } +} + +function DOM_Deselect() { + let query = document.querySelectorAll("#pin_list .selected"); + for (let s of query) { + s.classList.remove("selected"); + } + query = document.querySelectorAll("#" + tt.active_group + " .selected"); + for (let s of query) { + s.classList.remove("selected"); + } +} + +function DOM_FreezeSelection(all) { + if (all) { + let query = document.querySelectorAll(".selected"); + for (let s of query) { + DOM_SetClasses(s, ["selected_frozen"], ["selected", "selected_last"], []); + } + } else { + let query = document.querySelectorAll(".group:not(#" + tt.active_group + ") .selected"); + for (let s of query) { + DOM_SetClasses(s, ["selected_frozen"], ["selected", "selected_last"], []); + } + } +} + +function DOM_CleanUpDragAndDrop() { + if (opt.debug) Utils_log("f: CleanUpDragAndDrop, unfreezing and removing temporary classes..."); + let query = document.querySelectorAll(".selected_frozen"); + for (let s of query) { + DOM_SetClasses(s, ["selected"], ["selected_frozen"], []); + } + query = document.querySelectorAll(".selected_temporarly"); + for (let s of query) { + DOM_SetClasses(s, [], ["selected", "selected_frozen"], []); + } + query = document.querySelectorAll(".tab_header_hover"); + for (let s of query) { + s.classList.remove("tab_header_hover"); + } + query = document.querySelectorAll(".folder_header_hover"); + for (let s of query) { + s.classList.remove("folder_header_hover"); + } + query = document.querySelectorAll(".dragged_tree"); + for (let s of query) { + s.classList.remove("dragged_tree"); + } + query = document.querySelectorAll(".dragged_parents"); + for (let s of query) { + s.classList.remove("dragged_parents"); + } + if (opt.debug) Utils_log("f: removing DraggingParams..."); + tt.DragTreeDepth = 0; + tt.DraggingGroup = false; + tt.DraggingTab = false; + tt.DraggingFolder = false; + tt.DraggingPin = false; + tt.DragOverId = ""; +} + +function DOM_RemoveHighlight() { + let query = document.querySelectorAll(".highlighted_drop_target"); + for (let s of query) { + DOM_SetClasses(s, [], ["before", "after", "inside", "highlighted_drop_target"], []); + } +} + +function DOM_RemoveHeadersHoverClass() { + let query = document.querySelectorAll(".folder_header_hover, .tab_header_hover"); + for (let s of query) { + DOM_SetClasses(s, [], ["folder_header_hover", "tab_header_hover"], []); + } +} + +function DOM_Loadi18n() { + let query = document.querySelectorAll(".button, .manager_window_toolbar_button"); + for (let s of query) { + s.title = chrome.i18n.getMessage(s.id); + } + query = document.querySelectorAll(".menu_item, .edit_dialog_button, #manager_window_header_title, .manager_window_label"); + for (let s of query) { + s.textContent = chrome.i18n.getMessage(s.id); + } +} + +async function DOM_RefreshExpandStates() { // refresh open closed trees states + let query = document.querySelectorAll("#" + tt.active_group + " .folder, #" + tt.active_group + " .tab"); + for (let s of query) { + if (s.childNodes[1].children.length == 0) { + s.classList.remove("o"); s.classList.remove("c"); + } else { + if (s.classList.contains("o") == false && s.classList.contains("c") == false) s.classList.add("o"); + } + } + query = document.querySelectorAll(".pin"); + for (let s of query) { + s.classList.remove("o"); s.classList.remove("c"); + } +} + +async function DOM_RefreshCounters() { + if (opt.show_counter_tabs || opt.show_counter_tabs_hints) { + let query = document.querySelectorAll("#" + tt.active_group + " .o.tab, #" + tt.active_group + " .c.tab"); + for (let s of query) { + if (opt.show_counter_tabs) s.childNodes[0].childNodes[1].childNodes[0].textContent = document.querySelectorAll("[id='" + s.id + "'] .tab").length; + if (opt.show_counter_tabs_hints) { + let title = s.childNodes[0].getAttribute("tabTitle"); + s.childNodes[0].title = (document.querySelectorAll("[id='" + s.id + "'] .tab").length + " • ") + title; + } + } + query = document.querySelectorAll("#" + tt.active_group + " .folder"); + for (let s of query) { + if (opt.show_counter_tabs && tt.folders[s.id]) s.childNodes[0].childNodes[1].childNodes[0].textContent = document.querySelectorAll("[id='" + s.id + "'] .tab").length; + if (opt.show_counter_tabs_hints && tt.folders[s.id]) s.childNodes[0].title = (document.querySelectorAll("[id='" + s.id + "'] .tab").length + " • ") + tt.folders[s.id].name; + } + } +} + +async function DOM_RefreshGUI() { + let toolbar = document.getElementById("toolbar"); + let toolbarHeight = 27; + if (toolbar.children.length > 0) { + DOM_SetStyle(toolbar, {height: "", width: "", display: "", border: "", padding: ""}); + if (document.querySelector(".on.button") != null) { + toolbar.style.height = "53px"; + toolbarHeight = 54; + } else { + toolbar.style.height = "26px"; + } + } else { + DOM_SetStyle(toolbar, {height: "0px", width: "0px", display: "none", border: "none", padding: "0"}); + toolbar.style.height = "0px"; + toolbarHeight = 0; + } + let group_list = document.getElementById("group_list"); + group_list.style.width = document.body.clientWidth + 50 + "px"; + let pin_list = document.getElementById("pin_list"); + if (pin_list.children.length > 0) { + DOM_SetStyle(pin_list, {top: toolbarHeight + "px", height: "", width: "", display: "", border: "", padding: ""}); + } else { + DOM_SetStyle(pin_list, {top: "0px", height: "0px", width: "0px", display: "none", border: "none", padding: "0"}); + } + let pin_listHeight = pin_list.getBoundingClientRect().height; + let toolbar_groups = document.getElementById("toolbar_groups"); + DOM_SetStyle(toolbar_groups, {top: toolbarHeight + pin_listHeight + "px", height: document.body.clientHeight - toolbarHeight - pin_listHeight + "px"}); + let toolbar_groupsWidth = toolbar_groups.getBoundingClientRect().width; + if (opt.show_counter_groups) { + let query = document.querySelectorAll(".group"); + for (let s of query) { + let groupLabel = document.getElementById("_gte" + s.id); + if (groupLabel) groupLabel.textContent = (tt.groups[s.id] ? tt.groups[s.id].name : labels.noname_group) + " (" + document.querySelectorAll("#" + s.id + " .tab").length + ")"; + } + } else { + let query = document.querySelectorAll(".group"); + for (let s of query) { + let groupLabel = document.getElementById("_gte" + s.id); + if (groupLabel) groupLabel.textContent = tt.groups[s.id] ? tt.groups[s.id].name : labels.noname_group; + } + } + let query = document.querySelectorAll(".group_button"); + for (let s of query) { + s.style.height = s.firstChild.getBoundingClientRect().height + "px"; + } + let groups = document.getElementById("groups"); + let groupsHeight = document.body.clientHeight - toolbarHeight - pin_listHeight; + let groupsWidth = document.body.clientWidth - toolbar_groupsWidth - 1; + DOM_SetStyle(groups, {top: toolbarHeight + pin_listHeight + "px", left: toolbar_groupsWidth + "px", height: groupsHeight + "px", width: groupsWidth + "px"}); + let PanelList = document.querySelector(".mw_pan_on>.manager_window_list"); + let PanelListHeight = 3 + PanelList.children.length * 18; + let ManagerWindowPanelButtons = document.querySelector(".mw_pan_on>.manager_window_panel_buttons"); + let ManagerWindowPanelButtonsHeight = ManagerWindowPanelButtons.clientHeight; + let MaxAllowedHeight = document.body.clientHeight - 140; + if (PanelListHeight + ManagerWindowPanelButtonsHeight < MaxAllowedHeight) { + PanelList.style.height = PanelListHeight + "px"; + } else { + PanelList.style.height = MaxAllowedHeight - ManagerWindowPanelButtonsHeight + "px"; + } + let ManagerWindow = document.getElementById("manager_window"); + ManagerWindow.style.height = PanelList.clientHeight + ManagerWindowPanelButtonsHeight + 56 + "px"; +} + +function DOM_AutoRefreshMediaIcons() { // if changeInfo.audible listener does not work, this is my own implementation, hopefully this will not affect performance too much + setInterval(function() { + chrome.tabs.query({currentWindow: true, audible: true, discarded: false}, function(tabs) { + let query = document.querySelectorAll(".audible, .muted"); + for (let s of query) { + s.classList.remove("audible"); s.classList.remove("muted"); + } + for (let tab of tabs) { + if (tab.audible) document.getElementById(tab.id).classList.add("audible"); + if (tab.mutedInfo.muted) document.getElementById(tab.id).classList.add("muted"); + } + }); + }, 2000); +} \ No newline at end of file diff --git a/scripts/events.js b/scripts/events.js deleted file mode 100644 index 1c07bf9..0000000 --- a/scripts/events.js +++ /dev/null @@ -1,655 +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 SetEvents() { - if (opt.debug) { - log("f: SetEvents, adding global events."); - } - - let PinList = document.getElementById("pin_list"); - - if (!opt.switch_with_scroll) { - PinList.onmousewheel = function(event) { - let pinList = document.getElementById("pin_list"); - let direction = (event.wheelDelta > 0 || event.detail < 0) ? -1 : 1; - let speed = 0.1; - for (let t = 1; t < 40; t++) { - setTimeout(function() { - if (t < 30) { - speed = speed+0.1; // accelerate - } else { - speed = speed-0.3; // decelerate - } - pinList.scrollLeft = pinList.scrollLeft+(direction*speed); - }, t); - } - } - } - - document.oncontextmenu = function (event) { - if (!event.ctrlKey && event.target.classList.contains("text_input") == false) { - event.preventDefault(); - event.stopPropagation(); - return false; - } - }; - - window.addEventListener('contextmenu', function (event) { - if (!event.ctrlKey && event.target.classList.contains("text_input") == false) { - event.preventDefault(); - event.stopPropagation(); - return false; - } - }, false); - - - document.body.onresize = function(event) { - RefreshGUI(); - } - - // MOUSE DOWN EVENTS - document.body.onmousedown = function(event) { - if (event.which == 2) { - event.preventDefault(); - } - - if (event.which == 1 && event.target.classList.contains("menu_item") == false) { - HideMenus(); - } - event.stopImmediatePropagation(); - - if (event.which == 1) { - RemoveHeadersHoverClass(); - } - } - - // CONFIRM EDIT FOLDER - document.getElementById("folder_edit_confirm").onmousedown = function(event) { - if (event.which == 1) { - FolderRenameConfirm(); - } - } - - // DISCARD EDIT FOLDER - document.getElementById("folder_edit_discard").onmousedown = function(event) { - if (event.which == 1) { - HideRenameDialogs(); - } - } - - // CONFIRM EDIT GROUP - document.getElementById("group_edit_confirm").onmousedown = function(event) { - if (event.which == 1) { - GroupEditConfirm(); - } - } - // DISCARD EDIT GROUP - document.getElementById("group_edit_discard").onmousedown = function(event) { - if (event.which == 1) { - HideRenameDialogs(); - } - } - document.getElementById("folder_edit_name").onkeydown = function(event) { - if (event.keyCode == 13) { - FolderRenameConfirm(); - } - if (event.which == 27) { - HideRenameDialogs(); - } - } - document.getElementById("group_edit_name").onkeydown = function(event) { - if (event.keyCode == 13) { - GroupEditConfirm(); - } - if (event.which == 27) { - HideRenameDialogs(); - } - } - PinList.onclick = function(event) { - if (event.which == 1 && event.target == this) { - if (opt.pin_list_multi_row || (opt.pin_list_multi_row == false && event.clientY < (this.childNodes[0].getBoundingClientRect().height + this.getBoundingClientRect().top))) { - DeselectFolders(); - DeselectTabs(); - } - } - } - PinList.onmousedown = function(event) { - if (event.which == 1 && event.target == this) { - if (opt.pin_list_multi_row || (opt.pin_list_multi_row == false && event.clientY < (this.childNodes[0].getBoundingClientRect().height + this.getBoundingClientRect().top))) { - HideMenus(); - } - } - - if (event.which == 2 && event.target == this) { - ActionClickGroup(this, opt.midclick_group); - } - if (event.which == 3 && event.target == this) { - ShowFGlobalMenu(event); - } - } - PinList.ondragover = function(event) { - // PIN,TAB==>PINLIST - if (event.target.id == "pin_list" && tt.DragNodeClass == "tab" && this.classList.contains("highlighted_drop_target") == false) { - RemoveHighlight(); - this.classList.add("highlighted_drop_target"); - } - } - - // DOUBLE CLICK ACTION - PinList.ondblclick = function(event) { - if (event.target == this) { - ActionClickGroup(this, opt.dbclick_group); - } - } - - - // SHOW COLOR PICKER - document.getElementById("group_edit_font").onclick = function(event) { - if (event.which == 1) { - event.stopPropagation(); - let ColorPicker = document.getElementById("color_picker"); - ColorPicker.setAttribute("PickColor", this.id); - ColorPicker.value = "#"+RGBtoHex(this.style.backgroundColor); - ColorPicker.focus(); - ColorPicker.click(); - } - } - document.getElementById("color_picker").oninput = function(event) { - document.getElementById(this.getAttribute("PickColor")).style.backgroundColor = this.value; - } - - - document.getElementById("group_list").ondragleave = function(event) { - if (opt.open_tree_on_hover) { - clearTimeout(tt.DragOverTimer); - tt.DragOverId = ""; - } - } - - - // CATCH KEYBOARD GLOBAL KEYS - document.body.onkeydown = function(event) { - // ctrl+a to select all - if (event.ctrlKey && event.which == 65) { - if (document.querySelector(".pin>.tab_header_hover") != null) { - document.querySelectorAll(".pin").forEach(function(s){ - s.classList.add("selected_tab"); - }); - } - if (document.querySelector("#"+tt.active_group+" .tab>.tab_header_hover") != null) { - let rootId = document.querySelector("#"+tt.active_group+" .tab>.tab_header_hover").parentNode.parentNode.parentNode.id; - document.querySelectorAll("#ct"+rootId+">.tab").forEach(function(s){ - s.classList.add("selected_tab"); - }); - } - } - // ctrl+i to invert selection - if (event.ctrlKey && event.which == 73) { - if (document.querySelector(".pin>.tab_header_hover") != null) { - document.querySelectorAll(".pin").forEach(function(s){ - s.classList.toggle("selected_tab"); - }); - } - if (document.querySelector("#"+tt.active_group+" .tab>.tab_header_hover") != null) { - let rootId = document.querySelector("#"+tt.active_group+" .tab>.tab_header_hover").parentNode.parentNode.parentNode.id; - document.querySelectorAll("#ct"+rootId+">.tab").forEach(function(s){ - s.classList.toggle("selected_tab"); - }); - } - } - // esc to deselect tabs - if (event.which == 27) { - DeselectTabs(); - DeselectFolders(); - } - // alt+g to toggle group bar - if (event.altKey && event.which == 71) { - GroupsToolbarToggle(); - } - - // new folder - if (event.which == 192 && event.which == 70 && event.which == 69) { - let FolderId = AddNewFolder({SetEvents: true}); - ShowRenameFolderDialog(FolderId); - } - RefreshGUI(); - } - - - document.body.ondragover = function(event) { - if (opt.debug) { - log("drag over: "+event.target.id); - } - event.preventDefault(); - } - - document.ondrop = function(event) { - if (opt.debug) { - log("dropped on window: "+tt.CurrentWindowId); - } - - let Class = event.dataTransfer.getData("Class") ? event.dataTransfer.getData("Class") : ""; - let Group = event.dataTransfer.getData("Group") ? JSON.parse(event.dataTransfer.getData("Group")) : {}; - let DraggedTabNode = event.dataTransfer.getData("DraggedTabNode") ? event.dataTransfer.getData("DraggedTabNode") : false; - let TabsIds = event.dataTransfer.getData("TabsIds") ? JSON.parse(event.dataTransfer.getData("TabsIds")) : []; - let TabsIdsParents = event.dataTransfer.getData("TabsIdsParents") ? JSON.parse(event.dataTransfer.getData("TabsIdsParents")) : []; - let TabsIdsSelected = event.dataTransfer.getData("TabsIdsSelected") ? JSON.parse(event.dataTransfer.getData("TabsIdsSelected")) : []; - let Folders = event.dataTransfer.getData("Folders") ? JSON.parse(event.dataTransfer.getData("Folders")) : {}; - let FoldersSelected = event.dataTransfer.getData("FoldersSelected") ? JSON.parse(event.dataTransfer.getData("FoldersSelected")) : []; - let SourceWindowId = event.dataTransfer.getData("SourceWindowId") ? JSON.parse(event.dataTransfer.getData("SourceWindowId")) : 0; - let target = document.querySelector(".highlighted_drop_target"); - - let ActiveGroup = document.getElementById(tt.active_group); - let Scroll = ActiveGroup.scrollTop; - - clearTimeout(tt.DragOverTimer); - tt.DragOverId = ""; - - event.preventDefault(); - - if (SourceWindowId == tt.CurrentWindowId) { - if (Class == "group") { - DropToTarget({Class: Class, DraggedTabNode: DraggedTabNode, TargetNode: target, TabsIds: [], TabsIdsSelected: [], TabsIdsParents: [], Folders: {}, FoldersSelected: [], Group: Group, Scroll: Scroll}); - } else { - DropToTarget({Class: Class, DraggedTabNode: DraggedTabNode, TargetNode: target, TabsIds: TabsIds, TabsIdsSelected: TabsIdsSelected, TabsIdsParents: TabsIdsParents, Folders: Folders, FoldersSelected: FoldersSelected, Group: Group, Scroll: Scroll}); - } - } else { - FreezeSelected(); - - if (Object.keys(Group).length > 0) { - tt.groups[Group.id] = Object.assign({}, Group); - AppendGroupToList(Group.id, Group.name, Group.font, true); - } - - - if (Object.keys(Folders).length > 0) { - for (var folderId in Folders) { - AddNewFolder({folderId: folderId, ParentId: Folders[folderId].parent, Name: Folders[folderId].name, Index: Folders[folderId].index, ExpandState: Folders[folderId].expand, AdditionalClass: (FoldersSelected.indexOf(folderId) != -1 ? "selected_folder" : undefined), SetEvents: true}); - chrome.runtime.sendMessage({ command: "remove_folder", folderId: folderId }); - } - } - - if (opt.debug) { - log("DragAndDrop: will now move tabs"); - } - - chrome.tabs.move(TabsIds, { windowId: tt.CurrentWindowId, index: -1 }, function(MovedTab) { - setTimeout(function() { - DropToTarget({Class: Class, DraggedTabNode: DraggedTabNode, TargetNode: target, TabsIds: TabsIds, TabsIdsSelected: TabsIdsSelected, TabsIdsParents: TabsIdsParents, Folders: Folders, FoldersSelected: FoldersSelected, Group: Group, Scroll: Scroll}); - chrome.runtime.sendMessage({ command: "remove_group", groupId: Group.id }); - }, 2000); - }); - } - } - - - document.ondragleave = function(event) { - if (opt.debug) { - log("global dragleave"); - } - RemoveHighlight(); - if (opt.open_tree_on_hover) { - clearTimeout(tt.DragOverTimer); - tt.DragOverId = ""; - } - } - - document.ondragend = function(event) { - if (opt.open_tree_on_hover) { - clearTimeout(tt.DragOverTimer); - tt.DragOverId = ""; - } - // log("document dragend"); - // DETACHING TEMPORARILY DISABLED PLEASE USE MENU OR TOOLBAR! - // if (DragAndDrop.ComesFromWindowId == tt.CurrentWindowId && DragAndDrop.DroppedToWindowId == 0) { - // if ((browserId == "F" && ( event.screenX < event.view.mozInnerScreenX || event.screenX > (event.view.mozInnerScreenX + window.innerWidth) || event.screenY < event.view.mozInnerScreenY || event.screenY > (event.view.mozInnerScreenY + window.innerHeight)))|| (browserId != "F" && (event.pageX < 0 || event.pageX > window.outerWidth || event.pageY < 0 || event.pageY > window.outerHeight))) { - // log("dragged outside sidebar"); - // if (tt.DragNodeClass == "tab") { - // Detach(DragAndDrop.TabsIds, {}); - // } - // if (tt.DragNodeClass == "folder") { - // Detach(DragAndDrop.TabsIds, DragAndDrop.Folders); - // setTimeout(function() { - // SaveFolders(); - // }, 500); - // } - // } - // } - setTimeout(function() { - CleanUpDragClasses(); - chrome.runtime.sendMessage({command: "dragend"}); - }, 500); - } -} - - -function BindTabsSwitchingToMouseWheel(Id) { - if (opt.debug) { - log("f: BindTabsSwitchingToMouseWheel, binding tabs switch to group: "+Id); - } - - document.getElementById(Id).onwheel = function(event) { - event.preventDefault(); - let prev = event.deltaY < 0; - if (prev) { - ActivatePrevTab(); - } else { - ActivateNextTab(); - } - } -} - -function RemoveHighlight() { - document.querySelectorAll(".highlighted_drop_target").forEach(function(s){ - if (opt.debug) { - log("removing highlight of: " + s.id); - } - s.classList.remove("before"); - s.classList.remove("after"); - s.classList.remove("inside"); - s.classList.remove("highlighted_drop_target"); - }); -} - -function RemoveHeadersHoverClass() { - document.querySelectorAll(".folder_header_hover, .tab_header_hover").forEach(function(s){ - if (opt.debug) { - log("removing hover of: " + s.id); - } - s.classList.remove("folder_header_hover"); - s.classList.remove("tab_header_hover"); - }); -} - - - -function DropToTarget(p) { // Class: ("group", "tab", "folder"), DraggedTabNode: TabId, TargetNode: query node, TabsIdsSelected: arr of selected tabIds, TabsIds: arr of tabIds, TabsIdsParents: arr of parent tabIds, Folders: object with folders objects, FoldersSelected: arr of selected folders ids, Group: groupId, Scroll: bool - if (p.TargetNode != null) { - if (opt.debug) { - log("f: DropToTarget, DragNodeClass: "+p.Class+", TargetNode: "+p.TargetNode.id+", TabsIdsSelected: "+JSON.stringify(p.TabsIdsSelected)+", TabsIds: "+JSON.stringify(p.TabsIds)+", TabsIdsParents: "+JSON.stringify(p.TabsIdsParents)+", Folders: "+JSON.stringify(p.Folders)+", FoldersSelected: "+JSON.stringify(p.FoldersSelected) ); - } - - let ActiveGroup = document.getElementById(tt.active_group); - let pinTabs = false; - let SelectedTabsAppendTarget; - let FoldersSelectedAppendTarget; - - if (p.Class == "tab") { - if (p.TargetNode.classList.contains("pin")) { - pinTabs = true; - if (p.TargetNode.classList.contains("before")) { - p.TabsIds.forEach(function(tabId){ - InsterBeforeNode(document.getElementById(tabId), p.TargetNode); - }); - } - if (p.TargetNode.classList.contains("after")) { - for (let i = p.TabsIds.length-1; i >= 0; i--) { - InsterAfterNode(document.getElementById(p.TabsIds[i]), p.TargetNode); - } - } - } - - if (p.TargetNode.classList.contains("tab")) { - if (p.TargetNode.classList.contains("before")) { - p.TabsIdsSelected.forEach(function(tabId){ - InsterBeforeNode(document.getElementById(tabId), p.TargetNode); - }); - } - if (p.TargetNode.classList.contains("after")) { - for (let i = p.TabsIdsSelected.length-1; i >= 0; i--) { - InsterAfterNode(document.getElementById(p.TabsIdsSelected[i]), p.TargetNode); - } - } - if (p.TargetNode.classList.contains("inside")) { - SelectedTabsAppendTarget = p.TargetNode.childNodes[1]; - } - ActiveGroup.scrollTop = p.Scroll; - } - - if (p.TargetNode.id == "pin_list") { - pinTabs = true; - SelectedTabsAppendTarget = p.TargetNode; - } - - if (p.TargetNode.classList.contains("group")) { - SelectedTabsAppendTarget = p.TargetNode.childNodes[1]; - ActiveGroup.scrollTop = p.Scroll; - } - - if (p.TargetNode.classList.contains("folder")) { - SelectedTabsAppendTarget = p.TargetNode.childNodes[2]; - ActiveGroup.scrollTop = p.Scroll; - } - - if (p.TargetNode.classList.contains("group_button")) { // dropped on group button (group list) - SelectedTabsAppendTarget = document.getElementById("ct" + (p.TargetNode.id.substr(1))); - } - } - - - if (p.Class == "folder") { - if (p.TargetNode.classList.contains("folder")) { // dropped on folder - if (p.TargetNode.classList.contains("before")) { - p.FoldersSelected.forEach(function(folderId){ - InsterBeforeNode(document.getElementById(folderId), p.TargetNode); - }); - } - if (p.TargetNode.classList.contains("after")) { - for(let i = p.FoldersSelected.length-1; i >= 0; i--) { - InsterAfterNode(document.getElementById(p.FoldersSelected[i]), p.TargetNode); - } - } - if (p.TargetNode.classList.contains("inside")) { - FoldersSelectedAppendTarget = p.TargetNode.childNodes[1]; - } - ActiveGroup.scrollTop = p.Scroll; - } - - if (p.TargetNode.classList.contains("group")) { - FoldersSelectedAppendTarget = p.TargetNode.childNodes[0]; - ActiveGroup.scrollTop = p.Scroll; - } - - if (p.TargetNode.classList.contains("group_button")) { // dropped on group button (group list) - FoldersSelectedAppendTarget = document.getElementById("cf" + p.TargetNode.id.substr(1)); - } - - setTimeout(function() { - SaveFolders(); - }, 600); - } - - if (p.TargetNode.classList.contains("group_button") && (p.Class == "tab" || p.Class == "folder")) { - chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) { - let Tab = document.getElementById(activeTab[0].id); - if (Tab != null && p.TabsIds.indexOf(activeTab[0].id) != -1) { - SetActiveGroup(p.TargetNode.id.substr(1), false, false); - SetActiveTab(activeTab[0].id, true); - } - }); - } - - if (p.Class == "group") { - if (p.TargetNode.classList.contains("before")) { - InsterBeforeNode(document.getElementById("_"+p.Group.id), p.TargetNode); - } - if (p.TargetNode.classList.contains("after")) { - InsterAfterNode(document.getElementById("_"+p.Group.id), p.TargetNode); - } - UpdateBgGroupsOrder(); - RearrangeGroupsLists(); - if (opt.syncro_tabbar_groups_tabs_order) { - tt.schedule_rearrange_tabs++; - } - } - - if (FoldersSelectedAppendTarget) { - p.FoldersSelected.forEach(function(folderId){ - AppendToNode(document.getElementById(folderId), FoldersSelectedAppendTarget); - }); - } - - if (SelectedTabsAppendTarget) { - p.TabsIdsSelected.forEach(function(tabId){ - AppendToNode(document.getElementById(tabId), SelectedTabsAppendTarget); - }); - } - - - // recheck new structure - if (Object.keys(p.Folders).length > 0) { - for (var folderId in p.Folders) { - if (p.FoldersSelected.indexOf(folderId) == -1) { - let Folder = document.getElementById(folderId); - if (Folder != null && Folder.parentNode.id != "cf" + p.Folders[folderId].parent) { - let FolderParent = document.getElementById("cf" + p.Folders[folderId].parent); - if (FolderParent != null) { - FolderParent.appendChild(Folder); - } - } - } - } - } - - - - - if (p.TabsIds.length) { - if (pinTabs) { - for (var ind = 0; ind < p.TabsIds.length; ind++) { - let Tab = document.getElementById(p.TabsIds[ind]); - if (Tab != null && Tab.parentNode.id != "pin_list") { - document.getElementById("pin_list").appendChild(Tab); - } - } - } else { - for (var ind = 0; ind < p.TabsIds.length; ind++) { - if (p.TabsIdsSelected.indexOf(p.TabsIds[ind]) == -1) { - let Tab = document.getElementById(p.TabsIds[ind]); - let TabParent = document.getElementById(p.TabsIdsParents[ind]); - if (TabParent != null && Tab != null && TabParent.id != Tab.parentNode.id) { - TabParent.appendChild(Tab); - } - } - } - } - } - - - - - SetMultiTabsClass(p.TabsIds, pinTabs); - - p.TabsIdsSelected.forEach(function(selectedTabId) { - let selectedTab = document.getElementById(selectedTabId); - if (selectedTab != null) { - selectedTab.classList.add("selected_tab"); - } - }); - - if (p.DraggedTabNode) { - let tabNode = document.getElementById(p.DraggedTabNode); - if (tabNode != null) { - tabNode.classList.add("selected_temporarly"); - } - } - - if (opt.syncro_tabbar_tabs_order && p.TabsIds[0] != undefined) { - let tabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s){ - return parseInt(s.id); - }); - - if (opt.debug) { - log( "f: DropToTarget, will Syncro tabbar tabs order, TabsIds array is:"+JSON.stringify(p.TabsIds) ); - } - - chrome.tabs.move(p.TabsIds, {index: tabIds.indexOf(p.TabsIds[0])}); - setTimeout(function() { - tt.schedule_rearrange_tabs++; - }, 500); - } - } - - KeepOnlyOneActiveTabInGroup(); - - setTimeout(function() { - RefreshExpandStates(); - RefreshCounters(); - tt.schedule_update_data++; - RefreshGUI(); - EmptyDragAndDrop(); - - if (opt.debug) { - log("DropToTarget END"); - } - }, 500); - - setTimeout(function() { - CleanUpDragClasses(); - RemoveHighlight(); - }, 100); -} - - - -function FreezeSelected() { - document.querySelectorAll(".selected_tab").forEach(function(s){ - if (opt.debug) { - log("freezing selected tab: " + s.id); - } - s.classList.add("selected_frozen"); - s.classList.remove("selected_tab"); - s.classList.remove("selected_last"); - }); - document.querySelectorAll(".selected_folder").forEach(function(s){ - if (opt.debug) { - log("freezing selected folder: " + s.id); - } - s.classList.add("selected_folder_frozen"); - s.classList.remove("selected_folder"); - }); -} - - -function CleanUpDragClasses() { - if (opt.debug) { - log("f: CleanUpDragClasses, unfreezing and removing temporary classes..."); - } - document.querySelectorAll(".selected_frozen").forEach(function(s){ - s.classList.add("selected_tab"); - s.classList.remove("selected_frozen"); - }); - document.querySelectorAll(".selected_temporarly").forEach(function(s){ - s.classList.remove("selected_tab"); - s.classList.remove("selected_temporarly"); - }); - document.querySelectorAll(".selected_folder_frozen").forEach(function(s){ - s.classList.add("selected_folder"); - s.classList.remove("selected_folder_frozen"); - }); - document.querySelectorAll(".selected_folder_temporarly").forEach(function(s){ - s.classList.remove("selected_folder"); - s.classList.remove("selected_folder_temporarly"); - }); - document.querySelectorAll(".tab_header_hover").forEach(function(s){ - s.classList.remove("tab_header_hover"); - }); - document.querySelectorAll(".folder_header").forEach(function(s){ - s.classList.remove("folder_header_hover"); - }); - document.querySelectorAll(".dragged_tree").forEach(function(s){ - s.classList.remove("dragged_tree"); - }); - document.querySelectorAll(".dragged_parents").forEach(function(s){ - s.classList.remove("dragged_parents"); - }); -} - -function EmptyDragAndDrop() { - if (opt.debug) { - log("f: EmptyDragAndDrop and removing DragNodeClass..."); - } - tt.DragNodeClass = ""; - tt.DragTreeDepth = 0; -} \ No newline at end of file diff --git a/scripts/file.js b/scripts/file.js new file mode 100644 index 0000000..780dd48 --- /dev/null +++ b/scripts/file.js @@ -0,0 +1,22 @@ +function File_ShowOpenFileDialog(extension) { + let inp = DOM_New("input", document.getElementById("body"), {id: "file_import", type: "file", accept: extension}, {display: "none"}); + inp.click(); + return inp; +} + +function File_SaveFile(filename, extension, data) { + if (browserId == "V") { + chrome.tabs.create({url: "vivaldi/save_file.html"}, async function(tab) { + setTimeout(function() { + chrome.runtime.sendMessage({command: "save_file", filename: filename, extension: extension, data: data}); + }, 500); + }); + } else { + let file = new File([JSON.stringify(data)], filename + "." + extension, {type: "text/" + extension + ";charset=utf-8"}); + let savelink = DOM_New("a", document.getElementById("body"), {href:URL.createObjectURL(file), fileSize: file.size, target: "_blank", type: "file", download: (filename + "." + extension)}, {display: "none"}); + savelink.click(); + setTimeout(function() { + savelink.parentNode.removeChild(savelink); + }, 60000); + } +} \ No newline at end of file diff --git a/scripts/folders.js b/scripts/folders.js index 8e780f8..016a9ac 100644 --- a/scripts/folders.js +++ b/scripts/folders.js @@ -1,504 +1,283 @@ -// 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 AddNewFolder(p) { // folderId: string, ParentId: string, Name: string, Index: int, ExpandState: ("o","c"), AdditionalClass: string, SetEvents: bool - let newId = p.folderId ? p.folderId : GenerateNewFolderID(); - tt.folders[newId] = { id: newId, parent: (p.ParentId ? p.ParentId : ""), index: (p.Index ? p.Index : 0), name: (p.Name ? p.Name : labels.noname_group), expand: (p.ExpandState ? p.ExpandState : "") }; - if (opt.debug) { - log("f: AddNewFolder, folder: "+JSON.stringify(tt.folders[newId])); - } - AppendFolder(newId, labels.noname_group, (p.ParentId ? p.ParentId : ""), undefined, p.SetEvents, p.AdditionalClass); - SaveFolders(); - RefreshCounters(); - RefreshExpandStates(); - return newId; +function Folders_AddNewFolder(p) { // folderId: string, ParentId: string, Name: string, Index: int, ExpandState: ("o","c"), AdditionalClass: string, SetEvents: bool + let newId = p.folderId ? p.folderId : Folders_GenerateNewFolderID(); + tt.folders[newId] = {id: newId, parent: (p.ParentId ? p.ParentId : ""), index: (p.Index ? p.Index : 0), name: (p.Name ? p.Name : labels.noname_group), expand: (p.ExpandState ? p.ExpandState : "")}; + Folders_AppendFolder({folderId: newId, Name: tt.folders[newId].name, InsertAfterId: p.InsertAfterId, ParentId: p.ParentId, ExpandState: p.ExpandState, SkipSetEvents: p.SkipSetEvents, AdditionalClass: p.AdditionalClass}); + Folders_SaveFolders(); + DOM_RefreshCounters(); + DOM_RefreshExpandStates(); + return newId; } -function AppendFolder(folderId, Name, ParentId, Expand, SetEvents, AdditionalClass) { - if (opt.debug) { - log("f: AppendFolder, folder: "+JSON.stringify(tt.folders[folderId])); - } - let ClassList = "folder "; - if (AdditionalClass != undefined) { - ClassList = ClassList + AdditionalClass; - } - if (document.getElementById(folderId) == null) { - let fd = document.createElement("div"); fd.className = ClassList; if (Expand) { fd.className += Expand } fd.id = folderId; // FOLDER - let fh = document.createElement("div"); fh.className = (opt.always_show_close && !opt.never_show_close) ? "folder_header close_show" : "folder_header"; fh.id = "folder_header"+folderId; if (SetEvents) {fh.draggable = true;} fd.appendChild(fh); // HEADER - let ex = document.createElement("div"); ex.className = "folder_icon"; ex.id = "fop"+folderId; fh.appendChild(ex); - let ftbc = document.createElement("div"); ftbc.className = "folder_counter"; ftbc.id = "folder_counter"+folderId; fh.appendChild(ftbc); // TABS COUNTER - let fbcn = document.createElement("div"); fbcn.className = "counter_number"; fbcn.id = "counter_number"+folderId; ftbc.appendChild(fbcn); // TABS COUNTER NUMBER - - - let ft = document.createElement("div"); ft.className = "folder_title"; ft.id = "folder_title"+folderId; ft.textContent = Name; fh.appendChild(ft); // TITLE - let cf = document.createElement("div"); cf.className = "children_folders"; cf.id = "cf"+folderId; fd.appendChild(cf); - let ct = document.createElement("div"); ct.className = "children_tabs"; ct.id = "ct"+folderId; fd.appendChild(ct); - let di = document.createElement("div"); di.className = "drag_indicator"; di.id = "di"+folderId; fd.appendChild(di); // DROP TARGET INDICATOR - let cl = undefined; - if (!opt.never_show_close) { - cl = document.createElement("div"); cl.className = "close"; cl.id = "close"+folderId; fh.appendChild(cl); // CLOSE BUTTON - let ci = document.createElement("div"); ci.className = "close_img"; ci.id = "close_img"+folderId; cl.appendChild(ci); - } - - if (SetEvents) { - ct.ondblclick = function(event) { - if (event.target == this) { - ActionClickGroup(this.parentNode, opt.dbclick_group); - } - } - cf.ondblclick = function(event) { - if (event.target == this) { - ActionClickGroup(this.parentNode, opt.dbclick_group); - } - } - - cf.onclick = function(event) { - if (event.target == this && event.which == 1) { - DeselectFolders(); - DeselectTabs(); - } - } - ct.onclick = function(event) { - if (event.target == this && event.which == 1) { - DeselectFolders(); - DeselectTabs(); - } - } - cf.onmousedown = function(event) { - if (event.target == this) { - if (event.which == 2 && event.target == this) { - event.stopImmediatePropagation(); - ActionClickGroup(this.parentNode, opt.midclick_group); - } - if (event.which == 3) { - ShowFGlobalMenu(event); - } - } - } - ct.onmousedown = function(event) { - if (event.target == this) { - if (event.which == 2 && event.target == this) { - event.stopImmediatePropagation(); - ActionClickGroup(this.parentNode, opt.midclick_group); - } - if (event.which == 3) { - ShowFGlobalMenu(event); - } - } - } - - if (!opt.never_show_close && cl) { - cl.onmousedown = function(event) { - event.stopImmediatePropagation(); - if (event.which != 3) { - RemoveFolder(this.parentNode.parentNode.id); - } - } - cl.onmouseenter = function(event) { - this.classList.add("close_hover"); - } - cl.onmouseleave = function(event) { - this.classList.remove("close_hover"); - } - } - fh.onclick = function(event) { - // SELECT FOLDER - if (event.which == 1 && !event.shiftKey) { - DeselectTabs(); - if (!event.ctrlKey && this.parentNode.classList.contains("selected_folder") == false) { - DeselectFolders(); - } - if (event.ctrlKey) { - this.parentNode.classList.toggle("selected_folder"); - } - } - } - fh.onmousedown = function(event) { - if (document.getElementById("main_menu").style.top != "-1000px") { - HideMenus(); - } - if (event.which == 2) { - event.preventDefault(); - ActionClickFolder(this.parentNode, opt.midclick_folder); - } - // SHOW FOLDER MENU - if (event.which == 3) { - ShowFolderMenu(this.parentNode, event); - } - } - // edit folder - fh.ondblclick = function(event) { - if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target.classList.contains("folder_header")) { - ActionClickFolder(this.parentNode, opt.dbclick_folder); - } - } - fh.ondragstart = function(event) { // DRAG START - FolderStartDrag(this, event); - } - fh.ondragenter = function(event) { - this.classList.remove("folder_header_hover"); - } - fh.onmouseover = function(event) { - this.classList.add("folder_header_hover"); - if (opt.never_show_close == false && opt.always_show_close == false) { - this.classList.add("close_show"); - } - } - fh.onmouseleave = function(event) { - this.classList.remove("folder_header_hover"); - if (opt.never_show_close == false && opt.always_show_close == false) { - this.classList.remove("close_show"); - } - } - - fh.ondragleave = function(event) { - RemoveHighlight(); - } - - fh.ondragover = function(event) { - FolderDragOver(this, event); - if (opt.open_tree_on_hover && tt.DragOverId != this.id) { - if (this.parentNode.classList.contains("c") && this.parentNode.classList.contains("dragged_tree") == false) { - clearTimeout(tt.DragOverTimer); - tt.DragOverId = this.id; - let This = this; - tt.DragOverTimer = setTimeout(function() { - if (tt.DragOverId == This.id) { - This.parentNode.classList.add("o"); - This.parentNode.classList.remove("c"); - } - }, 1500); - } - } - } - - ex.onmousedown = function(event) { - event.stopPropagation(); - if (document.getElementById("main_menu").style.top != "-1000px") { - HideMenus(); - } - // EXPAND/COLLAPSE FOLDER - if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target == this) { - event.stopPropagation(); - EventExpandBox(this.parentNode.parentNode); - RefreshExpandStates(); - RefreshCounters(); - } - } - } - if (ParentId == "" || ParentId == undefined || document.getElementById("cf"+ParentId) == null) { - document.getElementById("cf"+tt.active_group).appendChild(fd); - } else { - document.getElementById("cf"+ParentId).appendChild(fd); - } - } +function Folders_AppendFolder(p) { // folderId: string, ParentId: string, Name: string, ExpandState: ("o","c"), AdditionalClass: string, SetEvents: bool + let ClassList = "folder"; + if (p.ExpandState) ClassList += " " + p.ExpandState; + if (p.AdditionalClass != undefined) ClassList += " " + p.AdditionalClass; + if (document.getElementById(p.folderId) == null) { + let DIV_folder = DOM_New("div", undefined, {id: p.folderId, className: ClassList}); + let DIV_header = DOM_New("div", DIV_folder, {id: ("folder_header_" + p.folderId), className: ((opt.always_show_close && !opt.never_show_close) ? "folder_header close_show" : "folder_header"), draggable: (!p.SkipSetEvents ? true : false)}); + let DIV_expand = DOM_New("div", DIV_header, {id: ("folder_expand_" + p.folderId), className: "folder_icon"}); + let DIV_counter = DOM_New("div", DIV_header, {id: ("folder_counter_" + p.folderId), className: "folder_counter"}); + DOM_New("div", DIV_counter, {id: ("folder_counter_number_" + p.folderId), className: "counter_number"}); + DOM_New("div", DIV_header, {id: ("folder_title_" + p.folderId), className: "folder_title", textContent: p.Name}); + let DIV_children = DOM_New("div", DIV_folder, {id: ("°" + p.folderId), className: "children"}); + DOM_New("div", DIV_folder, {id: (p.folderId + "_drag_indicator"), className: "drag_indicator"}); + let DIV_close_button = DOM_New("div", DIV_header, {id: ("close" + p.folderId), className : (opt.never_show_close ? "close hidden" : "close")}); + DOM_New("div", DIV_close_button, {id: ("close_img" + p.folderId), className: (opt.never_show_close ? "close_img hidden" : "close_img")}); + if (!p.SkipSetEvents) { + DIV_children.ondblclick = function(event) { + if (event.target == this) Groups_ActionClickGroup(this.parentNode, opt.dbclick_group); + } + DIV_children.onclick = function(event) { + if (event.target == this && event.which == 1) DOM_Deselect(); + } + DIV_children.onmousedown = function(event) { + event.stopImmediatePropagation(); + if (event.target == this) { + if (event.which == 2 && event.target == this) Groups_ActionClickGroup(this.parentNode, opt.midclick_group); + if (event.which == 3) Menu_ShowFGlobalMenu(event); + } + } + if (!opt.never_show_close) { + DIV_close_button.onmousedown = function(event) { + event.stopImmediatePropagation(); + if (event.which != 3) Folders_RemoveFolder(this.parentNode.parentNode.id); + } + DIV_close_button.onmouseenter = function(event) { + this.classList.add("close_hover"); + } + DIV_close_button.onmouseleave = function(event) { + this.classList.remove("close_hover"); + } + } + DIV_header.onclick = function(event) { + if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target.classList.contains("folder_header")) DOM_Deselect(); + } + DIV_header.onmousedown = function(event) { + event.stopImmediatePropagation(); + if (tt.DOMmenu.style.top != "-1000px") Menu_HideMenus(); + if (event.which == 1) DOM_Select(event, this.parentNode); + if (event.which == 2) { + event.preventDefault(); + Folders_ActionClickFolder(this.parentNode, opt.midclick_folder); + } + if (event.which == 3) Menu_ShowFolderMenu(this.parentNode, event); // SHOW FOLDER MENU + } + DIV_header.ondblclick = function(event) { // edit folder + if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target.classList.contains("folder_header")) Folders_ActionClickFolder(this.parentNode, opt.dbclick_folder); + } + DIV_header.ondragstart = function(event) { // DRAG START + event.stopPropagation(); + event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0); + event.dataTransfer.setData("text", ""); + event.dataTransfer.setData("SourceWindowId", tt.CurrentWindowId); + DOM_CleanUpDragAndDrop(); + tt.Dragging = true; + tt.DraggingGroup = false; + tt.DragTreeDepth = -1; + let Nodes = []; + if (this.parentNode.classList.contains("selected")) { + DOM_FreezeSelection(false); + } else { + DOM_FreezeSelection(true); + DOM_SetClasses(this.parentNode, ["selected_temporarly", "selected"], [], []); + } + DOM_RemoveHeadersHoverClass(); + let selected = document.querySelectorAll(".selected, .selected .tab, .selected .folder"); + for (let s of selected) { + s.classList.add("dragged_tree"); + if (s.classList.contains("pin")) { + tt.DraggingPin = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "pin"}); + } + if (s.classList.contains("tab")) { + tt.DraggingTab = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "tab"}); + } + if (s.classList.contains("folder")) { + tt.DraggingFolder = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "folder", index: (tt.folders[s.id] ? tt.folders[s.id].index : 0), name: (tt.folders[s.id] ? tt.folders[s.id].name : labels.noname_group), expand: (tt.folders[s.id] ? tt.folders[s.id].expand : "")}); + } + } + let DraggedFolderParents = DOM_GetParentsByClass(this.parentNode, "folder"); + for (let s of DraggedFolderParents) { + s.classList.add("dragged_parents"); + } + event.dataTransfer.setData("Nodes", JSON.stringify(Nodes)); + event.dataTransfer.setData("NodesTypes", JSON.stringify({DraggingGroup: tt.DraggingGroup, DraggingPin: tt.DraggingPin, DraggingTab: tt.DraggingTab, DraggingFolder: tt.DraggingFolder})); + chrome.runtime.sendMessage({command: "drag_start", DragTreeDepth: tt.DragTreeDepth, DraggingGroup: tt.DraggingGroup, DraggingPin: tt.DraggingPin, DraggingTab: tt.DraggingTab, DraggingFolder: tt.DraggingFolder}); + } + DIV_header.ondragenter = function(event) { + this.classList.remove("folder_header_hover"); + } + DIV_header.ondragend = function(event) { + if (opt.open_tree_on_hover) { + clearTimeout(tt.DragOverTimer); + tt.DragOverId = ""; + } + setTimeout(function() {DOM_CleanUpDragAndDrop();}, 300); + setTimeout(function() {chrome.runtime.sendMessage({command: "drag_end"});}, 500); + } + DIV_header.onmouseover = function(event) { + this.classList.add("folder_header_hover"); + if (opt.never_show_close == false && opt.always_show_close == false) this.classList.add("close_show"); + } + DIV_header.onmouseleave = function(event) { + this.classList.remove("folder_header_hover"); + if (opt.never_show_close == false && opt.always_show_close == false) this.classList.remove("close_show"); + } + DIV_header.ondragleave = function(event) { + DOM_RemoveHighlight(); + } + DIV_header.ondragover = function(event) { + if (tt.DraggingGroup == false && (tt.DraggingPin || tt.DraggingTab || tt.DraggingFolder) && this.parentNode.classList.contains("dragged_tree") == false) { + if (this.parentNode.classList.contains("before") == false && event.layerY < this.clientHeight / 3) { + DOM_RemoveHighlight(); + DOM_SetClasses(this.parentNode, ["before", "highlighted_drop_target"], ["inside", "after"], []); + } + if (this.parentNode.classList.contains("inside") == false && event.layerY > this.clientHeight / 3 && event.layerY <= 2 * (this.clientHeight / 3)) { + DOM_RemoveHighlight(); + DOM_SetClasses(this.parentNode, ["inside", "highlighted_drop_target"], ["before", "after"], []); + } + if (this.parentNode.classList.contains("after") == false && this.parentNode.classList.contains("o") == false && event.layerY > 2 * (this.clientHeight / 3)) { + DOM_RemoveHighlight(); + DOM_SetClasses(this.parentNode, ["after", "highlighted_drop_target"], ["inside", "before"], []); + } + } + if (opt.open_tree_on_hover && tt.DragOverId != this.id) { + if (this.parentNode.classList.contains("c") && this.parentNode.classList.contains("dragged_tree") == false) { + clearTimeout(tt.DragOverTimer); + tt.DragOverId = this.id; + let This = this; + tt.DragOverTimer = setTimeout(function() { + if (tt.DragOverId == This.id) DOM_SetClasses(This.parentNode, ["o"], ["c"], []); + }, 1500); + } + } + } + DIV_expand.onmousedown = function(event) { + event.stopPropagation(); + if (tt.DOMmenu.style.top != "-1000px") Menu_HideMenus(); + if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target == this) { // EXPAND/COLLAPSE FOLDER + event.stopPropagation(); + DOM_EventExpandBox(this.parentNode.parentNode); + DOM_RefreshExpandStates(); + DOM_RefreshCounters(); + } + } + } + if (p.ParentId == "pin_list" || p.ParentId == "" || p.ParentId == undefined || document.getElementById("°" + p.ParentId) == null) { + document.getElementById("°" + tt.active_group).appendChild(DIV_folder); + } else { + document.getElementById("°" + p.ParentId).appendChild(DIV_folder); + } + if (p.InsertAfterId) { + let After = document.getElementById(p.InsertAfterId); + if (After != null) DOM_InsterAfterNode(DIV_folder, After); + } + } } -function GenerateNewFolderID() { - let newID = ""; - while (newID == "") { - newID = "f_"+GenerateRandomID(); - if (document.getElementById(newID) != null) { - newID = ""; - } - } - return newID; +function Folders_GenerateNewFolderID() { + let newID = ""; + while (newID == "") { + newID = "f_" + GenerateRandomID(); + if (document.getElementById(newID) != null) newID = ""; + } + return newID; } -function AppendFolders(Folders) { - if (opt.debug) { - log("f: AppendFolders, Folders: "+JSON.stringify(Folders)); - } - for (let folderId in Folders) { - AppendFolder(folderId, Folders[folderId].name, Folders[folderId].parent, Folders[folderId].expand, true, undefined); - } - for (let folderId in Folders) { - let f = document.getElementById(folderId); - let parent = document.getElementById("cf"+Folders[folderId].parent); - if (f != null && parent != null && Folders[folderId].parent != f.parentNode.parentNode.id) { - parent.appendChild(f); - } - } +function Folders_PreAppendFolders(folders) { + for (let folderId in folders) {Folders_AppendFolder({folderId: folderId, Name: folders[folderId].name, ParentId: "tab_list", ExpandState: folders[folderId].expand});} } -function SaveFolders() { - document.querySelectorAll(".folder").forEach(function(s){ - tt.folders[s.id].parent = s.parentNode.parentNode.id; - tt.folders[s.id].index = Array.from(s.parentNode.children).indexOf(s); - tt.folders[s.id].expand = (s.classList.contains("c") ? "c" : (s.classList.contains("o") ? "o" : "")); - }); - chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId}); +function Folders_AppendFolders(folders) { + for (let folderId in folders) { + let f = document.getElementById(folderId); + let parent = document.getElementById("°" + folders[folderId].parent); + if (f != null && parent != null && folders[folderId].parent != f.parentNode.parentNode.id && parent.parentNode.classList.contains("pin") == false) parent.appendChild(f); + } } -function RearrangeFolders(first_loop) { - if (opt.debug) { - log("f: RearrangeFolders"); - } - document.querySelectorAll(".folder").forEach(function(s){ - if (tt.folders[s.id] && s.parentNode.childNodes[tt.folders[s.id].index]) { - let Ind = Array.from(s.parentNode.children).indexOf(s); - if (Ind > tt.folders[s.id].index) { - InsterBeforeNode(s, s.parentNode.childNodes[tt.folders[s.id].index]); - } else { - InsterAfterNode(s, s.parentNode.childNodes[tt.folders[s.id].index]); - } - } - let newInd = Array.from(s.parentNode.children).indexOf(s); - if (tt.folders[s.id] && newInd != tt.folders[s.id].index && first_loop) { - RearrangeFolders(false); - } - }); +function Folders_SaveFolders() { + let query = document.querySelectorAll(".folder"); + for (let s of query) { + tt.folders[s.id].parent = s.parentNode.parentNode.id; + tt.folders[s.id].index = Array.from(s.parentNode.children).indexOf(s); + tt.folders[s.id].expand = (s.classList.contains("c") ? "c" : (s.classList.contains("o") ? "o" : "")); + } + chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId}); } -function RemoveFolder(FolderId) { - if (opt.debug) { - log("f: RemoveFolder, folderId "+FolderId); - } - let folder = document.getElementById(FolderId); - if (folder != null) { - let CF = folder.childNodes[1]; // CF stands for DIV with children folders - let CT = folder.childNodes[2]; // CT stands for DIV with children tabs - if (opt.promote_children == true) { - if (opt.promote_children_in_first_child == true && CF.children.length > 0) { - let FirstFolderChild = CF.firstChild; - folder.parentNode.insertBefore(FirstFolderChild, folder); - let NewCF = FirstFolderChild.childNodes[1]; - while (CF.firstChild) { - NewCF.appendChild(CF.firstChild); - } - if (CT.childNodes.length > 0) { - let NewCT = FirstFolderChild.childNodes[2]; - while (CT.firstChild) { - NewCT.appendChild(CT.firstChild); - } - } - } else { - let NewCT = document.getElementById("ct"+folder.parentNode.parentNode.id); - // let NewCT = folder.parentNode.parentNode.childNodes[2]; - while (CT.firstChild) { - NewCT.appendChild(CT.firstChild); - } - while (CF.lastChild) { - folder.parentNode.insertBefore(CF.lastChild, folder); - } - } - } else { - document.querySelectorAll("#"+FolderId+" .tab").forEach(function(s){ - chrome.tabs.remove(parseInt(s.id), null); - }); - - document.querySelectorAll("#"+FolderId+" .folder").forEach(function(s){ - delete tt.folders[s.id]; - }); - } - folder.parentNode.removeChild(folder); - delete tt.folders[FolderId]; - RefreshExpandStates(); - chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId}); - } +function Folders_RemoveFolder(FolderId) { + if (opt.debug) Utils_log("f: RemoveFolder, folderId " + FolderId); + let folder = document.getElementById(FolderId); + if (folder != null) { + if (opt.promote_children == true) { + if (opt.promote_children_in_first_child == true && folder.childNodes[1].childNodes.length > 1) { + DOM_PromoteChildrenToFirstChild(folder); + } else { + let Children = folder.childNodes[1]; + while (Children.lastChild) { + DOM_InsterAfterNode(Children.lastChild, folder); + } + } + } else { + let query = document.querySelectorAll("#" + FolderId + " .tab"); + for (let s of query) { + chrome.tabs.remove(parseInt(s.id), null); + } + query = document.querySelectorAll("#" + FolderId + " .folder"); + for (let s of query) { + delete tt.folders[s.id]; + } + } + folder.parentNode.removeChild(folder); + delete tt.folders[FolderId]; + DOM_RefreshExpandStates(); + chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId}); + } } - -function ShowRenameFolderDialog(FolderId) { // Rename folder popup - if (opt.debug) { - log("f: ShowRenameFolderDialog, folderId "+FolderId); - } - HideRenameDialogs(); - if (tt.folders[FolderId]) { - let name = document.getElementById("folder_edit_name"); - name.value = tt.folders[FolderId].name; - let folderEditDialog = document.getElementById("folder_edit"); - folderEditDialog.setAttribute("FolderId", FolderId); - folderEditDialog.style.display = "block"; - folderEditDialog.style.top = document.getElementById("toolbar").getBoundingClientRect().height + document.getElementById("pin_list").getBoundingClientRect().height + 8 + "px"; - // folderEditDialog.style.left = "22px"; - folderEditDialog.style.left = ""; - setTimeout(function(){ - document.getElementById("folder_edit_name").select(); - },5); - } +function Folders_ShowRenameFolderDialog(FolderId) { // Rename folder popup + if (opt.debug) Utils_log("f: ShowRenameFolderDialog, folderId " + FolderId); + DOM_HideRenameDialogs(); + if (tt.folders[FolderId]) { + let name = document.getElementById("folder_edit_name"); + name.value = tt.folders[FolderId].name; + let folderEditDialog = document.getElementById("folder_edit"); + folderEditDialog.setAttribute("FolderId", FolderId); + DOM_SetStyle(folderEditDialog, {display: "block", left: "", top: document.getElementById("toolbar").getBoundingClientRect().height + document.getElementById("pin_list").getBoundingClientRect().height + 8 + "px"}); + setTimeout(function() {document.getElementById("folder_edit_name").select();}, 5); + } } -function FolderRenameConfirm() { // when pressed OK in folder popup - let name = document.getElementById("folder_edit_name"); - let FolderId = document.getElementById("folder_edit").getAttribute("FolderId"); - // name.value = name.value.replace(/[\f\n\r\v\t\<\>\+\-\(\)\.\,\;\:\~\/\|\?\@\!\"\'\£\$\%\&\^\#\=\*\[\]]?/gi, ""); - tt.folders[FolderId].name = name.value; - document.getElementById("folder_title" + FolderId).textContent = name.value; - HideRenameDialogs(); - if (opt.debug) { - log("f: FolderRenameConfirm, folderId "+FolderId+", name: "+name.value); - } - chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId}); - RefreshCounters(); +function Folders_FolderRenameConfirm() { // when pressed OK in folder popup + let name = document.getElementById("folder_edit_name"); + let FolderId = document.getElementById("folder_edit").getAttribute("FolderId"); + tt.folders[FolderId].name = name.value; + document.getElementById("folder_title_"+FolderId).textContent = name.value; + DOM_HideRenameDialogs(); + if (opt.debug) Utils_log("f: FolderRenameConfirm, folderId " + FolderId + ", name: " + name.value); + chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId}); + DOM_RefreshCounters(); } -function DeselectFolders() { - if (opt.debug) { - log("f: DeselectFolders"); - } - document.querySelectorAll("#"+tt.active_group+" .selected_folder").forEach(function(s){ - s.classList.remove("selected_folder"); - }); -} - -function ActionClickFolder(FolderNode, bgOption) { - if (opt.debug) { - log("f: ActionClickFolder, folderId "+FolderNode.id+", bgOption: "+bgOption); - } - if (bgOption == "rename_folder") { - ShowRenameFolderDialog(FolderNode.id); - } - if (bgOption == "new_folder") { - let FolderId = AddNewFolder({ParentId: FolderNode.id, SetEvents: true}); - ShowRenameFolderDialog(FolderId); - } - if (bgOption == "new_tab") { - OpenNewTab(false, FolderNode.id); - } - if (bgOption == "expand_collapse") { - EventExpandBox(FolderNode); - } - if (bgOption == "close_folder") { - RemoveFolder(FolderNode.id); - } - if (bgOption == "unload_folder") { - let tabsArr = []; - document.querySelectorAll("#"+FolderNode.id+" .tab").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - }); - DiscardTabs(tabsArr); - } -} - -function FolderStartDrag(Node, event) { - if (opt.debug) { - log("f: FolderStartDrag, folderId "+Node.id); - } - event.stopPropagation(); - event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0); - event.dataTransfer.setData("text", ""); - event.dataTransfer.setData("SourceWindowId", tt.CurrentWindowId); - CleanUpDragClasses(); - EmptyDragAndDrop(); - - tt.DragNodeClass = "folder"; - - let TabsIds = []; - let TabsIdsParents = []; - - let Folders = {}; - let FoldersSelected = []; - - - if (Node.parentNode.classList.contains("selected_folder")) { - document.querySelectorAll(".group:not(#"+tt.active_group+") .selected_folder").forEach(function(s){ - s.classList.add("selected_folder_frozen"); - s.classList.remove("selected_folder"); - }); - } else { - FreezeSelected(); - Node.parentNode.classList.add("selected_folder_temporarly"); - Node.parentNode.classList.add("selected_folder"); - } - - RemoveHeadersHoverClass(); - - document.querySelectorAll("[id='"+Node.parentNode.id+"'], [id='"+Node.parentNode.id+"'] .folder, [id='"+Node.parentNode.id+"'] .tab").forEach(function(s){ - s.classList.add("dragged_tree"); - }); - - if (opt.max_tree_drag_drop_folders || opt.max_tree_depth >= 0) { - document.querySelectorAll(".dragged_tree .folder").forEach(function(s){ - let parents = GetParentsByClass(s.parentNode, "dragged_tree"); - if (parents.length > tt.DragTreeDepth) { - tt.DragTreeDepth = parents.length; - } - }); - } else { - tt.DragTreeDepth = -1; - } - - // REST OF SELECTED FOLDERS+TABS THAT WILL BE DRAGGED - document.querySelectorAll(".selected_folder, .selected_folder .tab, .selected_folder .folder").forEach(function(s){ - s.classList.add("dragged_tree"); - }); - - document.querySelectorAll("#"+tt.active_group+" .selected_folder").forEach(function(s){ - FoldersSelected.push(s.id); - Folders[s.id] = Object.assign({}, tt.folders[s.id]); - let Fchildren = document.querySelectorAll("#cf"+s.id+" .folder"); - Fchildren.forEach(function(fc){ - Folders[fc.id] = Folders[fc.id] = Object.assign({}, tt.folders[fc.id]); - }); - let Tchildren = document.querySelectorAll("#ct"+s.id+" .tab"); - Tchildren.forEach(function(tc){ - TabsIds.push(parseInt(tc.id)); - TabsIdsParents.push(tc.parentNode.id); - }); - }); - - let DraggedFolderParents = GetParentsByClass(Node, "folder"); - DraggedFolderParents.forEach(function(s){ - s.classList.add("dragged_parents"); - }); - - event.dataTransfer.setData("Class", "folder"); - - event.dataTransfer.setData("TabsIds", JSON.stringify(TabsIds)); - event.dataTransfer.setData("TabsIdsParents", JSON.stringify(TabsIdsParents)); - - event.dataTransfer.setData("Folders", JSON.stringify(Folders)); - event.dataTransfer.setData("FoldersSelected", JSON.stringify(FoldersSelected)); - - chrome.runtime.sendMessage({ - command: "drag_drop", - DragNodeClass: "folder", - DragTreeDepth: tt.DragTreeDepth - }); -} - -function FolderDragOver(Node, event) { - if (opt.debug) { - log("f: debug, folderId "+Node.id); - } - if (Node.parentNode.classList.contains("dragged_tree") == false) { - - let PDepth = (GetParentsByClass(Node, "folder")).length + tt.DragTreeDepth; - let PIsGroup = Node.parentNode.parentNode.parentNode.classList.contains("group"); - let PIsDraggedParents = Node.parentNode.classList.contains("dragged_parents"); - - if (tt.DragNodeClass == "folder" && Node.parentNode.classList.contains("before") == false && event.layerY < Node.clientHeight/3 && (PDepth <= opt.max_tree_depth+1 || opt.max_tree_depth < 0 || PIsGroup || PIsDraggedParents || opt.max_tree_drag_drop_folders == false)) { - RemoveHighlight(); - Node.parentNode.classList.remove("inside"); - Node.parentNode.classList.remove("after"); - Node.parentNode.classList.add("before"); - Node.parentNode.classList.add("highlighted_drop_target"); - } - - if (tt.DragNodeClass == "folder" && Node.parentNode.classList.contains("inside") == false && event.layerY > Node.clientHeight/3 && event.layerY <= 2*(Node.clientHeight/3) && (PDepth <= opt.max_tree_depth || opt.max_tree_depth < 0 || PIsDraggedParents || opt.max_tree_drag_drop_folders == false)) { - RemoveHighlight(); - Node.parentNode.classList.remove("before"); - Node.parentNode.classList.remove("after"); - Node.parentNode.classList.add("inside"); - Node.parentNode.classList.add("highlighted_drop_target"); - } - - if (tt.DragNodeClass == "folder" && Node.parentNode.classList.contains("after") == false && Node.parentNode.classList.contains("o") == false && event.layerY > 2*(Node.clientHeight/3) && (PDepth <= opt.max_tree_depth+1 || opt.max_tree_depth < 0 || PIsGroup || PIsDraggedParents || opt.max_tree_drag_drop_folders == false)) { - RemoveHighlight(); - Node.parentNode.classList.remove("inside"); - Node.parentNode.classList.remove("before"); - Node.parentNode.classList.add("after"); - Node.parentNode.classList.add("highlighted_drop_target"); - } - - if (tt.DragNodeClass == "tab" && Node.parentNode.classList.contains("inside") == false && (PDepth <= opt.max_tree_depth || opt.max_tree_depth < 0 || PIsDraggedParents || opt.max_tree_drag_drop_folders == false)) { - RemoveHighlight(); - Node.parentNode.classList.remove("before"); - Node.parentNode.classList.remove("after"); - Node.parentNode.classList.add("inside"); - Node.parentNode.classList.add("highlighted_drop_target"); - } - } +function Folders_ActionClickFolder(FolderNode, bgOption) { + if (opt.debug) Utils_log("f: ActionClickFolder, folderId " + FolderNode.id + ", bgOption: " + bgOption); + if (bgOption == "rename_folder") Folders_ShowRenameFolderDialog(FolderNode.id); + if (bgOption == "new_folder") { + let FolderId = Folders_AddNewFolder({ParentId: FolderNode.id}); + Folders_ShowRenameFolderDialog(FolderId); + } + if (bgOption == "new_tab") Tabs_OpenNewTab(false, undefined, FolderNode.childNodes[1]); + if (bgOption == "expand_collapse") DOM_EventExpandBox(FolderNode); + if (bgOption == "close_folder") Folders_RemoveFolder(FolderNode.id); + if (bgOption == "unload_folder") { + let tabsArr = []; + let query = document.querySelectorAll("#" + FolderNode.id + " .tab"); + for (let s of query) { + tabsArr.push(parseInt(s.id)); + } + Tabs_DiscardTabs(tabsArr); + } } \ No newline at end of file diff --git a/scripts/groups.js b/scripts/groups.js index 02fbb88..1d816ad 100644 --- a/scripts/groups.js +++ b/scripts/groups.js @@ -1,574 +1,394 @@ -// 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/ - -// ********** GROUPS FUNCTIONS *************** - -function SaveGroups() { - chrome.runtime.sendMessage({command: "save_groups", groups: tt.groups, windowId: tt.CurrentWindowId}); +function Groups_AppendGroupToList(groupId, group_name, font_color, SetEvents) { + if (document.getElementById(groupId) == null) { + let grp = DOM_New("div", document.getElementById("groups"), {id: groupId, className: "group"}, {display: "none"}); + DOM_New("div", grp, {id: ("°" + groupId), className: "children"}); + if (SetEvents) { + grp.onclick = function(event) { + if (event.which == 1 && event.target == this && event.clientX < (this.childNodes[0].getBoundingClientRect().width + this.getBoundingClientRect().left)) DOM_Deselect(); + } + grp.onmousedown = function(event) { + event.stopImmediatePropagation(); + if (event.which == 1 && event.target == this && event.clientX < (this.childNodes[0].getBoundingClientRect().width + this.getBoundingClientRect().left)) { + Menu_HideMenus(); + return false; + } + if (event.which == 2) { + event.preventDefault(); + Groups_ActionClickGroup(this, opt.midclick_group); + } + if (event.which == 3 && event.target.id == this.id) Menu_ShowFGlobalMenu(event); + if (browserId == "V") { + chrome.windows.getCurrent({populate: false}, function(window) { + if (tt.CurrentWindowId != window.id && window.focused) location.reload(); + }); + } + } + grp.ondragover = function(event) { + if (event.target.id == this.id && (tt.DraggingGroup || tt.DraggingPin || tt.DraggingTab || tt.DraggingFolder)) { + DOM_RemoveHighlight(); + this.classList.add("highlighted_drop_target"); + } + } + grp.ondblclick = function(event) { + if (event.target.id == this.id) Groups_ActionClickGroup(this, opt.dbclick_group); + } + if (opt.switch_with_scroll) DOM_BindTabsSwitchingToMouseWheel(groupId); + } + } + if (document.getElementById("_" + groupId) == null) { + let gbn = DOM_New("div", document.getElementById("group_list"), {id: ("_" + groupId), className: "group_button", draggable: (SetEvents ? true : false)}); + DOM_New("span", gbn, {id: ("_gte" + groupId), className: "group_title", textContent: group_name}, {color: (font_color != "" ? ("#" + font_color) : (window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color")))}); + DOM_New("div", gbn, {id: ("di" + groupId), className: "drag_indicator"}); + if (SetEvents) { + gbn.onclick = function(event) { + Groups_SetActiveGroup(this.id.substr(1), true, true); + } + gbn.onmousedown = function(event) { + if (event.which == 3) Menu_ShowFGroupMenu(document.getElementById(this.id.substr(1)), event); + } + gbn.ondblclick = function(event) { + if (event.which == 1 && this.id != "_tab_list") Groups_ShowGroupEditWindow((this.id).substr(1)); + } + gbn.ondragstart = function(event) { // DRAG START + event.stopPropagation(); + event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0); + event.dataTransfer.setData("text", ""); + event.dataTransfer.setData("SourceWindowId", tt.CurrentWindowId); + DOM_CleanUpDragAndDrop(); + tt.Dragging = true; + tt.DraggingGroup = true; + tt.DragTreeDepth = -1; + let groupId = this.id.substr(1); + let Group = Object.assign({}, tt.groups[groupId]); + let Nodes = []; + let query = document.querySelectorAll("#" + groupId + " .tab, #" + groupId + " .folder"); + for (let s of query) { + if (s.classList.contains("tab")) { + tt.DraggingTab = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: false, temporary: false, NodeClass: "tab"}); + } + if (s.classList.contains("folder")) { + tt.DraggingFolder = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: false, temporary: false, NodeClass: "folder", index: (tt.folders[s.id] ? tt.folders[s.id].index : 0), name: (tt.folders[s.id] ? tt.folders[s.id].name : labels.noname_group), expand: (tt.folders[s.id] ? tt.folders[s.id].expand : "")}); + } + } + event.dataTransfer.setData("Group", JSON.stringify(Group)); + event.dataTransfer.setData("Nodes", JSON.stringify(Nodes)); + event.dataTransfer.setData("NodesTypes", JSON.stringify({DraggingGroup: tt.DraggingGroup, DraggingPin: tt.DraggingPin, DraggingTab: tt.DraggingTab, DraggingFolder: tt.DraggingFolder})); + chrome.runtime.sendMessage({command: "drag_start", DragTreeDepth: tt.DragTreeDepth, DraggingGroup: tt.DraggingGroup, DraggingPin: tt.DraggingPin, DraggingTab: tt.DraggingTab, DraggingFolder: tt.DraggingFolder}); + } + gbn.ondragover = function(event) { + if (this.classList.contains("inside") == false && tt.DraggingGroup == false && (tt.DraggingPin || tt.DraggingTab || tt.DraggingFolder)) { + DOM_RemoveHighlight(); + DOM_SetClasses(this, ["inside", "highlighted_drop_target"], ["before", "after"], []); + } + if (this.classList.contains("before") == false && event.layerY < this.clientHeight / 2 && tt.DraggingGroup) { + DOM_RemoveHighlight(); + DOM_SetClasses(this, ["before", "highlighted_drop_target"], ["inside", "after"], []); + } + if (this.classList.contains("after") == false && event.layerY > this.clientHeight / 2 && tt.DraggingGroup) { + DOM_RemoveHighlight(); + DOM_SetClasses(this, ["after", "highlighted_drop_target"], ["inside", "before"], []); + } + } + gbn.ondragenter = function(event) { + if (opt.open_tree_on_hover) { + if (this.classList.contains("active") == false && (tt.DraggingGroup || tt.DraggingPin || tt.DraggingTab || tt.DraggingFolder)) { + clearTimeout(tt.DragOverTimer); + let This = this; + tt.DragOverTimer = setTimeout(function() {Groups_SetActiveGroup(This.id.substr(1), false, false);}, 1500); + } + } + } + DOM_RefreshGUI(); + } + } } -function AppendGroups(Groups) { - if (opt.debug) { - log("f: AppendGroups, Groups: "+JSON.stringify(Groups)); - } - AppendGroupToList("tab_list", labels.ungrouped_group, "", true); - for (var group in Groups) { - AppendGroupToList(Groups[group].id, Groups[group].name, Groups[group].font, true); - if (document.querySelectorAll(".group").length == Object.keys(Groups).length) { - RearrangeGroupsButtons(); - setTimeout(function() { - RearrangeGroupsLists(); - }, 50); - } - } +function Groups_AddNewGroup(Name, FontColor) { + let newId = Groups_GenerateNewGroupID(); + tt.groups[newId] = {id: newId, index: 0, active_tab: 0, prev_active_tab: 0, name: (Name ? Name : labels.noname_group), font: (FontColor ? FontColor : "")}; + if (opt.debug) Utils_log("f: AddNewGroup, groupId: " + newId + ", Name: " + Name + ", FontColor: " + FontColor); + Groups_AppendGroupToList(newId, tt.groups[newId].name, tt.groups[newId].font, true); + Groups_UpdateBgGroupsOrder(); + return newId; } -function RearrangeGroupsButtons(first_loop) { - if (opt.debug) { - log("f: RearrangeGroupsButtons"); - } - document.querySelectorAll(".group_button").forEach(function(s){ - let groupId = (s.id).substr(1); - if (tt.groups[groupId]) { - if (s.parentNode.childNodes[tt.groups[groupId].index] != undefined) { - let Ind = Array.from(s.parentNode.children).indexOf(s); - if (Ind > tt.groups[groupId].index) { - InsterBeforeNode(s, s.parentNode.childNodes[tt.groups[groupId].index]); - } else { - InsterAfterNode(s, s.parentNode.childNodes[tt.groups[groupId].index]); - } - let newInd = Array.from(s.parentNode.children).indexOf(s); - if (newInd != tt.groups[groupId].index && first_loop) { - RearrangeGroupsButtons(false); - } - } - } - }); +function Groups_SaveGroups() { + chrome.runtime.sendMessage({command: "save_groups", groups: tt.groups, windowId: tt.CurrentWindowId}); } -function RearrangeGroupsLists() { - if (opt.debug) { - log("f: RearrangeGroupsLists"); - } - let activegroup = document.getElementById(tt.active_group); - let scroll = activegroup.scrollTop; - let groups = document.getElementById("groups"); - document.querySelectorAll(".group_button").forEach(function(s){ - let group = document.getElementById((s.id).substr(1)); - if (group != null) { - groups.appendChild(group); - } - }); - activegroup.scrollTop = scroll; +function Groups_AppendGroups(groups) { + Groups_AppendGroupToList("tab_list", labels.ungrouped_group, "", true); + for (var group in groups) { + Groups_AppendGroupToList(groups[group].id, groups[group].name, groups[group].font, true); + if (document.querySelectorAll(".group").length == Object.keys(groups).length) { + Groups_RearrangeGroupsButtons(); + setTimeout(function() {Groups_RearrangeGroupsLists();}, 50); + } + } } -function AppendGroupToList(groupId, group_name, font_color, SetEvents) { - if (opt.debug) { - log("f: AppendGroupToList, groupId: "+groupId+", group_name: "+group_name+", font_color: "+font_color+", SetEvents: "+SetEvents); - } - if (document.getElementById(groupId) == null) { - let grp = document.createElement("div"); grp.className = "group"; grp.id = groupId; grp.style.display = "none"; document.getElementById("groups").appendChild(grp); - let gcf = document.createElement("div"); gcf.className = "children_folders"; gcf.id = "cf"+groupId; grp.appendChild(gcf); - let gct = document.createElement("div"); gct.className = "children_tabs"; gct.id = "ct"+groupId; grp.appendChild(gct); - if (SetEvents) { - grp.onclick = function(event) { - if (event.which == 1 && event.target == this && event.clientX < (this.childNodes[0].getBoundingClientRect().width + this.getBoundingClientRect().left)) { - DeselectFolders(); - DeselectTabs(); - } - } - grp.onmousedown = function(event) { - event.stopImmediatePropagation(); - if (event.which == 1 && event.target == this && event.clientX < (this.childNodes[0].getBoundingClientRect().width + this.getBoundingClientRect().left)) { - HideMenus(); - return false; - } - if (event.which == 2) { - event.preventDefault(); - ActionClickGroup(this, opt.midclick_group); - } - if (event.which == 3 && event.target.id == this.id) { - // SHOW MENU - ShowFGlobalMenu(event); - } - if (browserId == "V") { - chrome.windows.getCurrent({populate: false}, function(window) { - if (tt.CurrentWindowId != window.id && window.focused) { - location.reload(); - } - }); - } - } - grp.ondragover = function(event) { - // PIN,TAB==>GROUP - if (event.target.id == this.id && (tt.DragNodeClass == "tab" || tt.DragNodeClass == "folder")) { - RemoveHighlight(); - this.classList.add("highlighted_drop_target"); - } - // tt.DragOverId = this.id; - } - // grp.ondragenter = function(event) { - // console.log("clearTimeout"); - // if (opt.open_tree_on_hover) { - // clearTimeout(tt.DragOverTimer); - // } - // } - - // DOUBLE CLICK ACTION - grp.ondblclick = function(event) { - if (event.target.id == this.id) { - ActionClickGroup(this, opt.dbclick_group); - } - } - - if (opt.switch_with_scroll) { - BindTabsSwitchingToMouseWheel(groupId); - } - - } - - } - - if (document.getElementById("_"+groupId) == null) { - let gbn = document.createElement("div"); gbn.className = "group_button"; if (SetEvents) {gbn.draggable = true;} gbn.id = "_"+groupId; document.getElementById("group_list").appendChild(gbn); - let gte = document.createElement("span"); gte.className = "group_title"; gte.id = "_gte"+groupId; gte.textContent = group_name; - if (font_color != "") { - gte.style.color = "#"+font_color; - } else { - gte.style.color = window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color"); - } - gbn.appendChild(gte); - var di = document.createElement("div"); di.className = "drag_indicator"; di.id = "di"+groupId; gbn.appendChild(di); // DROP TARGET INDICATOR - - if (SetEvents) { - - // ACTIVATE GROUP - gbn.onclick = function(event) { - SetActiveGroup(this.id.substr(1), true, true); - } - - // SHOW GROUP MENU - gbn.onmousedown = function(event) { - if (event.which == 3) { - ShowFGroupMenu(document.getElementById(this.id.substr(1)), event); - } - } - - // EDIT GROUP - gbn.ondblclick = function(event) { - if (event.which == 1 && this.id != "_tab_list") { - ShowGroupEditWindow((this.id).substr(1)); - } - } - - // DRAGGING GROUPS - gbn.ondragstart = function(event) { // DRAG START - GroupStartDrag(this, event); - } - - gbn.ondragover = function(event) { - GroupButtonDragOver(this, event); - } - - gbn.ondragenter = function(event) { - // console.log("gbn.ondragenter"); - if (opt.open_tree_on_hover) { - if (this.classList.contains("active") == false && tt.DragNodeClass != "group") { - clearTimeout(tt.DragOverTimer); - let This = this; - tt.DragOverTimer = setTimeout(function() { - SetActiveGroup(This.id.substr(1), false, false); - }, 1500); - } - } - } - // gbn.ondragleave = function(event) { - // console.log("gbn.ondragleave"); - // if (opt.open_tree_on_hover) { - // clearTimeout(tt.DragOverTimer); - // } - // } - - } - } - RefreshGUI(); +function Groups_RearrangeGroupsButtons(first_loop) { + let query = document.querySelectorAll(".group_button"); + for (let s of query) { + let groupId = (s.id).substr(1); + if (tt.groups[groupId]) { + if (s.parentNode.childNodes[tt.groups[groupId].index] != undefined) { + let Ind = Array.from(s.parentNode.children).indexOf(s); + if (Ind > tt.groups[groupId].index) { + DOM_InsterBeforeNode(s, s.parentNode.childNodes[tt.groups[groupId].index]); + } else { + DOM_InsterAfterNode(s, s.parentNode.childNodes[tt.groups[groupId].index]); + } + let newInd = Array.from(s.parentNode.children).indexOf(s); + if (newInd != tt.groups[groupId].index && first_loop) Groups_RearrangeGroupsButtons(false); + } + } + } } -function GenerateNewGroupID(){ - let newID = ""; - while (newID == "") { - newID = "g_"+GenerateRandomID(); - if (document.getElementById(newID) != null) { - newID = ""; - } - } - return newID; +function Groups_RearrangeGroupsLists() { + if (opt.debug) Utils_log("f: RearrangeGroupsLists"); + let activegroup = document.getElementById(tt.active_group); + let scroll = activegroup.scrollTop; + let groups = document.getElementById("groups"); + let query = document.querySelectorAll(".group_button"); + for (let s of query) { + let group = document.getElementById((s.id).substr(1)); + if (group != null) groups.appendChild(group); + } + activegroup.scrollTop = scroll; } -function AddNewGroup(Name, FontColor) { - let newId = GenerateNewGroupID(); - tt.groups[newId] = { id: newId, index: 0, active_tab: 0, prev_active_tab: 0, active_tab_ttid: "", name: (Name ? Name : labels.noname_group), font: (FontColor ? FontColor : "") }; - if (opt.debug) { - log("f: AddNewGroup, groupId: "+newId+", Name: "+Name+", FontColor: "+FontColor); - } - AppendGroupToList(newId, tt.groups[newId].name, tt.groups[newId].font, true); - UpdateBgGroupsOrder(); - return newId; +function Groups_UpdateBgGroupsOrder() { + let query = document.querySelectorAll(".group_button"); + for (let s of query) { + if (tt.groups[(s.id).substr(1)]) tt.groups[(s.id).substr(1)].index = Array.from(s.parentNode.children).indexOf(s); + } + Groups_SaveGroups(); } -// remove group, delete tabs if close_tabs is true -function GroupRemove(groupId, close_tabs) { - if (close_tabs) { - let tabIds = Array.prototype.map.call(document.querySelectorAll("#"+groupId+" .tab"), function(s){ - return parseInt(s.id); - }); - CloseTabs(tabIds); - document.querySelectorAll("#"+groupId+" .folder").forEach(function(s){ - RemoveFolder(s.id); - }); - } else { - let TabListFolders = document.getElementById("cftab_list"); - let GroupFolders = document.getElementById("cf"+groupId); - if (GroupFolders != null) { - while (GroupFolders.firstChild) { - TabListFolders.appendChild(GroupFolders.firstChild); - } - } - let TabListTabs = document.getElementById("cttab_list"); - let GroupTabs = document.getElementById("ct"+groupId); - if (GroupTabs != null) { - while (GroupTabs.firstChild) { - TabListTabs.appendChild(GroupTabs.firstChild); - } - } - RefreshExpandStates(); - RefreshCounters(); - } - if (groupId != "tab_list") { - delete tt.groups[groupId]; - if (groupId == tt.active_group) { - if (document.getElementById("_"+groupId).previousSibling) { - SetActiveGroup((document.getElementById("_"+groupId).previousSibling.id).substr(1), true, true); - } else { - if (document.getElementById("_"+groupId).nextSibling) { - SetActiveGroup((document.getElementById("_"+groupId).nextSibling.id).substr(1), true, true); - } else { - SetActiveGroup("tab_list", true, true); - } - } - } - let group = document.getElementById(groupId); - if (group != null) { - group.parentNode.removeChild(group); - } - let groupButton = document.getElementById("_"+groupId); - if (groupButton != null) { - groupButton.parentNode.removeChild(groupButton); - } - } - SaveGroups(); - tt.schedule_update_data++; +function Groups_GenerateNewGroupID() { + let newID = ""; + while (newID == "") { + newID = "g_" + GenerateRandomID(); + if (document.getElementById(newID) != null) newID = ""; + } + return newID; } -function UpdateBgGroupsOrder() { - document.querySelectorAll(".group_button").forEach(function(s){ - if (tt.groups[(s.id).substr(1)]) { - tt.groups[(s.id).substr(1)].index = Array.from(s.parentNode.children).indexOf(s); - } - }); - SaveGroups(); +function Groups_GroupRemove(groupId, close_tabs) { // remove group, delete tabs if close_tabs is true + if (close_tabs) { + let tabIds = Array.prototype.map.call(document.querySelectorAll("#" + groupId + " .tab"), function(s) {return parseInt(s.id);}); + Tabs_CloseTabs(tabIds); + let query = document.querySelectorAll("#" + groupId + " .folder"); + for (let s of query) { + Folders_RemoveFolder(s.id); + } + } else { + let TabList = document.getElementById("°tab_list"); + let GroupList = document.getElementById("°" + groupId); + if (TabList != null && GroupList != null) { + while (GroupList.firstChild) { + TabList.appendChild(GroupList.firstChild); + } + } + DOM_RefreshExpandStates(); + DOM_RefreshCounters(); + } + if (groupId != "tab_list") { + delete tt.groups[groupId]; + let active_tab_is_pin = document.querySelector(".pin.active_tab"); + if (groupId == tt.active_group && active_tab_is_pin == null) { + if (document.getElementById("_" + groupId).previousSibling) { + Groups_SetActiveGroup((document.getElementById("_" + groupId).previousSibling.id).substr(1), true, true); + } else { + if (document.getElementById("_" + groupId).nextSibling) { + Groups_SetActiveGroup((document.getElementById("_" + groupId).nextSibling.id).substr(1), true, true); + } else { + Groups_SetActiveGroup("tab_list", true, true); + } + } + } + let group = document.getElementById(groupId); + if (group != null) group.parentNode.removeChild(group); + let groupButton = document.getElementById("_" + groupId); + if (groupButton != null) groupButton.parentNode.removeChild(groupButton); + } + Groups_SaveGroups(); + tt.schedule_update_data++; } -function KeepOnlyOneActiveTabInGroup() { - let active_tabs = document.querySelectorAll("#"+tt.active_group+" .active_tab"); - if (active_tabs.length > 1) { - chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) { - SetActiveTab(activeTab[0].id, false); - }); - } +function Groups_KeepOnlyOneActiveTabInGroup() { + let active_tabs = document.querySelectorAll("#" + tt.active_group + " .active_tab"); + if (active_tabs.length > 1) { + chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) { + Tabs_SetActiveTab(activeTab[0].id, false); + }); + } } -function SetActiveGroup(groupId, switch_to_active_in_group, scroll_to_active) { - if (opt.debug) { - log("f: SetActiveGroup, groupId: "+groupId+", switch_to_active_in_group: "+switch_to_active_in_group+", scroll_to_active: "+scroll_to_active); - } - let group = document.getElementById(groupId); - if (group != null) { - tt.active_group = groupId; - document.querySelectorAll(".group_button").forEach(function(s){ - s.classList.remove("active_group"); - }); - document.getElementById("_"+groupId).classList.add("active_group"); - document.querySelectorAll(".group").forEach(function(s){ - s.style.display = "none"; - }); - group.style.display = ""; - RefreshGUI(); - HideRenameDialogs() - let activeTab = document.querySelector("#"+groupId+" .active_tab"); - if (activeTab != null ){ - if (switch_to_active_in_group){ - chrome.tabs.update(parseInt(activeTab.id), {active: true}); - } - if (scroll_to_active){ - ScrollToTab(activeTab.id); - } - KeepOnlyOneActiveTabInGroup(); - } - if (groupId == "tab_list") { - document.querySelectorAll("#button_remove_group, #button_edit_group").forEach(function(s){ - s.classList.add("disabled"); - }); - } else { - document.querySelectorAll("#button_remove_group, #button_edit_group").forEach(function(s){ - s.classList.remove("disabled"); - }); - } - chrome.runtime.sendMessage({command: "set_active_group", active_group: groupId, windowId: tt.CurrentWindowId}); - RefreshExpandStates(); - RefreshCounters(); - - if (browserId == "F" && opt.hide_other_groups_tabs_firefox) { - let HideTabIds = Array.prototype.map.call(document.querySelectorAll(".group:not([id='"+groupId+"']) .tab"), function(s){ - return parseInt(s.id); - }); - let ShowTabIds = Array.prototype.map.call(document.querySelectorAll("#"+groupId+" .tab"), function(s){ - return parseInt(s.id); - }); - - browser.tabs.hide(HideTabIds); - browser.tabs.show(ShowTabIds); - } - } +function Groups_SetActiveGroup(groupId, switch_to_active_in_group, scroll_to_active) { + if (opt.debug) Utils_log("f: SetActiveGroup, groupId: " + groupId + ", switch_to_active_in_group: " + switch_to_active_in_group + ", scroll_to_active: " + scroll_to_active); + let group = document.getElementById(groupId); + if (group != null) { + tt.active_group = groupId; + let query = document.querySelectorAll(".group_button"); + for (let s of query) { + s.classList.remove("active_group"); + } + document.getElementById("_" + groupId).classList.add("active_group"); + query = document.querySelectorAll(".group"); + for (let s of query) { + s.style.display = "none"; + } + group.style.display = ""; + DOM_RefreshGUI(); + DOM_HideRenameDialogs() + let activeTab = document.querySelector("#" + groupId + " .active_tab"); + if (activeTab != null) { + if (switch_to_active_in_group) chrome.tabs.update(parseInt(activeTab.id), {active: true}); + if (scroll_to_active && tt.tabs[activeTab.id]) tt.tabs[activeTab.id].ScrollToTab(); + Groups_KeepOnlyOneActiveTabInGroup(); + } + if (groupId == "tab_list") { + let query = document.querySelectorAll("#button_remove_group, #button_edit_group"); + for (let s of query) { + s.classList.add("disabled"); + } + } else { + let query = document.querySelectorAll("#button_remove_group, #button_edit_group"); + for (let s of query) { + s.classList.remove("disabled"); + } + } + chrome.runtime.sendMessage({command: "set_active_group", active_group: groupId, windowId: tt.CurrentWindowId}); + DOM_RefreshExpandStates(); + DOM_RefreshCounters(); + if (browserId == "F" && opt.hide_other_groups_tabs_firefox) { + let HideTabIds = Array.prototype.map.call(document.querySelectorAll(".group:not([id='" + groupId + "']) .tab"), function(s) { + return parseInt(s.id); + }); + let ShowTabIds = Array.prototype.map.call(document.querySelectorAll("#" + groupId + " .tab"), function(s) { + return parseInt(s.id); + }); + browser.tabs.hide(HideTabIds); + browser.tabs.show(ShowTabIds); + } + } } -function SetActiveTabInGroup(groupId, tabId) { - if (document.querySelector("#"+groupId+" [id='"+tabId+"']") != null && tt.groups[groupId] != undefined) { - if (groupId != tt.active_group) { - SetActiveGroup(groupId, false, true); - } - if (tt.groups[groupId]) { - tt.groups[groupId].prev_active_tab = tt.groups[groupId].active_tab; - tt.groups[groupId].active_tab = parseInt(tabId); - } - SaveGroups(); - } +function Groups_SetActiveTabInGroup(groupId, tabId) { + if (document.querySelector("#" + groupId + " [id='" + tabId + "']") != null && tt.groups[groupId] != undefined) { + if (groupId != tt.active_group) Groups_SetActiveGroup(groupId, false, true); + if (tt.groups[groupId]) { + tt.groups[groupId].prev_active_tab = tt.groups[groupId].active_tab; + tt.groups[groupId].active_tab = parseInt(tabId); + } + Groups_SaveGroups(); + } } -// Edit group popup -function ShowGroupEditWindow(groupId) { - HideRenameDialogs(); - if (tt.groups[groupId]) { - let name = document.getElementById("group_edit_name"); - name.value = tt.groups[groupId].name; - let groupEditDialog = document.getElementById("group_edit"); - groupEditDialog.setAttribute("groupId", groupId); - groupEditDialog.style.display = "block"; - groupEditDialog.style.top = document.getElementById("toolbar").getBoundingClientRect().height + document.getElementById("pin_list").getBoundingClientRect().height + 8 + "px"; - // groupEditDialog.style.left = "22px"; - groupEditDialog.style.left = ""; - let DefaultGroupButtonFontColor = window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color"); - let GroupEditFont = document.getElementById("group_edit_font"); - GroupEditFont.style.backgroundColor = (tt.groups[groupId].font == "" ? DefaultGroupButtonFontColor : "#"+tt.groups[groupId].font); - setTimeout(function(){ - document.getElementById("group_edit_name").select(); - },5); - } +function Groups_ShowGroupEditWindow(groupId) { // Edit group popup + DOM_HideRenameDialogs(); + if (tt.groups[groupId]) { + let name = document.getElementById("group_edit_name"); + name.value = tt.groups[groupId].name; + let groupEditDialog = document.getElementById("group_edit"); + groupEditDialog.setAttribute("groupId", groupId); + DOM_SetStyle(groupEditDialog, {display: "block", left: "", top: document.getElementById("toolbar").getBoundingClientRect().height + document.getElementById("pin_list").getBoundingClientRect().height + 8 + "px"}); + let DefaultGroupButtonFontColor = window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color"); + let GroupEditFont = document.getElementById("group_edit_font"); + GroupEditFont.style.backgroundColor = (tt.groups[groupId].font == "" ? DefaultGroupButtonFontColor : "#" + tt.groups[groupId].font); + setTimeout(function() {document.getElementById("group_edit_name").select();}, 5); + } } -// when pressed OK in group popup -function GroupEditConfirm() { - let groupId = document.getElementById("group_edit").getAttribute("groupId"); - if (tt.groups[groupId]) { - let GroupEditName = document.getElementById("group_edit_name"); - // GroupEditName.value = GroupEditName.value.replace(/[\f\n\r\v\t\<\>\+\-\(\)\.\,\;\:\~\/\|\?\@\!\"\'\£\$\%\&\^\#\=\*\[\]]?/gi, ""); - tt.groups[groupId].name = GroupEditName.value; - let GroupEditFont = document.getElementById("group_edit_font"); - let DefaultGroupButtonFontColor = window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color"); - let ThisGroupButtonFontColor = RGBtoHex(GroupEditFont.style.backgroundColor); - if ("#"+ThisGroupButtonFontColor != DefaultGroupButtonFontColor) { - tt.groups[groupId].font = ThisGroupButtonFontColor; - document.getElementById("_gte"+groupId).style.color = "#"+ThisGroupButtonFontColor; - } - HideRenameDialogs(); - RefreshGUI(); - SaveGroups(); - } +function Groups_GroupEditConfirm() { // when pressed OK in group popup + let groupId = document.getElementById("group_edit").getAttribute("groupId"); + if (tt.groups[groupId]) { + let GroupEditName = document.getElementById("group_edit_name"); + tt.groups[groupId].name = GroupEditName.value; + let GroupEditFont = document.getElementById("group_edit_font"); + let DefaultGroupButtonFontColor = window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color"); + let ThisGroupButtonFontColor = Utils_RGBtoHex(GroupEditFont.style.backgroundColor); + if ("#" + ThisGroupButtonFontColor != DefaultGroupButtonFontColor) { + tt.groups[groupId].font = ThisGroupButtonFontColor; + document.getElementById("_gte" + groupId).style.color = "#" + ThisGroupButtonFontColor; + } + DOM_HideRenameDialogs(); + DOM_RefreshGUI(); + Groups_SaveGroups(); + } } -function RestoreStateOfGroupsToolbar() { - chrome.runtime.sendMessage({command: "get_group_bar", windowId: tt.CurrentWindowId}, function(response) { - let toolbarGroups = document.getElementById("toolbar_groups"); - if (response == true) { - toolbarGroups.style.display = "inline-block"; - toolbarGroups.style.width = "19px"; - toolbarGroups.style.borderRight = "1px solid var(--group_list_borders)"; - toolbarGroups.classList.remove("hidden"); - } else { - toolbarGroups.style.display = "none"; - toolbarGroups.style.width = "0px"; - toolbarGroups.style.borderRight = "none"; - toolbarGroups.classList.add("hidden"); - } - }); +function Groups_RestoreStateOfGroupsToolbar() { + chrome.runtime.sendMessage({command: "get_group_bar", windowId: tt.CurrentWindowId}, function(response) { + let toolbarGroups = document.getElementById("toolbar_groups"); + if (response == true) { + DOM_SetStyle(toolbarGroups, {display: "inline-block", width: "19px", borderRight: "1px solid var(--group_list_borders)"}); + toolbarGroups.classList.remove("hidden"); + } else { + DOM_SetStyle(toolbarGroups, {display: "none", width: "0px", borderRight: "none"}); + toolbarGroups.classList.add("hidden"); + } + }); } -function GroupsToolbarToggle() { - let toolbarGroups = document.getElementById("toolbar_groups"); - toolbarGroups.classList.toggle("hidden"); - if (toolbarGroups.classList.contains("hidden")) { - toolbarGroups.style.display = "none"; - toolbarGroups.style.width = "0px"; - toolbarGroups.style.borderRight = "none"; - chrome.runtime.sendMessage({command: "set_group_bar", group_bar: false, windowId: tt.CurrentWindowId}); - } else { - toolbarGroups.style.display = "inline-block"; - toolbarGroups.style.width = "19px"; - toolbarGroups.style.borderRight = "1px solid var(--group_list_borders)"; - chrome.runtime.sendMessage({command: "set_group_bar", group_bar: true, windowId: tt.CurrentWindowId}); - } - RefreshGUI(); +function Groups_GroupsToolbarToggle() { + let toolbarGroups = document.getElementById("toolbar_groups"); + toolbarGroups.classList.toggle("hidden"); + if (toolbarGroups.classList.contains("hidden")) { + DOM_SetStyle(toolbarGroups, {display: "none", width: "0px", borderRight: "none"}); + chrome.runtime.sendMessage({command: "set_group_bar", group_bar: false, windowId: tt.CurrentWindowId}); + } else { + DOM_SetStyle(toolbarGroups, {display: "inline-block", width: "19px", borderRight: "1px solid var(--group_list_borders)"}); + chrome.runtime.sendMessage({command: "set_group_bar", group_bar: true, windowId: tt.CurrentWindowId}); + } + DOM_RefreshGUI(); } -function ActionClickGroup(Node, bgOption) { - if (bgOption == "new_tab") { - if (Node.id == "pin_list") { - OpenNewTab(true, undefined); - } - if (Node.classList.contains("tab") || Node.classList.contains("folder") || Node.classList.contains("group")) { - OpenNewTab(false, Node.id); - } - } - if (bgOption == "activate_previous_active") { - chrome.tabs.update(parseInt(tt.groups[tt.active_group].prev_active_tab), {active: true}); - } - if (bgOption == "undo_close_tab") { - chrome.sessions.getRecentlyClosed( null, function(sessions) { - if (sessions.length > 0) { - chrome.sessions.restore(null, function(restored) {}); - } - }); - } +function Groups_ActionClickGroup(Node, bgOption) { + if (bgOption == "new_tab") { + if (Node.id == "pin_list") Tabs_OpenNewTab(true, undefined, undefined); + if (Node.classList.contains("tab")) Tabs_OpenNewTab(false, Node); + if (Node.classList.contains("folder")) Tabs_OpenNewTab(false, undefined, Node.childNodes[1]); + if (Node.classList.contains("group")) Tabs_OpenNewTab(false, undefined, Node.childNodes[0]); + } + if (bgOption == "activate_previous_active") { + chrome.tabs.update(parseInt(tt.groups[tt.active_group].prev_active_tab), {active: true}); + } + if (bgOption == "undo_close_tab") { + chrome.sessions.getRecentlyClosed(null, function(sessions) { + if (sessions.length > 0) chrome.sessions.restore(null, function(restored) {}); + }); + } } - - - -// SET ACTIVE TAB FOR EACH GROUP -function SetActiveTabInEachGroup() { - chrome.tabs.query({currentWindow: true, active: true}, function(tabs) { - if (tabs.length) { - SetActiveTab(tabs[0].id); - chrome.runtime.sendMessage({command: "get_active_group", windowId: tt.CurrentWindowId}, function(response) { - if (response) { - SetActiveGroup(response, false, true); - for (var group in tt.groups) { - let ActiveInGroup = document.querySelector("#"+group+" [id='"+tt.groups[group].active_tab+"']"); - if (ActiveInGroup != null) { - ActiveInGroup.classList.add("active_tab"); - } - } - if (tabs[0].pinned) { - let ActiveTabinActiveGroup = document.querySelectorAll("#"+tt.active_group+" .active_tab"); - if (ActiveTabinActiveGroup != null) { - ActiveTabinActiveGroup.forEach(function(s){ - s.classList.remove("active_tab"); - }); - } - } - } else { - SetActiveGroup("tab_list", false, true); - } - }); - } - }); -} - - -// function ActionClickGroup(GroupNode, bgOption) { - // if (opt.debug) { - // log("f: ActionClickGroup, GroupId "+GroupNode.id+", bgOption: "+bgOption); - // } - // if (bgOption == "rename_folder") { - // ShowRenameFolderDialog(FolderNode.id); - // } -// } - - -function GroupButtonDragOver(Node, event) { - if (Node.classList.contains("inside") == false && (tt.DragNodeClass == "tab" || tt.DragNodeClass == "folder")) { - RemoveHighlight(); - Node.classList.remove("before"); - Node.classList.remove("after"); - Node.classList.add("inside"); - Node.classList.add("highlighted_drop_target"); - } - - if (Node.classList.contains("before") == false && event.layerY < Node.clientHeight/2 && tt.DragNodeClass == "group") { - RemoveHighlight(); - Node.classList.add("before"); - Node.classList.remove("after"); - Node.classList.remove("inside"); - Node.classList.add("highlighted_drop_target"); - } - - if (Node.classList.contains("after") == false && event.layerY > Node.clientHeight/2 && tt.DragNodeClass == "group") { - RemoveHighlight(); - Node.classList.remove("before"); - Node.classList.add("after"); - Node.classList.remove("inside"); - Node.classList.add("highlighted_drop_target"); - } -} - -function GroupStartDrag(Node, event) { - if (opt.debug) { - log("f: GroupStartDrag, GroupId "+Node.id); - } - event.stopPropagation(); - event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0); - event.dataTransfer.setData("text", ""); - event.dataTransfer.setData("SourceWindowId", tt.CurrentWindowId); - CleanUpDragClasses(); - EmptyDragAndDrop(); - - tt.DragNodeClass = "group"; - - let Group = Object.assign({}, tt.groups[Node.id.substr(1)]); - let TabsIds = []; - let TabsIdsParents = []; - let Folders = {}; - - - document.querySelectorAll("#"+Node.id.substr(1)+" .tab").forEach(function(s){ - TabsIds.push(parseInt(s.id)); - TabsIdsParents.push(s.parentNode.id); - }); - - document.querySelectorAll("#"+Node.id.substr(1)+" .folder").forEach(function(s){ - Folders[s.id] = Object.assign({}, tt.folders[s.id]); - }); - - // console.log(Group); - // console.log(TabsIds); - // console.log(TabsIdsParents); - // console.log(Folders); - - // let Group = document.getElementById(Node.id.substr(1)); - - event.dataTransfer.setData("Class", "group"); - - event.dataTransfer.setData("Group", JSON.stringify(Group)); - event.dataTransfer.setData("TabsIds", JSON.stringify(TabsIds)); - event.dataTransfer.setData("TabsIdsParents", JSON.stringify(TabsIdsParents)); - - event.dataTransfer.setData("Folders", JSON.stringify(Folders)); - - chrome.runtime.sendMessage({ - command: "drag_drop", - DragNodeClass: "group", - DragTreeDepth: 0 - }); - -} +function Groups_SetActiveTabInEachGroup() { // SET ACTIVE TAB FOR EACH GROUP + chrome.tabs.query({currentWindow: true, active: true}, function(tabs) { + if (tabs.length) { + Tabs_SetActiveTab(tabs[0].id); + chrome.runtime.sendMessage({command: "get_active_group", windowId: tt.CurrentWindowId}, function(response) { + if (response) { + Groups_SetActiveGroup(response, false, true); + for (var group in tt.groups) { + let ActiveInGroup = document.querySelector("#" + group + " [id='" + tt.groups[group].active_tab + "']"); + if (ActiveInGroup != null) ActiveInGroup.classList.add("active_tab"); + } + if (tabs[0].pinned) { + let ActiveTabinActiveGroup = document.querySelectorAll("#" + tt.active_group + " .active_tab"); + if (ActiveTabinActiveGroup != null) { + for (let s of ActiveTabinActiveGroup) { + s.classList.remove("active_tab"); + } + } + } + } else { + Groups_SetActiveGroup("tab_list", false, true); + } + }); + } + }); +} \ No newline at end of file diff --git a/scripts/listeners.js b/scripts/listeners.js deleted file mode 100644 index ce1ed94..0000000 --- a/scripts/listeners.js +++ /dev/null @@ -1,313 +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 StartSidebarListeners() { - if (browserId == "F") { - browser.browserAction.onClicked.addListener(function(tab) { - if (tab.windowId == tt.CurrentWindowId) { - browser.sidebarAction.close(); - } - }); - } - - chrome.commands.onCommand.addListener(function(command) { - chrome.windows.getCurrent({populate: false}, function(window) { - if (window.id == tt.CurrentWindowId && window.focused) { - chrome.tabs.query({windowId: tt.CurrentWindowId, active: true}, function(tabs) { - let tabsArr = []; - document.querySelectorAll("[id='"+tabs[0].id+"'] .tab, [id='"+tabs[0].id+"']").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - if (s.childNodes[1].childNodes.length > 0) { - document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){ - tabsArr.push(parseInt(t.id)); - }); - } - }); - CloseTabs(tabsArr); - }); - } - }); - }); - - chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { - if (message.command == "backup_available") { - if (opt.debug) { - log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command); - } - let BAKbutton = document.getElementById("button_load_bak"+message.bak); - if (BAKbutton != null) { - BAKbutton.classList.remove("disabled"); - } - return; - } - if (message.command == "drag_drop") { - if (opt.debug) { - log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command); - } - CleanUpDragClasses(); - tt.DragNodeClass = message.DragNodeClass; - tt.DragTreeDepth = message.DragTreeDepth; - return; - } - if (message.command == "dragend") { - if (opt.debug) { - log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command); - } - CleanUpDragClasses(); - EmptyDragAndDrop(); - return; - } - if (message.command == "remove_folder") { - if (opt.debug) { - log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command+" folderId: "+message.folderId); - } - RemoveFolder(message.folderId); - return; - } - if (message.command == "remove_group") { - if (opt.debug) { - log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command+" groupId: "+message.groupId); - } - setTimeout(function() { - GroupRemove(message.groupId, false); - }, 2000); - return; - } - if (message.command == "reload_sidebar") { - if (opt.debug) { - log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command); - } - window.location.reload(); - return; - } - if (message.command == "reload_options") { - if (opt.debug) { - log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command); - } - opt = Object.assign({}, message.opt); - setTimeout(function() { - RestorePinListRowSettings(); - }, 100); - return; - } - if (message.command == "reload_toolbar") { - if (opt.debug) { - log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command); - } - opt = Object.assign({}, message.opt); - - if (opt.show_toolbar) { - RemoveToolbar(); - RecreateToolbar(message.toolbar); - SetToolbarEvents(false, true, true, "mousedown"); - RestoreToolbarShelf(); - RestoreToolbarSearchFilter(); - } else { - RemoveToolbar(); - } - RefreshGUI(); - return; - } - if (message.command == "reload_theme") { - if (opt.debug) { - log("message to sidebar "+tt.CurrentWindowId+": message: "+message.command); - } - RestorePinListRowSettings(); - ApplyTheme(message.theme); - return; - } - if (message.windowId == tt.CurrentWindowId) { - - if (message.command == "append_group") { - if (tt.groups[message.groupId] == undefined) { - tt.groups[message.groupId] = {id: message.groupId, index: Object.keys(tt.groups).length, active_tab: 0, prev_active_tab: 0, active_tab_ttid: "", name: message.group_name, font: message.font_color}; - AppendGroupToList(message.groupId, message.group_name, message.font_color, true); - } - return; - } - - if (message.command == "append_tab_to_group") { - let Group = document.getElementById("ct"+message.groupId); - let Tab = document.getElementById(message.tabId); - if (Group && Tab) { - Group.appendChild(Tab); - SetActiveGroup(message.groupId, false, true); - } - return; - } - - if (message.command == "tab_created") { - - if (message.InsertAfterId && document.querySelectorAll("#"+tt.active_group+" .tab").length == 0) { - message.InsertAfterId = undefined; - message.ParentId = tt.active_group; - } - - - AppendTab({tab: message.tab, ParentId: message.ParentId, InsertAfterId: message.InsertAfterId, Append: message.Append, Scroll: true}); - - RefreshExpandStates(); - setTimeout(function() { - RefreshCounters(); - RefreshGUI(); - },50); - - if (opt.syncro_tabbar_tabs_order) { - let tabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s){ - return parseInt(s.id); - }); - chrome.tabs.move(message.tab.id, {index: tabIds.indexOf(message.tab.id)}); - } - - setTimeout(function() { - tt.schedule_update_data++; - }, 1000); - - return; - } - if (message.command == "tab_attached") { - if (opt.debug) { - log("chrome event: "+message.command+", tabId: "+message.tabId+", tab is pinned: "+message.tab.pinned+", ParentId: "+message.ParentId); - } - - AppendTab({tab: message.tab, ParentId: message.ParentId, Append: true, SkipSetActive: true, SkipMediaIcon: true}); - RefreshGUI(); - return; - } - if (message.command == "tab_detached") { - if (opt.debug) { - log("chrome event: "+message.command+ ", tabId: " + message.tabId); - } - let Tab = document.getElementById(message.tabId); - if (Tab != null) { - let ctDetachedParent = Tab.childNodes[1]; - if (opt.promote_children_in_first_child == true && ctDetachedParent.childNodes.length > 1) { - let ctNewParent = document.getElementById(ctDetachedParent.firstChild.id).childNodes[1]; - ctDetachedParent.parentNode.parentNode.insertBefore(ctDetachedParent.firstChild, ctDetachedParent.parentNode); - while (ctDetachedParent.firstChild) { - ctNewParent.appendChild(ctDetachedParent.firstChild); - } - } else { - while (ctDetachedParent.firstChild) { - ctDetachedParent.parentNode.parentNode.insertBefore(ctDetachedParent.firstChild, ctDetachedParent.parentNode); - } - } - } - RemoveTabFromList(message.tabId); - setTimeout(function() { - tt.schedule_update_data++; - }, 300); - RefreshGUI(); - return; - } - if (message.command == "tab_removed") { - if (opt.debug) { - log("chrome event: "+message.command+ ", tabId: " + message.tabId); - } - - - let mTab = document.getElementById(message.tabId); - if (mTab != null) { - let ctParent = mTab.childNodes[1]; - if (opt.debug) { - log("tab_removed, promote children: " +opt.promote_children); - } - if (opt.promote_children == true) { - if (opt.promote_children_in_first_child == true && ctParent.childNodes.length > 1) { - let ctNewParent = document.getElementById(ctParent.firstChild.id).childNodes[1]; - ctParent.parentNode.parentNode.insertBefore(ctParent.firstChild, ctParent.parentNode); - while (ctParent.firstChild) { - ctNewParent.appendChild(ctParent.firstChild); - } - } else { - while (ctParent.firstChild) { - ctParent.parentNode.parentNode.insertBefore(ctParent.firstChild, ctParent.parentNode); - } - } - } else { - document.querySelectorAll("[id='"+message.tabId+"'] .tab").forEach(function(s) { - chrome.tabs.remove(parseInt(s.id)); - }); - } - RemoveTabFromList(message.tabId); - RefreshExpandStates(); - setTimeout(function() { - tt.schedule_update_data++; - }, 300); - RefreshGUI(); - RefreshCounters(); - } - return; - } - if (message.command == "tab_activated") { - if (opt.debug) { - log("chrome event: "+message.command+ ", tabId: " + message.tabId); - } - SetActiveTab(message.tabId, true); - return; - } - if (message.command == "tab_attention") { - if (opt.debug) { - log("chrome event: "+message.command+ ", tabId: " + message.tabId); - } - SetAttentionIcon(message.tabId); - return; - } - if (message.command == "tab_updated") { - if (opt.debug) { - log("chrome event: "+message.command+ ", tabId: " + message.tabId); - // + ", changeInfo: "+JSON.stringify(message.changeInfo)); - // log(message.changeInfo); - } - - if (message.changeInfo.favIconUrl != undefined || message.changeInfo.url != undefined) { - setTimeout(function() { - GetFaviconAndTitle(message.tabId, true); - }, 100); - } - if (message.changeInfo.title != undefined) { - setTimeout(function() { - GetFaviconAndTitle(message.tabId, true); - }, 1000); - } - if (message.changeInfo.audible != undefined || message.changeInfo.mutedInfo != undefined) { - RefreshMediaIcon(message.tabId); - } - if (message.changeInfo.discarded != undefined) { - RefreshDiscarded(message.tabId); - // RefreshMediaIcon(message.tabId); - } - if (message.changeInfo.pinned != undefined) { - let updateTab = document.getElementById(message.tabId); - if (updateTab != null) { - if (message.tab.pinned && updateTab.classList.contains("pin") == false) { - SetTabClass(message.tabId, true); - tt.schedule_update_data++; - } - if (!message.tab.pinned && updateTab.classList.contains("tab") == false) { - SetTabClass(message.tabId, false); - tt.schedule_update_data++; - } - } - RefreshExpandStates(); - } - return; - } - // if (message.command == "set_active_group") { - // SetActiveGroup(message.groupId, false, false); - // return; - // } - if (message.command == "remote_update") { - if (opt.debug) { - log("chrome event: "+message.command+ ", tabId: " + message.tabId); - log(message); - } - RcreateTreeStructure(message.groups, message.folders, message.tabs); - sendResponse(true); - tt.schedule_update_data++; - return; - } - } - }); -} \ No newline at end of file diff --git a/scripts/manager.js b/scripts/manager.js index 5f3c399..f82decb 100644 --- a/scripts/manager.js +++ b/scripts/manager.js @@ -1,373 +1,744 @@ -// 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 OpenManagerWindow() { - HideRenameDialogs(); - - if (opt.debug) { - log("f: OpenManagerWindow"); - } - - chrome.storage.local.get(null, function(storage) { - let ManagerWindow = document.getElementById("manager_window"); - ManagerWindow.style.display = "block"; - - // ManagerWindow.style.top = document.getElementById("toolbar").getBoundingClientRect().height - 13 + "px"; - ManagerWindow.style.top = ""; - ManagerWindow.style.left = ""; - - let GroupList = document.getElementById("manager_window_groups_list"); - while (GroupList.hasChildNodes()) { - GroupList.removeChild(GroupList.firstChild); - } - - let SessionsList = document.getElementById("manager_window_sessions_list"); - while (SessionsList.hasChildNodes()) { - SessionsList.removeChild(SessionsList.firstChild); - } - - - if (storage.hibernated_groups != undefined) { - storage.hibernated_groups.forEach(function(hibernated_group){ - AddGroupToManagerList(hibernated_group); - }); - } - if (storage.saved_sessions != undefined) { - (storage.saved_sessions).forEach(function(saved_session){ - AddSessionToManagerList(saved_session); - }); - } - - ReAddSessionAutomaticToManagerList(storage); - }); +function Manager_OpenManagerWindow() { + DOM_HideRenameDialogs(); + if (opt.debug) Utils_log("f: Manager_OpenManagerWindow"); + chrome.storage.local.get(null, function(storage) { + DOM_SetStyle(document.getElementById("manager_window"), {display: "block", top: "", left: ""}); + let GroupList = document.getElementById("manager_window_groups_list"); + while (GroupList.hasChildNodes()) { + GroupList.removeChild(GroupList.firstChild); + } + let SessionsList = document.getElementById("manager_window_sessions_list"); + while (SessionsList.hasChildNodes()) { + SessionsList.removeChild(SessionsList.firstChild); + } + if (storage.hibernated_groups != undefined) { + for (let hibernated_group of storage.hibernated_groups) { + Manager_AddGroupToManagerList(hibernated_group); + } + } + if (storage.saved_sessions != undefined) { + for (let saved_session of storage.saved_sessions) { + Manager_AddSessionToManagerList(saved_session); + } + } + Manager_ReAddSessionAutomaticToManagerList(storage); + }); } - - -function AddGroupToManagerList(hibernated_group) { - - let GroupList = document.getElementById("manager_window_groups_list"); - - let HibernatedGroupRow = document.createElement("li"); - HibernatedGroupRow.classList = "hibernated_group_row" - GroupList.appendChild(HibernatedGroupRow); - - let DeleteGroupIcon = document.createElement("div"); - DeleteGroupIcon.classList = "manager_window_list_button delete_hibernated_group"; - DeleteGroupIcon.title = chrome.i18n.getMessage("manager_window_delete_icon"); - - DeleteGroupIcon.onmousedown = function(event) { - if (event.which == 1) { - let hib_group = this.parentNode; - let HibernategGroupIndex = Array.from(hib_group.parentNode.children).indexOf(hib_group); - - chrome.storage.local.get(null, function(storage) { - let hibernated_groups = storage.hibernated_groups; - hibernated_groups.splice(HibernategGroupIndex, 1); - - chrome.storage.local.set({hibernated_groups: hibernated_groups}); - hib_group.parentNode.removeChild(hib_group); - RefreshGUI(); - }); - } - } - HibernatedGroupRow.appendChild(DeleteGroupIcon); - - - let ExportGroupIcon = document.createElement("div"); - ExportGroupIcon.classList = "manager_window_list_button export_hibernated_group"; - ExportGroupIcon.title = chrome.i18n.getMessage("manager_window_savetofile_icon"); - ExportGroupIcon.onmousedown = function(event) { - if (event.which == 1) { - let HibernategGroupIndex = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode); - chrome.storage.local.get(null, function(storage) { - let filename = storage.hibernated_groups[HibernategGroupIndex].group.name == "" ? labels.noname_group : storage.hibernated_groups[HibernategGroupIndex].group.name; - SaveFile(filename, "tt_group", storage.hibernated_groups[HibernategGroupIndex]); - }); - } - } - HibernatedGroupRow.appendChild(ExportGroupIcon); - - let LoadGroupIcon = document.createElement("div"); - LoadGroupIcon.classList = "manager_window_list_button load_hibernated_group"; - LoadGroupIcon.title = chrome.i18n.getMessage("manager_window_load_icon"); - LoadGroupIcon.onmousedown = function(event) { - if (event.which == 1) { - let HibernategGroupIndex = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode); - chrome.storage.local.get(null, function(storage) { - RecreateGroup(storage.hibernated_groups[HibernategGroupIndex]); - }); - } - } - HibernatedGroupRow.appendChild(LoadGroupIcon); - - - let name = document.createElement("div"); - name.contentEditable = true; - name.textContent = hibernated_group.group.name; - name.classList = "manager_window_group_name text_input"; - name.onkeydown = function(event) { return event.which != 13; } - name.oninput = function(event) { - // this.textContent = (this.textContent).replace(/\n/g,' '); - let hib_group_name = this.textContent; - let hib_group = this.parentNode; - let HibernategGroupIndex = Array.from(hib_group.parentNode.children).indexOf(hib_group); - chrome.storage.local.get(null, function(storage) { - let hibernated_groups = storage.hibernated_groups; - hibernated_groups[HibernategGroupIndex].group.name = hib_group_name; - chrome.storage.local.set({hibernated_groups: hibernated_groups}); - }); - } - HibernatedGroupRow.appendChild(name); - let tabsCounter = document.createElement("div"); - tabsCounter.textContent = " - ("+ hibernated_group.tabs.length + ")"; - tabsCounter.classList = "manager_window_group_name"; - HibernatedGroupRow.appendChild(tabsCounter); - RefreshGUI(); +function Manager_AddGroupToManagerList(hibernated_group) { + let HibernatedGroupRow = DOM_New("li", document.getElementById("manager_window_groups_list"), {className: "hibernated_group_row"}); + let DeleteGroupIcon = DOM_New("div", HibernatedGroupRow, {className: "manager_window_list_button delete_hibernated_group", title: chrome.i18n.getMessage("manager_window_delete_icon")}); + DeleteGroupIcon.onmousedown = function(event) { + if (event.which == 1) { + let hib_group = this.parentNode; + let HibernategGroupIndex = Array.from(hib_group.parentNode.children).indexOf(hib_group); + chrome.storage.local.get(null, function(storage) { + let hibernated_groups = storage.hibernated_groups; + hibernated_groups.splice(HibernategGroupIndex, 1); + chrome.storage.local.set({hibernated_groups: hibernated_groups}); + hib_group.parentNode.removeChild(hib_group); + DOM_RefreshGUI(); + }); + } + } + let ExportGroupIcon = DOM_New("div", HibernatedGroupRow, {className: "manager_window_list_button export_hibernated_group", title: chrome.i18n.getMessage("manager_window_savetofile_icon")}); + ExportGroupIcon.onmousedown = function(event) { + if (event.which == 1) { + let HibernategGroupIndex = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode); + chrome.storage.local.get(null, function(storage) { + let filename = storage.hibernated_groups[HibernategGroupIndex].group.name == "" ? labels.noname_group : storage.hibernated_groups[HibernategGroupIndex].group.name; + File_SaveFile(filename, "tt_group", storage.hibernated_groups[HibernategGroupIndex]); + }); + } + } + let LoadGroupIcon = DOM_New("div", HibernatedGroupRow, {className: "manager_window_list_button load_hibernated_group", title: chrome.i18n.getMessage("manager_window_load_icon")}); + LoadGroupIcon.onmousedown = function(event) { + if (event.which == 1) { + let HibernategGroupIndex = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode); + chrome.storage.local.get(null, function(storage) { + Manager_RecreateGroup(storage.hibernated_groups[HibernategGroupIndex]); + }); + } + } + let name = DOM_New("div", HibernatedGroupRow, {className: "manager_window_group_name text_input", contentEditable: true, textContent: hibernated_group.group.name}); + name.onkeydown = function(event) { + return event.which != 13; + } + name.oninput = function(event) { + let hib_group_name = this.textContent; + let hib_group = this.parentNode; + let HibernategGroupIndex = Array.from(hib_group.parentNode.children).indexOf(hib_group); + chrome.storage.local.get(null, function(storage) { + let hibernated_groups = storage.hibernated_groups; + hibernated_groups[HibernategGroupIndex].group.name = hib_group_name; + chrome.storage.local.set({hibernated_groups: hibernated_groups}); + }); + } + DOM_New("div", HibernatedGroupRow, {className: "manager_window_group_name", textContent: " - (" + hibernated_group.tabs.length + ")"}); + DOM_RefreshGUI(); } - - -function AddSessionToManagerList(saved_session) { - let SessionsList = document.getElementById("manager_window_sessions_list"); - - let SavedSessionRow = document.createElement("li"); - SavedSessionRow.classList = "saved_session_row" - SessionsList.appendChild(SavedSessionRow); - - - let DeleteSessionIcon = document.createElement("div"); - DeleteSessionIcon.classList = "manager_window_list_button delete_saved_session"; - DeleteSessionIcon.title = chrome.i18n.getMessage("manager_window_delete_icon"); - DeleteSessionIcon.onmousedown = function(event) { - if (event.which == 1) { - let saved_session = this.parentNode; - let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); - chrome.storage.local.get(null, function(storage) { - let S_Sessions = storage.saved_sessions; - S_Sessions.splice(SessionIndex, 1); - chrome.storage.local.set({saved_sessions: S_Sessions}); - saved_session.parentNode.removeChild(saved_session); - RefreshGUI(); - - }); - } - } - SavedSessionRow.appendChild(DeleteSessionIcon); - - - let ExportSessionIcon = document.createElement("div"); - ExportSessionIcon.classList = "manager_window_list_button export_saved_session"; - ExportSessionIcon.title = chrome.i18n.getMessage("manager_window_savetofile_icon"); - ExportSessionIcon.onmousedown = function(event) { - if (event.which == 1) { - let saved_session = this.parentNode; - let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); - chrome.storage.local.get(null, function(storage) { - let filename = storage.saved_sessions[SessionIndex].name == "" ? labels.noname_group : storage.saved_sessions[SessionIndex].name; - SaveFile(filename, "tt_session", storage.saved_sessions[SessionIndex].session); - }); - } - } - SavedSessionRow.appendChild(ExportSessionIcon); - - - let LoadSessionIcon = document.createElement("div"); - LoadSessionIcon.classList = "manager_window_list_button load_saved_session"; - LoadSessionIcon.title = chrome.i18n.getMessage("manager_window_load_icon"); - LoadSessionIcon.onmousedown = function(event) { - if (event.which == 1) { - let saved_session = this.parentNode; - let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); - chrome.storage.local.get(null, function(storage) { - let S_Sessions = storage.saved_sessions; - RecreateSession(S_Sessions[SessionIndex].session); - }); - } - } - SavedSessionRow.appendChild(LoadSessionIcon); - - let MergeSessionIcon = document.createElement("div"); - MergeSessionIcon.classList = "manager_window_list_button merge_saved_session"; - MergeSessionIcon.title = chrome.i18n.getMessage("manager_window_merge_icon"); - MergeSessionIcon.onmousedown = function(event) { - if (event.which == 1) { - let saved_session = this.parentNode; - let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); - chrome.storage.local.get(null, function(storage) { - let S_Sessions = storage.saved_sessions; - ImportMergeTabs(S_Sessions[SessionIndex].session); - }); - } - } - SavedSessionRow.appendChild(MergeSessionIcon); - - let name = document.createElement("div"); - name.contentEditable = true; - name.textContent = saved_session.name; - name.classList = "manager_window_session_name"; - name.onkeydown = function(event) { return event.which != 13; } - name.oninput = function(event) { - // this.textContent = (this.textContent).replace(/\n/g,' '); - let session_name = this.textContent; - let s = this.parentNode; - let SessionIndex = Array.from(s.parentNode.children).indexOf(s); - chrome.storage.local.get(null, function(storage) { - let S_Sessions = storage.saved_sessions; - S_Sessions[SessionIndex].name = session_name; - chrome.storage.local.set({saved_sessions: S_Sessions}); - }); - } - SavedSessionRow.appendChild(name); - - RefreshGUI(); +function Manager_AddSessionToManagerList(saved_session) { + let SavedSessionRow = DOM_New("li", document.getElementById("manager_window_sessions_list"), {className: "saved_session_row"}); + let DeleteSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button delete_saved_session", title: chrome.i18n.getMessage("manager_window_delete_icon")}); + DeleteSessionIcon.onmousedown = function(event) { + if (event.which == 1) { + let saved_session = this.parentNode; + let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); + chrome.storage.local.get(null, function(storage) { + let S_Sessions = storage.saved_sessions; + S_Sessions.splice(SessionIndex, 1); + chrome.storage.local.set({saved_sessions: S_Sessions}); + saved_session.parentNode.removeChild(saved_session); + DOM_RefreshGUI(); + }); + } + } + let ExportSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button export_saved_session", title: chrome.i18n.getMessage("manager_window_savetofile_icon")}); + ExportSessionIcon.onmousedown = function(event) { + if (event.which == 1) { + let saved_session = this.parentNode; + let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); + chrome.storage.local.get(null, function(storage) { + let filename = storage.saved_sessions[SessionIndex].name == "" ? labels.noname_group : storage.saved_sessions[SessionIndex].name; + File_SaveFile(filename, "tt_session", storage.saved_sessions[SessionIndex].session); + }); + } + } + let LoadSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button load_saved_session", title: chrome.i18n.getMessage("manager_window_load_icon")}); + LoadSessionIcon.onmousedown = function(event) { + if (event.which == 1) { + let saved_session = this.parentNode; + let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); + chrome.storage.local.get(null, function(storage) { + let S_Sessions = storage.saved_sessions; + Manager_RecreateSession(S_Sessions[SessionIndex].session); + }); + } + } + let MergeSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button merge_saved_session", title: chrome.i18n.getMessage("manager_window_merge_icon")}); + MergeSessionIcon.onmousedown = function(event) { + if (event.which == 1) { + let saved_session = this.parentNode; + let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); + chrome.storage.local.get(null, function(storage) { + let S_Sessions = storage.saved_sessions; + Manager_ImportMergeTabs(S_Sessions[SessionIndex].session); + }); + } + } + let name = DOM_New("div", SavedSessionRow, {className: "manager_window_session_name", contentEditable: true, textContent: saved_session.name}); + name.onkeydown = function(event) { + return event.which != 13; + } + name.oninput = function(event) { + let session_name = this.textContent; + let s = this.parentNode; + let SessionIndex = Array.from(s.parentNode.children).indexOf(s); + chrome.storage.local.get(null, function(storage) { + let S_Sessions = storage.saved_sessions; + S_Sessions[SessionIndex].name = session_name; + chrome.storage.local.set({saved_sessions: S_Sessions}); + }); + } + DOM_RefreshGUI(); } - -function ReAddSessionAutomaticToManagerList(storage) { - let SessionsAutomaticList = document.getElementById("manager_window_autosessions_list"); - while (SessionsAutomaticList.hasChildNodes()) { - SessionsAutomaticList.removeChild(SessionsAutomaticList.firstChild); - } - if (storage.saved_sessions_automatic != undefined) { - (storage.saved_sessions_automatic).forEach(function(saved_sessions_automatic){ - AddSessionAutomaticToManagerList(saved_sessions_automatic); - }); - } - RefreshGUI(); +function Manager_ReAddSessionAutomaticToManagerList(storage) { + let SessionsAutomaticList = document.getElementById("manager_window_autosessions_list"); + while (SessionsAutomaticList.hasChildNodes()) { + SessionsAutomaticList.removeChild(SessionsAutomaticList.firstChild); + } + if (storage.saved_sessions_automatic != undefined) { + for (let saved_sessions_automatic of storage.saved_sessions_automatic) { + Manager_AddSessionAutomaticToManagerList(saved_sessions_automatic); + } + } + DOM_RefreshGUI(); } - -function AddSessionAutomaticToManagerList(saved_session) { - let SessionsList = document.getElementById("manager_window_autosessions_list"); - - let SavedSessionRow = document.createElement("li"); - SavedSessionRow.classList = "saved_session_row" - SessionsList.appendChild(SavedSessionRow); - - - let LoadSessionIcon = document.createElement("div"); - LoadSessionIcon.classList = "manager_window_list_button load_saved_session"; - LoadSessionIcon.title = chrome.i18n.getMessage("manager_window_load_icon"); - LoadSessionIcon.onmousedown = function(event) { - if (event.which == 1) { - let saved_session = this.parentNode; - let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); - chrome.storage.local.get(null, function(storage) { - let S_Sessions = storage.saved_sessions_automatic; - RecreateSession(S_Sessions[SessionIndex].session); - }); - } - } - SavedSessionRow.appendChild(LoadSessionIcon); - - - let MergeSessionIcon = document.createElement("div"); - MergeSessionIcon.classList = "manager_window_list_button merge_saved_session"; - MergeSessionIcon.title = chrome.i18n.getMessage("manager_window_merge_icon"); - MergeSessionIcon.onmousedown = function(event) { - if (event.which == 1) { - let saved_session = this.parentNode; - let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); - chrome.storage.local.get(null, function(storage) { - let S_Sessions = storage.saved_sessions_automatic; - // RecreateSession(S_Sessions[SessionIndex].session); - ImportMergeTabs(S_Sessions[SessionIndex].session); - }); - } - } - SavedSessionRow.appendChild(MergeSessionIcon); - - - - let name = document.createElement("div"); - name.textContent = saved_session.name; - name.classList = "manager_window_session_name"; - SavedSessionRow.appendChild(name); - - RefreshGUI(); +function Manager_AddSessionAutomaticToManagerList(saved_session) { + let SavedSessionRow = DOM_New("li", document.getElementById("manager_window_autosessions_list"), {className: "saved_session_row"}); + let LoadSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button load_saved_session", title: chrome.i18n.getMessage("manager_window_load_icon")}); + LoadSessionIcon.onmousedown = function(event) { + if (event.which == 1) { + let saved_session = this.parentNode; + let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); + chrome.storage.local.get(null, function(storage) { + let S_Sessions = storage.saved_sessions_automatic; + Manager_RecreateSession(S_Sessions[SessionIndex].session); + }); + } + } + let MergeSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button merge_saved_session", title: chrome.i18n.getMessage("manager_window_merge_icon")}); + MergeSessionIcon.onmousedown = function(event) { + if (event.which == 1) { + let saved_session = this.parentNode; + let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); + chrome.storage.local.get(null, function(storage) { + let S_Sessions = storage.saved_sessions_automatic; + Manager_ImportMergeTabs(S_Sessions[SessionIndex].session); + }); + } + } + DOM_New("div", SavedSessionRow, {className: "manager_window_session_name", textContent: saved_session.name}); + DOM_RefreshGUI(); } - -function SetManagerEvents() { - document.getElementById("manager_window_close").onmousedown = function(event) { - if (event.which == 1) { - HideRenameDialogs(); - } - } - - document.querySelectorAll(".manager_window_toolbar_button").forEach(function(s){ - s.onmousedown = function(event) { - if (event.which == 1) { - document.querySelectorAll(".manager_window_panel").forEach(function(s){ - s.classList.remove("mw_pan_on"); - }); - document.getElementById((this.id).replace("button", "panel")).classList.add("mw_pan_on"); - - document.querySelectorAll(".mw_on").forEach(function(s){ - s.classList.remove("mw_on"); - }); - this.classList.add("mw_on"); - RefreshGUI(); - } - } - }); - - - document.getElementById("manager_window_button_import_group").onmousedown = function(event) { - if (event.which == 1) { - let inputFile = ShowOpenFileDialog(".tt_group"); - inputFile.onchange = function(event) { - ImportGroup(false, true); - } - } - } - document.getElementById("manager_window_button_hibernate_group").onmousedown = function(event) { - if (event.which == 1) { - ExportGroup(tt.active_group, false, true); - setTimeout(function() { - GroupRemove(tt.active_group, true); - }, 100); - setTimeout(function() { - OpenManagerWindow(); - }, 150); - } - } - - - document.getElementById("manager_window_button_save_current_session").onmousedown = function(event) { - if (event.which == 1) { - let d = new Date(); - ExportSession((d.toLocaleString().replace("/", ".").replace("/", ".").replace(":", "꞉").replace(":", "꞉")), false, true, false); - } - } - document.getElementById("manager_window_button_import_session").onmousedown = function(event) { - if (event.which == 1) { - let inputFile = ShowOpenFileDialog(".tt_session"); - inputFile.onchange = function(event) { - ImportSession(false, true, false); - } - } - } - - - let autosessions_save_max_to_keep = document.getElementById("manager_window_autosessions_maximum_saves"); - autosessions_save_max_to_keep.value = opt.autosave_max_to_keep; - autosessions_save_max_to_keep.oninput = function(event) { - opt.autosave_max_to_keep = parseInt(this.value); - SavePreferences(); - } - - - let autosessions_save_timer = document.getElementById("manager_window_autosessions_save_timer"); - autosessions_save_timer.value = opt.autosave_interval; - autosessions_save_timer.oninput = function(event) { - opt.autosave_interval = parseInt(this.value); - SavePreferences(); - clearInterval(tt.AutoSaveSession); - StartAutoSaveSession(); - } - +function Manager_SetManagerEvents() { + document.getElementById("manager_window_close").onmousedown = function(event) { + if (event.which == 1) DOM_HideRenameDialogs(); + } + let query = document.querySelectorAll(".manager_window_toolbar_button"); + for (let s of query) { + s.onmousedown = function(event) { + if (event.which == 1) { + let window_panels = document.querySelectorAll(".manager_window_panel"); + for (let s of window_panels) { + s.classList.remove("mw_pan_on"); + } + document.getElementById((this.id).replace("button", "panel")).classList.add("mw_pan_on"); + let panel_on = document.querySelectorAll(".mw_on"); + for (let s of panel_on) { + s.classList.remove("mw_on"); + } + this.classList.add("mw_on"); + DOM_RefreshGUI(); + } + } + } + document.getElementById("manager_window_button_import_group").onmousedown = function(event) { + if (event.which == 1) { + let inputFile = File_ShowOpenFileDialog(".tt_group"); + inputFile.onchange = function(event) { + Manager_ImportGroup(false, true); + } + } + } + document.getElementById("manager_window_button_hibernate_group").onmousedown = function(event) { + if (event.which == 1) { + Manager_ExportGroup(tt.active_group, false, true); + setTimeout(function() {Groups_GroupRemove(tt.active_group, true);}, 100); + setTimeout(function() {Manager_OpenManagerWindow();}, 150); + } + } + document.getElementById("manager_window_button_save_current_session").onmousedown = function(event) { + if (event.which == 1) { + let d = new Date(); + Manager_ExportSession((d.toLocaleString().replace(/\//g, ".").replace(/:/g, "꞉")), false, true, false); + } + } + document.getElementById("manager_window_button_import_session").onmousedown = function(event) { + if (event.which == 1) { + let inputFile = File_ShowOpenFileDialog(".tt_session"); + inputFile.onchange = function(event) { + Manager_ImportSession(false, true, false); + } + } + } + let autosessions_save_max_to_keep = document.getElementById("manager_window_autosessions_maximum_saves"); + autosessions_save_max_to_keep.value = opt.autosave_max_to_keep; + autosessions_save_max_to_keep.oninput = function(event) { + opt.autosave_max_to_keep = parseInt(this.value); + Preferences_SavePreferences(opt); + } + let autosessions_save_timer = document.getElementById("manager_window_autosessions_save_timer"); + autosessions_save_timer.value = opt.autosave_interval; + autosessions_save_timer.oninput = function(event) { + opt.autosave_interval = parseInt(this.value); + Preferences_SavePreferences(opt); + clearInterval(tt.AutoSaveSession); + Manager_StartAutoSaveSession(); + } } + +function Manager_ExportGroup(groupId, filename, save_to_manager) { + let GroupToSave = {group: tt.groups[groupId], folders: {}, tabs: [], favicons: []}; + let query = document.querySelectorAll("#" + groupId + " .folder"); + for (let s of query) { + if (tt.folders[s.id]) GroupToSave.folders[s.id] = tt.folders[s.id]; + } + let Tabs = document.querySelectorAll("#" + groupId + " .tab"); + if (Tabs.length > 0) { + let lastId = parseInt(Tabs[Tabs.length - 1].id); + for (let s of Tabs) { + chrome.tabs.get(parseInt(s.id), async function(tab) { + if ((tab.url).startsWith("www") || (tab.url).startsWith("http") || (tab.url).startsWith("ftp") || (tab.url).startsWith("file")) { + let favicon = (browserId == "F" ? await browser.sessions.getTabValue(tab.id, "CachedFaviconUrl") : tab.favIconUrl); + let favicon_index = GroupToSave.favicons.indexOf(favicon); + if (favicon_index == -1) { + GroupToSave.favicons.push(favicon); + favicon_index = GroupToSave.favicons.length; + } + (GroupToSave.tabs).push({id: tab.id,parent: s.parentNode.parentNode.id,index: Array.from(s.parentNode.children).indexOf(s), expand: (s.classList.contains("c") ? "c" : (s.classList.contains("o") ? "o" : "")), url: tab.url, title: tab.title, favicon: favicon_index}); + } + if (tab.id == lastId) { + if (filename) File_SaveFile(filename, "tt_group", GroupToSave); + if (save_to_manager) Manager_AddGroupToStorage(GroupToSave, true); + if (opt.debug) Utils_log("f: ExportGroup, filename: " + filename + ", groupId: " + groupId + ", save_to_manager: " + save_to_manager); + } + }); + } + } else { + if (filename) File_SaveFile(filename, "tt_group", GroupToSave); + if (save_to_manager) Manager_AddGroupToStorage(GroupToSave, true); + if (opt.debug) Utils_log("f: ExportGroup, filename: " + filename + ", groupId: " + groupId + ", save_to_manager: " + save_to_manager); + } +} + +function Manager_ImportGroup(recreate_group, save_to_manager) { + let file = document.getElementById("file_import"); + let fr = new FileReader(); + if (file.files[0] == undefined) return; + fr.readAsText(file.files[0]); + fr.onload = function() { + let data = fr.result; + let group = JSON.parse(data); + file.parentNode.removeChild(file); + if (recreate_group) Manager_RecreateGroup(group); + if (save_to_manager) Manager_AddGroupToStorage(group, true); + if (opt.debug) Utils_log("f: ImportGroup, recreate_group: " + recreate_group + ", save_to_manager: " + save_to_manager); + } +} + +function Manager_RecreateGroup(LoadedGroup) { + if (opt.debug) Utils_log("f: RecreateGroup"); + let RefFolders = {}; + let NewFolders = {}; + let RefTabs = {}; + let NewTabs = []; + let NewGroupId = Groups_AddNewGroup(LoadedGroup.group.name, LoadedGroup.group.font); + for (var folder in LoadedGroup.folders) { + let newId = Folders_AddNewFolder({parent: NewGroupId, name: LoadedGroup.folders[folder].name, expand: LoadedGroup.folders[folder].expand}); + RefFolders[folder] = newId; + NewFolders[newId] = {id: newId, parent: (((LoadedGroup.folders[folder].parent).startsWith("g_") || (LoadedGroup.folders[folder].parent == "tab_list")) ? NewGroupId : LoadedGroup.folders[folder].parent), index: LoadedGroup.folders[folder].index, name: LoadedGroup.folders[folder].name, expand: LoadedGroup.folders[folder].expand}; + } + for (var new_folder in NewFolders) { + if ((NewFolders[new_folder].parent).startsWith("f_") && RefFolders[NewFolders[new_folder].parent]) NewFolders[new_folder].parent = RefFolders[NewFolders[new_folder].parent]; + } + (LoadedGroup.tabs).forEach(function(Tab) { + let params; + if (browserId == "F") { + params = {active: false, windowId: tt.CurrentWindowId, url: Tab.url, discarded: true, title: Tab.title}; + } else { + params = {active: false, windowId: tt.CurrentWindowId, url: Tab.url}; + } + chrome.tabs.create(params, function(new_tab) { + if (browserId == "F") browser.sessions.setTabValue(new_tab.id, "CachedFaviconUrl", Tab.favicon); + RefTabs[Tab.id] = new_tab.id; + Tab.id = new_tab.id; + if ((Tab.parent).startsWith("g_") || Tab.parent == "tab_list") Tab.parent = NewGroupId; + if ((Tab.parent).startsWith("f_") && RefFolders[Tab.parent]) Tab.parent = RefFolders[Tab.parent]; + NewTabs.push(Tab); + if (browserId != "O" && browserId != "F") chrome.runtime.sendMessage({command: "discard_tab", tabId: new_tab.id}); + if (NewTabs.length == LoadedGroup.tabs.length - 1) { + NewTabs.forEach(function(LTab) { + if (RefTabs[LTab.parent]) LTab.parent = RefTabs[LTab.parent]; + }); + let GiveUp = 3000; // gives up after: 300*3000/1000/60 = 15 minutes + let RecreateTreeS = setInterval(function() { + GiveUp--; + let LastTab = document.getElementById(NewTabs[NewTabs.length - 1].id); + if (LastTab != null || GiveUp < 0) { + Manager_RecreateTreeStructure({}, NewFolders, NewTabs); + clearInterval(RecreateTreeS); + } + }, 300); + } + }); + }); +} + +function Manager_AddGroupToStorage(group, add_to_manager) { + chrome.storage.local.get(null, function(storage) { + if (storage["hibernated_groups"] == undefined) { + let hibernated_groups = []; + hibernated_groups.push(group); + chrome.storage.local.set({hibernated_groups: hibernated_groups}); + if (add_to_manager) Manager_AddGroupToManagerList(group); + } else { + let hibernated_groups = storage["hibernated_groups"]; + hibernated_groups.push(group); + chrome.storage.local.set({hibernated_groups: hibernated_groups}); + if (add_to_manager) Manager_AddGroupToManagerList(group); + } + if (opt.debug) Utils_log("f: AddGroupToStorage, add_to_manager: " + add_to_manager); + }); +} + +function Manager_ExportSession(name, save_to_file, save_to_manager, save_to_autosave_manager) { + chrome.windows.getAll({windowTypes: ['normal'], populate: true}, function(win) { + chrome.runtime.sendMessage({command: "get_browser_tabs"}, function(t) { + let tabs = Object.assign({}, t); + chrome.runtime.sendMessage({command: "get_windows"}, function(w) { + let windows = Object.assign({}, w); + let ExportWindows = []; + win.forEach(function(CWin) { + if (CWin.tabs.length > 0) { + windows[CWin.id]["id"] = CWin.id; + windows[CWin.id]["tabs"] = []; + windows[CWin.id]["favicons"] = []; + CWin.tabs.forEach(async function(CTab) { + if ((CTab.url).startsWith("www") || (CTab.url).startsWith("http") || (CTab.url).startsWith("ftp")) { + let favicon = (browserId == "F" ? await browser.sessions.getTabValue(CTab.id, "CachedFaviconUrl") : CTab.favIconUrl); + let favicon_index = windows[CWin.id].favicons.indexOf(favicon); + if (favicon_index == -1) { + windows[CWin.id].favicons.push(favicon); + favicon_index = windows[CWin.id].favicons.length; + } + windows[CWin.id]["tabs"].push({id: CTab.id, url: CTab.url, parent: tabs[CTab.id].parent, index: tabs[CTab.id].index, expand: tabs[CTab.id].expand, title: CTab.title, favicon: favicon_index}); + } + }); + ExportWindows.push(windows[CWin.id]); + } + }); + if (save_to_file) File_SaveFile(name, "tt_session", ExportWindows); + if (save_to_manager) Manager_AddSessionToStorage(ExportWindows, name, true); + if (save_to_autosave_manager) Manager_AddAutosaveSessionToStorage(ExportWindows, name); + }); + }); + }); +} + +function Manager_ImportSession(recreate_session, save_to_manager, merge_session) { + let file = document.getElementById("file_import"); + let fr = new FileReader(); + if (file.files[0] == undefined) return; + fr.readAsText(file.files[file.files.length - 1]); + fr.onload = function() { + let data = fr.result; + file.parentNode.removeChild(file); + let LoadedSession = JSON.parse(data); + if (recreate_session) Manager_RecreateSession(LoadedSession); + if (merge_session) Manager_ImportMergeTabs(LoadedSession); + if (save_to_manager) Manager_AddSessionToStorage(LoadedSession, (file.files[file.files.length - 1].name).replace(".tt_session", ""), true); + } +} + +function Manager_AddSessionToStorage(session, name, add_to_manager) { + chrome.storage.local.get(null, function(storage) { + if (storage.saved_sessions == undefined) { + let saved_sessions = []; + saved_sessions.push({name: name, session: session}); + chrome.storage.local.set({saved_sessions: saved_sessions}); + if (add_to_manager) Manager_AddSessionToManagerList(saved_sessions[saved_sessions.length - 1]); + } else { + let saved_sessions = storage.saved_sessions; + saved_sessions.push({name: name, session: session}); + chrome.storage.local.set({saved_sessions: saved_sessions}); + if (add_to_manager) Manager_AddSessionToManagerList(saved_sessions[saved_sessions.length - 1]); + } + if (opt.debug) Utils_log("f: AddSessionToStorage, name: " + name + ", add_to_manager: " + add_to_manager); + }); +} + +function Manager_AddAutosaveSessionToStorage(session, name) { + chrome.storage.local.get(null, function(storage) { + if (storage.saved_sessions_automatic == undefined) { + let s = []; + s.push({name: name, session: session}); + chrome.storage.local.set({saved_sessions_automatic: s}); + } else { + let s = storage.saved_sessions_automatic; + s.unshift({name: name, session: session}); + if (s[opt.autosave_max_to_keep]) s.splice(opt.autosave_max_to_keep, (s.length - opt.autosave_max_to_keep)); + chrome.storage.local.set({saved_sessions_automatic: s}); + } + if (opt.debug) Utils_log("f: AddAutosaveSessionToStorage, name: " + name); + }); +} + +function Manager_RecreateSession(LoadedWindows) { + if (opt.debug) Utils_log("f: RecreateSession"); + let RefTabs = {}; + LoadedWindows.forEach(function(LWin) { + let NewTabs = []; + let urls = []; + for (let Tab of LWin.tabs) { + urls.push(Tab.url); + NewTabs.push(Tab); + } + chrome.windows.create({url: urls[0]}, function(new_window) { + chrome.runtime.sendMessage({command: "save_groups", windowId: new_window.id, groups: LWin.groups}); + chrome.runtime.sendMessage({command: "save_folders", windowId: new_window.id, folders: LWin.folders}); + (LWin.tabs).forEach(function(Tab) { + if (Tab.id != LWin.tabs[0].id) { // skip first tab + let params; + if (browserId == "F") { + params = {active: false, windowId: new_window.id, url: Tab.url, discarded: true, title: Tab.title}; + } else { + params = {active: false, windowId: new_window.id, url: Tab.url}; + } + chrome.tabs.create(params, function(new_tab) { + if (browserId == "F") browser.sessions.setTabValue(new_tab.id, "CachedFaviconUrl", LWin.favicons[Tab.favicon]); + if (Tab.id == LWin.tabs[LWin.tabs.length - 1].id) { // last tab + chrome.windows.get(new_window.id, {populate: true}, function(new_window_with_new_tabs) { + for (let tInd = 0; tInd < new_window_with_new_tabs.tabs.length; tInd++) { + RefTabs[NewTabs[tInd].id] = new_window_with_new_tabs.tabs[tInd].id; + NewTabs[tInd].id = new_window_with_new_tabs.tabs[tInd].id; + } + for (let tInd = 0; tInd < new_window_with_new_tabs.tabs.length; tInd++) { + if (RefTabs[NewTabs[tInd].parent] != undefined) NewTabs[tInd].parent = RefTabs[NewTabs[tInd].parent]; + } + for (let tInd = 0; tInd < new_window_with_new_tabs.tabs.length; tInd++) { + if (NewTabs[tInd].parent == "pin_list") chrome.tabs.update(new_window_with_new_tabs.tabs[tInd].id, {pinned: true}); + chrome.runtime.sendMessage({command: "update_tab", tabId: new_window_with_new_tabs.tabs[tInd].id, tab: {index: NewTabs[tInd].index, expand: NewTabs[tInd].expand, parent: NewTabs[tInd].parent}}); + if (browserId != "O" && browserId != "F") chrome.runtime.sendMessage({command: "discard_tab", tabId: new_window_with_new_tabs.tabs[tInd].id}); + } + }); + } + }); + } + }); + }); + }); +} + +function Manager_ImportMergeTabs(LoadedWindows) { + if (opt.debug) Utils_log("f: ImportMergeTabs"); + let RefTabs = {}; + for (let LWI = 0; LWI < LoadedWindows.length; LWI++) { // clear previous window ids + LoadedWindows[LWI].id = ""; + } + Manager_ShowStatusBar({show: true, spinner: true, message: chrome.i18n.getMessage("status_bar_loaded_tree_structure")}); + chrome.windows.getAll({windowTypes: ['normal'], populate: true}, function(cw) { + for (let CWI = 0; CWI < cw.length; CWI++) { // Current Windows + for (let LWI = 0; LWI < LoadedWindows.length; LWI++) { // Loaded Windows + if (LoadedWindows[LWI].id == "") { + let tabsMatch = 0; + for (let CTI = 0; CTI < cw[CWI].tabs.length; CTI++) { // loop Tabs of CWI Window + for (let LTI = 0; LTI < LoadedWindows[LWI].tabs.length; LTI++) { // loop Tabs of Loaded Window + if (cw[CWI].tabs[CTI].url == LoadedWindows[LWI].tabs[LTI].url) { + RefTabs[LoadedWindows[LWI].tabs[LTI].id] = cw[CWI].tabs[CTI].id; + LoadedWindows[LWI].tabs[LTI].id = cw[CWI].tabs[CTI].id; + LoadedWindows[LWI].tabs[LTI].url = ""; + tabsMatch++; + break; + } + } + } + if (opt.debug) Utils_log("f: ImportMergeTabs, tabsMatch: " + tabsMatch); + if (tabsMatch > LoadedWindows[LWI].tabs.length * 0.6) { + LoadedWindows[LWI].id = cw[CWI].id; + break; + } + } + } + } + LoadedWindows.forEach(function(w) { + if (w.id == "") { // missing window, lets make one + if (opt.debug) Utils_log("f: ImportMergeTabs, missing window"); + let NewTabs = []; + let urls = []; + (w.tabs).forEach(function(Tab) { + urls.push(Tab.url); + NewTabs.push(Tab); + }); + chrome.windows.create({url: urls[0]}, function(new_window) { + chrome.runtime.sendMessage({command: "save_groups", windowId: new_window.id, groups: LWin.groups}); + chrome.runtime.sendMessage({command: "save_folders", windowId: new_window.id, folders: LWin.folders}); + (w.tabs).forEach(function(Tab) { + if (Tab.id != LWin.tabs[0].id) { // skip first tab + let params; + if (browserId == "F") { + params = {active: false, windowId: new_window.id, url: Tab.url, discarded: true, title: Tab.title}; + } else { + params = {active: false, windowId: new_window.id, url: Tab.url}; + } + chrome.tabs.create(params, function(new_tab) { + if (browserId == "F") browser.sessions.setTabValue(new_tab.id, "CachedFaviconUrl", w.favicons[Tab.favicon]); + if (Tab.id == LWin.tabs[LWin.tabs.length - 1].id) { // last tab + chrome.windows.get(new_window.id, {populate: true}, function(new_window_with_new_tabs) { + for (let tInd = 0; tInd < new_window_with_new_tabs.tabs.length; tInd++) { + RefTabs[NewTabs[tInd].id] = new_window_with_new_tabs.tabs[tInd].id; + NewTabs[tInd].id = new_window_with_new_tabs.tabs[tInd].id; + } + for (let tInd = 0; tInd < new_window_with_new_tabs.tabs.length; tInd++) { + if (RefTabs[NewTabs[tInd].parent] != undefined) NewTabs[tInd].parent = RefTabs[NewTabs[tInd].parent]; + } + for (let tInd = 0; tInd < new_window_with_new_tabs.tabs.length; tInd++) { + if (NewTabs[tInd].parent == "pin_list") chrome.tabs.update(new_window_with_new_tabs.tabs[tInd].id, {pinned: true}); + chrome.runtime.sendMessage({command: "update_tab", tabId: new_window_with_new_tabs.tabs[tInd].id, tab: {index: NewTabs[tInd].index, expand: NewTabs[tInd].expand, parent: NewTabs[tInd].parent}}); + if (browserId != "O" && browserId != "F") chrome.runtime.sendMessage({command: "discard_tab", tabId: new_window_with_new_tabs.tabs[tInd].id}); + } + }); + } + }); + } + }); + }); + } else { // window exists, lets add missing tabs + let NewTabs = []; + let RefTabs = {}; + chrome.runtime.sendMessage({command: "get_folders", windowId: w.id}, function(f) { + chrome.runtime.sendMessage({command: "get_groups", windowId: w.id}, function(g) { + if (Object.keys(w.groups).length > 0) { + for (var group in w.groups) { + if (group != "" && group != "undefined" && w.groups[group] != undefined) g[w.groups[group].id] = Object.assign({}, w.groups[group]); + } + } + if (Object.keys(w.folders).length > 0) { + for (var folder in w.folders) { + if (folder != "" && folder != "undefined" && w.folders[folder] != undefined) w.folders[w.folders[folder].id] = Object.assign({}, w.folders[folder]); + } + } + if (Object.keys(g).length > 0) { + for (var groupId in g) { + w.groups[groupId] = Object.assign({}, g[groupId]); + } + } + if (Object.keys(f).length > 0) { + for (var folderId in f) { + w.folders[folderId] = Object.assign({}, f[folderId]); + } + } + chrome.runtime.sendMessage({command: "save_groups", windowId: w.id, groups: g}); + chrome.runtime.sendMessage({command: "save_folders", windowId: w.id, folders: f}); + chrome.runtime.sendMessage({command: "remote_update", groups: w.groups, folders: w.folders, tabs: [], windowId: w.id}); + if (w.id == tt.CurrentWindowId) Manager_RecreateTreeStructure(w.groups, w.folders, []); + (w.tabs).forEach(function(Tab) { + // let LastTabId = w.tabs[w.tabs.length - 1].id; + // let OriginalTabId = Tab.id; + if (Tab.url != "") { // missing tab, lets make one + let params; + if (browserId == "F") { + params = {active: false, windowId: w.id, url: Tab.url, discarded: true, title: Tab.title}; + } else { + params = {active: false, windowId: w.id, url: Tab.url}; + } + chrome.tabs.create(params, function(tab) { + if (browserId == "F") browser.sessions.setTabValue(tab.id, "CachedFaviconUrl", w.favicons[Tab.favicon]); + if (Tab.parent == "pin_list") chrome.tabs.update(tab.id, {pinned: true}); + RefTabs[Tab.id] = tab.id; + Tab.id = tab.id; + NewTabs.push(Tab); + chrome.runtime.sendMessage({command: "update_tab", tabId: tab.id, tab: {index: Tab.index, expand: Tab.expand, parent: Tab.parent}}); + }); + } else { + NewTabs.push(Tab); + } + // if (OriginalTabId == LastTabId) { // loop is on last tab + // setTimeout(function() { + // Manager_ShowStatusBar({show: true, spinner: true, message: chrome.i18n.getMessage("status_bar_finding_ref_tabs")}); + // for (let tInd = 0; tInd < NewTabs.length; tInd++) { + // if (RefTabs[NewTabs[tInd].parent] != undefined) { + // NewTabs[tInd].parent = RefTabs[NewTabs[tInd].parent]; + // } + // } + // }, 1000); + // } + }); + setTimeout(function() { + Manager_ShowStatusBar({show: true, spinner: true, message: chrome.i18n.getMessage("status_bar_finding_ref_tabs")}); + for (let tInd = 0; tInd < NewTabs.length; tInd++) { + if (RefTabs[NewTabs[tInd].parent] != undefined) NewTabs[tInd].parent = RefTabs[NewTabs[tInd].parent]; + } + }, 2000); + setTimeout(function() { + for (let NewTab of NewTabs) { + chrome.runtime.sendMessage({command: "update_tab", tabId: NewTab.id, tab: {index: NewTab.index, expand: NewTab.expand, parent: NewTab.parent}}); + } + Manager_ShowStatusBar({show: true, spinner: true, message: chrome.i18n.getMessage("status_bar_finding_other_windows")}); + if (w.id == tt.CurrentWindowId) { + Manager_RecreateTreeStructure(w.groups, w.folders, NewTabs); + } else { + chrome.runtime.sendMessage({command: "remote_update", groups: w.groups, folders: w.folders, tabs: NewTabs, windowId: w.id}); + } + Manager_ShowStatusBar({show: true, spinner: false, message: chrome.i18n.getMessage("status_bar_all_done"), hideTimeout: 2000}); + }, 6000); + }); + }); + } + }); + }); +} + +function Manager_StartAutoSaveSession() { + if (opt.autosave_interval > 0 && opt.autosave_max_to_keep > 0) { + tt.AutoSaveSession = setInterval(function() { + if (opt.debug) Utils_log("f: AutoSaveSession, loop time is: " + opt.autosave_interval); + let d = new Date(); + let newName = d.toLocaleString().replace(/\//g, ".").replace(/:/g, "꞉"); + Manager_ExportSession(newName, false, false, true); + Manager_ShowStatusBar({show: true, spinner: false, message: chrome.i18n.getMessage("status_bar_autosave") + newName, hideTimeout: 1500}); + if (document.getElementById("manager_window").style.top != "-500px") chrome.storage.local.get(null, function(storage) {Manager_ReAddSessionAutomaticToManagerList(storage);}); + }, opt.autosave_interval * 60000); + } +} + +function Manager_RecreateTreeStructure(groups, folders, tabs) { // groups and folders are in object, just like tt.groups and tt.folders, but tabs are in array of treetabs objects + if (opt.debug) Utils_log("f: RecreateTreeStructure"); + Manager_ShowStatusBar({show: true, spinner: true, message: chrome.i18n.getMessage("status_bar_quick_check_recreate_structure"), hideTimeout: 3000}); + if (groups && Object.keys(groups).length > 0) { + for (var group in groups) { + tt.groups[groups[group].id] = Object.assign({}, groups[group]); + } + Groups_AppendGroups(tt.groups); + } + if (folders && Object.keys(folders).length > 0) { + for (var folder in folders) { + tt.folders[folders[folder].id] = Object.assign({}, folders[folder]); + } + Folders_PreAppendFolders(tt.folders); + Folders_AppendFolders(tt.folders); + } + let ttTabs = {}; + tabs.forEach(function(Tab) { + if (Tab.parent == "pin_list") chrome.tabs.update(Tab.id, {pinned: true}); + if (Tab.parent != "") { + let AttemptNr = 20; + var Attempt = setInterval(function() { + AttemptNr--; + let tb = document.getElementById(Tab.id); + let tbp = document.getElementById("°" + Tab.parent); + if (tb != null && tbp != null) { + tbp.appendChild(tb); + if (Tab.expand != "") tb.classList.add(Tab.expand); + ttTabs[Tab.id] = {index: Tab.index, parent: Tab.parent, expand: Tab.expand}; + } + if (AttemptNr < 0 || (tb != null && tbp != null)) clearInterval(Attempt); + }, 500); + } + }); + let SortAttemptNr = 20; + var SortAttempt = setInterval(function() { + SortAttemptNr--; + if (SortAttemptNr < 0 || Object.keys(ttTabs).length == tabs.length || tabs.length == 0) { + Tabs_RearrangeTree(ttTabs, folders, false); + clearInterval(SortAttempt); + Groups_UpdateBgGroupsOrder(); + setTimeout(function() { + DOM_RefreshExpandStates(); + DOM_RefreshCounters(); + tt.schedule_update_data++; + Folders_SaveFolders(); + }, 3000); + } + }, 500); +} + +function Manager_ShowStatusBar(p) { // show, spinner, message + let status_bar = document.getElementById("status_bar"); + let busy_spinner = document.getElementById("busy_spinner"); + let status_message = document.getElementById("status_message"); + if (p.show) { + status_bar.style.display = "block"; + status_message.textContent = p.message; + if (p.spinner) { + busy_spinner.style.opacity = "1"; + } else { + busy_spinner.style.opacity = "0"; + } + } else { + busy_spinner.style.opacity = "0"; + status_message.textContent = ""; + status_bar.style.display = "none"; + } + if (p.hideTimeout) { + setTimeout(function() { + busy_spinner.style.opacity = "0"; + status_message.textContent = ""; + status_bar.style.display = "none"; + }, p.hideTimeout); + } +} \ No newline at end of file diff --git a/scripts/menu.js b/scripts/menu.js index 90b2ef1..554fde2 100644 --- a/scripts/menu.js +++ b/scripts/menu.js @@ -1,709 +1,496 @@ -// 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/ - -// ********** MENU *************** - -function HideMenus() { - document.querySelectorAll(".separator, .menu_item").forEach(function(s){s.style.display = "none";}); - document.querySelectorAll(".menu").forEach(function(s){ - s.style.top = "-1000px"; - s.style.left = "-1000px"; - s.style.display = "none"; - }); +class Menu_ttMenu { + constructor(MenuItem) { + let SeparatorDIV = DOM_New("div", tt.DOMmenu, {id: MenuItem[0], className: "separator"}); + let MenuLI = DOM_New("li", tt.DOMmenu, {id: MenuItem[1], className: "menu_item"}); + this.id = MenuLI.id; + this.Menu = MenuLI; + this.Separator = SeparatorDIV; + + if (this.id == "menu_new_pin") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("pin")) { + console.log(tt.menuItemNode) + Tabs_OpenNewTab(true, tt.menuItemNode, undefined); + } else { + Tabs_OpenNewTab(true, undefined, undefined); + } + }}} + if (this.id == "menu_new_tab") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("folder")) { + Tabs_OpenNewTab(false, undefined, tt.menuItemNode.childNodes[1]); + } else { + if (tt.menuItemNode.classList.contains("pin")) { + Tabs_OpenNewTab(true, tt.menuItemNode, undefined); + } else { + if (tt.menuItemNode.classList.contains("tab")) { + Tabs_OpenNewTab(false, tt.menuItemNode, undefined); + } else { + Tabs_OpenNewTab(false, undefined, document.getElementById("°"+tt.active_group)); + } + } + } + }}} + if (this.id == "menu_unpin_tab" || this.id == "menu_pin_tab") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("selected")) { + let query = document.querySelectorAll(".pin.selected, [id='" + tt.active_group + "'] .selected"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {pinned: (tt.menuItemNode.classList.contains("tab"))}); + } + } else { + chrome.tabs.update(parseInt(tt.menuItemNode.id), {pinned: (tt.menuItemNode.classList.contains("tab"))}); + } + }}} + if (this.id == "menu_duplicate_tab") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("selected")) { + let query = document.querySelectorAll(".pin.selected, [id='" + tt.active_group + "'] .selected"); + for (let s of query) { + tt.tabs[s.id].DuplicateTab(); + } + } else { + tt.tabs[tt.menuItemNode.id].DuplicateTab(); + } + }}} + if (this.id == "menu_detach_tab") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + DOM_FreezeSelection(false); + let Nodes = []; + let NodesTypes = {DraggingPin: false, DraggingTab: false, DraggingFolder: false}; + let query = []; + if (tt.menuItemNode.classList.contains("selected")) { + query = document.querySelectorAll(".selected, .selected .tab, .selected .folder"); + } else { + query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'], [id='" + tt.menuItemNode.id + "'] .tab, [id='" + tt.menuItemNode.id + "'] .folder"); + } + for (let s of query) { + if (s.classList.contains("pin")) { + NodesTypes.DraggingPin = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "pin"}); + } + if (s.classList.contains("tab")) { + NodesTypes.DraggingTab = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "tab"}); + } + if (s.classList.contains("folder")) { + NodesTypes.DraggingFolder = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "folder", index: (tt.folders[s.id] ? tt.folders[s.id].index : 0), name: (tt.folders[s.id] ? tt.folders[s.id].name : labels.noname_group), expand: (tt.folders[s.id] ? tt.folders[s.id].expand : "")}); + } + } + Tabs_Detach(Nodes, NodesTypes, {}); + }}} + if (this.id == "menu_reload_tab") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("selected")) { + let query = document.querySelectorAll(".pin.selected, [id='" + tt.active_group + "'] .selected"); + for (let s of query) { + chrome.tabs.reload(parseInt(s.id)); + } + } else { + chrome.tabs.reload(parseInt(tt.menuItemNode.id)); + } + }}} + if (this.id == "menu_unload") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("pin") || tt.menuItemNode.classList.contains("tab")) { + if (tt.menuItemNode.classList.contains("selected")) { + let tabsArr = []; + let query = document.querySelectorAll(".pin.selected, [id='" + tt.active_group + "'] .selected"); + for (let s of query) { + tabsArr.push(parseInt(s.id)); + let children = document.querySelectorAll("[id='" + s.id + "'] .tab"); + if (children.length > 0) { + for (let t of children) { + tabsArr.push(parseInt(t.id)); + } + } + } + Tabs_DiscardTabs(tabsArr); + } else { + Tabs_DiscardTabs([parseInt(tt.menuItemNode.id)]); + } + } + if (tt.menuItemNode.classList.contains("folder")) { + let tabsArr = []; + let query = document.querySelectorAll("[id='"+ tt.menuItemNode.id + "'] .tab"); + for (let s of query) { + tabsArr.push(parseInt(s.id)); + } + Tabs_DiscardTabs(tabsArr); + } + }}} + if (this.id == "menu_unload_tree") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("pin") || tt.menuItemNode.classList.contains("tab")) { + if (tt.menuItemNode.classList.contains("selected")) { + let tabsArr = []; + let query = document.querySelectorAll(".pin.selected, [id='" + tt.active_group + "'] .selected"); + for (let s of query) { + tabsArr.push(parseInt(s.id)); + let children = document.querySelectorAll("[id='" + s.id + "'] .tab"); + if (children.length > 0) { + for (let t of children) { + tabsArr.push(parseInt(t.id)); + } + } + } + Tabs_DiscardTabs(tabsArr); + } else { + let tabsArr = []; + tabsArr.push(parseInt(tt.menuItemNode.id)); + let children = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'] .tab"); + if (children.length > 0) { + for (let t of children) { + tabsArr.push(parseInt(t.id)); + } + } + Tabs_DiscardTabs(tabsArr); + } + } + if (tt.menuItemNode.classList.contains("folder")) { + let tabsArr = []; + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'] .tab"); + for (let s of query) { + tabsArr.push(parseInt(s.id)); + } + Tabs_DiscardTabs(tabsArr); + } + }}} + if (this.id == "menu_close") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("selected")) { + let tabsArr = []; + let query = document.querySelectorAll(".pin.selected, [id='" + tt.active_group + "'] .selected"); + for (let s of query) { + tabsArr.push(parseInt(s.id)); + } + Tabs_CloseTabs(tabsArr); + } else { + Tabs_CloseTabs([parseInt(tt.menuItemNode.id)]); + } + }}} + if (this.id == "menu_mute_tab") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("pin") || tt.menuItemNode.classList.contains("tab")) { + if (tt.menuItemNode.classList.contains("selected")) { + let query = document.querySelectorAll(".pin.selected, [id='" + tt.active_group + "'] .selected"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {muted: true}); + } + } else { + chrome.tabs.update(parseInt(tt.menuItemNode.id), {muted: true}); + } + } + if (tt.menuItemNode.classList.contains("folder")) { + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'] .tab"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {muted: true}); + } + } + }}} + if (this.id == "menu_mute_tree") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'], [id='" + tt.menuItemNode.id + "'] .tab"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {muted: true}); + } + }}} + if (this.id == "menu_unmute_tab") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("pin") || tt.menuItemNode.classList.contains("tab")) { + if (tt.menuItemNode.classList.contains("selected")) { + let query = document.querySelectorAll(".pin.selected, [id='" + tt.active_group + "'] .selected"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {muted: false}); + } + } else { + chrome.tabs.update(parseInt(tt.menuItemNode.id), {muted: false}); + } + } + if (tt.menuItemNode.classList.contains("folder")) { + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'] .tab"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {muted: false}); + } + } + }}} + if (this.id == "menu_unmute_tree") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'], [id='" + tt.menuItemNode.id + "'] .tab"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {muted: false}); + } + }}} + if (this.id == "menu_mute_other") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("selected")) { + let query = document.querySelectorAll(".pin:not(.selected), [id='" + tt.active_group + "'] .tab:not(.selected)"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {muted: true}); + } + } else { + let query = document.querySelectorAll(".pin:not([id='" + tt.menuItemNode.id + "']), [id='" + tt.active_group + "'] .tab:not([id='" + tt.menuItemNode.id + "'])"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {muted: true}); + } + } + }}} + if (this.id == "menu_unmute_other") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("selected")) { + let query = document.querySelectorAll(".pin:not(.selected), [id='" + tt.active_group + "'] .tab:not(.selected)"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {muted: false}); + } + } else { + let query = document.querySelectorAll(".pin:not([id='" + tt.menuItemNode.id + "']), [id='" + tt.active_group + "'] .tab:not([id='" + tt.menuItemNode.id + "'])"); + for (let s of query) { + chrome.tabs.update(parseInt(s.id), {muted: false}); + } + } + }}} + if (this.id == "menu_undo_close_tab") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + chrome.sessions.getRecentlyClosed(null, function(sessions) { + if (sessions.length > 0) { + chrome.sessions.restore(null, function() {}); + } + }); + }}} + if (this.id == "menu_new_folder") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("tab")) { + let FolderId = Folders_AddNewFolder({ParentId: tt.menuItemNode.parentNode.parentNode.id, InsertAfterId: tt.menuItemNode.id}); + Folders_ShowRenameFolderDialog(FolderId); + } else { + if (tt.menuItemNode.classList.contains("folder")) { + let FolderId = Folders_AddNewFolder({ParentId: tt.menuItemNode.id}); + Folders_ShowRenameFolderDialog(FolderId); + } else { + let FolderId = Folders_AddNewFolder({}); + Folders_ShowRenameFolderDialog(FolderId); + } + } + }}} + if (this.id == "menu_expand_tree") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'], [id='" + tt.menuItemNode.id + "'] .folder.c, [id='" + tt.menuItemNode.id + "'] .tab.c"); + for (let s of query) { + DOM_SetClasses(s, ["o"], ["c"], []); + } + tt.schedule_update_data++; + Folders_SaveFolders(); + }}} + if (this.id == "menu_collapse_tree") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'], [id='" + tt.menuItemNode.id + "'] .folder.c, [id='" + tt.menuItemNode.id + "'] .tab.c"); + for (let s of query) { + DOM_SetClasses(s, ["c"], ["o"], []); + } + tt.schedule_update_data++; + Folders_SaveFolders(); + }}} + if (this.id == "menu_expand_all") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let query = document.querySelectorAll("[id='" + tt.active_group + "'] .folder.c, [id='" + tt.active_group + "'] .tab.c"); + for (let s of query) { + DOM_SetClasses(s, ["o"], ["c"], []); + } + tt.schedule_update_data++; + Folders_SaveFolders(); + }}} + if (this.id == "menu_collapse_all") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let query = document.querySelectorAll("[id='" + tt.active_group + "'] .folder.o, [id='" + tt.active_group + "'] .tab.o"); + for (let s of query) { + DOM_SetClasses(s, ["c"], ["o"], []); + } + tt.schedule_update_data++; + Folders_SaveFolders(); + }}} + if (this.id == "menu_close_tree") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let tabsArr = []; + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'] .tab, [id='" + tt.menuItemNode.id + "']"); + for (let s of query) { + tabsArr.push(parseInt(s.id)); + } + Tabs_CloseTabs(tabsArr); + }}} + if (this.id == "menu_rename_folder") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + Folders_ShowRenameFolderDialog(tt.menuItemNode.id); + }}} + if (this.id == "menu_delete_folder") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + if (tt.menuItemNode.classList.contains("selected")) { + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'] .selected, [id='" + tt.menuItemNode.id + "']"); + for (let s of query) { + Folders_RemoveFolder(s.id); + } + } else { + Folders_RemoveFolder(tt.menuItemNode.id); + } + }}} + if (this.id == "menu_close_other") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let tabsArr = []; + let query = []; + if (tt.menuItemNode.classList.contains("selected")) { + if (tt.menuItemNode.classList.contains("pin")) query = document.querySelectorAll(".pin:not(.selected)"); + if (tt.menuItemNode.classList.contains("tab")) query = document.querySelectorAll("[id='" + tt.active_group + "'] .tab:not(.selected)"); + for (let s of query) { + let children = document.querySelectorAll("[id='" + s.id + "'] .selected"); + if (children.length == 0 || opt.promote_children) tabsArr.push(parseInt(s.id)); + } + Tabs_CloseTabs(tabsArr); + } else { + if (tt.menuItemNode.classList.contains("pin")) query = document.querySelectorAll(".pin:not([id='" + tt.menuItemNode.id + "'])"); + if (tt.menuItemNode.classList.contains("tab")) { + query = document.querySelectorAll("[id='°" + tt.active_group + "'] .tab:not([id='" + tt.menuItemNode.id + "'])"); + document.getElementById("°" + tt.active_group).appendChild(tt.menuItemNode); + } + for (let s of query) { + tabsArr.push(parseInt(s.id)); + } + Tabs_CloseTabs(tabsArr); + } + }}} + if (this.id == "menu_bookmark_tree") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + Bookmark(tt.menuItemNode); + }}} + if (this.id == "menu_rename_group") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + Groups_ShowGroupEditWindow(tt.menuItemNode.id); + }}} + if (this.id == "menu_delete_group") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + Groups_GroupRemove(tt.menuItemNode.id, false); + }}} + if (this.id == "menu_delete_group_tabs_close") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + Groups_GroupRemove(tt.menuItemNode.id, true); + }}} + if (this.id == "menu_groups_unload") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let tabsArr = []; + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'] .tab"); + for (let s of query) { + tabsArr.push(parseInt(s.id)); + } + Tabs_DiscardTabs(tabsArr); + }}} + if (this.id == "menu_group_tabs_close") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let tabsArr = []; + let query = document.querySelectorAll("[id='" + tt.menuItemNode.id + "'] .tab"); + for (let s of query) { + tabsArr.push(parseInt(s.id)); + } + Tabs_CloseTabs(tabsArr); + }}} + if (this.id == "menu_manager_window") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + Manager_OpenManagerWindow(); + }}} + if (this.id == "menu_groups_hibernate") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + Manager_ExportGroup(tt.menuItemNode.id, false, true); + setTimeout(function() {Groups_GroupRemove(tt.menuItemNode.id, true);}, 100); + }}} + if (this.id == "menu_bookmark_group") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + Bookmark(tt.menuItemNode); + }}} + if (this.id == "menu_new_group") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + let NewGroupId = Groups_AddNewGroup(); + Groups_ShowGroupEditWindow(NewGroupId); + }}} + if (this.id == "menu_treetabs_settings") { this.Menu.onmousedown = function(event) { if (event.which == 1) { + chrome.tabs.create({"url": "options/options.html"}); + }}} + } + MenuHide() { + this.Menu.style.display = "none"; + } + MenuShow() { + this.Menu.style.display = ""; + } + SeparatorHide() { + this.Separator.style.display = "none"; + } + SeparatorShow() { + this.Separator.style.display = ""; + } } -function ShowMenu(MenuNode, event) { - MenuNode.style.display = "block"; - let x = event.pageX >= (document.body.clientWidth - MenuNode.getBoundingClientRect().width - 5) ? (document.body.clientWidth - MenuNode.getBoundingClientRect().width - 5) : (event.pageX - 5); - let y = event.pageY >= (document.body.clientHeight - MenuNode.getBoundingClientRect().height - 16) ? (document.body.clientHeight - MenuNode.getBoundingClientRect().height - 16) : (event.pageY - 16); - MenuNode.style.top = y + "px"; - MenuNode.style.left = x + "px"; +function Menu_HideMenus() { + for (let MenuItem of DefaultMenu.all_entries) { + tt.menu[MenuItem[1]].MenuHide(); + tt.menu[MenuItem[1]].SeparatorHide(); + } + DOM_SetStyle(tt.menu[DefaultMenu.all_entries[0][1]].Menu.parentNode, {display: "none", top: "-1000px", left: "-1000px"}); } -function ShowTabMenu(TabNode, event) { - HideMenus(); - tt.menuItemNode = TabNode; - // $(".menu").hide(0); - - // MUTE TABS - // if (TabNode.classList.contains("audible") && !TabNode.classList.contains("muted")) { - // document.querySelector("#menu_mute_tab").style.display = ""; - // } - if (TabNode.classList.contains("muted")) { - document.querySelector("#menu_unmute_tab").style.display = ""; - } else { - document.querySelector("#menu_mute_tab").style.display = ""; - } - if (!TabNode.classList.contains("discarded")) { - document.querySelector("#menu_unload").style.display = ""; - } - - if (TabNode.classList.contains("pin")) { - if (opt.allow_pin_close) { - document.getElementById("menu_close").style.display = ""; - } - - document.querySelectorAll("#menu_new_pin, #separator_unpt, #menu_unpin_tab, #separator_dupt, #menu_duplicate_tab, #separator_undclo, #menu_undo_close_tab, #separator_deta, #menu_detach_tab, #menu_reload_tab, #separator_clo, #menu_close_other, #separator_mutot, #menu_mute_other, #menu_unmute_other, #separator_tts, #menu_manager_window, #menu_treetabs_settings").forEach(function(s){ - s.style.display = ""; - }); - } - - if (TabNode.classList.contains("tab")) { - - document.querySelectorAll("#menu_bookmark_tree, #menu_new_tab, #separator_pit, #menu_pin_tab, #separator_newf, #menu_new_folder, #separator_dupt, #menu_duplicate_tab, #separator_undclo, #menu_undo_close_tab, #separator_expaa, #menu_expand_all, #menu_collapse_all, #separator_deta, #menu_detach_tab, #menu_reload_tab, #separator_clo, #menu_close, #menu_close_other, #separator_mut, #separator_mutot, #menu_mute_other, #menu_unmute_other, #separator_tts, #menu_manager_window, #menu_treetabs_settings").forEach(function(s){ - s.style.display = ""; - }); - - if (TabNode.classList.contains("o")) { - document.querySelector("#separator_collt").style.display = ""; - document.querySelector("#menu_collapse_tree").style.display = ""; - } - if (TabNode.classList.contains("c")) { - document.querySelector("#separator_expat").style.display = ""; - document.querySelector("#menu_expand_tree").style.display = ""; - } - if (TabNode.classList.contains("c") || TabNode.classList.contains("o")) { - document.querySelector("#menu_close_tree").style.display = ""; - document.querySelector("#separator_bkt").style.display = ""; - // document.querySelector("#menu_bookmark_tree").style.display = ""; - document.querySelector("#separator_mutt").style.display = ""; - document.querySelector("#menu_mute_tree").style.display = ""; - document.querySelector("#menu_unmute_tree").style.display = ""; - } - } - ShowMenu(document.getElementById("main_menu"), event); +function Menu_ShowMenu(MenuItems, event, ) { + for (i = 0; i < DefaultMenu.all_entries.length; i++) { + if (MenuItems[i][1]) { + tt.menu[DefaultMenu.all_entries[i][1]].MenuShow(); + } else { + tt.menu[DefaultMenu.all_entries[i][1]].MenuHide(); + } + if (MenuItems[i][0]) { + tt.menu[DefaultMenu.all_entries[i][1]].SeparatorShow(); + } else { + tt.menu[DefaultMenu.all_entries[i][1]].SeparatorHide(); + } + } + setTimeout(function() { + tt.DOMmenu.style.display = "block"; + let x = event.pageX >= (document.body.clientWidth - tt.DOMmenu.getBoundingClientRect().width - 5) ? (document.body.clientWidth - tt.DOMmenu.getBoundingClientRect().width - 5) : (event.pageX - 5); + let y = event.pageY >= (document.body.clientHeight - tt.DOMmenu.getBoundingClientRect().height - 20) ? (document.body.clientHeight - tt.DOMmenu.getBoundingClientRect().height - 20) : (event.pageY - 20); + DOM_SetStyle(tt.DOMmenu, {top: y + "px", left: x + "px"}); + }, 10); } -function ShowFolderMenu(FolderNode, event) { - HideMenus(); - tt.menuItemNode = FolderNode; - - document.querySelectorAll("#menu_mute_tab, #menu_unmute_tab, #separator_unlo, #menu_unload, #menu_new_tab, #menu_new_folder, #separator_renf, #menu_rename_folder, #menu_delete_folder, #separator_bkt, #menu_bookmark_tree, #separator_expaa, #menu_expand_all, #menu_collapse_all, #menu_new_group, #separator_tts, #menu_manager_window, #menu_treetabs_settings").forEach(function(s){ - s.style.display = ""; - }); - - if (FolderNode.classList.contains("o")) { - document.querySelector("#folders_menu, #menu_collapse_tree").style.display = ""; - } - if (FolderNode.classList.contains("c")) { - document.querySelector("#folders_menu, #menu_expand_tree").style.display = ""; - } - - ShowMenu(document.getElementById("main_menu"), event); +function Menu_ShowTabMenu(TabNode, event) { + tt.menuItemNode = TabNode; + if (TabNode.classList.contains("pin")) { + Menu_ShowMenu(DefaultMenu.pin, event); + if (opt.allow_pin_close) tt.menu["menu_close"].MenuShow(); + } + if (TabNode.classList.contains("tab")) { + Menu_ShowMenu(DefaultMenu.tab, event); + if (TabNode.classList.contains("o")) { + tt.menu["menu_collapse_tree"].SeparatorShow(); + tt.menu["menu_collapse_tree"].MenuShow(); + } + if (TabNode.classList.contains("c")) { + tt.menu["menu_expand_tree"].SeparatorShow(); + tt.menu["menu_expand_tree"].MenuShow(); + } + if (TabNode.classList.contains("c") || TabNode.classList.contains("o")) { + tt.menu["menu_close_tree"].MenuShow(); + tt.menu["menu_mute_tree"].SeparatorShow(); + tt.menu["menu_mute_tree"].MenuShow(); + tt.menu["menu_unmute_tree"].MenuShow(); + tt.menu["menu_unload_tree"].MenuShow(); + } + } + if (TabNode.classList.contains("muted")) { + tt.menu["menu_unmute_tab"].MenuShow(); + } else { + tt.menu["menu_mute_tab"].MenuShow(); + } + if (!TabNode.classList.contains("discarded")) tt.menu["menu_unload"].MenuShow(); } -function ShowFGlobalMenu(event) { - tt.menuItemNode = event.target; - HideMenus(); - - - document.querySelectorAll("#menu_new_pin, #menu_new_tab, #menu_new_folder, #separator_undclo, #menu_undo_close_tab, #separator_expaa, #menu_expand_all, #menu_collapse_all, #separator_newg, #menu_new_group, #separator_gbk, #menu_bookmark_group, #separator_tts, #menu_manager_window, #menu_treetabs_settings").forEach(function(s){ - s.style.display = ""; - }); - ShowMenu(document.getElementById("main_menu"), event); +function Menu_ShowFolderMenu(FolderNode, event) { + tt.menuItemNode = FolderNode; + Menu_ShowMenu(DefaultMenu.folder, event); + if (FolderNode.classList.contains("o")) tt.menu["menu_collapse_tree"].MenuShow(); + if (FolderNode.classList.contains("c")) tt.menu["menu_expand_tree"].MenuShow(); + if (document.querySelectorAll("[id='" + FolderNode.id + "'] .tab").length == 0) { + tt.menu["menu_detach_tab"].SeparatorShow(); + tt.menu["menu_detach_tab"].MenuShow(); + } } -function ShowFGroupMenu(GroupNode, event) { - HideMenus(); - tt.menuItemNode = GroupNode; - - document.querySelectorAll("#menu_new_group, #menu_rename_group, #menu_delete_group, #separator_gtbcl, #menu_group_tabs_close, #menu_delete_group_tabs_close, #separator_gunlo, #menu_groups_unload, #separator_gbk, #separator_tts, #menu_bookmark_group, #separator_tts, #menu_groups_hibernate, #menu_manager_window, #menu_treetabs_settings").forEach(function(s){ - s.style.display = ""; - }); - if (tt.menuItemNode.id == "tab_list") { - document.querySelectorAll("#menu_groups_hibernate, #menu_rename_group, #menu_delete_group, #menu_delete_group_tabs_close").forEach(function(s){ - s.style.display = "none"; - }); - } - ShowMenu(document.getElementById("main_menu"), event); +function Menu_ShowFGlobalMenu(event) { + tt.menuItemNode = event.target; + Menu_ShowMenu(DefaultMenu.global, event); } -function SetMenu() { - document.querySelectorAll(".menu_item").forEach(function(m){ - if (m.id == "menu_new_pin") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("pin")) { - OpenNewTab(true, tt.menuItemNode.id); - } else { - OpenNewTab(true, undefined); - } - HideMenus(); - } - } - } - if (m.id == "menu_new_tab") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("folder")) { - OpenNewTab(false, tt.menuItemNode.id); - } else { - if (tt.menuItemNode.classList.contains("pin")) { - OpenNewTab(true, tt.menuItemNode.id); - } else { - if (tt.menuItemNode.classList.contains("tab")) { - OpenNewTab(false, tt.menuItemNode.id); - } else { - OpenNewTab(false, tt.active_group); - } - } - } - HideMenus(); - } - } - } +function Menu_ShowFGroupMenu(GroupNode, event) { + tt.menuItemNode = GroupNode; + Menu_ShowMenu(DefaultMenu.group, event); + if (tt.menuItemNode.id == "tab_list") { + tt.menu["menu_groups_hibernate"].MenuHide(); + tt.menu["menu_rename_group"].MenuHide(); + tt.menu["menu_delete_group"].MenuHide(); + tt.menu["menu_delete_group_tabs_close"].MenuHide(); + } +} - if (m.id == "menu_unpin_tab" || m.id == "menu_pin_tab") { - m.onmousedown = function(event) { - event.stopPropagation(); - if (event.which == 1) { - if (tt.menuItemNode.classList.contains("selected_tab")) { - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { pinned: (tt.menuItemNode.classList.contains("tab")) }); - }); - } else { - chrome.tabs.update(parseInt(tt.menuItemNode.id), { pinned: (tt.menuItemNode.classList.contains("tab")) }); - } - HideMenus(); - } - } - } - - if (m.id == "menu_duplicate_tab") { - m.onmousedown = function(event) { - event.stopPropagation(); - if (event.which == 1) { - if (tt.menuItemNode.classList.contains("selected_tab")) { - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - DuplicateTab(s); - }); - } else { - DuplicateTab(tt.menuItemNode); - } - HideMenus(); - } - } - } - - if (m.id == "menu_detach_tab") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - - if (tt.menuItemNode.classList.contains("selected_tab")) { - let tabsArr = []; - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - if (s.childNodes[1].childNodes.length > 0) { - document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){ - tabsArr.push(parseInt(t.id)); - }); - } - }); - Detach(tabsArr); - } else { - Detach([parseInt(tt.menuItemNode.id)]); - } - HideMenus(); - } - } - } - - if (m.id == "menu_reload_tab") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("selected_tab")) { - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - chrome.tabs.reload(parseInt(s.id)); - }); - } else { - chrome.tabs.reload(parseInt(tt.menuItemNode.id)); - } - HideMenus(); - } - } - } - - if (m.id == "menu_unload") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("pin") || tt.menuItemNode.classList.contains("tab")) { - if (tt.menuItemNode.classList.contains("selected_tab")) { - let tabsArr = []; - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - if (s.childNodes[1].childNodes.length > 0) { - document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){ - tabsArr.push(parseInt(t.id)); - }); - } - }); - DiscardTabs(tabsArr); - } else { - DiscardTabs([parseInt(tt.menuItemNode.id)]); - } - } - if (tt.menuItemNode.classList.contains("folder")) { - let tabsArr = []; - document.querySelectorAll("#"+tt.menuItemNode.id+" .tab").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - }); - DiscardTabs(tabsArr); - } - HideMenus(); - } - } - } - - if (m.id == "menu_close") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("selected_tab")) { - let tabsArr = []; - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - if (s.childNodes[1].childNodes.length > 0) { - document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){ - tabsArr.push(parseInt(t.id)); - }); - } - }); - CloseTabs(tabsArr); - } else { - CloseTabs([parseInt(tt.menuItemNode.id)]); - } - HideMenus(); - } - } - } - - if (m.id == "menu_mute_tab") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("pin") || tt.menuItemNode.classList.contains("tab")) { - if (tt.menuItemNode.classList.contains("selected_tab")) { - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { muted: true }); - }); - } else { - chrome.tabs.update(parseInt(tt.menuItemNode.id), { muted: true }); - } - } - if (tt.menuItemNode.classList.contains("folder")) { - document.querySelectorAll("#"+tt.menuItemNode.id+" .tab").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { muted: true }); - }); - } - HideMenus(); - } - } - } - - if (m.id == "menu_mute_tree") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - document.querySelectorAll("[id='"+tt.menuItemNode.id+"'], [id='"+tt.menuItemNode.id+"'] .tab").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { muted: true }); - }); - HideMenus(); - } - } - } - - if (m.id == "menu_unmute_tab") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("pin") || tt.menuItemNode.classList.contains("tab")) { - if (tt.menuItemNode.classList.contains("selected_tab")) { - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { muted: false }); - }); - } else { - chrome.tabs.update(parseInt(tt.menuItemNode.id), { muted: false }); - } - } - if (tt.menuItemNode.classList.contains("folder")) { - document.querySelectorAll("#"+tt.menuItemNode.id+" .tab").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { muted: false }); - }); - } - HideMenus(); - } - } - } - - if (m.id == "menu_unmute_tree") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - document.querySelectorAll("[id='"+tt.menuItemNode.id+"'], [id='"+tt.menuItemNode.id+"'] .tab").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { muted: false }); - }); - HideMenus(); - } - } - } - - - if (m.id == "menu_mute_other") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("selected_tab")) { - document.querySelectorAll(".pin:not(.selected_tab), #"+tt.active_group+" .tab:not(.selected_tab)").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { muted: true }); - }); - } else { - document.querySelectorAll(".pin:not([id='"+tt.menuItemNode.id+"']), #"+tt.active_group+" .tab:not([id='"+tt.menuItemNode.id+"'])").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { muted: true }); - }); - } - - HideMenus(); - } - } - } - - - if (m.id == "menu_unmute_other") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("selected_tab")) { - document.querySelectorAll(".pin:not(.selected_tab), #"+tt.active_group+" .tab:not(.selected_tab)").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { muted: false }); - }); - } else { - document.querySelectorAll(".pin:not([id='"+tt.menuItemNode.id+"']), #"+tt.active_group+" .tab:not([id='"+tt.menuItemNode.id+"'])").forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { muted: false }); - }); - } - HideMenus(); - } - } - } - - - - - if (m.id == "menu_undo_close_tab") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - chrome.sessions.getRecentlyClosed(null, function(sessions) { - if (sessions.length > 0) { - chrome.sessions.restore(null, function() {}); - } - }); - HideMenus(); - } - } - } - - - if (m.id == "menu_new_folder") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("folder")) { - let FolderId = AddNewFolder({ParentId: tt.menuItemNode.id, SetEvents: true}); - tt.menuItemNode.classList.remove("c"); - tt.menuItemNode.classList.add("o"); - ShowRenameFolderDialog(FolderId); - } else { - if (tt.menuItemNode.classList.contains("tab")) { - let folders = GetParentsByClass(tt.menuItemNode, "folder"); - if (folders.length > 0) { - let FolderId = AddNewFolder({ParentId: folders[0].id, SetEvents: true}); - ShowRenameFolderDialog(FolderId); - } else { - let FolderId = AddNewFolder({SetEvents: true}); - ShowRenameFolderDialog(FolderId); - } - } else { - let FolderId = AddNewFolder({SetEvents: true}); - ShowRenameFolderDialog(FolderId); - } - } - HideMenus(); - } - } - } - - - if (m.id == "menu_expand_tree") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - document.querySelectorAll("[id='"+tt.menuItemNode.id+"'], [id='"+tt.menuItemNode.id+"'] .folder.c, [id='"+tt.menuItemNode.id+"'] .tab.c").forEach(function(s){ - s.classList.add("o"); - s.classList.remove("c"); - }); - - tt.schedule_update_data++; - HideMenus(); - SaveFolders(); - } - } - } - - if (m.id == "menu_collapse_tree") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - document.querySelectorAll("[id='"+tt.menuItemNode.id+"'], [id='"+tt.menuItemNode.id+"'] .folder.c, [id='"+tt.menuItemNode.id+"'] .tab.c").forEach(function(s){ - s.classList.add("c"); - s.classList.remove("o"); - }); - tt.schedule_update_data++; - HideMenus(); - SaveFolders(); - } - } - } - - if (m.id == "menu_expand_all") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - document.querySelectorAll("#"+tt.active_group+" .folder.c, #"+tt.active_group+" .tab.c").forEach(function(s){ - s.classList.add("o"); - s.classList.remove("c"); - }); - tt.schedule_update_data++; - HideMenus(); - SaveFolders(); - } - } - } - - if (m.id == "menu_collapse_all") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - document.querySelectorAll("#"+tt.active_group+" .folder.o, #"+tt.active_group+" .tab.o").forEach(function(s){ - s.classList.add("c"); - s.classList.remove("o"); - }); - tt.schedule_update_data++; - HideMenus(); - SaveFolders(); - } - } - } - - - - if (m.id == "menu_close_tree") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - - let tabsArr = []; - document.querySelectorAll("[id='"+tt.menuItemNode.id+"'] .tab, [id='"+tt.menuItemNode.id+"']").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - if (s.childNodes[1].childNodes.length > 0) { - document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){ - tabsArr.push(parseInt(t.id)); - }); - } - }); - CloseTabs(tabsArr); - HideMenus(); - } - } - } - - if (m.id == "menu_rename_folder") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - ShowRenameFolderDialog(tt.menuItemNode.id); - HideMenus(); - } - } - } - - - if (m.id == "menu_delete_folder") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - if (tt.menuItemNode.classList.contains("selected_folder")) { - document.querySelectorAll("#"+tt.menuItemNode.id+" .selected_folder, #"+tt.menuItemNode.id).forEach(function(s){ - RemoveFolder(s.id); - }); - } else { - RemoveFolder(tt.menuItemNode.id); - } - HideMenus(); - } - } - } - - if (m.id == "menu_close_other") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - let tabsArr = []; - if (tt.menuItemNode.classList.contains("selected_tab")) { - document.querySelectorAll(".pin:not(.selected_tab), #"+tt.active_group+" .tab:not(.selected_tab)").forEach(function(s){ - let children = document.querySelectorAll("[id='"+s.id+"'] .selected_tab"); - if (children.length == 0 || opt.promote_children) { - tabsArr.push(parseInt(s.id)); - } - }); - CloseTabs(tabsArr); - } else { - if (tt.menuItemNode.classList.contains("tab")) { - document.getElementById(tt.active_group).appendChild(tt.menuItemNode); - } - document.querySelectorAll(".pin:not([id='"+tt.menuItemNode.id+"']), #"+tt.active_group+" .tab:not([id='"+tt.menuItemNode.id+"'])").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - }); - - CloseTabs(tabsArr); - } - HideMenus(); - } - } - } - - if (m.id == "menu_bookmark_tree") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - Bookmark(tt.menuItemNode); - HideMenus(); - } - } - } - - - if (m.id == "menu_rename_group") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - ShowGroupEditWindow(tt.menuItemNode.id); - HideMenus(); - } - } - } - - if (m.id == "menu_delete_group") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - GroupRemove(tt.menuItemNode.id, false); - HideMenus(); - } - } - } - - - if (m.id == "menu_delete_group_tabs_close") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - GroupRemove(tt.menuItemNode.id, true); - HideMenus(); - } - } - } - - - if (m.id == "menu_groups_unload") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - let tabsArr = []; - document.querySelectorAll("[id='"+tt.menuItemNode.id+"'] .tab").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - }); - DiscardTabs(tabsArr); - HideMenus(); - } - } - } - - if (m.id == "menu_group_tabs_close") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - let tabsArr = []; - document.querySelectorAll("[id='"+tt.menuItemNode.id+"'] .tab").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - }); - CloseTabs(tabsArr); - HideMenus(); - } - } - } - - if (m.id == "menu_manager_window") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - OpenManagerWindow(); - HideMenus(); - } - } - } - - if (m.id == "menu_groups_hibernate") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - ExportGroup(tt.menuItemNode.id, false, true); - HideMenus(); - setTimeout(function() { - GroupRemove(tt.menuItemNode.id, true); - }, 100); - } - } - } - - - if (m.id == "menu_bookmark_group") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - Bookmark(tt.menuItemNode); - HideMenus(); - } - } - } - - if (m.id == "menu_new_group") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - AddNewGroup(); - HideMenus(); - } - } - } - - - if (m.id == "menu_treetabs_settings") { - m.onmousedown = function(event) { - if (event.which == 1) { - event.stopPropagation(); - chrome.tabs.create({ "url": "options.html" }); - HideMenus(); - } - } - } - - }); - +function Menu_CreateMenu() { + tt.DOMmenu = document.getElementById("main_menu"); + tt.DOMmenu.onmousedown = function(event) { + event.preventDefault(); + event.stopPropagation(); + event.stopImmediatePropagation(); + } + tt.DOMmenu.onclick = function(event) { + Menu_HideMenus(); + } + for (let MenuItem of DefaultMenu.all_entries) { + tt.menu[MenuItem[1]] = new Menu_ttMenu(MenuItem); + } } \ No newline at end of file diff --git a/scripts/preferences.js b/scripts/preferences.js new file mode 100644 index 0000000..781cd78 --- /dev/null +++ b/scripts/preferences.js @@ -0,0 +1,26 @@ +function Preferences_SavePreferences(options) { + chrome.storage.local.set({preferences: options}); + chrome.runtime.sendMessage({command: "reload_options", opt: options}); +} + +function Preferences_LoadDefaultPreferences() { + opt = Object.assign({}, DefaultPreferences); +} + +function Preferences_GetCurrentPreferences(storage) { + opt = Object.assign({}, DefaultPreferences); + if (storage.preferences) { + for (let parameter in storage["preferences"]) { + if (opt[parameter] != undefined) { + opt[parameter] = storage["preferences"][parameter]; + + // legacy, changed from "after_active" to "after", because it is a parent tab, not necessarily an active tab + if (parameter == "append_child_tab" && storage["preferences"][parameter] == "after_active") { + opt[parameter] = "after"; + } + } + } + } else { + Preferences_SavePreferences(opt); + } +} \ No newline at end of file diff --git a/scripts/refresh.js b/scripts/refresh.js deleted file mode 100644 index 085f861..0000000 --- a/scripts/refresh.js +++ /dev/null @@ -1,327 +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/ - -// ********** REFRESH GUI *************** - -async function RefreshGUI() { - let toolbar = document.getElementById("toolbar"); - let toolbarHeight = 27; - if (toolbar.children.length > 0) { - toolbar.style.height = ""; - toolbar.style.width = ""; - toolbar.style.display = ""; - toolbar.style.border = ""; - toolbar.style.padding = ""; - if (document.querySelector(".on.button") != null) { - toolbar.style.height = "53px"; - toolbarHeight = 54; - } else { - toolbar.style.height = "26px"; - } - } else { - toolbar.style.height = "0px"; - toolbarHeight = 0; - toolbar.style.width = "0px"; - toolbar.style.display = "none"; - toolbar.style.border = "none"; - toolbar.style.padding = "0"; - } - - let group_list = document.getElementById("group_list"); - group_list.style.width = document.body.clientWidth + 50 + "px"; - - let pin_list = document.getElementById("pin_list"); - if (pin_list.children.length > 0) { - pin_list.style.top = toolbarHeight + "px"; - pin_list.style.height = ""; - pin_list.style.width = ""; - pin_list.style.display = ""; - pin_list.style.border = ""; - pin_list.style.padding = ""; - } else { - pin_list.style.top = "0px"; - pin_list.style.height = "0px"; - pin_list.style.width = "0px"; - pin_list.style.display = "none"; - pin_list.style.border = "none"; - pin_list.style.padding = "0"; - } - let pin_listHeight = pin_list.getBoundingClientRect().height; - - let toolbar_groups = document.getElementById("toolbar_groups"); - toolbar_groups.style.top = toolbarHeight + pin_listHeight + "px"; - toolbar_groups.style.height = document.body.clientHeight - toolbarHeight - pin_listHeight + "px"; - let toolbar_groupsWidth = toolbar_groups.getBoundingClientRect().width; - - if (opt.show_counter_groups) { - document.querySelectorAll(".group").forEach(function(s){ - let groupLabel = document.getElementById("_gte"+s.id); - if (groupLabel) { - groupLabel.textContent = (tt.groups[s.id] ? tt.groups[s.id].name : labels.noname_group) + " (" + document.querySelectorAll("#"+s.id+" .tab").length + ")"; - } - }); - } else { - document.querySelectorAll(".group").forEach(function(s){ - let groupLabel = document.getElementById("_gte"+s.id); - if (groupLabel) { - groupLabel.textContent = tt.groups[s.id] ? tt.groups[s.id].name : labels.noname_group; - } - }); - } - document.querySelectorAll(".group_button").forEach(function(s){ - s.style.height = s.firstChild.getBoundingClientRect().height + "px"; - }); - let groups = document.getElementById("groups"); - let groupsHeight = document.body.clientHeight - toolbarHeight - pin_listHeight; - let groupsWidth = document.body.clientWidth - toolbar_groupsWidth - 1; - - groups.style.top = toolbarHeight + pin_listHeight + "px"; - groups.style.left = toolbar_groupsWidth + "px"; - groups.style.height = groupsHeight + "px"; - groups.style.width = groupsWidth + "px"; - - // let bottom_floating_buttons = document.getElementById("status_bar"); - // let active_group_tabs = document.getElementById("ct"+tt.active_group); - // bottom_floating_buttons.style.left = toolbar_groupsWidth + "px"; - // bottom_floating_buttons.style.width = toolbar_groupsWidth + active_group_tabs.clientWidth + "px"; - - - let PanelList = document.querySelector(".mw_pan_on>.manager_window_list"); - let PanelListHeight = 3 + PanelList.children.length * 18; - - let ManagerWindowPanelButtons = document.querySelector(".mw_pan_on>.manager_window_panel_buttons"); - let ManagerWindowPanelButtonsHeight = ManagerWindowPanelButtons.clientHeight; - - let MaxAllowedHeight = document.body.clientHeight - 140; - - - if (PanelListHeight + ManagerWindowPanelButtonsHeight < MaxAllowedHeight) { - PanelList.style.height = PanelListHeight + "px"; - } else { - PanelList.style.height = MaxAllowedHeight - ManagerWindowPanelButtonsHeight + "px"; - } - - - let ManagerWindow = document.getElementById("manager_window"); - ManagerWindow.style.height = PanelList.clientHeight + ManagerWindowPanelButtonsHeight + 56 + "px"; -} - -// set discarded class -function RefreshDiscarded(tabId) { - let t = document.getElementById(tabId); - if (t != null) { - chrome.tabs.get(parseInt(tabId), function(tab) { - if (tab) { - if (tab.discarded) { - t.classList.add("discarded"); - } else { - t.classList.remove("discarded"); - t.classList.remove("audible"); - t.classList.remove("muted"); - } - } - }); - } -} - -// set discarded class -function SetAttentionIcon(tabId) { - let t = document.getElementById(tabId); - if (t != null) { - t.classList.add("attention"); - } -} - -// change media icon -function RefreshMediaIcon(tabId) { - let t = document.getElementById(tabId); - if (t != null) { - chrome.tabs.get(parseInt(tabId), function(tab) { - if (tab) { - if (tab.mutedInfo.muted && !tab.discarded) { - t.classList.remove("audible"); - t.classList.add("muted"); - } - if (!tab.mutedInfo.muted && tab.audible && !tab.discarded) { - t.classList.remove("muted"); - t.classList.add("audible"); - } - if ((!tab.mutedInfo.muted && !tab.audible) || tab.discarded) { - t.classList.remove("audible"); - t.classList.remove("muted"); - } - } - }); - } -} - - -// Vivaldi does not have changeInfo.audible listener, this is my own implementation, hopefully this will not affect performance too much -function VivaldiRefreshMediaIcons() { - setInterval(function() { - chrome.tabs.query({currentWindow: true, audible: true}, function(tabs) { - document.querySelectorAll(".audible, .muted").forEach(function(s){ - s.classList.remove("audible"); - s.classList.remove("muted"); - }); - let tc = tabs.length; - for (var ti = 0; ti < tc; ti++) { - if (tabs[ti].audible) { - document.getElementById(tabs[ti].id).classList.add("audible"); - } - if (tabs[ti].mutedInfo.muted) { - document.getElementById(tabs[ti].id).classList.add("muted"); - } - } - }); - }, 2000); -} - -async function LoadFavicon(tabId, Img, TryUrls, TabHeaderNode, i) { - if (TabHeaderNode){ - Img.src = TryUrls[i]; - Img.onload = function() { - TabHeaderNode.style.backgroundImage = "url(" + TryUrls[i] + ")"; - if (browserId == "F") { // cache Firefox favicon - solution for bug with empty favicons in unloaded tabs - browser.sessions.setTabValue(tabId, "CachedFaviconUrl", TryUrls[i]); - } - }; - Img.onerror = function() { - if (i < TryUrls.length) { - LoadFavicon(tabId, Img, TryUrls, TabHeaderNode, (i+1)); - } - } - } -} - -async function GetFaviconAndTitle(tabId, addCounter) { - let t = document.getElementById(tabId); - if (t != null) { - - let CachedFavicon; - if (browserId == "F") { - let ttf = Promise.resolve(browser.sessions.getTabValue(tabId, "CachedFaviconUrl")).then(function(FaviconUrl) { - CachedFavicon = FaviconUrl; - }); - } - - chrome.tabs.get(parseInt(tabId), function(tab) { - if (tab){ - let title = tab.title ? tab.title : tab.url; - let tHeader = t.childNodes[0]; - let tTitle = t.childNodes[0].childNodes[2]; - if (tab.status == "complete" || tab.discarded) { - t.classList.remove("loading"); - - tTitle.textContent = title; - tHeader.title = title; - if (opt.show_counter_tabs_hints) { - tHeader.setAttribute("tabTitle", title); - } - - let Img = new Image(); - - if (browserId != "F") { - CachedFavicon = "chrome://favicon/"+tab.url; - } - let TryCases = [tab.favIconUrl, CachedFavicon, , "./theme/icon_empty.svg"]; - LoadFavicon(tabId, Img, TryCases, tHeader, 0); - - } - if (tab.status == "loading" && tab.discarded == false) { - title = tab.title ? tab.title : labels.loading; - t.classList.add("loading"); - tHeader.style.backgroundImage = ""; - tHeader.title = labels.loading; - if (opt.show_counter_tabs_hints) { - tHeader.setAttribute("tabTitle", labels.loading); - } - tTitle.textContent = labels.loading; - setTimeout(function() { - if (document.getElementById(tab.id) != null) GetFaviconAndTitle(tab.id, addCounter); - }, 1000); - } - if (addCounter && (opt.show_counter_tabs || opt.show_counter_tabs_hints)) { - RefreshTabCounter(tabId); - } - } - }); - } -} - -// refresh open closed trees states -async function RefreshExpandStates() { - document.querySelectorAll("#"+tt.active_group+" .folder").forEach(function(s){ - if (s.childNodes[1].children.length == 0 && s.childNodes[2].children.length == 0) { - s.classList.remove("o"); - s.classList.remove("c"); - } else { - if (s.classList.contains("o") == false && s.classList.contains("c") == false) { - s.classList.add("o"); - } - } - }); - document.querySelectorAll("#"+tt.active_group+" .tab").forEach(function(s){ - if (s.childNodes[1].children.length == 0) { - s.classList.remove("o"); - s.classList.remove("c"); - } else { - if (s.classList.contains("o") == false && s.classList.contains("c") == false) { - s.classList.add("o"); - } - } - }); -} - -async function RefreshCounters() { - if (opt.show_counter_tabs || opt.show_counter_tabs_hints) { - // if (opt.show_counter_tabs_hints) { - // document.querySelectorAll("#"+tt.active_group+" .tab").forEach(function(s){ - // let title = s.childNodes[0].getAttribute("tabTitle"); - // if (title != null) { - // s.childNodes[0].title = title; - // s.childNodes[0].childNodes[1].textContent = title; - // } - // }); - // } - - document.querySelectorAll("#"+tt.active_group+" .o.tab, #"+tt.active_group+" .c.tab").forEach(function(s){ - if (opt.show_counter_tabs) { - s.childNodes[0].childNodes[1].childNodes[0].textContent = document.querySelectorAll("[id='" + s.id + "'] .tab").length; - } - if (opt.show_counter_tabs_hints) { - let title = s.childNodes[0].getAttribute("tabTitle"); - s.childNodes[0].title = (document.querySelectorAll("[id='" + s.id + "'] .tab").length +" • ") + title; - } - }); - // · - document.querySelectorAll("#"+tt.active_group+" .folder").forEach(function(s){ - if (opt.show_counter_tabs && tt.folders[s.id]) { - s.childNodes[0].childNodes[1].childNodes[0].textContent = document.querySelectorAll("[id='" + s.id + "'] .tab").length; - } - if (opt.show_counter_tabs_hints && tt.folders[s.id]) { - s.childNodes[0].title = (document.querySelectorAll("[id='" + s.id + "'] .tab").length +" • ") + tt.folders[s.id].name; - } - }); - } -} - -async function RefreshTabCounter(tabId) { - let t = document.getElementById(tabId); - if (t != null && t.childNodes[0]) { - let title = t.childNodes[0].getAttribute("tabTitle"); - if (t != null && title != null) { - if (t.classList.contains("o") || t.classList.contains("c")) { - if (opt.show_counter_tabs) { - t.childNodes[0].childNodes[1].childNodes[0].textContent = document.querySelectorAll("[id='" + t.id + "'] .tab").length; - } - if (opt.show_counter_tabs_hints) { - t.childNodes[0].title = (document.querySelectorAll("[id='" + t.id + "'] .tab").length +" • ") + title; - } - } else { - t.childNodes[0].title = title; - } - } - } -} diff --git a/scripts/tabs.js b/scripts/tabs.js index 981f4d4..c574b5d 100644 --- a/scripts/tabs.js +++ b/scripts/tabs.js @@ -1,1087 +1,974 @@ -// 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/ - -// ********** TABS FUNCTIONS *************** - - -async function UpdateData() { - if (opt.debug) { - log("f: UpdateData"); - } - - setInterval(function() { - if (tt.schedule_update_data > 1) { - tt.schedule_update_data = 1; - } - if (tt.schedule_update_data > 0) { - let PinInd = 0; - let pins_data = []; - document.querySelectorAll(".pin").forEach(function(pin){ - pins_data.push({id: pin.id, index: PinInd}); - PinInd++; - }); - - let tabs_data = []; - document.querySelectorAll(".tab").forEach(function(tab){ - tabs_data.push({id: tab.id, parent: tab.parentNode.parentNode.id, index: Array.from(tab.parentNode.children).indexOf(tab), expand: (tab.classList.contains("c") ? "c" : (tab.classList.contains("o") ? "o" : ""))}); - }); - chrome.runtime.sendMessage({command: "update_all_tabs", pins: pins_data, tabs: tabs_data}); - tt.schedule_update_data--; - } - }, 1000); +class Tabs_ttTab { + constructor(p) { + this.id = p.tab.id; + this.pinned = p.tab.pinned; + if (document.getElementById(p.tab.id) != null && tt.tabs[p.tab.id]) { + tt.tabs[p.tab.id].GetFaviconAndTitle(p.addCounter); + return; + } + let ClassList = p.tab.pinned ? "pin" : "tab"; + if (p.tab.discarded) ClassList += " discarded"; + if (p.tab.attention) ClassList += " attention"; + if (p.AdditionalClass) ClassList += " " + p.AdditionalClass; + if (p.ExpandState) ClassList += " " + p.ExpandState; + let DIV_Tab = DOM_New("div", undefined, {id: p.tab.id, className: ClassList}); + let DIV_header = DOM_New("div", DIV_Tab, {id: ("tab_header_" + p.tab.id), className: (opt.always_show_close && !opt.never_show_close) ? "tab_header close_show" : "tab_header", draggable: (!p.SkipSetEvents ? true : false)}); + let DIV_expand = DOM_New("div", DIV_header, {id: ("exp_" + p.tab.id), className: "expand"}); + let DIV_counter = DOM_New("div", DIV_header, {id: ("tab_counter_" + p.tab.id), className: "tab_counter"}); + DOM_New("div", DIV_counter, {id: ("counter_number_" + p.tab.id), className: "counter_number"}); + let DIV_title = DOM_New("div", DIV_header, {id: ("tab_title_" + p.tab.id), className: "tab_title"}); + let DIV_close_button = DOM_New("div", DIV_header, {id: ("close_" + p.tab.id), className: (opt.never_show_close ? "close hidden" : "close")}); + DOM_New("div", DIV_close_button, {id: ("close_img_" + p.tab.id), className: (opt.never_show_close ? "close_img hidden" : "close_img")}); + let DIV_audio_indicator = DOM_New("div", DIV_header, {id: ("tab_mediaicon_" + p.tab.id), className: "tab_mediaicon"}); + let DIV_children = DOM_New("div", DIV_Tab, {id: ("°" + p.tab.id), className: "children"}); + DOM_New("div", DIV_Tab, {id: ("drag_indicator_" + p.tab.id), className: "drag_indicator"}); + if (!p.SkipSetEvents) { + DIV_children.onclick = function(event) { + if (event.target == this && event.which == 1) DOM_Deselect(); + } + DIV_children.onmousedown = function(event) { + if (event.target == this) { + if (event.which == 2 && event.target == this) { + event.stopImmediatePropagation(); + Groups_ActionClickGroup(this.parentNode, opt.midclick_group); + } + if (event.which == 3) Menu_ShowFGlobalMenu(event); + } + } + DIV_children.ondblclick = function(event) { + if (event.target == this) Groups_ActionClickGroup(this.parentNode, opt.dbclick_group); + } + DIV_expand.onmousedown = function(event) { + if (tt.DOMmenu.style.top != "-1000px") Menu_HideMenus(); + if (event.which == 1 && !event.shiftKey && !event.ctrlKey) DOM_EventExpandBox(this.parentNode.parentNode); + } + DIV_expand.onmouseenter = function(event) { + this.classList.add("hover"); + } + DIV_expand.onmouseleave = function(event) { + this.classList.remove("hover"); + } + if (!opt.never_show_close) { + DIV_close_button.onmousedown = function(event) { + event.stopImmediatePropagation(); + if (event.which != 3) Tabs_CloseTabs([parseInt(this.parentNode.parentNode.id)]); + } + DIV_close_button.onmouseenter = function(event) { + this.classList.add("close_hover"); + } + DIV_close_button.onmouseleave = function(event) { + this.classList.remove("close_hover"); + } + } + DIV_header.ondblclick = function(event) { + if (event.target.classList && event.target.classList.contains("tab_header")) Tabs_ActionClickTab(this.parentNode, opt.dbclick_tab); + } + DIV_header.onmousedown = function(event) { + if (browserId == "V") { + chrome.windows.getCurrent({populate: false}, function(window) { + if (tt.CurrentWindowId != window.id && window.focused) location.reload(); + }); + } + event.stopImmediatePropagation(); + if (event.which == 1) { + if (tt.DOMmenu.style.top != "-1000px") { + Menu_HideMenus(); + } else { + + if (event.shiftKey || event.ctrlKey) { + DOM_Select(event, this.parentNode); + } + + // let tabId = parseInt(this.parentNode.id); + // setTimeout(function() { + // if (tt.Dragging == false && !event.shiftKey && !event.ctrlKey && event.target.classList.contains("tab_header") && event.target.parentNode.classList.contains("selected") == false) { + // chrome.tabs.update(tabId, {active: true}); + // } + // }, 90); + } + } + if (event.which == 2) { + event.preventDefault(); + Tabs_ActionClickTab(this.parentNode, opt.midclick_tab); + } + if (event.which == 3) Menu_ShowTabMenu(this.parentNode, event); + } + + DIV_header.onclick = function(event) { + if (!event.shiftKey && !event.ctrlKey) { + DOM_Deselect(); + + // let tabId = parseInt(this.parentNode.id); + + if (event.target.classList.contains("tab_header")) { + chrome.tabs.update(parseInt(this.parentNode.id), {active: true}); + // , function(tab) { + // if (was_selected) tt.tab[tab.id].Node.classList.add("selected"); + // }); + } + } + } + + + + // DIV_header.onmouseup = function(event) { + // event.stopImmediatePropagation(); + // if (tt.DOMmenu.style.top != "-1000px") { + // Menu_HideMenus(); + // } else { + // if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target.classList.contains("tab_header")) { + // DOM_Deselect(); + // chrome.tabs.update(parseInt(this.parentNode.id), {active: true}); + // } + // } + // } + DIV_header.onmouseover = function(event) { + this.classList.add("tab_header_hover"); + if (opt.never_show_close == false && opt.always_show_close == false) this.classList.add("close_show"); + } + DIV_header.onmouseleave = function(event) { + this.classList.remove("tab_header_hover"); + if (opt.never_show_close == false && opt.always_show_close == false) this.classList.remove("close_show"); + } + DIV_header.ondragstart = function(event) { // DRAG START + tt.Dragging = true; + tt.DraggingGroup = false; + event.stopPropagation(); + event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0); + event.dataTransfer.setData("text", ""); + event.dataTransfer.setData("SourceWindowId", tt.CurrentWindowId); + DOM_CleanUpDragAndDrop(); + let Nodes = []; + if (this.parentNode.classList.contains("selected")) { + DOM_FreezeSelection(false); + } else { + DOM_FreezeSelection(true); + DOM_SetClasses(this.parentNode, ["selected_temporarly", "selected"], [], []); + } + DOM_RemoveHeadersHoverClass(); + let selected = document.querySelectorAll(".selected, .selected .tab, .selected .folder"); + for (let s of selected) { + s.classList.add("dragged_tree"); + if (s.classList.contains("pin")) { + tt.DraggingPin = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "pin"}); + } + if (s.classList.contains("tab")) { + tt.DraggingTab = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "tab"}); + } + if (s.classList.contains("folder")) { + tt.DraggingFolder = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "folder", index: (tt.folders[s.id] ? tt.folders[s.id].index : 0), name: (tt.folders[s.id] ? tt.folders[s.id].name : labels.noname_group), expand: (tt.folders[s.id] ? tt.folders[s.id].expand : "")}); + } + } + if (opt.max_tree_drag_drop && opt.max_tree_depth >= 0) { + let dragged_tree = document.querySelectorAll(".dragged_tree .tab, .dragged_tree .folder"); + for (let s of dragged_tree) { + let parents = DOM_GetParentsByClass(s.parentNode, "dragged_tree"); + if (parents.length > tt.DragTreeDepth) tt.DragTreeDepth = parents.length; + } + } else { + tt.DragTreeDepth = -1; + } + let Parents = DOM_GetAllParents(this.parentNode); + for (let s of Parents) { + if (s.classList && (s.classList.contains("tab") || s.classList.contains("folder"))) s.classList.add("dragged_parents"); + } + event.dataTransfer.setData("Nodes", JSON.stringify(Nodes)); + event.dataTransfer.setData("NodesTypes", JSON.stringify({DraggingGroup: tt.DraggingGroup, DraggingPin: tt.DraggingPin, DraggingTab: tt.DraggingTab, DraggingFolder: tt.DraggingFolder})); + chrome.runtime.sendMessage({command: "drag_start", DragTreeDepth: tt.DragTreeDepth, DraggingGroup: tt.DraggingGroup, DraggingPin: tt.DraggingPin, DraggingTab: tt.DraggingTab, DraggingFolder: tt.DraggingFolder}); + } + DIV_header.ondragenter = function(event) { + this.classList.remove("tab_header_hover"); + } + DIV_header.ondragleave = function(event) { + DOM_RemoveHighlight(); + } + DIV_header.ondragover = function(event) { + if (tt.DraggingGroup == false && (tt.DraggingPin || tt.DraggingTab || tt.DraggingFolder) && this.parentNode.classList.contains("dragged_tree") == false) { + if (this.parentNode.classList.contains("pin")) { + if (this.parentNode.classList.contains("before") == false && event.layerX < this.clientWidth / 2) { + DOM_RemoveHighlight(); + DOM_SetClasses(this.parentNode, ["before", "highlighted_drop_target"], ["after"], []); + } + if (this.parentNode.classList.contains("after") == false && event.layerX >= this.clientWidth / 2) { + DOM_RemoveHighlight(); + DOM_SetClasses(this.parentNode, ["after", "highlighted_drop_target"], ["before"], []); + } + } + if (this.parentNode.classList.contains("tab")) { + let TabDepth = Tabs_GetTabDepthInTree(this); + let PDepth = TabDepth + tt.DragTreeDepth; + let PIsGroup = this.parentNode.parentNode.parentNode.classList.contains("group"); + // let PIsTab = this.parentNode.parentNode.parentNode.classList.contains("tab"); + let PIsFolder = this.parentNode.parentNode.parentNode.classList.contains("folder"); + let PIsDraggedParents = this.parentNode.classList.contains("dragged_parents"); + if ((PIsFolder == tt.DraggingFolder || tt.DraggingFolder == false || PIsGroup == true) && this.parentNode.classList.contains("before") == false && event.layerY < this.clientHeight / 3 && (PDepth <= opt.max_tree_depth + 1 || opt.max_tree_depth < 0 || opt.max_tree_drag_drop == false || PIsDraggedParents == true)) { + DOM_RemoveHighlight(); + DOM_SetClasses(this.parentNode, ["before", "highlighted_drop_target"], ["inside", "after"], []); + } + if (tt.DraggingFolder == false && this.parentNode.classList.contains("inside") == false && event.layerY > this.clientHeight / 3 && event.layerY <= 2 * (this.clientHeight / 3) && (PDepth <= opt.max_tree_depth || opt.max_tree_depth < 0 || opt.max_tree_drag_drop == false || PIsDraggedParents == true)) { + DOM_RemoveHighlight(); + DOM_SetClasses(this.parentNode, ["inside", "highlighted_drop_target"], ["before", "after"], []); + } + if ((PIsFolder == tt.DraggingFolder || tt.DraggingFolder == false || PIsGroup == true) && this.parentNode.classList.contains("after") == false && this.parentNode.classList.contains("o") == false && event.layerY > 2 * (this.clientHeight / 3) && (PDepth <= opt.max_tree_depth + 1 || opt.max_tree_depth < 0 || opt.max_tree_drag_drop == false || PIsDraggedParents == true)) { + DOM_RemoveHighlight(); + DOM_SetClasses(this.parentNode, ["after", "highlighted_drop_target"], ["before", "inside"], []); + } + } + } + if (opt.open_tree_on_hover && tt.DragOverId != this.id) { + if (this.parentNode.classList.contains("c") && this.parentNode.classList.contains("dragged_tree") == false) { + clearTimeout(tt.DragOverTimer); + tt.DragOverId = this.id; + let This = this; + tt.DragOverTimer = setTimeout(function() { + if (tt.DragOverId == This.id) DOM_SetClasses(This.parentNode, ["o"], ["c"], []); + }, 1500); + } + } + } + DIV_header.ondragend = function(event) { + if (opt.open_tree_on_hover) { + clearTimeout(tt.DragOverTimer); + tt.DragOverId = ""; + } + setTimeout(function() {DOM_CleanUpDragAndDrop();}, 300); + setTimeout(function() {chrome.runtime.sendMessage({command: "drag_end"});}, 500); + } + DIV_audio_indicator.onmousedown = function(event) { + event.stopImmediatePropagation(); + if (event.which == 1 && (this.parentNode.parentNode.classList.contains("audible") || this.parentNode.parentNode.classList.contains("muted"))) { + chrome.tabs.get(parseInt(this.parentNode.parentNode.id), function(tab) { + if (tab) chrome.tabs.update(tab.id, {muted: !tab.mutedInfo.muted}); + }); + } + } + } + let parent; + if (p.tab.pinned == true) { + parent = document.getElementById("pin_list"); + } else { + if (p.ParentId == false || p.ParentId == undefined || p.ParentId == "pin_list") { + parent = document.getElementById("°" + tt.active_group); + } else { + parent = document.getElementById(p.ParentId); + if (parent == null || parent.classList.contains("pin") || parent.parentNode.classList.contains("pin")) { + parent = document.getElementById("°" + tt.active_group); + } else { + parent = document.getElementById("°" + p.ParentId); + if (parent.children.length == 0) DOM_SetClasses(parent.parentNode, ["o"], ["c"], []); + } + } + } + if (p.Append == true && parent) parent.appendChild(DIV_Tab); + if ((p.Append == false || p.Append == undefined) && parent) {parent.prepend(DIV_Tab);} + if (p.InsertAfterId) { + let After = document.getElementById(p.InsertAfterId); + if (After != null) { + if ((p.tab.pinned && After.classList.contains("pin")) || (p.tab.pinned == false && (After.classList.contains("tab") || After.classList.contains("folder")))) { + DOM_InsterAfterNode(DIV_Tab, After); + } else { + parent.appendChild(DIV_Tab); + } + } else { + parent.appendChild(DIV_Tab); + } + } + this.Node = DIV_Tab; + this.title = DIV_title; + if (!p.SkipFavicon) this.GetFaviconAndTitle(p.addCounter); + if (!p.SkipMediaIcon) this.RefreshMediaIcon(p.tab.id); + if (p.RefreshDiscarded) this.RefreshDiscarded(); + if (p.tab.active && !p.SkipSetActive) Tabs_SetActiveTab(p.tab.id); + if (p.Scroll) this.ScrollToTab(); + } + RemoveTab() { + if (opt.debug) Utils_log("f: RemoveTab, tabId: " + this.id); + if (this.Node != null) { + this.Node.parentNode.removeChild(this.Node); + if (tt.tabs[this.id]) delete tt.tabs[this.id]; + } + } + ScrollToTab() { + let Tab = this.Node; + let P = document.getElementById("pin_list"); + let G = document.getElementById(tt.active_group); + if (Tab != null) { + if (Tab.classList.contains("pin")) { + if (Tab.getBoundingClientRect().left - P.getBoundingClientRect().left < 0) { + P.scrollLeft = P.scrollLeft + Tab.getBoundingClientRect().left - P.getBoundingClientRect().left - 2; + } else { + if (Tab.getBoundingClientRect().left - P.getBoundingClientRect().left > G.getBoundingClientRect().width - document.querySelector(".tab_header").getBoundingClientRect().width) { + P.scrollLeft = P.scrollLeft + Tab.getBoundingClientRect().left - P.getBoundingClientRect().left - P.getBoundingClientRect().width + document.querySelector(".tab_header").getBoundingClientRect().width + 2; + } + } + } else if (Tab.classList.contains("tab") && document.querySelector("#" + tt.active_group + " [id='" + this.id + "']") != null) { + let Parents = DOM_GetParentsByClass(Tab, "c"); + if (Parents.length > 0) { + for (let s of Parents) { + DOM_SetClasses(s, ["o"], ["c"], []); + } + } + if (Tab.getBoundingClientRect().top - G.getBoundingClientRect().top < 0) { + G.scrollTop = G.scrollTop + Tab.getBoundingClientRect().top - G.getBoundingClientRect().top - 2; + } else { + if (Tab.getBoundingClientRect().top - G.getBoundingClientRect().top > G.getBoundingClientRect().height - document.querySelector(".tab_header").getBoundingClientRect().height) { + G.scrollTop = G.scrollTop + Tab.getBoundingClientRect().top - G.getBoundingClientRect().top - G.getBoundingClientRect().height + document.querySelector(".tab_header").getBoundingClientRect().height + 10; + } + } + } + } + } + SetTabClass(pin) { + let GroupList = document.getElementById("°" + tt.active_group); + let Tab = this.Node; + if (Tab != null) { + if (pin) { + if (Tab.parentNode.id != "pin_list") document.getElementById("pin_list").appendChild(Tab); + DOM_SetClasses(Tab, ["pin"], ["tab", "o", "c"], []); + if (Tab.childNodes[1].childNodes.length > 0) { // flatten out children + let tabs = document.querySelectorAll("#°" + Tab.id + " .pin, #°" + Tab.id + " .tab"); + for (let tab of tabs) { + DOM_SetClasses(tab, ["pin"], ["tab", "o", "c"], []); + DOM_InsterAfterNode(tab, Tab); + chrome.tabs.update(parseInt(tab.id), {pinned: true}); + } + let folders = document.querySelectorAll("#°" + Tab.id + " .folder"); + for (let i = folders.length - 1; i >= 0; i--) { + GroupList.prepend(folders[i]); + } + } + chrome.tabs.update(parseInt(Tab.id), {pinned: true}); + } else { + if (Tab.parentNode.id == "pin_list") { // if coming from pin_list + if (GroupList.childNodes.length > 0) { + GroupList.insertBefore(Tab, GroupList.childNodes[0]); + } else { + GroupList.appendChild(Tab); + } + } + DOM_SetClasses(Tab, ["tab"], ["pin", "attention"], []); + DOM_RefreshExpandStates(); + chrome.tabs.update(parseInt(Tab.id), {pinned: false}); + } + DOM_RefreshGUI(); + } + } + DuplicateTab() { + let OriginalTabNode = this.Node; + chrome.tabs.duplicate(parseInt(this.id), function(tab) { + let DupRetry = setInterval(function() { + let DupTab = document.getElementById(tab.id); + if (DupTab != null && OriginalTabNode != null) { + if (browserId == "F" && tab.pinned) DOM_SetClasses(DupTab, ["pin"], ["tab"], []); + DOM_InsterAfterNode(DupTab, OriginalTabNode); + DOM_RefreshExpandStates(); + tt.schedule_update_data++; + DOM_RefreshCounters(); + clearInterval(DupRetry); + } + }, 10); + setTimeout(function() { + if (DupRetry) clearInterval(DupRetry); + }, 500); + }); + } + GetFaviconAndTitle(addCounter) { + let t = document.getElementById(this.id); + let tTitle = this.title; + if (t != null) { + chrome.tabs.get(parseInt(t.id), async function(tab) { + if (tab) { + let title = tab.title ? tab.title : tab.url; + let tHeader = t.childNodes[0]; + if (tab.status == "complete" || tab.discarded) { + t.classList.remove("loading"); + tTitle.textContent = title; + tHeader.title = title; + if (opt.show_counter_tabs_hints) tHeader.setAttribute("tabTitle", title); + let Img = new Image(); + let CachedFavicon = browserId == "F" ? await browser.sessions.getTabValue(tab.id, "CachedFaviconUrl") : "chrome://favicon/" + tab.url; + let TryCases = [tab.favIconUrl, CachedFavicon, "./theme/icon_empty.svg"]; + Tabs_LoadFavicon(tab.id, Img, TryCases, tHeader, 0); + } + if (tab.status == "loading" && tab.discarded == false) { + title = tab.title ? tab.title : labels.loading; + t.classList.add("loading"); + tHeader.style.backgroundImage = ""; + tHeader.title = labels.loading; + if (opt.show_counter_tabs_hints) tHeader.setAttribute("tabTitle", labels.loading); + tTitle.textContent = labels.loading; + setTimeout(function() { + if (document.getElementById(tab.id) != null && tt.tabs[tab.id]) tt.tabs[tab.id].GetFaviconAndTitle(addCounter); + }, 1000); + } + if (addCounter && (opt.show_counter_tabs || opt.show_counter_tabs_hints)) tt.tabs[t.id].RefreshTabCounter(); + } + }); + } + } + RefreshDiscarded() { // set discarded class + let t = document.getElementById(this.id); + if (t != null) { + chrome.tabs.get(parseInt(t.id), function(tab) { + if (tab) { + if (tab.discarded) { + DOM_SetClasses(t, ["discarded"], ["audible", "muted"], []); + } else { + t.classList.remove("discarded"); + } + } + }); + } + } + SetAttentionIcon() { // set attention class + let t = document.getElementById(this.id); + if (t != null) t.classList.add("attention"); + } + RefreshMediaIcon() { // change media icon + let t = document.getElementById(this.id); + if (t != null) { + chrome.tabs.get(parseInt(t.id), function(tab) { + if (tab) { + if (tab.mutedInfo.muted && !tab.discarded) DOM_SetClasses(t, ["muted"], ["audible"], []); + if (!tab.mutedInfo.muted && tab.audible && !tab.discarded) DOM_SetClasses(t, ["audible"], ["muted"], []); + if ((!tab.mutedInfo.muted && !tab.audible) || tab.discarded) DOM_SetClasses(t, [], ["audible", "muted"], []); + } + }); + } + } + RefreshTabCounter() { + let t = document.getElementById(this.id); + if (t != null && t.childNodes[0]) { + let title = t.childNodes[0].getAttribute("tabTitle"); + if (t != null && title != null) { + if (t.classList.contains("o") || t.classList.contains("c")) { + if (opt.show_counter_tabs) t.childNodes[0].childNodes[1].childNodes[0].textContent = document.querySelectorAll("[id='" + t.id + "'] .tab").length; + if (opt.show_counter_tabs_hints) t.childNodes[0].title = (document.querySelectorAll("[id='" + t.id + "'] .tab").length + " • ") + title; + } else { + t.childNodes[0].title = title; + } + } + } + } } -async function RearrangeBrowserTabs() { - setInterval(function() { - if (tt.schedule_rearrange_tabs > 0) { - tt.schedule_rearrange_tabs--; - if (opt.debug) { - log("f: RearrangeBrowserTabs"); - } - chrome.tabs.query({currentWindow: true}, function(tabs) { - let ttTabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s){ - return parseInt(s.id); - }); - let tabIds = Array.prototype.map.call(tabs, function(t){ - return t.id; - }); - RearrangeBrowserTabsLoop(ttTabIds, tabIds, ttTabIds.length-1); - }); - } - }, 1000); +async function Tabs_LoadFavicon(tabId, Img, TryUrls, TabHeaderNode, i) { + if (TabHeaderNode) { + Img.src = TryUrls[i]; + Img.onload = function() { + TabHeaderNode.style.backgroundImage = "url(" + TryUrls[i] + ")"; + if (browserId == "F") browser.sessions.setTabValue(tabId, "CachedFaviconUrl", TryUrls[i]); // cache Firefox favicon - solution for bug with empty favicons in unloaded tabs + }; + Img.onerror = function() { + if (i < TryUrls.length) Tabs_LoadFavicon(tabId, Img, TryUrls, TabHeaderNode, (i + 1)); + } + } } -async function RearrangeBrowserTabsLoop(ttTabIds, tabIds, tabIndex) { - if (opt.debug) { - log("f: RearrangeBrowserTabsLoop"); - } - if (tabIndex >= 0 && tt.schedule_rearrange_tabs == 0){ - if (ttTabIds[tabIndex] != tabIds[tabIndex]) { - chrome.tabs.move(ttTabIds[tabIndex], {index: tabIndex}); - } - setTimeout(function() { - RearrangeBrowserTabsLoop(ttTabIds, tabIds, (tabIndex-1)); - }, 0); - } +async function Tabs_SaveTabs() { + setInterval(function() { + if (tt.schedule_update_data > 1) tt.schedule_update_data = 1; + if (tt.schedule_update_data > 0) { + let pins_data = []; + let tabs_data = []; + for (let tabId in tt.tabs) { + if (tt.tabs[tabId].Node != null && tt.tabs[tabId].Node.parentNode != null) { + if (tt.tabs[tabId].pinned) { + pins_data.push({id: tabId, parent: "pin_list", index: Array.from(tt.tabs[tabId].Node.parentNode.children).indexOf(tt.tabs[tabId].Node), expand: ""}); + } else { + tabs_data.push({id: tabId, parent: tt.tabs[tabId].Node.parentNode.parentNode.id, index: Array.from(tt.tabs[tabId].Node.parentNode.children).indexOf(tt.tabs[tabId].Node), expand: (tt.tabs[tabId].Node.classList.contains("c") ? "c" : (tt.tabs[tabId].Node.classList.contains("o") ? "o" : ""))}); + } + } + } + chrome.runtime.sendMessage({command: "update_all_tabs", pins: pins_data, tabs: tabs_data}); + tt.schedule_update_data--; + } + }, 1000); } -function RearrangeTreeTabs(bgtabs, show_finish_in_status) { - if (opt.debug) { - log("f: RearrangeTreeTabs"); - } - ShowStatusBar({show: true, spinner: true, message: "Rearranging tabs and folders"}); - document.querySelectorAll(".pin, .tab").forEach(function(tab){ - if (bgtabs[tab.id]) { - let Sibling = tab.nextElementSibling; - while (Sibling) { - if (bgtabs[Sibling.id]) { - if (bgtabs[tab.id].index > bgtabs[Sibling.id].index ) { - InsterAfterNode(tab, Sibling); - } - } - Sibling = Sibling.nextElementSibling ? Sibling.nextElementSibling : false; - } - } - if (show_finish_in_status){ - ShowStatusBar({show: true, spinner: false, message: "Rearranging: done.", hideTimeout: 1000}); - } - }); +async function Tabs_RearrangeBrowserTabs() { + setInterval(function() { + if (tt.schedule_rearrange_tabs > 0) { + tt.schedule_rearrange_tabs--; + if (opt.debug) Utils_log("f: RearrangeBrowserTabs"); + chrome.tabs.query({currentWindow: true}, function(tabs) { + let ttTabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s) {return parseInt(s.id);}); + let tabIds = Array.prototype.map.call(tabs, function(t) {return t.id;}); + Tabs_RearrangeBrowserTabsLoop(ttTabIds, tabIds, ttTabIds.length - 1); + }); + } + }, 1000); } -function AppendTab(p) { // tab: chrome tab object, ParentId: int or string, InsertBeforeId: int or string, InsertAfterId: int or string, Append: bool, SkipSetEvents: bool, AdditionalClass: string, SkipSetActive: bool, Scroll: bool, addCounter: bool, SkipMediaIcon: bool - if (document.getElementById(p.tab.id) != null) { - GetFaviconAndTitle(p.tab.id, p.addCounter); - return; - } - let ClassList = p.tab.pinned ? "pin" : "tab"; - if (p.tab.discarded) { - ClassList = ClassList + " discarded"; - } - if (p.AdditionalClass) { - ClassList = ClassList +" "+ p.AdditionalClass; - } - let tb = document.createElement("div"); tb.className = ClassList; tb.id = p.tab.id; // TAB - let tbh = document.createElement("div"); tbh.className = (opt.always_show_close && !opt.never_show_close) ? "tab_header close_show" : "tab_header"; tbh.id = "tab_header"+p.tab.id; if (!p.SkipSetEvents) {tbh.draggable = true;} tb.appendChild(tbh); // HEADER - let tbe = document.createElement("div"); tbe.className = "expand"; tbe.id = "exp"+p.tab.id; tbh.appendChild(tbe); // EXPAND ARROW - - - let tbc = document.createElement("div"); tbc.className = "tab_counter"; tbc.id = "tab_counter"+p.tab.id; tbh.appendChild(tbc); // TABS COUNTER - let tbcn = document.createElement("div"); tbcn.className = "counter_number"; tbcn.id = "counter_number"+p.tab.id; tbc.appendChild(tbcn); // TABS COUNTER NUMBER - - - let tbt = document.createElement("div"); tbt.className = "tab_title"; tbt.id = "tab_title"+p.tab.id; tbh.appendChild(tbt); // TITLE - - let cl = undefined; - if (!opt.never_show_close) { - cl = document.createElement("div"); cl.className = "close"; cl.id = "close"+p.tab.id; tbh.appendChild(cl); // CLOSE BUTTON - let ci = document.createElement("div"); ci.className = "close_img"; ci.id = "close_img"+p.tab.id; cl.appendChild(ci); - } - let mi = document.createElement("div"); mi.className = "tab_mediaicon"; mi.id = "tab_mediaicon"+p.tab.id; tbh.appendChild(mi); - - - - let ct = document.createElement("div"); ct.className = "children_tabs"; ct.id = "ct"+p.tab.id; tb.appendChild(ct); - let di = document.createElement("div"); di.className = "drag_indicator"; di.id = "di"+p.tab.id; tb.appendChild(di); // DROP TARGET INDICATOR - - if (!p.SkipSetEvents) { - ct.onclick = function(event) { - if (event.target == this && event.which == 1) { - DeselectFolders(); - DeselectTabs(); - } - } - ct.onmousedown = function(event) { - if (event.target == this) { - if (event.which == 2 && event.target == this) { - event.stopImmediatePropagation(); - ActionClickGroup(this.parentNode, opt.midclick_group); - } - if (event.which == 3) { - ShowFGlobalMenu(event); - } - } - } - ct.ondblclick = function(event) { - if (event.target == this) { - ActionClickGroup(this.parentNode, opt.dbclick_group); - } - } - tbe.onmousedown = function(event) { - if (document.getElementById("main_menu").style.top != "-1000px") { - HideMenus(); - } - if (event.which == 1 && !event.shiftKey && !event.ctrlKey) { - EventExpandBox(this.parentNode.parentNode); - } - } - tbe.onmouseenter = function(event) { - this.classList.add("hover"); - } - tbe.onmouseleave = function(event) { - this.classList.remove("hover"); - } - - if (!opt.never_show_close && cl) { - cl.onmousedown = function(event) { - event.stopImmediatePropagation(); - if (event.which != 3) { - CloseTabs([parseInt(this.parentNode.parentNode.id)]); - } - } - cl.onmouseenter = function(event) { - this.classList.add("close_hover"); - } - cl.onmouseleave = function(event) { - this.classList.remove("close_hover"); - } - } - - tbh.onclick = function(event) { - event.stopImmediatePropagation(); - if (document.getElementById("main_menu").style.top != "-1000px") { - HideMenus(); - } else { - if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target.classList.contains("tab_header")) { - DeselectTabs(); - chrome.tabs.update(parseInt(this.parentNode.id), { active: true }); - } - } - } - tbh.ondblclick = function(event) { - if (event.target.classList && event.target.classList.contains("tab_header")) { - ActionClickTab(this.parentNode, opt.dbclick_tab); - } - } - - tbh.onmousedown = function(event) { - if (browserId == "V") { - chrome.windows.getCurrent({populate: false}, function(window) { - if (tt.CurrentWindowId != window.id && window.focused) { - location.reload(); - } - }); - } - event.stopImmediatePropagation(); - if (event.which == 1) { - EventSelectTab(event, this.parentNode); - } - if (event.which == 2) { - event.preventDefault(); - ActionClickTab(this.parentNode, opt.midclick_tab); - } - if (event.which == 3) { - ShowTabMenu(this.parentNode, event); - } - } - - tbh.onmouseover = function(event) { - this.classList.add("tab_header_hover"); - if (opt.never_show_close == false && opt.always_show_close == false) { - this.classList.add("close_show"); - } - } - tbh.onmouseleave = function(event) { - this.classList.remove("tab_header_hover"); - if (opt.never_show_close == false && opt.always_show_close == false) { - this.classList.remove("close_show"); - } - } - - - - tbh.ondragstart = function(event) { // DRAG START - TabStartDrag(this.parentNode, event); - } - - tbh.ondragenter = function(event) { - this.classList.remove("tab_header_hover"); - } - - tbh.ondragleave = function(event) { - RemoveHighlight(); - } - - tbh.ondragover = function(event) { - TabDragOver(this, event); - if (opt.open_tree_on_hover && tt.DragOverId != this.id) { - if (this.parentNode.classList.contains("c") && this.parentNode.classList.contains("dragged_tree") == false) { - clearTimeout(tt.DragOverTimer); - tt.DragOverId = this.id; - let This = this; - tt.DragOverTimer = setTimeout(function() { - if (tt.DragOverId == This.id) { - This.parentNode.classList.add("o"); - This.parentNode.classList.remove("c"); - } - }, 1500); - } - } - } - - mi.onmousedown = function(event) { - event.stopImmediatePropagation(); - if (event.which == 1 && (this.parentNode.parentNode.classList.contains("audible") || this.parentNode.parentNode.classList.contains("muted")) ) { - chrome.tabs.get(parseInt(this.parentNode.parentNode.id), function(tab) { - if (tab) { - chrome.tabs.update(tab.id, {muted:!tab.mutedInfo.muted}); - } - }); - } - } - } - - let parent; - if (p.tab.pinned) { - parent = document.getElementById("pin_list"); - } else { - if (p.ParentId == false || p.ParentId == undefined || document.getElementById(p.ParentId) == null || document.querySelector(".pin[id='"+p.ParentId+"']") != null || p.ParentId == "pin_list") { - parent = document.getElementById("ct"+tt.active_group); - } else { - parent = document.getElementById("ct"+p.ParentId); - if (parent.children.length == 0) { - parent.parentNode.classList.add("o"); - parent.parentNode.classList.remove("c"); - } - } - } - if (p.Append && parent) { - parent.appendChild(tb); - } - if (!p.Append && parent) { - parent.prepend(tb); - } - - if (p.InsertBeforeId) { - let Before = document.getElementById(p.InsertBeforeId); - if (Before != null) { - if ((p.tab.pinned && Before.classList.contains("pin")) || (p.tab.pinned == false && Before.classList.contains("tab"))) { - Before.parentNode.insertBefore(tb, Before); - } - } - } - if (p.InsertAfterId) { - let After = document.getElementById(p.InsertAfterId); - if (After != null) { - if ((p.tab.pinned && After.classList.contains("pin")) || (p.tab.pinned == false && After.classList.contains("tab"))) { - InsterAfterNode(tb, After); - } - } - } - GetFaviconAndTitle(p.tab.id, p.addCounter); - if (!p.SkipMediaIcon) { - RefreshMediaIcon(p.tab.id); - } - if (p.tab.active && !p.SkipSetActive) { - SetActiveTab(p.tab.id); - } - if (p.Scroll) { - ScrollToTab(p.tab.id); - } - - return tb; +async function Tabs_RearrangeBrowserTabsLoop(ttTabIds, tabIds, tabIndex) { + if (opt.debug) Utils_log("f: RearrangeBrowserTabsLoop"); + if (tabIndex >= 0 && tt.schedule_rearrange_tabs == 0) { + if (ttTabIds[tabIndex] != tabIds[tabIndex]) chrome.tabs.move(ttTabIds[tabIndex], {index: tabIndex}); + setTimeout(function() { + Tabs_RearrangeBrowserTabsLoop(ttTabIds, tabIds, (tabIndex - 1)); + }, 0); + } } - -function RemoveTabFromList(tabId) { - if (opt.debug) { - log("f: RemoveTabFromList, tabId: "+tabId); - } - let tab = document.getElementById(tabId); - if (tab != null) { - tab.parentNode.removeChild(tab); - } +function Tabs_RearrangeTree(TTtabs, TTfolders, show_finish_in_status) { + Manager_ShowStatusBar({show: true, spinner: true, message: chrome.i18n.getMessage("status_bar_rearranging_tabs")}); + let Nodes = document.querySelectorAll(".pin, .tab, .folder"); + for (let Node of Nodes) { + let Sibling = Node.nextElementSibling; + if (Sibling) { + let NodeIndex = TTtabs[Node.id] ? TTtabs[Node.id].index : (TTfolders[Node.id] ? TTfolders[Node.id].index : undefined); + while (Sibling && NodeIndex) { + let SiblingIndex = TTtabs[Sibling.id] ? TTtabs[Sibling.id].index : (TTfolders[Sibling.id] ? TTfolders[Sibling.id].index : 0); + if (NodeIndex > SiblingIndex) DOM_InsterAfterNode(Node, Sibling); + Sibling = Sibling.nextElementSibling ? Sibling.nextElementSibling : false; + } + } + if (show_finish_in_status) Manager_ShowStatusBar({show: true, spinner: false, message: chrome.i18n.getMessage("status_bar_rearranging_finished"), hideTimeout: 1000}); + } } -function SetTabClass(tabId, pin) { - let PinList = document.getElementById("pin_list"); - let GroupList = document.getElementById("ct"+tt.active_group); - let Tab = document.getElementById(tabId); - if (Tab != null) { - if (pin) { - if (Tab.parentNode.id != "pin_list") { - document.getElementById("pin_list").appendChild(Tab); - } - Tab.classList.remove("tab"); - Tab.classList.remove("o"); - Tab.classList.remove("c"); - Tab.classList.add("pin"); - if (document.getElementById("ct"+tabId).childNodes.length > 0) { // flatten out children - let tabs = document.querySelectorAll("#ct"+tabId+" .pin, #ct"+tabId+" .tab"); - for (let i = tabs.length-1; i >= 0; i--) { - tabs[i].classList.remove("tab"); - tabs[i].classList.remove("o"); - tabs[i].classList.remove("c"); - tabs[i].classList.add("pin"); - InsterAfterNode(tabs[i], Tab); - chrome.tabs.update(parseInt(tabs[i].id), {pinned: true}); - } - } - chrome.tabs.update(parseInt(tabId), {pinned: true}); - } else { - if (Tab.parentNode.id == "pin_list") { // if coming from pin_list - if (GroupList.childNodes.length > 0) { - GroupList.insertBefore(Tab, GroupList.childNodes[0]); - } else { - GroupList.appendChild(Tab); - } - } - Tab.classList.remove("pin"); - Tab.classList.remove("attention"); - Tab.classList.add("tab"); - RefreshExpandStates(); - chrome.tabs.update(parseInt(tabId), {pinned: false}); - } - RefreshGUI(); - } -} -function SetMultiTabsClass(TabsIds, pin) { - TabsIds.forEach(function(tabId){ - SetTabClass(tabId, pin); - chrome.tabs.update(parseInt(tabId), {pinned: pin}); - }); +function Tabs_Detach(Nodes, NodesTypes, Group) { + if (opt.debug) Utils_log("f: Detach"); + let folderNodes = {}; + let TabsIds = []; + for (let Node of Nodes) { + if (Node.NodeClass == "folder") folderNodes[Node.id] = {id: Node.id, parent: (Node.parent).substr(1), name: Node.name, index: Node.index, expand: Node.expand}; + if (Node.NodeClass == "pin") TabsIds.push(parseInt(Node.id)); + if (Node.NodeClass == "tab") TabsIds.push(parseInt(Node.id)); + } + chrome.windows.get(tt.CurrentWindowId, {populate : true}, function(window) { + if (window.tabs.length == 1) return; + if (TabsIds.length == window.tabs.length) { + if (opt.debug) Utils_log("You are trying to detach all tabs! Skipping!"); + return; + } + let params = TabsIds.length > 0 ? {tabId: TabsIds[0], state: window.state} : {state: window.state}; + chrome.windows.create(params, function(new_window) { + chrome.tabs.update(new_window.tabs[0].id, {active: true}); + chrome.runtime.sendMessage({command: "get_groups", windowId: new_window.id}, function(g) { + if (NodesTypes.DraggingGroup) { + let GroupsToDetach = Object.assign({}, g); // if there will be a multi groups selection, below I will need for each group loop + GroupsToDetach[Group.id] = Group; + chrome.runtime.sendMessage({command: "save_groups", groups: GroupsToDetach, windowId: new_window.id}); + setTimeout(function() {Groups_GroupRemove(Group.id, false);}, 2000); + } + chrome.runtime.sendMessage({command: "save_folders", folders: folderNodes, windowId: new_window.id}); + for (let Node of Nodes) { + if (Node.NodeClass == "pin") { + chrome.tabs.update(parseInt(Node.id), {pinned: true}); + chrome.runtime.sendMessage({command: "update_tab", tabId: Node.id, tab: {parent: "pin_list"}}); + } + if (Node.NodeClass == "tab") chrome.runtime.sendMessage({command: "update_tab", tabId: Node.id, tab: {parent: (Node.parent).substr(1)}}); + if (Node.NodeClass == "folder") Folders_RemoveFolder(Node.id); + } + if (TabsIds.length > 1) { + TabsIds.splice(0, 1); + chrome.tabs.move(TabsIds, {windowId: new_window.id, index:-1}, function(MovedTabs) { + for (let Node of Nodes) { + if (Node.NodeClass == "pin") {chrome.tabs.update(parseInt(Node.id), {pinned: true});} + if (Node.NodeClass == "folder") {Folders_RemoveFolder(Node.id);} + } + let Stop = 500; + let DetachNodes = setInterval(function() { + Stop--; + let all_moved = true; + for (let Node of Nodes) { + if (document.getElementById(Node.id) != null) all_moved = false; + if (Node.NodeClass == "pin") chrome.runtime.sendMessage({command: "update_tab", tabId: Node.id, tab: {parent: "pin_list"}}); + if (Node.NodeClass == "tab") chrome.runtime.sendMessage({command: "update_tab", tabId: Node.id, tab: {parent: (Node.parent).substr(1)}}); + } + if (all_moved || Stop < 0) { + setTimeout(function() { + clearInterval(DetachNodes); + }, 300); + } + }, 100); + }); + } + }); + }); + }); } -function SetActiveTab(tabId, switchToGroup) { - if (opt.debug) { - log("f: SetActiveTab, tabId: "+tabId); - } - let Tab = document.getElementById(tabId); - if (Tab != null) { - let TabGroup = GetParentsByClass(Tab, "group"); - if (TabGroup.length) { - if (Tab.classList.contains("tab")) { - SetActiveTabInGroup(TabGroup[0].id, tabId); - } - if (switchToGroup) { - SetActiveGroup(TabGroup[0].id, false, false); // not going to scroll, because mostly it's going to change to a new active in group AFTER switch, so we are not going to scroll to previous active tab - } - } - document.querySelectorAll(".selected_folder").forEach(function(s){ - s.classList.remove("selected_folder"); - }); - // document.querySelectorAll(".pin, #"+tt.active_group+" .tab"+(TabGroup.length ? ", #"+TabGroup[0].id+" .tab" : "")).forEach(function(s){ - document.querySelectorAll(".pin, #"+tt.active_group+" .tab").forEach(function(s){ - s.classList.remove("active_tab"); - s.classList.remove("selected_tab"); - s.classList.remove("selected_last"); - s.classList.remove("selected_frozen"); - s.classList.remove("selected_temporarly"); - s.classList.remove("tab_header_hover"); - }); - RemoveHighlight(); - Tab.classList.remove("attention"); - Tab.classList.add("active_tab"); - ScrollToTab(tabId); - } +function Tabs_DiscardTabs(tabsIds) { + let delay = 100; + let tabNode = document.getElementById(tabsIds[0]); + if (tabNode == null || tabNode.classList.contains("discarded") || tabNode.classList.contains("active_tab")) { + delay = 5; + } else { + chrome.tabs.discard(tabsIds[0]); + } + tabsIds.splice(0, 1); + if (tabsIds.length > 0) { + setTimeout(function() { + Tabs_DiscardTabs(tabsIds); + }, delay); + } } -function ScrollToTab(tabId) { - let Tab = document.getElementById(tabId); - if (Tab != null) { - if (Tab.classList.contains("pin")) { - if (Tab.getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().left < 0) { - document.getElementById("pin_list").scrollLeft = document.getElementById("pin_list").scrollLeft + Tab.getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().left - 2; - } else { - if (Tab.getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().left > document.getElementById(tt.active_group).getBoundingClientRect().width - document.querySelector(".tab_header").getBoundingClientRect().width) { - document.getElementById("pin_list").scrollLeft = document.getElementById("pin_list").scrollLeft + Tab.getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().left - document.getElementById("pin_list").getBoundingClientRect().width + document.querySelector(".tab_header").getBoundingClientRect().width + 2; - } - } - } - if (Tab.classList.contains("tab") && document.querySelector("#"+tt.active_group+" [id='"+tabId+"']") != null) { - let Parents = GetParentsByClass(Tab, "c"); - if (Parents.length > 0) { - Parents.forEach(function(s){ - s.classList.remove("c"); - s.classList.add("o"); - }); - } - if (Tab.getBoundingClientRect().top - document.getElementById(tt.active_group).getBoundingClientRect().top < 0) { - document.getElementById(tt.active_group).scrollTop = document.getElementById(tt.active_group).scrollTop + Tab.getBoundingClientRect().top - document.getElementById(tt.active_group).getBoundingClientRect().top - 2; - } else { - if (Tab.getBoundingClientRect().top - document.getElementById(tt.active_group).getBoundingClientRect().top > document.getElementById(tt.active_group).getBoundingClientRect().height - document.querySelector(".tab_header").getBoundingClientRect().height) { - document.getElementById(tt.active_group).scrollTop = document.getElementById(tt.active_group).scrollTop + Tab.getBoundingClientRect().top - document.getElementById(tt.active_group).getBoundingClientRect().top - document.getElementById(tt.active_group).getBoundingClientRect().height + document.querySelector(".tab_header").getBoundingClientRect().height + 10; - } - } - } - } +function Tabs_FindTab(input) { // find and select tabs + let ButtonFilterClear = document.getElementById("button_filter_clear"); + let Nodes = document.querySelectorAll(".filtered, .highlighted_search"); + for (let s of Nodes) { + DOM_SetClasses(s, [], ["selected", "selected_last", "filtered", "highlighted_search"], []); + } + if (input.length == 0) { + document.getElementById("filter_box").value = ""; + ButtonFilterClear.style.opacity = "0"; ButtonFilterClear.title = ""; + return; + } else { + ButtonFilterClear.style.opacity = "1"; ButtonFilterClear.title = labels.clear_filter; + } + tt.SearchIndex = 0; + let FilterType = document.getElementById("button_filter_type"); + let searchUrl = FilterType.classList.contains("url"); + let searchTitle = FilterType.classList.contains("title"); + let query = {windowId: tt.CurrentWindowId, pinned: false}; + if (input == "*audible") query = {windowId: tt.CurrentWindowId, discarded: false, audible: true, muted: false, pinned: false}; + if (input == "*muted") query = {windowId: tt.CurrentWindowId, discarded: false, muted: true, pinned: false}; + if (input == "*unloaded") query = {windowId: tt.CurrentWindowId, discarded: true, pinned: false}; + if (input == "*loaded") query = {windowId: tt.CurrentWindowId, discarded: false, pinned: false}; + chrome.tabs.query(query, function(tabs) { + for (let Tab of tabs) { + let t = document.getElementById(Tab.id); + if (input == "*audible" || input == "*muted" || input == "*unloaded" || input == "*loaded") { + DOM_SetClasses(t, ["filtered", "selected"], [], []); + } else { + if (searchUrl) { + if (Tab.url.toLowerCase().match(input.toLowerCase())) DOM_SetClasses(t, ["filtered", "selected"], [], []); + } + if (searchTitle) { + if (Tab.title.toLowerCase().match(input.toLowerCase())) DOM_SetClasses(t, ["filtered", "selected"], [], []); + } + } + } + }); } -function Detach(tabsIds, Folders) { - if (opt.debug) { - log("f: Detach"); - } - chrome.windows.get(tt.CurrentWindowId, {populate : true}, function(window) { - if (window.tabs.length == 1 || tabsIds.length == 0) { - return; - } - if (tabsIds.length == window.tabs.length) { - if (opt.debug) { - log("You are trying to detach all tabs! Skipping!"); - } - return; - } - - let Indexes = []; - let Parents = []; - let Expands = []; - let NewTabs = []; - let Ind = 0; - - tabsIds.forEach(function(tabId) { - let tab = document.getElementById(tabId); - Indexes.push(Array.from(tab.parentNode.children).indexOf(tab)); - Parents.push(tab.parentNode.parentNode.id); - Expands.push( (tab.classList.contains("c") ? "c" : (tab.classList.contains("o") ? "o" : "")) ); - }); - - chrome.windows.create({tabId: tabsIds[0], state:window.state}, function(new_window) { - - tabsIds.splice(0, 1); - chrome.tabs.move(tabsIds, {windowId: new_window.id, index:-1}, function(MovedTabs) { - - if (Folders && Object.keys(Folders).length > 0) { - for (let folder in Folders) { - RemoveFolder(Folders[folder].id); - } - } - - }); - }); - }); +function Tabs_CloseTabs(tabsIds) { + if (opt.debug) Utils_log("f: Tabs_CloseTabs, tabsIds are: " + JSON.stringify(tabsIds)); + for (let tabId of tabsIds) { + let t = document.getElementById(tabId); + if (t != null) t.classList.add("will_be_closed"); + } + let activeTab = document.querySelector(".pin.active_tab, #" + tt.active_group + " .tab.active_tab"); + if (activeTab != null && tabsIds.indexOf(parseInt(activeTab.id)) != -1) Tabs_SwitchActiveTabBeforeClose(tt.active_group); + setTimeout(function() { + for (let tabId of tabsIds) { + let t = document.getElementById(tabId); + if (t != null && t.classList.contains("pin") && opt.allow_pin_close) { + t.parentNode.removeChild(t); + chrome.tabs.update(tabId, {pinned: false}); + chrome.runtime.sendMessage({command: "update_tab", tabId: tabId, tab: {parent: "pin_list"}}); + } + if (tabId == tabsIds[tabsIds.length - 1]) { + setTimeout(function() {chrome.tabs.remove(tabsIds, null);}, 10); + DOM_RefreshGUI(); + } + } + }, 200); } -function CloseTabs(tabsIds) { - if (opt.debug) { - log("f: CloseTabs, tabsIds are: "+JSON.stringify(tabsIds)); - } - tabsIds.forEach(function(tabId) { - let Tab = document.getElementById(tabId); - if (Tab != null) { - Tab.classList.add("will_be_closed"); - } - }); - let activeTab = document.querySelector(".pin.active_tab, #"+tt.active_group+" .tab.active_tab"); - if (activeTab != null && tabsIds.indexOf(parseInt(activeTab.id)) != -1) { - SwitchActiveTabBeforeClose(tt.active_group); - } - setTimeout(function() { - tabsIds.forEach(function(tabId) { - let tab = document.getElementById(tabId); - if (tab.classList.contains("pin") && opt.allow_pin_close) { - tab.parentNode.removeChild(tab); - chrome.tabs.update(tabId, {pinned: false}); - // RefreshGUI(); - } - if (tabId == tabsIds[tabsIds.length-1]) { - setTimeout(function() { - chrome.tabs.remove(tabsIds, null); - }, 10); - } - }); - }, 200); +function Tabs_OpenNewTab(pin, InsertAfterNode, AppendToNode) { + // if (pin) { + chrome.tabs.create({pinned: pin}, function(tab) { + // console.log(tt.tabs[tab.id]) + + let Retry = setInterval(function() { + if (tt.tabs[tab.id]) { + if (InsertAfterNode) { + DOM_InsterAfterNode(tt.tabs[tab.id].Node, InsertAfterNode); + } + if (AppendToNode) { + DOM_AppendToNode(tt.tabs[tab.id].Node, AppendToNode); + } + tt.schedule_update_data++; + clearInterval(Retry); + } + }, 10); + setTimeout(function() { + if (Retry) clearInterval(Retry); + }, 500); + if (!pin && opt.move_tabs_on_url_change == "from_empty") chrome.runtime.sendMessage({command: "remove_tab_from_empty_tabs", tabId: tab.id}); + + + // if (InsertAfterNode && tt.tabs[tab.id]) { + // let parent = document.getElementById("#pin_list"); + // if (parent != null && tt.tabs[tab.id]) parent.appendChild(tt.tabs[tab.id].Node); + // } + }); + // } else { + // chrome.tabs.create({}, function(tab) { + // if (parentId) { + // let parent = document.getElementById("#°"+parentId); + // if (parent != null && tt.tabs[tab.id]) parent.appendChild(tt.tabs[tab.id].Node); + // tt.schedule_update_data++; + // } + // }); + // } } -function DiscardTabs(tabsIds) { - let delay = 100; - let tabNode = document.getElementById(tabsIds[0]); - if (tabNode == null || tabNode.classList.contains("discarded") || tabNode.classList.contains("active_tab")) { - delay = 5; - } else { - chrome.tabs.discard(tabsIds[0]); - } - tabsIds.splice(0, 1); - if (tabsIds.length > 0) { - setTimeout(function() { - DiscardTabs(tabsIds); - }, delay); - } +function Tabs_GetTabDepthInTree(Node) { + let Depth = 0; + let ParentNode = Node; + if (ParentNode == null) return Parents; + let Stop = false; + while (!Stop && ParentNode.parentNode != null) { + if (ParentNode.parentNode.classList != undefined) { + if (ParentNode.parentNode.classList.contains("tab")) Depth++; + if (ParentNode.parentNode.classList.contains("folder") || ParentNode.parentNode.classList.contains("group")) { + Stop = true; + } else { + ParentNode = ParentNode.parentNode; + } + } else { + Stop = true; + } + } + return Depth; } -function SwitchActiveTabBeforeClose(ActiveGroupId) { - if (opt.debug) { - log("f: SwitchActiveTabBeforeClose"); - } - let activeGroup = document.getElementById(ActiveGroupId); - - if (document.querySelectorAll("#"+ActiveGroupId+" .tab").length < 2 && document.querySelector(".pin.active_tab") == null) { // CHECK IF CLOSING LAST TAB IN ACTIVE GROUP - - let pins = document.querySelectorAll(".pin"); - - if (pins.length > 0) { // IF THERE ARE ANY PINNED TABS, ACTIVATE IT - if (opt.debug) { - log("available pin, switching to: "+pins[pins.length-1].id); - } - chrome.tabs.update(parseInt(pins[pins.length-1].id), {active: true}); - return; - } else { // NO OTHER CHOICE BUT TO SEEK IN ANOTHER GROUP - - if (opt.after_closing_active_tab == "above" || opt.after_closing_active_tab == "above_seek_in_parent") { - if (activeGroup.previousSibling != null) { - if (document.querySelectorAll("#"+activeGroup.previousSibling.id+" .tab").length > 0) { - SetActiveGroup(activeGroup.previousSibling.id, true, true); - } else { - SwitchActiveTabBeforeClose(activeGroup.previousSibling.id); - return; - } - } else { - SetActiveGroup("tab_list", true, true); - } - } else { - if (activeGroup.nextSibling != null) { - if (document.querySelectorAll("#"+activeGroup.nextSibling.id+" .tab").length > 0) { - SetActiveGroup(activeGroup.nextSibling.id, true, true); - } else { - SwitchActiveTabBeforeClose(activeGroup.nextSibling.id); - return; - } - } else { - SetActiveGroup("tab_list", true, true); - } - } - } - } else { - - if (opt.debug) { - log("available tabs in current group, switching option is: "+opt.after_closing_active_tab); - } - - if (opt.after_closing_active_tab == "above" || opt.after_closing_active_tab == "above_seek_in_parent") { - ActivatePrevTab(true); - } - if (opt.after_closing_active_tab == "below" || opt.after_closing_active_tab == "below_seek_in_parent") { - ActivateNextTab(true); - } - // if (opt.after_closing_active_tab == "above_seek_in_parent") { - // ActivatePrevTabBeforeClose(); - // } - // if (opt.after_closing_active_tab == "below_seek_in_parent") { - // ActivateNextTabBeforeClose(); - // } - } +function Tabs_ActionClickTab(TabNode, bgOption) { + if (bgOption == "new_tab") Tabs_OpenNewTab(TabNode.classList.contains("pin"), TabNode); + if (bgOption == "expand_collapse") DOM_EventExpandBox(TabNode); + if (bgOption == "close_tab") { + if ((TabNode.classList.contains("pin") && opt.allow_pin_close) || TabNode.classList.contains("tab")) Tabs_CloseTabs([parseInt(TabNode.id)]); + } + if (bgOption == "undo_close_tab") { + chrome.sessions.getRecentlyClosed(null, function(sessions) { + if (sessions.length > 0) chrome.sessions.restore(null, function(restored) {}); + }); + } + if (bgOption == "reload_tab") {chrome.tabs.reload(parseInt(TabNode.id));} + if (bgOption == "unload_tab") { + if (TabNode.classList.contains("active_tab")) { + Tabs_SwitchActiveTabBeforeClose(tt.active_group); + setTimeout(function() {Tabs_DiscardTabs([parseInt(TabNode.id)]);}, 500); + } else { + Tabs_DiscardTabs([parseInt(TabNode.id)]); + } + } + if (bgOption == "activate_previous_active" && TabNode.classList.contains("active_tab")) { + let PrevActiveTabId = parseInt(tt.groups[tt.active_group].prev_active_tab); + if (isNaN(PrevActiveTabId) == false) chrome.tabs.update(PrevActiveTabId, {active: true}); + } } -function ActivateNextTabBeforeClose() { - let activePin = document.querySelector(".pin.active_tab"); - if (activePin != null) { - if (activePin.nextSibling != null) { - chrome.tabs.update(parseInt(activePin.nextSibling.id), { active: true }); - } else { - if (activePin.previousSibling != null) { - chrome.tabs.update(parseInt(activePin.previousSibling.id), { active: true }); - } - } - } - - let will_be_closed = document.querySelectorAll("#"+tt.active_group+" .will_be_closed"); - let activeTab = will_be_closed.length > 0 ? will_be_closed[will_be_closed.length-1] : document.querySelector("#"+tt.active_group+" .tab.active_tab"); - - if (activeTab != null && document.querySelectorAll("#"+tt.active_group+" .tab:not(.will_be_closed)").length > 1) { - if (opt.promote_children && activeTab.childNodes[1].firstChild != null) { - chrome.tabs.update(parseInt(activeTab.childNodes[1].firstChild.id), { active: true }); - } else { - if (activeTab.nextSibling != null) { - chrome.tabs.update(parseInt(activeTab.nextSibling.id), { active: true }); - } else { - if (activeTab.previousSibling != null) { - chrome.tabs.update(parseInt(activeTab.previousSibling.id), { active: true }); - } else { - if (activeTab.parentNode.parentNode.classList.contains("tab")) { - chrome.tabs.update(parseInt(activeTab.parentNode.parentNode.id), { active: true }); - } else { - ActivatePrevTab(); - } - } - } - } - } +function Tabs_SetActiveTab(tabId, switchToGroup) { + if (opt.debug) Utils_log("f: SetActiveTab, tabId: " + tabId); + let Tab = document.getElementById(tabId); + if (Tab != null) { + let TabGroup = DOM_GetParentsByClass(Tab, "group"); + if (TabGroup.length) { + if (Tab.classList.contains("tab")) Groups_SetActiveTabInGroup(TabGroup[0].id, tabId); + if (switchToGroup) Groups_SetActiveGroup(TabGroup[0].id, false, false); // not going to scroll, because mostly it's going to change to a new active in group AFTER switch, so we are not going to scroll to previous active tab + } + // let selected = document.querySelectorAll(".selected"); + // for (let s of selected) { + // s.classList.remove("selected"); + // } + // let selected_not_in_group = document.querySelectorAll(".pin, #" + tt.active_group + " .tab"); + // for (let s of selected_not_in_group) { + // DOM_SetClasses(s, [], ["active_tab", "selected", "selected_last", "selected_frozen", "selected_temporarly", "tab_header_hover"], []); + // } + + + let active_tabs = document.querySelectorAll(".pin.active_tab, #" + tt.active_group + " .active_tab"); + for (let s of active_tabs) { + DOM_SetClasses(s, [], ["active_tab"], []); + } + DOM_RemoveHighlight(); + DOM_SetClasses(Tab, ["active_tab"], ["attention"], []); + if (tt.tabs[tabId]) tt.tabs[tabId].ScrollToTab(); + } } -function ActivatePrevTabBeforeClose() { - let activePin = document.querySelector(".pin.active_tab"); - if (activePin != null) { - if (activePin.previousSibling != null) { - chrome.tabs.update(parseInt(activePin.previousSibling.id), { active: true }); - } else { - if (activePin.nextSibling != null) { - chrome.tabs.update(parseInt(activePin.nextSibling.id), { active: true }); - } - } - } - - let will_be_closed = document.querySelectorAll("#"+tt.active_group+" .will_be_closed"); - let activeTab = will_be_closed.length > 0 ? will_be_closed[0] : document.querySelector("#"+tt.active_group+" .tab.active_tab"); - - if (activeTab != null && document.querySelectorAll("#"+tt.active_group+" .tab:not(.will_be_closed)").length > 1) { - if (opt.promote_children && activeTab.childNodes[1].firstChild != null) { - chrome.tabs.update(parseInt(activeTab.childNodes[1].firstChild.id), { active: true }); - } else { - if (activeTab.previousSibling != null) { - chrome.tabs.update(parseInt(activeTab.previousSibling.id), { active: true }); - } else { - if (activeTab.nextSibling != null) { - chrome.tabs.update(parseInt(activeTab.nextSibling.id), { active: true }); - } else { - if (activeTab.parentNode.parentNode.classList.contains("tab")) { - chrome.tabs.update(parseInt(activeTab.parentNode.parentNode.id), { active: true }); - } else { - ActivateNextTab(); - } - } - } - } - } +function Tabs_SwitchActiveTabBeforeClose(ActiveGroupId) { + if (opt.debug) Utils_log("f: SwitchActiveTabBeforeClose"); + let activeGroup = document.getElementById(ActiveGroupId); + if (document.querySelectorAll("#" + ActiveGroupId + " .tab:not(.will_be_closed)").length <= 1 && document.querySelector(".pin.active_tab") == null) { // CHECK IF CLOSING LAST TAB IN ACTIVE GROUP + let pins = document.querySelectorAll(".pin"); + if (pins.length > 0) { // IF THERE ARE ANY PINNED TABS, ACTIVATE IT + if (opt.debug) Utils_log("available pin, switching to: " + pins[pins.length - 1].id); + chrome.tabs.update(parseInt(pins[pins.length - 1].id), {active: true}); + return; + } else { // NO OTHER CHOICE BUT TO SEEK IN ANOTHER GROUP + if (opt.after_closing_active_tab == "above" || opt.after_closing_active_tab == "above_seek_in_parent") { + if (activeGroup.previousSibling != null) { + if (document.querySelectorAll("#" + activeGroup.previousSibling.id + " .tab").length > 0) { + Groups_SetActiveGroup(activeGroup.previousSibling.id, true, true); + } else { + Tabs_SwitchActiveTabBeforeClose(activeGroup.previousSibling.id); + return; + } + } else { + Groups_SetActiveGroup("tab_list", true, true); + } + } else { + if (activeGroup.nextSibling != null) { + if (document.querySelectorAll("#" + activeGroup.nextSibling.id + " .tab").length > 0) { + Groups_SetActiveGroup(activeGroup.nextSibling.id, true, true); + } else { + Tabs_SwitchActiveTabBeforeClose(activeGroup.nextSibling.id); + return; + } + } else { + Groups_SetActiveGroup("tab_list", true, true); + } + } + } + } else { + if (opt.debug) Utils_log("available tabs in current group, switching option is: " + opt.after_closing_active_tab); + if (opt.after_closing_active_tab == "above") Tabs_ActivatePrevTab(true); + if (opt.after_closing_active_tab == "below") Tabs_ActivateNextTab(true); + if (opt.after_closing_active_tab == "above_seek_in_parent") Tabs_ActivatePrevTabSameLevel(); + if (opt.after_closing_active_tab == "below_seek_in_parent") Tabs_ActivateNextTabSameLevel(); + } } -function ActivateNextTab(allow_reverse) { - let activePin = document.querySelector(".pin.active_tab"); - if (activePin != null) { - if (activePin.nextSibling != null) { - chrome.tabs.update(parseInt(activePin.nextSibling.id), { active: true }); - } else { - if (activePin.previousSibling != null && allow_reverse) { - chrome.tabs.update(parseInt(activePin.previousSibling.id), { active: true }); - } - } - } - - let will_be_closed = document.querySelectorAll("#"+tt.active_group+" .will_be_closed"); - let activeTab = will_be_closed.length > 0 ? will_be_closed[will_be_closed.length-1] : document.querySelector("#"+tt.active_group+" .tab.active_tab"); - - if (activeTab != null && document.querySelectorAll("#"+tt.active_group+" .tab").length > 1) { - let FirstChild = activeTab.childNodes[1].firstChild; - if (FirstChild != null) { - chrome.tabs.update(parseInt(FirstChild.id), { active: true }); - } else { - if (activeTab.nextSibling != null) { - chrome.tabs.update(parseInt(activeTab.nextSibling.id), { active: true }); - } else { - let Next = null; - while (Next == null && activeTab.parentNode != null && activeTab.parentNode.parentNode != null) { - if (activeTab.parentNode.parentNode.classList != undefined && activeTab.parentNode.parentNode.classList.contains("tab") && activeTab.parentNode.parentNode.nextSibling != null && activeTab.parentNode.parentNode.nextSibling.classList.contains("tab")) { - Next = activeTab.parentNode.parentNode.nextSibling; - } - activeTab = activeTab.parentNode.parentNode; - } - if (Next != null) { - chrome.tabs.update(parseInt(Next.id), { active: true }); - } else { - if (allow_reverse) { - ActivatePrevTab(); - } - } - } - } - } +function Tabs_ActivateNextTabSameLevel() { + let activeTab = document.querySelector("#" + tt.active_group + " .tab.active_tab") != null ? document.querySelector("#" + tt.active_group + " .tab.active_tab") : document.querySelector(".pin.active_tab"); + if (activeTab == null) return; + let NewActiveId; + let Node = activeTab; + if (activeTab.classList.contains("tab")) { + if (opt.promote_children && activeTab.childNodes[1].firstChild != null && activeTab.childNodes[1].firstChild.classList.contains("tab") && activeTab.childNodes[1].firstChild.classList.contains("will_be_closed") == false) NewActiveId = activeTab.childNodes[1].firstChild.id; + } + if (NewActiveId == undefined) { + while (NewActiveId == undefined && Node.nextSibling != null && Node.classList != undefined) { + if ((Node.nextSibling.classList.contains("pin") || Node.nextSibling.classList.contains("tab")) && Node.nextSibling.classList.contains("will_be_closed") == false) NewActiveId = Node.nextSibling.id; + Node = Node.nextSibling; + } + } + if (NewActiveId == undefined) { + while (NewActiveId == undefined && Node.previousSibling != null && Node.classList != undefined) { + if ((Node.previousSibling.classList.contains("pin") || Node.previousSibling.classList.contains("tab")) && Node.previousSibling.classList.contains("will_be_closed") == false) NewActiveId = Node.previousSibling.id; + Node = Node.previousSibling; + } + } + if (NewActiveId == undefined) {Tabs_ActivatePrevTab();} + if (NewActiveId != undefined) { + let tabId = parseInt(NewActiveId); + if (isNaN(tabId) == false) chrome.tabs.update(tabId, {active: true}); + } } -function ActivatePrevTab(allow_reverse) { - let activePin = document.querySelector(".pin.active_tab"); - if (activePin != null) { - if (activePin.previousSibling != null) { - chrome.tabs.update(parseInt(activePin.previousSibling.id), { active: true }); - } else { - if (activePin.nextSibling != null && allow_reverse) { - chrome.tabs.update(parseInt(activePin.nextSibling.id), { active: true }); - } - } - } - - let will_be_closed = document.querySelectorAll("#"+tt.active_group+" .will_be_closed"); - let activeTab = will_be_closed.length > 0 ? will_be_closed[0] : document.querySelector("#"+tt.active_group+" .tab.active_tab"); - - if (activeTab != null && document.querySelectorAll("#"+tt.active_group+" .tab").length > 1) { - let pSchildren = activeTab.previousSibling != null ? document.querySelectorAll("#ct"+activeTab.previousSibling.id+" .tab") : null; - if (activeTab.previousSibling != null && pSchildren.length > 0) { - chrome.tabs.update(parseInt(pSchildren[pSchildren.length-1].id), { active: true }); - } else { - if (activeTab.previousSibling != null) { - chrome.tabs.update(parseInt(activeTab.previousSibling.id), { active: true }); - } else { - if (activeTab.parentNode.parentNode.classList.contains("tab")) { - chrome.tabs.update(parseInt(activeTab.parentNode.parentNode.id), { active: true }); - } else { - if (allow_reverse) { - ActivateNextTab(); - } - } - } - } - } +function Tabs_ActivatePrevTabSameLevel() { + let activeTab = document.querySelector("#" + tt.active_group + " .tab.active_tab") != null ? document.querySelector("#" + tt.active_group + " .tab.active_tab") : document.querySelector(".pin.active_tab"); + if (activeTab == null) return; + let NewActiveId; + let Node = activeTab; + if (activeTab.classList.contains("tab")) { + if (opt.promote_children && activeTab.childNodes[1].firstChild != null && activeTab.childNodes[1].firstChild.classList.contains("tab") && activeTab.childNodes[1].firstChild.classList.contains("will_be_closed") == false) NewActiveId = activeTab.childNodes[1].firstChild.id; + } + if (NewActiveId == undefined) { + while (NewActiveId == undefined && Node.previousSibling != null && Node.classList != undefined) { + if ((Node.previousSibling.classList.contains("pin") || Node.previousSibling.classList.contains("tab")) && Node.previousSibling.classList.contains("will_be_closed") == false) NewActiveId = Node.previousSibling.id; + Node = Node.previousSibling; + } + } + if (NewActiveId == undefined) { + while (NewActiveId == undefined && Node.nextSibling != null && Node.classList != undefined) { + if ((Node.nextSibling.classList.contains("pin") || Node.nextSibling.classList.contains("tab")) && Node.nextSibling.classList.contains("will_be_closed") == false) NewActiveId = Node.nextSibling.id; + Node = Node.nextSibling; + } + } + if (NewActiveId == undefined) Tabs_ActivateNextTab(); + if (NewActiveId != undefined) { + let tabId = parseInt(NewActiveId); + if (isNaN(tabId) == false) chrome.tabs.update(tabId, {active: true}); + } } - -function OpenNewTab(pin, parentId) { - if (pin) { - chrome.tabs.create({pinned: true}, function(tab) { - if (parentId) { - AppendTab({tab: tab, ParentId: "pin_list", InsertAfterId: parentId, Append: true, Scroll: true}); - tt.schedule_update_data++; - } - }); - } else { - chrome.tabs.create({}, function(tab) { - if (parentId) { - AppendTab({tab: tab, ParentId: parentId, Append: (opt.append_orphan_tab == "top" ? false : true), Scroll: true}); - tt.schedule_update_data++; - } - if (opt.move_tabs_on_url_change == "from_empty") { - chrome.runtime.sendMessage({command: "remove_tab_from_empty_tabs", tabId: tab.id}); - } - }); - } +function Tabs_ActivateNextTab(allow_loop) { + let activeTab = document.querySelector("#" + tt.active_group + " .tab.active_tab") != null ? document.querySelector("#" + tt.active_group + " .tab.active_tab") : document.querySelector(".pin.active_tab"); + if (activeTab == null) return; + let NewActiveId; + let Node = activeTab; + let parents = DOM_GetAllParents(activeTab); + while (Node != null && Node.classList != undefined) { + if (parents.indexOf(Node) == -1 && Node != activeTab && (Node.classList.contains("pin") || Node.classList.contains("tab")) && Node.classList.contains("will_be_closed") == false) { + NewActiveId = Node.id; + Node = null; + } else { + if (parents.indexOf(Node) == -1 && Node.childNodes[1] && Node.childNodes[1].classList.contains("children") && Node.childNodes[1].childNodes.length > 0 && Node.classList.contains("c") == false) { // GO TO CHILDREN + Node = Node.childNodes[1].firstChild; + } else { + if (Node.nextSibling) { // GO TO NEXT SIBLING + Node = Node.nextSibling; + } else { // GO UP TO PARENT + Node = Node.parentNode.parentNode; + } + } + } + } + if (allow_loop && NewActiveId == undefined) { + let RestartLoopFromPin = document.querySelector(".pin"); + let RestartLoopFromTab = document.querySelector("#°" + tt.active_group + " .tab"); + if (activeTab.classList.contains("pin")) { + if (RestartLoopFromTab != null) { + NewActiveId = RestartLoopFromTab.id; + } else { + if (RestartLoopFromPin != null) NewActiveId = RestartLoopFromPin.id; + } + } + if (activeTab.classList.contains("tab")) { + if (RestartLoopFromPin != null) { + NewActiveId = RestartLoopFromPin.id; + } else { + if (RestartLoopFromTab != null) NewActiveId = RestartLoopFromTab.id; + } + } + } + if (NewActiveId != undefined) { + let tabId = parseInt(NewActiveId); + if (isNaN(tabId) == false) chrome.tabs.update(tabId, {active: true}); + } } -function DuplicateTab(SourceTabNode) { - chrome.tabs.duplicate(parseInt(SourceTabNode.id), function(tab) { - let DupRetry = setInterval(function() { - let DupTab = document.getElementById(tab.id); - if (DupTab != null) { - if (browserId == "F" && tab.pinned) { - DupTab.classList.remove("tab"); - DupTab.classList.add("pin"); - } - InsterAfterNode(DupTab, SourceTabNode); - RefreshExpandStates(); - tt.schedule_update_data++; - RefreshCounters(); - clearInterval(DupRetry); - } - }, 10); - setTimeout(function() { - if (DupRetry) { - clearInterval(DupRetry); - } - }, 500); - }); - -} - -function DeselectTabs() { - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - s.classList.remove("selected_tab"); - s.classList.remove("selected_last"); - }); -} - - -// TAB EVENTS - -function EventExpandBox(Node) { - if (Node.classList.contains("o")) { - Node.classList.remove("o"); - Node.classList.add("c"); - - if (Node.classList.contains("tab")) { - chrome.runtime.sendMessage({ command: "update_tab", tabId: parseInt(Node.id), tab: { expand: "c" } }); - } - - if (Node.classList.contains("folder")) { - SaveFolders(); - } - - } else { - if (Node.classList.contains("c")) { - if (opt.collapse_other_trees) { - let thisTreeTabs = GetParentsByClass(Node.childNodes[0], "tab"); // start from tab's first child, instead of tab, important to include clicked tab as well - let thisTreeFolders = GetParentsByClass(Node.childNodes[0], "folder"); - document.querySelectorAll("#"+tt.active_group+" .o.tab").forEach(function(s){ - s.classList.remove("o"); - s.classList.add("c"); - chrome.runtime.sendMessage({ command: "update_tab", tabId: parseInt(s.id), tab: { expand: "c" } }); - }); - - document.querySelectorAll("#"+tt.active_group+" .o.folder").forEach(function(s){ - s.classList.remove("o"); - s.classList.add("c"); - }); - thisTreeTabs.forEach(function(s){ - s.classList.remove("c"); - s.classList.add("o"); - chrome.runtime.sendMessage({ command: "update_tab", tabId: parseInt(s.id), tab: { expand: "o" } }); - }); - thisTreeFolders.forEach(function(s){ - s.classList.remove("c"); - s.classList.add("o"); - }); - SaveFolders(); - if (Node.classList.contains("tab")) { - ScrollToTab(Node.id); - } - } else { - Node.classList.remove("c"); - Node.classList.add("o"); - - if (Node.classList.contains("tab")) { - chrome.runtime.sendMessage({ command: "update_tab", tabId: parseInt(Node.id), tab: { expand: "o" } }); - } - - if (Node.classList.contains("folder")) { - SaveFolders(); - } - - } - } - } -} - -function EventSelectTab(event, TabNode) { - DeselectFolders(); - if (event.shiftKey) { // SET SELECTION WITH SHIFT - let activeTab = document.querySelector("#"+tt.active_group+" .selected_tab.selected_last"); - if (activeTab == null) { - activeTab = document.querySelector(".pin.active_tab, #"+tt.active_group+" .tab.active_tab"); - } - if (activeTab != null && TabNode.parentNode.id == activeTab.parentNode.id) { - - if (!event.ctrlKey) { - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - s.classList.remove("selected_frozen"); - s.classList.remove("selected_temporarly"); - s.classList.remove("selected_tab"); - s.classList.remove("selected_last"); - }); - } - let ChildrenArray = Array.from(TabNode.parentNode.children); - let activeTabIndex = ChildrenArray.indexOf(activeTab); - let thisTabIndex = ChildrenArray.indexOf(TabNode); - let fromIndex = thisTabIndex >= activeTabIndex ? activeTabIndex : thisTabIndex; - let toIndex = thisTabIndex >= activeTabIndex ? thisTabIndex : activeTabIndex; - for (let i = fromIndex; i <= toIndex; i++) { - activeTab.parentNode.childNodes[i].classList.add("selected_tab"); - if (i == toIndex && event.ctrlKey) { - activeTab.parentNode.childNodes[i].classList.add("selected_last"); - } - } - } - } - if (event.ctrlKey && !event.shiftKey) { // TOGGLE SELECTION WITH CTRL - TabNode.classList.toggle("selected_tab"); - if (TabNode.classList.contains("selected_tab")) { - document.querySelectorAll(".selected_last").forEach(function(s){ - s.classList.remove("selected_last"); - }); - TabNode.classList.add("selected_last"); - } else { - TabNode.classList.remove("selected_last"); - } - } -} - -function ActionClickTab(TabNode, bgOption) { - if (bgOption == "new_tab") { - OpenNewTab(TabNode.classList.contains("pin"), TabNode.id); - } - if (bgOption == "expand_collapse") { - EventExpandBox(TabNode); - } - if (bgOption == "close_tab") { - if ((TabNode.classList.contains("pin") && opt.allow_pin_close) || TabNode.classList.contains("tab")) { - CloseTabs([parseInt(TabNode.id)]); - } - } - if (bgOption == "undo_close_tab") { - chrome.sessions.getRecentlyClosed( null, function(sessions) { - if (sessions.length > 0) { - chrome.sessions.restore(null, function(restored) {}); - } - }); - } - if (bgOption == "reload_tab") { - chrome.tabs.reload(parseInt(TabNode.id)); - } - if (bgOption == "unload_tab") { - if (TabNode.classList.contains("active_tab")) { - SwitchActiveTabBeforeClose(tt.active_group); - setTimeout(function() { - DiscardTabs([parseInt(TabNode.id)]); - }, 500); - } else { - DiscardTabs([parseInt(TabNode.id)]); - } - } - if (bgOption == "activate_previous_active" && TabNode.classList.contains("active_tab")) { - chrome.tabs.update(parseInt(tt.groups[tt.active_group].prev_active_tab), {active: true}); - } -} - - - - - -function TabStartDrag(Node, event) { - event.stopPropagation(); - event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0); - event.dataTransfer.setData("text", ""); - event.dataTransfer.setData("SourceWindowId", tt.CurrentWindowId); - - CleanUpDragClasses(); - EmptyDragAndDrop(); - - tt.DragNodeClass = "tab"; - - let TabsIds = []; - let TabsIdsParents = []; - let TabsIdsSelected = []; - - if (Node.classList.contains("selected_tab")) { - document.querySelectorAll(".group:not(#"+tt.active_group+") .selected_tab").forEach(function(s){ - s.classList.add("selected_frozen"); - s.classList.remove("selected_tab"); - s.classList.remove("selected_last"); - }); - document.querySelectorAll("#pin_list .selected_tab, .group#"+tt.active_group+" .selected_tab").forEach(function(s){ - TabsIdsSelected.push(parseInt(s.id)); - }); - } else { - FreezeSelected(); - Node.classList.add("selected_temporarly"); - Node.classList.add("selected_tab"); - TabsIdsSelected.push(parseInt(Node.id)); - event.dataTransfer.setData("DraggedTabNode", Node.id); - } - - document.querySelectorAll("[id='"+Node.id+"'], [id='"+Node.id+"'] .tab").forEach(function(s){ - s.classList.add("dragged_tree"); - }); - - - if (opt.max_tree_drag_drop || opt.max_tree_depth >= 0) { - document.querySelectorAll(".dragged_tree .tab").forEach(function(s){ - let parents = GetParentsByClass(s.parentNode, "dragged_tree"); - if (parents.length > tt.DragTreeDepth) { - tt.DragTreeDepth = parents.length; - } - }); - } else { - tt.DragTreeDepth = -1; - } - - // REST OF SELECTED TABS THAT WILL BE DRAGGED - document.querySelectorAll(".selected_tab, .selected_tab .tab").forEach(function(s){ - s.classList.add("dragged_tree"); - TabsIds.push(parseInt(s.id)); - TabsIdsParents.push(s.parentNode.id); - }); - - let DraggedFolderParents = GetParentsByClass(Node, "folder"); - DraggedFolderParents.forEach(function(s){ - s.classList.add("dragged_parents"); - }); - let DraggedParents = GetParentsByClass(Node, "tab"); - DraggedParents.forEach(function(s){ - s.classList.add("dragged_parents"); - }); - - - DragAndDropData = {TabsIds: TabsIds, TabsIdsParents: TabsIdsParents, TabsIdsSelected: TabsIdsSelected}; - - event.dataTransfer.setData("Class", "tab"); - - event.dataTransfer.setData("TabsIds", JSON.stringify(TabsIds)); - event.dataTransfer.setData("TabsIdsParents", JSON.stringify(TabsIdsParents)); - event.dataTransfer.setData("TabsIdsSelected", JSON.stringify(TabsIdsSelected)); - - chrome.runtime.sendMessage({ - command: "drag_drop", - DragNodeClass: "tab", - DragTreeDepth: tt.DragTreeDepth - }); - - if (opt.debug) { - log("f: TabStartDrag, Node: "+Node.id+", TabsIdsSelected: "+JSON.stringify(TabsIdsSelected)+", TabsIds: "+JSON.stringify(TabsIds)+", TabsIdsParents: "+JSON.stringify(TabsIdsParents) ); - } - -} - -function TabDragOver(Node, event) { - if (tt.DragNodeClass == "tab" && Node.parentNode.classList.contains("dragged_tree") == false) { - - if (Node.parentNode.classList.contains("pin")) { - if (Node.parentNode.classList.contains("before") == false && event.layerX < Node.clientWidth/2) { - RemoveHighlight(); - Node.parentNode.classList.remove("after"); - Node.parentNode.classList.add("before"); - Node.parentNode.classList.add("highlighted_drop_target"); - } - if (Node.parentNode.classList.contains("after") == false && event.layerX >= Node.clientWidth/2) { - RemoveHighlight(); - Node.parentNode.classList.remove("before"); - Node.parentNode.classList.add("after"); - Node.parentNode.classList.add("highlighted_drop_target"); - } - } - - if (Node.parentNode.classList.contains("tab")) { - let PDepth = (GetParentsByClass(Node, "tab")).length + tt.DragTreeDepth; - let PIsGroup = Node.parentNode.parentNode.parentNode.classList.contains("group"); - let PIsDraggedParents = Node.parentNode.classList.contains("dragged_parents"); - - if (Node.parentNode.classList.contains("before") == false && event.layerY < Node.clientHeight/3 && (PDepth <= opt.max_tree_depth+1 || opt.max_tree_depth < 0 || PIsGroup || PIsDraggedParents || opt.max_tree_drag_drop == false)) { - RemoveHighlight(); - Node.parentNode.classList.remove("inside"); - Node.parentNode.classList.remove("after"); - Node.parentNode.classList.add("before"); - Node.parentNode.classList.add("highlighted_drop_target"); - } - - - if (Node.parentNode.classList.contains("inside") == false && event.layerY > Node.clientHeight/3 && event.layerY <= 2*(Node.clientHeight/3) && (PDepth <= opt.max_tree_depth || opt.max_tree_depth < 0 || PIsDraggedParents || opt.max_tree_drag_drop == false)) { - RemoveHighlight(); - Node.parentNode.classList.remove("before"); - Node.parentNode.classList.remove("after"); - Node.parentNode.classList.add("inside"); - Node.parentNode.classList.add("highlighted_drop_target"); - } - - - if (Node.parentNode.classList.contains("after") == false && Node.parentNode.classList.contains("o") == false && event.layerY > 2*(Node.clientHeight/3) && (PDepth <= opt.max_tree_depth+1 || opt.max_tree_depth < 0 || PIsGroup || PIsDraggedParents || opt.max_tree_drag_drop == false)) { - RemoveHighlight(); - Node.parentNode.classList.remove("inside"); - Node.parentNode.classList.remove("before"); - Node.parentNode.classList.add("after"); - Node.parentNode.classList.add("highlighted_drop_target"); - } - } - } +function Tabs_ActivatePrevTab(allow_loop) { + let activeTab = document.querySelector("#" + tt.active_group + " .tab.active_tab") != null ? document.querySelector("#" + tt.active_group + " .tab.active_tab") : document.querySelector(".pin.active_tab"); + if (activeTab == null) return; + let NewActiveId; + let Node = activeTab; + while (Node != null && Node.classList != undefined) { + if (Node != activeTab && (Node.classList.contains("pin") || Node.classList.contains("tab")) && Node.classList.contains("will_be_closed") == false) { + NewActiveId = Node.id; + Node = null; + } else { + if (Node.previousSibling) { // GO TO PREV SIBLING + Node = Node.previousSibling; + while (Node != null && Node.classList != undefined && Node.childNodes[1] && Node.childNodes[1].classList.contains("children") && Node.childNodes[1].childNodes.length > 0 && Node.classList.contains("c") == false) { + Node = Node.childNodes[1].lastChild; + } + } else { // GO UP TO PARENT + Node = Node.parentNode.parentNode; + } + } + } + if (allow_loop && NewActiveId == undefined) { + let RestartLoopFromPin = document.querySelector(".pin:last-child"); + let RestartLoopFromTab = document.querySelectorAll("#°" + tt.active_group + " .tab"); + if (activeTab.classList.contains("pin")) { + if (RestartLoopFromTab.length > 0) { + NewActiveId = RestartLoopFromTab[RestartLoopFromTab.length - 1].id; + } else { + if (RestartLoopFromPin != null) NewActiveId = RestartLoopFromPin.id; + } + } + if (activeTab.classList.contains("tab")) { + if (RestartLoopFromPin != null) { + NewActiveId = RestartLoopFromPin.id; + } else { + if (RestartLoopFromTab != null) NewActiveId = RestartLoopFromTab[RestartLoopFromTab.length - 1].id; + } + } + } + if (NewActiveId != undefined) { + let tabId = parseInt(NewActiveId); + if (isNaN(tabId) == false) chrome.tabs.update(tabId, {active: true}); + } } \ No newline at end of file diff --git a/scripts/theme.js b/scripts/theme.js index 8f87f2a..1dfe7a1 100644 --- a/scripts/theme.js +++ b/scripts/theme.js @@ -1,415 +1,283 @@ -// 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 Loadi18n() { - // toolbar labels - document.querySelectorAll(".button, .manager_window_toolbar_button").forEach(function(s){ - s.title = chrome.i18n.getMessage(s.id); - }); - // menu labels and edit group dialog labels - document.querySelectorAll(".menu_item, .edit_dialog_button, #manager_window_header_title, .manager_window_label").forEach(function(s){ - s.textContent = chrome.i18n.getMessage(s.id); - }); +function Theme_RestorePinListRowSettings() { + plist = document.getElementById("pin_list"); + if (opt.pin_list_multi_row) { + plist.style.whiteSpace = "normal"; + plist.style.overflowX = "hidden"; + } else { + plist.style.whiteSpace = ""; + plist.style.overflowX = ""; + } + DOM_RefreshGUI(); } -function RestorePinListRowSettings() { - plist = document.getElementById("pin_list"); - if (opt.pin_list_multi_row) { - plist.style.whiteSpace = "normal"; - plist.style.overflowX = "hidden"; - } else { - plist.style.whiteSpace = ""; - plist.style.overflowX = ""; - } - RefreshGUI(); -} - -function ApplyTheme(theme) { - RestoreStateOfGroupsToolbar(); - ApplySizeSet(theme["TabsSizeSetNumber"]); - ApplyColorsSet(theme["ColorsSet"]); - ApplyTabsMargins(theme["TabsMargins"]); - RefreshGUI(); - - for (var groupId in tt.groups) { - let groupTitle = document.getElementById("_gte"+groupId); - if (groupTitle != null && tt.groups[groupId].font == "") { - groupTitle.style.color = ""; - } - } - Loadi18n(); +function Theme_ApplyTheme(theme) { + Groups_RestoreStateOfGroupsToolbar(); + Theme_ApplySizeSet(theme["TabsSizeSetNumber"]); + Theme_ApplyColorsSet(theme["ColorsSet"]); + Theme_ApplyTabsMargins(theme["TabsMargins"]); + Theme_ApplyBlinking(); + DOM_RefreshGUI(); + // for some reason (top) text position is different in chromium !? + // if (browserId != "F") { + // document.styleSheets[document.styleSheets.length-1].insertRule(".tab_title, .folder_title { margin-top: 1px; }", document.styleSheets[document.styleSheets.length-1].cssRules.length); + // } + for (var groupId in tt.groups) { + let groupTitle = document.getElementById("_gte" + groupId); + if (groupTitle != null && tt.groups[groupId].font == "") groupTitle.style.color = ""; + } + DOM_Loadi18n(); } // theme colors is an object with css variables (but without --), for example; {"button_background": "#f2f2f2", "filter_box_border": "#cccccc"} -function ApplyColorsSet(ThemeColors){ - let css_variables = ""; - for (let css_variable in ThemeColors) { - css_variables = css_variables + "--" + css_variable + ":" + ThemeColors[css_variable] + ";"; - } - for (let si = 0; si < document.styleSheets.length; si++) { - if (document.styleSheets[si].ownerNode.id == "theme_colors") { - document.styleSheets[si].deleteRule(document.styleSheets[si].cssRules.length-1); - document.styleSheets[si].insertRule("body { "+css_variables+" }", document.styleSheets[si].cssRules.length); - } - } +function Theme_ApplyColorsSet(ThemeColors) { + let css_variables = ""; + for (let css_variable in ThemeColors) { + css_variables = css_variables + "--" + css_variable + ":" + ThemeColors[css_variable] + ";"; + } + for (let si = 0; si < document.styleSheets.length; si++) { + if (document.styleSheets[si].ownerNode.id == "theme_colors") { + document.styleSheets[si].deleteRule(document.styleSheets[si].cssRules.length - 1); + document.styleSheets[si].insertRule("body { " + css_variables + " }", document.styleSheets[si].cssRules.length); + } + } } -function ApplySizeSet(size){ - for (let si = 0; si < document.styleSheets.length; si++) { - if ((document.styleSheets[si].ownerNode.id).match("sizes_preset") != null) { - if (document.styleSheets[si].ownerNode.id == "sizes_preset_"+size) { - document.styleSheets.item(si).disabled = false; - } else { - document.styleSheets.item(si).disabled = true; - } - } - } - if (browserId == "F") { - // for some reason top position for various things is different in firefox????? - if (size > 1) { - document.styleSheets[document.styleSheets.length-1].insertRule(".tab_header>.tab_title { margin-top: -1px; }", document.styleSheets[document.styleSheets.length-1].cssRules.length); - } else { - document.styleSheets[document.styleSheets.length-1].insertRule(".tab_header>.tab_title { margin-top: 0px; }", document.styleSheets[document.styleSheets.length-1].cssRules.length); - } - } +function Theme_ApplySizeSet(size) { + for (let si = 0; si < document.styleSheets.length; si++) { + if ((document.styleSheets[si].ownerNode.id).match("sizes_preset") != null) { + if (document.styleSheets[si].ownerNode.id == "sizes_preset_" + size) { + document.styleSheets.item(si).disabled = false; + } else { + document.styleSheets.item(si).disabled = true; + } + } + } } -function ApplyTabsMargins(size){ - for (let si = 0; si < document.styleSheets.length; si++) { - if ((document.styleSheets[si].ownerNode.id).match("tabs_margin") != null) { - if (document.styleSheets[si].ownerNode.id == "tabs_margin_"+size) { - document.styleSheets.item(si).disabled = false; - } else { - document.styleSheets.item(si).disabled = true; - } - } - } +function Theme_ApplyTabsMargins(size) { + for (let si = 0; si < document.styleSheets.length; si++) { + if ((document.styleSheets[si].ownerNode.id).match("tabs_margin") != null) { + if (document.styleSheets[si].ownerNode.id == "tabs_margin_" + size) { + document.styleSheets.item(si).disabled = false; + } else { + document.styleSheets.item(si).disabled = true; + } + } + } } -function GetCurrentToolbar(storage) { - if (storage["toolbar"]) { - return storage["toolbar"]; - } else { - return DefaultToolbar; - } +function Theme_ApplyBlinking() { + for (let si = 0; si < document.styleSheets.length; si++) { + if ((document.styleSheets[si].ownerNode.id).match("blinking_pins") != null) { + if (opt.pin_attention_blinking) { + document.styleSheets.item(si).disabled = false; + } else { + document.styleSheets.item(si).disabled = true; + } + } + if ((document.styleSheets[si].ownerNode.id).match("blinking_audio") != null) { + if (opt.audio_blinking) { + document.styleSheets.item(si).disabled = false; + } else { + document.styleSheets.item(si).disabled = true; + } + } + } } +function Theme_GetCurrentToolbar(storage) { + if (storage["toolbar"]) { + return storage["toolbar"]; + } else { + return DefaultToolbar; + } +} -function GetCurrentTheme(storage) { - if (storage["current_theme"] && storage["themes"] && storage["themes"][storage["current_theme"]]) { - let theme = storage["themes"][storage["current_theme"]]; - let correctedTheme = CheckTheme(theme); - if (correctedTheme.theme_version < 4 && storage["preferences"].show_toolbar == undefined) { - opt.show_toolbar = correctedTheme.ToolbarShow; - SavePreferences(); - } - return correctedTheme; - } else { - return DefaultTheme; - } +function Theme_GetCurrentTheme(storage) { + if (storage["current_theme"] && storage["themes"] && storage["themes"][storage["current_theme"]]) { + let theme = storage["themes"][storage["current_theme"]]; + let correctedTheme = Theme_CheckTheme(theme); + if (correctedTheme.theme_version < 4 && storage["preferences"].show_toolbar == undefined) { + opt.show_toolbar = correctedTheme.ToolbarShow; + Preferences_SavePreferences(opt); + } + return correctedTheme; + } else { + return DefaultTheme; + } } // OPTIONS PAGE -function LoadTheme(ThemeId, reloadInSidebar) { - - document.querySelectorAll(".theme_buttons").forEach(function(s){ - s.disabled = true; - }); - - chrome.storage.local.set({current_theme: ThemeId}, function() { - chrome.storage.local.get(null, function(storage) { - SelectedTheme = Object.assign({}, GetCurrentTheme(storage)); - setTimeout(function() { - document.getElementById("new_theme_name").value = SelectedTheme.theme_name; - setTimeout(function() { - // SetToolbarEvents(true, false, false, ""); - RemoveToolbarEditEvents(); - - ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]); - ApplyColorsSet(SelectedTheme["ColorsSet"]); - document.getElementById("_gtetab_list").style.color = ""; - document.getElementById("_gtetab_list2").style.color = ""; - - if (SelectedTheme["TabsMargins"]) { - document.getElementById("tabs_margin_spacing")[SelectedTheme["TabsMargins"]].checked = true; - ApplyTabsMargins(SelectedTheme["TabsMargins"]); - } else { - document.getElementById("tabs_margin_spacing")["2"].checked = true; - } - - if (reloadInSidebar) { - chrome.runtime.sendMessage({command: "reload_theme", ThemeId: ThemeId, theme: SelectedTheme}); - } - - document.querySelectorAll(".theme_buttons").forEach(function(s){ - s.disabled = false; - }); - - }, 200); - }, 200); - }); - }); +function Theme_LoadTheme(ThemeId, reloadInSidebar) { + let query = document.querySelectorAll(".theme_buttons"); + for (let s of query) { + s.disabled = true; + } + chrome.storage.local.set({current_theme: ThemeId}, function() { + chrome.storage.local.get(null, function(storage) { + SelectedTheme = Object.assign({}, Theme_GetCurrentTheme(storage)); + setTimeout(function() { + document.getElementById("new_theme_name").value = SelectedTheme.theme_name; + setTimeout(function() { + RemoveToolbarEditEvents(); + Theme_ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]); + Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]); + document.getElementById("_gtetab_list").style.color = ""; + document.getElementById("_gtetab_list2").style.color = ""; + if (SelectedTheme["TabsMargins"]) { + document.getElementById("tabs_margin_spacing")[SelectedTheme["TabsMargins"]].checked = true; + Theme_ApplyTabsMargins(SelectedTheme["TabsMargins"]); + } else { + document.getElementById("tabs_margin_spacing")["2"].checked = true; + } + if (reloadInSidebar) chrome.runtime.sendMessage({command: "reload_theme", ThemeId: ThemeId, theme: SelectedTheme}); + let query = document.querySelectorAll(".theme_buttons"); + for (let s of query) { + s.disabled = false; + } + }, 200); + }, 200); + }); + }); } -function SaveTheme(ThemeId) { - chrome.storage.local.get(null, function(storage) { - - SelectedTheme.theme_version = DefaultTheme.theme_version; - - let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {}; - - LSthemes[ThemeId] = Object.assign({}, SelectedTheme); - - chrome.storage.local.set({themes: LSthemes}); - - chrome.runtime.sendMessage({command: "reload_theme", ThemeId: ThemeId, theme: SelectedTheme}); - return SelectedTheme; - }); +function Theme_SaveTheme(ThemeId) { + chrome.storage.local.get(null, function(storage) { + SelectedTheme.theme_version = DefaultTheme.theme_version; + let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {}; + LSthemes[ThemeId] = Object.assign({}, SelectedTheme); + chrome.storage.local.set({themes: LSthemes}); + chrome.runtime.sendMessage({command: "reload_theme", ThemeId: ThemeId, theme: SelectedTheme}); + return SelectedTheme; + }); } -function AddNewTheme() { - - let ThemeId = GenerateRandomID() + GenerateRandomID(); - let ThemeList = document.getElementById("theme_list"); - let ThemeNameBox = document.getElementById("new_theme_name"); - let NewName = ThemeNameBox.value; - - if (ThemeNameBox.value == "") { - alert(chrome.i18n.getMessage("options_theme_name_cannot_be_empty")); - return; - } - - SelectedTheme = Object.assign({}, DefaultTheme); - SelectedTheme["ColorsSet"] = {}; - - // let Names = []; - - // for (let i = 0; i < ThemeList.options.length; i++) { - // Names.push(ThemeList.options[i].text); - // } - - // while (Names.indexOf(NewName) != -1) { - // let matched = NewName.match(/\(\d+\)+/); - // if (matched != null && matched.length > 0) { - // NewName = NewName.replace(matched[0], ("(" + (parseInt(matched[0].match(/\d+/)[0]) + 1 ) + ")") ); - // } else { - // NewName = NewName + "(1)"; - // } - // } - - ThemeNameBox.value = NewName; - SelectedTheme["theme_name"] = NewName; - - themes.push(ThemeId); - - let ThemeNameOption = document.createElement("option"); - - ThemeNameOption.value = ThemeId; - ThemeNameOption.text = NewName; - - ThemeList.add(ThemeNameOption); - ThemeList.selectedIndex = ThemeList.options.length-1; - - SaveTheme(ThemeId); - setTimeout(function() { - LoadTheme(ThemeId, true); - }, 50); - - chrome.storage.local.set({current_theme: ThemeId}); - RefreshFields(); +function Theme_AddNewTheme() { + let ThemeId = GenerateRandomID() + GenerateRandomID(); + let ThemeList = document.getElementById("theme_list"); + let ThemeNameBox = document.getElementById("new_theme_name"); + let NewName = ThemeNameBox.value; + if (ThemeNameBox.value == "") { + alert(chrome.i18n.getMessage("options_theme_name_cannot_be_empty")); + return; + } + SelectedTheme = Object.assign({}, DefaultTheme); + SelectedTheme["ColorsSet"] = {}; + ThemeNameBox.value = NewName; + SelectedTheme["theme_name"] = NewName; + themes.push(ThemeId); + DOM_New("option", ThemeList, {value: ThemeId, text: NewName}); + ThemeList.selectedIndex = ThemeList.options.length - 1; + Theme_SaveTheme(ThemeId); + setTimeout(function() {Theme_LoadTheme(ThemeId, true);}, 50); + chrome.storage.local.set({current_theme: ThemeId}); + RefreshFields(); } -function DeleteSelectedTheme() { - chrome.storage.local.get(null, function(storage) { - let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {}; - - let ThemeList = document.getElementById("theme_list"); - - themes.splice(ThemeList.selectedIndex, 1); - if (LSthemes[current_theme]) { - delete LSthemes[current_theme]; - } - chrome.storage.local.set({themes: LSthemes}); - - ThemeList.remove(ThemeList.selectedIndex); - - current_theme = (ThemeList.options.length > 0) ? ThemeList.value : "default"; - - - chrome.storage.local.set({current_theme: current_theme}); - - if (ThemeList.options.length == 0) { - current_theme = ""; - SelectedTheme = Object.assign({}, DefaultTheme); - SelectedTheme["ColorsSet"] = {}; - chrome.storage.local.set({themes: {}}); - setTimeout(function() { - chrome.runtime.sendMessage({command: "reload_theme", themeName: "", theme: SelectedTheme}); - }, 500); - } - LoadTheme(current_theme, true); - RefreshFields(); - }); +function Theme_DeleteSelectedTheme() { + chrome.storage.local.get(null, function(storage) { + let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {}; + let ThemeList = document.getElementById("theme_list"); + themes.splice(ThemeList.selectedIndex, 1); + if (LSthemes[current_theme]) delete LSthemes[current_theme]; + chrome.storage.local.set({themes: LSthemes}); + ThemeList.remove(ThemeList.selectedIndex); + current_theme = (ThemeList.options.length > 0) ? ThemeList.value : "default"; + chrome.storage.local.set({current_theme: current_theme}); + if (ThemeList.options.length == 0) { + current_theme = ""; + SelectedTheme = Object.assign({}, DefaultTheme); + SelectedTheme["ColorsSet"] = {}; + chrome.storage.local.set({themes: {}}); + setTimeout(function() {chrome.runtime.sendMessage({command: "reload_theme", themeName: "", theme: SelectedTheme});}, 500); + } + Theme_LoadTheme(current_theme, true); + RefreshFields(); + }); } -function RenameSelectedTheme() { - let ThemeList = document.getElementById("theme_list"); - let ThemeNameBox = document.getElementById("new_theme_name"); - - // for (let i = 0; i < ThemeList.options.length; i++) { - // if (ThemeNameBox.value == ThemeList.options[i].text){ - // alert(chrome.i18n.getMessage("options_there_is_a_theme_with_this_name")); - // return; - // } - // } - - if (ThemeNameBox.value == "") { - alert(chrome.i18n.getMessage("options_theme_name_cannot_be_empty")); - return; - } - - - chrome.storage.local.get(null, function(storage) { - let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {}; - ThemeList.options[ThemeList.selectedIndex].text = ThemeNameBox.value; - SelectedTheme["theme_name"] = ThemeNameBox.value; - LSthemes[current_theme]["theme_name"] = ThemeNameBox.value; - chrome.storage.local.set({themes: LSthemes}); - chrome.storage.local.set({current_theme: current_theme}); - }); +function Theme_RenameSelectedTheme() { + let ThemeList = document.getElementById("theme_list"); + let ThemeNameBox = document.getElementById("new_theme_name"); + if (ThemeNameBox.value == "") { + alert(chrome.i18n.getMessage("options_theme_name_cannot_be_empty")); + return; + } + chrome.storage.local.get(null, function(storage) { + let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {}; + ThemeList.options[ThemeList.selectedIndex].text = ThemeNameBox.value; + SelectedTheme["theme_name"] = ThemeNameBox.value; + LSthemes[current_theme]["theme_name"] = ThemeNameBox.value; + chrome.storage.local.set({themes: LSthemes}); + chrome.storage.local.set({current_theme: current_theme}); + }); } - - -function CheckTheme(theme) { - if (theme.theme_version < 2) { - theme["ColorsSet"]["scrollbar_height"] = theme.ScrollbarPinList + "px"; - theme["ColorsSet"]["scrollbar_width"] = theme.ScrollbarTabList + "px"; - } - if (theme["TabsMargins"] == undefined) { - theme["TabsMargins"] = "2"; - } - if (theme.theme_version < 4) { - delete theme["ColorsSet"]["active_font_weight"]; - delete theme["ColorsSet"]["expand_lines"]; - delete theme["ColorsSet"]["expand_open_border"]; - delete theme["ColorsSet"]["expand_closed_border"]; - - if (theme["ColorsSet"]["toolbar_background"]) { - theme["ColorsSet"]["toolbar_shelf_background"] = theme["ColorsSet"]["toolbar_background"]; - theme["ColorsSet"]["button_on_background"] = theme["ColorsSet"]["toolbar_background"]; - } - if (theme["ColorsSet"]["button_icons"]) { - theme["ColorsSet"]["button_on_icons"] = theme["ColorsSet"]["button_icons"]; - theme["ColorsSet"]["button_shelf_icons"] = theme["ColorsSet"]["button_icons"]; - } - if (theme["ColorsSet"]["button_background"]) { - theme["ColorsSet"]["button_shelf_background"] = theme["ColorsSet"]["button_background"]; - } - if (theme["ColorsSet"]["button_hover_background"]) { - theme["ColorsSet"]["button_shelf_hover_background"] = theme["ColorsSet"]["button_hover_background"]; - } - if (theme["ColorsSet"]["button_border"]) { - theme["ColorsSet"]["button_shelf_border"] = theme["ColorsSet"]["button_border"]; - } - if (theme["ColorsSet"]["button_hover_border"]) { - theme["ColorsSet"]["button_shelf_hover_border"] = theme["ColorsSet"]["button_hover_border"]; - } - if (theme["ColorsSet"]["button_icons_hover"]) { - theme["ColorsSet"]["button_shelf_icons_hover"] = theme["ColorsSet"]["button_icons_hover"]; - } - - if (theme["ColorsSet"]["expand_hover_background"]) { - theme["ColorsSet"]["folder_icon_hover"] = theme["ColorsSet"]["expand_hover_background"]; - } - if (theme["ColorsSet"]["expand_closed_background"]) { - theme["ColorsSet"]["folder_icon_closed"] = theme["ColorsSet"]["expand_closed_background"]; - } - if (theme["ColorsSet"]["expand_open_background"]) { - theme["ColorsSet"]["folder_icon_open"] = theme["ColorsSet"]["expand_open_background"]; - } - } - - return theme; +function Theme_CheckTheme(theme) { + if (theme.theme_version < 2) { + theme["ColorsSet"]["scrollbar_height"] = theme.ScrollbarPinList + "px"; + theme["ColorsSet"]["scrollbar_width"] = theme.ScrollbarTabList + "px"; + } + if (theme["TabsMargins"] == undefined) theme["TabsMargins"] = "2"; + if (theme.theme_version < 4) { + delete theme["ColorsSet"]["active_font_weight"]; + delete theme["ColorsSet"]["expand_lines"]; + delete theme["ColorsSet"]["expand_open_border"]; + delete theme["ColorsSet"]["expand_closed_border"]; + if (theme["ColorsSet"]["toolbar_background"]) { + theme["ColorsSet"]["toolbar_shelf_background"] = theme["ColorsSet"]["toolbar_background"]; + theme["ColorsSet"]["button_on_background"] = theme["ColorsSet"]["toolbar_background"]; + } + if (theme["ColorsSet"]["button_icons"]) { + theme["ColorsSet"]["button_on_icons"] = theme["ColorsSet"]["button_icons"]; + theme["ColorsSet"]["button_shelf_icons"] = theme["ColorsSet"]["button_icons"]; + } + if (theme["ColorsSet"]["button_background"]) theme["ColorsSet"]["button_shelf_background"] = theme["ColorsSet"]["button_background"]; + if (theme["ColorsSet"]["button_hover_background"]) theme["ColorsSet"]["button_shelf_hover_background"] = theme["ColorsSet"]["button_hover_background"]; + if (theme["ColorsSet"]["button_border"]) theme["ColorsSet"]["button_shelf_border"] = theme["ColorsSet"]["button_border"]; + if (theme["ColorsSet"]["button_hover_border"]) theme["ColorsSet"]["button_shelf_hover_border"] = theme["ColorsSet"]["button_hover_border"]; + if (theme["ColorsSet"]["button_icons_hover"]) theme["ColorsSet"]["button_shelf_icons_hover"] = theme["ColorsSet"]["button_icons_hover"]; + if (theme["ColorsSet"]["expand_hover_background"]) theme["ColorsSet"]["folder_icon_hover"] = theme["ColorsSet"]["expand_hover_background"]; + if (theme["ColorsSet"]["expand_closed_background"]) theme["ColorsSet"]["folder_icon_closed"] = theme["ColorsSet"]["expand_closed_background"]; + if (theme["ColorsSet"]["expand_open_background"]) theme["ColorsSet"]["folder_icon_open"] = theme["ColorsSet"]["expand_open_background"]; + } + return theme; } - - -function ImportTheme() { - var file = document.getElementById("file_import"); - var fr = new FileReader(); - if (file.files[0] == undefined) return; - fr.readAsText(file.files[0]); - fr.onload = function() { - var data = fr.result; - file.parentNode.removeChild(file); - - var themeObj = JSON.parse(data); - - if (themeObj.theme_version > DefaultTheme["theme_version"]) { - alert(chrome.i18n.getMessage("options_loaded_theme_newer_version")); - } - if (themeObj.theme_version < DefaultTheme["theme_version"]) { - alert(chrome.i18n.getMessage("options_loaded_theme_older_version")); - } - - if (themeObj.theme_version <= DefaultTheme["theme_version"]) { - let ThemeList = document.getElementById("theme_list"); - let ThemeId = GenerateRandomID() + GenerateRandomID(); - let correctedTheme = CheckTheme(themeObj); - - SelectedTheme = Object.assign({}, DefaultTheme); - - for (var val in correctedTheme.ColorsSet) { - SelectedTheme["ColorsSet"][val] = correctedTheme.ColorsSet[val]; - } - - SelectedTheme["TabsSizeSetNumber"] = correctedTheme.TabsSizeSetNumber; - SelectedTheme["TabsMargins"] = correctedTheme["TabsMargins"]; - SelectedTheme["theme_version"] = DefaultTheme["theme_version"]; - - // let Names = []; - // for (let i = 0; i < ThemeList.options.length; i++) { - // Names.push(ThemeList.options[i].text); - // } - - // if (Names.indexOf(correctedTheme.theme_name) == -1) { - SelectedTheme["theme_name"] = correctedTheme.theme_name; - // } else { - // let NewName = correctedTheme.theme_name; - // while (Names.indexOf(NewName) != -1) { - // let matched = NewName.match(/\(\d+\)+/); - // if (matched != null && matched.length > 0) { - // NewName = NewName.replace(matched[0], ("(" + (parseInt(matched[0].match(/\d+/)[0]) + 1 ) + ")") ); - // } else { - // NewName = NewName + "(1)"; - // } - // } - // SelectedTheme["theme_name"] = NewName; - // } - - themes.push(ThemeId); - SaveTheme(ThemeId); - - var theme_name = document.createElement("option"); - - theme_name.value = ThemeId; - theme_name.text = SelectedTheme["theme_name"]; - - ThemeList.add(theme_name); - ThemeList.selectedIndex = ThemeList.options.length-1; - - current_theme = ThemeId; - document.createElement("new_theme_name").value = ThemeId; - - setTimeout(function() { - LoadTheme(ThemeId, true); - }, 500); - RefreshFields(); - DefaultTheme["ColorsSet"] = {}; - chrome.storage.local.set({current_theme: ThemeId}); - } - } +function Theme_ImportTheme() { + var file = document.getElementById("file_import"); + var fr = new FileReader(); + if (file.files[0] == undefined) return; + fr.readAsText(file.files[0]); + fr.onload = function() { + var data = fr.result; + file.parentNode.removeChild(file); + var themeObj = JSON.parse(data); + if (themeObj.theme_version > DefaultTheme["theme_version"]) alert(chrome.i18n.getMessage("options_loaded_theme_newer_version")); + if (themeObj.theme_version < DefaultTheme["theme_version"]) alert(chrome.i18n.getMessage("options_loaded_theme_older_version")); + if (themeObj.theme_version <= DefaultTheme["theme_version"]) { + let ThemeList = document.getElementById("theme_list"); + let ThemeId = GenerateRandomID() + GenerateRandomID(); + let correctedTheme = Theme_CheckTheme(themeObj); + SelectedTheme = Object.assign({}, DefaultTheme); + for (var val in correctedTheme.ColorsSet) { + SelectedTheme["ColorsSet"][val] = correctedTheme.ColorsSet[val]; + } + SelectedTheme["TabsSizeSetNumber"] = correctedTheme.TabsSizeSetNumber; + SelectedTheme["TabsMargins"] = correctedTheme["TabsMargins"]; + SelectedTheme["theme_version"] = DefaultTheme["theme_version"]; + SelectedTheme["theme_name"] = correctedTheme.theme_name; + themes.push(ThemeId); + Theme_SaveTheme(ThemeId); + let theme_name = DOM_New("option", undefined, {value: ThemeId, text: SelectedTheme["theme_name"]}); + ThemeList.add(theme_name); + ThemeList.selectedIndex = ThemeList.options.length - 1; + current_theme = ThemeId; + document.createElement("new_theme_name").value = ThemeId; + setTimeout(function() {Theme_LoadTheme(ThemeId, true);}, 500); + RefreshFields(); + DefaultTheme["ColorsSet"] = {}; + chrome.storage.local.set({current_theme: ThemeId}); + } + } } \ No newline at end of file diff --git a/scripts/toolbar.js b/scripts/toolbar.js index d71c500..2e62ae1 100644 --- a/scripts/toolbar.js +++ b/scripts/toolbar.js @@ -1,708 +1,538 @@ -// 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/ - -// ********** TOOLBAR *************** - -// RESTORE LAST USED SEARCH TYPE (URL OR TITLE) IN TOOLBAR SEARCH -function RestoreToolbarSearchFilter() { - chrome.runtime.sendMessage({command: "get_search_filter", windowId: tt.CurrentWindowId}, function(response) { - let ButtonFilter = document.getElementById("button_filter_type"); - if (response == "url") { - ButtonFilter.classList.add("url"); - ButtonFilter.classList.remove("title"); - } else { - ButtonFilter.classList.add("title"); - ButtonFilter.classList.remove("url"); - } - }); -} - -// RESTORE LAST ACTIVE SHELF (SEARCH, TOOLS, GROUPS, SESSION OR FOLDER) IN TOOLBAR -function RestoreToolbarShelf() { - chrome.runtime.sendMessage({command: "get_active_shelf", windowId: tt.CurrentWindowId}, function(response) { - let filterBox = document.getElementById("filter_box"); - filterBox.setAttribute("placeholder", labels.searchbox); - filterBox.style.opacity = "1"; - - document.querySelectorAll(".on").forEach(function(s){ - s.classList.remove("on"); - }); - document.querySelectorAll(".toolbar_shelf").forEach(function(s){ - s.classList.add("hidden"); - }); - - if (response == "search" && document.getElementById("button_search") != null) { - document.getElementById("toolbar_search").classList.remove("hidden"); - document.getElementById("button_search").classList.add("on"); - } - - if (response == "tools" && document.getElementById("button_tools") != null) { - document.getElementById("toolbar_shelf_tools").classList.remove("hidden"); - document.getElementById("button_tools").classList.add("on"); - } - - if (response == "groups" && document.getElementById("button_groups") != null) { - document.getElementById("toolbar_shelf_groups").classList.remove("hidden"); - document.getElementById("button_groups").classList.add("on"); - } - - if (response == "backup" && document.getElementById("button_backup") != null) { - document.getElementById("toolbar_shelf_backup").classList.remove("hidden"); - document.getElementById("button_backup").classList.add("on"); - } - - if (response == "folders" && document.getElementById("button_folders") != null) { - document.getElementById("toolbar_shelf_folders").classList.remove("hidden"); - document.getElementById("button_folders").classList.add("on"); - } - - if (browserId != "F") { - chrome.storage.local.get(null, function(storage) { - let bak1 = storage["windows_BAK1"] ? storage["windows_BAK1"] : []; - let bak2 = storage["windows_BAK2"] ? storage["windows_BAK2"] : []; - let bak3 = storage["windows_BAK3"] ? storage["windows_BAK3"] : []; - - if (bak1.length && document.getElementById("#button_load_bak1") != null) { - document.getElementById("button_load_bak1").classList.remove("disabled"); - } else { - document.getElementById("button_load_bak1").classList.add("disabled"); - } - - if (bak2.length && document.getElementById("#button_load_bak2") != null) { - document.getElementById("button_load_bak2").classList.remove("disabled"); - } else { - document.getElementById("button_load_bak2").classList.add("disabled"); - } - - if (bak3.length && document.getElementById("#button_load_bak3") != null) { - document.getElementById("button_load_bak3").classList.remove("disabled"); - } else { - document.getElementById("button_load_bak3").classList.add("disabled"); - } - - }); - } - - RefreshGUI(); - }); +function Toolbar_RestoreToolbarSearchFilter() { // RESTORE LAST USED SEARCH TYPE (URL OR TITLE) IN TOOLBAR SEARCH + chrome.runtime.sendMessage({command: "get_search_filter", windowId: tt.CurrentWindowId}, function(response) { + if (response == "url") { + DOM_SetClasses(document.getElementById("button_filter_type"), ["url"], ["title"], []); + } else { + DOM_SetClasses(document.getElementById("button_filter_type"), ["title"], ["url"], []); + } + }); } -// FUNCTION TO TOGGLE SHELFS AND SAVE IT -function ShelfToggle(mousebutton, button, toolbarId, SendMessage) { - if (mousebutton == 1) { - if (button.classList.contains("on")) { - document.querySelectorAll(".on").forEach(function(s){ - s.classList.remove("on"); - }); - document.querySelectorAll(".toolbar_shelf").forEach(function(s){ - s.classList.add("hidden"); - }); - } else { - document.querySelectorAll(".toolbar_shelf:not(#"+toolbarId+")").forEach(function(s){ - s.classList.add("hidden"); - }); - document.getElementById(toolbarId).classList.remove("hidden"); - chrome.runtime.sendMessage({command: "set_active_shelf", active_shelf: SendMessage, windowId: tt.CurrentWindowId}); - document.querySelectorAll(".on:not(#"+button.id+")").forEach(function(s){ - s.classList.remove("on"); - }); - button.classList.add("on"); - } - RefreshGUI(); - } +function Toolbar_RestoreToolbarShelf() { // RESTORE LAST ACTIVE SHELF (SEARCH, TOOLS, GROUPS, SESSION OR FOLDER) IN TOOLBAR + chrome.runtime.sendMessage({command: "get_active_shelf", windowId: tt.CurrentWindowId}, function(response) { + let filterBox = document.getElementById("filter_box"); + filterBox.setAttribute("placeholder", labels.searchbox); + filterBox.style.opacity = "1"; + + let query = document.querySelectorAll(".on"); + for (let s of query) { + s.classList.remove("on"); + } + query = document.querySelectorAll(".toolbar_shelf"); + for (let s of query) { + s.classList.add("hidden"); + } + if (response == "search" && document.getElementById("button_search") != null) { + document.getElementById("toolbar_search").classList.remove("hidden"); + document.getElementById("button_search").classList.add("on"); + } + if (response == "tools" && document.getElementById("button_tools") != null) { + document.getElementById("toolbar_shelf_tools").classList.remove("hidden"); + document.getElementById("button_tools").classList.add("on"); + } + if (response == "groups" && document.getElementById("button_groups") != null) { + document.getElementById("toolbar_shelf_groups").classList.remove("hidden"); + document.getElementById("button_groups").classList.add("on"); + } + if (response == "backup" && document.getElementById("button_backup") != null) { + document.getElementById("toolbar_shelf_backup").classList.remove("hidden"); + document.getElementById("button_backup").classList.add("on"); + } + if (response == "folders" && document.getElementById("button_folders") != null) { + document.getElementById("toolbar_shelf_folders").classList.remove("hidden"); + document.getElementById("button_folders").classList.add("on"); + } + if (browserId != "F") { + chrome.storage.local.get(null, function(storage) { + let bak1 = storage["windows_BAK1"] ? storage["windows_BAK1"] : []; + let bak2 = storage["windows_BAK2"] ? storage["windows_BAK2"] : []; + let bak3 = storage["windows_BAK3"] ? storage["windows_BAK3"] : []; + if (bak1.length && document.getElementById("#button_load_bak1") != null) { + document.getElementById("button_load_bak1").classList.remove("disabled"); + } else { + document.getElementById("button_load_bak1").classList.add("disabled"); + } + if (bak2.length && document.getElementById("#button_load_bak2") != null) { + document.getElementById("button_load_bak2").classList.remove("disabled"); + } else { + document.getElementById("button_load_bak2").classList.add("disabled"); + } + if (bak3.length && document.getElementById("#button_load_bak3") != null) { + document.getElementById("button_load_bak3").classList.remove("disabled"); + } else { + document.getElementById("button_load_bak3").classList.add("disabled"); + } + }); + } + DOM_RefreshGUI(); + }); } -function RemoveToolbar() { - let toolbar = document.getElementById("toolbar"); - while(toolbar.hasChildNodes()) { - toolbar.removeChild(toolbar.firstChild); - } +function Toolbar_ShelfToggle(mousebutton, button, toolbarId, SendMessage, SidebarRefreshGUI, OptionsRefreshGUI) { // FUNCTION TO TOGGLE SHELFS AND SAVE IT + if (mousebutton == 1) { + if (button.classList.contains("on")) { + let query = document.querySelectorAll(".on"); + for (let s of query) { + s.classList.remove("on"); + } + query = document.querySelectorAll(".toolbar_shelf"); + for (let s of query) { + s.classList.add("hidden"); + } + chrome.runtime.sendMessage({command: "set_active_shelf", active_shelf: "", windowId: tt.CurrentWindowId}); + } else { + let query = document.querySelectorAll(".toolbar_shelf:not(#" + toolbarId + ")"); + for (let s of query) { + s.classList.add("hidden"); + } + document.getElementById(toolbarId).classList.remove("hidden"); + chrome.runtime.sendMessage({command: "set_active_shelf", active_shelf: SendMessage, windowId: tt.CurrentWindowId}); + query = document.querySelectorAll(".on:not(#" + button.id + ")"); + for (let s of query) { + s.classList.remove("on"); + } + button.classList.add("on"); + } + if (SidebarRefreshGUI) DOM_RefreshGUI(); + if (OptionsRefreshGUI) RefreshGUI(); + } } -function RecreateToolbar(NewToolbar) { - let toolbar = document.getElementById("toolbar"); - - for (var shelf in NewToolbar) { - let NewShelf = document.createElement("div"); - NewShelf.id = shelf; - NewShelf.classList = "toolbar_shelf"; - toolbar.appendChild(NewShelf); - - NewToolbar[shelf].forEach(function(button){ - let Newbutton = document.createElement("div"); - Newbutton.id = button; - Newbutton.classList = "button"; - - NewShelf.appendChild(Newbutton); - - let NewbuttonIMG = document.createElement("div"); - NewbuttonIMG.classList = "button_img"; - Newbutton.appendChild(NewbuttonIMG); - - }); - - } - - let toolbar_main = document.getElementById("toolbar_main"); - let SearchShelf = document.getElementById("toolbar_search"); - - if (toolbar_main != null && SearchShelf != null) { - toolbar_main.classList.remove("toolbar_shelf"); - - let SearchBox = document.createElement("div"); - SearchBox.id = "toolbar_search_input_box"; - SearchShelf.appendChild(SearchBox); - - let SearchInput = document.createElement("input"); - SearchInput.classList = "text_input"; - SearchInput.id = "filter_box"; - SearchInput.type = "text"; - SearchInput.placeholder = labels.searchbox; - SearchBox.appendChild(SearchInput); - - let ClearX = document.createElement("div"); - ClearX.id = "button_filter_clear"; - ClearX.type = "reset"; - ClearX.style.opacity = "0"; - ClearX.style.position = "absolute"; - SearchBox.appendChild(ClearX); - - let SearchButtons = document.createElement("div"); - SearchButtons.id = "toolbar_search_buttons"; - SearchShelf.appendChild(SearchButtons); - - let FilterType = document.getElementById("button_filter_type"); - SearchButtons.appendChild(FilterType); - - let GoPrev = document.getElementById("filter_search_go_prev"); - SearchButtons.appendChild(GoPrev); - - let GoNext = document.getElementById("filter_search_go_next"); - SearchButtons.appendChild(GoNext); - - Loadi18n(); - } - +function Toolbar_RemoveToolbar() { + let toolbar = document.getElementById("toolbar"); + while (toolbar.hasChildNodes()) { + toolbar.removeChild(toolbar.firstChild); + } } -function RecreateToolbarUnusedButtons(buttonsIds) { - let unused_buttons = document.getElementById("toolbar_unused_buttons"); - - buttonsIds.forEach(function(button){ - let Newbutton = document.createElement("div"); - Newbutton.id = button; - Newbutton.classList = "button"; - unused_buttons.appendChild(Newbutton); - let NewbuttonIMG = document.createElement("div"); - NewbuttonIMG.classList = "button_img"; - Newbutton.appendChild(NewbuttonIMG); - - }); +function Toolbar_RecreateToolbar(NewToolbar) { + let toolbar = document.getElementById("toolbar"); + for (var shelf in NewToolbar) { + let NewShelf = DOM_New("div", toolbar, {id: shelf, className: "toolbar_shelf"}); + for (let button of NewToolbar[shelf]) { + let Newbutton = DOM_New("div", NewShelf, {id: button, className: "button"}); + DOM_New("div", Newbutton, {className: "button_img"}); + } + } + let toolbar_main = document.getElementById("toolbar_main"); + let SearchShelf = document.getElementById("toolbar_search"); + if (toolbar_main != null && SearchShelf != null) { + toolbar_main.classList.remove("toolbar_shelf"); + let SearchBox = DOM_New("div", SearchShelf, {id: "toolbar_search_input_box"}); + DOM_New("input", SearchBox, {id: "filter_box", className: "text_input", type: "text", placeholder: labels.searchbox}); + DOM_New("div", SearchBox, {id: "button_filter_clear", type: "reset"}, {opacity: "0", position: "absolute"}); + let SearchButtons = DOM_New("div", SearchShelf, {id: "toolbar_search_buttons"}); + DOM_AppendToNode(document.getElementById("button_filter_type"), SearchButtons); + DOM_AppendToNode(document.getElementById("filter_search_go_prev"), SearchButtons); + DOM_AppendToNode(document.getElementById("filter_search_go_next"), SearchButtons); + DOM_Loadi18n(); + } } - - -function SaveToolbar() { - let unused_buttons = []; - let toolbar = {}; - - let u = document.querySelectorAll("#toolbar_unused_buttons .button"); - u.forEach(function(b){ - unused_buttons.push(b.id); - }); - - let t = document.getElementById("toolbar"); - t.childNodes.forEach(function(s){ - toolbar[s.id] = []; - let t = document.querySelectorAll("#"+s.id+" .button").forEach(function(b){ - toolbar[s.id].push(b.id); - }); - }); - - chrome.storage.local.set({toolbar: toolbar}); - chrome.storage.local.set({unused_buttons: unused_buttons}); - setTimeout(function() { - chrome.runtime.sendMessage({command: "reload_toolbar", toolbar: toolbar, opt: opt}); - }, 50); +function Toolbar_RecreateToolbarUnusedButtons(buttonsIds) { // OPTIONS PAGE + let unused_buttons = document.getElementById("toolbar_unused_buttons"); + for (let button of buttonsIds) { + let Newbutton = DOM_New("div", unused_buttons, {id: button, className: "button"}); + DOM_New("div", Newbutton, {className: "button_img"}); + } } +function Toolbar_SaveToolbar() { // OPTIONS PAGE + let unused_buttons = []; + let toolbar = {}; + let unused_buttons_div = document.querySelectorAll("#toolbar_unused_buttons .button"); + for (let b of unused_buttons_div) { + unused_buttons.push(b.id); + } + let toolbar_div = document.getElementById("toolbar"); + for (let toolbar_shelf of toolbar_div.childNodes) { + toolbar[toolbar_shelf.id] = []; + let query = document.querySelectorAll("#" + toolbar_shelf.id + " .button"); + for (let button of query) { + toolbar[toolbar_shelf.id].push(button.id); + } + } + chrome.storage.local.set({toolbar: toolbar}); + chrome.storage.local.set({unused_buttons: unused_buttons}); + setTimeout(function() {chrome.runtime.sendMessage({command: "reload_toolbar", toolbar: toolbar, opt: opt});}, 50); +} -// ASSIGN MOUSE EVENTS FOR TOOLBAR BUTTONS, (Buttons AND ToolbarShelfToggle), PARAMETERS DECIDE IF BUTTONS ARE CLICKABLE +// ASSIGN MOUSE EVENTS FOR TOOLBAR BUTTONS, (Buttons AND BindToolbarShelfToggleButtons), PARAMETERS DECIDE IF BUTTONS ARE CLICKABLE // IN OPTIONS PAGE - TOOLBAR BUTTONS SAMPLES, MUST NOT CALL FUNCTIONS ON CLICKS, BUT STILL SHELFS BUTTONS MUST TOGGLE AND MOREOVER ON CLICK AND NOT ON MOUSEDOWN THIS IS WHERE ToolbarShelfToggleClickType="Click" IS NECESSARY -function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, ToolbarShelfToggleClickType) { +function Toolbar_SetToolbarEvents(CleanPreviousBindings, BindButtons, BindToolbarShelfToggleButtons, ToolbarShelfToggleClickType, SidebarRefreshGUI, OptionsRefreshGUI) { - let ClearSearch = document.getElementById("button_filter_clear"); - let FilterBox = document.getElementById("filter_box"); - - if (ClearSearch != null && FilterBox != null) { - if (CleanPreviousBindings) { - FilterBox.removeEventListener("oninput", function(){}); - ClearSearch.removeEventListener("onmousedown", function(){}); - } - if (Buttons) { - // FILTER ON INPUT - FilterBox.oninput = function(event) { - FindTab(this.value); - } - // CLEAR FILTER BUTTON - ClearSearch.onmousedown = function(event) { - if (event.which == 1) { - this.style.opacity = "0"; - this.style.opacity = "0"; - this.setAttribute("title", ""); - FindTab(""); - } - } - } - } + let ClearSearch = document.getElementById("button_filter_clear"); + let FilterBox = document.getElementById("filter_box"); - document.querySelectorAll(".button").forEach(function(s){ - - if (CleanPreviousBindings) { - s.removeEventListener("onmousedown", function(){}); - s.removeEventListener("onclick", function(){}); - s.removeEventListener("click", function(){}); - } - - if (ToolbarShelfToggle) { - if (s.id == "button_search") { - s.addEventListener(ToolbarShelfToggleClickType, function(event) { - if (event.which == 1) { - ShelfToggle(event.which, this, "toolbar_search", "search"); - } - }); - } - if (s.id == "button_tools") { - s.addEventListener(ToolbarShelfToggleClickType, function(event) { - if (event.which == 1) { - ShelfToggle(event.which, this, "toolbar_shelf_tools", "tools"); - } - }); - } - if (s.id == "button_groups") { - s.addEventListener(ToolbarShelfToggleClickType, function(event) { - if (event.which == 1) { - ShelfToggle(event.which, this, "toolbar_shelf_groups", "groups"); - } - }); - } - if (s.id == "button_backup") { - s.addEventListener(ToolbarShelfToggleClickType, function(event) { - if (event.which == 1) { - ShelfToggle(event.which, this, "toolbar_shelf_backup", "backup"); - } - }); - } - if (s.id == "button_folders") { - s.addEventListener(ToolbarShelfToggleClickType, function(event) { - if (event.which == 1) { - ShelfToggle(event.which, this, "toolbar_shelf_folders", "folders"); - } - }); - } - } - - if (Buttons) { - // NEW TAB - if (s.id == "button_new") { - s.onclick = function(event) { - if (event.which == 1) { - if (opt.append_tab_from_toolbar == "group_root") { - OpenNewTab(false, tt.active_group); - } - if (opt.append_tab_from_toolbar == "as_regular_orphan") { - OpenNewTab(false, (document.querySelectorAll("#"+tt.active_group+" .tab").length == 0 ? tt.active_group : undefined)); - } - } - } - s.onmousedown = function(event) { - // DUPLICATE TAB - if (event.which == 2) { - event.preventDefault(); - let activeTab = document.querySelector("#"+tt.active_group+" .active_tab") != null ? document.querySelector("#"+tt.active_group+" .active_tab") : document.querySelector(".pin.active_tab") != null ? document.querySelector(".pin.active_tab") : null; - if (activeTab != null) { - DuplicateTab(activeTab); - } - } - // SCROLL TO TAB - if (event.which == 3) { - chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) { - if (activeTab[0].pinned && opt.pin_list_multi_row == false) { - ScrollToTab(activeTab[0].id); - } - if (activeTab[0].pinned == false) { - let Tab = document.getElementById(activeTab[0].id); - let groupId = GetParentsByClass(Tab, "group")[0].id; - SetActiveGroup(groupId, true, true); - } - }); - } - } - } - // PIN TAB - if (s.id == "button_pin") { - s.onmousedown = function(event) { - if (event.which == 1) { - let Tabs = document.querySelectorAll(".pin.active_tab, .pin.selected_tab, #"+tt.active_group+" .active_tab, #"+tt.active_group+" .selected_tab"); - Tabs.forEach(function(s){ - chrome.tabs.update(parseInt(s.id), { pinned: Tabs[0].classList.contains("tab") }); - }) - } - } - } - // VERTICAL TABS OPTIONS - if (s.id == "button_options") { - s.onmousedown = function(event) { - if (event.which == 1) { - chrome.tabs.create({url: "options.html"}); - } - } - } + if (ClearSearch != null && FilterBox != null) { + if (CleanPreviousBindings) { + FilterBox.removeEventListener("oninput", function() {}); + ClearSearch.removeEventListener("onmousedown", function() {}); + } + if (BindButtons) { + // FILTER ON INPUT + FilterBox.oninput = function(event) { + Tabs_FindTab(this.value); + } + // CLEAR FILTER BUTTON + ClearSearch.onmousedown = function(event) { + if (event.which == 1) { + this.style.opacity = "0"; + this.setAttribute("title", ""); + Tabs_FindTab(""); + } + } + } + } - // UNDO CLOSE - if (s.id == "button_undo") { - s.onmousedown = function(event) { - if (event.which == 1) { - chrome.sessions.getRecentlyClosed( null, function(sessions) { - if (sessions.length > 0) { - chrome.sessions.restore(null, function(restored) {}); - } - }); - } - } - } - - // MOVE TAB TO NEW WINDOW (DETACH) - if (s.id == "button_detach" || s.id == "button_move") { // move is legacy name of detach button - s.onmousedown = function(event) { - if (event.which == 1) { - if (document.querySelectorAll("#"+tt.active_group+" .selected_folder").length > 0){ - let detach = GetSelectedFolders(); - Detach(detach.TabsIds, detach.Folders); - } else { - let tabsArr = []; - document.querySelectorAll(".pin.selected_tab, .pin.active_tab, #"+tt.active_group+" .selected_tab, #"+tt.active_group+" .active_tab").forEach(function(s){ - tabsArr.push(parseInt(s.id)); - if (s.childNodes[1].childNodes.length > 0) { - document.querySelectorAll("#"+s.childNodes[1].id+" .tab").forEach(function(t){ - tabsArr.push(parseInt(t.id)); - }); - } - }); - Detach(tabsArr); - } - } - } - } - - // GO TO PREVIOUS SEARCH RESULT - if (s.id == "filter_search_go_prev") { - s.onmousedown = function(event) { - if (event.which == 1) { - let filtered = document.querySelectorAll("#"+tt.active_group+" .tab.filtered"); - if (filtered.length > 0) { - document.querySelectorAll(".highlighted_search").forEach(function(s){ - s.classList.remove("highlighted_search"); - }); - if (tt.SearchIndex == 0) { - tt.SearchIndex = filtered.length-1; - } else { - tt.SearchIndex--; - } - filtered[tt.SearchIndex].classList.add("highlighted_search"); - ScrollToTab(filtered[tt.SearchIndex].id); - } - } - } - } - - // GO TO NEXT SEARCH RESULT - if (s.id == "filter_search_go_next") { - s.onmousedown = function(event) { - if (event.which == 1) { - let filtered = document.querySelectorAll("#"+tt.active_group+" .tab.filtered"); - if (filtered.length > 0) { - document.querySelectorAll(".highlighted_search").forEach(function(s){ - s.classList.remove("highlighted_search"); - }); - if (tt.SearchIndex == filtered.length-1) { - tt.SearchIndex = 0; - } else { - tt.SearchIndex++; - } - filtered[tt.SearchIndex].classList.add("highlighted_search"); - ScrollToTab(filtered[tt.SearchIndex].id); - } - } - } - } - - // SHOW/HIDE GROUPS TOOLBAR - if (s.id == "button_groups_toolbar_hide") { - s.onmousedown = function(event) { - if (event.which == 1) { - GroupsToolbarToggle(); - } - } - } - - // SHOW GROUP MANAGER - if (s.id == "button_manager_window") { - s.onmousedown = function(event) { - if (event.which == 1 && document.getElementById("manager_window").style.top == "-500px") { - OpenManagerWindow(); - } else { - HideRenameDialogs(); - } - } - } - // NEW GROUP - if (s.id == "button_new_group") { - s.onmousedown = function(event) { - if (event.which == 1) { - AddNewGroup(); - } - } - } - - // REMOVE GROUP - if (s.id == "button_remove_group") { - s.onmousedown = function(event) { - if (event.which == 1) { - if (tt.active_group != "tab_list") { - GroupRemove(tt.active_group, event.shiftKey); - } - } - } - } - - - - // EDIT GROUP - if (s.id == "button_edit_group") { - s.onmousedown = function(event) { - if (event.which == 1) { - if (tt.active_group != "tab_list") { - ShowGroupEditWindow(tt.active_group); - } - } - } - } - - // EXPORT GROUP - if (s.id == "button_export_group") { - s.onmousedown = function(event) { - if (event.which == 1) { - ExportGroup(tt.active_group, tt.groups[tt.active_group].name, false); - } - } - } - - // IMPORT GROUP - if (s.id == "button_import_group") { - s.onmousedown = function(event) { - if (event.which == 1) { - let inputFile = ShowOpenFileDialog(".tt_group"); - inputFile.onchange = function(event) { - ImportGroup(true, false); - } - } - } - } - - // NEW FOLDER - if (s.id == "button_new_folder") { - s.onmousedown = function(event) { - if (event.which == 1) { - let FolderId = AddNewFolder({SetEvents: true}); - ShowRenameFolderDialog(FolderId); - } - } - } - - // RENAME FOLDER - if (s.id == "button_edit_folder") { - s.onmousedown = function(event) { - if (event.which == 1) { - if (document.querySelectorAll("#"+tt.active_group+" .selected_folder").length > 0) { - ShowRenameFolderDialog(document.querySelectorAll("#"+tt.active_group+" .selected_folder")[0].id); - } - } - } - } - // REMOVE FOLDERS - if (s.id == "button_remove_folder") { - s.onmousedown = function(event) { - if (event.which == 1) { - document.querySelectorAll("#"+tt.active_group+" .selected_folder").forEach(function(s){ - RemoveFolder(s.id); - }); - } - } - } - // DISCARD TABS - if (s.id == "button_unload" || s.id == "button_discard") { - s.onmousedown = function(event) { - if (event.which == 1) { - if (document.querySelectorAll(".pin.selected_tab:not(.active_tab), #"+tt.active_group+" .selected_tab:not(.active_tab)").length > 0) { - DiscardTabs( - Array.prototype.map.call(document.querySelectorAll(".pin:not(.active_tab), #"+tt.active_group+" .selected_tab:not(.active_tab)"), function(s){ - return parseInt(s.id); - }) - ); - } else { - DiscardTabs( - Array.prototype.map.call(document.querySelectorAll(".pin:not(.active_tab), .tab:not(.active_tab)"), function(s){ - return parseInt(s.id); - }) - ); - } - } - } - } - // IMPORT BACKUP - if (s.id == "button_import_bak") { - s.onmousedown = function(event) { - if (event.which == 1) { - let inputFile = ShowOpenFileDialog(".tt_session"); - inputFile.onchange = function(event) { - ImportSession(true, false, false); - } - } - } - } - // EXPORT BACKUP - if (s.id == "button_export_bak") { - s.onmousedown = function(event) { - if (event.which == 1) { - let d = new Date(); - ExportSession((d.toLocaleString().replace("/", ".").replace("/", ".").replace(":", "꞉").replace(":", "꞉")), true, false, false); - } - } - } - // MERGE BACKUP - if (s.id == "button_import_merge_bak") { - s.onmousedown = function(event) { - if (event.which == 1) { - let inputFile = ShowOpenFileDialog(".tt_session"); - inputFile.onchange = function(event) { - ImportSession(false, false, true); - // ImportMergeTabs(); - } - } - } - } - - // CHANGE FILTERING TYPE - if (s.id == "button_filter_type") { - s.onmousedown = function(event) { - if (event.which == 1) { - if (this.classList.contains("url")) { - this.classList.remove("url"); - this.classList.add("title"); - chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "title", windowId: tt.CurrentWindowId}); - } else { - this.classList.remove("title"); - this.classList.add("url"); - chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "url", windowId: tt.CurrentWindowId}); - } - FindTab(document.getElementById("filter_box").value); - } - } - } - - // EMERGENCY RELOAD - if (s.id == "button_reboot") { - s.onmousedown = function(event) { - if (event.which == 1) { - chrome.runtime.sendMessage({command: "reload"}); - chrome.runtime.sendMessage({command: "reload_sidebar"}); - location.reload(); - } - } - } - - // SORT TABS - // if (s.id == "button_sort") { - // s.onmousedown = function(event) { - // if (event.which == 1) { - // SortTabs(); - // } - // } - // } - // REPEAT SEARCH - // if (s.id == "repeat_search") { - // s.onmousedown = function(event) { - // if (event.which == 1) { - // FindTab(document.getElementById("filter_box").value); - // } - // } - // } - - - if (browserId != "F") { - // BOOKMARKS - if (s.id == "button_bookmarks") { - s.onmousedown = function(event) { - if (event.which == 1) { - chrome.tabs.create({url: "chrome://bookmarks/"}); - } - } - } - - // DOWNLOADS - if (s.id == "button_downloads") { - s.onmousedown = function(event) { - if (event.which == 1) { - chrome.tabs.create({url: "chrome://downloads/"}); - } - } - } - - // HISTORY - if (s.id == "button_history") { - s.onmousedown = function(event) { - if (event.which == 1) { - chrome.tabs.create({url: "chrome://history/"}); - } - } - } - - // EXTENSIONS - if (s.id == "button_extensions") { - s.onmousedown = function(event) { - if (event.which == 1) { - chrome.tabs.create({url: "chrome://extensions"}); - } - } - } - - // SETTINGS - if (s.id == "button_settings") { - s.onmousedown = function(event) { - if (event.which == 1) { - chrome.tabs.create({url: "chrome://settings/"}); - } - } - } - - // LOAD BACKUPS - if (s.id == "button_load_bak1" || s.id == "button_load_bak2" || s.id == "button_load_bak3") { - s.onmousedown = function(event) { - if (event.which == 1 && this.classList.contains("disabled") == false) { - let BakN = (this.id).substr(15); - chrome.storage.local.get(null, function(storage) { - if (Object.keys(storage["windows_BAK"+BakN]).length > 0) { chrome.storage.local.set({"windows": storage["windows_BAK"+BakN]}); } - if (Object.keys(storage["tabs_BAK"+BakN]).length > 0) { chrome.storage.local.set({"tabs": storage["tabs_BAK"+BakN]}); alert("Loaded backup"); } - chrome.runtime.sendMessage({command: "reload"}); chrome.runtime.sendMessage({command: "reload_sidebar"}); location.reload(); - }); - } - } - } - } - } - - }); - -} \ No newline at end of file + let query = document.querySelectorAll(".button"); + for (let s of query) { + if (CleanPreviousBindings) { + s.removeEventListener("onmousedown", function() {}); + s.removeEventListener("onclick", function() {}); + s.removeEventListener("click", function() {}); + } + if (BindToolbarShelfToggleButtons) { + if (s.id == "button_search") { + s.addEventListener(ToolbarShelfToggleClickType, function(event) { + if (event.which == 1) Toolbar_ShelfToggle(event.which, this, "toolbar_search", "search", SidebarRefreshGUI, OptionsRefreshGUI); + }); + } + if (s.id == "button_tools") { + s.addEventListener(ToolbarShelfToggleClickType, function(event) { + if (event.which == 1) Toolbar_ShelfToggle(event.which, this, "toolbar_shelf_tools", "tools", SidebarRefreshGUI, OptionsRefreshGUI); + }); + } + if (s.id == "button_groups") { + s.addEventListener(ToolbarShelfToggleClickType, function(event) { + if (event.which == 1) Toolbar_ShelfToggle(event.which, this, "toolbar_shelf_groups", "groups", SidebarRefreshGUI, OptionsRefreshGUI); + }); + } + if (s.id == "button_backup") { + s.addEventListener(ToolbarShelfToggleClickType, function(event) { + if (event.which == 1) Toolbar_ShelfToggle(event.which, this, "toolbar_shelf_backup", "backup", SidebarRefreshGUI, OptionsRefreshGUI); + }); + } + if (s.id == "button_folders") { + s.addEventListener(ToolbarShelfToggleClickType, function(event) { + if (event.which == 1) Toolbar_ShelfToggle(event.which, this, "toolbar_shelf_folders", "folders", SidebarRefreshGUI, OptionsRefreshGUI); + }); + } + } + if (BindButtons) { + if (s.id == "button_new") { // NEW TAB + s.onclick = function(event) { + if (event.which == 1) { + if (opt.append_tab_from_toolbar == "group_root") Tabs_OpenNewTab(false, undefined, document.getElementById("°"+tt.active_group)); + if (opt.append_tab_from_toolbar == "as_regular_orphan") Tabs_OpenNewTab(false, undefined, undefined); + } + } + s.onmousedown = function(event) { + if (event.which == 2) { // DUPLICATE TAB + event.preventDefault(); + let activeTab = document.querySelector("#" + tt.active_group + " .active_tab") != null ? document.querySelector("#" + tt.active_group + " .active_tab") : document.querySelector(".pin.active_tab") != null ? document.querySelector(".pin.active_tab") : null; + if (activeTab != null && tt.tabs[activeTab.id]) tt.tabs[activeTab.id].DuplicateTab(); + } + if (event.which == 3) { // SCROLL TO TAB + chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) { + if (activeTab[0].pinned && opt.pin_list_multi_row == false && tt.tabs[activeTab[0].id]) tt.tabs[activeTab[0].id].ScrollToTab(); + if (activeTab[0].pinned == false) { + let Tab = document.getElementById(activeTab[0].id); + let groupId = DOM_GetParentsByClass(Tab, "group")[0].id; + Groups_SetActiveGroup(groupId, true, true); + } + }); + } + } + } + if (s.id == "button_pin") { // PIN TAB + s.onmousedown = function(event) { + if (event.which == 1) { + let Tabs = document.querySelectorAll(".pin.active_tab, .pin.selected, #" + tt.active_group + " .active_tab, #" + tt.active_group + " .selected"); + for (let s of Tabs) { + chrome.tabs.update(parseInt(s.id), {pinned: Tabs[0].classList.contains("tab")}); + } + } + } + } + if (s.id == "button_options") { // VERTICAL TABS OPTIONS + s.onmousedown = function(event) { + if (event.which == 1) chrome.tabs.create({url: "options/options.html"}); + } + } + if (s.id == "button_undo") { // UNDO CLOSE + s.onmousedown = function(event) { + if (event.which == 1) { + chrome.sessions.getRecentlyClosed(null, function(sessions) { + if (sessions.length > 0) chrome.sessions.restore(null, function(restored) {}); + }); + } + } + } + if (s.id == "button_detach" || s.id == "button_move") { // MOVE TAB TO NEW WINDOW (DETACH), move is legacy name of detach button + s.onmousedown = function(event) { + if (event.which == 1) { + DOM_FreezeSelection(false); + let Nodes = []; + let NodesTypes = {DraggingPin: false, DraggingTab: false, DraggingFolder: false}; + let query = []; + if (document.querySelectorAll(".selected").length > 0) { + query = document.querySelectorAll(".selected, .selected .tab, .selected .folder"); + } else { + query = document.querySelectorAll(".active_tab"); + } + for (let s of query) { + if (s.classList.contains("pin")) { + NodesTypes.DraggingPin = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "pin"}); + } + if (s.classList.contains("tab")) { + NodesTypes.DraggingTab = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "tab"}); + } + if (s.classList.contains("folder")) { + NodesTypes.DraggingFolder = true; + Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "folder", index: (tt.folders[s.id] ? tt.folders[s.id].index : 0), name: (tt.folders[s.id] ? tt.folders[s.id].name : labels.noname_group), expand: (tt.folders[s.id] ? tt.folders[s.id].expand : "")}); + } + } + Tabs_Detach(Nodes, NodesTypes, {}); + } + } + } + if (s.id == "filter_search_go_prev") { // GO TO PREVIOUS SEARCH RESULT + s.onmousedown = function(event) { + if (event.which == 1) { + let filtered = document.querySelectorAll("#" + tt.active_group + " .tab.filtered"); + if (filtered.length > 0) { + + let query = document.querySelectorAll(".highlighted_search"); + for (let s of query) { + s.classList.remove("highlighted_search"); + } + if (tt.SearchIndex == 0) { + tt.SearchIndex = filtered.length - 1; + } else { + tt.SearchIndex--; + } + filtered[tt.SearchIndex].classList.add("highlighted_search"); + if (tt.tabs[filtered[tt.SearchIndex].id]) tt.tabs[filtered[tt.SearchIndex].id].ScrollToTab(); + } + } + } + } + if (s.id == "filter_search_go_next") { // GO TO NEXT SEARCH RESULT + s.onmousedown = function(event) { + if (event.which == 1) { + let filtered = document.querySelectorAll("#" + tt.active_group + " .tab.filtered"); + if (filtered.length > 0) { + + let query = document.querySelectorAll(".highlighted_search"); + for (let s of query) { + s.classList.remove("highlighted_search"); + } + if (tt.SearchIndex == filtered.length - 1) { + tt.SearchIndex = 0; + } else { + tt.SearchIndex++; + } + filtered[tt.SearchIndex].classList.add("highlighted_search"); + if (tt.tabs[filtered[tt.SearchIndex].id]) tt.tabs[filtered[tt.SearchIndex].id].ScrollToTab(); + } + } + } + } + if (s.id == "button_groups_toolbar_hide") { // SHOW/HIDE GROUPS TOOLBAR + s.onmousedown = function(event) { + if (event.which == 1) Groups_GroupsToolbarToggle(); + } + } + if (s.id == "button_manager_window") { // SHOW GROUP MANAGER + s.onmousedown = function(event) { + if (event.which == 1 && document.getElementById("manager_window").style.top == "-500px") { + Manager_OpenManagerWindow(); + } else { + DOM_HideRenameDialogs(); + } + } + } + if (s.id == "button_new_group") { // NEW GROUP + s.onmousedown = function(event) { + if (event.which == 1) { + let NewGroupId = Groups_AddNewGroup(); + Groups_ShowGroupEditWindow(NewGroupId); + } + } + } + if (s.id == "button_remove_group") { // REMOVE GROUP + s.onmousedown = function(event) { + if (event.which == 1) { + if (tt.active_group != "tab_list") Groups_GroupRemove(tt.active_group, event.shiftKey); + } + } + } + if (s.id == "button_edit_group") { // EDIT GROUP + s.onmousedown = function(event) { + if (event.which == 1) { + if (tt.active_group != "tab_list") Groups_ShowGroupEditWindow(tt.active_group); + } + } + } + if (s.id == "button_export_group") { // EXPORT GROUP + s.onmousedown = function(event) { + if (event.which == 1) Manager_ExportGroup(tt.active_group, tt.groups[tt.active_group].name, false); + } + } + if (s.id == "button_import_group") { // IMPORT GROUP + s.onmousedown = function(event) { + if (event.which == 1) { + let inputFile = File_ShowOpenFileDialog(".tt_group"); + inputFile.onchange = function(event) { + Manager_ImportGroup(true, false); + } + } + } + } + if (s.id == "button_new_folder") { // NEW FOLDER + s.onmousedown = function(event) { + if (event.which == 1) { + let FolderId = Folders_AddNewFolder({}); + Folders_ShowRenameFolderDialog(FolderId); + } + } + } + if (s.id == "button_edit_folder") { // RENAME FOLDER + s.onmousedown = function(event) { + if (event.which == 1) { + if (document.querySelectorAll("#" + tt.active_group + " .selected").length > 0) Folders_ShowRenameFolderDialog(document.querySelectorAll("#" + tt.active_group + " .selected")[0].id); + } + } + } + if (s.id == "button_remove_folder") { // REMOVE FOLDERS + s.onmousedown = function(event) { + if (event.which == 1) { + + let query = document.querySelectorAll("#" + tt.active_group + " .selected"); + for (let s of query) { + Folders_RemoveFolder(s.id); + } + } + } + } + if (s.id == "button_unload" || s.id == "button_discard") { // DISCARD TABS + s.onmousedown = function(event) { + if (event.which == 1) { + if (document.querySelectorAll(".pin.selected:not(.active_tab), #" + tt.active_group + " .selected:not(.active_tab)").length > 0) { + Tabs_DiscardTabs( + Array.prototype.map.call(document.querySelectorAll(".pin:not(.active_tab), #" + tt.active_group + " .selected:not(.active_tab)"), function(s) { + return parseInt(s.id); + }) + ); + } else { + Tabs_DiscardTabs( + Array.prototype.map.call(document.querySelectorAll(".pin:not(.active_tab), .tab:not(.active_tab)"), function(s) { + return parseInt(s.id); + }) + ); + } + } + } + } + if (s.id == "button_import_bak") { // IMPORT BACKUP + s.onmousedown = function(event) { + if (event.which == 1) { + let inputFile = File_ShowOpenFileDialog(".tt_session"); + inputFile.onchange = function(event) { + Manager_ImportSession(true, false, false); + } + } + } + } + if (s.id == "button_export_bak") { // EXPORT BACKUP + s.onmousedown = function(event) { + if (event.which == 1) { + let d = new Date(); + Manager_ExportSession((d.toLocaleString().replace(/\//g, ".").replace(/:/g, "꞉")), true, false, false); + } + } + } + if (s.id == "button_import_merge_bak") { // MERGE BACKUP + s.onmousedown = function(event) { + if (event.which == 1) { + let inputFile = File_ShowOpenFileDialog(".tt_session"); + inputFile.onchange = function(event) { + Manager_ImportSession(false, false, true); + // Manager_ImportMergeTabs(); + } + } + } + } + if (s.id == "button_filter_type") { // CHANGE FILTERING TYPE + s.onmousedown = function(event) { + if (event.which == 1) { + if (this.classList.contains("url")) { + DOM_SetClasses(this, ["title"], ["url"], []); + chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "title", windowId: tt.CurrentWindowId}); + } else { + DOM_SetClasses(this, ["url"], ["title"], []); + chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "url", windowId: tt.CurrentWindowId}); + } + Tabs_FindTab(document.getElementById("filter_box").value); + } + } + } + if (s.id == "button_reboot") { // EMERGENCY RELOAD + s.onmousedown = function(event) { + if (event.which == 1) { + chrome.runtime.sendMessage({command: "reload"}); + chrome.runtime.sendMessage({command: "reload_sidebar"}); + location.reload(); + } + } + } + if (browserId != "F") { + if (s.id == "button_bookmarks") { // BOOKMARKS + s.onmousedown = function(event) { + if (event.which == 1) chrome.tabs.create({url: "chrome://bookmarks/"}); + } + } + if (s.id == "button_downloads") { // DOWNLOADS + s.onmousedown = function(event) { + if (event.which == 1) chrome.tabs.create({url: "chrome://downloads/"}); + } + } + if (s.id == "button_history") { // HISTORY + s.onmousedown = function(event) { + if (event.which == 1) chrome.tabs.create({url: "chrome://history/"}); + } + } + if (s.id == "button_extensions") { // EXTENSIONS + s.onmousedown = function(event) { + if (event.which == 1) chrome.tabs.create({url: "chrome://extensions"}); + } + } + if (s.id == "button_settings") { // SETTINGS + s.onmousedown = function(event) { + if (event.which == 1) chrome.tabs.create({url: "chrome://settings/"}); + } + } + if (s.id == "button_load_bak1" || s.id == "button_load_bak2" || s.id == "button_load_bak3") { // LOAD BACKUPS + s.onmousedown = function(event) { + if (event.which == 1 && this.classList.contains("disabled") == false) { + let BakN = (this.id).substr(15); + chrome.storage.local.get(null, function(storage) { + if (Object.keys(storage["windows_BAK" + BakN]).length > 0) chrome.storage.local.set({"windows": storage["windows_BAK" + BakN]}); + if (Object.keys(storage["tabs_BAK" + BakN]).length > 0) { + chrome.storage.local.set({"tabs": storage["tabs_BAK" + BakN]}); + alert("Loaded backup"); + } + chrome.runtime.sendMessage({command: "reload"}); + chrome.runtime.sendMessage({command: "reload_sidebar"}); + location.reload(); + }); + } + } + } + } + } + } +} diff --git a/scripts/utils.js b/scripts/utils.js index 6d7adf4..43166c5 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -1,401 +1,19 @@ -// 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 RecheckFirefox() { - chrome.tabs.query({pinned: false, currentWindow: true}, function(tabs) { - if (tabs.length > 1) { - let last_tabId = tabs[tabs.length-1].id; - let p = []; - let p_tt = []; - let t_ref = {}; - let t_ind = 0; - let ok = 0; - let ti = 0; - let tc = tabs.length; - for (ti = 0; ti < tc; ti++) { - let tabId = tabs[ti].id; - p.push(""); - p_tt.push(""); - let t = Promise.resolve(browser.sessions.getTabValue(tabId, "TTdata")).then(function(TabData) { - if (TabData != undefined) { - t_ref[TabData.ttid] = tabs[t_ind].id; - p_tt[t_ind] = TabData.parent_ttid; - p[t_ind] = TabData.parent; - } - t_ind++; - if (tabId == last_tabId) { - let i = 0; - for (i = 0; i < p.length; i++) { - if (t_ref[p_tt[i]]) { - p[i] = t_ref[p_tt[i]]; - } - } - for (i = 0; i < p.length; i++) { - let Tab = document.getElementById(tabs[i].id); - if (Tab && p[i] == Tab.parentNode.parentNode.id) { - ok++; - } - } - if (ok < tabs.length*0.5) { - if (opt.debug) { - log("emergency reload"); - } - chrome.storage.local.set({emergency_reload: true}); - chrome.runtime.sendMessage({command: "reload"}); - chrome.runtime.sendMessage({command: "reload_sidebar"}); - location.reload(); - } else { - if (opt.debug) { - log("f: RecheckFirefox, ok"); - } - } - } - }); - } - } - }); +function Utils_RGBtoHex(color) { // color in format "rgb(r,g,b)" or simply "r,g,b" (can have spaces, but must contain "," between values) + color = color.replace(/[rgb(]|\)|\s/g, ""); + color = color.split(","); + return color.map(function(v) {return ("0" + Math.min(Math.max(parseInt(v), 0), 255).toString(16)).slice(-2);}).join(""); } - -function SavePreferences() { - chrome.storage.local.set({preferences: opt}); - chrome.runtime.sendMessage({command: "reload_options", opt: opt}); +function Utils_HexToRGB(hex, alpha) { + hex = hex.replace('#', ''); + let r = parseInt(hex.length == 3 ? hex.slice(0, 1).repeat(2) : hex.slice(0, 2), 16); + let g = parseInt(hex.length == 3 ? hex.slice(1, 2).repeat(2) : hex.slice(2, 4), 16); + let b = parseInt(hex.length == 3 ? hex.slice(2, 3).repeat(2) : hex.slice(4, 6), 16); + if (alpha) { + return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')'; + } else { + return 'rgb(' + r + ', ' + g + ', ' + b + ')'; + } } - -function LoadDefaultPreferences() { - opt = Object.assign({}, DefaultPreferences); +function Utils_log(log) { + chrome.runtime.sendMessage({command: "debug", log: log}); } - -function ShowOpenFileDialog(extension) { - let body = document.getElementById("body"); - let inp = document.createElement("input"); - inp.id = "file_import"; - inp.type = "file"; - inp.accept = extension; - inp.style.display = "none"; - body.appendChild(inp); - inp.click(); - return inp; -} - -function SaveFile(filename, extension, data) { - let file = new File([JSON.stringify(data)], filename+"."+extension, {type: "text/"+extension+";charset=utf-8"} ); - let body = document.getElementById("body"); - let savelink = document.createElement("a"); - savelink.href = URL.createObjectURL(file); - savelink.fileSize = file.size; - savelink.target = "_blank"; - savelink.style.display = "none"; - savelink.type = "file"; - savelink.download = filename+"."+extension; - body.appendChild(savelink); - setTimeout(function() { - savelink.click(); - setTimeout(function() { - savelink.parentNode.removeChild(savelink); - }, 60000); - }, 10); -} - -function AppendToNode(Node, AppendNode) { - if (Node != null && AppendNode != null) { - AppendNode.appendChild(Node); - } -} - -function InsterBeforeNode(Node, BeforeNode) { - if (Node != null && BeforeNode != null) { - BeforeNode.parentNode.insertBefore(Node, BeforeNode); - } -} - -function InsterAfterNode(Node, AfterNode) { - if (Node != null && AfterNode != null) { - if (AfterNode.nextSibling != null) { - AfterNode.parentNode.insertBefore(Node, AfterNode.nextSibling); - } else { - AfterNode.parentNode.appendChild(Node); - } - } -} - -function HideRenameDialogs() { - document.querySelectorAll(".edit_dialog").forEach(function(s){ - s.style.display = "none"; - s.style.top = "-500px"; - s.style.left = "-500px"; - }); -} - -function GetParentsByClass(Node, Class) { - let Parents = []; - let ParentNode = Node; - while (ParentNode.parentNode != null) { - if (ParentNode.parentNode.classList != undefined && ParentNode.parentNode.classList.contains(Class)) { - Parents.push(ParentNode.parentNode); - } - ParentNode = ParentNode.parentNode; - } - return Parents; -} - -function GetParentsBy2Classes(Node, ClassA, ClassB) { - let Parents = []; - let ParentNode = Node; - while (ParentNode.parentNode != null) { - if (ParentNode.parentNode.classList != undefined && ParentNode.parentNode.classList.contains(ClassA) && ParentNode.parentNode.classList.contains(ClassB)) { - Parents.push(ParentNode.parentNode); - } - ParentNode = ParentNode.parentNode; - } - return Parents; -} - -// color in format "rgb(r,g,b)" or simply "r,g,b" (can have spaces, but must contain "," between values) -function RGBtoHex(color){ - color = color.replace(/[rgb(]|\)|\s/g, ""); color = color.split(","); return color.map(function(v){ return ("0"+Math.min(Math.max(parseInt(v), 0), 255).toString(16)).slice(-2); }).join(""); -} - -function HexToRGB(hex, alpha){ - hex = hex.replace('#', ''); - let r = parseInt(hex.length == 3 ? hex.slice(0, 1).repeat(2) : hex.slice(0, 2), 16); - let g = parseInt(hex.length == 3 ? hex.slice(1, 2).repeat(2) : hex.slice(2, 4), 16); - let b = parseInt(hex.length == 3 ? hex.slice(2, 3).repeat(2) : hex.slice(4, 6), 16); - if (alpha) { return 'rgba('+r+', '+g+', '+b+', '+alpha+')'; } else { return 'rgb('+r+', '+g+', '+b+')'; } -} - -function GetSelectedFolders() { - - if (opt.debug) { - log("f: GetSelectedFolders"); - } - - let res = {Folders: {}, FoldersSelected: [], TabsIds: [], TabsIdsParents: []}; - document.querySelectorAll("#"+tt.active_group+" .selected_folder").forEach(function(s){ - res.FoldersSelected.push(s.id); - res.Folders[s.id] = Object.assign({}, tt.folders[s.id]); - let Fchildren = document.querySelectorAll("#cf"+s.id+" .folder"); - Fchildren.forEach(function(fc){ - res.Folders[fc.id] = Object.assign({}, tt.folders[fc.id]); - }); - let Tchildren = document.querySelectorAll("#ct"+s.id+" .tab"); - Tchildren.forEach(function(tc){ - res.TabsIds.push(parseInt(tc.id)); - res.TabsIdsParents.push(tc.parentNode.id); - }); - }); - return res; -} - -function GetSelectedTabs() { - let res = {TabsIds: [], TabsIdsParents: [], TabsIdsSelected: []}; - document.querySelectorAll(".pin.selected_tab, #"+tt.active_group+" .selected_tab").forEach(function(s){ - res.TabsIds.push(parseInt(s.id)); - res.TabsIdsParents.push(s.parentNode.id); - res.TabsIdsSelected.push(parseInt(s.id)); - let Tchildren = document.querySelectorAll("#ct"+s.id+" .tab"); - Tchildren.forEach(function(tc){ - res.TabsIds.push(parseInt(tc.id)); - res.TabsIdsParents.push(tc.parentNode.id); - }); - }); - return res; -} - - -function FindTab(input) { // find and select tabs - let ButtonFilterClear = document.getElementById("button_filter_clear"); - document.querySelectorAll(".filtered, .highlighted_search").forEach(function(s){ - s.classList.remove("filtered"); - s.classList.remove("selected_tab"); - s.classList.remove("selected_last"); - s.classList.remove("highlighted_search"); - }) - if (input.length == 0) { - document.getElementById("filter_box").value = ""; - ButtonFilterClear.style.opacity = "0"; - ButtonFilterClear.title = ""; - return; - } else { - ButtonFilterClear.style.opacity = "1"; - ButtonFilterClear.title = labels.clear_filter; - } - tt.SearchIndex = 0; - let FilterType = document.getElementById("button_filter_type"); - let searchUrl = FilterType.classList.contains("url"); - let searchTitle = FilterType.classList.contains("title"); - - let query = {windowId: tt.CurrentWindowId, pinned: false}; - if (input == "*audible") { - query = {windowId: tt.CurrentWindowId, discarded: false, audible: true, muted: false, pinned: false}; - } - if (input == "*muted") { - query = {windowId: tt.CurrentWindowId, discarded: false, muted: true, pinned: false}; - } - if (input == "*unloaded") { - query = {windowId: tt.CurrentWindowId, discarded: true, pinned: false}; - } - if (input == "*loaded") { - query = {windowId: tt.CurrentWindowId, discarded: false, pinned: false}; - } - - chrome.tabs.query(query, function(tabs) { - tabs.forEach(function(Tab) { - if (input == "*audible" || input == "*muted" || input == "*unloaded" || input == "*loaded") { - document.getElementById(Tab.id).classList.add("filtered"); - document.getElementById(Tab.id).classList.add("selected_tab"); - } else { - if (searchUrl) { - if (Tab.url.toLowerCase().match(input.toLowerCase())) { - document.getElementById(Tab.id).classList.add("filtered"); - document.getElementById(Tab.id).classList.add("selected_tab"); - } - } - if (searchTitle) { - if (Tab.title.toLowerCase().match(input.toLowerCase())) { - document.getElementById(Tab.id).classList.add("filtered"); - document.getElementById(Tab.id).classList.add("selected_tab"); - } - } - } - }); - }); -} - -function Bookmark(rootNode) { - let ToolbarId = browserId == "F" ? "toolbar_____" : "1"; - chrome.bookmarks.get(ToolbarId, function(list) { - chrome.bookmarks.search("TreeTabs", function(list) { - let TreeTabsId; - for (var elem in list) { - if (list[elem].parentId == ToolbarId) { - TreeTabsId = list[elem].id; - break; - } - } - if (TreeTabsId == undefined) { - chrome.bookmarks.create({parentId: ToolbarId, title: "TreeTabs"}, function(TreeTabsNew) { - TreeTabsId = TreeTabsNew.id; - }); - Bookmark(rootNode); - return; - } else { - if (rootNode.classList.contains("tab")) { - chrome.tabs.get(parseInt(rootNode.id), function(tab) { - if (tab) { - chrome.bookmarks.create({parentId: TreeTabsId, title: tab.title}, function(root) { - document.querySelectorAll("[id='"+rootNode.id+"'], [id='"+rootNode.id+"'] .tab").forEach(function(s){ - chrome.tabs.get(parseInt(s.id), function(tab){ - if (tab) { - chrome.bookmarks.create({parentId: root.id, title: tab.title, url: tab.url }); - } - }); - }); - }); - } - }); - } - - if (rootNode.classList.contains("folder") || rootNode.classList.contains("group")) { - let rootName = labels.noname_group; - if (rootNode.classList.contains("folder") && tt.folders[rootNode.id]) { - rootName = tt.folders[rootNode.id].name; - } - if (rootNode.classList.contains("group") && tt.groups[rootNode.id]) { - rootName = tt.groups[rootNode.id].name; - } - - chrome.bookmarks.create({parentId: TreeTabsId, title: rootName}, function(root) { - let foldersRefs = {}; - - let folders = document.querySelectorAll("#cf"+rootNode.id+" .folder"); - folders.forEach(function(s){ - if (tt.folders[s.id]) { - let ttId = s.id; - chrome.bookmarks.create({parentId: root.id, title: tt.folders[ttId].name}, function(Bkfolder) { - foldersRefs[ttId] = {ttid: ttId, id: Bkfolder.id, ttparent: tt.folders[ttId].parent, parent: root.id}; - - let elemInd = 0; - if (ttId == folders[folders.length-1].id) { - for (var elem in foldersRefs) { - let FolderTTId = foldersRefs[elem].ttid; - let BookmarkFolderId = foldersRefs[elem].id; - let TTParentId = foldersRefs[elem].ttparent; - if (foldersRefs[TTParentId]) { - foldersRefs[FolderTTId].parent = foldersRefs[TTParentId].id; - } - - elemInd++; - - if (elemInd == Object.keys(foldersRefs).length) { - elemInd = 0; - for (var elem in foldersRefs) { - let BookmarkFolderId = foldersRefs[elem].id; - let BookmarkFolderParentId = foldersRefs[elem].parent; - chrome.bookmarks.move(BookmarkFolderId, {parentId: BookmarkFolderParentId}, function(BkFinalfolder) { - document.querySelectorAll("#ct"+foldersRefs[elem].ttid+" .tab").forEach(function(s){ - chrome.tabs.get(parseInt(s.id), function(tab){ - if (tab) { - chrome.bookmarks.create({parentId: BkFinalfolder.id, title: tab.title, url: tab.url }); - } - }); - }); - - elemInd++; - - }); - } - } - } - } - }); - } - }); - - document.querySelectorAll("#ct"+rootNode.id+" .tab").forEach(function(s){ - chrome.tabs.get(parseInt(s.id), function(tab){ - if (tab) { - chrome.bookmarks.create({parentId: root.id, title: tab.title, url: tab.url }); - } - }); - }); - - }); - } - } - }); - }); -} - -function ShowStatusBar(p) { // show, spinner, message - let status_bar = document.getElementById("status_bar"); - let busy_spinner = document.getElementById("busy_spinner"); - let status_message = document.getElementById("status_message"); - if (p.show) { - status_bar.style.display = "block"; - status_message.textContent = p.message; - if (p.spinner) { - busy_spinner.style.opacity = "1"; - } else { - busy_spinner.style.opacity = "0"; - } - } else { - busy_spinner.style.opacity = "0"; - status_message.textContent = ""; - status_bar.style.display = "none"; - } - if (p.hideTimeout) { - setTimeout(function() { - busy_spinner.style.opacity = "0"; - status_message.textContent = ""; - status_bar.style.display = "none"; - }, p.hideTimeout); - } -} - -function log(log) { - if (opt.debug) { - chrome.runtime.sendMessage({command: "debug", log: log}); - } -} \ No newline at end of file diff --git a/sidebar.html b/sidebar.html index 9e606c1..a8c9e49 100644 --- a/sidebar.html +++ b/sidebar.html @@ -1,199 +1,138 @@  - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - -
- -
-
-
-
-
- - -
-
- - + + + - - - - - - - -
-
-
-
-
- - + + + + + + +