1.8.7 release

This commit is contained in:
karol@jagiello.it 2018-12-13 23:55:34 +01:00
parent 6211e85683
commit 56b3bafe64
67 changed files with 10797 additions and 12527 deletions

View File

@ -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: CHANGES:
1. shortcut to open TreeTabs Sidebar is now F1 1. mute icon config option (disable animation)
2. log does not preserve any personal data (urls) for GDPR law 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
NEW:
1. you can now drag&drop entire group to another window
2. tree structure is tracked in background (excluded closing tabs)
3. added alt+w shortcut to close a tree of tabs
4. creating folder will now prompt for a new name
5. search for *audible, *muted, *unloaded, *loaded tabs! Just write *audible in search box!
FIXES:
1. import window was not showing up FIXED:
2. export group and export session had file extension in name "Close other" doesn't respect pinned tabs.
3. pin tree had bug in setting class
@ -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" 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 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. - 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 I DON'T UNDERSTAND THOSE FROM COMMENTS
- add possibility open all tabs in folder in new left tab group with deleting this folder; - 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; - 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; - real FF tabs must creating and linking only after activate your tabs;

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

File diff suppressed because one or more lines are too long

View File

@ -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}

View File

@ -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}

View File

@ -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}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
"manifest_version": 2, "manifest_version": 2,
"default_locale": "en", "default_locale": "en",
"background": { "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 "persistent": true
}, },
"name": "Tree Tabs", "name": "Tree Tabs",
@ -36,7 +36,7 @@
} }
}, },
"options_ui": { "options_ui": {
"page": "options.html", "page": "options/options.html",
"open_in_tab": true "open_in_tab": true
}, },
"commands": { "commands": {
@ -45,5 +45,5 @@
"description": "close tree" "description": "close tree"
} }
}, },
"version": "100" "version": "1.8.6"
} }

View File

@ -2,7 +2,7 @@
"manifest_version": 2, "manifest_version": 2,
"default_locale": "en", "default_locale": "en",
"background": { "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 "persistent": true
}, },
"name": "Tree Tabs", "name": "Tree Tabs",
@ -41,12 +41,12 @@
"applications": { "applications": {
"gecko": { "gecko": {
"id": "TreeTabs@jagiello.it", "id": "TreeTabs@jagiello.it",
"strict_min_version": "57.0" "strict_min_version": "63.0"
} }
}, },
"options_ui": { "options_ui": {
"page": "options.html", "page": "options/options.html",
"open_in_tab": true "open_in_tab": true
}, },
"version": "1.7.2" "version": "1.8.7"
} }

View File

@ -3,7 +3,7 @@
"minimum_opera_version": "42", "minimum_opera_version": "42",
"default_locale": "en", "default_locale": "en",
"background": { "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 "persistent": true
}, },
"name": "Tree Tabs", "name": "Tree Tabs",
@ -24,12 +24,12 @@
"default_panel": "sidebar.html", "default_panel": "sidebar.html",
"default_title": "Tree Tabs" "default_title": "Tree Tabs"
}, },
"options_page": "options.html", "options_page": "options/options.html",
"commands": { "commands": {
"close_tree": { "close_tree": {
"suggested_key": { "default": "Alt+W" }, "suggested_key": { "default": "Alt+W" },
"description": "close tree" "description": "close tree"
} }
}, },
"version": "1.7.2" "version": "1.8.6"
} }

View File

@ -2,7 +2,7 @@
"manifest_version": 2, "manifest_version": 2,
"default_locale": "en", "default_locale": "en",
"background": { "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 "persistent": true
}, },
"name": "Tree Tabs", "name": "Tree Tabs",
@ -16,7 +16,7 @@
}, },
"permissions": [ "tabs", "sessions", "<all_urls>", "storage", "unlimitedStorage", "bookmarks" ], "permissions": [ "tabs", "sessions", "<all_urls>", "storage", "unlimitedStorage", "bookmarks" ],
"options_ui": { "options_ui": {
"page": "options.html", "page": "options/options.html",
"open_in_tab": false "open_in_tab": false
}, },
"commands": { "commands": {
@ -25,5 +25,5 @@
"description": "close tree" "description": "close tree"
} }
}, },
"version": "1.7.2" "version": "1.8.6"
} }

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

335
background_firefox.js Normal file
View File

@ -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++;
});
}

266
background_opera.js Normal file
View File

@ -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;
});
}

377
background_vivaldi.js Normal file
View File

@ -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;
});
}

