From b7891bd65eb00f566dab1aba2705ba074c2e0455 Mon Sep 17 00:00:00 2001 From: wareya Date: Mon, 22 Jan 2018 15:47:17 -0500 Subject: [PATCH] options overhaul --- options.html | 45 +----- options.js | 399 ++++++++++++++++++++++++++++++++++++++------------- texthook.js | 90 ++++++++++-- 3 files changed, 384 insertions(+), 150 deletions(-) diff --git a/options.html b/options.html index 2d2b7cc..666202c 100644 --- a/options.html +++ b/options.html @@ -9,46 +9,11 @@
-
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- - - - - - - - - - + +
+
+ +

This extension uses JMdict, which is Copyright © 2017 The Electronic Dictionary Research and Development Group and licensed under the CC BY-SA 3.0 license.

This extension is otherwise licensed under the Apache License, version 2.0.

Meanings of abbreviations follow. From JMdict. Some may be unused. Unsorted.

diff --git a/options.js b/options.js index 853bf3d..7815fb0 100644 --- a/options.js +++ b/options.js @@ -1,42 +1,273 @@ +'use strict'; + +let settings = []; + +function defaults() +{ + // behavior + settings.push({ + kind: "dummy", + label: "Behavior" + }); + + settings.push({ + id: "enabled", + kind: "checkbox", + default: false, + label: "Enabled" + }); + settings.push({ + id: "compact", + kind: "checkbox", + default: true, + label: "Compact" + }); + settings.push({ + id: "showoriginal", + kind: "checkbox", + default: true, + label: "Show original text" + }); + settings.push({ + id: "length", + kind: "number", + min: 6, + max: 100, + step: 1, + default: 25, + label: "Search length (characters) (default 25, sane values are from 25 to 50)" + }); + settings.push({ + id: "lookuprate", + kind: "number", + min: 1, + max: 1000, + step: 1, + default: 8, + label: "Lookup throttle (milliseconds)" + }); + settings.push({ + id: "alternatives_mode", + kind: "combobox", + options: ["Longest match only", "Longest and shortest match", "Longest and second longest match", "All matches"], + default: 0, + label: "Matching mode" + }); + settings.push({ + id: "strict_alternatives", + kind: "checkbox", + default: true, + label: "Strict matching for alternative matches" + }); + + // display + settings.push({ + kind: "dummy", + label: "Display" + }); + + settings.push({ + id: "scale", + kind: "number", + min: 0.1, + max: 64, + step: 0.1, + default: 1, + label: "Lookup popup scale" + }); + settings.push({ + id: "xoffset", + kind: "number", + min: 1, + max: 200, + step: 1, + default: 5, + label: "Popup offset, horizontal (pixels, default is 5)" + }); + settings.push({ + id: "yoffset", + kind: "number", + min: 1, + max: 200, + step: 1, + default: 22, + label: "Popup offset, vertical (pixels, default is 22)" + }); + settings.push({ + id: "width", + kind: "number", + min: 100, + max: 10000, + step: 1, + default: 600, + label: "Lookup popup width (before scaling)" + }); + settings.push({ + id: "fixedwidth", + kind: "checkbox", + default: false, + label: "Fixed width" + }); + settings.push({ + id: "fixedwidthpositioning", + kind: "checkbox", + default: false, + label: "Position as though fixed width" + }); + settings.push({ + id: "corner", + kind: "combobox", + options: ["Top left", "Top right", "Bottom left", "Bottom right"], + default: 0, + label: "Popup positioning corner (note: order of definitions is reversed, but \"original text\" still shows up at top of each lookup's definitions, not bottom)" + }); + + // theme + settings.push({ + kind: "dummy", + label: "Theme" + }); + + settings.push({ + id: "superborder", + kind: "checkbox", + default: false, + label: "Super border" + }); + settings.push({ + id: "bgcolor", + kind: "color", + default: "#111111", + label: "Background color" + }); + settings.push({ + id: "fgcolor", + kind: "color", + default: "#CCCCCC", + label: "Foreground color" + }); + settings.push({ + id: "hlcolor", + kind: "color", + default: "#99DDFF", + label: "Highlight color" + }); + settings.push({ + id: "font", + kind: "text", + default: "", + label: "Font override (without trailing comma)" + }); + settings.push({ + id: "hlfont", + kind: "text", + default: "", + label: "Font override (highlighted text only) (without trailing comma)" + }); +} +defaults(); + function restoreListeners() { - document.querySelector("#enabled").addEventListener("change", setOptions); - document.querySelector("#compact").addEventListener("change", setOptions); - document.querySelector("#length").addEventListener("change", setOptions); - document.querySelector("#scale").addEventListener("change", setOptions); - document.querySelector("#width").addEventListener("change", setOptions); - document.querySelector("#lookuprate").addEventListener("change", setOptions); - document.querySelector("#fixedwidth").addEventListener("change", setOptions); - document.querySelector("#fixedwidthpositioning").addEventListener("change", setOptions); - document.querySelector("#superborder").addEventListener("change", setOptions); - document.querySelector("#showoriginal").addEventListener("change", setOptions); - document.querySelector("#bgcolor").addEventListener("change", setOptions); - document.querySelector("#fgcolor").addEventListener("change", setOptions); - document.querySelector("#hlcolor").addEventListener("change", setOptions); - document.querySelector("#font").addEventListener("change", setOptions); - document.querySelector("#hlfont").addEventListener("change", setOptions); - document.querySelector("#alternatives_mode").addEventListener("change", setOptions); - document.querySelector("#strict_alternatives").addEventListener("change", setOptions); + for(let option of settings) + { + if(option.kind == "dummy") continue; + document.querySelector("#"+option.id).addEventListener("change", setOptions); + } } function removeListeners() { - document.querySelector("#enabled").removeEventListener("change", setOptions); - document.querySelector("#compact").removeEventListener("change", setOptions); - document.querySelector("#length").removeEventListener("change", setOptions); - document.querySelector("#scale").addEventListener("change", setOptions); - document.querySelector("#width").addEventListener("change", setOptions); - document.querySelector("#lookuprate").addEventListener("change", setOptions); - document.querySelector("#fixedwidth").removeEventListener("change", setOptions); - document.querySelector("#fixedwidthpositioning").removeEventListener("change", setOptions); - document.querySelector("#superborder").addEventListener("change", setOptions); - document.querySelector("#showoriginal").addEventListener("change", setOptions); - document.querySelector("#bgcolor").addEventListener("change", setOptions); - document.querySelector("#fgcolor").addEventListener("change", setOptions); - document.querySelector("#hlcolor").addEventListener("change", setOptions); - document.querySelector("#font").addEventListener("change", setOptions); - document.querySelector("#hlfont").addEventListener("change", setOptions); - document.querySelector("#alternatives_mode").addEventListener("change", setOptions); - document.querySelector("#strict_alternatives").addEventListener("change", setOptions); + for(let option of settings) + { + if(option.kind == "dummy") continue; + document.querySelector("#"+option.id).removeEventListener("change", setOptions); + } +} + +function buildpage() +{ + let optionsection = document.querySelector("#optionsection"); + for(let option of settings) + { + if(option.kind == "dummy") + { + let header = document.createElement("h2"); + header.textContent = option.label; + optionsection.appendChild(header); + continue; + } + let configger = undefined; + if(option.kind == "checkbox") + { + let input = document.createElement("input"); + input.type = "checkbox"; + input.id = option.id; + input.name = option.id; + input.checked = option.default; + input.style.zIndex = -100000; + configger = input; + } + if(option.kind == "number") + { + let input = document.createElement("input"); + input.type = "number"; + input.id = option.id; + input.name = option.id; + input.min = option.min; + input.max = option.max; + input.value = option.default; + input.step = option.step; + configger = input; + } + if(option.kind == "combobox") + { + let select = document.createElement("select"); + select.id = option.id; + select.name = option.id; + let i = 0; + for(let setting of option.options) + { + let opt = document.createElement("option"); + opt.value = i; + opt.text = setting; + select.add(opt); + i += 1; + } + select.value = option.default; + configger = select; + } + if(option.kind == "color") + { + let input = document.createElement("input"); + input.type = "color"; + input.id = option.id; + input.name = option.id; + input.value = option.default; + configger = input; + } + if(option.kind == "text") + { + let input = document.createElement("input"); + input.type = "text"; + input.id = option.id; + input.name = option.id; + input.value = option.default; + configger = input; + } + + let label = document.createElement("label"); + label.for = option.id; + label.className = "panel-formElements-item"; + let labelText = document.createTextNode(option.label); + + if(option.kind == "checkbox") + label.appendChild(configger); + else + optionsection.appendChild(configger); + + label.appendChild(labelText); + optionsection.appendChild(label); + } } async function restoreOptions() @@ -45,46 +276,23 @@ async function restoreOptions() { async function getvar(name, defval) { - let temp = (await browser.storage.local.get(name))[name]; + let temp = (await browser.storage.local.get(name))[name]; // FIXME do this for all options instead of once per option if(temp == undefined) temp = defval; return temp; } - let enabled = await getvar("enabled", false); - let compact = await getvar("compact", true); - let length = await getvar("length", 25); - let scale = await getvar("scale", 1); - let width = await getvar("width", 600); - let lookuprate = await getvar("lookuprate", 8); - let fixedwidth = await getvar("fixedwidth", false); - let fixedwidthpositioning = await getvar("fixedwidthpositioning", false); - let superborder = await getvar("superborder", false); - let showoriginal = await getvar("showoriginal", true); - let bgcolor = await getvar("bgcolor", "#111111"); - let fgcolor = await getvar("fgcolor", "#CCCCCC"); - let hlcolor = await getvar("hlcolor", "#99DDFF"); - let font = await getvar("font", ""); - let hlfont = await getvar("hlfont", ""); let alternatives_mode = await getvar("alternatives_mode", 0); let strict_alternatives = await getvar("strict_alternatives", true); removeListeners(); - document.querySelector("#enabled").checked = enabled?true:false; - document.querySelector("#compact").checked = compact?true:false; - document.querySelector("#length").value = length?length:25; - document.querySelector("#scale").value = scale?scale:1; - document.querySelector("#width").value = width?width:600; - document.querySelector("#lookuprate").value = lookuprate?lookuprate:8; - document.querySelector("#fixedwidth").checked = fixedwidth?true:false; - document.querySelector("#fixedwidthpositioning").checked = fixedwidthpositioning?true:false; - document.querySelector("#superborder").checked = superborder?true:false; - document.querySelector("#showoriginal").checked = showoriginal?true:false; - document.querySelector("#bgcolor").value = bgcolor?bgcolor:"#111111"; - document.querySelector("#fgcolor").value = fgcolor?fgcolor:"#CCCCCC"; - document.querySelector("#hlcolor").value = hlcolor?hlcolor:"#99DDFF"; - document.querySelector("#font").value = font?font:""; - document.querySelector("#hlfont").value = hlfont?hlfont:""; - document.querySelector("#alternatives_mode").value = alternatives_mode?alternatives_mode:0; - document.querySelector("#strict_alternatives").checked = strict_alternatives?strict_alternatives:true; + for(let option of settings) + { + if(option.kind == "dummy") continue; + let value = await getvar(option.id, option.default); + if(option.kind == "checkbox") + document.querySelector("#"+option.id).checked = value?true:false; + if(option.kind == "number" || option.kind == "text" || option.kind == "color" || option.kind == "combobox") + document.querySelector("#"+option.id).value = value?value:option.default; + } } catch (error) {} removeListeners(); restoreListeners(); @@ -97,47 +305,38 @@ function fixicon() function setOptions() { - let length = parseInt(document.querySelector("#length").value, 10); - if(!length) // NaN is falsy - length = 25; - let scale = Number(document.querySelector("#scale").value); - if(!scale) // NaN is falsy - scale = 1; - let width = Number(document.querySelector("#width").value); - if(!width) // NaN is falsy - width = 600; - let lookuprate = Number(document.querySelector("#lookuprate").value); - if(!lookuprate) // NaN is falsy - lookuprate = 8; - browser.storage.local.set( + let setstuff = {}; + for(let option of settings) { - enabled: document.querySelector("#enabled").checked, - compact: document.querySelector("#compact").checked, - length: length, - scale: scale, - width: width, - lookuprate: lookuprate, - fixedwidth: document.querySelector("#fixedwidth").checked, - fixedwidthpositioning: document.querySelector("#fixedwidthpositioning").checked, - superborder: document.querySelector("#superborder").checked, - showoriginal: document.querySelector("#showoriginal").checked, - bgcolor: document.querySelector("#bgcolor").value, - fgcolor: document.querySelector("#fgcolor").value, - hlcolor: document.querySelector("#hlcolor").value, - font: document.querySelector("#font").value, - hlfont: document.querySelector("#hlfont").value, - alternatives_mode: document.querySelector("#alternatives_mode").value, - strict_alternatives: document.querySelector("#strict_alternatives").checked, - }).then(()=>{fixicon();},()=>{}); + if(option.kind == "dummy") continue; + if(option.kind == "checkbox") + setstuff[option.id] = document.querySelector("#"+option.id).checked; + if(option.kind == "number") + { + let num = Number(document.querySelector("#"+option.id).value); + if(!num) // NaN is falsy + num = option.default; + if(option.step % 1 == 0) + num = Math.round(num); + setstuff[option.id] = num; + } + if(option.kind == "text") + setstuff[option.id] = document.querySelector("#"+option.id).value; + if(option.kind == "color") + setstuff[option.id] = document.querySelector("#"+option.id).value; + if(option.kind == "combobox") + setstuff[option.id] = document.querySelector("#"+option.id).value; + } + browser.storage.local.set(setstuff).then(()=>{fixicon();},()=>{}); } if (document.readyState == "complete") { + buildpage(); restoreOptions(); - //setOptions(); } else { + document.addEventListener("DOMContentLoaded", buildpage); document.addEventListener("DOMContentLoaded", restoreOptions); - //document.addEventListener("DOMContentLoaded", setOptions); } diff --git a/texthook.js b/texthook.js index c6e68f0..d21aae9 100644 --- a/texthook.js +++ b/texthook.js @@ -4,6 +4,7 @@ * TODO: * * ! Finish porting the underlay's deconjugation rules + * - Add an option for "hide unfitting senses/spellings/readings" vs "show everything but with details about what can be what" * - Fix katakana-hiragana matching (only happens in lookups right now, not display generation) * - More configurability * - VNstats frequency data @@ -36,6 +37,9 @@ fgcolor: "#CCCCCC", hlcolor: "#99DDFF", font: "", hlfont: "", +corner: 0, +xoffset: 5, +yoffset: 22 }; let last_time_display = Date.now(); @@ -87,6 +91,7 @@ function display_div (middle, x, y, time) styletext += "width: " + Math.round(Number(settings.width)) + "px; " else styletext += "max-width: " + Math.round(Number(settings.width)) + "px; " + styletext += "min-width: 150px; " styletext += "position: absolute; top: 0; left: 0; "; if(settings.superborder) @@ -94,6 +99,8 @@ function display_div (middle, x, y, time) else styletext += `border-radius: 3px; background-color: ${settings.bgcolor}; z-index: 100000;`; + styletext += "writing-mode: horizontal-tb; line-height: initial;"; + let other = mydoc.body.getElementsByClassName(div_class); let outer = undefined; if(other.length > 0) @@ -123,16 +130,60 @@ function display_div (middle, x, y, time) let buffer = 25; let pretend_doc_width = Math.max(mywidth, mydoc.defaultView.innerWidth); - if(newx + mywidth > pretend_doc_width-buffer) + if(settings.corner == 1 || settings.corner == 3) { - newx -= (newx + mywidth - pretend_doc_width); - newx -= buffer; - if(newx < 0) - newx = 0; + newx = mydoc.defaultView.innerWidth - newx; + if(newx + mywidth > pretend_doc_width-buffer) + { + newx -= (newx + mywidth - pretend_doc_width); + newx -= buffer; + if(newx > mydoc.defaultView.innerWidth) + newx = mydoc.defaultView.innerWidth; + } + } + else + { + if(newx + mywidth > pretend_doc_width-buffer) + { + newx += (newx + mywidth - pretend_doc_width); + newx += buffer; + if(newx < 0) + newx = 0; + } + } + if(settings.corner == 2 || settings.corner == 3) + { + newy = mydoc.defaultView.innerHeight - newy; } - outer.style.top = (newy+5)+"px"; - outer.style.left = (newx+5)+"px"; + if(settings.corner == 3) + { + outer.style.top = "unset"; + outer.style.bottom = (newy+settings.yoffset)+"px"; + outer.style.right = (newx-settings.xoffset)+"px"; + outer.style.left = "unset"; + } + else if(settings.corner == 2) + { + outer.style.top = "unset"; + outer.style.bottom = (newy+settings.yoffset)+"px"; + outer.style.right = "unset"; + outer.style.left = (newx+settings.xoffset)+"px"; + } + else if(settings.corner == 1) + { + outer.style.top = (newy+settings.yoffset)+"px"; + outer.style.bottom = "unset"; + outer.style.right = (newx-settings.xoffset)+"px"; + outer.style.left = "unset"; + } + else // 0 etc + { + outer.style.top = (newy+settings.yoffset)+"px"; + outer.style.bottom = "unset"; + outer.style.right = "unset"; + outer.style.left = (newx+settings.xoffset)+"px"; + } } function exists_div() @@ -164,15 +215,17 @@ function build_div_inner (text, result) //console.log("building div for " + text); //console.log(result); let temp = document.createElement("div"); + temp.style.position = "relative"; if(settings.showoriginal) { let original = document.createElement("div"); original.className = "nazeka_original"; - original.textContent = "Looked up "; + //original.textContent = "Looked up "; let original_inner = document.createElement("span"); original_inner.className = "nazeka_lookup"; original_inner.textContent = text; original.appendChild(original_inner); + temp.appendChild(original); } else @@ -620,7 +673,15 @@ function build_div_inner (text, result) } } container.appendChild(definition); - temp.appendChild(container); + if(settings.corner == 2 || settings.corner == 3) + { + if(settings.showoriginal) + temp.insertBefore(container, temp.children[0].nextSibling); + else + temp.insertBefore(container, temp.children[0]); + } + else + temp.appendChild(container); } return temp; } @@ -648,7 +709,12 @@ function build_div_compound (results) //print_object(result); let middle = build_div_intermediary(); for(let lookup of results) - middle.firstChild.appendChild(build_div_inner(lookup.text, lookup.result)); + { + if(settings.corner == 2 || settings.corner == 3) + middle.firstChild.insertBefore(build_div_inner(lookup.text, lookup.result), middle.firstChild.children[0]); + else + middle.firstChild.appendChild(build_div_inner(lookup.text, lookup.result)); + } return middle; } @@ -683,6 +749,10 @@ async function settings_init() getvar("alternatives_mode", 0); getvar("strict_alternatives", true); + getvar("corner", 0); + getvar("xoffset", 5); + getvar("yoffset", 22); + if(!settings.enabled && exists_div()) delete_div(); } catch(err) {} // options not stored yet