From f7922f419a96321ddc564cef5dc31639329e14de Mon Sep 17 00:00:00 2001 From: MrOtherGuy Date: Mon, 1 Jun 2020 20:24:22 +0300 Subject: [PATCH] Add experimental style browser ui --- add_style.py | 110 +++++++++++++++++++++++++++++ chrome/test.css | 3 + html_resources/main.css | 44 ++++++++++++ html_resources/selector.js | 139 +++++++++++++++++++++++++++++++++++++ html_resources/tagmap.json | 95 +++++++++++++++++++++++++ tags.csv | 93 +++++++++++++++++++++++++ 6 files changed, 484 insertions(+) create mode 100644 add_style.py create mode 100644 chrome/test.css create mode 100644 html_resources/main.css create mode 100644 html_resources/selector.js create mode 100644 html_resources/tagmap.json create mode 100644 tags.csv diff --git a/add_style.py b/add_style.py new file mode 100644 index 0000000..e883922 --- /dev/null +++ b/add_style.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 + +# +# usage: +# add_style.py +# where is a space-separated list of tags to apply for that style (1 minimum) +# OR +# add_style-py --update-only +# +# When called with it will create a new file to chrome/ folder and +# update tags.csv and docs/tagmap.json +# +# With --update-only it will only update docs/tagmap.json based on tags.csv + +import sys, os + +def filterEmpty(list): + for i in range(2,len(list)): + if list[i] == "": + del list[i] + +def createJSON(tagmap,filename,args,onlyupdate): + charBuffer = "{\n" + map_last = len(tagmap) - 1 + n_line=0 + for line in tagmap: + tokens = line.rsplit(",") + filterEmpty(tokens) + if len(tokens) < 2: + continue + charBuffer += "\"{}\":[".format(tokens[0]) + for t in range(1,len(tokens)): + # if len(tokens[t]) > 0: + charBuffer += "\"{}\"".format(tokens[t]) + if t < len(tokens)-1: + charBuffer += "," + if(n_line < map_last): + charBuffer += "],\n" + + else: + if onlyupdate: + charBuffer += "]\n}" + break + else: + charBuffer += "],\n" + n_line += 1 + if not(onlyupdate): + charBuffer += "\"{}\":[".format(filename) + for t in range(0,len(args)): + charBuffer += "\"{}\"".format(args[t]) + if t < len(args) - 1: + charBuffer += "," + charBuffer += "]\n}" + + with open("html_resources/tagmap.json","w") as json: + print(charBuffer,file=json) + print("wrote JSON\n") + + +def searchFile(tagmap,name): + for line in tagmap: + if name in line: + return True + return False + +def createNewFile(name): + text = "/* Source file https://github.com/MrOtherGuy/firefox-csshacks/tree/master/chrome/{} made available under Mozilla Public License v. 2.0\nSee the above repository for updates as well as full license text. */\n".format(name) + + if os.path.isfile("chrome/{}".format(name)): + confirm = input("File {} already exists! proceed (will overwrite) ? [y/N] ".format(name)) + if confirm != "y": + print("Aborted") + return False + + + with open("chrome/{}".format(name),"w") as css: + print(text,file=css) + print("Created chrome/{}".format(name)) + return True + +if __name__ == "__main__": + + if len(sys.argv) < (2 + (0 if (sys.argv[1] == "--update-only") else 1)): + print("usage: add_file.py ") + exit() + + args = [] + for i in range (2,(len(sys.argv))): + args.append(sys.argv[i]) + + name = sys.argv[1] + update_only = name == "--update-only" + + file = open("tags.csv") + + tagmap = file.read().lstrip().splitlines() + file.close() + if not(update_only) and searchFile(tagmap,name): + print(name + "exist already") + else: + if not(update_only): + exists = createNewFile(name) + file = open("tags.csv","a") + file.write(name+","+",".join(args)+"\n") + file.close() + else: + print("Only update json") + createJSON(tagmap,name,args,update_only) + print("Done") + exit(0) diff --git a/chrome/test.css b/chrome/test.css new file mode 100644 index 0000000..c4933ca --- /dev/null +++ b/chrome/test.css @@ -0,0 +1,3 @@ +/* Source file https://github.com/MrOtherGuy/firefox-csshacks/tree/master/chrome/test.css made available under Mozilla Public License v. 2.0 +See the above repository for updates as well as full license text. */ + diff --git a/html_resources/main.css b/html_resources/main.css new file mode 100644 index 0000000..16fbef1 --- /dev/null +++ b/html_resources/main.css @@ -0,0 +1,44 @@ +body{background-color: rgb(60,50,70); color: silver; margin: 0px } +#ui{ display: flex; } + +#categories{ + padding-block: 1em; + box-sizing: border-box; + border-inline-end: 1px solid gold; + background-color: rgb(60,60,70); + max-height: 100vh; + overflow-y: auto; + min-width: 18ch +} +a{ color: rgb(100,150,200); margin-inline-start: 1ch } +a:visited{ color: rgb(150,100,200) } +a:hover{ color: rgb(200,150,100) } +pre:empty{ display: none } +.category{ padding: 0.2em 1em; cursor: pointer } + +.currentCategory, +.category:hover{ background-color: grey } + +.target{ + margin: 0.2em; + background-color: rgb(60,60,70); + padding: 0.5em; + border: 1px solid rgb(40,40,40); + border-radius: 4px; + max-width: 50ch; + cursor: pointer +} +.target:hover{ background-color: rgb(80,80,90) } +#targets{ display: flex; flex-wrap: wrap } + +pre{ + white-space: pre-wrap; + margin: 1em; + border: 2px inset; + padding: 0.5em; + background-color: rgb(40,50,50) +} + +.hidden{ display: none !important } + +.target{ display: flex; justify-content: space-between } \ No newline at end of file diff --git a/html_resources/selector.js b/html_resources/selector.js new file mode 100644 index 0000000..0411db1 --- /dev/null +++ b/html_resources/selector.js @@ -0,0 +1,139 @@ +'use strict'; + +let DB = null; + +function initDB(obj){ + DB = obj; + Object.defineProperty(DB,"query",{value:function (q,list){ + let nlist = []; + for(let key of list || Object.keys(this)){ + if(this[key].includes(q)){ + nlist.push(key) + } + } + return nlist + }}); + return true +} + +let previousCategory = new (function(){ + let current = null; + this.set = function(t){ + current&¤t.classList.remove("currentCategory"); + current = t; + current.classList.add("currentCategory"); + }; + return this +})() + +function getText(node){ + return node.childNodes[0].textContent +} + +async function onCategoryClicked(categoryNode){ + + previousCategory.set(categoryNode); + + let names = DB.query(categoryNode.textContent); + for(let c of Array.from(document.querySelectorAll(".target"))){ + names.includes(getText(c)) ? c.classList.remove("hidden") : c.classList.add("hidden"); + } +} + +async function onTargetClicked(targetNode){ + const codeBlock = document.querySelector("pre"); + let file = await fetch(`chrome/${getText(targetNode)}`); + let t = await file.text(); + codeBlock.textContent = t; +} + +function onSomeClicked(e){ + let cl = e.target.parentNode.id; + switch(cl){ + case "categories": + onCategoryClicked(e.target); + break; + case "targets": + onTargetClicked(e.target); + break; + default: + break; + } +} + + +function createCategories(){ + + const CAT_PARENT = document.getElementById("categories"); + CAT_PARENT.addEventListener("click",onSomeClicked) + + const TAR_PARENT = document.getElementById("targets"); + TAR_PARENT.addEventListener("click",onSomeClicked); + + const createNode = function(name,type){ + let node = document.createElement("div"); + node.classList.add(type); + node.textContent = name; + if(type === "target"){ + let link = node.appendChild(document.createElement("a")); + node.classList.add("hidden"); + link.href = `https://github.com/MrOtherGuy/firefox-csshacks/tree/master/chrome/${name}`; + link.textContent = "Github"; + } + + return node; + } + + const createCategory = name => createNode(name,"category"); + + const createTarget = name => createNode(name,"target"); + + const CAT_NAMES = (function(){ + let list = []; + + for(let key of Object.keys(DB)){ + TAR_PARENT.appendChild(createNode(key,"target")); + let things = DB[key]; + for(let t of things){ + list.push(t) + } + } + list.sort(); + let ret = []; + let ns = [0]; + ret[0] = list[0]; + let i = 0; + for(let item of list){ + if(ret[i]!=item){ + ret[++i]=item; + ns[i]=0; + }else{ + ns[i]++ + } + } + let map = ret.map((a,i)=>({name:a,value:ns[i]})) + + return map.sort((a,b)=>(a.value > b.value?-1:a.value < b.value ? 1:0)) + })(); + + for(let cat of CAT_NAMES){ + CAT_PARENT.appendChild(createCategory(cat.name)) + } + +} + +document.onreadystatechange = (function () { + if (document.readyState === "complete") { + fetch("html_resources/tagmap.json") + .then(response => { + const contentType = response.headers.get('content-type'); + if (!contentType || !contentType.includes('application/json')) { + throw new TypeError("Oops, we haven't got JSON!"); + } + return response.json(); + }) + .then(json=>(initDB(json))) + .then(()=>createCategories()) + .catch(e=>{console.log(e);document.getElementById("ui").textContent = "FAILURE, Database could not be loaded"}); + } +}); \ No newline at end of file diff --git a/html_resources/tagmap.json b/html_resources/tagmap.json new file mode 100644 index 0000000..c13bdf3 --- /dev/null +++ b/html_resources/tagmap.json @@ -0,0 +1,95 @@ +{ +"Fx65_tabs_on_bottom.css":["tabs","toolbars","classic"], +"Fx65_tabs_on_bottom_menubar_on_top_patch.css":["tabs","menubar","toolbars","classic","patch"], +"autohide_bookmarks_and_main_toolbars.css":["autohide","bookmarks","toolbars","nav-bar","toolbox"], +"autohide_bookmarks_toolbar.css":["autohide","bookmarks","toolbars"], +"autohide_menubar.css":["autohide","menubar","toolbars"], +"autohide_navigation_button.css":["autohide","minimal","navigation","buttons"], +"autohide_sidebar.css":["autohide","sidebar"], +"autohide_tabstoolbar.css":["autohide","tabs","toolbars"], +"autohide_toolbox.css":["autohide","toolbox","toolbars","fullscreen"], +"blank_page_background.css":["dark-mode","flash","blank","background"], +"bookmarksbar_on_new_tabs_only.css":["legacy"], +"button_effect_icon_glow.css":["buttons","effect","minimal"], +"button_effect_scale_onclick.css":["buttons","effect","minimal"], +"button_effect_scale_onhover.css":["buttons","effect","minimal"], +"classic_grid_main_menu_popup.css":["classic","grid","menu","popup"], +"click_selected_tab_to_focus_urlbar.css":["hack","tabs","urlbar"], +"color_variable_template.css":["theme","color","variables"], +"combined_favicon_and_tab_close_button.css":["tab","icon","close"], +"combined_tabs_and_main_toolbars.css":["minimal","tabs","toolbars"], +"compact_urlbar_megabar.css":["urlbar","minimal"], +"dark_additional_windows.css":["windows","dark-mode"], +"dark_checkboxes_and_radios.css":["widgets","dark-mode"], +"dark_context_menus.css":["dark-mode","menus"], +"dark_theme_aware_statuspanel.css":["staus","dark-mode"], +"disable_newtab_on_middle_click.css":["hack","newtab","tab"], +"fake_statusbar.css":["hack","status","toolbar"], +"floating_findbar_on_top.css":["findbar","overlay"], +"full_width_urlbar_popup.css":["ulrbar","popup"], +"google_style_urlbar_popup.css":["urlbar","popup"], +"grid_overflow_menu.css":["popup","menu"], +"hide_statuspanel_when_fullscreen.css":["status","fullscreen","hiding"], +"hide_tabs_toolbar.css":["hiding","tabs","toolbars"], +"hide_tabs_with_one_tab.css":["hiding","tabs","toolbars"], +"hide_tabs_with_one_tab_w_window_controls.css":["hiding","tabs","toolbars"], +"hide_toolbox_top_bottom_borders.css":["toolbox","hiding"], +"hide_urlbar_first_row.css":["urlbar","popup","hiding"], +"linux_gtk_window_control_patch.css":["patch","window-control"], +"menubar_in_toolbar.css":["toolbars","minimal"], +"menubar_in_toolbar_oneliner_compatible.css":["toolbars","minimal"], +"minimal_in-UI_scrollbars.css":["minimal","scrollbar"], +"minimal_text_fields.css":["minimal","urlbar","searchbar"], +"minimal_toolbarbuttons.css":["minimal","buttons"], +"minimal_toolbarbuttons_v2.css":["minimal","buttons"], +"minimal_toolbarbuttons_v3.css":["minimal","buttons"], +"more_visible_tab_icon.css":["tab","icon"], +"multi-row_bookmarks.css":["multi-row","bookmarks"], +"multi-row_oneliner_combo_patch.css":["multi-row","patch","1-line","minimal"], +"multi-row_tabs.css":["tabs","multi-row","toolbars"], +"multi-row_tabs_Fx66%2B.css":["legacy"], +"multi-row_tabs_below_content.css":["multi-row","tabs","toolbars"], +"multi-row_tabs_below_content_legacy.css":["legacy"], +"multi-row_tabs_legacy.css":["legacy"], +"multi-row_tabs_window_control_patch.css":["patch","multi-row","window-control"], +"navbar_below_content.css":["nav-bar","toolbars"], +"navbar_tabs_oneliner.css":["1-line","minimal","tabs","nav-bar","toolbars"], +"navbar_tabs_oneliner_menu_buttons_on_right.css":["1-line","minimal","tabs","nav-bar","toolbars","patch","menubar"], +"navbar_tabs_oneliner_tabs_on_left.css":["1-line","minimal","tabs","nav-bar","toolbar"], +"navbar_tabs_responsive_oneliner.css":["1-line","minimal","tabs","nav-bar","toolbars"], +"navigation_buttons_inside_urlbar.css":["navigation","buttons","urlbar"], +"numbered_tabs.css":["tabs"], +"overlay_menubar.css":["menubar"], +"overlay_scrollbars.as.css":["scrollbar"], +"page_action_buttons_on_hover.css":["urlbar","minimal","effect"], +"pinned_tabs_on_right.css":["tabs"], +"scrollable_menupopups.css":["scrollbar","popup","menu"], +"scrollable_urlbar_popup.css":["scrollbar","popup","urlbar"], +"show_navbar_on_focus_only.css":["urlbar","nav-bar","toolbar","hiding"], +"show_window_title_in_menubar.css":["windows","menubar"], +"status_inside_urlbar.css":["status","urlbar","hack"], +"tab_close_button_always_on_hover.css":["tab","close"], +"tab_loading_progress_throbber.css":["tab","icon","animation"], +"tabs_animated_gradient_border.css":["hack","animation"], +"tabs_below_content.css":["toolbars","tabs"], +"tabs_fill_available_width.css":["tab","tabs"], +"textual_context_navigation.css":["navigation","popup","menu"], +"theme_additional_windows.css":["legacy"], +"theme_color_variables.css":["legacy"], +"theme_popups_and_menus.css":["legacy"], +"theme_sidebar.css":["legacy"], +"theme_toolbars.css":["legacy"], +"toggle_bookmarksbar_with_alt.css":["legacy"], +"toggle_tabs_toolbar_with_alt.css":["hack","tabs","menubar"], +"toolbarbuttons_icon%2Blabel.css":["buttons","icon"], +"toolbars_below_content.css":["tabs","toolbox","toolbars"], +"urlbar_and_popup_equal_width.css":["legacy"], +"urlbar_centered_text.css":["urlbar"], +"urlbar_full_width.css":["urlbar","popup"], +"urlbar_results_in_two_rows.css":["urlbar","popup"], +"urlbar_visible_on_active_tab_click.css":["hack","urlbar"], +"vertical_context_navigation.css":["navigation","menu","popup"], +"vertical_context_navigation_v2.css":["navigation","menu","popup"], +"vertical_menubar.css":["menubar","hack"], +"window_control_placeholder_support.css":["window-control","patch"] +} diff --git a/tags.csv b/tags.csv new file mode 100644 index 0000000..ea74565 --- /dev/null +++ b/tags.csv @@ -0,0 +1,93 @@ +Fx65_tabs_on_bottom.css,tabs,toolbars,classic +Fx65_tabs_on_bottom_menubar_on_top_patch.css,tabs,menubar,toolbars,classic,patch +autohide_bookmarks_and_main_toolbars.css,autohide,bookmarks,toolbars,nav-bar,toolbox +autohide_bookmarks_toolbar.css,autohide,bookmarks,toolbars +autohide_menubar.css,autohide,menubar,toolbars +autohide_navigation_button.css,autohide,minimal,navigation,buttons +autohide_sidebar.css,autohide,sidebar +autohide_tabstoolbar.css,autohide,tabs,toolbars +autohide_toolbox.css,autohide,toolbox,toolbars,fullscreen +blank_page_background.css,dark-mode,flash,blank,background +bookmarksbar_on_new_tabs_only.css,legacy +button_effect_icon_glow.css,buttons,effect,minimal +button_effect_scale_onclick.css,buttons,effect,minimal +button_effect_scale_onhover.css,buttons,effect,minimal +classic_grid_main_menu_popup.css,classic,grid,menu,popup +click_selected_tab_to_focus_urlbar.css,hack,tabs,urlbar +color_variable_template.css,theme,color,variables +combined_favicon_and_tab_close_button.css,tab,icon,close +combined_tabs_and_main_toolbars.css,minimal,tabs,toolbars +compact_urlbar_megabar.css,urlbar,minimal +dark_additional_windows.css,windows,dark-mode +dark_checkboxes_and_radios.css,widgets,dark-mode +dark_context_menus.css,dark-mode,menus +dark_theme_aware_statuspanel.css,staus,dark-mode +disable_newtab_on_middle_click.css,hack,newtab,tab +fake_statusbar.css,hack,status,toolbar +floating_findbar_on_top.css,findbar,overlay +full_width_urlbar_popup.css,ulrbar,popup +google_style_urlbar_popup.css,urlbar,popup +grid_overflow_menu.css,popup,menu +hide_statuspanel_when_fullscreen.css,status,fullscreen,hiding +hide_tabs_toolbar.css,hiding,tabs,toolbars +hide_tabs_with_one_tab.css,hiding,tabs,toolbars +hide_tabs_with_one_tab_w_window_controls.css,hiding,tabs,toolbars +hide_toolbox_top_bottom_borders.css,toolbox,hiding +hide_urlbar_first_row.css,urlbar,popup,hiding +linux_gtk_window_control_patch.css,patch,window-control +menubar_in_toolbar.css,toolbars,minimal +menubar_in_toolbar_oneliner_compatible.css,toolbars,minimal +minimal_in-UI_scrollbars.css,minimal,scrollbar +minimal_text_fields.css,minimal,urlbar,searchbar +minimal_toolbarbuttons.css,minimal,buttons +minimal_toolbarbuttons_v2.css,minimal,buttons +minimal_toolbarbuttons_v3.css,minimal,buttons +more_visible_tab_icon.css,tab,icon +multi-row_bookmarks.css,multi-row,bookmarks +multi-row_oneliner_combo_patch.css,multi-row,patch,1-line,minimal +multi-row_tabs.css,tabs,multi-row,toolbars +multi-row_tabs_Fx66%2B.css,legacy +multi-row_tabs_below_content.css,multi-row,tabs,toolbars +multi-row_tabs_below_content_legacy.css,legacy +multi-row_tabs_legacy.css,legacy +multi-row_tabs_window_control_patch.css,patch,multi-row,window-control +navbar_below_content.css,nav-bar,toolbars +navbar_tabs_oneliner.css,1-line,minimal,tabs,nav-bar,toolbars +navbar_tabs_oneliner_menu_buttons_on_right.css,1-line,minimal,tabs,nav-bar,toolbars,patch,menubar +navbar_tabs_oneliner_tabs_on_left.css,1-line,minimal,tabs,nav-bar,toolbar +navbar_tabs_responsive_oneliner.css,1-line,minimal,tabs,nav-bar,toolbars +navigation_buttons_inside_urlbar.css,navigation,buttons,urlbar +numbered_tabs.css,tabs +overlay_menubar.css,menubar +overlay_scrollbars.as.css,scrollbar +page_action_buttons_on_hover.css,urlbar,minimal,effect +pinned_tabs_on_right.css,tabs +scrollable_menupopups.css,scrollbar,popup,menu +scrollable_urlbar_popup.css,scrollbar,popup,urlbar +show_navbar_on_focus_only.css,urlbar,nav-bar,toolbar,hiding +show_window_title_in_menubar.css,windows,menubar +status_inside_urlbar.css,status,urlbar,hack +tab_close_button_always_on_hover.css,tab,close +tab_loading_progress_throbber.css,tab,icon,animation +tabs_animated_gradient_border.css,hack,animation +tabs_below_content.css,toolbars,tabs +tabs_fill_available_width.css,tab,tabs +textual_context_navigation.css,navigation,popup,menu +theme_additional_windows.css,legacy +theme_color_variables.css,legacy, +theme_popups_and_menus.css,legacy +theme_sidebar.css,legacy +theme_toolbars.css,legacy +toggle_bookmarksbar_with_alt.css,legacy +toggle_tabs_toolbar_with_alt.css,hack,tabs,menubar +toolbarbuttons_icon%2Blabel.css,buttons,icon +toolbars_below_content.css,tabs,toolbox,toolbars +urlbar_and_popup_equal_width.css,legacy +urlbar_centered_text.css,urlbar +urlbar_full_width.css,urlbar,popup +urlbar_results_in_two_rows.css,urlbar,popup +urlbar_visible_on_active_tab_click.css,hack,urlbar +vertical_context_navigation.css,navigation,menu,popup +vertical_context_navigation_v2.css,navigation,menu,popup +vertical_menubar.css,menubar,hack +window_control_placeholder_support.css,window-control,patch