diff options
author | Wojtek Kosior <koszko@koszko.org> | 2021-09-01 11:45:06 +0200 |
---|---|---|
committer | Wojtek Kosior <koszko@koszko.org> | 2021-09-01 11:45:06 +0200 |
commit | 453ba03962ececcdff9264bea606b7bc488c1803 (patch) | |
tree | 169d81bb94e2c2849d1756c65ad3a528a9d944db | |
parent | 544c6df3ab1e331c6b6779b76ad33180a06b0b4d (diff) | |
download | browser-extension-453ba03962ececcdff9264bea606b7bc488c1803.tar.gz browser-extension-453ba03962ececcdff9264bea606b7bc488c1803.zip |
add styling for popup page\n\nThis does not include styling for contents of the import dialog
-rw-r--r-- | copyright | 4 | ||||
-rw-r--r-- | html/DOM_helpers.js | 2 | ||||
-rw-r--r-- | html/back_button.css | 50 | ||||
-rw-r--r-- | html/base.css | 22 | ||||
-rw-r--r-- | html/display-panel.html | 365 | ||||
-rw-r--r-- | html/display-panel.js | 174 | ||||
-rw-r--r-- | html/import_frame.html | 1 | ||||
-rw-r--r-- | html/options.html | 95 | ||||
-rw-r--r-- | html/options_main.js | 8 | ||||
-rw-r--r-- | html/table.css | 46 |
10 files changed, 532 insertions, 235 deletions
@@ -31,6 +31,10 @@ Files: *.html README.txt copyright Copyright: 2021 Wojtek Kosior <koszko@koszko.org> License: GPL-3+ or Alicense-1.0 or CC-BY-SA-4.0 +Files: html/*.css +Copyright: 2021 Wojtek Kosior <koszko@koszko.org> +License: GPL-3+ or Alicense-1.0 or CC-BY-SA-4.0 + Files: html/base.css Copyright: 2021 Wojtek Kosior <koszko@koszko.org> 2021 Nicholas Johnson <nicholasjohnson@posteo.org> diff --git a/html/DOM_helpers.js b/html/DOM_helpers.js index 392299f..01e2be9 100644 --- a/html/DOM_helpers.js +++ b/html/DOM_helpers.js @@ -42,7 +42,7 @@ function clone_template(template_id) result_object[template_key] = element; element.removeAttribute("id"); - element.removeAttribute("template_key"); + element.removeAttribute("data-template"); for (const child of element.children) to_process.push(child); diff --git a/html/back_button.css b/html/back_button.css new file mode 100644 index 0000000..1ddc5da --- /dev/null +++ b/html/back_button.css @@ -0,0 +1,50 @@ +/** + * part of Hachette + * Style for a "back" button with a CSS arrow image. + * + * Copyright (C) 2021 Wojtek Kosior + * Redistribution terms are gathered in the `copyright' file. + */ + +.back_button { + display: block; + width: auto; + height: auto; + background-color: white; + border: solid #454 0.4em; + border-left: none; + border-radius: 0 1.5em 1.5em 0; + cursor: pointer; +} + +.back_button:hover { + box-shadow: 0 6px 8px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19); +} + +.back_button>div, .back_arrow { + width: 2em; + height: 0.5em; + background-color: #4CAF50; + border-radius: 0.3em; + margin: 1.15em 0.4em; +} + +.back_button>div::after, .back_arrow::after, +.back_button>div::before, .back_arrow::before { + content: ""; + display: block; + position: relative; + background-color: inherit; + width: 1.3em; + height: 0.5em; + transform: rotate(45deg); + border-radius: 0.3em; + top: 0.3em; + right: 0.2em; + margin: 0 -1.3em -0.5em 0; +} + +.back_button>div::before, .back_arrow::before { + transform: rotate(-45deg); + top: -0.3em; +} diff --git a/html/base.css b/html/base.css index 91fd953..0b9c7d3 100644 --- a/html/base.css +++ b/html/base.css @@ -6,8 +6,11 @@ * Redistribution terms are gathered in the `copyright' file. */ -html { +body { font-family: sans-serif; + background-color: #f0f0f0; + color: #555; + overflow: auto; } textarea { @@ -18,6 +21,10 @@ input[type="checkbox"], input[type="radio"], .hide { display: none; } +.camouflage { + visibility: hidden; +} + .show_next:not(:checked)+* { display: none; } @@ -42,6 +49,8 @@ button, .button { margin: 2px 0px; -moz-user-select: none; user-select: none; + cursor: pointer; + font: 400 15px sans-serif; } button.slimbutton, .button.slimbutton { @@ -64,3 +73,14 @@ aside { textarea: { resize: none; } + +.has_bottom_line::after, .has_upper_line::before { + content: ""; + display: block; + height: 8px; + background: linear-gradient(transparent, #555); +} + +.has_bottom_line::after { + background: linear-gradient(#555, transparent); +} diff --git a/html/display-panel.html b/html/display-panel.html index cbd7dc8..4121c30 100644 --- a/html/display-panel.html +++ b/html/display-panel.html @@ -9,117 +9,336 @@ <title>Hachette - page settings</title> <link type="text/css" rel="stylesheet" href="reset.css" /> <link type="text/css" rel="stylesheet" href="base.css" /> + <link type="text/css" rel="stylesheet" href="back_button.css" /> + <link type="text/css" rel="stylesheet" href="table.css" /> <style> body { - width: 300px; - height: 300px; + width: max-content; + width: -moz-max-content; } - ul { - padding-inline-start: 15px; + .bold, h2 { + font-weight: bold; } - .bold { - font-weight: bold; + h2 { + margin: 8px; + font-size: 120%; + } + + .top>h2 { + padding-left: calc(0.8*3.2em - 8px); + } + + .top { + line-height: calc(0.8*3.6em - 16px); } - .unroll_chbx:not(:checked)+*+label span.triangle:first-child+span.triangle, - .unroll_chbx:checked+*+label span.triangle:first-child, - .unroll_chbx:not(:checked)+*, - .unroll_chbx:not(:checked)+*+label+* { + #main_view>.top>h2 { + padding-left: 0; + } + + h3 { + padding: 5px; + font-size: 108%; + text-shadow: 0 0 0 #454; + } + + .unroll_chbx:not(:checked)+div>:not(:first-child) { display: none; } + .unroll_triangle { + height: 1em; + width: 1em; + display: inline-block; + } + + .unroll_triangle::after { + content: ""; + width: 0.6em; + height: 0.6em; + background: linear-gradient(-45deg, currentColor 50%, transparent 50%); + display: block; + position: relative; + transform: rotate(-45deg); + top: 0.3em; + } + + .unroll_chbx:checked+div>:first-child .unroll_triangle::after { + transform: rotate(45deg); + left: 0.2em; + top: 0.2em; + } + + .unroll_chbx:checked+div>:first-child .unroll_block { + display: block; + } + + .unroll_chbx:checked+div>:first-child { + line-height: 1.4em; + } + + .l2_ul { + border-left: solid #454 5px; + } + + .l1_li { + margin-top: 0.3em; + margin-bottom: 0.3em; + } + + .l1_li>div { + padding: 0.3em 0.3em 0.3em 0; + } + + .l2_li { + padding: 0.3em; + } + + #container_for_injected>*:nth-child(odd), + .l2_li:nth-child(odd) { + background-color: #e5e5e5; + } + #container_for_injected>#none_injected:not(:last-child) { display: none; } + + #page_url_heading>span { + display: inline-block; + } + + .back_button { + position: fixed; + z-index: 1; + top: 0; + left: 0; + /* The following scales the entire button. */ + font-size: 80%; + } + + #show_main_view_radio:checked~.back_button { + margin-left: -3.2em; + } + + #show_main_view_radio:not(:checked)~.back_button { + transition: all 0.2s ease-out; + } + + pre { + font-family: monospace; + background-color: white; + border-top: dashed #4CAF50 1px; + border-bottom: dashed #4CAF50 1px; + padding: 1px 5px; + } + + .matched_pattern { + font-weight: bold; + } + + tr.matched_pattern~tr { + color: #777; + font-size: 90%; + } + + .padding_inline { + padding-left: 5px; + padding-right: 5px; + } + + .header { + border-bottom: dashed #4CAF50 1px; + padding-bottom: 0.3em; + margin-bottom: 0.5em; + text-align: center; + } + + .middle { + margin-top: 0.5em; + margin-bottom: 0.5em; + } + + .footer { + border-top: dashed #4CAF50 1px; + padding-top: 0.3em; + margin-top: 0.5em; + text-align: center; + } + + .active_setting_table { + margin-bottom: 0.5em; + } + + .active_setting_table td { + padding: 5px; + vertical-align: middle; + } </style> </head> <body> <template> - <li id="pattern_li"> - <span></span> - <button>View in settings</button> - </li> - <li id="query_match_li" class="queried_pattern_match" data-template="li"> + <tr id="pattern_entry" data-template="entry"> + <td data-template="name"></td> + <td> + <div class="button" data-template="button">Add setting</div> + </td> + </tr> + + <li id="query_match_li" class="l2_li" data-template="li"> <div> <span>pattern:</span> <span class="bold" data-template="pattern"></span> - <button data-template="btn">Install</button> + <label class="button slimbutton" for="show_install_view_radio" data-template="btn"> + Install + </label> </div> <div id="unrollable_component" data-template="unroll_container"> - <span data-template="component_label">payload:</span> <input type="checkbox" class="unroll_chbx" data-template="chbx"></input> - <br data-template="br"/> - <label class="bold" data-template="lbl"> - <span data-template="triangle"> - <span class="triangle">⏵</span> - <span class="triangle">⏷</span> + <div> + <span>payload: + <label class="bold unroll_block" data-template="lbl"> + <div data-template="triangle" class="unroll_triangle"></div> + <span data-template="payload"></span> + </label> </span> - <span data-template="component"></span> + <div data-template="unroll"></div> + </div> + </div> + </li> + + <div id="injected_script" data-template="div"> + <input type="checkbox" class="unroll_chbx" data-template="chbx"></input> + <div> + <label data-template="lbl"> + <h3><div class="unroll_triangle"></div> script</h3> </label> - <div data-template="unroll"></div> + <pre data-template="script_contents"></pre> + </div> + </div> + + <div id="multi_repos_query_result" data-template="div"> + Results for <span class="bold" data-template="url_span"></span> + <ul class="l1_ul" data-template="ul"></ul> + </div> + + <li id="single_repo_query_result" class="l1_li" data-template="li"> + <div> + From <span class="bold" data-template="repo_url"></span> </div> </li> + + <ul id="result_patterns_list" class="l2_ul" data-template="ul"> + </ul> </template> - <input id="show_install_view_chbx" type="checkbox" class="show_hide_next2"></input> + <input id="show_install_view_radio" type="radio" class="show_next" name="current_view"></input> <div id="install_view"> + <div class="top has_bottom_line"><h2> Site modifiers install </h2></div> <IMPORT html/import_frame.html /> - <!-- - <div id="install_status"></div> - <label for="show_install_chbx" class="bold">Cancel install</label> - <button id="commit_install_but">Commit install</button> - --> </div> - <div id="main_view"> - <h2 id="page_url_heading"></h2> - - <input id="show_privileged_notice_chbx" type="checkbox" class="show_next"></input> - <h3>Privileged page</h3> - - <input id="show_page_state_chbx" type="checkbox" class="show_next"></input> - <div> - <input id="possible_patterns_chbx" type="checkbox" class="unroll_chbx"></input> - <span></span> - <label for="possible_patterns_chbx"> - <h3> - <span class="triangle">⏵</span> - <span class="triangle">⏷</span> - Possible patterns - </h3> - </label> - <ul id="possible_patterns"></ul> - - <input id="connected_chbx" type="checkbox" class="show_hide_next2"></input> + + <input id="show_injected_view_radio" type="radio" class="show_next" name="current_view"></input> + <div id="injected_view"> + <div class="top has_bottom_line"><h2>Injected scripts</h2></div> + <div id="container_for_injected"> + <span id="none_injected">None</span> + </div> + </div> + + <input id="show_patterns_view_radio" type="radio" class="show_next" name="current_view"></input> + <div> + <div class="top has_bottom_line"><h2>Possible patterns for this page</h2></div> + <div class="padding_inline"> + <aside> + Patterns higher are more specific and override the ones below. + </aside> + </div> + <div class="table_wrapper"> <div> - Matched pattern: <span id="pattern" class="bold">...</span> - <button id="view_pattern" class="hide"> - View in settings - </button> - <br/> - Blocked: <span id="blocked" class="bold">...</span> - <br/> - Payload: <span id="payload" class="bold">...</span> - <button id="view_payload" class="hide"> - View in settings - </button> - <h3>Injected</h3> - <div id="container_for_injected"> - <span id="none_injected">None</span> + <table> + <tbody id="possible_patterns"> + </tbody> + </table> + </div> + </div> + </div> + + <input id="show_queried_view_radio" type="radio" class="show_next" name="current_view"></input> + <div> + <div class="top has_bottom_line"><h2>Queried from repositories</h2></div> + <div id="container_for_repo_responses" class="padding_inline"> + </div> + </div> + + <input id="show_main_view_radio" type="radio" class="show_next" name="current_view" checked></input> + <div id="main_view"> + <div class="top has_bottom_line"><h2 id="page_url_heading"></h2></div> + <h3 id="privileged_notice" class="middle hide">Privileged page</h3> + + <div id="page_state" class="hide"> + <div class="header padding_inline"> + <label for="show_patterns_view_radio" class="button"> + Edit settings for this page + </label> + </div> + <div class="middle padding_inline"> + <input id="connected_chbx" type="checkbox" class="show_hide_next2"></input> + <div> + <table class="active_setting_table"> + <tbody> + <tr> + <td>Matched pattern:</td> + <td id="pattern" class="bold">...</td> + <td> + <button id="view_pattern" class="hide"> + View in settings + </button> + </td> + </tr> + <tr> + <td>Scripts blocked:</td> + <td id="blocked" class="bold">...</td> + <td></td> + </tr> + <tr> + <td>Injected payload:</td> + <td id="payload" class="bold">...</td> + <td id="payload_buttons" class="hide"> + <button id="view_payload"> View in settings </button> + <br/> + <label id="view_injected" class="button" for="show_injected_view_radio"> + View injected scripts + </label> + </td> + </tr> + </tbody> + </table> + <label id="query_pattern" for="show_queried_view_radio" class="button"> + Install scripts for this page + </label> </div> - <input id="query_started_chbx" type="checkbox" class="show_hide_next2"></input> - <div id="container_for_repo_responses"> - <h3>Queried from repositories</h3> + <div> + <h3> + Connecting to content script..<span id="loading_point">.</span> + </h3> + <aside id="reload_notice"> + Try reloading the page. + </aside> </div> - <button id="query_pattern"> - Search for matching patterns - </button> </div> - <h3>Trying to connect..<input id="loading_chbx" type="checkbox" class="show_next"></input><span>.</span></h3> </div> - <button id="settings_but" type="button" style="margin-top: 20px;">Settings</button> - </div>_POPUPSCRIPTS_ + <div class="footer padding_inline"> + <button id="settings_but" type="button"> + Open Hachette settings + </button> + </div> + </div> + + <div class="has_upper_line"></div> + + <label for="show_main_view_radio" class="back_button"><div></div></label>_POPUPSCRIPTS_ </body> </html> diff --git a/html/display-panel.js b/html/display-panel.js index 54b5578..0c89864 100644 --- a/html/display-panel.js +++ b/html/display-panel.js @@ -20,6 +20,7 @@ * IMPORT TYPE_PREFIX * IMPORT nice_name * IMPORT open_in_settings + * IMPORT url_matches * IMPORT each_url_pattern * IMPORT by_id * IMPORT get_template @@ -30,6 +31,16 @@ let storage; let tab_url; +/* Force popup <html>'s reflow on stupid Firefox. */ +if (is_mozilla) { + const reflow_forcer = + () => document.documentElement.style.width = "-moz-fit-content"; + for (const radio of document.querySelectorAll('[name="current_view"]')) + radio.addEventListener("change", reflow_forcer); +} + +const show_queried_view_radio = by_id("show_queried_view_radio"); + const tab_query = {currentWindow: true, active: true}; async function get_current_tab() @@ -48,8 +59,21 @@ async function get_current_tab() } const page_url_heading = by_id("page_url_heading"); -const show_privileged_notice_chbx = by_id("show_privileged_notice_chbx"); -const show_page_state_chbx = by_id("show_page_state_chbx"); +const privileged_notice = by_id("privileged_notice"); +const page_state = by_id("page_state"); + +/* Helper functions to convert string into a list of one-letter <span>'s. */ +function char_to_span(char, doc) +{ + const span = document.createElement("span"); + span.textContent = char; + return span; +} + +function to_spans(string, doc=document) +{ + return string.split("").map(c => char_to_span(c, doc)); +} async function show_page_activity_info() { @@ -61,69 +85,65 @@ async function show_page_activity_info() } tab_url = /^([^?#]*)/.exec(tab.url)[1]; - page_url_heading.textContent = tab_url; + to_spans(tab_url).forEach(s => page_url_heading.append(s)); if (is_privileged_url(tab_url)) { - show_privileged_notice_chbx.checked = true; + privileged_notice.classList.remove("hide"); return; } populate_possible_patterns_list(tab_url); - show_page_state_chbx.checked = true; + page_state.classList.remove("hide"); try_to_connect(tab.id); } -const possible_patterns_ul = by_id("possible_patterns"); -const pattern_li_template = get_template("pattern_li"); -pattern_li_template.removeAttribute("id"); +const possible_patterns_list = by_id("possible_patterns"); const known_patterns = new Map(); function add_pattern_to_list(pattern) { - const li = pattern_li_template.cloneNode(true); - li.id = `pattern_li_${known_patterns.size}`; - known_patterns.set(pattern, li.id); + const template = clone_template("pattern_entry"); + template.name.textContent = pattern; - const span = li.firstElementChild; - span.textContent = pattern; - - const button = span.nextElementSibling; const settings_opener = () => open_in_settings(TYPE_PREFIX.PAGE, pattern); - button.addEventListener("click", settings_opener); + template.button.addEventListener("click", settings_opener); - possible_patterns_ul.appendChild(li) + known_patterns.set(pattern, template); + possible_patterns_list.append(template.entry); - return li.id; + return template; } function ensure_pattern_exists(pattern) { - let id = known_patterns.get(pattern); + let entry_object = known_patterns.get(pattern); /* * As long as pattern computation works well, we should never get into this * conditional block. This is just a safety measure. To be removed as part * of a bigger rework when we start taking iframes into account. */ - if (id === undefined) { + if (entry_object === undefined) { console.log(`unknown pattern: ${pattern}`); - id = add_pattern_to_list(pattern); + entry_object = add_pattern_to_list(pattern); } - return id; + return entry_object; } -function set_pattern_li_button_text(li_id, text) +function style_possible_pattern_entry(pattern, exists_in_settings) { - by_id(li_id).firstElementChild.nextElementSibling.textContent = text; + const [text, class_action] = exists_in_settings ? + ["Edit", "add"] : ["Add", "remove"]; + const entry_object = ensure_pattern_exists(pattern); + + entry_object.button.textContent = `${text} setting`; + entry_object.entry.classList[class_action]("matched_pattern"); } function handle_page_change(change) { - const li_id = ensure_pattern_exists(change.item); - if (change.old_val === undefined) - set_pattern_li_button_text(li_id, "Edit in settings"); - if (change.new_val === undefined) - set_pattern_li_button_text(li_id, "Add setting"); + if (url_matches(tab_url, change.item)) + style_possible_pattern_entry(change.item, change.new_val !== undefined); } function populate_possible_patterns_list(url) @@ -131,10 +151,8 @@ function populate_possible_patterns_list(url) for (const pattern of each_url_pattern(url)) add_pattern_to_list(pattern); - for (const [pattern, settings] of query_all(storage, url)) { - set_pattern_li_button_text(ensure_pattern_exists(pattern), - "Edit in settings"); - } + for (const [pattern, settings] of query_all(storage, url)) + style_possible_pattern_entry(pattern, true); storage.add_change_listener(handle_page_change, [TYPE_PREFIX.PAGE]); } @@ -160,17 +178,16 @@ function try_to_connect(tab_id) setTimeout(() => monitor_connecting(tab_id), 1000); } -const query_started_chbx = by_id("query_started_chbx"); - -function start_querying_repos(port) +function start_querying_repos() { + query_pattern_but.removeEventListener("click", start_querying_repos); const repo_urls = storage.get_all_names(TYPE_PREFIX.REPO); if (content_script_port) content_script_port.postMessage([TYPE_PREFIX.URL, tab_url, repo_urls]); - query_started_chbx.checked = true; } -const loading_chbx = by_id("loading_chbx"); +const loading_point = by_id("loading_point"); +const reload_notice = by_id("reload_notice"); function handle_disconnect(tab_id, button_cb) { @@ -184,7 +201,9 @@ function handle_disconnect(tab_id, button_cb) if (connected_chbx.checked) return; - loading_chbx.checked = !loading_chbx.checked; + loading_point.classList.toggle("camouflage"); + reload_notice.classList.remove("hide"); + setTimeout(() => try_to_connect(tab_id), 1000); } @@ -198,7 +217,8 @@ function monitor_connecting(tab_id) else return; - loading_chbx.checked = !loading_chbx.checked; + loading_point.classList.toggle("camouflage"); + reload_notice.classList.remove("hide"); try_to_connect(tab_id); } @@ -206,11 +226,15 @@ const pattern_span = by_id("pattern"); const view_pattern_but = by_id("view_pattern"); const blocked_span = by_id("blocked"); const payload_span = by_id("payload"); +const payload_buttons_div = by_id("payload_buttons"); const view_payload_but = by_id("view_payload"); +const view_injected_but = by_id("view_injected"); const container_for_injected = by_id("container_for_injected"); const queried_items = new Map(); +let max_injected_script_id = 0; + function handle_activity_report(message) { connected_chbx.checked = true; @@ -236,25 +260,22 @@ function handle_activity_report(message) const components = settings.components; if (components) { payload_span.textContent = nice_name(...components); + payload_buttons_div.classList.remove("hide"); const settings_opener = () => open_in_settings(...components); - view_payload_but.classList.remove("hide"); view_payload_but.addEventListener("click", settings_opener); } else { payload_span.textContent = "none"; } } if (type === "script") { - const h4 = document.createElement("h4"); - const pre = document.createElement("pre"); - h4.textContent = "script"; - pre.textContent = data; - - container_for_injected.appendChild(h4); - container_for_injected.appendChild(pre); + const template = clone_template("injected_script"); + const chbx_id = `injected_script_${max_injected_script_id++}`; + template.chbx.id = chbx_id; + template.lbl.setAttribute("for", chbx_id); + template.script_contents.textContent = data; + container_for_injected.appendChild(template.div); } if (type === "repo_query_action") { - query_started_chbx.checked = true; - const key = data.prefix + data.item; const results = queried_items.get(key) || {}; Object.assign(results, data.results); @@ -274,35 +295,26 @@ const results_lists = new Map(); function create_results_list(url) { - const list_div = document.createElement("div"); - const list_head = document.createElement("h4"); - const list = document.createElement("ul"); + const cloned_template = clone_template("multi_repos_query_result"); + cloned_template.url_span.textContent = url; + container_for_repo_responses.appendChild(cloned_template.div); - list_head.textContent = url; - list_div.appendChild(list_head); - list_div.appendChild(list); - container_for_repo_responses.appendChild(list_div); + cloned_template.by_repo = new Map(); + results_lists.set(url, cloned_template); - const list_object = {list, by_repo: new Map()}; - - results_lists.set(url, list_object); - - return list_object; + return cloned_template; } function create_result_item(list_object, repo_url, result) { - const result_li = document.createElement("li"); - const repo_url_span = document.createElement("span"); - const result_item = {result_li, appended: null}; - - repo_url_span.textContent = repo_url; - result_li.appendChild(repo_url_span); + const cloned_template = clone_template("single_repo_query_result"); + cloned_template.repo_url.textContent = repo_url; + cloned_template.appended = null; - list_object.list.appendChild(result_li); - list_object.by_repo.set(repo_url, result_item); + list_object.ul.appendChild(cloned_template.li); + list_object.by_repo.set(repo_url, cloned_template); - return result_item; + return cloned_template; } function set_appended(result_item, element) @@ -310,7 +322,7 @@ function set_appended(result_item, element) if (result_item.appended) result_item.appended.remove(); result_item.appended = element; - result_item.result_li.appendChild(element); + result_item.li.appendChild(element); } function show_message(result_item, text) @@ -333,11 +345,9 @@ function unroll_chbx_first_checked(entry_object) entry_object.chbx.removeEventListener("change", entry_object.unroll_cb); delete entry_object.unroll_cb; - entry_object.unroll.textContent = "preview not implemented..."; + entry_object.unroll.innerHTML = "preview not implemented...<br />(consider contributing)"; } -const show_install_chbx = by_id("show_install_view_chbx"); - let import_frame; let install_target = null; @@ -463,7 +473,6 @@ function record_fetched_install_dep(prefix, item, repo_url, result) function install_clicked(entry_object) { - show_install_chbx.checked = true; import_frame.show_loading(); install_target = { @@ -483,25 +492,24 @@ var max_query_result_id = 0; function show_query_successful_result(result_item, repo_url, result) { - const ul = document.createElement("ul"); - - set_appended(result_item, ul); + const cloned_ul_template = clone_template("result_patterns_list"); + set_appended(result_item, cloned_ul_template.ul); for (const match of result) { const entry_object = clone_template("query_match_li"); entry_object.pattern.textContent = match.pattern; - ul.appendChild(entry_object.li); + cloned_ul_template.ul.appendChild(entry_object.li); if (!match.payload) { entry_object.payload.textContent = "(none)"; - for (const key of ["chbx", "br", "triangle", "unroll"]) + for (const key of ["chbx", "triangle", "unroll"]) entry_object[key].remove(); continue; } - entry_object.component.textContent = nice_name(...match.payload); + entry_object.payload.textContent = nice_name(...match.payload); const install_cb = () => install_clicked(entry_object); entry_object.btn.addEventListener("click", install_cb); @@ -544,7 +552,7 @@ async function main() { storage = await get_remote_storage(); import_frame = await get_import_frame(); - import_frame.onclose = () => show_install_chbx.checked = false; + import_frame.onclose = () => show_queried_view_radio.checked = true; show_page_activity_info(); } diff --git a/html/import_frame.html b/html/import_frame.html index 0511e6c..835977d 100644 --- a/html/import_frame.html +++ b/html/import_frame.html @@ -5,7 +5,6 @@ <span></span> </li> </template> -<h2> Settings import </h2> <input id="import_loading_radio" type="radio" name="import_window_content" class="show_next"></input> <span> Loading... </span> <input id="import_failed_radio" type="radio" name="import_window_content" class="show_next"></input> diff --git a/html/options.html b/html/options.html index e0c3c23..13a8973 100644 --- a/html/options.html +++ b/html/options.html @@ -9,11 +9,9 @@ <title>Hachette options</title> <link type="text/css" rel="stylesheet" href="reset.css" /> <link type="text/css" rel="stylesheet" href="base.css" /> + <link type="text/css" rel="stylesheet" href="table.css" /> <style> body { - background-color: #f0f0f0; - color: #555; - overflow: auto; width: 100%; } @@ -37,6 +35,10 @@ font-size: 130%; padding: 10px; display: inline-block; + cursor: pointer; + } + + #tab_heads { -moz-user-select: none; user-select: none; } @@ -49,13 +51,6 @@ border-radius: 0; } - #tab_heads::after { - display: block; - height: 8px; - content: ""; - background: linear-gradient(#555, transparent); - } - div.tab { min-width: 50vw; width: fit-content; @@ -86,77 +81,36 @@ width: fit-content; } - div.ul_container { - background-color: #f0f0f0; - width: -moz-fit-content; - width: fit-content; - margin: 6px 0; - } - - div.ul_container::after, div.ul_container::before { - display: block; - height: 6px; - content: ""; - background: linear-gradient(transparent, #555); - } - - div.ul_container::after { - background: linear-gradient(#555, transparent); - } - - .work_li div.ul_container::before { + .work_li .table_wrapper::before { background: linear-gradient(#e0f0f0, #555); } - .work_li div.ul_container::after { + .work_li .table_wrapper::after { background: linear-gradient(#555, #e0f0f0); } - div.ul_container>.always_scrollbar{ + .table_wrapper>.always_scrollbar{ border-left: solid #454 8px; max-height: 80vh; overflow-y: scroll; } - div.ul_container table { - border-collapse: unset; - } - - div.ul_container, div.ul_container>*, div.ul_container table>tbody { - width: -moz-min-content; - width: min-content; - } - - div.ul_container div.ul_container>.always_scrollbar, - .popup_frame div.ul_container>.always_scrollbar { + .table_wrapper .table_wrapper>.always_scrollbar, + .popup_frame .table_wrapper>.always_scrollbar { max-height: 60vh; } - .popup_frame div.ul_container table { + .popup_frame .table_wrapper table { min-width: 30vw; } - .popup_frame div.ul_container { + .popup_frame .table_wrapper { margin: 0 auto; } - tr:nth-child(odd) { - background-color: #e5e5e5; - } - - td { - vertical-align: middle; - min-width: fit-content; - min-width: -moz-fit-content; - width: 1%; - } - tr>td:first-child { - padding: 3px 10px 6px; max-width: 70vw; overflow: hidden; - width: 100%; - white-space: nowrap; } tr.work_li>td:first-child { @@ -198,14 +152,6 @@ min-width: 70vw; resize: none; } - - td>div.button { - margin-right: 4px; - } - - input[type="radio"]:not(:checked)+.import_window_content { - display: none; - } </style> </head> <body> @@ -239,7 +185,7 @@ <input type="radio" name="tabs" id="show_pages" checked></input> <input type="radio" name="tabs" id="show_bags"></input> <input type="radio" name="tabs" id="show_scripts"></input> - <div id="tab_heads"> + <div id="tab_heads" class="has_bottom_line"> <label for="show_repos" id="repos_lbl"> Repos </label> <label for="show_pages" id="pages_lbl"> Pages </label> <label for="show_bags" id="bags_lbl"> Bags </label> @@ -247,7 +193,7 @@ <button id="import_but" style="margin-left: 40px;"> Import </button> </div> <div id="repos" class="tab"> - <div class="ul_container"> + <div class="table_wrapper tight_table has_bottom_line has_upper_line"> <div> <table> <tbody id="repos_ul"> @@ -270,7 +216,7 @@ <button id="add_repo_but" type="button"> Add repository </button> </div> <div id="pages" class="tab"> - <div class="ul_container"> + <div class="table_wrapper tight_table has_bottom_line has_upper_line"> <div> <table> <tbody id="pages_ul"> @@ -304,7 +250,7 @@ <button id="add_page_but" type="button"> Add page </button> </div> <div id="bags" class="tab"> - <div class="ul_container"> + <div class="table_wrapper tight_table has_bottom_line has_upper_line"> <div> <table> <tbody id="bags_ul"> @@ -313,7 +259,7 @@ <div class="form_grid"> <label for="bag_name_field"> Name: </label> <input id="bag_name_field"></input> - <div class="ul_container"> + <div class="table_wrapper tight_table has_bottom_line has_upper_line"> <div> <table> <tbody id="bag_components_ul"> @@ -341,7 +287,7 @@ <button id="add_bag_but" type="button"> Add bag </button> </div> <div id="scripts" class="tab"> - <div class="ul_container"> + <div class="table_wrapper tight_table has_bottom_line has_upper_line"> <div> <table> <tbody id="scripts_ul"> @@ -375,7 +321,7 @@ <div id="chbx_components_window" class="hide popup" position="absolute"> <div class="popup_frame"> - <div class="ul_container"> + <div class="table_wrapper tight_table has_bottom_line has_upper_line"> <div> <table> <tbody id="chbx_components_ul"> @@ -390,7 +336,7 @@ <div id="radio_components_window" class="hide popup" position="absolute"> <div class="popup_frame"> - <div class="ul_container"> + <div class="table_wrapper tight_table has_bottom_line has_upper_line"> <div class="always_scrollbar"> <table> <tbody id="radio_components_ul"> @@ -411,6 +357,7 @@ <div id="import_window" class="hide popup" position="absolute"> <div class="popup_frame"> + <h2> Settings import </h2> <IMPORT html/import_frame.html /> </div> </div> diff --git a/html/options_main.js b/html/options_main.js index 8067fe7..03505a5 100644 --- a/html/options_main.js +++ b/html/options_main.js @@ -77,8 +77,12 @@ function add_li(prefix, item, at_the_end=false) break; } } - if (!li.parentElement) - ul.ul.appendChild(li); + if (!li.parentElement) { + if (ul.work_li !== ul.ul.lastElementChild) + ul.ul.appendChild(li); + else + ul.work_li.before(li); + } list_set_scrollbar(ul.ul); } diff --git a/html/table.css b/html/table.css new file mode 100644 index 0000000..6296f83 --- /dev/null +++ b/html/table.css @@ -0,0 +1,46 @@ +.table_wrapper { + display: block; + background-color: #f0f0f0; + margin: 6px 0; +} + +.table_wrapper table { + border-collapse: unset; + width: 100%; +} + +.table_wrapper.tight_table, +.table_wrapper.tight_table>*, +.table_wrapper.tight_table>*>table { + width: -moz-min-content; + width: min-content; +} + +tr:nth-child(odd) { + background-color: #e5e5e5; +} + +td { + vertical-align: middle; + min-width: fit-content; + min-width: -moz-fit-content; +} + +.tight_table td { + width: 1%; +} + +td:first-child { + padding: 3px 10px 6px; + white-space: nowrap; +} + +.tight_table td:first-child { + width: 100%; +} + +td>div.button { + margin-right: 4px; + white-space: nowrap; + float: right; +} |