Support for popup-follows-cursor and bugfixes

- Fix performance problems on massive pages with tons of elements (e.g. long 4chan threads)
- Fix the fallback for not looking up within the lookup on android and make it apply to sticky mode too
- Fix for a general performance issue with backwards lookups
- Fix for how context separation works
- Fix for ignoring hard newlines
- Workaround for absolute-positioned span elements to allow some display:block elements to get jumped outside of by the text grabbing code
This commit is contained in:
wareya committed 2018-06-11 17:38:14 -04:00
1 parent 1876f4525b
commit 1c7a43893c
3 files changed
+74 -23

No files matched your search

+4 -4
View File
@@ -69,8 +69,8 @@ let dictsloaded = 0;
function builddict() function builddict()
{ {
console.log("load"); //console.log("load");
console.log(this); //console.log(this);
if (this.readyState === 4) if (this.readyState === 4)
{ {
if (this.status === 200) if (this.status === 200)
@@ -1167,7 +1167,7 @@ function sort_results(text, results)
// FIXME: prefer short deconjugations to long deconjugations, not just no deconjugations to any deconjugations // FIXME: prefer short deconjugations to long deconjugations, not just no deconjugations to any deconjugations
if(entry.deconj) if(entry.deconj)
entry.priority -= 1; entry.priority -= 1;
console.log(entry); //console.log(entry);
} }
results.sort((a,b)=> results.sort((a,b)=>
@@ -1389,7 +1389,7 @@ function lookup_indirect(text, time, divexisted, alternatives_mode, strict_alter
//if(time < last_time_lookup+20) // reduces lag buildup //if(time < last_time_lookup+20) // reduces lag buildup
// return; // return;
if(text == last_lookup && divexisted)// || time < last_time_lookup+100)) // helps reduce double-lookups if(text == last_lookup && divexisted)// || time < last_time_lookup+100)) // helps reduce double-lookups
return; return "itsthesame";
last_lookup = text; last_lookup = text;
last_time_lookup = time; last_time_lookup = time;
+6
View File
@@ -59,6 +59,12 @@ function defaults()
default: true, default: true,
label: "Strict matching for alternative matches" label: "Strict matching for alternative matches"
}); });
settings.push({
id: "popup_follows_mouse",
kind: "checkbox",
default: true,
label: "Popup follows mouse (even if it doesn't update)"
});
// display // display
settings.push({ settings.push({
+64 -19
View File
@@ -24,6 +24,7 @@ enabled: false,
compact: true, compact: true,
usetextfields: true, usetextfields: true,
length: 25, length: 25,
contextlength: 100, // nonconfigurable
fixedwidth: false, fixedwidth: false,
fixedwidthpositioning: false, fixedwidthpositioning: false,
superborder: false, superborder: false,
@@ -42,7 +43,8 @@ corner: 0,
xoffset: 5, xoffset: 5,
yoffset: 22, yoffset: 22,
ignore_linebreaks: false, ignore_linebreaks: false,
sticky: false sticky: false,
popup_follows_mouse: true
}; };
let platform = "win"; let platform = "win";
@@ -77,10 +79,14 @@ function delete_div()
let other = document.body.getElementsByClassName(div_class); let other = document.body.getElementsByClassName(div_class);
if(other.length > 0) if(other.length > 0)
{ {
other[0].innerHTML = "";
other[0].removeAttribute('style');
/*
other[0].style.display = "none"; other[0].style.display = "none";
if(other[0].children.length > 0) if(other[0].children.length > 0)
other[0].children[0].innerHTML = ""; other[0].children[0].innerHTML = "";
other[0].style.position = "relative"; other[0].style.position = "relative";
*/
} }
} }
@@ -105,7 +111,7 @@ function set_sticky_styles(mydiv)
// here we set all the styling and positioning of the div, passing "middle" as the actual contents of it. // 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 // 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) function display_div(middle, x, y)
{ {
let font = settings.font.trim().replace(";","").replace("}",""); let font = settings.font.trim().replace(";","").replace("}","");
if(font != "") if(font != "")
@@ -173,13 +179,17 @@ function display_div(middle, x, y, time)
if(other.length > 0) if(other.length > 0)
{ {
outer = other[0]; outer = other[0];
outer.replaceChild(middle, other[0].firstChild); if(!outer.firstChild)
outer.appendChild(middle);
else if(outer.firstChild != middle)
outer.replaceChild(middle, outer.firstChild);
outer.style.display = "block"; outer.style.display = "block";
} }
else else
{ {
outer = mydoc.createElement("div"); outer = mydoc.createElement("div");
outer.className = div_class; outer.className = div_class;
if(!outer.firstChild || outer.firstChild != middle)
outer.appendChild(middle); outer.appendChild(middle);
mydoc.body.appendChild(outer); mydoc.body.appendChild(outer);
} }
@@ -306,7 +316,7 @@ function exists_div()
} }
let other = mydoc.body.getElementsByClassName(div_class); let other = mydoc.body.getElementsByClassName(div_class);
return (other.length > 0 && other[0].style.display != "none"); return (other.length > 0 && other[0].style.display != "none" && other[0].innerHTML != "");
} }
@@ -814,8 +824,10 @@ function build_div_intermediary()
} }
// for popups with single lookup results // for popups with single lookup results
let lastMoreText = "";
function build_div (text, result, moreText, index) function build_div (text, result, moreText, index)
{ {
lastMoreText = moreText;
last_displayed = [{text:text, result:result}]; last_displayed = [{text:text, result:result}];
let middle = build_div_intermediary(); let middle = build_div_intermediary();
middle.firstChild.appendChild(build_div_inner(text, result, moreText, index)); middle.firstChild.appendChild(build_div_inner(text, result, moreText, index));
@@ -824,6 +836,7 @@ function build_div (text, result, moreText, index)
// for popups with multiple lookup results // for popups with multiple lookup results
function build_div_compound (results, moreText, index) function build_div_compound (results, moreText, index)
{ {
lastMoreText = moreText;
last_displayed = results; last_displayed = results;
//console.log("Displaying:"); //console.log("Displaying:");
//print_object(result); //print_object(result);
@@ -936,7 +949,7 @@ async function lookup_loop()
//console.log("asking background to search the dictionary"); //console.log("asking background to search the dictionary");
let response = await browser.runtime.sendMessage({type:"search", text:lookup[0], time:Date.now(), divexisted:exists_div(), alternatives_mode:settings.alternatives_mode, strict_alternatives:settings.strict_alternatives}); let response = await browser.runtime.sendMessage({type:"search", text:lookup[0], time:Date.now(), divexisted:exists_div(), alternatives_mode:settings.alternatives_mode, strict_alternatives:settings.strict_alternatives});
//console.log("got response"); //console.log("got response");
if(response) if(response && response != "itsthesame")
{ {
if(!response.length) if(!response.length)
{ {
@@ -951,6 +964,9 @@ async function lookup_loop()
display_div(mydiv, lookup[3], lookup[4]); display_div(mydiv, lookup[3], lookup[4]);
} }
} }
//else if(response != "itsthesame" && settings.popup_follows_mouse && exists_div() && !lastMoreText.includes(lookup[0].substring(0, Math.max(0, lookup[0].length-2))))
else if(response != "itsthesame" && exists_div() && !lastMoreText.includes(lookup[0].substring(0, Math.max(1, lookup[0].length-2))))
lookup_cancel();
} }
let t_end = Date.now(); let t_end = Date.now();
let t_to_wait = settings.lookuprate - (t_end - t_start); let t_to_wait = settings.lookuprate - (t_end - t_start);
@@ -1048,23 +1064,36 @@ function grab_more_text(textNode, direction = 1)
direction = -1; direction = -1;
let text = ""; let text = "";
let current_node = textNode; let current_node = textNode;
while(text.length < settings.length || (direction < 0 && !text.includes("。") && !text.includes("\n"))) let iters = 0;
while(text.length < settings.contextlength
&& !text.includes("。") && !text.includes("!") && !text.includes("‼") && !text.includes("?") && !text.includes("??") && !text.includes("…")
&& (!text.includes("\n") || settings.ignore_linebreaks))
{ {
iters += 1;
if(current_node == undefined) break; if(current_node == undefined) break;
// don't search up parent element if current element isn't inline-like
try try
{ {
let display = getComputedStyle(current_node).display; let display = getComputedStyle(current_node).display;
// break out of elements neither inline nor ruby // break out of elements neither inline nor ruby
if(display != "inline" && display != "ruby") if(display != "inline" && display != "ruby" && current_node.tagName.toLowerCase() != "span")
{
break; break;
}
}catch(err){} }catch(err){}
if(iters > 100)
{
//console.log(current_node);
break;
}
let parent = current_node.parentNode; let parent = current_node.parentNode;
if(parent == undefined) break; if(parent == undefined || parent == current_node) break;
let i = Array.prototype.indexOf.call(current_node.parentNode.childNodes, current_node); let i = Array.prototype.indexOf.call(current_node.parentNode.childNodes, current_node);
if(i < 0) break; if(i < 0) break;
i += direction; i += direction;
while(i < current_node.parentNode.childNodes.length && i >= 0) while(i < current_node.parentNode.childNodes.length && i >= 0 && text.length < settings.contextlength && (!text.includes("\n") || settings.ignore_linebreaks))
{ {
let next_node = current_node.parentNode.childNodes[i]; let next_node = current_node.parentNode.childNodes[i];
i += direction; i += direction;
@@ -1083,7 +1112,7 @@ function grab_more_text(textNode, direction = 1)
if(display == "ruby-text") if(display == "ruby-text")
continue; continue;
if(display == "inline") if(display == "inline" || (next_node.tagName?next_node.tagName.toLowerCase() == "span":false))
{ {
if(direction > 0) if(direction > 0)
ttext += next_node.textContent; ttext += next_node.textContent;
@@ -1101,7 +1130,7 @@ function grab_more_text(textNode, direction = 1)
let display = getComputedStyle(child).display; let display = getComputedStyle(child).display;
//if(display == "ruby-text") //if(display == "ruby-text")
// continue; // continue;
if(display == "inline") if(display == "inline" || (child.tagName?child.tagName.toLowerCase() == "span":false))
{ {
subtext += child.textContent; subtext += child.textContent;
} }
@@ -1129,8 +1158,10 @@ function grab_more_text(textNode, direction = 1)
text = next_node.textContent + text; text = next_node.textContent + text;
} }
} }
if(text.length < settings.length || direction < 0) if(text.length < settings.contextlength)
current_node = current_node.parentNode; current_node = current_node.parentNode;
else
break;
} }
return text; return text;
} }
@@ -1155,6 +1186,11 @@ function grab_text(textNode, offset, elemental)
text += grab_more_text(textNode); text += grab_more_text(textNode);
moreText = grab_more_text(textNode, -1) + moreText + grab_more_text(textNode); moreText = grab_more_text(textNode, -1) + moreText + grab_more_text(textNode);
if(settings.ignore_linebreaks)
text = text.replace(/\n/g, "");
if(settings.ignore_linebreaks)
moreText = moreText.replace(/\n/g, "");
//console.log("more (orig): " + moreText); //console.log("more (orig): " + moreText);
//console.log("less (orig): " + text); //console.log("less (orig): " + text);
@@ -1179,6 +1215,7 @@ function grab_text(textNode, offset, elemental)
//console.log("less: " + text); //console.log("less: " + text);
// grab text from later and surrounding DOM nodes // grab text from later and surrounding DOM nodes
text = moreText.substring(index);
return [text, moreText, index]; return [text, moreText, index];
} }
@@ -1186,10 +1223,18 @@ function update(event)
{ {
if(!settings.enabled) return; if(!settings.enabled) return;
if(settings.popup_follows_mouse && exists_div() && !settings.sticky)
{
let other = document.body.getElementsByClassName(div_class)[0];
//let middle = other.firstChild.cloneNode(true);
let middle = other.firstChild;
if(middle)
display_div(middle, event.pageX, event.pageY);
//move_div(event.pageX, event.pageY);
}
if(Date.now() - time_of_last < settings.lookuprate) if(Date.now() - time_of_last < settings.lookuprate)
{ {
//console.log("too soon, returning");
//console.log(Date.now() + " vs " + time_of_last);
return; return;
} }
@@ -1251,15 +1296,16 @@ function update(event)
}; };
hitpage(event.clientX, search_x_offset, event.clientY); hitpage(event.clientX, search_x_offset, event.clientY);
if (platform == "android" && exists_div()) // try without the offset
if (textNode == undefined || (textNode.nodeType != 3 && !acceptable_element(textNode)))
hitpage(event.clientX, 0, event.clientY);
if ((platform == "android" || settings.sticky) && exists_div())
{ {
let ele = document.body.getElementsByClassName(div_class)[0]; let ele = document.body.getElementsByClassName(div_class)[0];
if(ele.contains(textNode)) if(ele.contains(textNode))
return; return;
} }
// try without the offset
if (textNode == undefined || (textNode.nodeType != 3 && !acceptable_element(textNode)))
hitpage(event.clientX, 0, event.clientY);
if(!(textNode == undefined)) if(!(textNode == undefined))
{ {
@@ -1410,7 +1456,6 @@ function mine(highlight)
function keytest(event) function keytest(event)
{ {
console.log("asdf");
if(event.target != document.body) if(event.target != document.body)
return; return;
if(event.shiftKey || event.ctrlKey || event.metaKey || event.altKey) if(event.shiftKey || event.ctrlKey || event.metaKey || event.altKey)