92
global.js Normal file
View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -2,7 +2,7 @@
"manifest_version": 2, "manifest_version": 2,
"default_locale": "en", "default_locale": "en",
"background": { "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 "persistent": true
}, },
"name": "Tree Tabs", "name": "Tree Tabs",
@ -14,8 +14,7 @@
"19": "icons/16.png", "19": "icons/16.png",
"16": "icons/16.png" "16": "icons/16.png"
}, },
"permissions": [ "<all_urls>", "tabs", "sessions", "storage", "unlimitedStorage", "bookmarks", "tabHide" ], "permissions": [ "tabs", "sessions", "storage", "unlimitedStorage", "bookmarks", "tabHide" ],
"sidebar_action": { "sidebar_action": {
"default_icon": { "default_icon": {
"16": "icons/16.png", "16": "icons/16.png",
@ -29,21 +28,25 @@
"browser_action": { "browser_action": {
"default_icon": "icons/24.png" "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": { "commands": {
"_execute_browser_action": {
"suggested_key": { "default": "F1" },
"description": "toggle Tree Tabs"
},
"close_tree": { "close_tree": {
"suggested_key": { "default": "Alt+W" }, "suggested_key": { "default": "Alt+W" },
"description": "close tree" "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"
} }

View File

@ -1,858 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title></title>
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_0.css" id="sizes_preset_0" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_1.css" id="sizes_preset_1" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_2.css" id="sizes_preset_2" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_3.css" id="sizes_preset_3" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_4.css" id="sizes_preset_4" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_0.css" id="tabs_margin_0" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_1.css" id="tabs_margin_1" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_2.css" id="tabs_margin_2" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_colors.css" id="theme_colors" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme.css" id="theme" />
<link type="text/css" rel="stylesheet" media="all" href="options/options.css" id="main_body_css" />
<style rel="stylesheet"> #red_higlights_go_here { background-color: transparent; } </style>
<link type="text/css" rel="stylesheet" media="all" href="options/options overwrite.css" id="overwrite" />
</head>
<body id="body" class="options_body">
<div style="width:850px; align:left;"><span style="width:100%; font-size:20px; display:inline-block; text-align:center; ">Tree Tabs</span></div>
<br>
<fieldset class="field" id="field_vivaldi" style="display:none;">
<legend class="label" id="options_vivaldi"></legend>
<table>
<tr>
<td class="label" id="opt_url_for_web_panel"></td>
<td><input style="position:relative;width:450px;left:8px;" type="text" id="url_for_web_panel" value=""></input></td>
<td><div style="position:relative; width:20px; height: 20px; left:8px; background-size: 20px 20px; background-image: url(options/options_copy_icon.png);" id="copy_vivaldi_url_for_web_panel" ></div></td>
</tr>
</table>
</fieldset>
<fieldset class="field" id="field_pins">
<legend class="label" id="options_pinned" ></legend>
<table style="display:inline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="pin_list_multi_row"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_pin_list_multi_row"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="allow_pin_close"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="option_allow_pin_close"></td>
</tr>
</table>
</fieldset>
<fieldset class="field" id="field_groups">
<legend class="label" id="options_groups"></legend>
<table style="display:vinline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="groups_toolbar_default"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_groups_toolbar_default"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="show_counter_groups"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_show_counter_groups"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="syncro_tabbar_groups_tabs_order"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_syncro_tabbar_groups_tabs_order"></td>
</tr>
<tr id="firefox_option_hide_other_groups_tabs_firefox">
<td><input type="checkbox" class="opt_checkbox bg_opt" id="hide_other_groups_tabs_firefox"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_hide_other_groups_tabs_firefox"></td>
</tr>
</table>
<ul>
<li>
<label class="label" id="options_midclick_group"></label>
<select id="midclick_group">
<option class="bg_opt_drop_down_menu" id="options_action_group_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_new" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_undo_close_tab" value="undo_close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_activate_previous_active" value="activate_previous_active"></option>
</select>
</li>
<li>
<label class="label" id="options_dbclick_group"></label>
<select id="dbclick_group">
<option class="bg_opt_drop_down_menu" id="options_action_group_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_new" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_undo_close_tab" value="undo_close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_activate_previous_active" value="activate_previous_active"></option>
</select>
</li>
</ul>
</fieldset>
<fieldset class="field" id="field_folders">
<legend class="label" id="options_folders"></legend>
<ul>
<li>
<label class="label" id="options_midclick_folder"></label>
<select id="midclick_folder">
<option class="bg_opt_drop_down_menu" id="options_action_folder_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_rename" value="rename_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_new_folder" value="new_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_new_tab" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_expand_collapse" value="expand_collapse"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_close" value="close_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_unload" value="unload_folder"></option>
</select>
</li>
<li>
<label class="label" id="options_dbclick_folder"></label>
<select id="dbclick_folder">
<option class="bg_opt_drop_down_menu" id="options_action_folder_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_rename" value="rename_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_new_folder" value="new_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_new_tab" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_expand_collapse" value="expand_collapse"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_close" value="close_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_unload" value="unload_folder"></option>
</select>
</li>
</ul>
<table style="display:vinline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="max_tree_drag_drop_folders"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_max_tree_drag_drop_folders"></td>
</tr>
</table>
</fieldset>
<fieldset class="field" id="field_tabs">
<legend class="label" id="options_tabs"></legend>
<ul>
<li>
<label class="label" id="options_midclick_tab"></label>
<select id="midclick_tab">
<option class="bg_opt_drop_down_menu" id="options_action_tab_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_new" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_expand_collapse" value="expand_collapse"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_close" value="close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_undo_close" value="undo_close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_reload" value="reload_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_unload" value="unload_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_activate_previous_active" value="activate_previous_active"></option>
</select>
</li>
<li>
<label class="label" id="options_dbclick_tab"></label>
<select id="dbclick_tab">
<option class="bg_opt_drop_down_menu" id="options_action_tab_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_new" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_expand_collapse" value="expand_collapse"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_close" value="close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_undo_close" value="undo_close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_reload" value="reload_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_activate_previous_active" value="activate_previous_active"></option>
</select>
</li>
</ul>
<table style="display:vinline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="syncro_tabbar_tabs_order"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_syncro_tabbar_tabs_order"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="switch_with_scroll"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_switch_with_scroll"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="orphaned_tabs_to_ungrouped"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_orphaned_tabs_to_ungrouped"></td>
</tr>
</table>
<ul>
<li>
<label class="label" id="options_append_child_tab"></label>
<select id="append_child_tab">
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_top" value="top"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_bottom" value="bottom"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after" value="after"></option>
</select>
</li>
<li id="append_child_tab_after_limit_dropdown">
<label class="label" id="options_append_child_tab_after_limit"></label>
<select id="append_child_tab_after_limit">
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_top" value="top"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_after" value="after"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_bottom" value="bottom"></option>
</select>
</li>
<li>
<label class="label" id="options_append_orphan_tab"></label>
<select id="append_orphan_tab">
<option class="bg_opt_drop_down_menu" id="options_append_orphan_tab_top" value="top"></option>
<option class="bg_opt_drop_down_menu" id="options_append_orphan_tab_after_active" value="after_active"></option>
<option class="bg_opt_drop_down_menu" id="options_append_orphan_tab_bottom" value="bottom"></option>
<option class="bg_opt_drop_down_menu" id="options_append_orphan_tab_as_child" value="as_child"></option>
</select>
</li>
<li>
<label class="label" id="options_toolbar_new_tab"></label>
<select id="append_tab_from_toolbar">
<option class="bg_opt_drop_down_menu" id="options_toolbar_new_tab_as_regular_orphan" value="as_regular_orphan"></option>
<option class="bg_opt_drop_down_menu" id="options_toolbar_new_tab_root_of_group" value="group_root"></option>
</select>
</li>
<li>
<label class="label" id="options_after_closing_active_tab"></label>
<select id="after_closing_active_tab">
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_up" value="above"></option>
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_down" value="below"></option>
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_up_seek_in_parent" value="above_seek_in_parent"></option>
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_down_seek_in_parent" value="below_seek_in_parent"></option>
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_browser" value="browser"></option>
</select>
</li>
<li>
<label class="label" id="options_tab_group_regex"></label><br>
<br><span class="regexLabel">
<label class="label" id="option_tab_match"></label>
</span>
<span class="regexLabel">
<label class="label" id="option_tab_group" style="width:200px"></label>
</span>
<div id="tab_group_regexes"></div>
<button class="set_button" type="button" id="add_tab_group_regex" style="margin:6px;"></button>
</li>
<li>
<label class="label" id="options_move_on_url_change"></label>
<select id="move_tabs_on_url_change">
<option class="bg_opt_drop_down_menu" id="options_move_on_url_change_never" value="never"></option>
<option class="bg_opt_drop_down_menu" id="options_move_on_url_change_from_empty" value="from_empty"></option>
<option class="bg_opt_drop_down_menu" id="options_move_on_url_change_from_empty_b" value="from_empty_b"></option>
<option class="bg_opt_drop_down_menu" id="options_move_on_url_change_all_new" value="all_new"></option>
<option class="bg_opt_drop_down_menu" id="options_move_on_url_change_always" value="always"></option>
</select>
</li>
</ul>
<table style="display:vinline-block;">
<tr>
<td>
<input type="number" style="width:80px;" min="-1" max="9999" step="1" id="max_tree_depth"></input>
</td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_max_tree_depth"></td>
</tr>
</table>
<table style="display:vinline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="max_tree_drag_drop"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_max_tree_drag_drop"></td>
</tr>
</table>
<br>
<p style="font-size:11px; color: red;" class="hint_explanation" id="hint_orphan_tab"></p>
<ul style="list-style-type:disc; font-size:11px;">
<li class="hint_explanation" id="hint_ctrl_t"></li>
<li class="hint_explanation" id="hint_from_pin"></li>
<li class="hint_explanation" id="hint_from_bookmark"></li>
<li class="hint_explanation" id="hint_from_external_link"></li>
<li class="hint_explanation" id="hint_from_popup"></li>
</ul>
<span style="display:block; font-size:11px; color: red;" class="hint_explanation" id="hint_explained_new_tab_settings"></span>
<span style="display:block; font-size:11px; color: red;" class="hint_explanation" id="hint_explained_orphan_after_active_settings"></span>
<br>
</fieldset>
<fieldset class="field" id="field_global">
<legend class="label" id="options_global"></legend>
<table style="display:vinline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="always_show_close"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_always_show_close"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="never_show_close"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_never_show_close"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="collapse_other_trees"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_collapse_other_trees"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="open_tree_on_hover"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_open_tree_on_hover"></td>
</tr>
<tr>
<td style="position:relative;top:-5px;"><input type="checkbox" class="opt_checkbox bg_opt" id="promote_children"></input></td>
<td style="position:relative;top:-5px;left:2px;width:3px;">-</td>
<td class="label" id="options_promote_children"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="promote_children_in_first_child"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_promote_children_in_first_child"></td>
</tr>
<tr>
<td style="position:relative;top:-1px;"><input type="checkbox" class="opt_checkbox bg_opt" id="skip_load"></input></td>
<td style="position:relative;top:-1px;left:2px;width:3px;">-</td>
<td class="label" id="options_skip_load"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="show_counter_tabs"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_show_counter_tabs"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="show_counter_tabs_hints"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_show_counter_tabs_hints"></td>
</tr>
</table>
</fieldset>
<fieldset class="field" id="field_show_toolbar" style="position: relative; width:850px;">
<legend id="toolbar_legend">
<input type="checkbox" class="opt_checkbox bg_opt" style="position:relative; top:-1px;" id="show_toolbar"></input>
<label class="label" style="position:relative; top:-3px;" id="options_toolbar"></label>
</legend>
<label class="label" style="margin-top: 4px;" id="options_available_buttons"></label>
<div id="sample_toolbar_block" style="position:relative; margin: 10px; width: 355px;">
<div id="toolbar_unused_buttons" style="position: relative; background-color: #b8ffbf; height: 30px; width: 788px;"></div>
<div class="toolbar_edit" id="toolbar" style="position: relative; top: 5px; height: 26px; width: 788px; overflow:hidden;"></div>
</div>
<button class="set_button" type="button" id="options_reset_toolbar_button" style="margin:10px; margin-top:20px;">Reset</button>
</fieldset>
<fieldset class="field" id="field_theme" style="width:850px;">
<legend class="label" id="options_theme"></legend>
<select id="theme_list" style="padding-right:6px;"></select>
<input type="text" id="new_theme_name" name="untitled" value="untitled"></input>
<button class="set_button theme_buttons" type="button" id="options_rename_theme_button" style="margin:6px;">Rename</button>
<button class="set_button theme_buttons" type="button" id="options_add_theme_button" style="margin:6px;">Add new</button>
<button class="set_button theme_buttons" type="button" id="options_remove_theme_button" style="margin:6px;">Remove</button>
<button class="set_button theme_buttons" type="button" id="options_import_theme_button" style="margin:6px;">Import</button>
<button class="set_button theme_buttons" type="button" id="options_export_theme_button" style="margin:6px;">Export</button>
<button class="set_button theme_buttons" type="button" id="options_share_theme_link" style="margin:6px;">Export</button>
<br>
<br>
<fieldset class="field" id="options_toolbar_look" style="position: relative; width:816px;">
<legend id="toolbar_legend">
<label class="label" id="options_toolbar_look"></label>
</legend>
<div id="sample_toolbar_block" style="position:relative; width: 788px; margin: 10px;">
<div id="toolbar_colors_pick_block" style="position: relative; width: 788px; height: 26px;">
<div class="pick_col color_bucket" id="button_background" ></div>
<div class="pick_col color_bucket" id="button_hover_background" ></div>
<div class="pick_col color_bucket" id="button_on_background" ></div>
<div class="spacer"></div>
<div class="pick_col color_toolbar_icon" id="button_icons" ></div>
<div class="pick_col color_toolbar_icon" id="button_icons_hover" ></div>
<div class="pick_col color_toolbar_icon" id="button_on_icons" ></div>
<div class="spacer"></div>
<div class="pick_col color_border" id="button_border" ></div>
<div class="pick_col color_border" id="button_hover_border" ></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="pick_col font_color" id="filter_box_font" ></div>
<div class="pick_col color_bucket" id="filter_box_background" ></div>
<div class="pick_col color_border" id="filter_box_border" ></div>
<div class="pick_col color_x" id="filter_clear_icon" ></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="pick_col color_bucket" id="toolbar_background" ></div>
<div class="pick_col color_bucket" id="toolbar_shelf_background" ></div>
<div class="pick_col color_border" id="toolbar_border_bottom" ></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="pick_col color_bucket" id="button_shelf_background" ></div>
<div class="pick_col color_bucket" id="button_shelf_hover_background" ></div>
<div class="spacer"></div>
<div class="pick_col color_toolbar_icon" id="button_shelf_icons" ></div>
<div class="pick_col color_toolbar_icon" id="button_shelf_icons_hover" ></div>
<div class="spacer"></div>
<div class="pick_col color_border" id="button_shelf_border" ></div>
<div class="pick_col color_border" id="button_shelf_hover_border" ></div>
</div>
<div class="toolbar" id="toolbar_theme" style="position: relative; top: 5px; height: 53px; width: 788px; overflow:hidden;">
<div id="toolbar_main_theme">
<div class="button_theme" id="button_theme_plus"><div class="button_img_theme" id="button_theme_plus_img"></div></div>
<div class="button_theme" id="button_theme_search"><div class="button_img_theme" id="button_theme_search_img"></div></div>
</div>
<div id="toolbar_search_input_box_theme">
<input id="filter_box_theme" type="text" placeholder="Search tabs..."></input>
<div id="button_filter_clear_theme" style="position:absolute;" type="reset"></div>
<div class="button_shelf_theme" id="button_theme_pen"><div class="button_img_shelf_theme" id="button_theme_pen_img"></div></div>
</div>
</div>
</div>
</fieldset>
<fieldset class="field" id="Tabs" style="position: relative; top: 6px; width:816px; height: 950px;">
<legend class="label" id="options_theme_tabs"></legend>
<div id="tabs_options_block">
<div id="ff_folder1" class="tab_color_options_row">
<div class="pick_col color_bucket" id="folder_icon_open"></div>
</div>
<div id="ff_folder2" class="tab_color_options_row">
<div class="pick_col color_bucket" id="folder_icon_closed"></div>
</div>
<div id="ff_folder3" class="tab_color_options_row">
<div class="pick_col color_bucket" id="folder_icon_hover"></div>
</div>
<div id="t2" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_background"></div>
<div class="tab_col pick_col color_border" id="tab_border"></div>
</div>
<div id="t11" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_hover_border"></div>
<div class="pick_col color_x" id="close_x"></div>
</div>
<div id="t12" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_selected_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_selected_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_selected_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_selected_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_selected_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_selected_background"></div>
<div class="tab_col pick_col color_border" id="tab_selected_border"></div>
</div>
<div id="t13" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_selected_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_selected_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_selected_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_selected_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_selected_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_selected_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_selected_hover_border"></div>
<div class="pick_col color_x" id="close_hover_x"></div>
<div class="pick_col color_border" id="close_hover_border"></div>
<div class="pick_col color_bucket" id="close_hover_background"></div>
</div>
<div id="t3" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_active_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_active_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_active_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_active_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_active_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_active_background"></div>
<div class="tab_col pick_col color_border" id="tab_active_border"></div>
</div>
<div id="t15" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_active_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_active_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_active_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_active_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_active_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_active_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_active_hover_border"></div>
</div>
<div id="t14" class="tab_color_options_row">
<div class="pick_col color_bucket" id="expand_closed_background"></div>
<div class="tab_col pick_col font_color" id="tab_active_selected_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_active_selected_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_active_selected_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_active_selected_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_active_selected_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_active_selected_background"></div>
<div class="tab_col pick_col color_border" id="tab_active_selected_border"></div>
</div>
<div id="t16" class="tab_color_options_row">
<div class="pick_col color_bucket" id="expand_hover_background"></div>
<div class="tab_col pick_col font_color" id="tab_selected_active_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_selected_active_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_selected_active_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_selected_active_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_selected_active_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_selected_active_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_selected_active_hover_border"></div>
</div>
<div id="t5" class="tab_color_options_row">
<div class="pick_col color_bucket" id="expand_open_background"></div>
<div class="tab_col pick_col font_color" id="tab_discarded_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_discarded_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_discarded_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_discarded_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_discarded_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_discarded_background"></div>
<div class="tab_col pick_col color_border" id="tab_discarded_border"></div>
</div>
<div id="t17" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_discarded_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_discarded_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_discarded_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_discarded_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_discarded_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_discarded_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_discarded_hover_border"></div>
</div>
<div id="t19" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_selected_discarded_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_selected_discarded_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_selected_discarded_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_selected_discarded_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_selected_discarded_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_selected_discarded_background"></div>
<div class="tab_col pick_col color_border" id="tab_selected_discarded_border"></div>
<div class="pick_col color_bucket" id="drag_indicator"></div>
</div>
<div id="t20" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_selected_discarded_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_selected_discarded_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_selected_discarded_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_selected_discarded_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_selected_discarded_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_selected_discarded_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_selected_discarded_hover_border"></div>
</div>
<div id="t6" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_border"></div>
</div>
<div id="t21" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_hover_border"></div>
</div>
<div id="t22" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_active_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_active_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_active_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_active_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_active_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_active_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_active_border"></div>
</div>
<div id="t23" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_active_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_active_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_active_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_active_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_active_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_active_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_active_hover_border"></div>
</div>
<div id="t8" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_border"></div>
</div>
<div id="t18" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_hover_border"></div>
</div>
<div id="t25" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_active_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_active_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_active_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_active_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_active_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_active_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_active_border"></div>
</div>
<div id="t26" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_active_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_active_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_active_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_active_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_active_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_active_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_active_hover_border"></div>
</div>
<div id="t30" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_highlighted_search_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_highlighted_search_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_highlighted_search_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_highlighted_search_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_highlighted_search_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_highlighted_search_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_highlighted_search_border"></div>
</div>
<div id="t31" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_highlighted_search_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_highlighted_search_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_highlighted_search_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_highlighted_search_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_highlighted_search_hover_border"></div>
</div>
<div id="t32" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_active_highlighted_search_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_active_highlighted_search_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_active_highlighted_search_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_active_highlighted_search_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_active_highlighted_search_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_active_highlighted_search_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_active_highlighted_search_border"></div>
</div>
<div id="t33" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_active_highlighted_search_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_active_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_active_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_active_highlighted_search_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_active_highlighted_search_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_active_highlighted_search_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_active_highlighted_search_hover_border"></div>
</div>
<div id="t34" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_highlighted_search_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_highlighted_search_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_highlighted_search_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_highlighted_search_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_highlighted_search_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_highlighted_search_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_highlighted_search_border"></div>
</div>
<div id="t35" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_highlighted_search_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_highlighted_search_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_highlighted_search_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_highlighted_search_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_highlighted_search_hover_border"></div>
</div>
<div id="t36" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_active_highlighted_search_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_active_highlighted_search_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_active_highlighted_search_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_active_highlighted_search_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_active_highlighted_search_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_active_highlighted_search_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_active_highlighted_search_border"></div>
</div>
<div id="t37" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_active_highlighted_search_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_active_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_active_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_active_highlighted_search_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_active_highlighted_search_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_active_highlighted_search_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_active_highlighted_search_hover_border"></div>
</div>
</div>
<div id="scrollbar_size_indicator">
<div class="options_button_minus" id="options_tab_list_scrollbar_width_down"></div>
<div class="options_button_plus" id="options_tab_list_scrollbar_width_up"></div>
<div class="options_button_minus" id="options_tab_list_scrollbar_height_down"></div>
<div class="options_button_plus" id="options_tab_list_scrollbar_height_up"></div>
</div>
<div class="pick_col color_bucket" id="scrollbar_thumb"></div>
<div class="pick_col color_bucket pick_col_hover" id="scrollbar_thumb_hover"></div>
<div class="pick_col color_bucket" id="scrollbar_track"></div>
<div class="pin_list" id="pin_list"></div>
<div id="groups">
<div class="group" id="tab_list">
<div class="children_folders" id="cftab_list"></div>
<div class="children_tabs" id="cttab_list"></div>
</div>
</div>
<div id="pin_list_scrollbar"><div id="pin_list_scrollbar_thumb"></div></div>
<div id="group_scrollbar"><div id="group_scrollbar_thumb"></div></div>
<div class="pick_col color_bucket" id="group_list_background"></div>
<div class="pick_col color_border" id="group_list_borders"></div>
<div class="pick_col color_bucket pick_col_hover" id="group_list_button_hover_background"></div>
<div class="pick_col font_color" id="group_list_default_font_color"></div>
<div id="toolbar_groups_block">
<div class="scroll_group" id="scroll_group_up"></div>
<div class="group_list" id="group_list"></div>
<div class="scroll_group" id="scroll_group_down"></div>
</div>
<div id="options_tabs_margins_indicator">
<form action="" id="tabs_margin_spacing" style="position:absolute; left:4px; top:12px;">
<input type="radio" class="tabs_margin_spacing" id="options_tabs_margin_overlap" name="tabs_margin_spacing" value="overlap"></input>
<input type="radio" class="tabs_margin_spacing" id="options_tabs_margin_0" name="tabs_margin_spacing" value="no_space"></input>
<input type="radio" class="tabs_margin_spacing" id="options_tabs_margin_1" name="tabs_margin_spacing" value="1px_space"></input>
</form>
</div>
<div id="options_tabs_indentation_indicator">
<div class="options_button_minus" id="options_tabs_indentation_down"></div>
<div class="options_button_plus" id="options_tabs_indentation_up"></div>
</div>
<div id="options_tabs_roundness_indicator">
<div class="options_button_minus" id="options_tabs_roundness_down"></div>
<div class="options_button_plus" id="options_tabs_roundness_up"></div>
</div>
<div id="options_tabs_size_indicator">
<div class="options_button_minus" id="options_tabs_size_down"></div>
<div class="options_button_plus" id="options_tabs_size_up"></div>
</div>
<div id="pin_list_options_block">
<div class="pick_col color_bucket" id="attention_background"></div>
<div class="pick_col color_border" id="attention_border"></div>
<div class="pick_col color_border" id="pin_list_border_bottom"></div>
<div class="pick_col color_bucket" id="pin_list_background"></div>
</div>
<div class="pick_col color_bucket" id="tab_list_background"></div>
</fieldset>
<fieldset class="field" style="width:816px;">
<legend class="label" id="options_menu"></legend>
<div id="menu_options_block" style="position:relative; top:0px; left:10px;">
<div class="pick_col color_border" id="tabs_menu_border"></div>
<div class="pick_col color_bucket" id="tabs_menu_background"></div>
<div class="pick_col font_color" id="tabs_menu_font"></div>
<div class="pick_col color_border" id="tabs_menu_hover_border"></div>
<div class="pick_col color_bucket" id="tabs_menu_hover_background"></div>
<div class="pick_col color_border" id="tabs_menu_separator"></div>
</div>
<ul class="menu" id="tabs_menu" style="display:inline-block;position:relative;top:0px;left:10px;">
<li class="menu_item" id="menu_hover_sample"></li>
<div class="separator" id="menu_separator1"></div>
<li class="menu_item" id="menu_sample1"></li>
<div class="separator" id="menu_separator2"></div>
<li class="menu_item" id="menu_sample2"></li>
</ul>
</fieldset>
</fieldset>
<fieldset class="field"">
<legend class="label" id="options_development"></legend>
<table style="display:inline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="debug"></input></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_debug"></td>
</tr>
</table>
<br>
<button class="set_button" type="button" id="options_export_debug" style="position: relative; margin:10px;"></button>
<button class="set_button" type="button" id="options_print_debug" style="position: relative; margin:10px;"></button>
</fieldset>
<button class="set_button" type="button" id="options_clear_data" style="margin:10px;"></button>
<input type="color" id="color_picker" style="position:absolute; left:-1000px; top:-1000px; width:1px; height:1px; overflow:hidden;">
<div id="DragImage" style="display: none; width:0px; height:0px;"></div>
<script type="text/javascript" src="scripts/common.js"></script>
<script type="text/javascript" src="scripts/utils.js"></script>
<script type="text/javascript" src="scripts/toolbar.js"></script>
<script type="text/javascript" src="scripts/tabs.js"></script>
<script type="text/javascript" src="scripts/groups.js"></script>
<script type="text/javascript" src="scripts/folders.js"></script>
<script type="text/javascript" src="scripts/theme.js"></script>
<script type="text/javascript" src="options/sample_tabs.js"></script>
<script type="text/javascript" src="options/options.js"></script>
<div id="donate"></div>
<div id="donate_paypal" class="donation_button"></div>
<div id="donate_litecoin" class="donation_button"></div>
<div id="donate_bitcoin" class="donation_button"></div>
<div id="donate_ethereum" class="donation_button"></div>
</body>
</html>

View File

@ -425,7 +425,7 @@ ul:not(.menu) li {
/* TAB LIST AND SCROLLBAR */ /* TAB LIST AND SCROLLBAR */
#groups { #groups {
position: absolute; position: absolute;
height: 850px; height: calc(100% - var(--pin_height) - 80px);
width: calc(771px - var(--scrollbar_width)); width: calc(771px - var(--scrollbar_width));
top: calc(var(--scrollbar_height) + var(--pin_height) + 33px); top: calc(var(--scrollbar_height) + var(--pin_height) + 33px);
left: 40px; left: 40px;
@ -434,7 +434,7 @@ ul:not(.menu) li {
#group_scrollbar { #group_scrollbar {
position: absolute; position: absolute;
height: 850px; height: calc(100% - var(--pin_height) - 80px);
width: var(--scrollbar_width); width: var(--scrollbar_width);
top: calc(var(--scrollbar_height) + var(--pin_height) + 33px); top: calc(var(--scrollbar_height) + var(--pin_height) + 33px);
left: calc(810px - var(--scrollbar_width)); left: calc(810px - var(--scrollbar_width));
@ -602,7 +602,7 @@ ul:not(.menu) li {
left: 20px; left: 20px;
top: calc(var(--scrollbar_height) + var(--pin_height) + 33px); top: calc(var(--scrollbar_height) + var(--pin_height) + 33px);
width: 19px; width: 19px;
height: 850px; height: calc(100% - var(--pin_height) - 80px);
background-color: var(--group_list_background); background-color: var(--group_list_background);
border-right: 1px solid var(--group_list_borders); border-right: 1px solid var(--group_list_borders);
overflow: visible; overflow: visible;

905
options/options.html Normal file
View File

@ -0,0 +1,905 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_0.css" id="sizes_preset_0" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_1.css" id="sizes_preset_1" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_2.css" id="sizes_preset_2" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_3.css" id="sizes_preset_3" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_4.css" id="sizes_preset_4" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_size_preset_5.css" id="sizes_preset_5" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_tabs_margin_0.css" id="tabs_margin_0" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_tabs_margin_1.css" id="tabs_margin_1" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_tabs_margin_2.css" id="tabs_margin_2" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_colors.css" id="theme_colors" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme.css" id="theme" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_blinking_attention.css" id="blinking_pins" />
<link type="text/css" rel="stylesheet" media="all" href="../theme/theme_blinking_audio.css" id="blinking_audio" />
<link type="text/css" rel="stylesheet" media="all" href="./options.css" id="main_body_css" />
<style rel="stylesheet">
#red_higlights_go_here {
background-color: transparent;
}
</style>
<link type="text/css" rel="stylesheet" media="all" href="./options_overwrite.css" id="overwrite" />
</head>
<body id="body" class="options_body">
<div style="width:850px; align:left;"><span style="width:100%; font-size:20px; display:inline-block; text-align:center;">Tree Tabs</span></div>
<br>
<fieldset class="field" id="field_vivaldi" style="display:none;">
<legend class="label" id="options_vivaldi"></legend>
<table>
<tr>
<td class="label" id="opt_url_for_web_panel"></td>
<td><input style="position:relative;width:450px;left:8px;" type="text" id="url_for_web_panel" value=""/></td>
<td><div style="position:relative; width:20px; height: 20px; left:8px; background-size: 20px 20px; background-image: url(./options_copy_icon.png);" id="copy_vivaldi_url_for_web_panel" ></div></td>
</tr>
</table>
</fieldset>
<fieldset class="field" id="field_pins">
<legend class="label" id="options_pinned" ></legend>
<table style="display:inline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="pin_list_multi_row"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_pin_list_multi_row"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="allow_pin_close"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="option_allow_pin_close"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="pin_attention_blinking"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="option_pin_attention_blinking"></td>
</tr>
</table>
</fieldset>
<fieldset class="field" id="field_groups">
<legend class="label" id="options_groups"></legend>
<table style="display:vinline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="groups_toolbar_default"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_groups_toolbar_default"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="show_counter_groups"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_show_counter_groups"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="syncro_tabbar_groups_tabs_order"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_syncro_tabbar_groups_tabs_order"></td>
</tr>
<tr id="firefox_option_hide_other_groups_tabs_firefox">
<td><input type="checkbox" class="opt_checkbox bg_opt" id="hide_other_groups_tabs_firefox"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_hide_other_groups_tabs_firefox"></td>
</tr>
</table>
<ul>
<li>
<label class="label" id="options_midclick_group"></label>
<select id="midclick_group">
<option class="bg_opt_drop_down_menu" id="options_action_group_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_new" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_undo_close_tab" value="undo_close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_activate_previous_active" value="activate_previous_active"></option>
</select>
</li>
<li>
<label class="label" id="options_dbclick_group"></label>
<select id="dbclick_group">
<option class="bg_opt_drop_down_menu" id="options_action_group_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_new" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_undo_close_tab" value="undo_close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_group_activate_previous_active" value="activate_previous_active"></option>
</select>
</li>
</ul>
</fieldset>
<fieldset class="field" id="field_folders">
<legend class="label" id="options_folders"></legend>
<ul>
<li>
<label class="label" id="options_midclick_folder"></label>
<select id="midclick_folder">
<option class="bg_opt_drop_down_menu" id="options_action_folder_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_rename" value="rename_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_new_folder" value="new_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_new_tab" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_expand_collapse" value="expand_collapse"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_close" value="close_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_unload" value="unload_folder"></option>
</select>
</li>
<li>
<label class="label" id="options_dbclick_folder"></label>
<select id="dbclick_folder">
<option class="bg_opt_drop_down_menu" id="options_action_folder_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_rename" value="rename_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_new_folder" value="new_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_new_tab" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_expand_collapse" value="expand_collapse"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_close" value="close_folder"></option>
<option class="bg_opt_drop_down_menu" id="options_action_folder_unload" value="unload_folder"></option>
</select>
</li>
</ul>
<!--
<table style="display:vinline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="max_tree_drag_drop_folders"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_max_tree_drag_drop_folders"></td>
</tr>
</table>
-->
</fieldset>
<fieldset class="field" id="field_tabs">
<legend class="label" id="options_tabs"></legend>
<ul>
<li>
<label class="label" id="options_midclick_tab"></label>
<select id="midclick_tab">
<option class="bg_opt_drop_down_menu" id="options_action_tab_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_new" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_expand_collapse" value="expand_collapse"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_close" value="close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_undo_close" value="undo_close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_reload" value="reload_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_unload" value="unload_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_activate_previous_active" value="activate_previous_active"></option>
</select>
</li>
<li>
<label class="label" id="options_dbclick_tab"></label>
<select id="dbclick_tab">
<option class="bg_opt_drop_down_menu" id="options_action_tab_none" value="nothing"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_new" value="new_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_expand_collapse" value="expand_collapse"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_close" value="close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_undo_close" value="undo_close_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_reload" value="reload_tab"></option>
<option class="bg_opt_drop_down_menu" id="options_action_tab_activate_previous_active" value="activate_previous_active"></option>
</select>
</li>
</ul>
<table style="display:vinline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="syncro_tabbar_tabs_order"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_syncro_tabbar_tabs_order"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="switch_with_scroll"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_switch_with_scroll"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="orphaned_tabs_to_ungrouped"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_orphaned_tabs_to_ungrouped"></td>
</tr>
</table>
<p style="position: relative; top: -10px; left: 40px; font-size:11px; color: #c71414;" class="hint_explanation" id="hint_orphan_tab"></p>
<ul style="position: relative; top: -14px; left: 30px; list-style-type:disc; font-size:11px; color: #c71414;">
<li class="hint_explanation" id="hint_ctrl_t"></li>
<li class="hint_explanation" id="hint_from_pin"></li>
<li class="hint_explanation" id="hint_from_bookmark"></li>
<li class="hint_explanation" id="hint_from_external_link"></li>
<li class="hint_explanation" id="hint_from_popup"></li>
<li class="hint_explanation" id="hint_explained_new_tab_settings"></li>
</ul>
<ul>
<li>
<label class="label" id="options_append_pinned_tab"></label>
<select id="append_pinned_tab">
<option class="bg_opt_drop_down_menu" id="options_append_pinned_tab_first" value="first"></option>
<option class="bg_opt_drop_down_menu" id="options_append_pinned_tab_after" value="after"></option>
<option class="bg_opt_drop_down_menu" id="options_append_pinned_tab_last" value="last"></option>
</select>
</li>
<li>
<label class="label" id="options_append_child_tab"></label>
<select id="append_child_tab">
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_top" value="top"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_bottom" value="bottom"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after" value="after"></option>
</select>
</li>
<li id="append_child_tab_after_limit_dropdown">
<label class="label" id="options_append_child_tab_after_limit"></label>
<select id="append_child_tab_after_limit">
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_top" value="top"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_after" value="after"></option>
<option class="bg_opt_drop_down_menu" id="options_append_child_tab_after_limit_bottom" value="bottom"></option>
</select>
</li>
<li>
<label class="label" id="options_append_orphan_tab"></label>
<select id="append_orphan_tab">
<option class="bg_opt_drop_down_menu" id="options_append_orphan_tab_top" value="top"></option>
<option class="bg_opt_drop_down_menu" id="options_append_orphan_tab_bottom" value="bottom"></option>
<option class="bg_opt_drop_down_menu" id="options_append_orphan_tab_after_active" value="after_active"></option>
<option class="bg_opt_drop_down_menu" id="options_append_orphan_tab_active_parent_top" value="active_parent_top"></option>
<option class="bg_opt_drop_down_menu" id="options_append_orphan_tab_active_parent_bottom" value="active_parent_bottom"></option>
<option class="bg_opt_drop_down_menu" id="options_append_orphan_tab_as_child" value="as_child"></option>
</select>
<span style="position: relative; left: 6px; display:block; font-size:10px; color: #c71414;" class="hint_explanation" id="hint_explained_orphan_after_active_settings"></span>
</li>
<li>
<label class="label" id="options_toolbar_new_tab"></label>
<select id="append_tab_from_toolbar">
<option class="bg_opt_drop_down_menu" id="options_toolbar_new_tab_as_regular_orphan" value="as_regular_orphan"></option>
<option class="bg_opt_drop_down_menu" id="options_toolbar_new_tab_root_of_group" value="group_root"></option>
</select>
</li>
<li>
<label class="label" id="options_after_closing_active_tab"></label>
<select id="after_closing_active_tab">
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_up" value="above"></option>
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_down" value="below"></option>
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_up_seek_in_parent" value="above_seek_in_parent"></option>
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_down_seek_in_parent" value="below_seek_in_parent"></option>
<option class="bg_opt_drop_down_menu" id="options_after_closing_active_tab_go_browser" value="browser"></option>
</select>
</li>
<li>
<label class="label" id="options_tab_group_regex"></label><br>
<br><span class="regexLabel">
<label class="label" id="option_tab_match"></label>
</span>
<span class="regexLabel">
<label class="label" id="option_tab_group" style="width:200px"></label>
</span>
<div id="tab_group_regexes"></div>
<button class="set_button" type="button" id="add_tab_group_regex" style="margin:6px;"></button>
</li>
<li>
<label class="label" id="options_move_on_url_change"></label>
<select id="move_tabs_on_url_change">
<option class="bg_opt_drop_down_menu" id="options_move_on_url_change_never" value="never"></option>
<option class="bg_opt_drop_down_menu" id="options_move_on_url_change_from_empty" value="from_empty"></option>
<option class="bg_opt_drop_down_menu" id="options_move_on_url_change_from_empty_b" value="from_empty_b"></option>
<option class="bg_opt_drop_down_menu" id="options_move_on_url_change_all_new" value="all_new"></option>
<option class="bg_opt_drop_down_menu" id="options_move_on_url_change_always" value="always"></option>
</select>
</li>
</ul>
<table style="display:vinline-block;">
<tr>
<td>
<input type="number" style="width:80px;" min="-1" max="9999" step="1" id="max_tree_depth"/>
</td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_max_tree_depth"></td>
</tr>
</table>
<table style="display:vinline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="max_tree_drag_drop"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_max_tree_drag_drop"></td>
</tr>
</table>
</fieldset>
<fieldset class="field" id="field_global">
<legend class="label" id="options_global"></legend>
<table style="display:vinline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="audio_blinking"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="option_audio_blinking"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="always_show_close"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_always_show_close"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="never_show_close"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_never_show_close"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="collapse_other_trees"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_collapse_other_trees"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="open_tree_on_hover"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_open_tree_on_hover"></td>
</tr>
<tr>
<td style="position:relative;top:-5px;"><input type="checkbox" class="opt_checkbox bg_opt" id="promote_children"/></td>
<td style="position:relative;top:-5px;left:2px;width:3px;">-</td>
<td class="label" id="options_promote_children"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="promote_children_in_first_child"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_promote_children_in_first_child"></td>
</tr>
<tr>
<td style="position:relative;top:-1px;"><input type="checkbox" class="opt_checkbox bg_opt" id="skip_load"/></td>
<td style="position:relative;top:-1px;left:2px;width:3px;">-</td>
<td class="label" id="options_skip_load"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="show_counter_tabs"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_show_counter_tabs"></td>
</tr>
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="show_counter_tabs_hints"/></td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_show_counter_tabs_hints"></td>
</tr>
</table>
</fieldset>
<fieldset class="field" id="field_show_toolbar" style="position: relative; width:850px;">
<legend id="toolbar_legend">
<input type="checkbox" class="opt_checkbox bg_opt" style="position:relative; top:-1px;" id="show_toolbar"/>
<label class="label" style="position:relative; top:-3px;" id="options_toolbar"></label>
</legend>
<label class="label" style="margin-top: 4px;" id="options_available_buttons"></label>
<div id="sample_toolbar_block" style="position:relative; margin: 10px; width: 355px;">
<div id="toolbar_unused_buttons" style="position: relative; background-color: #b8ffbf; height: 30px; width: 788px;"></div>
<div class="toolbar_edit" id="toolbar" style="position: relative; top: 5px; height: 26px; width: 788px; overflow:hidden;"></div>
</div>
<button class="set_button" type="button" id="options_reset_toolbar_button" style="margin:10px; margin-top:20px;">Reset</button>
</fieldset>
<fieldset class="field" id="field_theme" style="width:850px;">
<legend class="label" id="options_theme"></legend>
<select id="theme_list" style="padding-right:6px;"></select>
<input type="text" id="new_theme_name" name="untitled" value="untitled"/>
<button class="set_button theme_buttons" type="button" id="options_rename_theme_button" style="margin:6px;">Rename</button>
<button class="set_button theme_buttons" type="button" id="options_add_theme_button" style="margin:6px;">Add new</button>
<button class="set_button theme_buttons" type="button" id="options_remove_theme_button" style="margin:6px;">Remove</button>
<button class="set_button theme_buttons" type="button" id="options_import_theme_button" style="margin:6px;">Import</button>
<button class="set_button theme_buttons" type="button" id="options_export_theme_button" style="margin:6px;">Export</button>
<button class="set_button theme_buttons" type="button" id="options_share_theme_link" style="margin:6px;">Export</button>
<br>
<br>
<fieldset class="field" id="options_toolbar_look" style="position: relative; width:816px;">
<legend id="toolbar_legend">
<label class="label" id="options_toolbar_look"></label>
</legend>
<div id="sample_toolbar_block" style="position:relative; width: 788px; margin: 10px;">
<div id="toolbar_colors_pick_block" style="position: relative; width: 788px; height: 26px;">
<div class="pick_col color_bucket" id="button_background" ></div>
<div class="pick_col color_bucket" id="button_hover_background" ></div>
<div class="pick_col color_bucket" id="button_on_background" ></div>
<div class="spacer"></div>
<div class="pick_col color_toolbar_icon" id="button_icons" ></div>
<div class="pick_col color_toolbar_icon" id="button_icons_hover" ></div>
<div class="pick_col color_toolbar_icon" id="button_on_icons" ></div>
<div class="spacer"></div>
<div class="pick_col color_border" id="button_border" ></div>
<div class="pick_col color_border" id="button_hover_border" ></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="pick_col font_color" id="filter_box_font" ></div>
<div class="pick_col color_bucket" id="filter_box_background" ></div>
<div class="pick_col color_border" id="filter_box_border" ></div>
<div class="pick_col color_x" id="filter_clear_icon" ></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="pick_col color_bucket" id="toolbar_background" ></div>
<div class="pick_col color_bucket" id="toolbar_shelf_background" ></div>
<div class="pick_col color_border" id="toolbar_border_bottom" ></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="pick_col color_bucket" id="button_shelf_background" ></div>
<div class="pick_col color_bucket" id="button_shelf_hover_background" ></div>
<div class="spacer"></div>
<div class="pick_col color_toolbar_icon" id="button_shelf_icons" ></div>
<div class="pick_col color_toolbar_icon" id="button_shelf_icons_hover" ></div>
<div class="spacer"></div>
<div class="pick_col color_border" id="button_shelf_border" ></div>
<div class="pick_col color_border" id="button_shelf_hover_border" ></div>
</div>
<div class="toolbar" id="toolbar_theme" style="position: relative; top: 5px; height: 53px; width: 788px; overflow:hidden;">
<div id="toolbar_main_theme">
<div class="button_theme" id="button_theme_plus"><div class="button_img_theme" id="button_theme_plus_img"></div></div>
<div class="button_theme" id="button_theme_search"><div class="button_img_theme" id="button_theme_search_img"></div></div>
</div>
<div id="toolbar_search_input_box_theme">
<input id="filter_box_theme" type="text" placeholder="Search tabs..."/>
<div id="button_filter_clear_theme" style="position:absolute;" type="reset"></div>
<div class="button_shelf_theme" id="button_theme_pen"><div class="button_img_shelf_theme" id="button_theme_pen_img"></div></div>
</div>
</div>
</div>
</fieldset>
<fieldset class="field" id="Tabs" style="position: relative; top: 6px; width:816px; height: 1050px;">
<legend class="label" id="options_theme_tabs"></legend>
<div id="tabs_options_block">
<div id="ff_folder1" class="tab_color_options_row">
<div class="pick_col color_bucket" id="folder_icon_open"></div>
</div>
<div id="ff_folder2" class="tab_color_options_row">
<div class="pick_col color_bucket" id="folder_icon_closed"></div>
</div>
<div id="ff_folder3" class="tab_color_options_row">
<div class="pick_col color_bucket" id="folder_icon_hover"></div>
</div>
<div id="t2" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_background"></div>
<div class="tab_col pick_col color_border" id="tab_border"></div>
</div>
<div id="t11" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_hover_border"></div>
<div class="pick_col color_x" id="close_x"></div>
</div>
<div id="t12" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_selected_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_selected_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_selected_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_selected_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_selected_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_selected_background"></div>
<div class="tab_col pick_col color_border" id="tab_selected_border"></div>
</div>
<div id="t13" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_selected_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_selected_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_selected_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_selected_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_selected_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_selected_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_selected_hover_border"></div>
<div class="pick_col color_x" id="close_hover_x"></div>
<div class="pick_col color_border" id="close_hover_border"></div>
<div class="pick_col color_bucket" id="close_hover_background"></div>
</div>
<div id="t3" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_active_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_active_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_active_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_active_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_active_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_active_background"></div>
<div class="tab_col pick_col color_border" id="tab_active_border"></div>
</div>
<div id="t15" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_active_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_active_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_active_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_active_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_active_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_active_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_active_hover_border"></div>
</div>
<div id="t14" class="tab_color_options_row">
<div class="pick_col color_bucket" id="expand_closed_background"></div>
<div class="tab_col pick_col font_color" id="tab_active_selected_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_active_selected_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_active_selected_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_active_selected_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_active_selected_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_active_selected_background"></div>
<div class="tab_col pick_col color_border" id="tab_active_selected_border"></div>
</div>
<div id="t16" class="tab_color_options_row">
<div class="pick_col color_bucket" id="expand_hover_background"></div>
<div class="tab_col pick_col font_color" id="tab_selected_active_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_selected_active_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_selected_active_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_selected_active_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_selected_active_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_selected_active_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_selected_active_hover_border"></div>
</div>
<div id="t5" class="tab_color_options_row">
<div class="pick_col color_bucket" id="expand_open_background"></div>
<div class="tab_col pick_col font_color" id="tab_discarded_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_discarded_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_discarded_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_discarded_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_discarded_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_discarded_background"></div>
<div class="tab_col pick_col color_border" id="tab_discarded_border"></div>
</div>
<div id="t17" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_discarded_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_discarded_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_discarded_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_discarded_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_discarded_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_discarded_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_discarded_hover_border"></div>
</div>
<div id="t19" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_selected_discarded_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_selected_discarded_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_selected_discarded_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_selected_discarded_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_selected_discarded_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_selected_discarded_background"></div>
<div class="tab_col pick_col color_border" id="tab_selected_discarded_border"></div>
<div class="pick_col color_bucket" id="drag_indicator"></div>
</div>
<div id="t20" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_selected_discarded_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_selected_discarded_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_selected_discarded_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_selected_discarded_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_selected_discarded_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_selected_discarded_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_selected_discarded_hover_border"></div>
</div>
<div id="t6" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_border"></div>
</div>
<div id="t21" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_hover_border"></div>
</div>
<div id="t22" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_active_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_active_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_active_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_active_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_active_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_active_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_active_border"></div>
</div>
<div id="t23" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_active_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_active_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_active_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_active_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_active_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_active_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_active_hover_border"></div>
</div>
<div id="t8" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_border"></div>
</div>
<div id="t18" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_hover_border"></div>
</div>
<div id="t25" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_active_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_active_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_active_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_active_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_active_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_active_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_active_border"></div>
</div>
<div id="t26" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_active_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_active_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_active_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_active_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_active_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_active_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_active_hover_border"></div>
</div>
<div id="t30" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_highlighted_search_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_highlighted_search_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_highlighted_search_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_highlighted_search_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_highlighted_search_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_highlighted_search_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_highlighted_search_border"></div>
</div>
<div id="t31" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_highlighted_search_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_highlighted_search_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_highlighted_search_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_highlighted_search_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_highlighted_search_hover_border"></div>
</div>
<div id="t32" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_active_highlighted_search_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_active_highlighted_search_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_active_highlighted_search_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_active_highlighted_search_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_active_highlighted_search_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_active_highlighted_search_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_active_highlighted_search_border"></div>
</div>
<div id="t33" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_active_highlighted_search_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_active_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_active_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_active_highlighted_search_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_active_highlighted_search_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_active_highlighted_search_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_active_highlighted_search_hover_border"></div>
</div>
<div id="t34" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_highlighted_search_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_highlighted_search_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_highlighted_search_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_highlighted_search_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_highlighted_search_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_highlighted_search_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_highlighted_search_border"></div>
</div>
<div id="t35" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_highlighted_search_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_highlighted_search_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_highlighted_search_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_highlighted_search_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_highlighted_search_hover_border"></div>
</div>
<div id="t36" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_active_highlighted_search_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_active_highlighted_search_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_active_highlighted_search_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_active_highlighted_search_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_active_highlighted_search_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_active_highlighted_search_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_active_highlighted_search_border"></div>
</div>
<div id="t37" class="tab_color_options_row">
<div class="tab_col pick_col font_color" id="tab_filtered_selected_active_highlighted_search_hover_title_font_color"></div>
<div class="tab_col font_weight_normal" id="tab_filtered_selected_active_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_weight_bold" id="tab_filtered_selected_active_highlighted_search_hover_title_font_weight"></div>
<div class="tab_col font_style_normal" id="tab_filtered_selected_active_highlighted_search_hover_title_font_style"></div>
<div class="tab_col font_style_italic" id="tab_filtered_selected_active_highlighted_search_hover_title_font_style"></div>
<div class="tab_col pick_col color_bucket" id="tab_filtered_selected_active_highlighted_search_hover_background"></div>
<div class="tab_col pick_col color_border" id="tab_filtered_selected_active_highlighted_search_hover_border"></div>
</div>
</div>
<div id="scrollbar_size_indicator">
<div class="options_button_minus" id="options_tab_list_scrollbar_width_down"></div>
<div class="options_button_plus" id="options_tab_list_scrollbar_width_up"></div>
<div class="options_button_minus" id="options_tab_list_scrollbar_height_down"></div>
<div class="options_button_plus" id="options_tab_list_scrollbar_height_up"></div>
</div>
<div class="pick_col color_bucket" id="scrollbar_thumb"></div>
<div class="pick_col color_bucket pick_col_hover" id="scrollbar_thumb_hover"></div>
<div class="pick_col color_bucket" id="scrollbar_track"></div>
<div class="pin_list" id="pin_list"></div>
<div id="groups">
<div class="group" id="tab_list">
<div class="children" id="°tab_list"></div>
</div>
</div>
<div id="pin_list_scrollbar"><div id="pin_list_scrollbar_thumb"></div></div>
<div id="group_scrollbar"><div id="group_scrollbar_thumb"></div></div>
<div class="pick_col color_bucket" id="group_list_background"></div>
<div class="pick_col color_border" id="group_list_borders"></div>
<div class="pick_col color_bucket pick_col_hover" id="group_list_button_hover_background"></div>
<div class="pick_col font_color" id="group_list_default_font_color"></div>
<div id="toolbar_groups_block">
<div class="scroll_group" id="scroll_group_up"></div>
<div class="group_list" id="group_list"></div>
<div class="scroll_group" id="scroll_group_down"></div>
</div>
<div id="options_tabs_margins_indicator">
<form action="" id="tabs_margin_spacing" style="position:absolute; left:4px; top:12px;">
<input type="radio" class="tabs_margin_spacing" id="options_tabs_margin_overlap" name="tabs_margin_spacing" value="overlap"/>
<input type="radio" class="tabs_margin_spacing" id="options_tabs_margin_0" name="tabs_margin_spacing" value="no_space"/>
<input type="radio" class="tabs_margin_spacing" id="options_tabs_margin_1" name="tabs_margin_spacing" value="1px_space"/>
</form>
</div>
<div id="options_tabs_indentation_indicator">
<div class="options_button_minus" id="options_tabs_indentation_down"></div>
<div class="options_button_plus" id="options_tabs_indentation_up"></div>
</div>
<div id="options_tabs_roundness_indicator">
<div class="options_button_minus" id="options_tabs_roundness_down"></div>
<div class="options_button_plus" id="options_tabs_roundness_up"></div>
</div>
<div id="options_tabs_size_indicator">
<div class="options_button_minus" id="options_tabs_size_down"></div>
<div class="options_button_plus" id="options_tabs_size_up"></div>
</div>
<div id="pin_list_options_block">
<div class="pick_col color_bucket" id="attention_background"></div>
<div class="pick_col color_border" id="attention_border"></div>
<div class="pick_col color_border" id="pin_list_border_bottom"></div>
<div class="pick_col color_bucket" id="pin_list_background"></div>
</div>
<div class="pick_col color_bucket" id="tab_list_background"></div>
</fieldset>
<fieldset class="field" style="width:816px;">
<legend class="label" id="options_menu"></legend>
<div id="menu_options_block" style="position:relative; top:0px; left:10px;">
<div class="pick_col color_border" id="tabs_menu_border"></div>
<div class="pick_col color_bucket" id="tabs_menu_background"></div>
<div class="pick_col font_color" id="tabs_menu_font"></div>
<div class="pick_col color_border" id="tabs_menu_hover_border"></div>
<div class="pick_col color_bucket" id="tabs_menu_hover_background"></div>
<div class="pick_col color_border" id="tabs_menu_separator"></div>
</div>
<ul class="menu" id="tabs_menu" style="display:inline-block;position:relative;top:0px;left:10px;">
<li class="menu_item" id="menu_hover_sample"></li>
<div class="separator" id="menu_separator1"></div>
<li class="menu_item" id="menu_sample1"></li>
<div class="separator" id="menu_separator2"></div>
<li class="menu_item" id="menu_sample2"></li>
</ul>
</fieldset>
</fieldset>
<fieldset class="field">
<legend class="label" id="options_development"></legend>
<table style="display:inline-block;">
<tr>
<td><input type="checkbox" class="opt_checkbox bg_opt" id="debug"/>
</td>
<td style="position:relative;left:2px;width:3px;">-</td>
<td class="label" id="options_debug"></td>
</tr>
</table>
<br>
<button class="set_button" type="button" id="options_export_debug" style="position: relative; margin:10px;"></button>
<button class="set_button" type="button" id="options_print_debug" style="position: relative; margin:10px;"></button>
<br>
<a href="../translator/translator.html">Your language is not available? Can you help? Translate here.</a>
<br>
<a href="https://drive.google.com/drive/u/1/folders/0B3jXQpRtOfvSelFrTEVHZEx3Nms">Themes</a>
<br>
<a href="https://forum.vivaldi.net/topic/15332/tree-tabs">Forum</a>
<br>
<a href="mailto:karol@jagiello.it">Support Email</a>
<br>
<a href="https://gitlab.com/kroppy/TreeTabs/issues">Report a bug</a>
</fieldset>
<button class="set_button" type="button" id="options_clear_data" style="margin:10px;"></button>
<input type="color" id="color_picker" style="position:absolute; left:-1000px; top:-1000px; width:1px; height:1px; overflow:hidden;">
<div id="DragImage" style="display: none; width:0px; height:0px;"></div>
<script type="text/javascript" src="../global.js"></script>
<script type="text/javascript" src="../scripts/utils.js"></script>
<script type="text/javascript" src="../scripts/dom.js"></script>
<script type="text/javascript" src="../scripts/tabs.js"></script>
<script type="text/javascript" src="../scripts/folders.js"></script>
<script type="text/javascript" src="../scripts/groups.js"></script>
<script type="text/javascript" src="../scripts/menu.js"></script>
<script type="text/javascript" src="../scripts/manager.js"></script>
<script type="text/javascript" src="../scripts/toolbar.js"></script>
<script type="text/javascript" src="../scripts/theme.js"></script>
<script type="text/javascript" src="../scripts/file.js"></script>
<script type="text/javascript" src="../scripts/preferences.js"></script>
<script type="text/javascript" src="../scripts/bookmark.js"></script>
<script type="text/javascript" src="./options.js"></script>
<div id="donate"></div>
<div id="donate_paypal" class="donation_button"></div>
<div id="donate_litecoin" class="donation_button"></div>
<div id="donate_bitcoin" class="donation_button"></div>
<div id="donate_ethereum" class="donation_button"></div>
</body>
</html>

View File

@ -1,26 +1,29 @@
// 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 *************** // ********** OPTIONS ***************
var current_theme = ""; var current_theme = "";
var themes = []; var themes = [];
var SelectedTheme = Object.assign({}, DefaultTheme); 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 // 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.addEventListener("DOMContentLoaded", function() {
document.title = "Tree Tabs"; document.title = "Tree Tabs";
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
AppendGroupToList("tab_list", labels.ungrouped_group, "", false); Groups_AppendGroupToList("tab_list", labels.ungrouped_group, "", false);
AppendGroupToList("tab_list2", labels.noname_group, "", false); Groups_AppendGroupToList("tab_list2", labels.noname_group, "", false);
AppendSampleTabs(); AppendSampleTabs();
GetCurrentPreferences(storage); Preferences_GetCurrentPreferences(storage);
if (storage["themes"]) { if (storage["themes"]) {
for (var themeName in storage["themes"]) { for (var themeName in storage["themes"]) {
@ -29,16 +32,16 @@ document.addEventListener("DOMContentLoaded", function() {
} }
if (storage["current_theme"]) { if (storage["current_theme"]) {
current_theme = storage["current_theme"]; current_theme = storage["current_theme"];
LoadTheme(storage["current_theme"]); Theme_LoadTheme(storage["current_theme"]);
} }
if (storage["unused_buttons"]) { if (storage["unused_buttons"]) {
RecreateToolbarUnusedButtons(storage["unused_buttons"]); Toolbar_RecreateToolbarUnusedButtons(storage["unused_buttons"]);
} }
RecreateToolbar(GetCurrentToolbar(storage)); Toolbar_RecreateToolbar(Theme_GetCurrentToolbar(storage));
SetToolbarEvents(false, false, true, "click"); Toolbar_SetToolbarEvents(false, false, true, "click", false, true);
AddEditToolbarEditEvents(); AddEditToolbarEditEvents();
@ -66,7 +69,7 @@ function SetRegexes() {
opt.tab_group_regexes.push([regex, groupName]); opt.tab_group_regexes.push([regex, groupName]);
} }
} }
SavePreferences(); Preferences_SavePreferences(opt);
} }
function AddRegexPair() { function AddRegexPair() {
@ -201,6 +204,7 @@ function AddBlueBackgroundPreview(Id, removePreview) {
if (removePreview) RemovePreview(); if (removePreview) RemovePreview();
document.getElementById(Id).classList.add("hover_blinking"); document.getElementById(Id).classList.add("hover_blinking");
} }
function AddBlueBorderPreview(Id, removePreview) { function AddBlueBorderPreview(Id, removePreview) {
if (removePreview) RemovePreview(); if (removePreview) RemovePreview();
document.getElementById(Id).classList.add("hover_border_blinking"); document.getElementById(Id).classList.add("hover_border_blinking");
@ -211,28 +215,38 @@ function AddBlueBorderPreview(Id, removePreview) {
function SetEvents() { function SetEvents() {
// --------------------------------DONATIONS----------------------------------------------------------------------------- // --------------------------------DONATIONS-----------------------------------------------------------------------------
document.getElementById("donate_paypal").onclick = function(event) {if (event.which == 1) { document.getElementById("donate_paypal").onclick = function(event) {
if (event.which == 1) {
chrome.tabs.create({ url: "https://www.paypal.me/KarolJagiello/1" }); chrome.tabs.create({ url: "https://www.paypal.me/KarolJagiello/1" });
}} }
document.getElementById("donate_litecoin").onclick = function(event) {if (event.which == 1) { }
document.getElementById("donate_litecoin").onclick = function(event) {
if (event.which == 1) {
copyStringToClipboard("LdQ1ZH1CgSneBbmmVBFrg5BFDFHZMa6h76"); copyStringToClipboard("LdQ1ZH1CgSneBbmmVBFrg5BFDFHZMa6h76");
alert(chrome.i18n.getMessage("options_copied_wallet_address")); alert(chrome.i18n.getMessage("options_copied_wallet_address"));
}} }
document.getElementById("donate_bitcoin").onclick = function(event) {if (event.which == 1) { }
document.getElementById("donate_bitcoin").onclick = function(event) {
if (event.which == 1) {
copyStringToClipboard("19Z8w1RJEcBQpKSdiWa3UTBuKRJUkr96nJ"); copyStringToClipboard("19Z8w1RJEcBQpKSdiWa3UTBuKRJUkr96nJ");
alert(chrome.i18n.getMessage("options_copied_wallet_address")); alert(chrome.i18n.getMessage("options_copied_wallet_address"));
}} }
document.getElementById("donate_ethereum").onclick = function(event) {if (event.which == 1) { }
document.getElementById("donate_ethereum").onclick = function(event) {
if (event.which == 1) {
copyStringToClipboard("0x70B05eAD03bF08220d5aF4E1E868C351bfe145D6"); copyStringToClipboard("0x70B05eAD03bF08220d5aF4E1E868C351bfe145D6");
alert(chrome.i18n.getMessage("options_copied_wallet_address")); alert(chrome.i18n.getMessage("options_copied_wallet_address"));
}} }
}
// --------------------------------COPY VIVALDI LINK---------------------------------------------------------------------- // --------------------------------COPY VIVALDI LINK----------------------------------------------------------------------
document.getElementById("copy_vivaldi_url_for_web_panel").onclick = function(event) {if (event.which == 1) { document.getElementById("copy_vivaldi_url_for_web_panel").onclick = function(event) {
if (event.which == 1) {
copyStringToClipboard(chrome.runtime.getURL("sidebar.html")); copyStringToClipboard(chrome.runtime.getURL("sidebar.html"));
alert(chrome.i18n.getMessage("options_vivaldi_copied_url")); alert(chrome.i18n.getMessage("options_vivaldi_copied_url"));
}} }
}
// --------------------------------ADD RED AND BLUE PREVIEWS--------------------------------------------------------------- // --------------------------------ADD RED AND BLUE PREVIEWS---------------------------------------------------------------
// document.body.onmousedown = function(event) { // document.body.onmousedown = function(event) {
@ -242,9 +256,11 @@ function SetEvents() {
// } // }
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) { 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(); RemovePreview();
}}); }
});
// toolbar buttons // toolbar buttons
document.getElementById("button_background").onmouseenter = function(event) { document.getElementById("button_background").onmouseenter = function(event) {
@ -329,14 +345,14 @@ function SetEvents() {
// pinned tab attention_background // pinned tab attention_background
document.getElementById("attention_background").onmouseenter = function(event) { document.getElementById("attention_background").onmouseenter = function(event) {
AddRedStylePreview("tab_header10", "backgroundColor", "red", true); AddRedStylePreview("tab_header_10", "backgroundColor", "red", true);
document.getElementById("tab_header10").style.animation = "none"; document.getElementById("tab_header_10").style.animation = "none";
} }
// pinned tab attention_border // pinned tab attention_border
document.getElementById("attention_border").onmouseenter = function(event) { document.getElementById("attention_border").onmouseenter = function(event) {
AddRedStylePreview("tab_header10", "border", "1px solid red", true); AddRedStylePreview("tab_header_10", "border", "1px solid red", true);
document.getElementById("tab_header10").style.animation = "none"; document.getElementById("tab_header_10").style.animation = "none";
} }
// pin_list border bottom // pin_list border bottom
@ -351,43 +367,57 @@ function SetEvents() {
// tab row font_color // tab row font_color
document.querySelectorAll(".tab_col.font_color").forEach(function(s){s.onmouseenter = function(event) { document.querySelectorAll(".tab_col.font_color").forEach(function(s) {
AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "color", "red", true); s.onmouseenter = function(event) {
}}); AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "color", "red", true);
}
});
// tab row font not bold // tab row font not bold
document.querySelectorAll(".tab_col.font_weight_normal").forEach(function(s){s.onmouseenter = function(event) { document.querySelectorAll(".tab_col.font_weight_normal").forEach(function(s) {
AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "color", "red", true); s.onmouseenter = function(event) {
AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "fontWeight", "normal", false); 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 // tab row font bold
document.querySelectorAll(".tab_col.font_weight_bold").forEach(function(s){s.onmouseenter = function(event) { document.querySelectorAll(".tab_col.font_weight_bold").forEach(function(s) {
AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "color", "red", true); s.onmouseenter = function(event) {
AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "fontWeight", "bold", false); 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 // tab row font style normal
document.querySelectorAll(".tab_col.font_style_normal").forEach(function(s){s.onmouseenter = function(event) { document.querySelectorAll(".tab_col.font_style_normal").forEach(function(s) {
AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "color", "red", true); s.onmouseenter = function(event) {
AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "fontStyle", "normal", false); 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 // tab row font style italic
document.querySelectorAll(".tab_col.font_style_italic").forEach(function(s){s.onmouseenter = function(event) { document.querySelectorAll(".tab_col.font_style_italic").forEach(function(s) {
AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "color", "red", true); s.onmouseenter = function(event) {
AddRedStylePreview("tab_title" + this.parentNode.id.substr(1), "fontStyle", "italic", false); AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "color", "red", true);
}}); AddRedStylePreview("tab_title_" + this.parentNode.id.substr(1), "fontStyle", "italic", false);
}
});
// tab border // tab border
document.querySelectorAll(".tab_col.color_border").forEach(function(s){s.onmouseenter = function(event) { document.querySelectorAll(".tab_col.color_border").forEach(function(s) {
AddRedStylePreview("tab_header" + this.parentNode.id.substr(1), "border", "1px solid red", true); s.onmouseenter = function(event) {
}}); AddRedStylePreview("tab_header_" + this.parentNode.id.substr(1), "border", "1px solid red", true);
}
});
// tab background // tab background
document.querySelectorAll(".tab_col.color_bucket").forEach(function(s){s.onmouseenter = function(event) { document.querySelectorAll(".tab_col.color_bucket").forEach(function(s) {
AddRedStylePreview("tab_header" + this.parentNode.id.substr(1), "backgroundColor", "red", true); s.onmouseenter = function(event) {
}}); AddRedStylePreview("tab_header_" + this.parentNode.id.substr(1), "backgroundColor", "red", true);
}
});
// scrollbars hover // scrollbars hover
document.getElementById("scrollbar_thumb_hover").onmouseenter = function(event) { document.getElementById("scrollbar_thumb_hover").onmouseenter = function(event) {
@ -410,44 +440,48 @@ function SetEvents() {
// tab_list scrollbars // tab_list scrollbars
document.querySelectorAll("#options_tab_list_scrollbar_width_up, #options_tab_list_scrollbar_width_down").forEach(function(s){s.onmouseenter = function(event) { 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", "backgroundColor", "red", true);
AddRedStylePreview("group_scrollbar_thumb", "backgroundColor", "red"); AddRedStylePreview("group_scrollbar_thumb", "backgroundColor", "red");
}}); }
});
// pin_list scrollbars // pin_list scrollbars
document.querySelectorAll("#options_tab_list_scrollbar_height_up, #options_tab_list_scrollbar_height_down").forEach(function(s){s.onmouseenter = function(event) { 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", "backgroundColor", "red", true);
AddRedStylePreview("pin_list_scrollbar_thumb", "backgroundColor", "red"); AddRedStylePreview("pin_list_scrollbar_thumb", "backgroundColor", "red");
}}); }
});
// folder icon open // folder icon open
document.getElementById("folder_icon_open").onmouseenter = function(event) { document.getElementById("folder_icon_open").onmouseenter = function(event) {
AddRedStylePreview("fopf_folder1", "backgroundColor", "red", true); AddRedStylePreview("folder_expand_f_folder1", "backgroundColor", "red", true);
} }
// folder icon closed // folder icon closed
document.getElementById("folder_icon_closed").onmouseenter = function(event) { document.getElementById("folder_icon_closed").onmouseenter = function(event) {
AddRedStylePreview("fopf_folder2", "backgroundColor", "red", true); AddRedStylePreview("folder_expand_f_folder2", "backgroundColor", "red", true);
} }
// folder icon hover // folder icon hover
document.getElementById("folder_icon_hover").onmouseenter = function(event) { document.getElementById("folder_icon_hover").onmouseenter = function(event) {
AddBlueBackgroundPreview("fopf_folder3", true); AddBlueBackgroundPreview("folder_expand_f_folder3", true);
} }
// tab expand closed // tab expand closed
document.getElementById("expand_closed_background").onmouseenter = function(event) { document.getElementById("expand_closed_background").onmouseenter = function(event) {
AddRedStylePreview("exp14", "backgroundColor", "red", true); AddRedStylePreview("exp_14", "backgroundColor", "red", true);
} }
// tab expand hover // tab expand hover
document.getElementById("expand_hover_background").onmouseenter = function(event) { document.getElementById("expand_hover_background").onmouseenter = function(event) {
AddBlueBackgroundPreview("exp16", true); AddBlueBackgroundPreview("exp_16", true);
} }
// tab expand open // tab expand open
document.getElementById("expand_open_background").onmouseenter = function(event) { document.getElementById("expand_open_background").onmouseenter = function(event) {
AddRedStylePreview("exp5", "backgroundColor", "red", true); AddRedStylePreview("exp_5", "backgroundColor", "red", true);
} }
@ -456,25 +490,25 @@ function SetEvents() {
// drag indicator // drag indicator
document.getElementById("drag_indicator").onmouseenter = function(event) { document.getElementById("drag_indicator").onmouseenter = function(event) {
AddRedStylePreview("di19", "borderBottom", "1px solid red", true); AddRedStylePreview("drag_indicator_19", "borderBottom", "1px solid red", true);
} }
// close x // close x
document.getElementById("close_x").onmouseenter = function(event) { document.getElementById("close_x").onmouseenter = function(event) {
AddRedStylePreview("close_img11", "backgroundColor", "red", true); AddRedStylePreview("close_img_11", "backgroundColor", "red", true);
} }
// close x hover // close x hover
document.getElementById("close_hover_x").onmouseenter = function(event) { document.getElementById("close_hover_x").onmouseenter = function(event) {
AddBlueBackgroundPreview("close_img13", true); AddBlueBackgroundPreview("close_img_13", true);
} }
// close border hover // close border hover
document.getElementById("close_hover_border").onmouseenter = function(event) { document.getElementById("close_hover_border").onmouseenter = function(event) {
AddBlueBorderPreview("close13", true); AddBlueBorderPreview("close_13", true);
} }
// close border hover // close border hover
document.getElementById("close_hover_background").onmouseenter = function(event) { document.getElementById("close_hover_background").onmouseenter = function(event) {
AddBlueBackgroundPreview("close13", true); AddBlueBackgroundPreview("close_13", true);
} }
@ -546,7 +580,8 @@ function SetEvents() {
// --------------------------------------COLOR PICKER--------------------------------------------------------------------- // --------------------------------------COLOR PICKER---------------------------------------------------------------------
// change fonts weight && style // 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) { document.querySelectorAll(".font_weight_normal, .font_weight_bold, .font_style_normal, .font_style_italic").forEach(function(s) {
s.onmousedown = function(event) {
event.stopPropagation(); event.stopPropagation();
// if this.classList.contains("font_weight_normal") || this.classList.contains("font_style_normal") // if this.classList.contains("font_weight_normal") || this.classList.contains("font_style_normal")
let FontStyle = "normal"; let FontStyle = "normal";
@ -557,12 +592,15 @@ function SetEvents() {
FontStyle = "italic"; FontStyle = "italic";
} }
SelectedTheme["ColorsSet"][this.id] = FontStyle; SelectedTheme["ColorsSet"][this.id] = FontStyle;
ApplyColorsSet(SelectedTheme["ColorsSet"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
}}); }
});
// show color picker // show color picker
document.querySelectorAll(".pick_col").forEach(function(s){s.onclick = function(event) {if (event.which == 1) { document.querySelectorAll(".pick_col").forEach(function(s) {
s.onclick = function(event) {
if (event.which == 1) {
RemovePreview(); RemovePreview();
event.stopPropagation(); event.stopPropagation();
let bod = document.getElementById("body"); let bod = document.getElementById("body");
@ -571,23 +609,27 @@ function SetEvents() {
ColorPicker.setAttribute("PickColor", this.id); ColorPicker.setAttribute("PickColor", this.id);
ColorPicker.value = color.replace(" ", ""); ColorPicker.value = color.replace(" ", "");
ColorPicker.click(); ColorPicker.click();
}}}); }
}
});
document.getElementById("color_picker").oninput = function(event) { document.getElementById("color_picker").oninput = function(event) {
let ColorPicker = document.getElementById("color_picker"); let ColorPicker = document.getElementById("color_picker");
SelectedTheme["ColorsSet"][this.getAttribute("PickColor")] = ColorPicker.value; SelectedTheme["ColorsSet"][this.getAttribute("PickColor")] = ColorPicker.value;
ApplyColorsSet(SelectedTheme["ColorsSet"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
// SaveTheme(document.getElementById("theme_list").value); // Theme_SaveTheme(document.getElementById("theme_list").value);
} }
document.getElementById("color_picker").onchange = function(event) { document.getElementById("color_picker").onchange = function(event) {
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
// ----------------------------------EVENTS FOR CHECKBOXES AND DROPDOWN MENUS--------------------------------------------- // ----------------------------------EVENTS FOR CHECKBOXES AND DROPDOWN MENUS---------------------------------------------
// set checkbox options on/off and save // set checkbox options on/off and save
document.querySelectorAll(".bg_opt").forEach(function(s){s.onclick = function(event) {if (event.which == 1) { document.querySelectorAll(".bg_opt").forEach(function(s) {
s.onclick = function(event) {
if (event.which == 1) {
opt[this.id] = this.checked ? true : false; opt[this.id] = this.checked ? true : false;
if (this.checked) { if (this.checked) {
if (this.id == "never_show_close") { if (this.id == "never_show_close") {
@ -604,9 +646,9 @@ function SetEvents() {
document.getElementById("promote_children_in_first_child").disabled = true; document.getElementById("promote_children_in_first_child").disabled = true;
} }
} }
SavePreferences(); Preferences_SavePreferences(opt);
if (this.id == "show_toolbar") { if (this.id == "show_toolbar") {
SaveToolbar(); Toolbar_SaveToolbar();
RefreshFields(); RefreshFields();
@ -614,11 +656,14 @@ function SetEvents() {
// chrome.runtime.sendMessage({command: "reload_toolbar", toolbar: toolbar, opt: opt}); // chrome.runtime.sendMessage({command: "reload_toolbar", toolbar: toolbar, opt: opt});
// }, 300); // }, 300);
} }
}}}); }
}
});
// options that need reload // options that need reload
document.onclick = function(event) {if (event.which == 1) { 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" || 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") { 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() { setTimeout(function() {
@ -631,7 +676,8 @@ function SetEvents() {
location.reload(); location.reload();
}, 300); }, 300);
} }
}} }
}
// set dropdown menu options // set dropdown menu options
for (let i = 0; i < DropDownList.length; i++) { for (let i = 0; i < DropDownList.length; i++) {
@ -639,7 +685,7 @@ function SetEvents() {
opt[this.id] = this.value; opt[this.id] = this.value;
RefreshFields(); RefreshFields();
setTimeout(function() { setTimeout(function() {
SavePreferences(); Preferences_SavePreferences(opt);
// chrome.runtime.sendMessage({command: "reload_sidebar"}); // chrome.runtime.sendMessage({command: "reload_sidebar"});
}, 50); }, 50);
} }
@ -649,7 +695,7 @@ function SetEvents() {
document.getElementById("max_tree_depth").oninput = function(event) { document.getElementById("max_tree_depth").oninput = function(event) {
opt.max_tree_depth = parseInt(this.value); opt.max_tree_depth = parseInt(this.value);
setTimeout(function() { setTimeout(function() {
SavePreferences(); Preferences_SavePreferences(opt);
}, 50); }, 50);
} }
@ -657,7 +703,7 @@ function SetEvents() {
// document.getElementById("show_toolbar").onclick = function(event) {if (event.which == 1) { // document.getElementById("show_toolbar").onclick = function(event) {if (event.which == 1) {
// SelectedTheme.ToolbarShow = this.checked ? true : false; // SelectedTheme.ToolbarShow = this.checked ? true : false;
// RefreshFields(); // RefreshFields();
// SaveTheme(document.getElementById("theme_list").value); // Theme_SaveTheme(document.getElementById("theme_list").value);
// }} // }}
@ -677,9 +723,10 @@ function SetEvents() {
// ----------------------------RESET TOOLBAR BUTTON----------------------------------------------------------------------- // ----------------------------RESET TOOLBAR BUTTON-----------------------------------------------------------------------
document.getElementById("options_reset_toolbar_button").onclick = function(event) {if (event.which == 1) { document.getElementById("options_reset_toolbar_button").onclick = function(event) {
if (event.which == 1) {
SetToolbarEvents(true, false, false, ""); Toolbar_SetToolbarEvents(true, false, false, "", false, false);
RemoveToolbarEditEvents(); RemoveToolbarEditEvents();
@ -688,62 +735,75 @@ function SetEvents() {
unused_buttons.removeChild(unused_buttons.firstChild); unused_buttons.removeChild(unused_buttons.firstChild);
} }
RemoveToolbar(); Toolbar_RemoveToolbar();
RecreateToolbar(DefaultToolbar); Toolbar_RecreateToolbar(DefaultToolbar);
SetToolbarEvents(false, false, true, "click"); Toolbar_SetToolbarEvents(false, false, true, "click", false, true);
AddEditToolbarEditEvents(); AddEditToolbarEditEvents();
SaveToolbar(); Toolbar_SaveToolbar();
}} }
}
// --------------------------------------THEME BUTTONS-------------------------------------------------------------------- // --------------------------------------THEME BUTTONS--------------------------------------------------------------------
// add new theme preset button // add new theme preset button
document.getElementById("options_add_theme_button").onclick = function(event) {if (event.which == 1) { document.getElementById("options_add_theme_button").onclick = function(event) {
AddNewTheme(); if (event.which == 1) {
}} Theme_AddNewTheme();
}
}
// remove theme preset button // remove theme preset button
document.getElementById("options_remove_theme_button").onclick = function(event) {if (event.which == 1) { document.getElementById("options_remove_theme_button").onclick = function(event) {
DeleteSelectedTheme(); if (event.which == 1) {
}} Theme_DeleteSelectedTheme();
}
}
// select theme from list // select theme from list
document.getElementById("theme_list").onchange = function(event) { document.getElementById("theme_list").onchange = function(event) {
LoadTheme(this.value, true); Theme_LoadTheme(this.value, true);
chrome.storage.local.set({ current_theme: this.value }); chrome.storage.local.set({ current_theme: this.value });
} }
// import theme preset button // import theme preset button
document.getElementById("options_import_theme_button").onclick = function(event) {if (event.which == 1) { document.getElementById("options_import_theme_button").onclick = function(event) {
let inputFile = ShowOpenFileDialog(".tt_theme"); if (event.which == 1) {
let inputFile = File_ShowOpenFileDialog(".tt_theme");
inputFile.onchange = function(event) { inputFile.onchange = function(event) {
ImportTheme(); Theme_ImportTheme();
}
}
} }
}}
// export theme preset button // export theme preset button
document.getElementById("options_export_theme_button").onclick = function(event) {if (event.which == 1) { document.getElementById("options_export_theme_button").onclick = function(event) {
if (event.which == 1) {
let ThemeList = document.getElementById("theme_list"); let ThemeList = document.getElementById("theme_list");
if (ThemeList.options.length == 0) { if (ThemeList.options.length == 0) {
alert(chrome.i18n.getMessage("options_no_theme_to_export")); alert(chrome.i18n.getMessage("options_no_theme_to_export"));
} else { } else {
SaveFile(ThemeList.options[ThemeList.selectedIndex].text, "tt_theme", SelectedTheme); File_SaveFile(ThemeList.options[ThemeList.selectedIndex].text, "tt_theme", SelectedTheme);
}
}
} }
}}
// rename theme preset button // rename theme preset button
document.getElementById("options_rename_theme_button").onclick = function(event) {if (event.which == 1) { document.getElementById("options_rename_theme_button").onclick = function(event) {
RenameSelectedTheme(); if (event.which == 1) {
}} Theme_RenameSelectedTheme();
}
}
// get themes // get themes
document.getElementById("options_share_theme_link").onclick = function(event) {if (event.which == 1) { 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" }); chrome.tabs.create({ url: "https://drive.google.com/drive/folders/0B3jXQpRtOfvSelFrTEVHZEx3Nms?usp=sharing" });
}} }
}
// -------------------------------INDENTATION ADJUSTMENT------------------------------------------------------------------ // -------------------------------INDENTATION ADJUSTMENT------------------------------------------------------------------
@ -755,8 +815,8 @@ function SetEvents() {
if (indentation > 0) { if (indentation > 0) {
indentation--; indentation--;
SelectedTheme["ColorsSet"]["children_padding_left"] = indentation + "px"; SelectedTheme["ColorsSet"]["children_padding_left"] = indentation + "px";
ApplyColorsSet(SelectedTheme["ColorsSet"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
} }
@ -767,8 +827,8 @@ function SetEvents() {
if (indentation < 50) { if (indentation < 50) {
indentation++; indentation++;
SelectedTheme["ColorsSet"]["children_padding_left"] = indentation + "px"; SelectedTheme["ColorsSet"]["children_padding_left"] = indentation + "px";
ApplyColorsSet(SelectedTheme["ColorsSet"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
} }
@ -782,8 +842,8 @@ function SetEvents() {
if (border_radius > 0) { if (border_radius > 0) {
border_radius--; border_radius--;
SelectedTheme["ColorsSet"]["tab_header_border_radius"] = border_radius + "px"; SelectedTheme["ColorsSet"]["tab_header_border_radius"] = border_radius + "px";
ApplyColorsSet(SelectedTheme["ColorsSet"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
} }
@ -794,8 +854,8 @@ function SetEvents() {
if (border_radius < 25) { if (border_radius < 25) {
border_radius++; border_radius++;
SelectedTheme["ColorsSet"]["tab_header_border_radius"] = border_radius + "px"; SelectedTheme["ColorsSet"]["tab_header_border_radius"] = border_radius + "px";
ApplyColorsSet(SelectedTheme["ColorsSet"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
} }
@ -812,8 +872,8 @@ function SetEvents() {
} }
} }
SelectedTheme["TabsMargins"] = size; SelectedTheme["TabsMargins"] = size;
ApplyTabsMargins(size); Theme_ApplyTabsMargins(size);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
@ -821,17 +881,17 @@ function SetEvents() {
document.getElementById("options_tabs_size_down").onmousedown = function(event) { document.getElementById("options_tabs_size_down").onmousedown = function(event) {
if (SelectedTheme["TabsSizeSetNumber"] > 0) { if (SelectedTheme["TabsSizeSetNumber"] > 0) {
SelectedTheme["TabsSizeSetNumber"]--; SelectedTheme["TabsSizeSetNumber"]--;
ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]); Theme_ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
} }
// change tabs size preset(up) // change tabs size preset(up)
document.getElementById("options_tabs_size_up").onmousedown = function(event) { document.getElementById("options_tabs_size_up").onmousedown = function(event) {
if (SelectedTheme["TabsSizeSetNumber"] < 4) { if (SelectedTheme["TabsSizeSetNumber"] < 5) {
SelectedTheme["TabsSizeSetNumber"]++; SelectedTheme["TabsSizeSetNumber"]++;
ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]); Theme_ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
} }
@ -845,8 +905,8 @@ function SetEvents() {
if (border_radius > 0) { if (border_radius > 0) {
border_radius--; border_radius--;
SelectedTheme["ColorsSet"]["scrollbar_width"] = border_radius + "px"; SelectedTheme["ColorsSet"]["scrollbar_width"] = border_radius + "px";
ApplyColorsSet(SelectedTheme["ColorsSet"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
} }
@ -857,8 +917,8 @@ function SetEvents() {
if (border_radius < 20) { if (border_radius < 20) {
border_radius++; border_radius++;
SelectedTheme["ColorsSet"]["scrollbar_width"] = border_radius + "px"; SelectedTheme["ColorsSet"]["scrollbar_width"] = border_radius + "px";
ApplyColorsSet(SelectedTheme["ColorsSet"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
} }
@ -869,8 +929,8 @@ function SetEvents() {
if (border_radius > 0) { if (border_radius > 0) {
border_radius--; border_radius--;
SelectedTheme["ColorsSet"]["scrollbar_height"] = border_radius + "px"; SelectedTheme["ColorsSet"]["scrollbar_height"] = border_radius + "px";
ApplyColorsSet(SelectedTheme["ColorsSet"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
} }
@ -881,23 +941,26 @@ function SetEvents() {
if (border_radius < 20) { if (border_radius < 20) {
border_radius++; border_radius++;
SelectedTheme["ColorsSet"]["scrollbar_height"] = border_radius + "px"; SelectedTheme["ColorsSet"]["scrollbar_height"] = border_radius + "px";
ApplyColorsSet(SelectedTheme["ColorsSet"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
SaveTheme(document.getElementById("theme_list").value); Theme_SaveTheme(document.getElementById("theme_list").value);
} }
} }
// ----------------------EXPORT DEBUG LOG--------------------------------------------------------------------------------- // ----------------------EXPORT DEBUG LOG---------------------------------------------------------------------------------
document.getElementById("options_export_debug").onclick = function(event) {if (event.which == 1) { document.getElementById("options_export_debug").onclick = function(event) {
if (event.which == 1) {
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
SaveFile("TreeTabs", "log", storage.debug_log); File_SaveFile("TreeTabs", "log", storage.debug_log);
}); });
}} }
}
// ----------------------IMPORT DEBUG LOG---------------------------------------------------------------------------- // ----------------------IMPORT DEBUG LOG----------------------------------------------------------------------------
document.getElementById("options_print_debug").onclick = function(event) {if (event.which == 1) { document.getElementById("options_print_debug").onclick = function(event) {
let inputFile = ShowOpenFileDialog(".log"); if (event.which == 1) {
let inputFile = File_ShowOpenFileDialog(".log");
inputFile.onchange = function(event) { inputFile.onchange = function(event) {
let file = document.getElementById("file_import"); let file = document.getElementById("file_import");
let fr = new FileReader(); let fr = new FileReader();
@ -916,19 +979,22 @@ function SetEvents() {
} }
} }
}} }
}
// ----------------------CLEAR DATA BUTTON-------------------------------------------------------------------------------- // ----------------------CLEAR DATA BUTTON--------------------------------------------------------------------------------
// clear data // clear data
document.getElementById("options_clear_data").onclick = function(event) {if (event.which == 1) { document.getElementById("options_clear_data").onclick = function(event) {
if (event.which == 1) {
chrome.storage.local.clear(); chrome.storage.local.clear();
setTimeout(function() { setTimeout(function() {
chrome.runtime.sendMessage({ command: "reload" }); chrome.runtime.sendMessage({ command: "reload" });
chrome.runtime.sendMessage({ command: "reload_sidebar" }); chrome.runtime.sendMessage({ command: "reload_sidebar" });
location.reload(); location.reload();
}, 100); }, 100);
}} }
}
} }
@ -967,21 +1033,22 @@ function AddEditToolbarEditEvents() {
let Index = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode); let Index = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode);
if (Index <= dragged_buttonIndex) { if (Index <= dragged_buttonIndex) {
InsterBeforeNode(dragged_button, this.parentNode); DOM_InsterBeforeNode(dragged_button, this.parentNode);
} else { } else {
InsterAfterNode(dragged_button, this.parentNode); DOM_InsterAfterNode(dragged_button, this.parentNode);
} }
} }
// save toolbar // save toolbar
s.ondragend = function(event) { s.ondragend = function(event) {
RemoveToolbarEditEvents(); RemoveToolbarEditEvents();
SaveToolbar(); Toolbar_SaveToolbar();
AddEditToolbarEditEvents(); AddEditToolbarEditEvents();
} }
}); });
document.querySelectorAll("#toolbar_main, .toolbar_shelf:not(#toolbar_search), #toolbar_unused_buttons").forEach(function(s){s.ondragenter = function(event) { 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")) { 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; return;
} }
@ -989,7 +1056,8 @@ function AddEditToolbarEditEvents() {
this.appendChild(dragged_button); this.appendChild(dragged_button);
} }
}}); }
});
} }
function copyStringToClipboard(string) { function copyStringToClipboard(string) {
@ -1047,7 +1115,7 @@ function RefreshFields() {
if (opt.append_child_tab == "after" && opt.append_orphan_tab == "as_child") { if (opt.append_child_tab == "after" && opt.append_orphan_tab == "as_child") {
opt.append_orphan_tab = "after_active"; opt.append_orphan_tab = "after_active";
document.getElementById("append_orphan_tab").value = "after_active"; document.getElementById("append_orphan_tab").value = "after_active";
SavePreferences(); Preferences_SavePreferences(opt);
} }
} else { } else {
@ -1069,13 +1137,130 @@ function RefreshGUI() {
} }
} }
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 // pins
function BindTabsSwitchingToMouseWheel() {} tt.tabs["0"] = new Tabs_ttTab({ tab: { id: 0, pinned: true, active: false }, Append: true, SkipSetActive: true, SkipSetEvents: true, SkipFavicon: true, SkipMediaIcon: true });
function GetFaviconAndTitle() {} tt.tabs["1"] = new Tabs_ttTab({ tab: { id: 1, pinned: true, active: false }, Append: true, SkipSetActive: true, SkipSetEvents: true, SkipFavicon: true, SkipMediaIcon: true });
function RefreshMediaIcon() {} tt.tabs["10"] = new Tabs_ttTab({ tab: { id: 10, pinned: true, active: false }, Append: true, SkipSetActive: true, SkipSetEvents: true, SkipFavicon: true, SkipMediaIcon: true });
function SetActiveTab() {} document.getElementById("10").classList.add("attention");
function RefreshCounters() {}
function RefreshExpandStates() {} // regular tabs
function Loadi18n() {} 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");
}

View File

@ -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");
}

View File

@ -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);
}
}

80
scripts/bookmark.js Normal file
View File

@ -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);
});
}
}
});
});
}

View File

@ -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";
}
}
}
}
}

