diff options
Diffstat (limited to 'ext/bg/js')
-rw-r--r-- | ext/bg/js/api.js | 4 | ||||
-rw-r--r-- | ext/bg/js/backend.js | 6 | ||||
-rw-r--r-- | ext/bg/js/search-query-parser-generator.js | 78 | ||||
-rw-r--r-- | ext/bg/js/search-query-parser.js | 60 | ||||
-rw-r--r-- | ext/bg/js/templates.js | 55 |
5 files changed, 105 insertions, 98 deletions
diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index f4be7a0c..cd6a9d18 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -33,6 +33,10 @@ function apiClipboardGet() { return _apiInvoke('clipboardGet'); } +function apiGetQueryParserTemplatesHtml() { + return _apiInvoke('getQueryParserTemplatesHtml'); +} + function _apiInvoke(action, params={}) { const data = {action, params}; return new Promise((resolve, reject) => { diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 668d1fb7..529055d2 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -567,6 +567,11 @@ class Backend { return await requestText(url, 'GET'); } + async _onApiGetQueryParserTemplatesHtml() { + const url = chrome.runtime.getURL('/bg/query-parser-templates.html'); + return await requestText(url, 'GET'); + } + _onApiGetZoom(params, sender) { if (!sender || !sender.tab) { return Promise.reject(new Error('Invalid tab')); @@ -854,6 +859,7 @@ Backend._messageHandlers = new Map([ ['getEnvironmentInfo', (self, ...args) => self._onApiGetEnvironmentInfo(...args)], ['clipboardGet', (self, ...args) => self._onApiClipboardGet(...args)], ['getDisplayTemplatesHtml', (self, ...args) => self._onApiGetDisplayTemplatesHtml(...args)], + ['getQueryParserTemplatesHtml', (self, ...args) => self._onApiGetQueryParserTemplatesHtml(...args)], ['getZoom', (self, ...args) => self._onApiGetZoom(...args)] ]); diff --git a/ext/bg/js/search-query-parser-generator.js b/ext/bg/js/search-query-parser-generator.js new file mode 100644 index 00000000..67a1ccad --- /dev/null +++ b/ext/bg/js/search-query-parser-generator.js @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 Alex Yatskov <alex@foosoft.net> + * Author: Alex Yatskov <alex@foosoft.net> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + + +class QueryParserGenerator { + constructor() { + this._templateHandler = null; + this._initialize(); + } + + async _initialize() { + const html = await apiGetQueryParserTemplatesHtml(); + this._templateHandler = new TemplateHandler(html); + } + + createParseResult(terms, preview=false) { + const fragment = document.createDocumentFragment(); + for (const term of terms) { + const termContainer = this._templateHandler.instantiate(preview ? 'term-preview' : 'term'); + for (const segment of term) { + if (!segment.text.trim()) { continue; } + if (!segment.reading || !segment.reading.trim()) { + termContainer.appendChild(this.createSegmentText(segment.text)); + } else { + termContainer.appendChild(this.createSegment(segment)); + } + } + fragment.appendChild(termContainer); + } + return fragment; + } + + createSegment(segment) { + const segmentContainer = this._templateHandler.instantiate('segment'); + const segmentTextContainer = segmentContainer.querySelector('.query-parser-segment-text'); + const segmentReadingContainer = segmentContainer.querySelector('.query-parser-segment-reading'); + segmentTextContainer.appendChild(this.createSegmentText(segment.text)); + segmentReadingContainer.innerText = segment.reading; + return segmentContainer; + } + + createSegmentText(text) { + const fragment = document.createDocumentFragment(); + for (const chr of text) { + const charContainer = this._templateHandler.instantiate('char'); + charContainer.innerText = chr; + fragment.appendChild(charContainer); + } + return fragment; + } + + createParserSelect(parseResults, selectedParser) { + const selectContainer = this._templateHandler.instantiate('select'); + for (const parseResult of parseResults) { + const optionContainer = this._templateHandler.instantiate('select-option'); + optionContainer.value = parseResult.id; + optionContainer.innerText = parseResult.name; + optionContainer.defaultSelected = selectedParser === parseResult.id; + selectContainer.appendChild(optionContainer); + } + return selectContainer; + } +} diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index e8e6d11f..3a93c7e7 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -19,14 +19,16 @@ class QueryParser extends TextScanner { constructor(search) { - super(document.querySelector('#query-parser'), [], [], []); + super(document.querySelector('#query-parser-content'), [], [], []); this.search = search; this.parseResults = []; this.selectedParser = null; - this.queryParser = document.querySelector('#query-parser'); - this.queryParserSelect = document.querySelector('#query-parser-select'); + this.queryParser = document.querySelector('#query-parser-content'); + this.queryParserSelect = document.querySelector('#query-parser-select-container'); + + this.queryParserGenerator = new QueryParserGenerator(); } onError(error) { @@ -64,7 +66,7 @@ class QueryParser extends TextScanner { const selectedParser = e.target.value; this.selectedParser = selectedParser; apiOptionsSet({parsing: {selectedParser}}, this.search.getOptionsContext()); - this.renderParseResult(this.getParseResult()); + this.renderParseResult(); } getMouseEventListeners() { @@ -113,13 +115,13 @@ class QueryParser extends TextScanner { async setText(text) { this.search.setSpinnerVisible(true); - await this.setPreview(text); + this.setPreview(text); this.parseResults = await this.parseText(text); this.refreshSelectedParser(); this.renderParserSelect(); - await this.renderParseResult(); + this.renderParseResult(); this.search.setSpinnerVisible(false); } @@ -146,57 +148,29 @@ class QueryParser extends TextScanner { return results; } - async setPreview(text) { + setPreview(text) { const previewTerms = []; for (let i = 0, ii = text.length; i < ii; i += 2) { const tempText = text.substring(i, i + 2); - previewTerms.push([{text: tempText.split('')}]); + previewTerms.push([{text: tempText}]); } - this.queryParser.innerHTML = await apiTemplateRender('query-parser.html', { - terms: previewTerms, - preview: true - }); + this.queryParser.textContent = ''; + this.queryParser.appendChild(this.queryParserGenerator.createParseResult(previewTerms, true)); } renderParserSelect() { this.queryParserSelect.innerHTML = ''; if (this.parseResults.length > 1) { - const select = document.createElement('select'); - select.classList.add('form-control'); - for (const parseResult of this.parseResults) { - const option = document.createElement('option'); - option.value = parseResult.id; - option.innerText = parseResult.name; - option.defaultSelected = this.selectedParser === parseResult.id; - select.appendChild(option); - } + const select = this.queryParserGenerator.createParserSelect(this.parseResults, this.selectedParser); select.addEventListener('change', this.onParserChange.bind(this)); this.queryParserSelect.appendChild(select); } } - async renderParseResult() { + renderParseResult() { const parseResult = this.getParseResult(); - if (!parseResult) { - this.queryParser.innerHTML = ''; - return; - } - - this.queryParser.innerHTML = await apiTemplateRender( - 'query-parser.html', - {terms: QueryParser.processParseResultForDisplay(parseResult.parsedText)} - ); - } - - static processParseResultForDisplay(result) { - return result.map((term) => { - return term.filter((part) => part.text.trim()).map((part) => { - return { - text: part.text.split(''), - reading: part.reading, - raw: !part.reading || !part.reading.trim() - }; - }); - }); + this.queryParser.textContent = ''; + if (!parseResult) { return; } + this.queryParser.appendChild(this.queryParserGenerator.createParseResult(parseResult.parsedText)); } } diff --git a/ext/bg/js/templates.js b/ext/bg/js/templates.js deleted file mode 100644 index 2f65be31..00000000 --- a/ext/bg/js/templates.js +++ /dev/null @@ -1,55 +0,0 @@ -(function() { - var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; -templates['query-parser.html'] = template({"1":function(container,depth0,helpers,partials,data) { - var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}); - - return ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.preview : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "") - + ((stack1 = helpers.each.call(alias1,depth0,{"name":"each","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "</span>"; -},"2":function(container,depth0,helpers,partials,data) { - return "<span class=\"query-parser-term-preview\">"; -},"4":function(container,depth0,helpers,partials,data) { - return "<span class=\"query-parser-term\">"; -},"6":function(container,depth0,helpers,partials,data) { - var stack1; - - return ((stack1 = container.invokePartial(partials.part,depth0,{"name":"part","data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : ""); -},"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(12, data, 0),"data":data})) != null ? stack1 : ""); -},"9":function(container,depth0,helpers,partials,data) { - var stack1; - - 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>" - + ((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>" - + 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>"; -},"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(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; - - fn = decorators.inline(fn,props,container,{"name":"inline","hash":{},"fn":container.program(1, data, 0, blockParams, depths),"inverse":container.noop,"args":["term"],"data":data}) || fn; - fn = decorators.inline(fn,props,container,{"name":"inline","hash":{},"fn":container.program(8, data, 0, blockParams, depths),"inverse":container.noop,"args":["part"],"data":data}) || fn; - return fn; - } - -,"useDecorators":true,"usePartial":true,"useData":true,"useDepths":true}); -})();
\ No newline at end of file |