comment maintainence and refactor the restriction code into a single function in background-script

This commit is contained in:
wareya committed 2018-01-30 20:06:58 -05:00
1 parent 6fc55999de
commit 33725e603f
2 files changed
+184 -127

No files matched your search

+163 -2
View File
@@ -13,7 +13,6 @@ let epwing = [
let lookup_epwing_kan = new Map();
let lookup_epwing_kana = new Map();
function string_is_kana(str)
{
for(let i = 0; i < str.length; i++)
@@ -1042,6 +1041,168 @@ function filter_kana_ish_results(results)
return newresults;
}
// https://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript
function copy(orig)
{
let mine = orig;
mine = Object.assign({}, orig)
for(let f in mine)
{
f = Object.assign({}, f)
}
return mine;
}
// Restrict the listed spellings/readings of a JMdict entry to the ones allowed by the looked-up text.
function restrict_by_text(entry, text)
{
// deep clone lol (we should probably do this WAY earlier)
let term = copy(entry);
//console.log(entry);
//console.log(term);
if(!term.found) // bogus lookup
return term;
// Example restrictions:
// ゆう: 夕 only
// さくや: 昨夜 only
// evening: 夕・夕べ only
// last night: ゆうべ・さくや only
// Derived:
// 昨夜: さくや・ゆうべ only
// 夕: ゆう・ゆうべ only
// 夕べ: ゆうべ only
// evening: ゆう・ゆうべ only
// last night: 夕べ・昨夜 only
// if we didn't look up kanji, look for the first fitting kanji spellings in the entry (they're ordered sensibly) if there are kanji spellings
term.orig_found = term.found;
if(!!(term.found.reb) && term.k_ele)
{
let r_restr = undefined;
// kanji to which the reb is restricted
if(term.found.restr && term.found.restr.length > 0)
r_restr = term.found.restr;
if(!r_restr)
r_restr = [];
// find the first kanji-including spelling that isn't restricted to readings that aren't the one we looked up
for(let j = 0; j < term.k_ele.length; j++)
{
// if this spelling is restricted to particular readings
if(term.k_ele[j].restr)
{
for(let l = 0; l < term.k_ele[j].restr.length; l++)
{
// if the reading we looked up is one of the ones it's restricted to
// if the reading we looked up isn't restricted to spellings other than this one
if(term.k_ele[j].restr[l] == term.found.reb && (r_restr.length == 0 || r_restr.indexOf(term.k_ele[j].keb) > -1))
{
// pretend we looked up this spelling
term.found = term.k_ele[j];
break;
}
}
}
// if the spelling does not have restrictions
// if the reading is not restricted to other spellings
else if(r_restr.length == 0 || r_restr.indexOf(term.k_ele[j].keb) > -1)
{
// pretend we looked up this spelling
term.found = term.k_ele[j];
break;
}
}
}
// eliminate unfitting kanji spellings if we originally looked up a reading
if(!!(term.orig_found.reb) && term.k_ele)
{
let r_restr = undefined;
// kanji to which the reb is restricted
if(term.orig_found.restr && term.orig_found.restr.length > 0)
r_restr = term.orig_found.restr;
else
r_restr = [];
let new_k_ele = [];
for(let j = 0; j < term.k_ele.length; j++)
{
if(r_restr.length > 0 && r_restr.indexOf(term.k_ele[j].keb) < 0)
continue;
// if this spelling is restricted to particular readings
if(term.k_ele[j].restr)
{
for(let l = 0; l < term.k_ele[j].restr.length; l++)
// if the reading we looked up is one of the ones it's restricted to
// if the reading we looked up isn't restricted to spellings other than this one
if(term.k_ele[j].restr[l] == term.orig_found.reb)
new_k_ele.push(term.k_ele[j]);
}
// if the spelling does not have restrictions
// if the reading is not restricted to other spellings
else
new_k_ele.push(term.k_ele[j]);
}
term.k_ele = new_k_ele;
}
// eliminate unfitting readings if we originally looked up a spelling
if(!!(term.orig_found.keb) && term.r_ele)
{
let k_restr = undefined;
// kanji to which the reb is restricted
if(term.orig_found.restr && term.orig_found.restr.length > 0)
k_restr = term.orig_found.restr;
else
k_restr = [];
let new_r_ele = [];
for(let j = 0; j < term.r_ele.length; j++)
{
if(k_restr.length > 0 && k_restr.indexOf(term.r_ele[j].reb) < 0)
continue;
if(term.r_ele[j].restr)
{
for(let l = 0; l < term.r_ele[j].restr.length; l++)
if(term.r_ele[j].restr[l] == term.orig_found.keb)
new_r_ele.push(term.r_ele[j]);
}
else
new_r_ele.push(term.r_ele[j]);
}
term.r_ele = new_r_ele;
}
// eliminate unfitting definitions for the original lookup
if(term.sense)
{
let new_sense = [];
for(let j = 0; j < term.sense.length; j++)
{
if(term.orig_found.keb && term.sense[j].stagk)
{
for(let l = 0; l < term.sense[j].stagk.length; l++)
if(term.sense[j].stagk[l] == term.orig_found.keb)
new_sense.push(term.sense[j]);
}
else if(term.orig_found.reb && term.sense[j].stagr)
{
for(let l = 0; l < term.sense[j].stagr.length; l++)
if(term.sense[j].stagr[l] == term.orig_found.reb)
new_sense.push(term.sense[j]);
}
// if the spelling does not have restrictions
// if the reading is not restricted to other spellings
else
new_sense.push(term.sense[j]);
}
term.sense = new_sense;
}
return term;
}
// Skip JMdict entries reappearing in alternative lookups (so only the first one is shown)
function skip_rereferenced_entries(results)
{
let newresults = [];
@@ -1057,7 +1218,7 @@ function skip_rereferenced_entries(results)
if(seenseq.has(entry.seq))
continue;
seenseq.add(entry.seq);
newlookup.push(entry);
newlookup.push(restrict_by_text(entry, lookup.text));
}
if(newlookup.length > 0)
newresults.push({text:lookup.text, result:newlookup});
+21 -125
View File
@@ -18,6 +18,7 @@
'use strict';
// updated by a timer looping function, based on local storage set by the options page
let settings = {
enabled: false,
compact: true,
@@ -44,8 +45,10 @@ yoffset: 22
let last_time_display = Date.now();
// FIXME: this should be the extension ID or a per-page random string, but it's not useful to change this yet, not until firefox lands shadow DOM
let div_class = "nazeka_fGKRTDGFGgr9atT";
// the popup is inserted into the page as a screen-relative div, we never delete it because modifying the root DOM of very long pages is expensive, we hide it instead
let last_displayed = undefined;
function delete_div ()
{
@@ -59,14 +62,11 @@ function delete_div ()
}
}
// here we set all the styling and positioning of the div, passing "middle" as the actual contents of it.
// this is rather elaborate because of 1) a lack of shadow DOM, even for just styling 2) options 3) """features""" of how HTML viewport stuff works that are actually terrible
function display_div (middle, x, y, time)
{
//let bordercolor = undefined;
//if(settings.superborder)
// bordercolor = "white";
//else
// bordercolor = "#CCC";
let font = settings.font.trim().replace(";","");
let font = settings.font.trim().replace(";","").replace("}","");
if(font != "")
font += ",";
middle.style = `background-color: ${settings.bgcolor}; border-radius: 2.5px; border: 1px solid ${settings.bgcolor};`;
@@ -235,14 +235,18 @@ function clip(str)
return str.substring(1, str.length-1);
}
// Here we actually build the content of the lookup popup, based on the text we looked up and the list of lookups from the background script
// note that we can get multiple lookups and this function only handles a single lookup
function build_div_inner (text, result)
{
//console.log("building div for " + text);
//console.log(result);
let temp = document.createElement("div");
temp.style.position = "relative";
// the "Looked up XXXX" text
if(settings.showoriginal)
{
// nesting it like this lets us access nazeka_lookup when we want to get the text we looked up, if we have text in front of it, which we don't anymore
let original = document.createElement("div");
original.className = "nazeka_original";
//original.textContent = "Looked up ";
@@ -262,13 +266,14 @@ function build_div_inner (text, result)
temp.appendChild(original_inner);
}
// styling for highlighted stuff and the lookup text
let style = document.createElement("style");
style.type = "text/css";
let font = settings.hlfont.trim();
let font = settings.hlfont.trim().replace(";","").replace("}","");
if(font != "")
font += ",";
if(settings.font.trim().replace(";","") != "")
font += settings.font.trim().replace(";","") + ",";
if(settings.font.trim().replace(";","").replace("}","") != "")
font += settings.font.trim().replace(";","").replace("}","") + ",";
style.textContent =
`.nazeka_main_keb{font-family: ${font}IPAGothic,TakaoGothic,Noto Sans CJK JP Regular,Meiryo,sans-serif;font-size:18px;color:${settings.hlcolor}}\
.nazeka_main_reb{font-family: ${font}IPAGothic,TakaoGothic,Noto Sans CJK JP Regular,Meiryo,sans-serif;font-size:18px;color:${settings.hlcolor}}\
@@ -280,9 +285,6 @@ function build_div_inner (text, result)
for(let i = 0; i < result.length; i++)
{
let term = result[i];
// shouldn't happen but just in case of broken data
if(!term.found)
continue;
let container = document.createElement("div");
container.className = "nazeka_word_container";
@@ -299,60 +301,11 @@ function build_div_inner (text, result)
let temptag = document.createElement("span");
temptag.className = "nazeka_word";
let found_kanji = true;
let original_kana = "";
if(term.found.reb)
original_kana = term.found.reb;
if(term.k_ele)
{
let looked_up_kanji = !!(term.found.keb);
let r_restr = [];
// if we didn't look up kanji, look for the first fitting kanji in the entry (they're ordered sensibly)
if(!looked_up_kanji)
{
if(term.found.restr && term.found.restr.length > 0)
r_restr = term.found.restr;
if(!r_restr)
r_restr = [];
// find the first kanji that isn't restricted to readings that aren't the one we looked up
for(let j = 0; j < term.k_ele.length; j++)
{
if(term.k_ele[j].restr)
{
for(let l = 0; l < term.k_ele[j].restr.length; l++)
{
if(term.k_ele[j].restr[l] == text)
{
if(r_restr.length == 0 || r_restr.indexOf(term.k_ele[j].keb) > -1)
{
term.found = term.k_ele[j];
//console.log("reassigned found")
//console.log(term.found);
found_kanji = true;
break;
}
}
}
}
else
{
if(r_restr.length == 0 || r_restr.indexOf(term.k_ele[j].keb) > -1)
{
term.found = term.k_ele[j];
//console.log("reassigned found")
//console.log(term.found);
found_kanji = true;
break;
}
}
}
}
else
found_kanji = true;
if(found_kanji)
if(term.found.keb)
{
let k_ele = term.found;
let kanji_text = k_ele.keb;
@@ -362,24 +315,11 @@ function build_div_inner (text, result)
temptag.appendChild(keb);
// list readings
let readings = [];
// don't list readings if restricted to kanji we didn't look up
for(let j = 0; j < term.r_ele.length; j++)
{
let r = term.r_ele[j];
let invalid = r.restr != undefined;
if(r.restr)
{
for(let l = 0; l < r.restr.length; l++)
if(r.restr[l] == kanji_text)
invalid = false;
}
if(!invalid)
readings.push(term.r_ele[j]);
let readings = term.r_ele;
}
if(term.deconj)
{
//console.log(term.deconj);
let deconj = "";
let first = true;
for(let form of term.deconj)
@@ -451,25 +391,9 @@ function build_div_inner (text, result)
// list alternatives
let alternatives = [];
// don't list spellings if restricted to kana we didn't look up
for(let j = 0; j < term.k_ele.length; j++)
{
if(term.k_ele[j].keb != kanji_text)
{
let k = term.k_ele[j];
let invalid = !looked_up_kanji && k.restr;
if(!looked_up_kanji && k.restr)
{
for(let l = 0; l < k.restr.length; l++)
if(k.restr[l] == text)
invalid = false;
}
if(!looked_up_kanji && r_restr.indexOf(k.keb) < 0)
invalid = true;
if(!invalid)
alternatives.push(term.k_ele[j]);
}
}
if(alternatives.length > 0)
temptag.appendChild(document.createTextNode(" (also "));
@@ -495,10 +419,7 @@ function build_div_inner (text, result)
if(alternatives.length > 0)
temptag.appendChild(document.createTextNode(")"));
}
}
else
found_kanji = false;
if(!found_kanji)
{
let main_reb = document.createElement("span");
main_reb.className = "nazeka_main_reb";
@@ -587,36 +508,8 @@ function build_div_inner (text, result)
container.appendChild(temptag);
container.appendChild(document.createElement("br"));
let goodsenses = [];
for(let j = 0; j < term.sense.length; j++)
{
let sense = term.sense[j];
let goodsenses = term.sense;
// FIXME: this shows too many senses. it's better than the previous code, which could show too few when looking up kana,
// but for looking up さくや for example, it shows both definitions, even though さくや is restricted to a spelling that is restricted to only one definition.
if(original_kana != "")
{
if(sense.stagr)
{
let found = false;
for(let l = 0; l < sense.stagr.length; l++)
if(sense.stagr[l] == original_kana)
found = true;
if(!found)
continue;
}
}
else if(sense.stagk && found_kanji)
{
let found = false;
for(let l = 0; l < sense.stagk.length; l++)
if(sense.stagk[l] == text)
found = true;
if(!found)
continue;
}
goodsenses.push(sense);
}
let lastpos = [];
let definition = document.createElement("div");
definition.className = "nazeka_definitions";
@@ -716,6 +609,7 @@ function build_div_inner (text, result)
return temp;
}
// this are the divs we use to contain the list of lookups. they're all contained in the same inner div from here.
function build_div_intermediary()
{
let middle = document.createElement("div");
@@ -725,6 +619,7 @@ function build_div_intermediary()
return middle;
}
// for popups with single lookup results
function build_div (text, result)
{
last_displayed = [{text:text, result:result}];
@@ -732,6 +627,7 @@ function build_div (text, result)
middle.firstChild.appendChild(build_div_inner(text, result));
return middle;
}
// for popups with multiple lookup results
function build_div_compound (results)
{
last_displayed = results;