720
scripts/dom.js Normal file
View File

@ -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);
}

View File

@ -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;
}

22
scripts/file.js Normal file
View File

@ -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);
}
}

View File

@ -1,504 +1,283 @@
// Copyright (c) 2017 kroppy. All rights reserved. function Folders_AddNewFolder(p) { // folderId: string, ParentId: string, Name: string, Index: int, ExpandState: ("o","c"), AdditionalClass: string, SetEvents: bool
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license let newId = p.folderId ? p.folderId : Folders_GenerateNewFolderID();
// 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 : "")}; 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) { Folders_AppendFolder({folderId: newId, Name: tt.folders[newId].name, InsertAfterId: p.InsertAfterId, ParentId: p.ParentId, ExpandState: p.ExpandState, SkipSetEvents: p.SkipSetEvents, AdditionalClass: p.AdditionalClass});
log("f: AddNewFolder, folder: "+JSON.stringify(tt.folders[newId])); Folders_SaveFolders();
} DOM_RefreshCounters();
AppendFolder(newId, labels.noname_group, (p.ParentId ? p.ParentId : ""), undefined, p.SetEvents, p.AdditionalClass); DOM_RefreshExpandStates();
SaveFolders();
RefreshCounters();
RefreshExpandStates();
return newId; return newId;
} }
function AppendFolder(folderId, Name, ParentId, Expand, SetEvents, AdditionalClass) { function Folders_AppendFolder(p) { // folderId: string, ParentId: string, Name: string, ExpandState: ("o","c"), AdditionalClass: string, SetEvents: bool
if (opt.debug) {
log("f: AppendFolder, folder: "+JSON.stringify(tt.folders[folderId]));
}
let ClassList = "folder"; let ClassList = "folder";
if (AdditionalClass != undefined) { if (p.ExpandState) ClassList += " " + p.ExpandState;
ClassList = ClassList + AdditionalClass; 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 (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) { if (!opt.never_show_close) {
cl = document.createElement("div"); cl.className = "close"; cl.id = "close"+folderId; fh.appendChild(cl); // CLOSE BUTTON DIV_close_button.onmousedown = function(event) {
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(); event.stopImmediatePropagation();
ActionClickGroup(this.parentNode, opt.midclick_group); if (event.which != 3) Folders_RemoveFolder(this.parentNode.parentNode.id);
} }
if (event.which == 3) { DIV_close_button.onmouseenter = function(event) {
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"); this.classList.add("close_hover");
} }
cl.onmouseleave = function(event) { DIV_close_button.onmouseleave = function(event) {
this.classList.remove("close_hover"); this.classList.remove("close_hover");
} }
} }
fh.onclick = function(event) { DIV_header.onclick = function(event) {
// SELECT FOLDER if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target.classList.contains("folder_header")) DOM_Deselect();
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();
} }
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) { if (event.which == 2) {
event.preventDefault(); event.preventDefault();
ActionClickFolder(this.parentNode, opt.midclick_folder); Folders_ActionClickFolder(this.parentNode, opt.midclick_folder);
} }
// SHOW FOLDER MENU if (event.which == 3) Menu_ShowFolderMenu(this.parentNode, event); // SHOW FOLDER MENU
if (event.which == 3) { }
ShowFolderMenu(this.parentNode, event); 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 : "")});
} }
} }
// edit folder let DraggedFolderParents = DOM_GetParentsByClass(this.parentNode, "folder");
fh.ondblclick = function(event) { for (let s of DraggedFolderParents) {
if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target.classList.contains("folder_header")) { s.classList.add("dragged_parents");
ActionClickFolder(this.parentNode, opt.dbclick_folder);
} }
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});
} }
fh.ondragstart = function(event) { // DRAG START DIV_header.ondragenter = function(event) {
FolderStartDrag(this, event);
}
fh.ondragenter = function(event) {
this.classList.remove("folder_header_hover"); this.classList.remove("folder_header_hover");
} }
fh.onmouseover = function(event) { 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"); this.classList.add("folder_header_hover");
if (opt.never_show_close == false && opt.always_show_close == false) { if (opt.never_show_close == false && opt.always_show_close == false) this.classList.add("close_show");
this.classList.add("close_show");
} }
} DIV_header.onmouseleave = function(event) {
fh.onmouseleave = function(event) {
this.classList.remove("folder_header_hover"); this.classList.remove("folder_header_hover");
if (opt.never_show_close == false && opt.always_show_close == false) { if (opt.never_show_close == false && opt.always_show_close == false) this.classList.remove("close_show");
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"], []);
} }
} }
fh.ondragleave = function(event) {
RemoveHighlight();
}
fh.ondragover = function(event) {
FolderDragOver(this, event);
if (opt.open_tree_on_hover && tt.DragOverId != this.id) { if (opt.open_tree_on_hover && tt.DragOverId != this.id) {
if (this.parentNode.classList.contains("c") && this.parentNode.classList.contains("dragged_tree") == false) { if (this.parentNode.classList.contains("c") && this.parentNode.classList.contains("dragged_tree") == false) {
clearTimeout(tt.DragOverTimer); clearTimeout(tt.DragOverTimer);
tt.DragOverId = this.id; tt.DragOverId = this.id;
let This = this; let This = this;
tt.DragOverTimer = setTimeout(function() { tt.DragOverTimer = setTimeout(function() {
if (tt.DragOverId == This.id) { if (tt.DragOverId == This.id) DOM_SetClasses(This.parentNode, ["o"], ["c"], []);
This.parentNode.classList.add("o");
This.parentNode.classList.remove("c");
}
}, 1500); }, 1500);
} }
} }
} }
DIV_expand.onmousedown = function(event) {
ex.onmousedown = function(event) {
event.stopPropagation(); event.stopPropagation();
if (document.getElementById("main_menu").style.top != "-1000px") { if (tt.DOMmenu.style.top != "-1000px") Menu_HideMenus();
HideMenus(); if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target == this) { // EXPAND/COLLAPSE FOLDER
}
// EXPAND/COLLAPSE FOLDER
if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target == this) {
event.stopPropagation(); event.stopPropagation();
EventExpandBox(this.parentNode.parentNode); DOM_EventExpandBox(this.parentNode.parentNode);
RefreshExpandStates(); DOM_RefreshExpandStates();
RefreshCounters(); DOM_RefreshCounters();
} }
} }
} }
if (ParentId == "" || ParentId == undefined || document.getElementById("cf"+ParentId) == null) { if (p.ParentId == "pin_list" || p.ParentId == "" || p.ParentId == undefined || document.getElementById("°" + p.ParentId) == null) {
document.getElementById("cf"+tt.active_group).appendChild(fd); document.getElementById("°" + tt.active_group).appendChild(DIV_folder);
} else { } else {
document.getElementById("cf"+ParentId).appendChild(fd); 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() { function Folders_GenerateNewFolderID() {
let newID = ""; let newID = "";
while (newID == "") { while (newID == "") {
newID = "f_" + GenerateRandomID(); newID = "f_" + GenerateRandomID();
if (document.getElementById(newID) != null) { if (document.getElementById(newID) != null) newID = "";
newID = "";
}
} }
return newID; return newID;
} }
function AppendFolders(Folders) { function Folders_PreAppendFolders(folders) {
if (opt.debug) { for (let folderId in folders) {Folders_AppendFolder({folderId: folderId, Name: folders[folderId].name, ParentId: "tab_list", ExpandState: folders[folderId].expand});}
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); function Folders_AppendFolders(folders) {
} for (let folderId in folders) {
for (let folderId in Folders) {
let f = document.getElementById(folderId); let f = document.getElementById(folderId);
let parent = document.getElementById("cf"+Folders[folderId].parent); let parent = document.getElementById("°" + folders[folderId].parent);
if (f != null && parent != null && Folders[folderId].parent != f.parentNode.parentNode.id) { if (f != null && parent != null && folders[folderId].parent != f.parentNode.parentNode.id && parent.parentNode.classList.contains("pin") == false) parent.appendChild(f);
parent.appendChild(f);
}
} }
} }
function SaveFolders() { function Folders_SaveFolders() {
document.querySelectorAll(".folder").forEach(function(s){ let query = document.querySelectorAll(".folder");
for (let s of query) {
tt.folders[s.id].parent = s.parentNode.parentNode.id; 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].index = Array.from(s.parentNode.children).indexOf(s);
tt.folders[s.id].expand = (s.classList.contains("c") ? "c" : (s.classList.contains("o") ? "o" : "")); 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}); chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId});
} }
function RearrangeFolders(first_loop) { function Folders_RemoveFolder(FolderId) {
if (opt.debug) { if (opt.debug) Utils_log("f: RemoveFolder, folderId " + FolderId);
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 RemoveFolder(FolderId) {
if (opt.debug) {
log("f: RemoveFolder, folderId "+FolderId);
}
let folder = document.getElementById(FolderId); let folder = document.getElementById(FolderId);
if (folder != null) { 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 == true) {
if (opt.promote_children_in_first_child == true && CF.children.length > 0) { if (opt.promote_children_in_first_child == true && folder.childNodes[1].childNodes.length > 1) {
let FirstFolderChild = CF.firstChild; DOM_PromoteChildrenToFirstChild(folder);
folder.parentNode.insertBefore(FirstFolderChild, folder); } else {
let NewCF = FirstFolderChild.childNodes[1]; let Children = folder.childNodes[1];
while (CF.firstChild) { while (Children.lastChild) {
NewCF.appendChild(CF.firstChild); DOM_InsterAfterNode(Children.lastChild, folder);
}
if (CT.childNodes.length > 0) {
let NewCT = FirstFolderChild.childNodes[2];
while (CT.firstChild) {
NewCT.appendChild(CT.firstChild);
} }
} }
} else { } else {
let NewCT = document.getElementById("ct"+folder.parentNode.parentNode.id); let query = document.querySelectorAll("#" + FolderId + " .tab");
// let NewCT = folder.parentNode.parentNode.childNodes[2]; for (let s of query) {
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); chrome.tabs.remove(parseInt(s.id), null);
}); }
query = document.querySelectorAll("#" + FolderId + " .folder");
document.querySelectorAll("#"+FolderId+" .folder").forEach(function(s){ for (let s of query) {
delete tt.folders[s.id]; delete tt.folders[s.id];
}); }
} }
folder.parentNode.removeChild(folder); folder.parentNode.removeChild(folder);
delete tt.folders[FolderId]; delete tt.folders[FolderId];
RefreshExpandStates(); DOM_RefreshExpandStates();
chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId}); chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId});
} }
} }
function Folders_ShowRenameFolderDialog(FolderId) { // Rename folder popup
function ShowRenameFolderDialog(FolderId) { // Rename folder popup if (opt.debug) Utils_log("f: ShowRenameFolderDialog, folderId " + FolderId);
if (opt.debug) { DOM_HideRenameDialogs();
log("f: ShowRenameFolderDialog, folderId "+FolderId);
}
HideRenameDialogs();
if (tt.folders[FolderId]) { if (tt.folders[FolderId]) {
let name = document.getElementById("folder_edit_name"); let name = document.getElementById("folder_edit_name");
name.value = tt.folders[FolderId].name; name.value = tt.folders[FolderId].name;
let folderEditDialog = document.getElementById("folder_edit"); let folderEditDialog = document.getElementById("folder_edit");
folderEditDialog.setAttribute("FolderId", FolderId); folderEditDialog.setAttribute("FolderId", FolderId);
folderEditDialog.style.display = "block"; DOM_SetStyle(folderEditDialog, {display: "block", left: "", top: document.getElementById("toolbar").getBoundingClientRect().height + document.getElementById("pin_list").getBoundingClientRect().height + 8 + "px"});
folderEditDialog.style.top = document.getElementById("toolbar").getBoundingClientRect().height + document.getElementById("pin_list").getBoundingClientRect().height + 8 + "px"; setTimeout(function() {document.getElementById("folder_edit_name").select();}, 5);
// folderEditDialog.style.left = "22px";
folderEditDialog.style.left = "";
setTimeout(function(){
document.getElementById("folder_edit_name").select();
},5);
} }
} }
function FolderRenameConfirm() { // when pressed OK in folder popup function Folders_FolderRenameConfirm() { // when pressed OK in folder popup
let name = document.getElementById("folder_edit_name"); let name = document.getElementById("folder_edit_name");
let FolderId = document.getElementById("folder_edit").getAttribute("FolderId"); 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; tt.folders[FolderId].name = name.value;
document.getElementById("folder_title" + FolderId).textContent = name.value; document.getElementById("folder_title_"+FolderId).textContent = name.value;
HideRenameDialogs(); DOM_HideRenameDialogs();
if (opt.debug) { if (opt.debug) Utils_log("f: FolderRenameConfirm, folderId " + FolderId + ", name: " + name.value);
log("f: FolderRenameConfirm, folderId "+FolderId+", name: "+name.value);
}
chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId}); chrome.runtime.sendMessage({command: "save_folders", folders: tt.folders, windowId: tt.CurrentWindowId});
RefreshCounters(); DOM_RefreshCounters();
} }
function DeselectFolders() { function Folders_ActionClickFolder(FolderNode, bgOption) {
if (opt.debug) { if (opt.debug) Utils_log("f: ActionClickFolder, folderId " + FolderNode.id + ", bgOption: " + bgOption);
log("f: DeselectFolders"); if (bgOption == "rename_folder") Folders_ShowRenameFolderDialog(FolderNode.id);
}
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") { if (bgOption == "new_folder") {
let FolderId = AddNewFolder({ParentId: FolderNode.id, SetEvents: true}); let FolderId = Folders_AddNewFolder({ParentId: FolderNode.id});
ShowRenameFolderDialog(FolderId); Folders_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 == "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") { if (bgOption == "unload_folder") {
let tabsArr = []; let tabsArr = [];
document.querySelectorAll("#"+FolderNode.id+" .tab").forEach(function(s){ let query = document.querySelectorAll("#" + FolderNode.id + " .tab");
for (let s of query) {
tabsArr.push(parseInt(s.id)); tabsArr.push(parseInt(s.id));
}); }
DiscardTabs(tabsArr); Tabs_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");
}
} }
} }

