diff options
Diffstat (limited to 'html/options_main.js')
-rw-r--r-- | html/options_main.js | 1262 |
1 files changed, 631 insertions, 631 deletions
diff --git a/html/options_main.js b/html/options_main.js index ef01e60..6f203fa 100644 --- a/html/options_main.js +++ b/html/options_main.js @@ -5,746 +5,746 @@ * Redistribution terms are gathered in the `copyright' file. */ -"use strict"; - -(() => { - const get_storage = window.get_storage; - const TYPE_PREFIX = window.TYPE_PREFIX; - const TYPE_NAME = window.TYPE_NAME; - const list_prefixes = window.list_prefixes; - - var storage; - function by_id(id) - { - return document.getElementById(id); - } - - function nice_name(prefix, name) - { - return `${name} (${TYPE_NAME[prefix]})`; - } - - const item_li_template = by_id("item_li_template"); - const bag_component_li_template = by_id("bag_component_li_template"); - const chbx_component_li_template = by_id("chbx_component_li_template"); - const radio_component_li_template = by_id("radio_component_li_template"); - const import_li_template = by_id("import_li_template"); - /* Make sure they are later cloned without id. */ - item_li_template.removeAttribute("id"); - bag_component_li_template.removeAttribute("id"); - chbx_component_li_template.removeAttribute("id"); - radio_component_li_template.removeAttribute("id"); - import_li_template.removeAttribute("id"); - - function item_li_id(prefix, item) - { - return `li_${prefix}_${item}`; - } - - /* Insert into list of bags/pages/scripts */ - function add_li(prefix, item, at_the_end=false) - { - let ul = ul_by_prefix[prefix]; - let li = item_li_template.cloneNode(true); - li.id = item_li_id(prefix, item); - - let span = li.firstElementChild; - span.textContent = item; - - let edit_button = span.nextElementSibling; - edit_button.addEventListener("click", () => edit_item(prefix, item)); - - let remove_button = edit_button.nextElementSibling; - remove_button.addEventListener("click", - () => storage.remove(prefix, item)); - - let export_button = remove_button.nextElementSibling; - export_button.addEventListener("click", - () => export_item(prefix, item)); +/* + * IMPORTS_START + * IMPORT get_remote_storage + * IMPORT TYPE_PREFIX + * IMPORT TYPE_NAME + * IMPORT list_prefixes + * IMPORTS_END + */ - if (!at_the_end) { - for (let element of ul.ul.children) { - if (element.id < li.id || element.id.startsWith("work_")) - continue; +var storage; +function by_id(id) +{ + return document.getElementById(id); +} + +function nice_name(prefix, name) +{ + return `${name} (${TYPE_NAME[prefix]})`; +} + +const item_li_template = by_id("item_li_template"); +const bag_component_li_template = by_id("bag_component_li_template"); +const chbx_component_li_template = by_id("chbx_component_li_template"); +const radio_component_li_template = by_id("radio_component_li_template"); +const import_li_template = by_id("import_li_template"); +/* Make sure they are later cloned without id. */ +item_li_template.removeAttribute("id"); +bag_component_li_template.removeAttribute("id"); +chbx_component_li_template.removeAttribute("id"); +radio_component_li_template.removeAttribute("id"); +import_li_template.removeAttribute("id"); + +function item_li_id(prefix, item) +{ + return `li_${prefix}_${item}`; +} + +/* Insert into list of bags/pages/scripts */ +function add_li(prefix, item, at_the_end=false) +{ + let ul = ul_by_prefix[prefix]; + let li = item_li_template.cloneNode(true); + li.id = item_li_id(prefix, item); + + let span = li.firstElementChild; + span.textContent = item; + + let edit_button = span.nextElementSibling; + edit_button.addEventListener("click", () => edit_item(prefix, item)); + + let remove_button = edit_button.nextElementSibling; + remove_button.addEventListener("click", + () => storage.remove(prefix, item)); + + let export_button = remove_button.nextElementSibling; + export_button.addEventListener("click", + () => export_item(prefix, item)); + + if (!at_the_end) { + for (let element of ul.ul.children) { + if (element.id < li.id || element.id.startsWith("work_")) + continue; - ul.ul.insertBefore(li, element); - return; - } + ul.ul.insertBefore(li, element); + return; } - - ul.ul.appendChild(li); } - const chbx_components_ul = by_id("chbx_components_ul"); - const radio_components_ul = by_id("radio_components_ul"); + ul.ul.appendChild(li); +} - function chbx_li_id(prefix, item) - { - return `cli_${prefix}_${item}`; - } +const chbx_components_ul = by_id("chbx_components_ul"); +const radio_components_ul = by_id("radio_components_ul"); - function radio_li_id(prefix, item) - { - return `rli_${prefix}_${item}`; - } +function chbx_li_id(prefix, item) +{ + return `cli_${prefix}_${item}`; +} - //TODO: refactor the 2 functions below +function radio_li_id(prefix, item) +{ + return `rli_${prefix}_${item}`; +} - function add_chbx_li(prefix, name) - { - if (prefix === TYPE_PREFIX.PAGE) - return; +//TODO: refactor the 2 functions below - let li = chbx_component_li_template.cloneNode(true); - li.id = chbx_li_id(prefix, name); - li.setAttribute("data-prefix", prefix); - li.setAttribute("data-name", name); - - let chbx = li.firstElementChild; - let span = chbx.nextElementSibling; - - span.textContent = nice_name(prefix, name); - - chbx_components_ul.appendChild(li); - } - - var radio_component_none_li = by_id("radio_component_none_li"); +function add_chbx_li(prefix, name) +{ + if (prefix === TYPE_PREFIX.PAGE) + return; - function add_radio_li(prefix, name) - { - if (prefix === TYPE_PREFIX.PAGE) - return; + let li = chbx_component_li_template.cloneNode(true); + li.id = chbx_li_id(prefix, name); + li.setAttribute("data-prefix", prefix); + li.setAttribute("data-name", name); - let li = radio_component_li_template.cloneNode(true); - li.id = radio_li_id(prefix, name); - li.setAttribute("data-prefix", prefix); - li.setAttribute("data-name", name); + let chbx = li.firstElementChild; + let span = chbx.nextElementSibling; - let radio = li.firstElementChild; - let span = radio.nextElementSibling; + span.textContent = nice_name(prefix, name); - span.textContent = nice_name(prefix, name); + chbx_components_ul.appendChild(li); +} - radio_components_ul.insertBefore(li, radio_component_none_li); - } - - const page_payload_span = by_id("page_payload"); - - function set_page_components(components) - { - if (components === undefined) { - page_payload_span.setAttribute("data-payload", "no"); - page_payload_span.textContent = "(None)"; - } else { - page_payload_span.setAttribute("data-payload", "yes"); - let [prefix, name] = components; - page_payload_span.setAttribute("data-prefix", prefix); - page_payload_span.setAttribute("data-name", name); - page_payload_span.textContent = nice_name(prefix, name); - } - } +var radio_component_none_li = by_id("radio_component_none_li"); - const page_allow_chbx = by_id("page_allow_chbx"); +function add_radio_li(prefix, name) +{ + if (prefix === TYPE_PREFIX.PAGE) + return; - /* Used to reset edited page. */ - function reset_work_page_li(ul, item, settings) - { - ul.work_name_input.value = maybe_string(item); - settings = settings || {allow: false, components: undefined}; - page_allow_chbx.checked = !!settings.allow; + let li = radio_component_li_template.cloneNode(true); + li.id = radio_li_id(prefix, name); + li.setAttribute("data-prefix", prefix); + li.setAttribute("data-name", name); - set_page_components(settings.components); - } + let radio = li.firstElementChild; + let span = radio.nextElementSibling; - function work_page_li_components() - { - if (page_payload_span.getAttribute("data-payload") === "no") - return undefined; + span.textContent = nice_name(prefix, name); - let prefix = page_payload_span.getAttribute("data-prefix"); - let name = page_payload_span.getAttribute("data-name"); - return [prefix, name]; - } + radio_components_ul.insertBefore(li, radio_component_none_li); +} - /* Used to get edited page data for saving. */ - function work_page_li_data(ul) - { - let url = ul.work_name_input.value; - let settings = { - components : work_page_li_components(), - allow : !!page_allow_chbx.checked - }; +const page_payload_span = by_id("page_payload"); - return [url, settings]; +function set_page_components(components) +{ + if (components === undefined) { + page_payload_span.setAttribute("data-payload", "no"); + page_payload_span.textContent = "(None)"; + } else { + page_payload_span.setAttribute("data-payload", "yes"); + let [prefix, name] = components; + page_payload_span.setAttribute("data-prefix", prefix); + page_payload_span.setAttribute("data-name", name); + page_payload_span.textContent = nice_name(prefix, name); } +} - const empty_bag_component_li = by_id("empty_bag_component_li"); - var bag_components_ul = by_id("bag_components_ul"); - - /* Used to construct and update components list of edited bag. */ - function add_bag_components(components) - { - for (let component of components) { - let [prefix, name] = component; - let li = bag_component_li_template.cloneNode(true); - li.setAttribute("data-prefix", prefix); - li.setAttribute("data-name", name); - let span = li.firstElementChild; - span.textContent = nice_name(prefix, name); - let remove_but = span.nextElementSibling; - remove_but.addEventListener("click", () => - bag_components_ul.removeChild(li)); - bag_components_ul.appendChild(li); - } - - bag_components_ul.appendChild(empty_bag_component_li); - } +const page_allow_chbx = by_id("page_allow_chbx"); - /* Used to reset edited bag. */ - function reset_work_bag_li(ul, item, components) - { - components = components || []; +/* Used to reset edited page. */ +function reset_work_page_li(ul, item, settings) +{ + ul.work_name_input.value = maybe_string(item); + settings = settings || {allow: false, components: undefined}; + page_allow_chbx.checked = !!settings.allow; - ul.work_name_input.value = maybe_string(item); - let old_components_ul = bag_components_ul; - bag_components_ul = old_components_ul.cloneNode(false); + set_page_components(settings.components); +} - ul.work_li.insertBefore(bag_components_ul, old_components_ul); - ul.work_li.removeChild(old_components_ul); +function work_page_li_components() +{ + if (page_payload_span.getAttribute("data-payload") === "no") + return undefined; - add_bag_components(components); - } + let prefix = page_payload_span.getAttribute("data-prefix"); + let name = page_payload_span.getAttribute("data-name"); + return [prefix, name]; +} - /* Used to get edited bag data for saving. */ - function work_bag_li_data(ul) - { - let components_ul = ul.work_name_input.nextElementSibling; - let component_li = components_ul.firstElementChild; +/* Used to get edited page data for saving. */ +function work_page_li_data(ul) +{ + let url = ul.work_name_input.value; + let settings = { + components : work_page_li_components(), + allow : !!page_allow_chbx.checked + }; - let components = []; + return [url, settings]; +} - /* Last list element is empty li with id set. */ - while (component_li.id === '') { - components.push([component_li.getAttribute("data-prefix"), - component_li.getAttribute("data-name")]); - component_li = component_li.nextElementSibling; - } +const empty_bag_component_li = by_id("empty_bag_component_li"); +var bag_components_ul = by_id("bag_components_ul"); - return [ul.work_name_input.value, components]; +/* Used to construct and update components list of edited bag. */ +function add_bag_components(components) +{ + for (let component of components) { + let [prefix, name] = component; + let li = bag_component_li_template.cloneNode(true); + li.setAttribute("data-prefix", prefix); + li.setAttribute("data-name", name); + let span = li.firstElementChild; + span.textContent = nice_name(prefix, name); + let remove_but = span.nextElementSibling; + remove_but.addEventListener("click", () => + bag_components_ul.removeChild(li)); + bag_components_ul.appendChild(li); } - const script_url_input = by_id("script_url_field"); - const script_sha256_input = by_id("script_sha256_field"); - const script_contents_field = by_id("script_contents_field"); + bag_components_ul.appendChild(empty_bag_component_li); +} - function maybe_string(maybe_defined) - { - return maybe_defined === undefined ? "" : maybe_defined + ""; - } +/* Used to reset edited bag. */ +function reset_work_bag_li(ul, item, components) +{ + components = components || []; - /* Used to reset edited script. */ - function reset_work_script_li(ul, name, data) - { - ul.work_name_input.value = maybe_string(name); - if (data === undefined) - data = {}; - script_url_input.value = maybe_string(data.url); - script_sha256_input.value = maybe_string(data.hash); - script_contents_field.value = maybe_string(data.text); - } + ul.work_name_input.value = maybe_string(item); + let old_components_ul = bag_components_ul; + bag_components_ul = old_components_ul.cloneNode(false); - /* Used to get edited script data for saving. */ - function work_script_li_data(ul) - { - return [ul.work_name_input.value, { - url : script_url_input.value, - hash : script_sha256_input.value, - text : script_contents_field.value - }]; - } + ul.work_li.insertBefore(bag_components_ul, old_components_ul); + ul.work_li.removeChild(old_components_ul); - function cancel_work(prefix) - { - let ul = ul_by_prefix[prefix]; + add_bag_components(components); +} - if (ul.state === UL_STATE.IDLE) - return; +/* Used to get edited bag data for saving. */ +function work_bag_li_data(ul) +{ + let components_ul = ul.work_name_input.nextElementSibling; + let component_li = components_ul.firstElementChild; - if (ul.state === UL_STATE.EDITING_ENTRY) { - add_li(prefix, ul.edited_item); - } + let components = []; - ul.work_li.classList.add("hide"); - ul.state = UL_STATE.IDLE; + /* Last list element is empty li with id set. */ + while (component_li.id === '') { + components.push([component_li.getAttribute("data-prefix"), + component_li.getAttribute("data-name")]); + component_li = component_li.nextElementSibling; } - function save_work(prefix) - { - let ul = ul_by_prefix[prefix]; + return [ul.work_name_input.value, components]; +} - if (ul.state === UL_STATE.IDLE) - return; +const script_url_input = by_id("script_url_field"); +const script_sha256_input = by_id("script_sha256_field"); +const script_contents_field = by_id("script_contents_field"); - let [item, data] = ul.get_work_li_data(ul); +function maybe_string(maybe_defined) +{ + return maybe_defined === undefined ? "" : maybe_defined + ""; +} - /* Here we fire promises and return without waiting. */ +/* Used to reset edited script. */ +function reset_work_script_li(ul, name, data) +{ + ul.work_name_input.value = maybe_string(name); + if (data === undefined) + data = {}; + script_url_input.value = maybe_string(data.url); + script_sha256_input.value = maybe_string(data.hash); + script_contents_field.value = maybe_string(data.text); +} - if (ul.state === UL_STATE.EDITING_ENTRY) - storage.replace(prefix, ul.edited_item, item, data); - if (ul.state === UL_STATE.ADDING_ENTRY) - storage.set(prefix, item, data); +/* Used to get edited script data for saving. */ +function work_script_li_data(ul) +{ + return [ul.work_name_input.value, { + url : script_url_input.value, + hash : script_sha256_input.value, + text : script_contents_field.value + }]; +} - cancel_work(prefix); - } +function cancel_work(prefix) +{ + let ul = ul_by_prefix[prefix]; - function edit_item(prefix, item) - { - cancel_work(prefix); + if (ul.state === UL_STATE.IDLE) + return; - let ul = ul_by_prefix[prefix]; - let li = by_id(item_li_id(prefix, item)); - ul.reset_work_li(ul, item, storage.get(prefix, item)); - ul.ul.insertBefore(ul.work_li, li); - ul.ul.removeChild(li); - ul.work_li.classList.remove("hide"); - - ul.state = UL_STATE.EDITING_ENTRY; - ul.edited_item = item; + if (ul.state === UL_STATE.EDITING_ENTRY) { + add_li(prefix, ul.edited_item); } - const file_downloader = by_id("file_downloader"); + ul.work_li.classList.add("hide"); + ul.state = UL_STATE.IDLE; +} - function recursively_export_item(prefix, name, added_items, items_data) - { - let key = prefix + name; +function save_work(prefix) +{ + let ul = ul_by_prefix[prefix]; - if (added_items.has(key)) - return; + if (ul.state === UL_STATE.IDLE) + return; - let data = storage.get(prefix, name); - if (data === undefined) { - console.log(`${TYPE_NAME[prefix]} '${name}' for export not found`); - return; - } + let [item, data] = ul.get_work_li_data(ul); - if (prefix !== TYPE_PREFIX.SCRIPT) { - let components = prefix === TYPE_PREFIX.BAG ? - data : [data.components]; + /* Here we fire promises and return without waiting. */ - for (let [comp_prefix, comp_name] of components) { - recursively_export_item(comp_prefix, comp_name, - added_items, items_data); - } - } + if (ul.state === UL_STATE.EDITING_ENTRY) + storage.replace(prefix, ul.edited_item, item, data); + if (ul.state === UL_STATE.ADDING_ENTRY) + storage.set(prefix, item, data); - items_data.push({[key]: data}); - added_items.add(key); - } + cancel_work(prefix); +} - function export_item(prefix, name) - { - let added_items = new Set(); - let items_data = []; - recursively_export_item(prefix, name, added_items, items_data); - let file = new Blob([JSON.stringify(items_data)], - {type: "application/json"}); - let url = URL.createObjectURL(file); - file_downloader.setAttribute("href", url); - file_downloader.setAttribute("download", prefix + name + ".json"); - file_downloader.click(); - file_downloader.removeAttribute("href"); - URL.revokeObjectURL(url); - } +function edit_item(prefix, item) +{ + cancel_work(prefix); - function add_new_item(prefix) - { - cancel_work(prefix); + let ul = ul_by_prefix[prefix]; + let li = by_id(item_li_id(prefix, item)); + ul.reset_work_li(ul, item, storage.get(prefix, item)); + ul.ul.insertBefore(ul.work_li, li); + ul.ul.removeChild(li); + ul.work_li.classList.remove("hide"); - let ul = ul_by_prefix[prefix]; - ul.reset_work_li(ul); - ul.work_li.classList.remove("hide"); - ul.ul.appendChild(ul.work_li); + ul.state = UL_STATE.EDITING_ENTRY; + ul.edited_item = item; +} - ul.state = UL_STATE.ADDING_ENTRY; - } +const file_downloader = by_id("file_downloader"); - const chbx_components_window = by_id("chbx_components_window"); +function recursively_export_item(prefix, name, added_items, items_data) +{ + let key = prefix + name; - function bag_components() - { - chbx_components_window.classList.remove("hide"); - radio_components_window.classList.add("hide"); + if (added_items.has(key)) + return; - for (let li of chbx_components_ul.children) { - let chbx = li.firstElementChild; - chbx.checked = false; - } + let data = storage.get(prefix, name); + if (data === undefined) { + console.log(`${TYPE_NAME[prefix]} '${name}' for export not found`); + return; } - function commit_bag_components() - { - let selected = []; - - for (let li of chbx_components_ul.children) { - let chbx = li.firstElementChild; - if (!chbx.checked) - continue; - - selected.push([li.getAttribute("data-prefix"), - li.getAttribute("data-name")]); + if (prefix !== TYPE_PREFIX.SCRIPT) { + let components = prefix === TYPE_PREFIX.BAG ? + data : [data.components]; + + for (let [comp_prefix, comp_name] of components) { + recursively_export_item(comp_prefix, comp_name, + added_items, items_data); } - - add_bag_components(selected); - cancel_components(); } - const radio_components_window = by_id("radio_components_window"); - var radio_component_none_input = by_id("radio_component_none_input"); - - function page_components() - { - radio_components_window.classList.remove("hide"); - chbx_components_window.classList.add("hide"); + items_data.push({[key]: data}); + added_items.add(key); +} + +function export_item(prefix, name) +{ + let added_items = new Set(); + let items_data = []; + recursively_export_item(prefix, name, added_items, items_data); + let file = new Blob([JSON.stringify(items_data)], + {type: "application/json"}); + let url = URL.createObjectURL(file); + file_downloader.setAttribute("href", url); + file_downloader.setAttribute("download", prefix + name + ".json"); + file_downloader.click(); + file_downloader.removeAttribute("href"); + URL.revokeObjectURL(url); +} + +function add_new_item(prefix) +{ + cancel_work(prefix); + + let ul = ul_by_prefix[prefix]; + ul.reset_work_li(ul); + ul.work_li.classList.remove("hide"); + ul.ul.appendChild(ul.work_li); + + ul.state = UL_STATE.ADDING_ENTRY; +} + +const chbx_components_window = by_id("chbx_components_window"); + +function bag_components() +{ + chbx_components_window.classList.remove("hide"); + radio_components_window.classList.add("hide"); + + for (let li of chbx_components_ul.children) { + let chbx = li.firstElementChild; + chbx.checked = false; + } +} - radio_component_none_input.checked = true; +function commit_bag_components() +{ + let selected = []; - let components = work_page_li_components(); - if (components === undefined) - return; + for (let li of chbx_components_ul.children) { + let chbx = li.firstElementChild; + if (!chbx.checked) + continue; - let [prefix, item] = components; - let li = by_id(radio_li_id(prefix, item)); - if (li === null) - radio_component_none_input.checked = false; - else - li.firstElementChild.checked = true; + selected.push([li.getAttribute("data-prefix"), + li.getAttribute("data-name")]); } - function commit_page_components() - { - let components = null; + add_bag_components(selected); + cancel_components(); +} - for (let li of radio_components_ul.children) { - let radio = li.firstElementChild; - if (!radio.checked) - continue; +const radio_components_window = by_id("radio_components_window"); +var radio_component_none_input = by_id("radio_component_none_input"); - components = [li.getAttribute("data-prefix"), - li.getAttribute("data-name")]; +function page_components() +{ + radio_components_window.classList.remove("hide"); + chbx_components_window.classList.add("hide"); - if (radio.id === "radio_component_none_input") - components = undefined; + radio_component_none_input.checked = true; - break; - } + let components = work_page_li_components(); + if (components === undefined) + return; - if (components !== null) - set_page_components(components); - cancel_components(); - } + let [prefix, item] = components; + let li = by_id(radio_li_id(prefix, item)); + if (li === null) + radio_component_none_input.checked = false; + else + li.firstElementChild.checked = true; +} - function cancel_components() - { - chbx_components_window.classList.add("hide"); - radio_components_window.classList.add("hide"); - } +function commit_page_components() +{ + let components = null; - const UL_STATE = { - EDITING_ENTRY : 0, - ADDING_ENTRY : 1, - IDLE : 2 - }; - - const ul_by_prefix = { - [TYPE_PREFIX.PAGE] : { - ul : by_id("pages_ul"), - work_li : by_id("work_page_li"), - work_name_input : by_id("page_url_field"), - reset_work_li : reset_work_page_li, - get_work_li_data : work_page_li_data, - select_components : page_components, - commit_components : commit_page_components, - state : UL_STATE.IDLE, - edited_item : undefined, - }, - [TYPE_PREFIX.BAG] : { - ul : by_id("bags_ul"), - work_li : by_id("work_bag_li"), - work_name_input : by_id("bag_name_field"), - reset_work_li : reset_work_bag_li, - get_work_li_data : work_bag_li_data, - select_components : bag_components, - commit_components : commit_bag_components, - state : UL_STATE.IDLE, - edited_item : undefined, - }, - [TYPE_PREFIX.SCRIPT] : { - ul : by_id("scripts_ul"), - work_li : by_id("work_script_li"), - work_name_input : by_id("script_name_field"), - reset_work_li : reset_work_script_li, - get_work_li_data : work_script_li_data, - state : UL_STATE.IDLE, - edited_item : undefined, - } - } + for (let li of radio_components_ul.children) { + let radio = li.firstElementChild; + if (!radio.checked) + continue; + + components = [li.getAttribute("data-prefix"), + li.getAttribute("data-name")]; + + if (radio.id === "radio_component_none_input") + components = undefined; + + break; + } + + if (components !== null) + set_page_components(components); + cancel_components(); +} + +function cancel_components() +{ + chbx_components_window.classList.add("hide"); + radio_components_window.classList.add("hide"); +} + +const UL_STATE = { + EDITING_ENTRY : 0, + ADDING_ENTRY : 1, + IDLE : 2 +}; + +const ul_by_prefix = { + [TYPE_PREFIX.PAGE] : { + ul : by_id("pages_ul"), + work_li : by_id("work_page_li"), + work_name_input : by_id("page_url_field"), + reset_work_li : reset_work_page_li, + get_work_li_data : work_page_li_data, + select_components : page_components, + commit_components : commit_page_components, + state : UL_STATE.IDLE, + edited_item : undefined, + }, + [TYPE_PREFIX.BAG] : { + ul : by_id("bags_ul"), + work_li : by_id("work_bag_li"), + work_name_input : by_id("bag_name_field"), + reset_work_li : reset_work_bag_li, + get_work_li_data : work_bag_li_data, + select_components : bag_components, + commit_components : commit_bag_components, + state : UL_STATE.IDLE, + edited_item : undefined, + }, + [TYPE_PREFIX.SCRIPT] : { + ul : by_id("scripts_ul"), + work_li : by_id("work_script_li"), + work_name_input : by_id("script_name_field"), + reset_work_li : reset_work_script_li, + get_work_li_data : work_script_li_data, + state : UL_STATE.IDLE, + edited_item : undefined, + } +} + +const import_window = by_id("import_window"); +const import_loading_radio = by_id("import_loading_radio"); +const import_failed_radio = by_id("import_failed_radio"); +const import_selection_radio = by_id("import_selection_radio"); +const bad_file_errormsg = by_id("bad_file_errormsg"); + +/* + * Newer browsers could utilise `text' method of File objects. + * Older ones require FileReader. + */ - const import_window = by_id("import_window"); - const import_loading_radio = by_id("import_loading_radio"); - const import_failed_radio = by_id("import_failed_radio"); - const import_selection_radio = by_id("import_selection_radio"); - const bad_file_errormsg = by_id("bad_file_errormsg"); +function _read_file(file, resolve, reject) +{ + let reader = new FileReader(); + + reader.onload = () => resolve(reader.result); + reader.onerror = () => reject(reader.error); + reader.readAsText(file); +} + +function read_file(file) +{ + return new Promise((resolve, reject) => + _read_file(file, resolve, reject)); +} + +async function import_from_file(event) +{ + let files = event.target.files; + if (files.length < 1) + return; + + import_window.classList.remove("hide"); + import_loading_radio.checked = true; + + let result = undefined; + + try { + result = JSON.parse(await read_file(files[0])); + } catch(e) { + bad_file_errormsg.textContent = "" + e; + import_failed_radio.checked = true; + return; + } + + let errormsg = validate_settings(result); + if (errormsg !== false) { + bad_file_errormsg.textContent = errormsg; + import_failed_radio.checked = true; + return; + } + + populate_import_list(result); + import_selection_radio.checked = true; +} + +function validate_settings(settings) +{ + // TODO + return false; +} + +function import_li_id(prefix, item) +{ + return `ili_${prefix}_${item}`; +} + +let import_ul = by_id("import_ul"); +let import_chbxs_colliding = undefined; +let settings_import_map = undefined; + +function populate_import_list(settings) +{ + let old_children = import_ul.children; + while (old_children[0] !== undefined) + import_ul.removeChild(old_children[0]); + + import_chbxs_colliding = []; + settings_import_map = new Map(); + + for (let setting of settings) { + let [key, value] = Object.entries(setting)[0]; + let prefix = key[0]; + let name = key.substring(1); + add_import_li(prefix, name); + settings_import_map.set(key, value); + } +} + +function add_import_li(prefix, name) +{ + let li = import_li_template.cloneNode(true); + let name_span = li.firstElementChild; + let chbx = name_span.nextElementSibling; + let warning_span = chbx.nextElementSibling; + + li.setAttribute("data-prefix", prefix); + li.setAttribute("data-name", name); + li.id = import_li_id(prefix, name); + name_span.textContent = nice_name(prefix, name); + + if (storage.get(prefix, name) !== undefined) { + import_chbxs_colliding.push(chbx); + warning_span.textContent = "(will overwrite existing setting!)"; + } + + import_ul.appendChild(li); +} + +function check_all_imports() +{ + for (let li of import_ul.children) + li.firstElementChild.nextElementSibling.checked = true; +} + +function uncheck_all_imports() +{ + for (let li of import_ul.children) + li.firstElementChild.nextElementSibling.checked = false; +} + +function uncheck_colliding_imports() +{ + for (let chbx of import_chbxs_colliding) + chbx.checked = false; +} + +const file_opener_form = by_id("file_opener_form"); + +function hide_import_window() +{ + import_window.classList.add("hide"); + /* Let GC free some memory */ + import_chbxs_colliding = undefined; + settings_import_map = undefined; /* - * Newer browsers could utilise `text' method of File objects. - * Older ones require FileReader. + * Reset file <input>. Without this, a second attempt to import the same + * file would result in "change" event on happening on <input> element. */ + file_opener_form.reset(); +} - function _read_file(file, resolve, reject) - { - let reader = new FileReader(); +function commit_import() +{ + for (let li of import_ul.children) { + let chbx = li.firstElementChild.nextElementSibling; - reader.onload = () => resolve(reader.result); - reader.onerror = () => reject(reader.error); - reader.readAsText(file); - } - - function read_file(file) - { - return new Promise((resolve, reject) => - _read_file(file, resolve, reject)); - } + if (!chbx.checked) + continue; - async function import_from_file(event) - { - let files = event.target.files; - if (files.length < 1) - return; - - import_window.classList.remove("hide"); - import_loading_radio.checked = true; - - let result = undefined; - - try { - result = JSON.parse(await read_file(files[0])); - } catch(e) { - bad_file_errormsg.textContent = "" + e; - import_failed_radio.checked = true; - return; - } - - let errormsg = validate_settings(result); - if (errormsg !== false) { - bad_file_errormsg.textContent = errormsg; - import_failed_radio.checked = true; - return; + let prefix = li.getAttribute("data-prefix"); + let name = li.getAttribute("data-name"); + let key = prefix + name; + let value = settings_import_map.get(key); + storage.set(prefix, name, value); + } + + hide_import_window(); +} + +function initialize_import_facility() +{ + let import_but = by_id("import_but"); + let file_opener = by_id("file_opener"); + let import_failok_but = by_id("import_failok_but"); + let check_all_import_but = by_id("check_all_import_but"); + let uncheck_all_import_but = by_id("uncheck_all_import_but"); + let uncheck_existing_import_but = by_id("uncheck_existing_import_but"); + let commit_import_but = by_id("commit_import_but"); + let cancel_import_but = by_id("cancel_import_but"); + import_but.addEventListener("click", () => file_opener.click()); + file_opener.addEventListener("change", import_from_file); + import_failok_but.addEventListener("click", hide_import_window); + check_all_import_but.addEventListener("click", check_all_imports); + uncheck_all_import_but.addEventListener("click", uncheck_all_imports); + uncheck_colliding_import_but + .addEventListener("click", uncheck_colliding_imports); + commit_import_but.addEventListener("click", commit_import); + cancel_import_but.addEventListener("click", hide_import_window); +} + +async function main() +{ + storage = await get_remote_storage(); + + for (let prefix of list_prefixes) { + for (let item of storage.get_all_names(prefix).sort()) { + add_li(prefix, item, true); + add_chbx_li(prefix, item); + add_radio_li(prefix, item); } - populate_import_list(result); - import_selection_radio.checked = true; - } - - function validate_settings(settings) - { - // TODO - return false; - } + let name = TYPE_NAME[prefix]; - function import_li_id(prefix, item) - { - return `ili_${prefix}_${item}`; - } + let add_but = by_id(`add_${name}_but`); + let discard_but = by_id(`discard_${name}_but`); + let save_but = by_id(`save_${name}_but`); - let import_ul = by_id("import_ul"); - let import_chbxs_colliding = undefined; - let settings_import_map = undefined; - - function populate_import_list(settings) - { - let old_children = import_ul.children; - while (old_children[0] !== undefined) - import_ul.removeChild(old_children[0]); - - import_chbxs_colliding = []; - settings_import_map = new Map(); - - for (let setting of settings) { - let [key, value] = Object.entries(setting)[0]; - let prefix = key[0]; - let name = key.substring(1); - add_import_li(prefix, name); - settings_import_map.set(key, value); - } - } + add_but.addEventListener("click", () => add_new_item(prefix)); + discard_but.addEventListener("click", () => cancel_work(prefix)); + save_but.addEventListener("click", () => save_work(prefix)); - function add_import_li(prefix, name) - { - let li = import_li_template.cloneNode(true); - let name_span = li.firstElementChild; - let chbx = name_span.nextElementSibling; - let warning_span = chbx.nextElementSibling; + if (prefix === TYPE_PREFIX.SCRIPT) + continue; - li.setAttribute("data-prefix", prefix); - li.setAttribute("data-name", name); - li.id = import_li_id(prefix, name); - name_span.textContent = nice_name(prefix, name); - - if (storage.get(prefix, name) !== undefined) { - import_chbxs_colliding.push(chbx); - warning_span.textContent = "(will overwrite existing setting!)"; - } + let ul = ul_by_prefix[prefix]; - import_ul.appendChild(li); - } + let commit_components_but = by_id(`commit_${name}_components_but`); + let cancel_components_but = by_id(`cancel_${name}_components_but`); + let select_components_but = by_id(`select_${name}_components_but`); - function check_all_imports() - { - for (let li of import_ul.children) - li.firstElementChild.nextElementSibling.checked = true; + commit_components_but + .addEventListener("click", ul.commit_components); + select_components_but + .addEventListener("click", ul.select_components); + cancel_components_but.addEventListener("click", cancel_components); } - function uncheck_all_imports() - { - for (let li of import_ul.children) - li.firstElementChild.nextElementSibling.checked = false; - } - - function uncheck_colliding_imports() - { - for (let chbx of import_chbxs_colliding) - chbx.checked = false; - } + initialize_import_facility(); - const file_opener_form = by_id("file_opener_form"); + storage.add_change_listener(handle_change); +} - function hide_import_window() - { - import_window.classList.add("hide"); - /* Let GC free some memory */ - import_chbxs_colliding = undefined; - settings_import_map = undefined; +function handle_change(change) +{ + if (change.old_val === undefined) { + add_li(change.prefix, change.item); + add_chbx_li(change.prefix, change.item); + add_radio_li(change.prefix, change.item); - /* - * Reset file <input>. Without this, a second attempt to import the same - * file would result in "change" event on happening on <input> element. - */ - file_opener_form.reset(); + return; } - function commit_import() - { - for (let li of import_ul.children) { - let chbx = li.firstElementChild.nextElementSibling; - - if (!chbx.checked) - continue; - - let prefix = li.getAttribute("data-prefix"); - let name = li.getAttribute("data-name"); - let key = prefix + name; - let value = settings_import_map.get(key); - storage.set(prefix, name, value); - } - - hide_import_window(); - } + if (change.new_val !== undefined) + return; - function initialize_import_facility() - { - let import_but = by_id("import_but"); - let file_opener = by_id("file_opener"); - let import_failok_but = by_id("import_failok_but"); - let check_all_import_but = by_id("check_all_import_but"); - let uncheck_all_import_but = by_id("uncheck_all_import_but"); - let uncheck_existing_import_but = by_id("uncheck_existing_import_but"); - let commit_import_but = by_id("commit_import_but"); - let cancel_import_but = by_id("cancel_import_but"); - import_but.addEventListener("click", () => file_opener.click()); - file_opener.addEventListener("change", import_from_file); - import_failok_but.addEventListener("click", hide_import_window); - check_all_import_but.addEventListener("click", check_all_imports); - uncheck_all_import_but.addEventListener("click", uncheck_all_imports); - uncheck_colliding_import_but - .addEventListener("click", uncheck_colliding_imports); - commit_import_but.addEventListener("click", commit_import); - cancel_import_but.addEventListener("click", hide_import_window); + let ul = ul_by_prefix[change.prefix]; + if (ul.state === UL_STATE.EDITING_ENTRY && + ul.edited_item === change.item) { + ul.state = UL_STATE.ADDING_ENTRY; + return; } - async function main() - { - storage = await get_storage(); - - for (let prefix of list_prefixes) { - for (let item of storage.get_all_names(prefix).sort()) { - add_li(prefix, item, true); - add_chbx_li(prefix, item); - add_radio_li(prefix, item); - } - - let name = TYPE_NAME[prefix]; - - let add_but = by_id(`add_${name}_but`); - let discard_but = by_id(`discard_${name}_but`); - let save_but = by_id(`save_${name}_but`); - - add_but.addEventListener("click", () => add_new_item(prefix)); - discard_but.addEventListener("click", () => cancel_work(prefix)); - save_but.addEventListener("click", () => save_work(prefix)); - - if (prefix === TYPE_PREFIX.SCRIPT) - continue; - - let ul = ul_by_prefix[prefix]; - - let commit_components_but = by_id(`commit_${name}_components_but`); - let cancel_components_but = by_id(`cancel_${name}_components_but`); - let select_components_but = by_id(`select_${name}_components_but`); - - commit_components_but - .addEventListener("click", ul.commit_components); - select_components_but - .addEventListener("click", ul.select_components); - cancel_components_but.addEventListener("click", cancel_components); - } - - initialize_import_facility(); + let uls_creators = [[ul.ul, item_li_id]]; - storage.add_change_listener(handle_change); + if (change.prefix !== TYPE_PREFIX.PAGE) { + uls_creators.push([chbx_components_ul, chbx_li_id]); + uls_creators.push([radio_components_ul, radio_li_id]); } - function handle_change(change) - { - if (change.old_val === undefined) { - add_li(change.prefix, change.item); - add_chbx_li(change.prefix, change.item); - add_radio_li(change.prefix, change.item); - - return; - } - - if (change.new_val !== undefined) - return; - - let ul = ul_by_prefix[change.prefix]; - if (ul.state === UL_STATE.EDITING_ENTRY && - ul.edited_item === change.item) { - ul.state = UL_STATE.ADDING_ENTRY; - return; - } - - let uls_creators = [[ul.ul, item_li_id]]; - - if (change.prefix !== TYPE_PREFIX.PAGE) { - uls_creators.push([chbx_components_ul, chbx_li_id]); - uls_creators.push([radio_components_ul, radio_li_id]); - } - - for (let [components_ul, id_creator] of uls_creators) { - let li = by_id(id_creator(change.prefix, change.item)); - components_ul.removeChild(li); - } + for (let [components_ul, id_creator] of uls_creators) { + let li = by_id(id_creator(change.prefix, change.item)); + components_ul.removeChild(li); } +} - main(); -})(); +main(); |