From 03f7ca23e118c5ca804eef35cea05070e69779c7 Mon Sep 17 00:00:00 2001
From: siikamiika <siikamiika@users.noreply.github.com>
Date: Sun, 15 Oct 2017 05:19:16 +0300
Subject: merged mode: add secondary searches

---
 ext/bg/js/database.js   | 26 ++++++++++++++++++++++++++
 ext/bg/js/settings.js   | 12 +++++++-----
 ext/bg/js/templates.js  |  4 +++-
 ext/bg/js/translator.js | 20 ++++++++++++++++++--
 4 files changed, 54 insertions(+), 8 deletions(-)

(limited to 'ext')

diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js
index 8350e214..dea78196 100644
--- a/ext/bg/js/database.js
+++ b/ext/bg/js/database.js
@@ -86,6 +86,32 @@ class Database {
         return results;
     }
 
+    async findTermsExact(term, reading, titles) {
+        if (!this.db) {
+            throw 'Database not initialized';
+        }
+
+        const results = [];
+        await this.db.terms.where('expression').equals(term).each(row => {
+            if (row.reading === reading && titles.includes(row.dictionary)) {
+                results.push({
+                    expression: row.expression,
+                    reading: row.reading,
+                    definitionTags: dictFieldSplit(row.definitionTags),
+                    termTags: dictFieldSplit(row.termTags || ''),
+                    rules: dictFieldSplit(row.rules),
+                    glossary: row.glossary,
+                    score: row.score,
+                    dictionary: row.dictionary,
+                    id: row.id,
+                    sequence: typeof row.sequence === 'undefined' ? -1 : row.sequence
+                });
+            }
+        });
+
+        return results;
+    }
+
     async findTermsBySequence(sequence, mainDictionary) {
         if (!this.db) {
             throw 'Database not initialized';
diff --git a/ext/bg/js/settings.js b/ext/bg/js/settings.js
index f59c3ad0..b9c59a4a 100644
--- a/ext/bg/js/settings.js
+++ b/ext/bg/js/settings.js
@@ -62,7 +62,8 @@ async function formRead() {
         const priority = parseInt(dictionary.find('.dict-priority').val(), 10);
         const enabled = dictionary.find('.dict-enabled').prop('checked');
         const main = dictionary.find('.dict-main').prop('checked');
-        optionsNew.dictionaries[title] = {priority, enabled, main};
+        const allowSecondarySearches = dictionary.find('.dict-allow-secondary-searches').prop('checked');
+        optionsNew.dictionaries[title] = {priority, enabled, main, allowSecondarySearches};
     });
 
     return {optionsNew, optionsOld};
@@ -262,14 +263,15 @@ async function dictionaryGroupsPopulate(options) {
     }
 
     for (const dictRow of dictRowsSort(dictRows, options)) {
-        const dictOptions = options.dictionaries[dictRow.title] || {enabled: false, priority: 0, main: false};
+        const dictOptions = options.dictionaries[dictRow.title] || {enabled: false, priority: 0, main: false, allowSecondarySearches: false};
         const dictHtml = await apiTemplateRender('dictionary.html', {
             title: dictRow.title,
             version: dictRow.version,
             revision: dictRow.revision,
             priority: dictOptions.priority,
             enabled: dictOptions.enabled,
-            main: dictOptions.main
+            main: dictOptions.main,
+            allowSecondarySearches: dictOptions.allowSecondarySearches
         });
 
         dictGroups.append($(dictHtml));
@@ -277,7 +279,7 @@ async function dictionaryGroupsPopulate(options) {
 
     formUpdateVisibility(options);
 
-    $('.dict-enabled, .dict-priority').change(e => {
+    $('.dict-enabled, .dict-priority, .dict-allow-secondary-searches').change(e => {
         dictionaryGroupsSort();
         onFormOptionsChanged(e);
     });
@@ -329,7 +331,7 @@ async function onDictionaryImport(e) {
 
         const options = await optionsLoad();
         const summary = await utilDatabaseImport(e.target.files[0], updateProgress);
-        options.dictionaries[summary.title] = {enabled: true, priority: 0, main: false};
+        options.dictionaries[summary.title] = {enabled: true, priority: 0, main: false, allowSecondarySearches: false};
         await optionsSave(options);
 
         await dictionaryGroupsPopulate(options);
diff --git a/ext/bg/js/templates.js b/ext/bg/js/templates.js
index b7b4721e..2e13053b 100644
--- a/ext/bg/js/templates.js
+++ b/ext/bg/js/templates.js
@@ -13,7 +13,9 @@ templates['dictionary.html'] = template({"1":function(container,depth0,helpers,p
     + alias4(((helper = (helper = helpers.revision || (depth0 != null ? depth0.revision : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"revision","hash":{},"data":data}) : helper)))
     + "</small></h4>\n\n    <div class=\"checkbox\">\n        <label><input type=\"checkbox\" class=\"dict-enabled\" "
     + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.enabled : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
-    + "> Enable search</label>\n        <label><input type=\"radio\" class=\"dict-main\" "
+    + "> Enable search</label>\n    </div>\n    <div class=\"checkbox options-advanced\">\n        <label><input type=\"checkbox\" class=\"dict-allow-secondary-searches\" "
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.allowSecondarySearches : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "> Allow secondary searches</label>\n    </div>\n    <div class=\"radio\">\n        <label><input type=\"radio\" class=\"dict-main\" "
     + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.main : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
     + "> Set as main dictionary</label>\n    </div>\n    <div class=\"form-group options-advanced\">\n        <label for=\"dict-"
     + alias4(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"title","hash":{},"data":data}) : helper)))
diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js
index c102f6a8..29bb857b 100644
--- a/ext/bg/js/translator.js
+++ b/ext/bg/js/translator.js
@@ -58,6 +58,7 @@ class Translator {
     async findTermsMerged(text, dictionaries, alphanumeric) {
         const options = await apiOptionsGet();
         const mainDictionary = Object.keys(options.dictionaries).filter(dict => options.dictionaries[dict].main).concat([''])[0];
+        const secondarySearchTitles = Object.keys(options.dictionaries).filter(dict => options.dictionaries[dict].allowSecondarySearches);
         const titles = Object.keys(dictionaries);
         const {length, definitions} = await this.findTerms(text, dictionaries, alphanumeric);
 
@@ -74,7 +75,23 @@ class Translator {
 
             const rawDefinitionsBySequence = await this.database.findTermsBySequence(Number(sequence), mainDictionary);
             const definitionsByGloss = dictTermsMergeByGloss(result, rawDefinitionsBySequence);
-            dictTermsMergeByGloss(result, definitionsBySequence['-1'], definitionsByGloss, mergedByTermIndices);
+
+            const secondarySearchResults = [];
+            if (secondarySearchTitles.length) {
+                for (const expression of result.expressions.keys()) {
+                    if (expression === text) {
+                        continue;
+                    }
+
+                    for (const reading of result.expressions.get(expression).keys()) {
+                        for (const definition of await this.database.findTermsExact(expression, reading, secondarySearchTitles)) {
+                            secondarySearchResults.push(definition);
+                        }
+                    }
+                }
+            }
+
+            dictTermsMergeByGloss(result, definitionsBySequence['-1'].concat(secondarySearchResults), definitionsByGloss, mergedByTermIndices);
 
             for (const gloss in definitionsByGloss) {
                 const definition = definitionsByGloss[gloss];
@@ -88,7 +105,6 @@ class Translator {
 
             dictTermsSort(result.definitions, dictionaries);
 
-            // turn the Map()/Set() mess to [{expression: E1, reading: R1}, {...}] and tag popular/normal/rare instead of actual tags
             const expressions = [];
             for (const expression of result.expressions.keys()) {
                 for (const reading of result.expressions.get(expression).keys()) {
-- 
cgit v1.2.3