View File

@ -1,334 +1,271 @@
// Copyright (c) 2017 kroppy. All rights reserved. function Groups_AppendGroupToList(groupId, group_name, font_color, SetEvents) {
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license if (document.getElementById(groupId) == null) {
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/ 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();
}
}
}
// ********** GROUPS FUNCTIONS *************** 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 SaveGroups() { function Groups_SaveGroups() {
chrome.runtime.sendMessage({command: "save_groups", groups: tt.groups, windowId: tt.CurrentWindowId}); chrome.runtime.sendMessage({command: "save_groups", groups: tt.groups, windowId: tt.CurrentWindowId});
} }
function AppendGroups(Groups) { function Groups_AppendGroups(groups) {
if (opt.debug) { Groups_AppendGroupToList("tab_list", labels.ungrouped_group, "", true);
log("f: AppendGroups, Groups: "+JSON.stringify(Groups)); for (var group in groups) {
} Groups_AppendGroupToList(groups[group].id, groups[group].name, groups[group].font, true);
AppendGroupToList("tab_list", labels.ungrouped_group, "", true); if (document.querySelectorAll(".group").length == Object.keys(groups).length) {
for (var group in Groups) { Groups_RearrangeGroupsButtons();
AppendGroupToList(Groups[group].id, Groups[group].name, Groups[group].font, true); setTimeout(function() {Groups_RearrangeGroupsLists();}, 50);
if (document.querySelectorAll(".group").length == Object.keys(Groups).length) {
RearrangeGroupsButtons();
setTimeout(function() {
RearrangeGroupsLists();
}, 50);
} }
} }
} }
function RearrangeGroupsButtons(first_loop) { function Groups_RearrangeGroupsButtons(first_loop) {
if (opt.debug) { let query = document.querySelectorAll(".group_button");
log("f: RearrangeGroupsButtons"); for (let s of query) {
}
document.querySelectorAll(".group_button").forEach(function(s){
let groupId = (s.id).substr(1); let groupId = (s.id).substr(1);
if (tt.groups[groupId]) { if (tt.groups[groupId]) {
if (s.parentNode.childNodes[tt.groups[groupId].index] != undefined) { if (s.parentNode.childNodes[tt.groups[groupId].index] != undefined) {
let Ind = Array.from(s.parentNode.children).indexOf(s); let Ind = Array.from(s.parentNode.children).indexOf(s);
if (Ind > tt.groups[groupId].index) { if (Ind > tt.groups[groupId].index) {
InsterBeforeNode(s, s.parentNode.childNodes[tt.groups[groupId].index]); DOM_InsterBeforeNode(s, s.parentNode.childNodes[tt.groups[groupId].index]);
} else { } else {
InsterAfterNode(s, s.parentNode.childNodes[tt.groups[groupId].index]); DOM_InsterAfterNode(s, s.parentNode.childNodes[tt.groups[groupId].index]);
} }
let newInd = Array.from(s.parentNode.children).indexOf(s); let newInd = Array.from(s.parentNode.children).indexOf(s);
if (newInd != tt.groups[groupId].index && first_loop) { if (newInd != tt.groups[groupId].index && first_loop) Groups_RearrangeGroupsButtons(false);
RearrangeGroupsButtons(false);
} }
} }
} }
});
} }
function RearrangeGroupsLists() { function Groups_RearrangeGroupsLists() {
if (opt.debug) { if (opt.debug) Utils_log("f: RearrangeGroupsLists");
log("f: RearrangeGroupsLists");
}
let activegroup = document.getElementById(tt.active_group); let activegroup = document.getElementById(tt.active_group);
let scroll = activegroup.scrollTop; let scroll = activegroup.scrollTop;
let groups = document.getElementById("groups"); let groups = document.getElementById("groups");
document.querySelectorAll(".group_button").forEach(function(s){ let query = document.querySelectorAll(".group_button");
for (let s of query) {
let group = document.getElementById((s.id).substr(1)); let group = document.getElementById((s.id).substr(1));
if (group != null) { if (group != null) groups.appendChild(group);
groups.appendChild(group);
} }
});
activegroup.scrollTop = scroll; activegroup.scrollTop = scroll;
} }
function AppendGroupToList(groupId, group_name, font_color, SetEvents) { function Groups_UpdateBgGroupsOrder() {
if (opt.debug) { let query = document.querySelectorAll(".group_button");
log("f: AppendGroupToList, groupId: "+groupId+", group_name: "+group_name+", font_color: "+font_color+", SetEvents: "+SetEvents); 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);
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);
} }
Groups_SaveGroups();
} }
if (opt.switch_with_scroll) { function Groups_GenerateNewGroupID() {
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 GenerateNewGroupID(){
let newID = ""; let newID = "";
while (newID == "") { while (newID == "") {
newID = "g_" + GenerateRandomID(); newID = "g_" + GenerateRandomID();
if (document.getElementById(newID) != null) { if (document.getElementById(newID) != null) newID = "";
newID = "";
}
} }
return newID; return newID;
} }
function AddNewGroup(Name, FontColor) { function Groups_GroupRemove(groupId, close_tabs) { // remove group, delete tabs if close_tabs is true
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;
}
// remove group, delete tabs if close_tabs is true
function GroupRemove(groupId, close_tabs) {
if (close_tabs) { if (close_tabs) {
let tabIds = Array.prototype.map.call(document.querySelectorAll("#"+groupId+" .tab"), function(s){ let tabIds = Array.prototype.map.call(document.querySelectorAll("#" + groupId + " .tab"), function(s) {return parseInt(s.id);});
return parseInt(s.id); Tabs_CloseTabs(tabIds);
}); let query = document.querySelectorAll("#" + groupId + " .folder");
CloseTabs(tabIds); for (let s of query) {
document.querySelectorAll("#"+groupId+" .folder").forEach(function(s){ Folders_RemoveFolder(s.id);
RemoveFolder(s.id); }
});
} else { } else {
let TabListFolders = document.getElementById("cftab_list"); let TabList = document.getElementById("°tab_list");
let GroupFolders = document.getElementById("cf"+groupId); let GroupList = document.getElementById("°" + groupId);
if (GroupFolders != null) { if (TabList != null && GroupList != null) {
while (GroupFolders.firstChild) { while (GroupList.firstChild) {
TabListFolders.appendChild(GroupFolders.firstChild); TabList.appendChild(GroupList.firstChild);
} }
} }
let TabListTabs = document.getElementById("cttab_list"); DOM_RefreshExpandStates();
let GroupTabs = document.getElementById("ct"+groupId); DOM_RefreshCounters();
if (GroupTabs != null) {
while (GroupTabs.firstChild) {
TabListTabs.appendChild(GroupTabs.firstChild);
}
}
RefreshExpandStates();
RefreshCounters();
} }
if (groupId != "tab_list") { if (groupId != "tab_list") {
delete tt.groups[groupId]; delete tt.groups[groupId];
if (groupId == tt.active_group) { 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) { if (document.getElementById("_" + groupId).previousSibling) {
SetActiveGroup((document.getElementById("_"+groupId).previousSibling.id).substr(1), true, true); Groups_SetActiveGroup((document.getElementById("_" + groupId).previousSibling.id).substr(1), true, true);
} else { } else {
if (document.getElementById("_" + groupId).nextSibling) { if (document.getElementById("_" + groupId).nextSibling) {
SetActiveGroup((document.getElementById("_"+groupId).nextSibling.id).substr(1), true, true); Groups_SetActiveGroup((document.getElementById("_" + groupId).nextSibling.id).substr(1), true, true);
} else { } else {
SetActiveGroup("tab_list", true, true); Groups_SetActiveGroup("tab_list", true, true);
} }
} }
} }
let group = document.getElementById(groupId); let group = document.getElementById(groupId);
if (group != null) { if (group != null) group.parentNode.removeChild(group);
group.parentNode.removeChild(group);
}
let groupButton = document.getElementById("_" + groupId); let groupButton = document.getElementById("_" + groupId);
if (groupButton != null) { if (groupButton != null) groupButton.parentNode.removeChild(groupButton);
groupButton.parentNode.removeChild(groupButton);
} }
} Groups_SaveGroups();
SaveGroups();
tt.schedule_update_data++; tt.schedule_update_data++;
} }
function UpdateBgGroupsOrder() { function Groups_KeepOnlyOneActiveTabInGroup() {
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 KeepOnlyOneActiveTabInGroup() {
let active_tabs = document.querySelectorAll("#" + tt.active_group + " .active_tab"); let active_tabs = document.querySelectorAll("#" + tt.active_group + " .active_tab");
if (active_tabs.length > 1) { if (active_tabs.length > 1) {
chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) { chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) {
SetActiveTab(activeTab[0].id, false); Tabs_SetActiveTab(activeTab[0].id, false);
}); });
} }
} }
function SetActiveGroup(groupId, switch_to_active_in_group, scroll_to_active) { function Groups_SetActiveGroup(groupId, switch_to_active_in_group, scroll_to_active) {
if (opt.debug) { 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);
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); let group = document.getElementById(groupId);
if (group != null) { if (group != null) {
tt.active_group = groupId; tt.active_group = groupId;
document.querySelectorAll(".group_button").forEach(function(s){ let query = document.querySelectorAll(".group_button");
for (let s of query) {
s.classList.remove("active_group"); s.classList.remove("active_group");
}); }
document.getElementById("_" + groupId).classList.add("active_group"); document.getElementById("_" + groupId).classList.add("active_group");
document.querySelectorAll(".group").forEach(function(s){ query = document.querySelectorAll(".group");
for (let s of query) {
s.style.display = "none"; s.style.display = "none";
}); }
group.style.display = ""; group.style.display = "";
RefreshGUI(); DOM_RefreshGUI();
HideRenameDialogs() DOM_HideRenameDialogs()
let activeTab = document.querySelector("#" + groupId + " .active_tab"); let activeTab = document.querySelector("#" + groupId + " .active_tab");
if (activeTab != null) { if (activeTab != null) {
if (switch_to_active_in_group){ if (switch_to_active_in_group) chrome.tabs.update(parseInt(activeTab.id), {active: true});
chrome.tabs.update(parseInt(activeTab.id), {active: true}); if (scroll_to_active && tt.tabs[activeTab.id]) tt.tabs[activeTab.id].ScrollToTab();
} Groups_KeepOnlyOneActiveTabInGroup();
if (scroll_to_active){
ScrollToTab(activeTab.id);
}
KeepOnlyOneActiveTabInGroup();
} }
if (groupId == "tab_list") { if (groupId == "tab_list") {
document.querySelectorAll("#button_remove_group, #button_edit_group").forEach(function(s){ let query = document.querySelectorAll("#button_remove_group, #button_edit_group");
for (let s of query) {
s.classList.add("disabled"); s.classList.add("disabled");
}); }
} else { } else {
document.querySelectorAll("#button_remove_group, #button_edit_group").forEach(function(s){ let query = document.querySelectorAll("#button_remove_group, #button_edit_group");
for (let s of query) {
s.classList.remove("disabled"); s.classList.remove("disabled");
}); }
} }
chrome.runtime.sendMessage({command: "set_active_group", active_group: groupId, windowId: tt.CurrentWindowId}); chrome.runtime.sendMessage({command: "set_active_group", active_group: groupId, windowId: tt.CurrentWindowId});
RefreshExpandStates(); DOM_RefreshExpandStates();
RefreshCounters(); DOM_RefreshCounters();
if (browserId == "F" && opt.hide_other_groups_tabs_firefox) { if (browserId == "F" && opt.hide_other_groups_tabs_firefox) {
let HideTabIds = Array.prototype.map.call(document.querySelectorAll(".group:not([id='" + groupId + "']) .tab"), function(s) { let HideTabIds = Array.prototype.map.call(document.querySelectorAll(".group:not([id='" + groupId + "']) .tab"), function(s) {
return parseInt(s.id); return parseInt(s.id);
@ -336,239 +273,122 @@ function SetActiveGroup(groupId, switch_to_active_in_group, scroll_to_active) {
let ShowTabIds = Array.prototype.map.call(document.querySelectorAll("#" + groupId + " .tab"), function(s) { let ShowTabIds = Array.prototype.map.call(document.querySelectorAll("#" + groupId + " .tab"), function(s) {
return parseInt(s.id); return parseInt(s.id);
}); });
browser.tabs.hide(HideTabIds); browser.tabs.hide(HideTabIds);
browser.tabs.show(ShowTabIds); browser.tabs.show(ShowTabIds);
} }
} }
} }
function SetActiveTabInGroup(groupId, tabId) { function Groups_SetActiveTabInGroup(groupId, tabId) {
if (document.querySelector("#" + groupId + " [id='" + tabId + "']") != null && tt.groups[groupId] != undefined) { if (document.querySelector("#" + groupId + " [id='" + tabId + "']") != null && tt.groups[groupId] != undefined) {
if (groupId != tt.active_group) { if (groupId != tt.active_group) Groups_SetActiveGroup(groupId, false, true);
SetActiveGroup(groupId, false, true);
}
if (tt.groups[groupId]) { if (tt.groups[groupId]) {
tt.groups[groupId].prev_active_tab = tt.groups[groupId].active_tab; tt.groups[groupId].prev_active_tab = tt.groups[groupId].active_tab;
tt.groups[groupId].active_tab = parseInt(tabId); tt.groups[groupId].active_tab = parseInt(tabId);
} }
SaveGroups(); Groups_SaveGroups();
} }
} }
// Edit group popup function Groups_ShowGroupEditWindow(groupId) { // Edit group popup
function ShowGroupEditWindow(groupId) { DOM_HideRenameDialogs();
HideRenameDialogs();
if (tt.groups[groupId]) { if (tt.groups[groupId]) {
let name = document.getElementById("group_edit_name"); let name = document.getElementById("group_edit_name");
name.value = tt.groups[groupId].name; name.value = tt.groups[groupId].name;
let groupEditDialog = document.getElementById("group_edit"); let groupEditDialog = document.getElementById("group_edit");
groupEditDialog.setAttribute("groupId", groupId); groupEditDialog.setAttribute("groupId", groupId);
groupEditDialog.style.display = "block"; DOM_SetStyle(groupEditDialog, {display: "block", left: "", top: document.getElementById("toolbar").getBoundingClientRect().height + document.getElementById("pin_list").getBoundingClientRect().height + 8 + "px"});
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 DefaultGroupButtonFontColor = window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color");
let GroupEditFont = document.getElementById("group_edit_font"); let GroupEditFont = document.getElementById("group_edit_font");
GroupEditFont.style.backgroundColor = (tt.groups[groupId].font == "" ? DefaultGroupButtonFontColor : "#" + tt.groups[groupId].font); GroupEditFont.style.backgroundColor = (tt.groups[groupId].font == "" ? DefaultGroupButtonFontColor : "#" + tt.groups[groupId].font);
setTimeout(function(){ setTimeout(function() {document.getElementById("group_edit_name").select();}, 5);
document.getElementById("group_edit_name").select();
},5);
} }
} }
// when pressed OK in group popup function Groups_GroupEditConfirm() { // when pressed OK in group popup
function GroupEditConfirm() {
let groupId = document.getElementById("group_edit").getAttribute("groupId"); let groupId = document.getElementById("group_edit").getAttribute("groupId");
if (tt.groups[groupId]) { if (tt.groups[groupId]) {
let GroupEditName = document.getElementById("group_edit_name"); let GroupEditName = document.getElementById("group_edit_name");
// GroupEditName.value = GroupEditName.value.replace(/[\f\n\r\v\t\<\>\+\-\(\)\.\,\;\:\~\/\|\?\@\!\"\'\£\$\%\&\^\#\=\*\[\]]?/gi, "");
tt.groups[groupId].name = GroupEditName.value; tt.groups[groupId].name = GroupEditName.value;
let GroupEditFont = document.getElementById("group_edit_font"); let GroupEditFont = document.getElementById("group_edit_font");
let DefaultGroupButtonFontColor = window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color"); let DefaultGroupButtonFontColor = window.getComputedStyle(document.getElementById("body"), null).getPropertyValue("--group_list_default_font_color");
let ThisGroupButtonFontColor = RGBtoHex(GroupEditFont.style.backgroundColor); let ThisGroupButtonFontColor = Utils_RGBtoHex(GroupEditFont.style.backgroundColor);
if ("#" + ThisGroupButtonFontColor != DefaultGroupButtonFontColor) { if ("#" + ThisGroupButtonFontColor != DefaultGroupButtonFontColor) {
tt.groups[groupId].font = ThisGroupButtonFontColor; tt.groups[groupId].font = ThisGroupButtonFontColor;
document.getElementById("_gte" + groupId).style.color = "#" + ThisGroupButtonFontColor; document.getElementById("_gte" + groupId).style.color = "#" + ThisGroupButtonFontColor;
} }
HideRenameDialogs(); DOM_HideRenameDialogs();
RefreshGUI(); DOM_RefreshGUI();
SaveGroups(); Groups_SaveGroups();
} }
} }
function RestoreStateOfGroupsToolbar() { function Groups_RestoreStateOfGroupsToolbar() {
chrome.runtime.sendMessage({command: "get_group_bar", windowId: tt.CurrentWindowId}, function(response) { chrome.runtime.sendMessage({command: "get_group_bar", windowId: tt.CurrentWindowId}, function(response) {
let toolbarGroups = document.getElementById("toolbar_groups"); let toolbarGroups = document.getElementById("toolbar_groups");
if (response == true) { if (response == true) {
toolbarGroups.style.display = "inline-block"; DOM_SetStyle(toolbarGroups, {display: "inline-block", width: "19px", borderRight: "1px solid var(--group_list_borders)"});
toolbarGroups.style.width = "19px";
toolbarGroups.style.borderRight = "1px solid var(--group_list_borders)";
toolbarGroups.classList.remove("hidden"); toolbarGroups.classList.remove("hidden");
} else { } else {
toolbarGroups.style.display = "none"; DOM_SetStyle(toolbarGroups, {display: "none", width: "0px", borderRight: "none"});
toolbarGroups.style.width = "0px";
toolbarGroups.style.borderRight = "none";
toolbarGroups.classList.add("hidden"); toolbarGroups.classList.add("hidden");
} }
}); });
} }
function GroupsToolbarToggle() { function Groups_GroupsToolbarToggle() {
let toolbarGroups = document.getElementById("toolbar_groups"); let toolbarGroups = document.getElementById("toolbar_groups");
toolbarGroups.classList.toggle("hidden"); toolbarGroups.classList.toggle("hidden");
if (toolbarGroups.classList.contains("hidden")) { if (toolbarGroups.classList.contains("hidden")) {
toolbarGroups.style.display = "none"; DOM_SetStyle(toolbarGroups, {display: "none", width: "0px", borderRight: "none"});
toolbarGroups.style.width = "0px";
toolbarGroups.style.borderRight = "none";
chrome.runtime.sendMessage({command: "set_group_bar", group_bar: false, windowId: tt.CurrentWindowId}); chrome.runtime.sendMessage({command: "set_group_bar", group_bar: false, windowId: tt.CurrentWindowId});
} else { } else {
toolbarGroups.style.display = "inline-block"; DOM_SetStyle(toolbarGroups, {display: "inline-block", width: "19px", borderRight: "1px solid var(--group_list_borders)"});
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}); chrome.runtime.sendMessage({command: "set_group_bar", group_bar: true, windowId: tt.CurrentWindowId});
} }
RefreshGUI(); DOM_RefreshGUI();
} }
function ActionClickGroup(Node, bgOption) { function Groups_ActionClickGroup(Node, bgOption) {
if (bgOption == "new_tab") { if (bgOption == "new_tab") {
if (Node.id == "pin_list") { if (Node.id == "pin_list") Tabs_OpenNewTab(true, undefined, undefined);
OpenNewTab(true, 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("tab") || Node.classList.contains("folder") || Node.classList.contains("group")) { if (Node.classList.contains("group")) Tabs_OpenNewTab(false, undefined, Node.childNodes[0]);
OpenNewTab(false, Node.id);
}
} }
if (bgOption == "activate_previous_active") { if (bgOption == "activate_previous_active") {
chrome.tabs.update(parseInt(tt.groups[tt.active_group].prev_active_tab), {active: true}); chrome.tabs.update(parseInt(tt.groups[tt.active_group].prev_active_tab), {active: true});
} }
if (bgOption == "undo_close_tab") { if (bgOption == "undo_close_tab") {
chrome.sessions.getRecentlyClosed(null, function(sessions) { chrome.sessions.getRecentlyClosed(null, function(sessions) {
if (sessions.length > 0) { if (sessions.length > 0) chrome.sessions.restore(null, function(restored) {});
chrome.sessions.restore(null, function(restored) {});
}
}); });
} }
} }
function Groups_SetActiveTabInEachGroup() { // SET ACTIVE TAB FOR EACH GROUP
// SET ACTIVE TAB FOR EACH GROUP
function SetActiveTabInEachGroup() {
chrome.tabs.query({currentWindow: true, active: true}, function(tabs) { chrome.tabs.query({currentWindow: true, active: true}, function(tabs) {
if (tabs.length) { if (tabs.length) {
SetActiveTab(tabs[0].id); Tabs_SetActiveTab(tabs[0].id);
chrome.runtime.sendMessage({command: "get_active_group", windowId: tt.CurrentWindowId}, function(response) { chrome.runtime.sendMessage({command: "get_active_group", windowId: tt.CurrentWindowId}, function(response) {
if (response) { if (response) {
SetActiveGroup(response, false, true); Groups_SetActiveGroup(response, false, true);
for (var group in tt.groups) { for (var group in tt.groups) {
let ActiveInGroup = document.querySelector("#" + group + " [id='" + tt.groups[group].active_tab + "']"); let ActiveInGroup = document.querySelector("#" + group + " [id='" + tt.groups[group].active_tab + "']");
if (ActiveInGroup != null) { if (ActiveInGroup != null) ActiveInGroup.classList.add("active_tab");
ActiveInGroup.classList.add("active_tab");
}
} }
if (tabs[0].pinned) { if (tabs[0].pinned) {
let ActiveTabinActiveGroup = document.querySelectorAll("#" + tt.active_group + " .active_tab"); let ActiveTabinActiveGroup = document.querySelectorAll("#" + tt.active_group + " .active_tab");
if (ActiveTabinActiveGroup != null) { if (ActiveTabinActiveGroup != null) {
ActiveTabinActiveGroup.forEach(function(s){ for (let s of ActiveTabinActiveGroup) {
s.classList.remove("active_tab"); s.classList.remove("active_tab");
}); }
} }
} }
} else { } else {
SetActiveGroup("tab_list", false, true); Groups_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
});
}

View File

@ -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;
}
}
});
}

View File

@ -1,116 +1,70 @@
// Copyright (c) 2017 kroppy. All rights reserved. function Manager_OpenManagerWindow() {
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license DOM_HideRenameDialogs();
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/ if (opt.debug) Utils_log("f: Manager_OpenManagerWindow");
function OpenManagerWindow() {
HideRenameDialogs();
if (opt.debug) {
log("f: OpenManagerWindow");
}
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let ManagerWindow = document.getElementById("manager_window"); DOM_SetStyle(document.getElementById("manager_window"), {display: "block", top: "", left: ""});
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"); let GroupList = document.getElementById("manager_window_groups_list");
while (GroupList.hasChildNodes()) { while (GroupList.hasChildNodes()) {
GroupList.removeChild(GroupList.firstChild); GroupList.removeChild(GroupList.firstChild);
} }
let SessionsList = document.getElementById("manager_window_sessions_list"); let SessionsList = document.getElementById("manager_window_sessions_list");
while (SessionsList.hasChildNodes()) { while (SessionsList.hasChildNodes()) {
SessionsList.removeChild(SessionsList.firstChild); SessionsList.removeChild(SessionsList.firstChild);
} }
if (storage.hibernated_groups != undefined) { if (storage.hibernated_groups != undefined) {
storage.hibernated_groups.forEach(function(hibernated_group){ for (let hibernated_group of storage.hibernated_groups) {
AddGroupToManagerList(hibernated_group); Manager_AddGroupToManagerList(hibernated_group);
}); }
} }
if (storage.saved_sessions != undefined) { if (storage.saved_sessions != undefined) {
(storage.saved_sessions).forEach(function(saved_session){ for (let saved_session of storage.saved_sessions) {
AddSessionToManagerList(saved_session); Manager_AddSessionToManagerList(saved_session);
}
}
Manager_ReAddSessionAutomaticToManagerList(storage);
}); });
} }
ReAddSessionAutomaticToManagerList(storage); 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")});
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) { DeleteGroupIcon.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let hib_group = this.parentNode; let hib_group = this.parentNode;
let HibernategGroupIndex = Array.from(hib_group.parentNode.children).indexOf(hib_group); let HibernategGroupIndex = Array.from(hib_group.parentNode.children).indexOf(hib_group);
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let hibernated_groups = storage.hibernated_groups; let hibernated_groups = storage.hibernated_groups;
hibernated_groups.splice(HibernategGroupIndex, 1); hibernated_groups.splice(HibernategGroupIndex, 1);
chrome.storage.local.set({hibernated_groups: hibernated_groups}); chrome.storage.local.set({hibernated_groups: hibernated_groups});
hib_group.parentNode.removeChild(hib_group); hib_group.parentNode.removeChild(hib_group);
RefreshGUI(); DOM_RefreshGUI();
}); });
} }
} }
HibernatedGroupRow.appendChild(DeleteGroupIcon); let ExportGroupIcon = DOM_New("div", HibernatedGroupRow, {className: "manager_window_list_button export_hibernated_group", title: chrome.i18n.getMessage("manager_window_savetofile_icon")});
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) { ExportGroupIcon.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let HibernategGroupIndex = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode); let HibernategGroupIndex = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode);
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let filename = storage.hibernated_groups[HibernategGroupIndex].group.name == "" ? labels.noname_group : storage.hibernated_groups[HibernategGroupIndex].group.name; let filename = storage.hibernated_groups[HibernategGroupIndex].group.name == "" ? labels.noname_group : storage.hibernated_groups[HibernategGroupIndex].group.name;
SaveFile(filename, "tt_group", storage.hibernated_groups[HibernategGroupIndex]); File_SaveFile(filename, "tt_group", storage.hibernated_groups[HibernategGroupIndex]);
}); });
} }
} }
HibernatedGroupRow.appendChild(ExportGroupIcon); let LoadGroupIcon = DOM_New("div", HibernatedGroupRow, {className: "manager_window_list_button load_hibernated_group", title: chrome.i18n.getMessage("manager_window_load_icon")});
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) { LoadGroupIcon.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let HibernategGroupIndex = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode); let HibernategGroupIndex = Array.from(this.parentNode.parentNode.children).indexOf(this.parentNode);
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
RecreateGroup(storage.hibernated_groups[HibernategGroupIndex]); Manager_RecreateGroup(storage.hibernated_groups[HibernategGroupIndex]);
}); });
} }
} }
HibernatedGroupRow.appendChild(LoadGroupIcon); 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;
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) { name.oninput = function(event) {
// this.textContent = (this.textContent).replace(/\n/g,' ');
let hib_group_name = this.textContent; let hib_group_name = this.textContent;
let hib_group = this.parentNode; let hib_group = this.parentNode;
let HibernategGroupIndex = Array.from(hib_group.parentNode.children).indexOf(hib_group); let HibernategGroupIndex = Array.from(hib_group.parentNode.children).indexOf(hib_group);
@ -120,27 +74,13 @@ function AddGroupToManagerList(hibernated_group) {
chrome.storage.local.set({hibernated_groups: hibernated_groups}); chrome.storage.local.set({hibernated_groups: hibernated_groups});
}); });
} }
HibernatedGroupRow.appendChild(name); DOM_New("div", HibernatedGroupRow, {className: "manager_window_group_name", textContent: "-(" + hibernated_group.tabs.length + ")"});
let tabsCounter = document.createElement("div"); DOM_RefreshGUI();
tabsCounter.textContent = "-("+ hibernated_group.tabs.length + ")";
tabsCounter.classList = "manager_window_group_name";
HibernatedGroupRow.appendChild(tabsCounter);
RefreshGUI();
} }
function Manager_AddSessionToManagerList(saved_session) {
let SavedSessionRow = DOM_New("li", document.getElementById("manager_window_sessions_list"), {className: "saved_session_row"});
function AddSessionToManagerList(saved_session) { let DeleteSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button delete_saved_session", title: chrome.i18n.getMessage("manager_window_delete_icon")});
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) { DeleteSessionIcon.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let saved_session = this.parentNode; let saved_session = this.parentNode;
@ -150,67 +90,48 @@ function AddSessionToManagerList(saved_session) {
S_Sessions.splice(SessionIndex, 1); S_Sessions.splice(SessionIndex, 1);
chrome.storage.local.set({saved_sessions: S_Sessions}); chrome.storage.local.set({saved_sessions: S_Sessions});
saved_session.parentNode.removeChild(saved_session); saved_session.parentNode.removeChild(saved_session);
RefreshGUI(); DOM_RefreshGUI();
}); });
} }
} }
SavedSessionRow.appendChild(DeleteSessionIcon); let ExportSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button export_saved_session", title: chrome.i18n.getMessage("manager_window_savetofile_icon")});
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) { ExportSessionIcon.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let saved_session = this.parentNode; let saved_session = this.parentNode;
let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session);
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let filename = storage.saved_sessions[SessionIndex].name == "" ? labels.noname_group : storage.saved_sessions[SessionIndex].name; let filename = storage.saved_sessions[SessionIndex].name == "" ? labels.noname_group : storage.saved_sessions[SessionIndex].name;
SaveFile(filename, "tt_session", storage.saved_sessions[SessionIndex].session); File_SaveFile(filename, "tt_session", storage.saved_sessions[SessionIndex].session);
}); });
} }
} }
SavedSessionRow.appendChild(ExportSessionIcon); let LoadSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button load_saved_session", title: chrome.i18n.getMessage("manager_window_load_icon")});
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) { LoadSessionIcon.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let saved_session = this.parentNode; let saved_session = this.parentNode;
let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session);
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let S_Sessions = storage.saved_sessions; let S_Sessions = storage.saved_sessions;
RecreateSession(S_Sessions[SessionIndex].session); Manager_RecreateSession(S_Sessions[SessionIndex].session);
}); });
} }
} }
SavedSessionRow.appendChild(LoadSessionIcon); let MergeSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button merge_saved_session", title: chrome.i18n.getMessage("manager_window_merge_icon")});
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) { MergeSessionIcon.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let saved_session = this.parentNode; let saved_session = this.parentNode;
let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session);
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let S_Sessions = storage.saved_sessions; let S_Sessions = storage.saved_sessions;
ImportMergeTabs(S_Sessions[SessionIndex].session); Manager_ImportMergeTabs(S_Sessions[SessionIndex].session);
}); });
} }
} }
SavedSessionRow.appendChild(MergeSessionIcon); let name = DOM_New("div", SavedSessionRow, {className: "manager_window_session_name", contentEditable: true, textContent: saved_session.name});
name.onkeydown = function(event) {
let name = document.createElement("div"); return event.which != 13;
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) { name.oninput = function(event) {
// this.textContent = (this.textContent).replace(/\n/g,' ');
let session_name = this.textContent; let session_name = this.textContent;
let s = this.parentNode; let s = this.parentNode;
let SessionIndex = Array.from(s.parentNode.children).indexOf(s); let SessionIndex = Array.from(s.parentNode.children).indexOf(s);
@ -220,154 +141,604 @@ function AddSessionToManagerList(saved_session) {
chrome.storage.local.set({saved_sessions: S_Sessions}); chrome.storage.local.set({saved_sessions: S_Sessions});
}); });
} }
SavedSessionRow.appendChild(name); DOM_RefreshGUI();
RefreshGUI();
} }
function Manager_ReAddSessionAutomaticToManagerList(storage) {
function ReAddSessionAutomaticToManagerList(storage) {
let SessionsAutomaticList = document.getElementById("manager_window_autosessions_list"); let SessionsAutomaticList = document.getElementById("manager_window_autosessions_list");
while (SessionsAutomaticList.hasChildNodes()) { while (SessionsAutomaticList.hasChildNodes()) {
SessionsAutomaticList.removeChild(SessionsAutomaticList.firstChild); SessionsAutomaticList.removeChild(SessionsAutomaticList.firstChild);
} }
if (storage.saved_sessions_automatic != undefined) { if (storage.saved_sessions_automatic != undefined) {
(storage.saved_sessions_automatic).forEach(function(saved_sessions_automatic){ for (let saved_sessions_automatic of storage.saved_sessions_automatic) {
AddSessionAutomaticToManagerList(saved_sessions_automatic); Manager_AddSessionAutomaticToManagerList(saved_sessions_automatic);
});
} }
RefreshGUI(); }
DOM_RefreshGUI();
} }
function Manager_AddSessionAutomaticToManagerList(saved_session) {
function AddSessionAutomaticToManagerList(saved_session) { let SavedSessionRow = DOM_New("li", document.getElementById("manager_window_autosessions_list"), {className: "saved_session_row"});
let SessionsList = document.getElementById("manager_window_autosessions_list"); let LoadSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button load_saved_session", title: chrome.i18n.getMessage("manager_window_load_icon")});
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) { LoadSessionIcon.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let saved_session = this.parentNode; let saved_session = this.parentNode;
let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session);
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let S_Sessions = storage.saved_sessions_automatic; let S_Sessions = storage.saved_sessions_automatic;
RecreateSession(S_Sessions[SessionIndex].session); Manager_RecreateSession(S_Sessions[SessionIndex].session);
}); });
} }
} }
SavedSessionRow.appendChild(LoadSessionIcon); let MergeSessionIcon = DOM_New("div", SavedSessionRow, {className: "manager_window_list_button merge_saved_session", title: chrome.i18n.getMessage("manager_window_merge_icon")});
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) { MergeSessionIcon.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let saved_session = this.parentNode; let saved_session = this.parentNode;
let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session); let SessionIndex = Array.from(saved_session.parentNode.children).indexOf(saved_session);
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let S_Sessions = storage.saved_sessions_automatic; let S_Sessions = storage.saved_sessions_automatic;
// RecreateSession(S_Sessions[SessionIndex].session); Manager_ImportMergeTabs(S_Sessions[SessionIndex].session);
ImportMergeTabs(S_Sessions[SessionIndex].session);
}); });
} }
} }
SavedSessionRow.appendChild(MergeSessionIcon); DOM_New("div", SavedSessionRow, {className: "manager_window_session_name", textContent: saved_session.name});
DOM_RefreshGUI();
let name = document.createElement("div");
name.textContent = saved_session.name;
name.classList = "manager_window_session_name";
SavedSessionRow.appendChild(name);
RefreshGUI();
} }
function Manager_SetManagerEvents() {
function SetManagerEvents() {
document.getElementById("manager_window_close").onmousedown = function(event) { document.getElementById("manager_window_close").onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) DOM_HideRenameDialogs();
HideRenameDialogs();
} }
} let query = document.querySelectorAll(".manager_window_toolbar_button");
for (let s of query) {
document.querySelectorAll(".manager_window_toolbar_button").forEach(function(s){
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
document.querySelectorAll(".manager_window_panel").forEach(function(s){ let window_panels = document.querySelectorAll(".manager_window_panel");
for (let s of window_panels) {
s.classList.remove("mw_pan_on"); s.classList.remove("mw_pan_on");
}); }
document.getElementById((this.id).replace("button", "panel")).classList.add("mw_pan_on"); document.getElementById((this.id).replace("button", "panel")).classList.add("mw_pan_on");
let panel_on = document.querySelectorAll(".mw_on");
document.querySelectorAll(".mw_on").forEach(function(s){ for (let s of panel_on) {
s.classList.remove("mw_on"); s.classList.remove("mw_on");
}); }
this.classList.add("mw_on"); this.classList.add("mw_on");
RefreshGUI(); DOM_RefreshGUI();
}
} }
} }
});
document.getElementById("manager_window_button_import_group").onmousedown = function(event) { document.getElementById("manager_window_button_import_group").onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let inputFile = ShowOpenFileDialog(".tt_group"); let inputFile = File_ShowOpenFileDialog(".tt_group");
inputFile.onchange = function(event) { inputFile.onchange = function(event) {
ImportGroup(false, true); Manager_ImportGroup(false, true);
} }
} }
} }
document.getElementById("manager_window_button_hibernate_group").onmousedown = function(event) { document.getElementById("manager_window_button_hibernate_group").onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
ExportGroup(tt.active_group, false, true); Manager_ExportGroup(tt.active_group, false, true);
setTimeout(function() { setTimeout(function() {Groups_GroupRemove(tt.active_group, true);}, 100);
GroupRemove(tt.active_group, true); setTimeout(function() {Manager_OpenManagerWindow();}, 150);
}, 100);
setTimeout(function() {
OpenManagerWindow();
}, 150);
} }
} }
document.getElementById("manager_window_button_save_current_session").onmousedown = function(event) { document.getElementById("manager_window_button_save_current_session").onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let d = new Date(); let d = new Date();
ExportSession((d.toLocaleString().replace("/", ".").replace("/", ".").replace(":", "").replace(":", "")), false, true, false); Manager_ExportSession((d.toLocaleString().replace(/\//g, ".").replace(/:/g, "")), false, true, false);
} }
} }
document.getElementById("manager_window_button_import_session").onmousedown = function(event) { document.getElementById("manager_window_button_import_session").onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let inputFile = ShowOpenFileDialog(".tt_session"); let inputFile = File_ShowOpenFileDialog(".tt_session");
inputFile.onchange = function(event) { inputFile.onchange = function(event) {
ImportSession(false, true, false); Manager_ImportSession(false, true, false);
} }
} }
} }
let autosessions_save_max_to_keep = document.getElementById("manager_window_autosessions_maximum_saves"); 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.value = opt.autosave_max_to_keep;
autosessions_save_max_to_keep.oninput = function(event) { autosessions_save_max_to_keep.oninput = function(event) {
opt.autosave_max_to_keep = parseInt(this.value); opt.autosave_max_to_keep = parseInt(this.value);
SavePreferences(); Preferences_SavePreferences(opt);
} }
let autosessions_save_timer = document.getElementById("manager_window_autosessions_save_timer"); let autosessions_save_timer = document.getElementById("manager_window_autosessions_save_timer");
autosessions_save_timer.value = opt.autosave_interval; autosessions_save_timer.value = opt.autosave_interval;
autosessions_save_timer.oninput = function(event) { autosessions_save_timer.oninput = function(event) {
opt.autosave_interval = parseInt(this.value); opt.autosave_interval = parseInt(this.value);
SavePreferences(); Preferences_SavePreferences(opt);
clearInterval(tt.AutoSaveSession); clearInterval(tt.AutoSaveSession);
StartAutoSaveSession(); 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);
}
} }

