From 5a3e8c819c94be628101311e53c164b0cdd234b4 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 3 Nov 2019 15:19:42 +0200 Subject: [PATCH] optimize mouseover scanning in query parser --- ext/bg/js/search-query-parser.js | 91 +++++++++++++++++++------------- ext/bg/js/templates.js | 22 ++++---- tmpl/query-parser.html | 8 ++- 3 files changed, 72 insertions(+), 49 deletions(-) diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index 0c74e550..8c3159cd 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -20,11 +20,11 @@ class QueryParser { constructor(search) { this.search = search; + this.pendingLookup = false; this.queryParser = document.querySelector('#query-parser'); this.queryParser.addEventListener('click', (e) => this.onClick(e)); - this.queryParser.addEventListener('mousemove', (e) => this.onMouseMove(e)); } onError(error) { @@ -35,8 +35,9 @@ class QueryParser { this.onTermLookup(e, {disableScroll: true, selectText: true}); } - async onMouseMove(e) { + onMouseEnter(e) { if ( + this.pendingLookup || (e.buttons & 0x1) !== 0x0 // Left mouse button ) { return; @@ -51,22 +52,51 @@ class QueryParser { return; } - await this.onTermLookup(e, {disableScroll: true, selectText: true, disableHistory: true}) + this.onTermLookup(e, {disableScroll: true, selectText: true, disableHistory: true}); } onTermLookup(e, params) { - this.search.onTermLookup(e, params); + this.pendingLookup = true; + (async () => { + await this.search.onTermLookup(e, params); + this.pendingLookup = false; + })(); } async setText(text) { this.search.setSpinnerVisible(true); + await this.setPreview(text); + // const results = await apiTextParse(text, this.search.getOptionsContext()); + const results = await apiTextParseMecab(text, this.search.getOptionsContext()); + + const content = await apiTemplateRender('query-parser.html', { + terms: results.map((term) => { + return term.filter(part => part.text.trim()).map((part) => { + return { + text: Array.from(part.text), + reading: part.reading, + raw: !part.reading || !part.reading.trim(), + }; + }); + }) + }); + + this.queryParser.innerHTML = content; + + this.queryParser.querySelectorAll('.query-parser-char').forEach((charElement) => { + this.activateScanning(charElement); + }); + + this.search.setSpinnerVisible(false); + } + + async setPreview(text) { const previewTerms = []; - let previewText = text; - while (previewText) { - const tempText = previewText.slice(0, 2); - previewTerms.push([{text: tempText}]); - previewText = previewText.slice(2); + while (text) { + const tempText = text.slice(0, 2); + previewTerms.push([{text: Array.from(tempText)}]); + text = text.slice(2); } this.queryParser.innerHTML = await apiTemplateRender('query-parser.html', { @@ -74,21 +104,22 @@ class QueryParser { preview: true }); - // const results = await apiTextParse(text, this.search.getOptionsContext()); - const results = await apiTextParseMecab(text, this.search.getOptionsContext()); - - const content = await apiTemplateRender('query-parser.html', { - terms: results.map((term) => { - return term.map((part) => { - part.raw = !part.text.trim() && (!part.reading || !part.reading.trim()); - return part; - }); - }) + this.queryParser.querySelectorAll('.query-parser-char').forEach((charElement) => { + this.activateScanning(charElement); }); + } - this.queryParser.innerHTML = content; - - this.search.setSpinnerVisible(false); + activateScanning(element) { + element.addEventListener('mouseenter', (e) => { + e.target.dataset.timer = setTimeout(() => { + this.onMouseEnter(e); + delete e.target.dataset.timer; + }, this.search.options.scanning.delay); + }); + element.addEventListener('mouseleave', (e) => { + clearTimeout(e.target.dataset.timer); + delete e.target.dataset.timer; + }); } async parseText(text) { @@ -106,22 +137,6 @@ class QueryParser { return results; } - popupTimerSet(callback) { - const delay = this.options.scanning.delay; - if (delay > 0) { - this.popupTimer = window.setTimeout(callback, delay); - } else { - Promise.resolve().then(callback); - } - } - - popupTimerClear() { - if (this.popupTimer !== null) { - window.clearTimeout(this.popupTimer); - this.popupTimer = null; - } - } - static isScanningModifierPressed(scanningModifier, mouseEvent) { switch (scanningModifier) { case 'alt': return mouseEvent.altKey; diff --git a/ext/bg/js/templates.js b/ext/bg/js/templates.js index cc233d49..6e377957 100644 --- a/ext/bg/js/templates.js +++ b/ext/bg/js/templates.js @@ -180,27 +180,31 @@ templates['query-parser.html'] = template({"1":function(container,depth0,helpers },"8":function(container,depth0,helpers,partials,data) { var stack1; - return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.raw : depth0),{"name":"if","hash":{},"fn":container.program(9, data, 0),"inverse":container.program(11, data, 0),"data":data})) != null ? stack1 : ""); + return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.raw : depth0),{"name":"if","hash":{},"fn":container.program(9, data, 0),"inverse":container.program(12, data, 0),"data":data})) != null ? stack1 : ""); },"9":function(container,depth0,helpers,partials,data) { - var helper; + var stack1; - return container.escapeExpression(((helper = (helper = helpers.text || (depth0 != null ? depth0.text : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"text","hash":{},"data":data}) : helper))); -},"11":function(container,depth0,helpers,partials,data) { - var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; + return ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.text : depth0),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); +},"10":function(container,depth0,helpers,partials,data) { + return "" + + container.escapeExpression(container.lambda(depth0, depth0)) + + ""; +},"12":function(container,depth0,helpers,partials,data) { + var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}); return "" - + alias4(((helper = (helper = helpers.text || (depth0 != null ? depth0.text : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"text","hash":{},"data":data}) : helper))) + + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.text : depth0),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "" - + alias4(((helper = (helper = helpers.reading || (depth0 != null ? depth0.reading : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"reading","hash":{},"data":data}) : helper))) + + container.escapeExpression(((helper = (helper = helpers.reading || (depth0 != null ? depth0.reading : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(alias1,{"name":"reading","hash":{},"data":data}) : helper))) + ""; -},"13":function(container,depth0,helpers,partials,data,blockParams,depths) { +},"14":function(container,depth0,helpers,partials,data,blockParams,depths) { var stack1; return ((stack1 = container.invokePartial(partials.term,depth0,{"name":"term","hash":{"preview":(depths[1] != null ? depths[1].preview : depths[1])},"data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : ""); },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data,blockParams,depths) { var stack1; - return ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.terms : depth0),{"name":"each","hash":{},"fn":container.program(13, data, 0, blockParams, depths),"inverse":container.noop,"data":data})) != null ? stack1 : ""); + return ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.terms : depth0),{"name":"each","hash":{},"fn":container.program(14, data, 0, blockParams, depths),"inverse":container.noop,"data":data})) != null ? stack1 : ""); },"main_d": function(fn, props, container, depth0, data, blockParams, depths) { var decorators = container.decorators; diff --git a/tmpl/query-parser.html b/tmpl/query-parser.html index 818650e6..db98b5ff 100644 --- a/tmpl/query-parser.html +++ b/tmpl/query-parser.html @@ -12,9 +12,13 @@ {{~#*inline "part"~}} {{~#if raw~}} -{{text}} +{{~#each text~}} +{{this}} +{{~/each~}} {{~else~}} -{{text}}{{reading}} +{{~#each text~}} +{{this}} +{{~/each~}}{{reading}} {{~/if~}} {{~/inline~}}