diff options
| author | siikamiika <siikamiika@users.noreply.github.com> | 2019-11-03 15:19:42 +0200 | 
|---|---|---|
| committer | siikamiika <siikamiika@users.noreply.github.com> | 2019-11-23 17:45:44 +0200 | 
| commit | 5a3e8c819c94be628101311e53c164b0cdd234b4 (patch) | |
| tree | 18045bc11bb347555f33dc9e9c13bd23dd8f5736 | |
| parent | 41020289ab68ef22a0691a9f268a79d6a706df6b (diff) | |
optimize mouseover scanning in query parser
| -rw-r--r-- | ext/bg/js/search-query-parser.js | 87 | ||||
| -rw-r--r-- | ext/bg/js/templates.js | 22 | ||||
| -rw-r--r-- | tmpl/query-parser.html | 8 | 
3 files changed, 70 insertions, 47 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,46 +52,76 @@ 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); - -        const previewTerms = []; -        let previewText = text; -        while (previewText) { -            const tempText = previewText.slice(0, 2); -            previewTerms.push([{text: tempText}]); -            previewText = previewText.slice(2); -        } - -        this.queryParser.innerHTML = await apiTemplateRender('query-parser.html', { -            terms: previewTerms, -            preview: 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.map((part) => { -                    part.raw = !part.text.trim() && (!part.reading || !part.reading.trim()); -                    return part; +                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 = []; +        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', { +            terms: previewTerms, +            preview: true +        }); + +        this.queryParser.querySelectorAll('.query-parser-char').forEach((charElement) => { +            this.activateScanning(charElement); +        }); +    } + +    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) {          const results = [];          while (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 "<span class=\"query-parser-char\">" +    + container.escapeExpression(container.lambda(depth0, depth0)) +    + "</span>"; +},"12":function(container,depth0,helpers,partials,data) { +    var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {});    return "<ruby>" -    + 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 : "")      + "<rt>" -    + 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)))      + "</rt></ruby>"; -},"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~}} +<span class="query-parser-char">{{this}}</span> +{{~/each~}}  {{~else~}} -<ruby>{{text}}<rt>{{reading}}</rt></ruby> +<ruby>{{~#each text~}} +<span class="query-parser-char">{{this}}</span> +{{~/each~}}<rt>{{reading}}</rt></ruby>  {{~/if~}}  {{~/inline~}} |