File diff suppressed because it is too large Load Diff

26
scripts/preferences.js Normal file
View File

@ -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);
}
}

View File

@ -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;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,4 @@
// Copyright (c) 2017 kroppy. All rights reserved. function Theme_RestorePinListRowSettings() {
// 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 RestorePinListRowSettings() {
plist = document.getElementById("pin_list"); plist = document.getElementById("pin_list");
if (opt.pin_list_multi_row) { if (opt.pin_list_multi_row) {
plist.style.whiteSpace = "normal"; plist.style.whiteSpace = "normal";
@ -23,27 +7,29 @@ function RestorePinListRowSettings() {
plist.style.whiteSpace = ""; plist.style.whiteSpace = "";
plist.style.overflowX = ""; plist.style.overflowX = "";
} }
RefreshGUI(); DOM_RefreshGUI();
} }
function ApplyTheme(theme) { function Theme_ApplyTheme(theme) {
RestoreStateOfGroupsToolbar(); Groups_RestoreStateOfGroupsToolbar();
ApplySizeSet(theme["TabsSizeSetNumber"]); Theme_ApplySizeSet(theme["TabsSizeSetNumber"]);
ApplyColorsSet(theme["ColorsSet"]); Theme_ApplyColorsSet(theme["ColorsSet"]);
ApplyTabsMargins(theme["TabsMargins"]); Theme_ApplyTabsMargins(theme["TabsMargins"]);
RefreshGUI(); 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) { for (var groupId in tt.groups) {
let groupTitle = document.getElementById("_gte" + groupId); let groupTitle = document.getElementById("_gte" + groupId);
if (groupTitle != null && tt.groups[groupId].font == "") { if (groupTitle != null && tt.groups[groupId].font == "") groupTitle.style.color = "";
groupTitle.style.color = "";
} }
} DOM_Loadi18n();
Loadi18n();
} }
// theme colors is an object with css variables (but without --), for example; {"button_background": "#f2f2f2", "filter_box_border": "#cccccc"} // theme colors is an object with css variables (but without --), for example; {"button_background": "#f2f2f2", "filter_box_border": "#cccccc"}
function ApplyColorsSet(ThemeColors){ function Theme_ApplyColorsSet(ThemeColors) {
let css_variables = ""; let css_variables = "";
for (let css_variable in ThemeColors) { for (let css_variable in ThemeColors) {
css_variables = css_variables + "--" + css_variable + ":" + ThemeColors[css_variable] + ";"; css_variables = css_variables + "--" + css_variable + ":" + ThemeColors[css_variable] + ";";
@ -56,7 +42,7 @@ function ApplyColorsSet(ThemeColors){
} }
} }
function ApplySizeSet(size){ function Theme_ApplySizeSet(size) {
for (let si = 0; si < document.styleSheets.length; si++) { 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).match("sizes_preset") != null) {
if (document.styleSheets[si].ownerNode.id == "sizes_preset_" + size) { if (document.styleSheets[si].ownerNode.id == "sizes_preset_" + size) {
@ -66,17 +52,9 @@ function ApplySizeSet(size){
} }
} }
} }
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 ApplyTabsMargins(size){ function Theme_ApplyTabsMargins(size) {
for (let si = 0; si < document.styleSheets.length; si++) { 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).match("tabs_margin") != null) {
if (document.styleSheets[si].ownerNode.id == "tabs_margin_" + size) { if (document.styleSheets[si].ownerNode.id == "tabs_margin_" + size) {
@ -88,7 +66,26 @@ function ApplyTabsMargins(size){
} }
} }
function GetCurrentToolbar(storage) { 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"]) { if (storage["toolbar"]) {
return storage["toolbar"]; return storage["toolbar"];
} else { } else {
@ -96,14 +93,13 @@ function GetCurrentToolbar(storage) {
} }
} }
function Theme_GetCurrentTheme(storage) {
function GetCurrentTheme(storage) {
if (storage["current_theme"] && storage["themes"] && storage["themes"][storage["current_theme"]]) { if (storage["current_theme"] && storage["themes"] && storage["themes"][storage["current_theme"]]) {
let theme = storage["themes"][storage["current_theme"]]; let theme = storage["themes"][storage["current_theme"]];
let correctedTheme = CheckTheme(theme); let correctedTheme = Theme_CheckTheme(theme);
if (correctedTheme.theme_version < 4 && storage["preferences"].show_toolbar == undefined) { if (correctedTheme.theme_version < 4 && storage["preferences"].show_toolbar == undefined) {
opt.show_toolbar = correctedTheme.ToolbarShow; opt.show_toolbar = correctedTheme.ToolbarShow;
SavePreferences(); Preferences_SavePreferences(opt);
} }
return correctedTheme; return correctedTheme;
} else { } else {
@ -112,165 +108,101 @@ function GetCurrentTheme(storage) {
} }
// OPTIONS PAGE // OPTIONS PAGE
function LoadTheme(ThemeId, reloadInSidebar) { function Theme_LoadTheme(ThemeId, reloadInSidebar) {
let query = document.querySelectorAll(".theme_buttons");
document.querySelectorAll(".theme_buttons").forEach(function(s){ for (let s of query) {
s.disabled = true; s.disabled = true;
}); }
chrome.storage.local.set({current_theme: ThemeId}, function() { chrome.storage.local.set({current_theme: ThemeId}, function() {
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
SelectedTheme = Object.assign({}, GetCurrentTheme(storage)); SelectedTheme = Object.assign({}, Theme_GetCurrentTheme(storage));
setTimeout(function() { setTimeout(function() {
document.getElementById("new_theme_name").value = SelectedTheme.theme_name; document.getElementById("new_theme_name").value = SelectedTheme.theme_name;
setTimeout(function() { setTimeout(function() {
// SetToolbarEvents(true, false, false, "");
RemoveToolbarEditEvents(); RemoveToolbarEditEvents();
Theme_ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]);
ApplySizeSet(SelectedTheme["TabsSizeSetNumber"]); Theme_ApplyColorsSet(SelectedTheme["ColorsSet"]);
ApplyColorsSet(SelectedTheme["ColorsSet"]);
document.getElementById("_gtetab_list").style.color = ""; document.getElementById("_gtetab_list").style.color = "";
document.getElementById("_gtetab_list2").style.color = ""; document.getElementById("_gtetab_list2").style.color = "";
if (SelectedTheme["TabsMargins"]) { if (SelectedTheme["TabsMargins"]) {
document.getElementById("tabs_margin_spacing")[SelectedTheme["TabsMargins"]].checked = true; document.getElementById("tabs_margin_spacing")[SelectedTheme["TabsMargins"]].checked = true;
ApplyTabsMargins(SelectedTheme["TabsMargins"]); Theme_ApplyTabsMargins(SelectedTheme["TabsMargins"]);
} else { } else {
document.getElementById("tabs_margin_spacing")["2"].checked = true; document.getElementById("tabs_margin_spacing")["2"].checked = true;
} }
if (reloadInSidebar) chrome.runtime.sendMessage({command: "reload_theme", ThemeId: ThemeId, theme: SelectedTheme});
if (reloadInSidebar) { let query = document.querySelectorAll(".theme_buttons");
chrome.runtime.sendMessage({command: "reload_theme", ThemeId: ThemeId, theme: SelectedTheme}); for (let s of query) {
}
document.querySelectorAll(".theme_buttons").forEach(function(s){
s.disabled = false; s.disabled = false;
}); }
}, 200); }, 200);
}, 200); }, 200);
}); });
}); });
} }
function SaveTheme(ThemeId) { function Theme_SaveTheme(ThemeId) {
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
SelectedTheme.theme_version = DefaultTheme.theme_version; SelectedTheme.theme_version = DefaultTheme.theme_version;
let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {}; let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {};
LSthemes[ThemeId] = Object.assign({}, SelectedTheme); LSthemes[ThemeId] = Object.assign({}, SelectedTheme);
chrome.storage.local.set({themes: LSthemes}); chrome.storage.local.set({themes: LSthemes});
chrome.runtime.sendMessage({command: "reload_theme", ThemeId: ThemeId, theme: SelectedTheme}); chrome.runtime.sendMessage({command: "reload_theme", ThemeId: ThemeId, theme: SelectedTheme});
return SelectedTheme; return SelectedTheme;
}); });
} }
function AddNewTheme() { function Theme_AddNewTheme() {
let ThemeId = GenerateRandomID() + GenerateRandomID(); let ThemeId = GenerateRandomID() + GenerateRandomID();
let ThemeList = document.getElementById("theme_list"); let ThemeList = document.getElementById("theme_list");
let ThemeNameBox = document.getElementById("new_theme_name"); let ThemeNameBox = document.getElementById("new_theme_name");
let NewName = ThemeNameBox.value; let NewName = ThemeNameBox.value;
if (ThemeNameBox.value == "") { if (ThemeNameBox.value == "") {
alert(chrome.i18n.getMessage("options_theme_name_cannot_be_empty")); alert(chrome.i18n.getMessage("options_theme_name_cannot_be_empty"));
return; return;
} }
SelectedTheme = Object.assign({}, DefaultTheme); SelectedTheme = Object.assign({}, DefaultTheme);
SelectedTheme["ColorsSet"] = {}; 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; ThemeNameBox.value = NewName;
SelectedTheme["theme_name"] = NewName; SelectedTheme["theme_name"] = NewName;
themes.push(ThemeId); themes.push(ThemeId);
DOM_New("option", ThemeList, {value: ThemeId, text: NewName});
let ThemeNameOption = document.createElement("option");
ThemeNameOption.value = ThemeId;
ThemeNameOption.text = NewName;
ThemeList.add(ThemeNameOption);
ThemeList.selectedIndex = ThemeList.options.length - 1; ThemeList.selectedIndex = ThemeList.options.length - 1;
Theme_SaveTheme(ThemeId);
SaveTheme(ThemeId); setTimeout(function() {Theme_LoadTheme(ThemeId, true);}, 50);
setTimeout(function() {
LoadTheme(ThemeId, true);
}, 50);
chrome.storage.local.set({current_theme: ThemeId}); chrome.storage.local.set({current_theme: ThemeId});
RefreshFields(); RefreshFields();
} }
function DeleteSelectedTheme() { function Theme_DeleteSelectedTheme() {
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {}; let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {};
let ThemeList = document.getElementById("theme_list"); let ThemeList = document.getElementById("theme_list");
themes.splice(ThemeList.selectedIndex, 1); themes.splice(ThemeList.selectedIndex, 1);
if (LSthemes[current_theme]) { if (LSthemes[current_theme]) delete LSthemes[current_theme];
delete LSthemes[current_theme];
}
chrome.storage.local.set({themes: LSthemes}); chrome.storage.local.set({themes: LSthemes});
ThemeList.remove(ThemeList.selectedIndex); ThemeList.remove(ThemeList.selectedIndex);
current_theme = (ThemeList.options.length > 0) ? ThemeList.value : "default"; current_theme = (ThemeList.options.length > 0) ? ThemeList.value : "default";
chrome.storage.local.set({current_theme: current_theme}); chrome.storage.local.set({current_theme: current_theme});
if (ThemeList.options.length == 0) { if (ThemeList.options.length == 0) {
current_theme = ""; current_theme = "";
SelectedTheme = Object.assign({}, DefaultTheme); SelectedTheme = Object.assign({}, DefaultTheme);
SelectedTheme["ColorsSet"] = {}; SelectedTheme["ColorsSet"] = {};
chrome.storage.local.set({themes: {}}); chrome.storage.local.set({themes: {}});
setTimeout(function() { setTimeout(function() {chrome.runtime.sendMessage({command: "reload_theme", themeName: "", theme: SelectedTheme});}, 500);
chrome.runtime.sendMessage({command: "reload_theme", themeName: "", theme: SelectedTheme});
}, 500);
} }
LoadTheme(current_theme, true); Theme_LoadTheme(current_theme, true);
RefreshFields(); RefreshFields();
}); });
} }
function RenameSelectedTheme() { function Theme_RenameSelectedTheme() {
let ThemeList = document.getElementById("theme_list"); let ThemeList = document.getElementById("theme_list");
let ThemeNameBox = document.getElementById("new_theme_name"); 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 == "") { if (ThemeNameBox.value == "") {
alert(chrome.i18n.getMessage("options_theme_name_cannot_be_empty")); alert(chrome.i18n.getMessage("options_theme_name_cannot_be_empty"));
return; return;
} }
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {}; let LSthemes = storage.themes ? Object.assign({}, storage.themes) : {};
ThemeList.options[ThemeList.selectedIndex].text = ThemeNameBox.value; ThemeList.options[ThemeList.selectedIndex].text = ThemeNameBox.value;
@ -281,22 +213,17 @@ function RenameSelectedTheme() {
}); });
} }
function Theme_CheckTheme(theme) {
function CheckTheme(theme) {
if (theme.theme_version < 2) { if (theme.theme_version < 2) {
theme["ColorsSet"]["scrollbar_height"] = theme.ScrollbarPinList + "px"; theme["ColorsSet"]["scrollbar_height"] = theme.ScrollbarPinList + "px";
theme["ColorsSet"]["scrollbar_width"] = theme.ScrollbarTabList + "px"; theme["ColorsSet"]["scrollbar_width"] = theme.ScrollbarTabList + "px";
} }
if (theme["TabsMargins"] == undefined) { if (theme["TabsMargins"] == undefined) theme["TabsMargins"] = "2";
theme["TabsMargins"] = "2";
}
if (theme.theme_version < 4) { if (theme.theme_version < 4) {
delete theme["ColorsSet"]["active_font_weight"]; delete theme["ColorsSet"]["active_font_weight"];
delete theme["ColorsSet"]["expand_lines"]; delete theme["ColorsSet"]["expand_lines"];
delete theme["ColorsSet"]["expand_open_border"]; delete theme["ColorsSet"]["expand_open_border"];
delete theme["ColorsSet"]["expand_closed_border"]; delete theme["ColorsSet"]["expand_closed_border"];
if (theme["ColorsSet"]["toolbar_background"]) { if (theme["ColorsSet"]["toolbar_background"]) {
theme["ColorsSet"]["toolbar_shelf_background"] = theme["ColorsSet"]["toolbar_background"]; theme["ColorsSet"]["toolbar_shelf_background"] = theme["ColorsSet"]["toolbar_background"];
theme["ColorsSet"]["button_on_background"] = theme["ColorsSet"]["toolbar_background"]; theme["ColorsSet"]["button_on_background"] = theme["ColorsSet"]["toolbar_background"];
@ -305,39 +232,19 @@ function CheckTheme(theme) {
theme["ColorsSet"]["button_on_icons"] = theme["ColorsSet"]["button_icons"]; theme["ColorsSet"]["button_on_icons"] = theme["ColorsSet"]["button_icons"];
theme["ColorsSet"]["button_shelf_icons"] = theme["ColorsSet"]["button_icons"]; theme["ColorsSet"]["button_shelf_icons"] = theme["ColorsSet"]["button_icons"];
} }
if (theme["ColorsSet"]["button_background"]) { if (theme["ColorsSet"]["button_background"]) theme["ColorsSet"]["button_shelf_background"] = 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"];
} }
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; return theme;
} }
function Theme_ImportTheme() {
function ImportTheme() {
var file = document.getElementById("file_import"); var file = document.getElementById("file_import");
var fr = new FileReader(); var fr = new FileReader();
if (file.files[0] == undefined) return; if (file.files[0] == undefined) return;
@ -345,68 +252,29 @@ function ImportTheme() {
fr.onload = function() { fr.onload = function() {
var data = fr.result; var data = fr.result;
file.parentNode.removeChild(file); file.parentNode.removeChild(file);
var themeObj = JSON.parse(data); 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"]) { if (themeObj.theme_version < DefaultTheme["theme_version"]) alert(chrome.i18n.getMessage("options_loaded_theme_older_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"]) { if (themeObj.theme_version <= DefaultTheme["theme_version"]) {
let ThemeList = document.getElementById("theme_list"); let ThemeList = document.getElementById("theme_list");
let ThemeId = GenerateRandomID() + GenerateRandomID(); let ThemeId = GenerateRandomID() + GenerateRandomID();
let correctedTheme = CheckTheme(themeObj); let correctedTheme = Theme_CheckTheme(themeObj);
SelectedTheme = Object.assign({}, DefaultTheme); SelectedTheme = Object.assign({}, DefaultTheme);
for (var val in correctedTheme.ColorsSet) { for (var val in correctedTheme.ColorsSet) {
SelectedTheme["ColorsSet"][val] = correctedTheme.ColorsSet[val]; SelectedTheme["ColorsSet"][val] = correctedTheme.ColorsSet[val];
} }
SelectedTheme["TabsSizeSetNumber"] = correctedTheme.TabsSizeSetNumber; SelectedTheme["TabsSizeSetNumber"] = correctedTheme.TabsSizeSetNumber;
SelectedTheme["TabsMargins"] = correctedTheme["TabsMargins"]; SelectedTheme["TabsMargins"] = correctedTheme["TabsMargins"];
SelectedTheme["theme_version"] = DefaultTheme["theme_version"]; 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; 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); themes.push(ThemeId);
SaveTheme(ThemeId); Theme_SaveTheme(ThemeId);
let theme_name = DOM_New("option", undefined, {value: ThemeId, text: SelectedTheme["theme_name"]});
var theme_name = document.createElement("option");
theme_name.value = ThemeId;
theme_name.text = SelectedTheme["theme_name"];
ThemeList.add(theme_name); ThemeList.add(theme_name);
ThemeList.selectedIndex = ThemeList.options.length - 1; ThemeList.selectedIndex = ThemeList.options.length - 1;
current_theme = ThemeId; current_theme = ThemeId;
document.createElement("new_theme_name").value = ThemeId; document.createElement("new_theme_name").value = ThemeId;
setTimeout(function() {Theme_LoadTheme(ThemeId, true);}, 500);
setTimeout(function() {
LoadTheme(ThemeId, true);
}, 500);
RefreshFields(); RefreshFields();
DefaultTheme["ColorsSet"] = {}; DefaultTheme["ColorsSet"] = {};
chrome.storage.local.set({current_theme: ThemeId}); chrome.storage.local.set({current_theme: ThemeId});

View File

@ -1,236 +1,165 @@
// Copyright (c) 2017 kroppy. All rights reserved. function Toolbar_RestoreToolbarSearchFilter() { // RESTORE LAST USED SEARCH TYPE (URL OR TITLE) IN TOOLBAR SEARCH
// 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) { chrome.runtime.sendMessage({command: "get_search_filter", windowId: tt.CurrentWindowId}, function(response) {
let ButtonFilter = document.getElementById("button_filter_type");
if (response == "url") { if (response == "url") {
ButtonFilter.classList.add("url"); DOM_SetClasses(document.getElementById("button_filter_type"), ["url"], ["title"], []);
ButtonFilter.classList.remove("title");
} else { } else {
ButtonFilter.classList.add("title"); DOM_SetClasses(document.getElementById("button_filter_type"), ["title"], ["url"], []);
ButtonFilter.classList.remove("url");
} }
}); });
} }
// RESTORE LAST ACTIVE SHELF (SEARCH, TOOLS, GROUPS, SESSION OR FOLDER) IN TOOLBAR function Toolbar_RestoreToolbarShelf() { // 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) { chrome.runtime.sendMessage({command: "get_active_shelf", windowId: tt.CurrentWindowId}, function(response) {
let filterBox = document.getElementById("filter_box"); let filterBox = document.getElementById("filter_box");
filterBox.setAttribute("placeholder", labels.searchbox); filterBox.setAttribute("placeholder", labels.searchbox);
filterBox.style.opacity = "1"; filterBox.style.opacity = "1";
document.querySelectorAll(".on").forEach(function(s){ let query = document.querySelectorAll(".on");
for (let s of query) {
s.classList.remove("on"); s.classList.remove("on");
}); }
document.querySelectorAll(".toolbar_shelf").forEach(function(s){ query = document.querySelectorAll(".toolbar_shelf");
for (let s of query) {
s.classList.add("hidden"); s.classList.add("hidden");
}); }
if (response == "search" && document.getElementById("button_search") != null) { if (response == "search" && document.getElementById("button_search") != null) {
document.getElementById("toolbar_search").classList.remove("hidden"); document.getElementById("toolbar_search").classList.remove("hidden");
document.getElementById("button_search").classList.add("on"); document.getElementById("button_search").classList.add("on");
} }
if (response == "tools" && document.getElementById("button_tools") != null) { if (response == "tools" && document.getElementById("button_tools") != null) {
document.getElementById("toolbar_shelf_tools").classList.remove("hidden"); document.getElementById("toolbar_shelf_tools").classList.remove("hidden");
document.getElementById("button_tools").classList.add("on"); document.getElementById("button_tools").classList.add("on");
} }
if (response == "groups" && document.getElementById("button_groups") != null) { if (response == "groups" && document.getElementById("button_groups") != null) {
document.getElementById("toolbar_shelf_groups").classList.remove("hidden"); document.getElementById("toolbar_shelf_groups").classList.remove("hidden");
document.getElementById("button_groups").classList.add("on"); document.getElementById("button_groups").classList.add("on");
} }
if (response == "backup" && document.getElementById("button_backup") != null) { if (response == "backup" && document.getElementById("button_backup") != null) {
document.getElementById("toolbar_shelf_backup").classList.remove("hidden"); document.getElementById("toolbar_shelf_backup").classList.remove("hidden");
document.getElementById("button_backup").classList.add("on"); document.getElementById("button_backup").classList.add("on");
} }
if (response == "folders" && document.getElementById("button_folders") != null) { if (response == "folders" && document.getElementById("button_folders") != null) {
document.getElementById("toolbar_shelf_folders").classList.remove("hidden"); document.getElementById("toolbar_shelf_folders").classList.remove("hidden");
document.getElementById("button_folders").classList.add("on"); document.getElementById("button_folders").classList.add("on");
} }
if (browserId != "F") { if (browserId != "F") {
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
let bak1 = storage["windows_BAK1"] ? storage["windows_BAK1"] : []; let bak1 = storage["windows_BAK1"] ? storage["windows_BAK1"] : [];
let bak2 = storage["windows_BAK2"] ? storage["windows_BAK2"] : []; let bak2 = storage["windows_BAK2"] ? storage["windows_BAK2"] : [];
let bak3 = storage["windows_BAK3"] ? storage["windows_BAK3"] : []; let bak3 = storage["windows_BAK3"] ? storage["windows_BAK3"] : [];
if (bak1.length && document.getElementById("#button_load_bak1") != null) { if (bak1.length && document.getElementById("#button_load_bak1") != null) {
document.getElementById("button_load_bak1").classList.remove("disabled"); document.getElementById("button_load_bak1").classList.remove("disabled");
} else { } else {
document.getElementById("button_load_bak1").classList.add("disabled"); document.getElementById("button_load_bak1").classList.add("disabled");
} }
if (bak2.length && document.getElementById("#button_load_bak2") != null) { if (bak2.length && document.getElementById("#button_load_bak2") != null) {
document.getElementById("button_load_bak2").classList.remove("disabled"); document.getElementById("button_load_bak2").classList.remove("disabled");
} else { } else {
document.getElementById("button_load_bak2").classList.add("disabled"); document.getElementById("button_load_bak2").classList.add("disabled");
} }
if (bak3.length && document.getElementById("#button_load_bak3") != null) { if (bak3.length && document.getElementById("#button_load_bak3") != null) {
document.getElementById("button_load_bak3").classList.remove("disabled"); document.getElementById("button_load_bak3").classList.remove("disabled");
} else { } else {
document.getElementById("button_load_bak3").classList.add("disabled"); document.getElementById("button_load_bak3").classList.add("disabled");
} }
});
}
DOM_RefreshGUI();
}); });
} }
RefreshGUI(); function Toolbar_ShelfToggle(mousebutton, button, toolbarId, SendMessage, SidebarRefreshGUI, OptionsRefreshGUI) { // FUNCTION TO TOGGLE SHELFS AND SAVE IT
});
}
// FUNCTION TO TOGGLE SHELFS AND SAVE IT
function ShelfToggle(mousebutton, button, toolbarId, SendMessage) {
if (mousebutton == 1) { if (mousebutton == 1) {
if (button.classList.contains("on")) { if (button.classList.contains("on")) {
document.querySelectorAll(".on").forEach(function(s){ let query = document.querySelectorAll(".on");
for (let s of query) {
s.classList.remove("on"); s.classList.remove("on");
}); }
document.querySelectorAll(".toolbar_shelf").forEach(function(s){ query = document.querySelectorAll(".toolbar_shelf");
for (let s of query) {
s.classList.add("hidden"); s.classList.add("hidden");
}); }
chrome.runtime.sendMessage({command: "set_active_shelf", active_shelf: "", windowId: tt.CurrentWindowId});
} else { } else {
document.querySelectorAll(".toolbar_shelf:not(#"+toolbarId+")").forEach(function(s){ let query = document.querySelectorAll(".toolbar_shelf:not(#" + toolbarId + ")");
for (let s of query) {
s.classList.add("hidden"); s.classList.add("hidden");
}); }
document.getElementById(toolbarId).classList.remove("hidden"); document.getElementById(toolbarId).classList.remove("hidden");
chrome.runtime.sendMessage({command: "set_active_shelf", active_shelf: SendMessage, windowId: tt.CurrentWindowId}); chrome.runtime.sendMessage({command: "set_active_shelf", active_shelf: SendMessage, windowId: tt.CurrentWindowId});
document.querySelectorAll(".on:not(#"+button.id+")").forEach(function(s){ query = document.querySelectorAll(".on:not(#" + button.id + ")");
for (let s of query) {
s.classList.remove("on"); s.classList.remove("on");
}); }
button.classList.add("on"); button.classList.add("on");
} }
RefreshGUI(); if (SidebarRefreshGUI) DOM_RefreshGUI();
if (OptionsRefreshGUI) RefreshGUI();
} }
} }
function RemoveToolbar() { function Toolbar_RemoveToolbar() {
let toolbar = document.getElementById("toolbar"); let toolbar = document.getElementById("toolbar");
while (toolbar.hasChildNodes()) { while (toolbar.hasChildNodes()) {
toolbar.removeChild(toolbar.firstChild); toolbar.removeChild(toolbar.firstChild);
} }
} }
function RecreateToolbar(NewToolbar) { function Toolbar_RecreateToolbar(NewToolbar) {
let toolbar = document.getElementById("toolbar"); let toolbar = document.getElementById("toolbar");
for (var shelf in NewToolbar) { for (var shelf in NewToolbar) {
let NewShelf = document.createElement("div"); let NewShelf = DOM_New("div", toolbar, {id: shelf, className: "toolbar_shelf"});
NewShelf.id = shelf; for (let button of NewToolbar[shelf]) {
NewShelf.classList = "toolbar_shelf"; let Newbutton = DOM_New("div", NewShelf, {id: button, className: "button"});
toolbar.appendChild(NewShelf); DOM_New("div", Newbutton, {className: "button_img"});
}
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 toolbar_main = document.getElementById("toolbar_main");
let SearchShelf = document.getElementById("toolbar_search"); let SearchShelf = document.getElementById("toolbar_search");
if (toolbar_main != null && SearchShelf != null) { if (toolbar_main != null && SearchShelf != null) {
toolbar_main.classList.remove("toolbar_shelf"); toolbar_main.classList.remove("toolbar_shelf");
let SearchBox = DOM_New("div", SearchShelf, {id: "toolbar_search_input_box"});
let SearchBox = document.createElement("div"); DOM_New("input", SearchBox, {id: "filter_box", className: "text_input", type: "text", placeholder: labels.searchbox});
SearchBox.id = "toolbar_search_input_box"; DOM_New("div", SearchBox, {id: "button_filter_clear", type: "reset"}, {opacity: "0", position: "absolute"});
SearchShelf.appendChild(SearchBox); let SearchButtons = DOM_New("div", SearchShelf, {id: "toolbar_search_buttons"});
DOM_AppendToNode(document.getElementById("button_filter_type"), SearchButtons);
let SearchInput = document.createElement("input"); DOM_AppendToNode(document.getElementById("filter_search_go_prev"), SearchButtons);
SearchInput.classList = "text_input"; DOM_AppendToNode(document.getElementById("filter_search_go_next"), SearchButtons);
SearchInput.id = "filter_box"; DOM_Loadi18n();
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_RecreateToolbarUnusedButtons(buttonsIds) { // OPTIONS PAGE
function RecreateToolbarUnusedButtons(buttonsIds) {
let unused_buttons = document.getElementById("toolbar_unused_buttons"); let unused_buttons = document.getElementById("toolbar_unused_buttons");
for (let button of buttonsIds) {
buttonsIds.forEach(function(button){ let Newbutton = DOM_New("div", unused_buttons, {id: button, className: "button"});
let Newbutton = document.createElement("div"); DOM_New("div", Newbutton, {className: "button_img"});
Newbutton.id = button; }
Newbutton.classList = "button";
unused_buttons.appendChild(Newbutton);
let NewbuttonIMG = document.createElement("div");
NewbuttonIMG.classList = "button_img";
Newbutton.appendChild(NewbuttonIMG);
});
} }
function Toolbar_SaveToolbar() { // OPTIONS PAGE
function SaveToolbar() {
let unused_buttons = []; let unused_buttons = [];
let toolbar = {}; let toolbar = {};
let unused_buttons_div = document.querySelectorAll("#toolbar_unused_buttons .button");
let u = document.querySelectorAll("#toolbar_unused_buttons .button"); for (let b of unused_buttons_div) {
u.forEach(function(b){
unused_buttons.push(b.id); unused_buttons.push(b.id);
}); }
let toolbar_div = document.getElementById("toolbar");
let t = document.getElementById("toolbar"); for (let toolbar_shelf of toolbar_div.childNodes) {
t.childNodes.forEach(function(s){ toolbar[toolbar_shelf.id] = [];
toolbar[s.id] = []; let query = document.querySelectorAll("#" + toolbar_shelf.id + " .button");
let t = document.querySelectorAll("#"+s.id+" .button").forEach(function(b){ for (let button of query) {
toolbar[s.id].push(b.id); toolbar[toolbar_shelf.id].push(button.id);
}); }
}); }
chrome.storage.local.set({toolbar: toolbar}); chrome.storage.local.set({toolbar: toolbar});
chrome.storage.local.set({unused_buttons: unused_buttons}); chrome.storage.local.set({unused_buttons: unused_buttons});
setTimeout(function() { setTimeout(function() {chrome.runtime.sendMessage({command: "reload_toolbar", toolbar: toolbar, opt: opt});}, 50);
chrome.runtime.sendMessage({command: "reload_toolbar", toolbar: toolbar, opt: opt});
}, 50);
} }
// ASSIGN MOUSE EVENTS FOR TOOLBAR BUTTONS, (Buttons AND BindToolbarShelfToggleButtons), PARAMETERS DECIDE IF BUTTONS ARE CLICKABLE
// ASSIGN MOUSE EVENTS FOR TOOLBAR BUTTONS, (Buttons AND ToolbarShelfToggle), 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 // 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 ClearSearch = document.getElementById("button_filter_clear");
let FilterBox = document.getElementById("filter_box"); let FilterBox = document.getElementById("filter_box");
@ -240,319 +169,266 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
FilterBox.removeEventListener("oninput", function() {}); FilterBox.removeEventListener("oninput", function() {});
ClearSearch.removeEventListener("onmousedown", function() {}); ClearSearch.removeEventListener("onmousedown", function() {});
} }
if (Buttons) { if (BindButtons) {
// FILTER ON INPUT // FILTER ON INPUT
FilterBox.oninput = function(event) { FilterBox.oninput = function(event) {
FindTab(this.value); Tabs_FindTab(this.value);
} }
// CLEAR FILTER BUTTON // CLEAR FILTER BUTTON
ClearSearch.onmousedown = function(event) { ClearSearch.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
this.style.opacity = "0";
this.style.opacity = "0"; this.style.opacity = "0";
this.setAttribute("title", ""); this.setAttribute("title", "");
FindTab(""); Tabs_FindTab("");
} }
} }
} }
} }
document.querySelectorAll(".button").forEach(function(s){ let query = document.querySelectorAll(".button");
for (let s of query) {
if (CleanPreviousBindings) { if (CleanPreviousBindings) {
s.removeEventListener("onmousedown", function() {}); s.removeEventListener("onmousedown", function() {});
s.removeEventListener("onclick", function() {}); s.removeEventListener("onclick", function() {});
s.removeEventListener("click", function() {}); s.removeEventListener("click", function() {});
} }
if (BindToolbarShelfToggleButtons) {
if (ToolbarShelfToggle) {
if (s.id == "button_search") { if (s.id == "button_search") {
s.addEventListener(ToolbarShelfToggleClickType, function(event) { s.addEventListener(ToolbarShelfToggleClickType, function(event) {
if (event.which == 1) { if (event.which == 1) Toolbar_ShelfToggle(event.which, this, "toolbar_search", "search", SidebarRefreshGUI, OptionsRefreshGUI);
ShelfToggle(event.which, this, "toolbar_search", "search");
}
}); });
} }
if (s.id == "button_tools") { if (s.id == "button_tools") {
s.addEventListener(ToolbarShelfToggleClickType, function(event) { s.addEventListener(ToolbarShelfToggleClickType, function(event) {
if (event.which == 1) { if (event.which == 1) Toolbar_ShelfToggle(event.which, this, "toolbar_shelf_tools", "tools", SidebarRefreshGUI, OptionsRefreshGUI);
ShelfToggle(event.which, this, "toolbar_shelf_tools", "tools");
}
}); });
} }
if (s.id == "button_groups") { if (s.id == "button_groups") {
s.addEventListener(ToolbarShelfToggleClickType, function(event) { s.addEventListener(ToolbarShelfToggleClickType, function(event) {
if (event.which == 1) { if (event.which == 1) Toolbar_ShelfToggle(event.which, this, "toolbar_shelf_groups", "groups", SidebarRefreshGUI, OptionsRefreshGUI);
ShelfToggle(event.which, this, "toolbar_shelf_groups", "groups");
}
}); });
} }
if (s.id == "button_backup") { if (s.id == "button_backup") {
s.addEventListener(ToolbarShelfToggleClickType, function(event) { s.addEventListener(ToolbarShelfToggleClickType, function(event) {
if (event.which == 1) { if (event.which == 1) Toolbar_ShelfToggle(event.which, this, "toolbar_shelf_backup", "backup", SidebarRefreshGUI, OptionsRefreshGUI);
ShelfToggle(event.which, this, "toolbar_shelf_backup", "backup");
}
}); });
} }
if (s.id == "button_folders") { if (s.id == "button_folders") {
s.addEventListener(ToolbarShelfToggleClickType, function(event) { s.addEventListener(ToolbarShelfToggleClickType, function(event) {
if (event.which == 1) { if (event.which == 1) Toolbar_ShelfToggle(event.which, this, "toolbar_shelf_folders", "folders", SidebarRefreshGUI, OptionsRefreshGUI);
ShelfToggle(event.which, this, "toolbar_shelf_folders", "folders");
}
}); });
} }
} }
if (BindButtons) {
if (Buttons) { if (s.id == "button_new") { // NEW TAB
// NEW TAB
if (s.id == "button_new") {
s.onclick = function(event) { s.onclick = function(event) {
if (event.which == 1) { if (event.which == 1) {
if (opt.append_tab_from_toolbar == "group_root") { if (opt.append_tab_from_toolbar == "group_root") Tabs_OpenNewTab(false, undefined, document.getElementById("°"+tt.active_group));
OpenNewTab(false, tt.active_group); if (opt.append_tab_from_toolbar == "as_regular_orphan") Tabs_OpenNewTab(false, undefined, undefined);
}
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) { s.onmousedown = function(event) {
// DUPLICATE TAB if (event.which == 2) { // DUPLICATE TAB
if (event.which == 2) {
event.preventDefault(); 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; 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) { if (activeTab != null && tt.tabs[activeTab.id]) tt.tabs[activeTab.id].DuplicateTab();
DuplicateTab(activeTab);
} }
} if (event.which == 3) { // SCROLL TO TAB
// SCROLL TO TAB
if (event.which == 3) {
chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) { chrome.tabs.query({currentWindow: true, active: true}, function(activeTab) {
if (activeTab[0].pinned && opt.pin_list_multi_row == false) { if (activeTab[0].pinned && opt.pin_list_multi_row == false && tt.tabs[activeTab[0].id]) tt.tabs[activeTab[0].id].ScrollToTab();
ScrollToTab(activeTab[0].id);
}
if (activeTab[0].pinned == false) { if (activeTab[0].pinned == false) {
let Tab = document.getElementById(activeTab[0].id); let Tab = document.getElementById(activeTab[0].id);
let groupId = GetParentsByClass(Tab, "group")[0].id; let groupId = DOM_GetParentsByClass(Tab, "group")[0].id;
SetActiveGroup(groupId, true, true); Groups_SetActiveGroup(groupId, true, true);
} }
}); });
} }
} }
} }
// PIN TAB if (s.id == "button_pin") { // PIN TAB
if (s.id == "button_pin") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let Tabs = document.querySelectorAll(".pin.active_tab, .pin.selected_tab, #"+tt.active_group+" .active_tab, #"+tt.active_group+" .selected_tab"); let Tabs = document.querySelectorAll(".pin.active_tab, .pin.selected, #" + tt.active_group + " .active_tab, #" + tt.active_group + " .selected");
Tabs.forEach(function(s){ for (let s of Tabs) {
chrome.tabs.update(parseInt(s.id), {pinned: Tabs[0].classList.contains("tab")}); chrome.tabs.update(parseInt(s.id), {pinned: Tabs[0].classList.contains("tab")});
})
} }
} }
} }
// VERTICAL TABS OPTIONS }
if (s.id == "button_options") { if (s.id == "button_options") { // VERTICAL TABS OPTIONS
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) chrome.tabs.create({url: "options/options.html"});
chrome.tabs.create({url: "options.html"});
} }
} }
} if (s.id == "button_undo") { // UNDO CLOSE
// UNDO CLOSE
if (s.id == "button_undo") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
chrome.sessions.getRecentlyClosed(null, function(sessions) { chrome.sessions.getRecentlyClosed(null, function(sessions) {
if (sessions.length > 0) { if (sessions.length > 0) chrome.sessions.restore(null, function(restored) {});
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
// 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) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
if (document.querySelectorAll("#"+tt.active_group+" .selected_folder").length > 0){ DOM_FreezeSelection(false);
let detach = GetSelectedFolders(); let Nodes = [];
Detach(detach.TabsIds, detach.Folders); 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 { } else {
let tabsArr = []; query = document.querySelectorAll(".active_tab");
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));
});
} }
}); for (let s of query) {
Detach(tabsArr); 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
// GO TO PREVIOUS SEARCH RESULT
if (s.id == "filter_search_go_prev") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let filtered = document.querySelectorAll("#" + tt.active_group + " .tab.filtered"); let filtered = document.querySelectorAll("#" + tt.active_group + " .tab.filtered");
if (filtered.length > 0) { if (filtered.length > 0) {
document.querySelectorAll(".highlighted_search").forEach(function(s){
let query = document.querySelectorAll(".highlighted_search");
for (let s of query) {
s.classList.remove("highlighted_search"); s.classList.remove("highlighted_search");
}); }
if (tt.SearchIndex == 0) { if (tt.SearchIndex == 0) {
tt.SearchIndex = filtered.length - 1; tt.SearchIndex = filtered.length - 1;
} else { } else {
tt.SearchIndex--; tt.SearchIndex--;
} }
filtered[tt.SearchIndex].classList.add("highlighted_search"); filtered[tt.SearchIndex].classList.add("highlighted_search");
ScrollToTab(filtered[tt.SearchIndex].id); 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
// GO TO NEXT SEARCH RESULT
if (s.id == "filter_search_go_next") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let filtered = document.querySelectorAll("#" + tt.active_group + " .tab.filtered"); let filtered = document.querySelectorAll("#" + tt.active_group + " .tab.filtered");
if (filtered.length > 0) { if (filtered.length > 0) {
document.querySelectorAll(".highlighted_search").forEach(function(s){
let query = document.querySelectorAll(".highlighted_search");
for (let s of query) {
s.classList.remove("highlighted_search"); s.classList.remove("highlighted_search");
}); }
if (tt.SearchIndex == filtered.length - 1) { if (tt.SearchIndex == filtered.length - 1) {
tt.SearchIndex = 0; tt.SearchIndex = 0;
} else { } else {
tt.SearchIndex++; tt.SearchIndex++;
} }
filtered[tt.SearchIndex].classList.add("highlighted_search"); filtered[tt.SearchIndex].classList.add("highlighted_search");
ScrollToTab(filtered[tt.SearchIndex].id); 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
// SHOW/HIDE GROUPS TOOLBAR
if (s.id == "button_groups_toolbar_hide") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) Groups_GroupsToolbarToggle();
GroupsToolbarToggle();
} }
} }
} if (s.id == "button_manager_window") { // SHOW GROUP MANAGER
// SHOW GROUP MANAGER
if (s.id == "button_manager_window") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1 && document.getElementById("manager_window").style.top == "-500px") { if (event.which == 1 && document.getElementById("manager_window").style.top == "-500px") {
OpenManagerWindow(); Manager_OpenManagerWindow();
} else { } else {
HideRenameDialogs(); DOM_HideRenameDialogs();
} }
} }
} }
// NEW GROUP if (s.id == "button_new_group") { // NEW GROUP
if (s.id == "button_new_group") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
AddNewGroup(); let NewGroupId = Groups_AddNewGroup();
Groups_ShowGroupEditWindow(NewGroupId);
} }
} }
} }
if (s.id == "button_remove_group") { // REMOVE GROUP
// REMOVE GROUP
if (s.id == "button_remove_group") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
if (tt.active_group != "tab_list") { if (tt.active_group != "tab_list") Groups_GroupRemove(tt.active_group, event.shiftKey);
GroupRemove(tt.active_group, event.shiftKey);
} }
} }
} }
} if (s.id == "button_edit_group") { // EDIT GROUP
// EDIT GROUP
if (s.id == "button_edit_group") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
if (tt.active_group != "tab_list") { if (tt.active_group != "tab_list") Groups_ShowGroupEditWindow(tt.active_group);
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);
} }
}
// EXPORT GROUP if (s.id == "button_import_group") { // IMPORT GROUP
if (s.id == "button_export_group") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
ExportGroup(tt.active_group, tt.groups[tt.active_group].name, false); let inputFile = File_ShowOpenFileDialog(".tt_group");
}
}
}
// 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) { inputFile.onchange = function(event) {
ImportGroup(true, false); 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) {
// NEW FOLDER let query = document.querySelectorAll("#" + tt.active_group + " .selected");
if (s.id == "button_new_folder") { for (let s of query) {
Folders_RemoveFolder(s.id);
}
}
}
}
if (s.id == "button_unload" || s.id == "button_discard") { // DISCARD TABS
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let FolderId = AddNewFolder({SetEvents: true}); if (document.querySelectorAll(".pin.selected:not(.active_tab), #" + tt.active_group + " .selected:not(.active_tab)").length > 0) {
ShowRenameFolderDialog(FolderId); Tabs_DiscardTabs(
} Array.prototype.map.call(document.querySelectorAll(".pin:not(.active_tab), #" + tt.active_group + " .selected:not(.active_tab)"), function(s) {
}
}
// 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); return parseInt(s.id);
}) })
); );
} else { } else {
DiscardTabs( Tabs_DiscardTabs(
Array.prototype.map.call(document.querySelectorAll(".pin:not(.active_tab), .tab:not(.active_tab)"), function(s) { Array.prototype.map.call(document.querySelectorAll(".pin:not(.active_tab), .tab:not(.active_tab)"), function(s) {
return parseInt(s.id); return parseInt(s.id);
}) })
@ -561,59 +437,50 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
} }
} }
} }
// IMPORT BACKUP if (s.id == "button_import_bak") { // IMPORT BACKUP
if (s.id == "button_import_bak") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let inputFile = ShowOpenFileDialog(".tt_session"); let inputFile = File_ShowOpenFileDialog(".tt_session");
inputFile.onchange = function(event) { inputFile.onchange = function(event) {
ImportSession(true, false, false); Manager_ImportSession(true, false, false);
} }
} }
} }
} }
// EXPORT BACKUP if (s.id == "button_export_bak") { // EXPORT BACKUP
if (s.id == "button_export_bak") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let d = new Date(); let d = new Date();
ExportSession((d.toLocaleString().replace("/", ".").replace("/", ".").replace(":", "").replace(":", "")), true, false, false); Manager_ExportSession((d.toLocaleString().replace(/\//g, ".").replace(/:/g, "")), true, false, false);
} }
} }
} }
// MERGE BACKUP if (s.id == "button_import_merge_bak") { // MERGE BACKUP
if (s.id == "button_import_merge_bak") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
let inputFile = ShowOpenFileDialog(".tt_session"); let inputFile = File_ShowOpenFileDialog(".tt_session");
inputFile.onchange = function(event) { inputFile.onchange = function(event) {
ImportSession(false, false, true); Manager_ImportSession(false, false, true);
// ImportMergeTabs(); // Manager_ImportMergeTabs();
} }
} }
} }
} }
if (s.id == "button_filter_type") { // CHANGE FILTERING TYPE
// CHANGE FILTERING TYPE
if (s.id == "button_filter_type") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
if (this.classList.contains("url")) { if (this.classList.contains("url")) {
this.classList.remove("url"); DOM_SetClasses(this, ["title"], ["url"], []);
this.classList.add("title");
chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "title", windowId: tt.CurrentWindowId}); chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "title", windowId: tt.CurrentWindowId});
} else { } else {
this.classList.remove("title"); DOM_SetClasses(this, ["url"], ["title"], []);
this.classList.add("url");
chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "url", windowId: tt.CurrentWindowId}); chrome.runtime.sendMessage({command: "set_search_filter", search_filter: "url", windowId: tt.CurrentWindowId});
} }
FindTab(document.getElementById("filter_box").value); Tabs_FindTab(document.getElementById("filter_box").value);
} }
} }
} }
if (s.id == "button_reboot") { // EMERGENCY RELOAD
// EMERGENCY RELOAD
if (s.id == "button_reboot") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) {
chrome.runtime.sendMessage({command: "reload"}); chrome.runtime.sendMessage({command: "reload"});
@ -622,87 +489,50 @@ function SetToolbarEvents(CleanPreviousBindings, Buttons, ToolbarShelfToggle, To
} }
} }
} }
// 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") { if (browserId != "F") {
// BOOKMARKS if (s.id == "button_bookmarks") { // BOOKMARKS
if (s.id == "button_bookmarks") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) chrome.tabs.create({url: "chrome://bookmarks/"});
chrome.tabs.create({url: "chrome://bookmarks/"});
} }
} }
} if (s.id == "button_downloads") { // DOWNLOADS
// DOWNLOADS
if (s.id == "button_downloads") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) chrome.tabs.create({url: "chrome://downloads/"});
chrome.tabs.create({url: "chrome://downloads/"});
} }
} }
} if (s.id == "button_history") { // HISTORY
// HISTORY
if (s.id == "button_history") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) chrome.tabs.create({url: "chrome://history/"});
chrome.tabs.create({url: "chrome://history/"});
} }
} }
} if (s.id == "button_extensions") { // EXTENSIONS
// EXTENSIONS
if (s.id == "button_extensions") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) chrome.tabs.create({url: "chrome://extensions"});
chrome.tabs.create({url: "chrome://extensions"});
} }
} }
} if (s.id == "button_settings") { // SETTINGS
// SETTINGS
if (s.id == "button_settings") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1) { if (event.which == 1) chrome.tabs.create({url: "chrome://settings/"});
chrome.tabs.create({url: "chrome://settings/"});
} }
} }
} if (s.id == "button_load_bak1" || s.id == "button_load_bak2" || s.id == "button_load_bak3") { // LOAD BACKUPS
// LOAD BACKUPS
if (s.id == "button_load_bak1" || s.id == "button_load_bak2" || s.id == "button_load_bak3") {
s.onmousedown = function(event) { s.onmousedown = function(event) {
if (event.which == 1 && this.classList.contains("disabled") == false) { if (event.which == 1 && this.classList.contains("disabled") == false) {
let BakN = (this.id).substr(15); let BakN = (this.id).substr(15);
chrome.storage.local.get(null, function(storage) { 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["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"); } if (Object.keys(storage["tabs_BAK" + BakN]).length > 0) {
chrome.runtime.sendMessage({command: "reload"}); chrome.runtime.sendMessage({command: "reload_sidebar"}); location.reload(); 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();
}); });
} }
} }
} }
} }
} }
}
});
} }

View File

@ -1,401 +1,19 @@
// Copyright (c) 2017 kroppy. All rights reserved. function Utils_RGBtoHex(color) { // color in format "rgb(r,g,b)" or simply "r,g,b" (can have spaces, but must contain "," between values)
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license color = color.replace(/[rgb(]|\)|\s/g, "");
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/ color = color.split(",");
return color.map(function(v) {return ("0" + Math.min(Math.max(parseInt(v), 0), 255).toString(16)).slice(-2);}).join("");
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++; function Utils_HexToRGB(hex, alpha) {
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 SavePreferences() {
chrome.storage.local.set({preferences: opt});
chrome.runtime.sendMessage({command: "reload_options", opt: opt});
}
function LoadDefaultPreferences() {
opt = Object.assign({}, DefaultPreferences);
}
function ShowOpenFileDialog(extension) {
let body = document.getElementById("body");
let inp = document.createElement("input");
inp.id = "file_import";
inp.type = "file";
inp.accept = extension;
inp.style.display = "none";
body.appendChild(inp);
inp.click();
return inp;
}
function SaveFile(filename, extension, data) {
let file = new File([JSON.stringify(data)], filename+"."+extension, {type: "text/"+extension+";charset=utf-8"} );
let body = document.getElementById("body");
let savelink = document.createElement("a");
savelink.href = URL.createObjectURL(file);
savelink.fileSize = file.size;
savelink.target = "_blank";
savelink.style.display = "none";
savelink.type = "file";
savelink.download = filename+"."+extension;
body.appendChild(savelink);
setTimeout(function() {
savelink.click();
setTimeout(function() {
savelink.parentNode.removeChild(savelink);
}, 60000);
}, 10);
}
function AppendToNode(Node, AppendNode) {
if (Node != null && AppendNode != null) {
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('#', ''); hex = hex.replace('#', '');
let r = parseInt(hex.length == 3 ? hex.slice(0, 1).repeat(2) : hex.slice(0, 2), 16); 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 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); 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+')'; } if (alpha) {
} return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')';
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 { } else {
ButtonFilterClear.style.opacity = "1"; return 'rgb(' + r + ', ' + g + ', ' + b + ')';
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) { function Utils_log(log) {
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}); chrome.runtime.sendMessage({command: "debug", log: log});
} }
}

View File

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title></title> <title></title>
@ -23,6 +24,7 @@
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_2.css" id="sizes_preset_2" /> <link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_2.css" id="sizes_preset_2" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_3.css" id="sizes_preset_3" /> <link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_3.css" id="sizes_preset_3" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_4.css" id="sizes_preset_4" /> <link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_4.css" id="sizes_preset_4" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_size_preset_5.css" id="sizes_preset_5" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_0.css" id="tabs_margin_0" /> <link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_0.css" id="tabs_margin_0" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_1.css" id="tabs_margin_1" /> <link type="text/css" rel="stylesheet" media="all" href="theme/theme_tabs_margin_1.css" id="tabs_margin_1" />
@ -31,7 +33,10 @@
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_colors.css" id="theme_colors" /> <link type="text/css" rel="stylesheet" media="all" href="theme/theme_colors.css" id="theme_colors" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme.css" id="theme" /> <link type="text/css" rel="stylesheet" media="all" href="theme/theme.css" id="theme" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_manager.css" id="manager" /> <link type="text/css" rel="stylesheet" media="all" href="theme/theme_manager.css" id="manager" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_blinking_attention.css" id="blinking_pins" />
<link type="text/css" rel="stylesheet" media="all" href="theme/theme_blinking_audio.css" id="blinking_audio" />
</head> </head>
<body id="body" class="sidebar_body"> <body id="body" class="sidebar_body">
<div id="DragImage" style="display: none; width:0px; height:0px;"></div> <div id="DragImage" style="display: none; width:0px; height:0px;"></div>
@ -66,7 +71,12 @@
</ul> </ul>
<ul class="edit_dialog" id="manager_window"> <ul class="edit_dialog" id="manager_window">
<div id="manager_window_header"><div id="manager_window_header_title"></div><div id="manager_window_close"><div class="close_img"></div></div></div> <div id="manager_window_header">
<div id="manager_window_header_title"></div>
<div id="manager_window_close">
<div class="close_img"></div>
</div>
</div>
<div id="manager_window_toolbar"> <div id="manager_window_toolbar">
<div class="manager_window_toolbar_button mw_on" id="manager_window_groups_button"> <div class="manager_window_toolbar_button mw_on" id="manager_window_groups_button">
@ -118,82 +128,11 @@
<div id="status_message"></div> <div id="status_message"></div>
<div id="busy_spinner"></div> <div id="busy_spinner"></div>
</div> </div>
<ul class="menu" id="main_menu"></ul>
<ul class="menu" id="main_menu">
<li class="menu_item" id="menu_new_pin"></li>
<div class="separator" id="separator_newt"></div>
<li class="menu_item" id="menu_new_tab"></li>
<div class="separator" id="separator_unpt"></div>
<li class="menu_item" id="menu_unpin_tab"></li>
<div class="separator" id="separator_pit"></div>
<li class="menu_item" id="menu_pin_tab"></li>
<div class="separator" id="separator_newf"></div>
<li class="menu_item" id="menu_new_folder"></li>
<div class="separator" id="separator_renf"></div>
<li class="menu_item" id="menu_rename_folder"></li>
<div class="separator" id="separator_delf"></div>
<li class="menu_item" id="menu_delete_folder"></li>
<div class="separator" id="separator_dupt"></div>
<li class="menu_item" id="menu_duplicate_tab"></li>
<div class="separator" id="separator_undclo"></div>
<li class="menu_item" id="menu_undo_close_tab"></li>
<div class="separator" id="separator_bkt"></div>
<li class="menu_item" id="menu_bookmark_tree"></li>
<div class="separator" id="separator_expat"></div>
<li class="menu_item" id="menu_expand_tree"></li>
<div class="separator" id="separator_collt"></div>
<li class="menu_item" id="menu_collapse_tree"></li>
<div class="separator" id="separator_expaa"></div>
<li class="menu_item" id="menu_expand_all"></li>
<div class="separator" id="separator_colla"></div>
<li class="menu_item" id="menu_collapse_all"></li>
<div class="separator" id="separator_deta"></div>
<li class="menu_item" id="menu_detach_tab"></li>
<div class="separator" id="separator_rel"></div>
<li class="menu_item" id="menu_reload_tab"></li>
<div class="separator" id="separator_unlo"></div>
<li class="menu_item" id="menu_unload"></li>
<div class="separator" id="separator_clo"></div>
<li class="menu_item" id="menu_close"></li>
<div class="separator" id="separator_clot"></div>
<li class="menu_item" id="menu_close_tree"></li>
<div class="separator" id="separator_cloo"></div>
<li class="menu_item" id="menu_close_other"></li>
<div class="separator" id="separator_mut"></div>
<li class="menu_item" id="menu_mute_tab"></li>
<div class="separator" id="separator_mutt"></div>
<li class="menu_item" id="menu_mute_tree"></li>
<div class="separator" id="separator_unmu"></div>
<li class="menu_item" id="menu_unmute_tab"></li>
<div class="separator" id="separator_unmut"></div>
<li class="menu_item" id="menu_unmute_tree"></li>
<div class="separator" id="separator_mutot"></div>
<li class="menu_item" id="menu_mute_other"></li>
<div class="separator" id="separator_unmutot"></div>
<li class="menu_item" id="menu_unmute_other"></li>
<div class="separator" id="separator_newg"></div>
<li class="menu_item" id="menu_new_group"></li>
<div class="separator" id="separator_reng"></div>
<li class="menu_item" id="menu_rename_group"></li>
<div class="separator" id="separator_delg"></div>
<li class="menu_item" id="menu_delete_group"></li>
<div class="separator" id="separator_delgclo"></div>
<li class="menu_item" id="menu_delete_group_tabs_close"></li>
<div class="separator" id="separator_gunlo"></div>
<li class="menu_item" id="menu_groups_unload"></li>
<div class="separator" id="separator_ghiber"></div>
<li class="menu_item" id="menu_groups_hibernate"></li>
<div class="separator" id="separator_gtbcl"></div>
<li class="menu_item" id="menu_group_tabs_close"></li>
<div class="separator" id="separator_gbk"></div>
<li class="menu_item" id="menu_bookmark_group"></li>
<div class="separator" id="separator_tts"></div>
<li class="menu_item" id="menu_manager_window"></li>
<li class="menu_item" id="menu_treetabs_settings"></li>
</ul>
<!-- <!--
<ul class="menu" id="move_to_group_menu"> <ul class="menu" id="move_to_group_menu">
<li data-action="move_to_new_group" class="menu_item" id="menu_detach_tab_to_new_group"></li> <li data-action="move_to_new_group" class="menu_item" id="menu_detach_tab_to_new_group"></li>
<div class="separator"></div> <div class="separator"></div>
@ -218,24 +157,20 @@
<script type="text/javascript" src="scripts/common.js"></script> <script type="text/javascript" src="./global.js"></script>
<script type="text/javascript" src="scripts/listeners.js"></script> <script type="text/javascript" src="./scripts/utils.js"></script>
<script type="text/javascript" src="./scripts/dom.js"></script>
<script type="text/javascript" src="scripts/utils.js"></script> <script type="text/javascript" src="./scripts/tabs.js"></script>
<script type="text/javascript" src="scripts/theme.js"></script> <script type="text/javascript" src="./scripts/folders.js"></script>
<script type="text/javascript" src="scripts/toolbar.js"></script> <script type="text/javascript" src="./scripts/groups.js"></script>
<script type="text/javascript" src="scripts/refresh.js"></script> <script type="text/javascript" src="./scripts/menu.js"></script>
<script type="text/javascript" src="./scripts/manager.js"></script>
<script type="text/javascript" src="scripts/backup.js"></script> <script type="text/javascript" src="./scripts/toolbar.js"></script>
<script type="text/javascript" src="scripts/tabs.js"></script> <script type="text/javascript" src="./scripts/theme.js"></script>
<script type="text/javascript" src="scripts/folders.js"></script> <script type="text/javascript" src="./scripts/file.js"></script>
<script type="text/javascript" src="scripts/groups.js"></script> <script type="text/javascript" src="./scripts/preferences.js"></script>
<script type="text/javascript" src="scripts/menu.js"></script> <script type="text/javascript" src="./scripts/bookmark.js"></script>
<script type="text/javascript" src="scripts/manager.js"></script> <script type="text/javascript" src="./sidebar.js"></script>
<script type="text/javascript" src="sidebar.js"></script>
<script type="text/javascript" src="scripts/events.js"></script>
</body> </body>

View File

@ -1,37 +1,287 @@
// Copyright (c) 2017 kroppy. All rights reserved. // SIDEBAR VARIABLES
// Use of this source code is governed by a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license let tt = {
// that can be found at https://creativecommons.org/licenses/by-nc-nd/4.0/ CurrentWindowId: 0,
active_group: "tab_list",
tabs: {},
groups: {},
folders: {},
schedule_update_data: 0,
schedule_rearrange_tabs: 0,
document.addEventListener("DOMContentLoaded", Run(), false); Dragging: false,
DraggingGroup: false,
DraggingPin: false,
DraggingTab: false,
DraggingFolder: false,
DragTreeDepth: 0,
DragOverId: "",
DragOverTimer: undefined,
DOMmenu: undefined,
menu: {},
menuItemNode: undefined,
SearchIndex: 0,
function Run() { AutoSaveSession: undefined,
ShowStatusBar({show: true, spinner: true, message: "Starting up"}); pressed_keys: []
chrome.runtime.sendMessage({command: "is_bg_ready"}, function(response) { };
if (response == true) {
Initialize(); function StartSidebarListeners() {
} else { if (browserId == "F") {
browser.browserAction.onClicked.addListener(function(tab) {
if (tab.windowId == tt.CurrentWindowId) browser.sidebarAction.close();
});
}
chrome.commands.onCommand.addListener(function(command) {
if (command == "close_tree") {
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 = [];
let close_tree = document.querySelectorAll("[id='" + tabs[0].id + "'] .tab, [id='" + tabs[0].id + "']");
for (let s of close_tree) {
tabsArr.push(parseInt(s.id));
if (s.childNodes[2].childNodes.length > 0) {
let trees_children = document.querySelectorAll("#" + s.childNodes[2].id + " .tab");
for (let t of trees_children) {
tabsArr.push(parseInt(t.id));
}
}
}
Tabs_CloseTabs(tabsArr);
});
}
});
}
});
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message.command == "bg_started") {
window.location.reload();
return;
}
if (message.command == "backup_available") {
if (opt.debug) Utils_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_start") {
if (opt.debug) Utils_log("message to sidebar " + tt.CurrentWindowId + ": message: " + message.command);
DOM_CleanUpDragAndDrop();
tt.DragTreeDepth = message.DragTreeDepth;
tt.DraggingGroup = message.DraggingGroup;
tt.DraggingPin = message.DraggingPin;
tt.DraggingTab = message.DraggingTab;
tt.DraggingFolder = message.DraggingFolder;
return;
}
if (message.command == "drag_end") {
if (opt.debug) Utils_log("message to sidebar " + tt.CurrentWindowId + ": message: " + message.command);
tt.Dragging = false;
DOM_CleanUpDragAndDrop();
DOM_RemoveHighlight();
return;
}
if (message.command == "remove_folder") {
if (opt.debug) Utils_log("message to sidebar " + tt.CurrentWindowId + ": message: " + message.command + " folderId: " + message.folderId);
Folders_RemoveFolder(message.folderId);
return;
}
if (message.command == "remove_group") {
if (opt.debug) Utils_log("message to sidebar " + tt.CurrentWindowId + ": message: " + message.command + " groupId: " + message.groupId);
setTimeout(function() {Groups_GroupRemove(message.groupId, false);}, 2000);
return;
}
if (message.command == "reload_sidebar") {
if (opt.debug) Utils_log("message to sidebar " + tt.CurrentWindowId + ": message: " + message.command);
window.location.reload();
return;
}
if (message.command == "reload_options") {
if (opt.debug) Utils_log("message to sidebar " + tt.CurrentWindowId + ": message: " + message.command);
opt = Object.assign({}, message.opt);
setTimeout(function() { setTimeout(function() {
Run(); Theme_RestorePinListRowSettings();
}, 100); }, 100);
return;
}
if (message.command == "reload_toolbar") {
if (opt.debug) Utils_log("message to sidebar " + tt.CurrentWindowId + ": message: " + message.command);
opt = Object.assign({}, message.opt);
if (opt.show_toolbar) {
Toolbar_RemoveToolbar();
Toolbar_RecreateToolbar(message.toolbar);
Toolbar_SetToolbarEvents(false, true, true, "mousedown", true);
Toolbar_RestoreToolbarShelf();
Toolbar_RestoreToolbarSearchFilter();
} else {
Toolbar_RemoveToolbar();
}
DOM_RefreshGUI();
return;
}
if (message.command == "reload_theme") {
if (opt.debug) Utils_log("message to sidebar " + tt.CurrentWindowId + ": message: " + message.command);
Theme_RestorePinListRowSettings();
Theme_ApplyTheme(message.theme);
return;
}
if (message.windowId == tt.CurrentWindowId) {
if (message.command == "tab_created") {
if (message.InsertAfterId && document.querySelectorAll("#" + tt.active_group + " .tab").length == 0) {
message.InsertAfterId = undefined;
message.ParentId = tt.active_group;
}
tt.tabs[message.tabId] = new Tabs_ttTab({tab: message.tab, ParentId: message.ParentId, InsertAfterId: message.InsertAfterId, Append: message.Append, Scroll: true});
DOM_RefreshExpandStates();
setTimeout(function() {
DOM_RefreshCounters();
DOM_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++;}, 2000);
return;
}
if (message.command == "tab_attached") {
if (opt.debug) Utils_log("chrome event: " + message.command + ", tabId: " + message.tabId + ", tab is pinned: " + message.tab.pinned + ", ParentId: " + message.ParentId);
tt.tabs[message.tabId] = new Tabs_ttTab({tab: message.tab, ParentId: message.ParentId, Append: true, SkipSetActive: false, SkipMediaIcon: false});
DOM_RefreshGUI();
return;
}
if (message.command == "tab_detached") {
if (opt.debug) Utils_log("chrome event: " + message.command + ", tabId: " + message.tabId);
let Tab = document.getElementById(message.tabId);
if (Tab != null && tt.tabs[message.tabId]) {
let ctDetachedParent = Tab.childNodes[1];
if (opt.promote_children_in_first_child == true && Tab.childNodes[1].childNodes.length > 1) {
DOM_PromoteChildrenToFirstChild(Tab);
} else {
while (ctDetachedParent.firstChild) {
ctDetachedParent.parentNode.parentNode.insertBefore(ctDetachedParent.firstChild, ctDetachedParent.parentNode);
}
}
}
tt.tabs[message.tabId].RemoveTab();
setTimeout(function() {tt.schedule_update_data++;}, 300);
DOM_RefreshGUI();
return;
}
if (message.command == "tab_removed") {
if (opt.debug) {Utils_log("chrome event: " + message.command + ", tabId: " + message.tabId);}
let mTab = document.getElementById(message.tabId);
if (mTab != null && tt.tabs[message.tabId]) {
let ctParent = mTab.childNodes[1];
if (opt.debug) Utils_log("tab_removed, promote children: " + opt.promote_children);
if (opt.promote_children == true) {
if (opt.promote_children_in_first_child == true && mTab.childNodes[1].childNodes.length > 1) {
DOM_PromoteChildrenToFirstChild(mTab);
} else {
while (ctParent.firstChild) {
ctParent.parentNode.parentNode.insertBefore(ctParent.firstChild, ctParent.parentNode);
}
}
} else {
let tab_children = document.querySelectorAll("[id='" + message.tabId + "'] .tab");
for (let s of tab_children) {
chrome.tabs.remove(parseInt(s.id));
}
}
tt.tabs[message.tabId].RemoveTab();
DOM_RefreshExpandStates();
setTimeout(function() {tt.schedule_update_data++;}, 300);
DOM_RefreshGUI();
DOM_RefreshCounters();
}
return;
}
if (message.command == "tab_activated") {
if (opt.debug) Utils_log("chrome event: " + message.command + ", tabId: " + message.tabId);
Tabs_SetActiveTab(message.tabId, true);
return;
}
if (message.command == "tab_attention") {
if (opt.debug) Utils_log("chrome event: " + message.command + ", tabId: " + message.tabId);
if (tt.tabs[message.tabId]) tt.tabs[message.tabId].SetAttentionIcon();
return;
}
if (message.command == "tab_updated") {
if (opt.debug) Utils_log("chrome event: " + message.command + ", tabId: " + message.tabId);
if (tt.tabs[message.tabId]) {
if (message.changeInfo.favIconUrl != undefined || message.changeInfo.url != undefined) {
if (browserId == "F" && (message.changeInfo.favIconUrl == undefined || message.changeInfo.favIconUrl == "")) browser.sessions.setTabValue(message.tabId, "CachedFaviconUrl", "");
setTimeout(function() {
if (tt.tabs[message.tabId]) tt.tabs[message.tabId].GetFaviconAndTitle(true);
}, 100);
}
if (message.changeInfo.title != undefined) {
setTimeout(function() {
if (tt.tabs[message.tabId]) tt.tabs[message.tabId].GetFaviconAndTitle(true);
}, 1000);
}
if (message.changeInfo.audible != undefined || message.changeInfo.mutedInfo != undefined) tt.tabs[message.tabId].RefreshMediaIcon();
if (message.changeInfo.discarded != undefined) tt.tabs[message.tabId].RefreshDiscarded();
if (message.changeInfo.pinned != undefined) {
let updateTab = document.getElementById(message.tabId);
if (updateTab != null) {
if (message.tab.pinned && updateTab.classList.contains("pin") == false) {
tt.tabs[message.tabId].SetTabClass(true);
tt.tabs[message.tabId].pinned = true;
tt.schedule_update_data++;
}
if (!message.tab.pinned && updateTab.classList.contains("tab") == false) {
tt.tabs[message.tabId].SetTabClass(false);
tt.tabs[message.tabId].pinned = false;
tt.schedule_update_data++;
}
}
DOM_RefreshExpandStates();
}
}
return;
}
// if (message.command == "set_active_group") {
// Groups_SetActiveGroup(message.groupId, false, false);
// return;
// }
if (message.command == "remote_update") {
if (opt.debug) {
Utils_log("chrome event: " + message.command + ", tabId: " + message.tabId);
Utils_log(message);
}
Manager_RecreateTreeStructure(message.groups, message.folders, message.tabs);
sendResponse(true);
tt.schedule_update_data++;
return;
}
if (message.command == "switch_active_tab") {
Tabs_SwitchActiveTabBeforeClose(tt.active_group);
return;
}
} }
}); });
} }
function Initialize() { function Initialize() {
chrome.windows.getCurrent({populate: true}, function(window) { chrome.windows.getCurrent({populate: true}, function(window) {
tt.CurrentWindowId = window.id; tt.CurrentWindowId = window.id;
let tabs = window.tabs;
chrome.storage.local.get(null, function(storage) { chrome.storage.local.get(null, function(storage) {
GetCurrentPreferences(storage); Preferences_GetCurrentPreferences(storage);
ApplyTheme(GetCurrentTheme(storage)); Menu_CreateMenu();
Theme_ApplyTheme(Theme_GetCurrentTheme(storage));
if (opt.show_toolbar) { if (opt.show_toolbar) {
RecreateToolbar(GetCurrentToolbar(storage)); Toolbar_RecreateToolbar(Theme_GetCurrentToolbar(storage));
SetToolbarEvents(false, true, true, "mousedown"); Toolbar_SetToolbarEvents(false, true, true, "mousedown", true, false);
RestoreToolbarShelf(); Toolbar_RestoreToolbarShelf();
RestoreToolbarSearchFilter(); Toolbar_RestoreToolbarSearchFilter();
} }
chrome.runtime.sendMessage({command: "get_browser_tabs"}, function(bgtabs) { chrome.runtime.sendMessage({command: "get_browser_tabs"}, function(bgtabs) {
@ -40,62 +290,65 @@ function Initialize() {
chrome.runtime.sendMessage({command: "get_groups", windowId: tt.CurrentWindowId}, function(g) { chrome.runtime.sendMessage({command: "get_groups", windowId: tt.CurrentWindowId}, function(g) {
tt.groups = Object.assign({}, g); tt.groups = Object.assign({}, g);
// APPEND GROUPS // APPEND GROUPS
AppendGroups(tt.groups); Groups_AppendGroups(tt.groups);
// APPEND FOLDERS
AppendFolders(tt.folders);
// APPEND TABS
let ti = 0;
let tc = tabs.length;
let ttTabs = [];
for (ti = 0; ti < tc; ti++) { // APPEND FOLDERS TO TABLIST
ttTabs.push(AppendTab({ tab: tabs[ti], Append: true, SkipSetActive: true, AdditionalClass: (bgtabs[tabs[ti].id].expand != "" ? bgtabs[tabs[ti].id].expand : undefined) })); Folders_PreAppendFolders(tt.folders);
// APPEND TABS TO TABLIST
for (const tab of window.tabs) {
tt.tabs[tab.id] = new Tabs_ttTab({tab: tab, Append: true, SkipSetActive: true, AdditionalClass: ((bgtabs[tab.id] && bgtabs[tab.id].expand != "") ? bgtabs[tab.id].expand : undefined)});
} }
// APPEND FOLDERS TO CORRECT PARENTS
Folders_AppendFolders(tt.folders);
// APPEND TABS TO CORRECT PARENTS
if (opt.skip_load == false) { if (opt.skip_load == false) {
for (ti = 0; ti < tc; ti++) { for (const tab of window.tabs) {
if (bgtabs[tabs[ti].id] && !tabs[ti].pinned) { if (bgtabs[tab.id] && !tab.pinned) {
let TabParent = document.getElementById("ct"+bgtabs[tabs[ti].id].parent); let TabParent = document.getElementById("°"+bgtabs[tab.id].parent);
if (TabParent != null && document.querySelector("[id='"+tabs[ti].id+"'] #ct"+bgtabs[tabs[ti].id].parent) == null) { if (TabParent != null && document.querySelector("[id='"+tab.id+"'] #°"+bgtabs[tab.id].parent) == null) {
TabParent.appendChild(ttTabs[ti]); TabParent.appendChild(tt.tabs[tab.id].Node);
} }
} }
} }
} }
// SET ACTIVE TAB FOR EACH GROUP, REARRENGE EVERYTHING AND START BROWSER LISTENERS // SET ACTIVE TAB FOR EACH GROUP, REARRENGE EVERYTHING AND START BROWSER LISTENERS
SetActiveTabInEachGroup(); Groups_SetActiveTabInEachGroup();
RearrangeFolders(true); Tabs_RearrangeTree(bgtabs, tt.folders, true);
RearrangeTreeTabs(bgtabs, true);
StartSidebarListeners(); StartSidebarListeners();
SetMenu(); DOM_SetEvents();
SetEvents(); Manager_SetManagerEvents();
SetManagerEvents(); Menu_HideMenus();
HideMenus();
if (opt.switch_with_scroll) { if (opt.switch_with_scroll) {
BindTabsSwitchingToMouseWheel("pin_list"); DOM_BindTabsSwitchingToMouseWheel("pin_list");
} }
if (opt.syncro_tabbar_tabs_order || opt.syncro_tabbar_groups_tabs_order) { if (opt.syncro_tabbar_tabs_order || opt.syncro_tabbar_groups_tabs_order) {
RearrangeBrowserTabs(); Tabs_RearrangeBrowserTabs();
} }
RestorePinListRowSettings();
StartAutoSaveSession(); Theme_RestorePinListRowSettings();
if (browserId == "V") { Manager_StartAutoSaveSession();
VivaldiRefreshMediaIcons();
if (browserId == "O") {
DOM_AutoRefreshMediaIcons();
} }
setTimeout(function() { setTimeout(function() {
RefreshExpandStates(); DOM_RefreshExpandStates();
RefreshCounters(); DOM_RefreshCounters();
SetActiveTabInEachGroup(); Groups_SetActiveTabInEachGroup();
if (browserId == "F" && opt.skip_load == false && storage.emergency_reload == undefined) {
RecheckFirefox();
}
}, 1000); }, 1000);
ShowStatusBar({show: true, spinner: false, message: "Ready.", hideTimeout: 2000});
Manager_ShowStatusBar({show: true, spinner: false, message: "Ready.", hideTimeout: 2000});
setTimeout(function() { setTimeout(function() {
UpdateData(); Tabs_SaveTabs();
delete b;
delete DefaultToolbar; delete DefaultToolbar;
delete DefaultTheme; delete DefaultTheme;
delete DefaultPreferences; delete DefaultPreferences;
@ -103,6 +356,7 @@ function Initialize() {
chrome.storage.local.remove("emergency_reload"); chrome.storage.local.remove("emergency_reload");
} }
}, 5000); }, 5000);
if (browserId != "F") { if (browserId != "F") {
if (storage.windows_BAK1 && Object.keys(storage["windows_BAK1"]).length > 0 && document.getElementById("button_load_bak1") != null) { document.getElementById("button_load_bak1").classList.remove("disabled"); } if (storage.windows_BAK1 && Object.keys(storage["windows_BAK1"]).length > 0 && document.getElementById("button_load_bak1") != null) { document.getElementById("button_load_bak1").classList.remove("disabled"); }
if (storage.windows_BAK2 && Object.keys(storage["windows_BAK2"]).length > 0 && document.getElementById("button_load_bak2") != null) { document.getElementById("button_load_bak2").classList.remove("disabled"); } if (storage.windows_BAK2 && Object.keys(storage["windows_BAK2"]).length > 0 && document.getElementById("button_load_bak2") != null) { document.getElementById("button_load_bak2").classList.remove("disabled"); }
@ -114,3 +368,18 @@ function Initialize() {
}); });
}); });
} }
function Run() {
Manager_ShowStatusBar({show: true, spinner: true, message: "Starting up"});
chrome.runtime.sendMessage({command: "is_bg_ready"}, function(response) {
if (response == true) {
Initialize();
} else {
setTimeout(function() {
Run();
},100);
}
});
}
document.addEventListener("DOMContentLoaded", Run(), false);

View File

@ -499,11 +499,7 @@ div {
overflow-y: auto; overflow-y: auto;
} }
.group>.children_folders { .group>.children {
position: relative;
top: var(--group_folders_top);
}
.group>.children_tabs {
position: relative; position: relative;
top: var(--group_tabs_top); top: var(--group_tabs_top);
} }
@ -582,295 +578,8 @@ div {
} }
/* PINS AND TABS COLORS, WATCH OUT AND DON'T MESS WITH IT */
/* normal */
.tab_header{
border-radius:var(--tab_header_border_radius);
border:1px solid var(--tab_border);
background-color:var(--tab_background);
}
.tab>.tab_header>.tab_title{
color:var(--tab_title_font_color);
font-style:var(--tab_title_font_style);
font-weight:var(--tab_title_font_weight);
}
/* normal hover */
.tab_header_hover{
border-radius:var(--tab_header_border_radius);
border:1px solid var(--tab_hover_border);
background-color:var(--tab_hover_background);
}
.tab>.tab_header_hover>.tab_title{
color:var(--tab_hover_title_font_color);
font-style:var(--tab_hover_title_font_style);
font-weight:var(--tab_hover_title_font_weight);
}
/* normal selected */
.selected_tab>.tab_header{
border:1px solid var(--tab_selected_border);
background-color:var(--tab_selected_background);
}
.tab.selected_tab>.tab_header>.tab_title{
color:var(--tab_selected_title_font_color);
font-style:var(--tab_selected_title_font_style);
font-weight:var(--tab_selected_title_font_weight);
}
/* normal selected hover */
.selected_tab>.tab_header_hover{
border:1px solid var(--tab_selected_hover_border);
background-color:var(--tab_selected_hover_background);
}
.tab.selected_tab>.tab_header_hover>.tab_title{
color:var(--tab_selected_hover_title_font_color);
font-style:var(--tab_selected_hover_title_font_style);
font-weight:var(--tab_selected_hover_title_font_weight);
}
/* normal active */
.active_tab>.tab_header{
border:1px solid var(--tab_active_border);
background-color:var(--tab_active_background);
}
.tab.active_tab>.tab_header>.tab_title{
color:var(--tab_active_title_font_color);
font-style:var(--tab_active_title_font_style);
font-weight:var(--tab_active_title_font_weight);
}
/* normal active hover */
.active_tab>.tab_header_hover{
border:1px solid var(--tab_active_hover_border);
background-color:var(--tab_active_hover_background);
}
.tab.active_tab>.tab_header_hover>.tab_title{
color:var(--tab_active_hover_title_font_color);
font-style:var(--tab_active_hover_title_font_style);
font-weight:var(--tab_active_hover_title_font_weight);
}
/* normal selected active */
.selected_tab.active_tab>.tab_header{
border:1px solid var(--tab_active_selected_border);
background-color:var(--tab_active_selected_background);
}
.tab.selected_tab.active_tab>.tab_header>.tab_title{
color:var(--tab_active_selected_title_font_color);
font-style:var(--tab_active_selected_title_font_style);
font-weight:var(--tab_active_selected_title_font_weight);
}
/* normal selected active hover */
.selected_tab.active_tab>.tab_header_hover{
border:1px solid var(--tab_selected_active_hover_border);
background-color:var(--tab_selected_active_hover_background);
}
.tab.selected_tab.active_tab>.tab_header_hover>.tab_title{
color:var(--tab_selected_active_hover_title_font_color);
font-style:var(--tab_selected_active_hover_title_font_style);
font-weight:var(--tab_selected_active_hover_title_font_weight);
}
/* unloaded */
.discarded>.tab_header{
border:1px solid var(--tab_discarded_border);
background-color:var(--tab_discarded_background);
}
.tab.discarded>.tab_header>.tab_title{
color:var(--tab_discarded_title_font_color);
font-style:var(--tab_discarded_title_font_style);
font-weight:var(--tab_discarded_title_font_weight);
}
/* unloaded hover */
.discarded>.tab_header_hover{
border:1px solid var(--tab_discarded_hover_border);
background-color:var(--tab_discarded_hover_background);
}
.tab.discarded>.tab_header_hover>.tab_title{
color:var(--tab_discarded_hover_title_font_color);
font-style:var(--tab_discarded_hover_title_font_style);
font-weight:var(--tab_discarded_hover_title_font_weight);
}
/* unloaded selected */
.selected_tab.discarded>.tab_header{
border:1px solid var(--tab_selected_discarded_border);
background-color:var(--tab_selected_discarded_background);
}
.tab.selected_tab.discarded>.tab_header>.tab_title{
color:var(--tab_selected_discarded_title_font_color);
font-style:var(--tab_selected_discarded_title_font_style);
font-weight:var(--tab_selected_discarded_title_font_weight);
}
/* unloaded selected hover */
.selected_tab.discarded>.tab_header_hover{
border:1px solid var(--tab_selected_discarded_hover_border);
background-color:var(--tab_selected_discarded_hover_background);
}
.tab.selected_tab.discarded>.tab_header_hover>.tab_title{
color:var(--tab_selected_discarded_hover_title_font_color);
font-style:var(--tab_selected_discarded_hover_title_font_style);
font-weight:var(--tab_selected_discarded_hover_title_font_weight);
}
/* search result */
.filtered>.tab_header{
border:1px solid var(--tab_filtered_border);
background-color:var(--tab_filtered_background);
}
.tab.filtered>.tab_header>.tab_title{
color:var(--tab_filtered_title_font_color);
font-style:var(--tab_filtered_title_font_style);
font-weight:var(--tab_filtered_title_font_weight);
}
/* search result hover */
.filtered>.tab_header_hover{
border:1px solid var(--tab_filtered_hover_border);
background-color:var(--tab_filtered_hover_background);
}
.tab.filtered>.tab_header_hover>.tab_title{
color:var(--tab_filtered_hover_title_font_color);
font-style:var(--tab_filtered_hover_title_font_style);
font-weight:var(--tab_filtered_hover_title_font_weight);
}
/* search result active */
.filtered.active_tab>.tab_header{
border:1px solid var(--tab_filtered_active_border);
background-color:var(--tab_filtered_active_background);
}
.tab.filtered.active_tab>.tab_header>.tab_title{
color:var(--tab_filtered_active_title_font_color);
font-style:var(--tab_filtered_active_title_font_style);
font-weight:var(--tab_filtered_active_title_font_weight);
}
/* search result active hover */
.filtered.active_tab>.tab_header_hover{
border:1px solid var(--tab_filtered_active_hover_border);
background-color:var(--tab_filtered_active_hover_background);
}
.tab.filtered.active_tab>.tab_header_hover>.tab_title{
color:var(--tab_filtered_active_hover_title_font_color);
font-style:var(--tab_filtered_active_hover_title_font_style);
font-weight:var(--tab_filtered_active_hover_title_font_weight);
}
/* search result selected */
.selected_tab.filtered>.tab_header{
border:1px solid var(--tab_filtered_selected_border);
background-color:var(--tab_filtered_selected_background);
}
.tab.selected_tab.filtered>.tab_header>.tab_title{
color:var(--tab_filtered_selected_title_font_color);
font-style:var(--tab_filtered_selected_title_font_style);
font-weight:var(--tab_filtered_selected_title_font_weight);
}
/* search result selected hover */
.selected_tab.filtered>.tab_header_hover{
border:1px solid var(--tab_filtered_selected_hover_border);
background-color:var(--tab_filtered_selected_hover_background);
}
.tab.selected_tab.filtered>.tab_header_hover>.tab_title{
color:var(--tab_filtered_selected_hover_title_font_color);
font-style:var(--tab_filtered_selected_hover_title_font_style);
font-weight:var(--tab_filtered_selected_hover_title_font_weight);
}
/* search result active selected */
.selected_tab.filtered.active_tab>.tab_header{
border:1px solid var(--tab_filtered_selected_active_border);
background-color:var(--tab_filtered_selected_active_background);
}
.tab.selected_tab.filtered.active_tab>.tab_header>.tab_title{
color:var(--tab_filtered_selected_active_title_font_color);
font-style:var(--tab_filtered_selected_active_title_font_style);
font-weight:var(--tab_filtered_selected_active_title_font_weight);
}
/* search result active selected hover */
.selected_tab.filtered.active_tab>.tab_header_hover{
border:1px solid var(--tab_filtered_selected_active_hover_border);
background-color:var(--tab_filtered_selected_active_hover_background);
}
.tab.filtered.selected_tab.active_tab>.tab_header_hover>.tab_title{
color:var(--tab_filtered_selected_active_hover_title_font_color);
font-style:var(--tab_filtered_selected_active_hover_title_font_style);
font-weight:var(--tab_filtered_selected_active_hover_title_font_weight);
}
/* search result highlighted */
.filtered.highlighted_search>.tab_header{
border:1px solid var(--tab_filtered_highlighted_search_border);
background-color:var(--tab_filtered_highlighted_search_background);
}
.tab.filtered.highlighted_search>.tab_header>.tab_title{
color:var(--tab_filtered_highlighted_search_title_font_color);
font-style:var(--tab_filtered_highlighted_search_title_font_style);
font-weight:var(--tab_filtered_highlighted_search_title_font_weight);
}
/* search result highlighted hover */
.filtered.highlighted_search>.tab_header_hover{
border:1px solid var(--tab_filtered_highlighted_search_hover_border);
background-color:var(--tab_filtered_highlighted_search_hover_background);
}
.tab.filtered.highlighted_search>.tab_header_hover>.tab_title{
color:var(--tab_filtered_highlighted_search_hover_title_font_color);
font-style:var(--tab_filtered_highlighted_search_hover_title_font_style);
font-weight:var(--tab_filtered_highlighted_search_hover_title_font_weight);
}
/* search result active highlighted */
.active_tab.filtered.highlighted_search>.tab_header{
border:1px solid var(--tab_filtered_active_highlighted_search_border);
background-color:var(--tab_filtered_active_highlighted_search_background);
}
.tab.active_tab.filtered.highlighted_search>.tab_header>.tab_title{
color:var(--tab_filtered_active_highlighted_search_title_font_color);
font-style:var(--tab_filtered_active_highlighted_search_title_font_style);
font-weight:var(--tab_filtered_active_highlighted_search_title_font_weight);
}
/* search result active highlighted hover */
.active_tab.filtered.highlighted_search>.tab_header_hover{
border:1px solid var(--tab_filtered_active_highlighted_search_hover_border);
background-color:var(--tab_filtered_active_highlighted_search_hover_background);
}
.tab.active_tab.filtered.highlighted_search>.tab_header_hover>.tab_title{
color:var(--tab_filtered_active_highlighted_search_hover_title_font_color);
font-style:var(--tab_filtered_active_highlighted_search_hover_title_font_style);
font-weight:var(--tab_filtered_active_highlighted_search_hover_title_font_weight);
}
/* search result selected highlighted */
.selected_tab.filtered.highlighted_search>.tab_header{
border:1px solid var(--tab_filtered_selected_highlighted_search_border);
background-color:var(--tab_filtered_selected_highlighted_search_background);
}
.tab.selected_tab.filtered.highlighted_search>.tab_header>.tab_title{
color:var(--tab_filtered_selected_highlighted_search_title_font_color);
font-style:var(--tab_filtered_selected_highlighted_search_title_font_style);
font-weight:var(--tab_filtered_selected_highlighted_search_title_font_weight);
}
/* search result selected highlighted hover */
.selected_tab.filtered.highlighted_search>.tab_header_hover{
border:1px solid var(--tab_filtered_selected_highlighted_search_hover_border);
background-color:var(--tab_filtered_selected_highlighted_search_hover_background);
}
.tab.selected_tab.filtered.highlighted_search>.tab_header_hover>.tab_title{
color:var(--tab_filtered_selected_highlighted_search_hover_title_font_color);
font-style:var(--tab_filtered_selected_highlighted_search_hover_title_font_style);
font-weight:var(--tab_filtered_selected_highlighted_search_hover_title_font_weight);
}
/* search result selected active highlighted */
.active_tab.selected_tab.filtered.highlighted_search>.tab_header{
border:1px solid var(--tab_filtered_selected_active_highlighted_search_border);
background-color:var(--tab_filtered_selected_active_highlighted_search_background);
}
.tab.active_tab.selected_tab.filtered.highlighted_search>.tab_header>.tab_title{
color:var(--tab_filtered_selected_active_highlighted_search_title_font_color);
font-style:var(--tab_filtered_selected_active_highlighted_search_title_font_style);
font-weight:var(--tab_filtered_selected_active_highlighted_search_title_font_weight);
}
/* search result selected active highlighted hover */
.active_tab.selected_tab.filtered.highlighted_search>.tab_header_hover{
border:1px solid var(--tab_filtered_selected_active_highlighted_search_hover_border);
background-color:var(--tab_filtered_selected_active_highlighted_search_hover_background);
}
.tab.active_tab.selected_tab.filtered.highlighted_search>.tab_header_hover>.tab_title{
color:var(--tab_filtered_selected_active_highlighted_search_hover_title_font_color);
font-style:var(--tab_filtered_selected_active_highlighted_search_hover_title_font_style);
font-weight:var(--tab_filtered_selected_active_highlighted_search_hover_title_font_weight);
}
/* TABS */ /* TABS */
/* regular tab title */ /* regular tab title */
.tab_title { .tab_title {
z-index: 5; z-index: 5;
@ -883,6 +592,7 @@ div {
padding-left: var(--tab_title_text_padding_left); padding-left: var(--tab_title_text_padding_left);
font-size: var(--title_font_size); font-size: var(--title_font_size);
pointer-events: none; pointer-events: none;
line-height: var(--tab_height);
} }
.tab { .tab {
@ -904,7 +614,7 @@ div {
top: 0px; top: 0px;
left: 0px; left: 0px;
height: var(--tab_height); height: var(--tab_height);
line-height: var(--tab_height_line); /* line-height: var(--tab_height_line); */
width: calc(100% - 2px); width: calc(100% - 2px);
background-image: url(../theme/icon_empty.svg); background-image: url(../theme/icon_empty.svg);
background-size: var(--favicon_width) var(--favicon_height); background-size: var(--favicon_width) var(--favicon_height);
@ -912,7 +622,7 @@ div {
/* background-image: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.6) 100%), url(../theme/icon_empty.svg); */ /* background-image: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.6) 100%), url(../theme/icon_empty.svg); */
} }
.group>.children_tabs>:last-child { .group>.children>:last-child {
margin-bottom: 16px; margin-bottom: 16px;
} }
@ -934,19 +644,19 @@ div {
} }
/* CHILDREN TABS */ /* CHILDREN TABS */
.tab>.children_tabs { .tab>.children {
position: relative; position: relative;
padding-left: var(--children_padding_left); padding-left: var(--children_padding_left);
} }
.tab>.children_tabs>.tab { .tab>.children>.tab {
margin-right: 0px; margin-right: 0px;
} }
.tab.o>.children_tabs { .tab.o>.children {
height: auto; height: auto;
} }
.tab.c>.children_tabs { .tab.c>.children {
display: none; display: none;
height: 0px; height: 0px;
} }
@ -980,7 +690,6 @@ div {
} }
/* FOLDERS */ /* FOLDERS */
.folder_title { .folder_title {
z-index: 5; z-index: 5;
font-family: Arial, Helvetica, "Nimbus Sans L", "Liberation Sans", FreeSans, Sans-serif; font-family: Arial, Helvetica, "Nimbus Sans L", "Liberation Sans", FreeSans, Sans-serif;
@ -991,10 +700,12 @@ div {
padding-right: 3px; padding-right: 3px;
padding-left: var(--tab_title_text_padding_left); padding-left: var(--tab_title_text_padding_left);
font-size: var(--title_font_size); font-size: var(--title_font_size);
pointer-events: none;
line-height: var(--tab_height);
/* colors and styles */
color:var(--tab_title_font_color); color:var(--tab_title_font_color);
font-style:var(--tab_title_font_style); font-style:var(--tab_title_font_style);
font-weight:var(--tab_title_font_weight); font-weight:var(--tab_title_font_weight);
pointer-events: none;
} }
.folder { .folder {
@ -1014,32 +725,29 @@ div {
top: 0px; top: 0px;
left: 0px; left: 0px;
height: var(--tab_height); height: var(--tab_height);
line-height: var(--tab_height_line); /* line-height: var(--tab_height_line); */
width: calc(100% - 2px); width: calc(100% - 2px);
border-radius: var(--tab_header_border_radius); border-radius: var(--tab_header_border_radius);
border: 1px solid var(--tab_border); border: 1px solid var(--tab_border);
background-color: var(--tab_background); background-color: var(--tab_background);
} }
.folder>.children_folders, .folder>.children {
.folder>.children_tabs {
position: relative; position: relative;
padding-left: var(--children_padding_left); padding-left: var(--children_padding_left);
} }
.folder>.children_folders>.folder, .folder>.children>.folder,
.folder>.children_tabs>.tab { .folder>.children>.tab {
margin-right: 0px; margin-right: 0px;
} }
.folder.o>.children_folders, .folder.o>.children {
.folder.o>.children_tabs {
height: auto; height: auto;
} }
.folder.c>.children_folders, .folder.c>.children {
.folder.c>.children_tabs {
display: none; display: none;
height: 0px; height: 0px;
} }
@ -1079,36 +787,7 @@ div {
mask-image: url(../theme/icon_folder_open.svg); mask-image: url(../theme/icon_folder_open.svg);
} }
/* normal hover */ .selected>.folder_header
.folder>.folder_header_hover{
border-radius:var(--tab_header_border_radius);
border:1px solid var(--tab_hover_border);
background-color:var(--tab_hover_background);
}
/* normal selected */
.selected_folder>.folder_header{
border:1px solid var(--tab_selected_border);
background-color:var(--tab_selected_background);
}
.selected_folder>.folder_header>.folder_title{
color:var(--tab_selected_title_font_color);
font-style:var(--tab_selected_title_font_style);
font-weight:var(--tab_selected_title_font_weight);
}
/* normal selected hover */
.selected_folder>.folder_header_hover{
border:1px solid var(--tab_selected_hover_border);
background-color:var(--tab_selected_hover_background);
}
.selected_folder>.folder_header_hover>.folder_title{
color:var(--tab_selected_hover_title_font_color);
font-style:var(--tab_selected_hover_title_font_style);
font-weight:var(--tab_selected_hover_title_font_weight);
}
.selected_folder>.folder_header
.active_folder>.folder_header { .active_folder>.folder_header {
z-index: 900; z-index: 900;
} }
@ -1119,15 +798,6 @@ div {
/* PINS */ /* PINS */
@keyframes blinking {
0% {background-color: var(--tab_background); border:1px solid var(--tab_border);}
50% {background-color: var(--attention_background); border:1px solid var(--attention_border);}
80% {background-color: var(--tab_background); border:1px solid var(--tab_border);}
100% {background-color: var(--tab_background); border:1px solid var(--tab_border);}
}
.pin.attention>.tab_header {
animation: blinking 2.5s infinite;
}
.pin { .pin {
/* pin size is here, all the rest is automatically calculated */ /* pin size is here, all the rest is automatically calculated */
position: relative; position: relative;
@ -1163,7 +833,7 @@ div {
background-position: center, center; background-position: center, center;
} }
.pin>.children_tabs { .pin>.children {
display: none; display: none;
position: absolute; position: absolute;
top: 0px; top: 0px;
@ -1171,7 +841,7 @@ div {
width: 0px; width: 0px;
} }
.pin.selected_tab, .pin.selected,
.pin.active_tab { .pin.active_tab {
z-index: 800; z-index: 800;
} }
@ -1179,8 +849,10 @@ div {
margin-right: var(--pin_last_margin_right); margin-right: var(--pin_last_margin_right);
} }
.pin.attention>.tab_header {
background-color: var(--attention_background);
border: 1px solid var(--attention_border);
}
/* DRAG AND DROP TARGETS */ /* DRAG AND DROP TARGETS */
@ -1244,7 +916,8 @@ div {
} }
.group.highlighted_drop_target>.children_tabs>.tab:last-child>.drag_indicator, .group.highlighted_drop_target>.children>.tab:last-child>.drag_indicator,
.group.highlighted_drop_target>.children>.folder:last-child>.drag_indicator,
.folder.highlighted_drop_target.after>.drag_indicator, .folder.highlighted_drop_target.after>.drag_indicator,
.tab.highlighted_drop_target.after>.drag_indicator { .tab.highlighted_drop_target.after>.drag_indicator {
display: block; display: block;
@ -1257,8 +930,342 @@ div {
} }
.group>.children_tabs>.tab:first-child>.drag_indicator,
.group>.children_folders>.folder:first-child>.drag_indicator {
/* PINS FOLDERS AND TABS COLORS, WATCH OUT AND DON'T MESS WITH IT */
/* normal */
.folder_header.folder_header_hover,
.tab_header.tab_header_hover {
z-index: 9999;
}
.tab_header {
border-radius:var(--tab_header_border_radius);
border:1px solid var(--tab_border);
background-color:var(--tab_background);
}
.tab>.tab_header>.tab_title {
color:var(--tab_title_font_color);
font-style:var(--tab_title_font_style);
font-weight:var(--tab_title_font_weight);
}
/* normal hover */
.folder_header.folder_header_hover,
.tab_header.tab_header_hover {
border-radius:var(--tab_header_border_radius);
border:1px solid var(--tab_hover_border);
background-color:var(--tab_hover_background);
}
.folder>.folder_header_hover>.folder_title,
.tab>.tab_header_hover>.tab_title {
color:var(--tab_hover_title_font_color);
font-style:var(--tab_hover_title_font_style);
font-weight:var(--tab_hover_title_font_weight);
}
/* normal selected */
.folder.selected>.folder_header,
.pin.selected>.tab_header,
.tab.selected>.tab_header {
border:1px solid var(--tab_selected_border);
background-color:var(--tab_selected_background);
}
/* selected header title */
.folder.selected>.folder_header>.folder_title,
.tab.selected>.tab_header>.tab_title {
color:var(--tab_selected_title_font_color);
font-style:var(--tab_selected_title_font_style);
font-weight:var(--tab_selected_title_font_weight);
}
/* normal selected hover */
.folder.selected>.folder_header_hover,
.pin.selected>.tab_header_hover,
.tab.selected>.tab_header_hover {
border:1px solid var(--tab_selected_hover_border);
background-color:var(--tab_selected_hover_background);
}
.folder.selected>.folder_header_hover>.folder_title,
.tab.selected>.tab_header_hover>.tab_title {
color:var(--tab_selected_hover_title_font_color);
font-style:var(--tab_selected_hover_title_font_style);
font-weight:var(--tab_selected_hover_title_font_weight);
}
/* normal active */
.pin.active_tab>.tab_header,
.tab.active_tab>.tab_header {
border:1px solid var(--tab_active_border);
background-color:var(--tab_active_background);
}
.tab.active_tab>.tab_header>.tab_title {
color:var(--tab_active_title_font_color);
font-style:var(--tab_active_title_font_style);
font-weight:var(--tab_active_title_font_weight);
}
/* normal active hover */
.pin.active_tab>.tab_header_hover,
.tab.active_tab>.tab_header_hover {
border:1px solid var(--tab_active_hover_border);
background-color:var(--tab_active_hover_background);
}
.tab.active_tab>.tab_header_hover>.tab_title {
color:var(--tab_active_hover_title_font_color);
font-style:var(--tab_active_hover_title_font_style);
font-weight:var(--tab_active_hover_title_font_weight);
}
/* normal selected active */
.pin.selected.active_tab>.tab_header,
.tab.selected.active_tab>.tab_header {
border:1px solid var(--tab_active_selected_border);
background-color:var(--tab_active_selected_background);
}
.tab.selected.active_tab>.tab_header>.tab_title {
color:var(--tab_active_selected_title_font_color);
font-style:var(--tab_active_selected_title_font_style);
font-weight:var(--tab_active_selected_title_font_weight);
}
/* normal selected active hover */
.pin.selected.active_tab>.tab_header_hover,
.tab.selected.active_tab>.tab_header_hover {
border:1px solid var(--tab_selected_active_hover_border);
background-color:var(--tab_selected_active_hover_background);
}
.tab.selected.active_tab>.tab_header_hover>.tab_title {
color:var(--tab_selected_active_hover_title_font_color);
font-style:var(--tab_selected_active_hover_title_font_style);
font-weight:var(--tab_selected_active_hover_title_font_weight);
}
/* unloaded */
.pin.discarded>.tab_header,
.tab.discarded>.tab_header {
border:1px solid var(--tab_discarded_border);
background-color:var(--tab_discarded_background);
}
.tab.discarded>.tab_header>.tab_title {
color:var(--tab_discarded_title_font_color);
font-style:var(--tab_discarded_title_font_style);
font-weight:var(--tab_discarded_title_font_weight);
}
/* unloaded hover */
.pin.discarded>.tab_header_hover,
.tab.discarded>.tab_header_hover {
border:1px solid var(--tab_discarded_hover_border);
background-color:var(--tab_discarded_hover_background);
}
.tab.discarded>.tab_header_hover>.tab_title {
color:var(--tab_discarded_hover_title_font_color);
font-style:var(--tab_discarded_hover_title_font_style);
font-weight:var(--tab_discarded_hover_title_font_weight);
}
/* unloaded selected */
.pin.selected.discarded>.tab_header,
.tab.selected.discarded>.tab_header {
border:1px solid var(--tab_selected_discarded_border);
background-color:var(--tab_selected_discarded_background);
}
.tab.selected.discarded>.tab_header>.tab_title {
color:var(--tab_selected_discarded_title_font_color);
font-style:var(--tab_selected_discarded_title_font_style);
font-weight:var(--tab_selected_discarded_title_font_weight);
}
/* unloaded selected hover */
.pin.selected.discarded>.tab_header_hover,
.tab.selected.discarded>.tab_header_hover {
border:1px solid var(--tab_selected_discarded_hover_border);
background-color:var(--tab_selected_discarded_hover_background);
}
.tab.selected.discarded>.tab_header_hover>.tab_title {
color:var(--tab_selected_discarded_hover_title_font_color);
font-style:var(--tab_selected_discarded_hover_title_font_style);
font-weight:var(--tab_selected_discarded_hover_title_font_weight);
}
/* search result */
.pin.filtered>.tab_header,
.tab.filtered>.tab_header {
border:1px solid var(--tab_filtered_border);
background-color:var(--tab_filtered_background);
}
.tab.filtered>.tab_header>.tab_title {
color:var(--tab_filtered_title_font_color);
font-style:var(--tab_filtered_title_font_style);
font-weight:var(--tab_filtered_title_font_weight);
}
/* search result hover */
.pin.filtered>.tab_header_hover,
.tab.filtered>.tab_header_hover {
border:1px solid var(--tab_filtered_hover_border);
background-color:var(--tab_filtered_hover_background);
}
.tab.filtered>.tab_header_hover>.tab_title {
color:var(--tab_filtered_hover_title_font_color);
font-style:var(--tab_filtered_hover_title_font_style);
font-weight:var(--tab_filtered_hover_title_font_weight);
}
/* search result active */
.pin.filtered.active_tab>.tab_header,
.tab.filtered.active_tab>.tab_header {
border:1px solid var(--tab_filtered_active_border);
background-color:var(--tab_filtered_active_background);
}
.tab.filtered.active_tab>.tab_header>.tab_title {
color:var(--tab_filtered_active_title_font_color);
font-style:var(--tab_filtered_active_title_font_style);
font-weight:var(--tab_filtered_active_title_font_weight);
}
/* search result active hover */
.pin.filtered.active_tab>.tab_header_hover,
.tab.filtered.active_tab>.tab_header_hover {
border:1px solid var(--tab_filtered_active_hover_border);
background-color:var(--tab_filtered_active_hover_background);
}
.tab.filtered.active_tab>.tab_header_hover>.tab_title {
color:var(--tab_filtered_active_hover_title_font_color);
font-style:var(--tab_filtered_active_hover_title_font_style);
font-weight:var(--tab_filtered_active_hover_title_font_weight);
}
/* search result selected */
.pin.selected.filtered>.tab_header,
.tab.selected.filtered>.tab_header {
border:1px solid var(--tab_filtered_selected_border);
background-color:var(--tab_filtered_selected_background);
}
.tab.selected.filtered>.tab_header>.tab_title {
color:var(--tab_filtered_selected_title_font_color);
font-style:var(--tab_filtered_selected_title_font_style);
font-weight:var(--tab_filtered_selected_title_font_weight);
}
/* search result selected hover */
.pin.selected.filtered>.tab_header_hover,
.tab.selected.filtered>.tab_header_hover {
border:1px solid var(--tab_filtered_selected_hover_border);
background-color:var(--tab_filtered_selected_hover_background);
}
.tab.selected.filtered>.tab_header_hover>.tab_title {
color:var(--tab_filtered_selected_hover_title_font_color);
font-style:var(--tab_filtered_selected_hover_title_font_style);
font-weight:var(--tab_filtered_selected_hover_title_font_weight);
}
/* search result active selected */
.pin.selected.filtered.active_tab>.tab_header,
.tab.selected.filtered.active_tab>.tab_header {
border:1px solid var(--tab_filtered_selected_active_border);
background-color:var(--tab_filtered_selected_active_background);
}
.tab.selected.filtered.active_tab>.tab_header>.tab_title {
color:var(--tab_filtered_selected_active_title_font_color);
font-style:var(--tab_filtered_selected_active_title_font_style);
font-weight:var(--tab_filtered_selected_active_title_font_weight);
}
/* search result active selected hover */
.pin.selected.filtered.active_tab>.tab_header_hover,
.tab.selected.filtered.active_tab>.tab_header_hover {
border:1px solid var(--tab_filtered_selected_active_hover_border);
background-color:var(--tab_filtered_selected_active_hover_background);
}
.tab.filtered.selected.active_tab>.tab_header_hover>.tab_title {
color:var(--tab_filtered_selected_active_hover_title_font_color);
font-style:var(--tab_filtered_selected_active_hover_title_font_style);
font-weight:var(--tab_filtered_selected_active_hover_title_font_weight);
}
/* search result highlighted */
.pin.filtered.highlighted_search>.tab_header,
.tab.filtered.highlighted_search>.tab_header {
border:1px solid var(--tab_filtered_highlighted_search_border);
background-color:var(--tab_filtered_highlighted_search_background);
}
.tab.filtered.highlighted_search>.tab_header>.tab_title {
color:var(--tab_filtered_highlighted_search_title_font_color);
font-style:var(--tab_filtered_highlighted_search_title_font_style);
font-weight:var(--tab_filtered_highlighted_search_title_font_weight);
}
/* search result highlighted hover */
.pin.filtered.highlighted_search>.tab_header_hover,
.tab.filtered.highlighted_search>.tab_header_hover {
border:1px solid var(--tab_filtered_highlighted_search_hover_border);
background-color:var(--tab_filtered_highlighted_search_hover_background);
}
.tab.filtered.highlighted_search>.tab_header_hover>.tab_title {
color:var(--tab_filtered_highlighted_search_hover_title_font_color);
font-style:var(--tab_filtered_highlighted_search_hover_title_font_style);
font-weight:var(--tab_filtered_highlighted_search_hover_title_font_weight);
}
/* search result active highlighted */
.pin.active_tab.filtered.highlighted_search>.tab_header,
.tab.active_tab.filtered.highlighted_search>.tab_header {
border:1px solid var(--tab_filtered_active_highlighted_search_border);
background-color:var(--tab_filtered_active_highlighted_search_background);
}
.tab.active_tab.filtered.highlighted_search>.tab_header>.tab_title {
color:var(--tab_filtered_active_highlighted_search_title_font_color);
font-style:var(--tab_filtered_active_highlighted_search_title_font_style);
font-weight:var(--tab_filtered_active_highlighted_search_title_font_weight);
}
/* search result active highlighted hover */
.pin.active_tab.filtered.highlighted_search>.tab_header_hover,
.tab.active_tab.filtered.highlighted_search>.tab_header_hover {
border:1px solid var(--tab_filtered_active_highlighted_search_hover_border);
background-color:var(--tab_filtered_active_highlighted_search_hover_background);
}
.tab.active_tab.filtered.highlighted_search>.tab_header_hover>.tab_title {
color:var(--tab_filtered_active_highlighted_search_hover_title_font_color);
font-style:var(--tab_filtered_active_highlighted_search_hover_title_font_style);
font-weight:var(--tab_filtered_active_highlighted_search_hover_title_font_weight);
}
/* search result selected highlighted */
.pin.selected.filtered.highlighted_search>.tab_header,
.tab.selected.filtered.highlighted_search>.tab_header {
border:1px solid var(--tab_filtered_selected_highlighted_search_border);
background-color:var(--tab_filtered_selected_highlighted_search_background);
}
.tab.selected.filtered.highlighted_search>.tab_header>.tab_title {
color:var(--tab_filtered_selected_highlighted_search_title_font_color);
font-style:var(--tab_filtered_selected_highlighted_search_title_font_style);
font-weight:var(--tab_filtered_selected_highlighted_search_title_font_weight);
}
/* search result selected highlighted hover */
.pin.selected.filtered.highlighted_search>.tab_header_hover,
.tab.selected.filtered.highlighted_search>.tab_header_hover {
border:1px solid var(--tab_filtered_selected_highlighted_search_hover_border);
background-color:var(--tab_filtered_selected_highlighted_search_hover_background);
}
.tab.selected.filtered.highlighted_search>.tab_header_hover>.tab_title {
color:var(--tab_filtered_selected_highlighted_search_hover_title_font_color);
font-style:var(--tab_filtered_selected_highlighted_search_hover_title_font_style);
font-weight:var(--tab_filtered_selected_highlighted_search_hover_title_font_weight);
}
/* search result selected active highlighted */
.pin.active_tab.selected.filtered.highlighted_search>.tab_header,
.tab.active_tab.selected.filtered.highlighted_search>.tab_header {
border:1px solid var(--tab_filtered_selected_active_highlighted_search_border);
background-color:var(--tab_filtered_selected_active_highlighted_search_background);
}
.tab.active_tab.selected.filtered.highlighted_search>.tab_header>.tab_title {
color:var(--tab_filtered_selected_active_highlighted_search_title_font_color);
font-style:var(--tab_filtered_selected_active_highlighted_search_title_font_style);
font-weight:var(--tab_filtered_selected_active_highlighted_search_title_font_weight);
}
/* search result selected active highlighted hover */
.pin.active_tab.selected.filtered.highlighted_search>.tab_header_hover,
.tab.active_tab.selected.filtered.highlighted_search>.tab_header_hover {
border:1px solid var(--tab_filtered_selected_active_highlighted_search_hover_border);
background-color:var(--tab_filtered_selected_active_highlighted_search_hover_background);
}
.tab.active_tab.selected.filtered.highlighted_search>.tab_header_hover>.tab_title {
color:var(--tab_filtered_selected_active_highlighted_search_hover_title_font_color);
font-style:var(--tab_filtered_selected_active_highlighted_search_hover_title_font_style);
font-weight:var(--tab_filtered_selected_active_highlighted_search_hover_title_font_weight);
}
.group>.children>.tab:first-child>.drag_indicator,
.group>.children>.folder:first-child>.drag_indicator {
top: 1px; top: 1px;
} }
@ -1297,12 +1304,6 @@ div {
/* MEDIA */ /* MEDIA */
@keyframes blinking2 {
0% {opacity: 0}
30% {opacity: 1}
70% {opacity: 1}
100% {opacity: 0}
}
.tab_mediaicon { .tab_mediaicon {
animation: none; animation: none;
position: absolute; position: absolute;
@ -1317,7 +1318,6 @@ div {
} }
.audible>.tab_header>.tab_mediaicon { .audible>.tab_header>.tab_mediaicon {
animation: blinking2 1.5s infinite;
display: inline-block; display: inline-block;
height: var(--tab_mediaicon_height); height: var(--tab_mediaicon_height);
width: var(--tab_mediaicon_width); width: var(--tab_mediaicon_width);
@ -1330,7 +1330,6 @@ div {
} }
.muted>.tab_header>.tab_mediaicon { .muted>.tab_header>.tab_mediaicon {
animation: blinking2 1.5s infinite;
display: inline-block; display: inline-block;
height: var(--tab_mediaicon_height); height: var(--tab_mediaicon_height);
width: var(--tab_mediaicon_width); width: var(--tab_mediaicon_width);
@ -1372,9 +1371,9 @@ div {
width: var(--close_width); width: var(--close_width);
background-color: var(--close_x); background-color: var(--close_x);
-webkit-mask-image: url(../theme/close.svg); -webkit-mask-image: url(../theme/close.svg);
-webkit-mask-size: var(--close_height) var(--close_width); -webkit-mask-size: 100% 100%;
mask-image: url(../theme/close.svg); mask-image: url(../theme/close.svg);
mask-size: 100%; mask-size: var(--close_width) var(--close_height);
mask-position: center, center; mask-position: center, center;
} }
@ -1403,16 +1402,12 @@ div {
border: none; border: none;
} }
.folder_header.folder_header_hover,
.tab_header.tab_header_hover {
z-index: 9999;
}
.dragged_tree>.folder_header, .folder.dragged_tree>.folder_header,
.dragged_tree>.tab_header { .pin.dragged_tree>.tab_header,
.tab.dragged_tree>.tab_header {
border: 1px solid var(--tab_selected_border); border: 1px solid var(--tab_selected_border);
background-color: var(--tab_selected_background); background-color: var(--tab_selected_background);
} }
@ -1432,7 +1427,8 @@ div {
.o>.tab_header>.tab_counter, .o>.tab_header>.tab_counter,
.c>.folder_header>.folder_counter, .c>.folder_header>.folder_counter,
.c>.tab_header>.tab_counter { .c>.tab_header>.tab_counter {
opacity: 0.3; font-family: Arial, Helvetica, "Nimbus Sans L", "Liberation Sans", FreeSans, Sans-serif;
opacity: 0.7;
display: block; display: block;
position: absolute; position: absolute;
vertical-align: bottom; vertical-align: bottom;
@ -1441,42 +1437,45 @@ div {
top: var(--counter_top); top: var(--counter_top);
text-overflow: ellipsis; text-overflow: ellipsis;
width: auto; width: auto;
height: var(--counter_height); height: var(--counter_size);
padding-top: 0px;
padding-bottom: 0px;
padding-left: 1px;
padding-right: 1px;
overflow: hidden; overflow: hidden;
border: 1px solid #e7e7e7; border: 1px solid #e7e7e7;
border-radius: 6px; border-radius: 6px;
background-color: #e7e7e7; background-color: #e7e7e7;
line-height: 10px;
} }
.o>.folder_header:hover>.folder_counter, .o>.folder_header:hover>.folder_counter,
.o>.tab_header:hover>.tab_counter, .o>.tab_header:hover>.tab_counter,
.c>.folder_header:hover>.folder_counter, .c>.folder_header:hover>.folder_counter,
.c>.tab_header:hover>.tab_counter { .c>.tab_header:hover>.tab_counter {
opacity: 0.9; opacity: 1;
height: calc(var(--counter_height) + 1px);
} }
/*
.o>.tab_header:hover>.tab_counter>.counter_number, .o>.tab_header:hover>.tab_counter>.counter_number,
.c>.tab_header:hover>.tab_counter>.counter_number, .c>.tab_header:hover>.tab_counter>.counter_number,
.o>.folder_header:hover>.folder_counter>.counter_number, .o>.folder_header:hover>.folder_counter>.counter_number,
.c>.folder_header:hover>.folder_counter>.counter_number { .c>.folder_header:hover>.folder_counter>.counter_number {
top: calc(var(--counter_number_top) + 1px); top: calc(var(--counter_number_top) + 1px);
font-size: calc(var(--counter_font_size) + 1px); font-size: calc(var(--counter_font_size) + 1px);
line-height: calc(var(--counter_height) + 4px);
} }
*/
.folder_counter>.counter_number, .folder_counter>.counter_number,
.tab_counter>.counter_number { .tab_counter>.counter_number {
position: relative; position: relative;
top: var(--counter_number_top);
font-family: Arial, Helvetica, "Nimbus Sans L", "Liberation Sans", FreeSans, Sans-serif; font-family: Arial, Helvetica, "Nimbus Sans L", "Liberation Sans", FreeSans, Sans-serif;
white-space: nowrap; white-space: nowrap;
font-size: var(--counter_font_size); font-size: var(--counter_size);
/* color: #303030; */
color: #000000; color: #000000;
padding-left: 1px; line-height: 1px;
padding-right: 1px; bottom: var(--counter_number);
} }

View File

@ -0,0 +1,9 @@
@keyframes attention_blinking {
0% {background-color: var(--tab_background); border:1px solid var(--tab_border);}
50% {background-color: var(--attention_background); border:1px solid var(--attention_border);}
80% {background-color: var(--tab_background); border:1px solid var(--tab_border);}
100% {background-color: var(--tab_background); border:1px solid var(--tab_border);}
}
.pin.attention>.tab_header {
animation: attention_blinking 2.5s infinite;
}

View File

@ -0,0 +1,12 @@
@keyframes audio_blinking {
0% {opacity: 0}
30% {opacity: 1}
70% {opacity: 1}
100% {opacity: 0}
}
.audible>.tab_header>.tab_mediaicon {
animation: audio_blinking 1.5s infinite;
}
.muted>.tab_header>.tab_mediaicon {
animation: audio_blinking 1.5s infinite;
}

View File

@ -7,9 +7,7 @@ body {
--pin_height: 22px; --pin_height: 22px;
--tab_height: 16px; --tab_height: 16px;
--tab_height_line: 16px; --title_font_size: 11px;
--title_font_size: 10.5px;
--tab_title_text_padding_left: 18px; --tab_title_text_padding_left: 18px;
--tab_title_text_padding_exp_left: 25px; --tab_title_text_padding_exp_left: 25px;
@ -29,16 +27,15 @@ body {
--children_padding_left: 5px; --children_padding_left: 5px;
--close_top: 1px; --close_top: 1px;
--close_right: 0px; --close_right: 1px;
--close_height: 12px; --close_height: 12px;
--close_width: 12px; --close_width: 12px;
--tab_mediaicon_height: 8px; --tab_mediaicon_height: 8px;
--tab_mediaicon_width: 8px; --tab_mediaicon_width: 8px;
--counter_height: 5px; --counter_size: 7px;
--counter_left: 19px;
--counter_top: 0px; --counter_top: 0px;
--counter_font_size: 7px; --counter_left: 18px;
--counter_number_top: -3px; --counter_number: -3px;
} }

View File

@ -6,10 +6,8 @@ body {
--pin_width: 22px; --pin_width: 22px;
--pin_height: 22px; --pin_height: 22px;
--tab_height: 17px; --tab_height: 18px;
--tab_height_line: 18px; --title_font_size: 12px;
--title_font_size: 10.5px;
--tab_title_text_padding_left: 21px; --tab_title_text_padding_left: 21px;
--tab_title_text_padding_exp_left: 30px; --tab_title_text_padding_exp_left: 30px;
@ -30,15 +28,14 @@ body {
--children_padding_left: 5px; --children_padding_left: 5px;
--close_top: 1px; --close_top: 1px;
--close_right: 1px; --close_right: 1px;
--close_height: 13px; --close_height: 14px;
--close_width: 13px; --close_width: 13px;
--tab_mediaicon_height: 9px; --tab_mediaicon_height: 9px;
--tab_mediaicon_width: 9px; --tab_mediaicon_width: 9px;
--counter_height: 6px; --counter_size: 7px;
--counter_left: 21px;
--counter_top: 0px; --counter_top: 0px;
--counter_font_size: 8px; --counter_left: 21px;
--counter_number_top: -2px; --counter_number: -3px;
} }

View File

@ -7,9 +7,7 @@ body {
--pin_height: 24px; --pin_height: 24px;
--tab_height: 20px; --tab_height: 20px;
--tab_height_line: 23px; --title_font_size: 14px;
--title_font_size: 12px;
--tab_title_text_padding_left: 26px; --tab_title_text_padding_left: 26px;
--tab_title_text_padding_exp_left: 35px; --tab_title_text_padding_exp_left: 35px;
@ -29,17 +27,15 @@ body {
--children_padding_left: 5px; --children_padding_left: 5px;
--close_top: 2px; --close_top: 2px;
--close_right: 1px; --close_right: 2px;
--close_height: 14px; --close_height: 14px;
--close_width: 14px; --close_width: 14px;
--tab_mediaicon_height: 10px; --tab_mediaicon_height: 10px;
--tab_mediaicon_width: 10px; --tab_mediaicon_width: 10px;
--counter_height: 6px; --counter_size: 8px;
--counter_left: 24px;
/* --counter_left: 1px; */
--counter_top: 1px; --counter_top: 1px;
--counter_font_size: 8px; --counter_left: 24px;
--counter_number_top: -2px; --counter_number: -4px;
} }

View File

@ -7,9 +7,7 @@ body {
--pin_height: 26px; --pin_height: 26px;
--tab_height: 22px; --tab_height: 22px;
--tab_height_line: 24px; --title_font_size: 14px;
--title_font_size: 13px;
--tab_title_text_padding_left: 25px; --tab_title_text_padding_left: 25px;
--tab_title_text_padding_exp_left: 37px; --tab_title_text_padding_exp_left: 37px;
@ -36,9 +34,8 @@ body {
--tab_mediaicon_height: 11px; --tab_mediaicon_height: 11px;
--tab_mediaicon_width: 11px; --tab_mediaicon_width: 11px;
--counter_height: 6px; --counter_size: 8px;
--counter_left: 26px;
--counter_top: 1px; --counter_top: 1px;
--counter_font_size: 8px; --counter_left: 26px;
--counter_number_top: -2px; --counter_number: -4px;
} }

View File

@ -7,16 +7,14 @@ body {
--pin_height: 28px; --pin_height: 28px;
--tab_height: 24px; --tab_height: 24px;
--tab_height_line: 26px; --title_font_size: 15px;
--title_font_size: 14px;
--tab_title_text_padding_left: 27px; --tab_title_text_padding_left: 27px;
--tab_title_text_padding_exp_left: 39px; --tab_title_text_padding_exp_left: 39px;
--tab_title_text_padding_right_with_close_button: 24px; --tab_title_text_padding_right_with_close_button: 24px;
--favicon_width: 18px; --favicon_width: 16px;
--favicon_height: 18px; --favicon_height: 16px;
--favicon_left: 3px; --favicon_left: 3px;
--expand_height: 23px; --expand_height: 23px;
@ -36,9 +34,8 @@ body {
--tab_mediaicon_height: 12px; --tab_mediaicon_height: 12px;
--tab_mediaicon_width: 12px; --tab_mediaicon_width: 12px;
--counter_height: 6px; --counter_size: 8px;
--counter_left: 28px;
--counter_top: 1px; --counter_top: 1px;
--counter_font_size: 8px; --counter_left: 28px;
--counter_number_top: -2px; --counter_number: -4px;
} }

View File

@ -0,0 +1,41 @@
body {
--scrollbar_height: 4px;
--scrollbar_width: 16px;
--pin_width: 30px;
--pin_height: 30px;
--tab_height: 26px;
--title_font_size: 16px;
--tab_title_text_padding_left: 29px;
--tab_title_text_padding_exp_left: 41px;
--tab_title_text_padding_right_with_close_button: 24px;
--favicon_width: 16px;
--favicon_height: 16px;
--favicon_left: 3px;
--expand_height: 25px;
--expand_width: 45px;
--expand_mask_top: 10px;
--expand_mask_left: 29px;
--expand_mask_height: 7px;
--expand_mask_width: 7px;
--children_padding_left: 5px;
--close_top: 5px;
--close_right: 5px;
--close_height: 14px;
--close_width: 14px;
--tab_mediaicon_height: 13px;
--tab_mediaicon_width: 13px;
--counter_size: 8px;
--counter_top: 1px;
--counter_left: 30px;
--counter_number: -4px;
}

View File

@ -23,6 +23,5 @@ body {
--pin_list_padding_bottom: 2px; --pin_list_padding_bottom: 2px;
--pin_list_padding_left: 2px; --pin_list_padding_left: 2px;
--group_folders_top: 2px;
--group_tabs_top: 2px; --group_tabs_top: 2px;
} }

View File

@ -23,6 +23,5 @@ body {
--pin_list_padding_bottom: 1px; --pin_list_padding_bottom: 1px;
--pin_list_padding_left: 1px; --pin_list_padding_left: 1px;
--group_folders_top: 1px;
--group_tabs_top: 1px; --group_tabs_top: 1px;
} }

View File

@ -23,6 +23,5 @@ body {
--pin_list_padding_bottom: 0px; --pin_list_padding_bottom: 0px;
--pin_list_padding_left: 0px; --pin_list_padding_left: 0px;
--group_folders_top: -1px; --group_tabs_top: 0px;
--group_tabs_top: -1px;
} }

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Tree Tabs - translation tool</title>
</head>
<body id="body" class="sidebar_body">
<button type="button" id="load_translation" style="position: relative; margin:10px;">Load translated file</button>
<button type="button" id="export_translation" style="position: relative; margin:10px;">Export translation</button>
<a href="mailto:karol@jagiello.it">Send your translation here</a>
<script type="text/javascript" src="./translator.js"></script>
</body>
</html>

121
translator/translator.js Normal file
View File

@ -0,0 +1,121 @@
const english_base = {"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 Tree Tabs toolbar, places new tabs in the root of the active group, unless set differently."},"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"}};
let translator = {
Nodes: {
},
init: function() {
for (var Id in english_base) {
translator.Nodes[Id] = new translator.textBox({id: Id, message: english_base[Id].message});
}
document.getElementById("load_translation").onclick = function(event) {
if (event.which == 1) {
translator.File_OpenFile();
}
}
document.getElementById("export_translation").onclick = function(event) {
if (event.which == 1) {
translator.File_SaveFile();
}
}
},
textBox: class {
constructor(p) {
let OriginalText = document.createElement("div");
OriginalText.classList = "original";
OriginalText.id = p.id;
OriginalText.innerHTML = p.message;
body.appendChild(OriginalText);
this.OriginalText = OriginalText;
let TextBox = document.createElement("textarea");
TextBox.classList = "translated";
TextBox.id = p.id;
TextBox.style.width = "100%";
TextBox.value = "";
TextBox.style.whiteSpace = "normal";
TextBox.style.marginBottom = "10px";
body.appendChild(TextBox);
this.TextBox = TextBox;
}
},
File: {
OpenFile: function(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();
inp.onchange = function(event) {
let fr = new FileReader();
if (inp.files[0] == undefined) return;
fr.readAsText(inp.files[0]);
fr.onload = function() {
let data = JSON.parse(fr.result);
inp.parentNode.removeChild(inp);
for (var Id in data) {
if (translator.Nodes[Id]) {
translator.Nodes[Id].TextBox.value = data[Id].message;
}
}
}
}
},
SaveFile: function() {
let data = {};
for (var Id in translator.Nodes) {
data[Id] = {"message": translator.Nodes[Id].TextBox.value};
}
let file = new File([JSON.stringify(data)], "messages.json", {type: "text/json;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 = "messages.json";
body.appendChild(savelink);
setTimeout(function() {
savelink.click();
setTimeout(function() {
savelink.parentNode.removeChild(savelink);
}, 60000);
}, 10);
}
},
}
translator.init();

14
vivaldi/save_file.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body id="body">
<p>This tab can be closed after saving file</p>
<script type="text/javascript" src="./save_file.js"></script>
</body>
</html>

24
vivaldi/save_file.js Normal file
View File

@ -0,0 +1,24 @@
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;
}
function File_SaveFile(filename, extension, data) {
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();
}
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message.command == "save_file") {
File_SaveFile(message.filename, message.extension, message.data);
}
});