diff options
| -rw-r--r-- | ext/bg/js/database.js | 28 | ||||
| -rw-r--r-- | ext/bg/js/translator.js | 160 | 
2 files changed, 80 insertions, 108 deletions
| diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index 06312438..9eed8ea3 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -69,14 +69,14 @@ class Database {          await this.prepare();      } -    async findTerms(term, dictionaries) { +    async findTerms(term, titles) {          if (!this.db) {              throw 'database not initialized';          }          const results = [];          await this.db.terms.where('expression').equals(term).or('reading').equals(term).each(row => { -            if (dictionaries.includes(row.dictionary)) { +            if (titles.includes(row.dictionary)) {                  results.push({                      expression: row.expression,                      reading: row.reading, @@ -90,7 +90,7 @@ class Database {              }          }); -        await this.cacheTagMeta(dictionaries); +        await this.cacheTagMeta(titles);          for (const result of results) {              result.tagMeta = this.tagCache[result.dictionary] || {};          } @@ -98,14 +98,14 @@ class Database {          return results;      } -    async findKanji(kanji, dictionaries) { +    async findKanji(kanji, titles) {          if (!this.db) {              return Promise.reject('database not initialized');          }          const results = [];          await this.db.kanji.where('character').equals(kanji).each(row => { -            if (dictionaries.includes(row.dictionary)) { +            if (titles.includes(row.dictionary)) {                  results.push({                      character: row.character,                      onyomi: dictFieldSplit(row.onyomi), @@ -117,7 +117,7 @@ class Database {              }          }); -        await this.cacheTagMeta(dictionaries); +        await this.cacheTagMeta(titles);          for (const result of results) {              result.tagMeta = this.tagCache[result.dictionary] || {};          } @@ -125,29 +125,29 @@ class Database {          return results;      } -    async cacheTagMeta(dictionaries) { +    async cacheTagMeta(titles) {          if (!this.db) {              throw 'database not initialized';          } -        for (const dictionary of dictionaries) { -            if (!this.tagCache[dictionary]) { +        for (const title of titles) { +            if (!this.tagCache[title]) {                  const tagMeta = {}; -                await this.db.tagMeta.where('dictionary').equals(dictionary).each(row => { +                await this.db.tagMeta.where('dictionary').equals(title).each(row => {                      tagMeta[row.name] = {category: row.category, notes: row.notes, order: row.order};                  }); -                this.tagCache[dictionary] = tagMeta; +                this.tagCache[title] = tagMeta;              }          }      }      async getDictionaries() { -        if (!this.db) { +        if (this.db) { +            return this.db.dictionaries.toArray(); +        } else {              throw 'database not initialized';          } - -        return this.db.dictionaries.toArray();      }      async importDictionary(archive, callback) { diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index f1858247..35b49608 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -19,135 +19,107 @@  class Translator {      constructor() { -        this.loaded = false; -        this.ruleMeta = null;          this.database = new Database();          this.deinflector = new Deinflector(); +        this.loaded = false;      } -    prepare() { -        if (this.loaded) { -            return Promise.resolve(); -        } - -        const promises = [ -            jsonLoadInt('/bg/lang/deinflect.json'), -            this.database.prepare() -        ]; - -        return Promise.all(promises).then(([reasons]) => { +    async prepare() { +        if (!this.loaded) { +            const reasons = await jsonLoadInt('/bg/lang/deinflect.json');              this.deinflector.setReasons(reasons); +            await this.database.prepare();              this.loaded = true; -        }); +        }      } -    findTerms(text, dictionaries, alphanumeric) { -        const titles = Object.keys(dictionaries); -        const cache = {}; +    async findTermsGrouped(text, dictionaries, alphanumeric) { +        const {length, definitions} = await this.findTerms(text, dictionaries, alphanumeric); +        return {length, definitions: dictTermsGroup(definitions, dictionaries)}; +    } +    async findTerms(text, dictionaries, alphanumeric) {          if (!alphanumeric && text.length > 0) {              const c = text[0];              if (!jpIsKana(c) && !jpIsKanji(c)) { -                return Promise.resolve({length: 0, definitions: []}); +                return {length: 0, definitions: []};              }          } -        return this.findTermsDeinflected(text, titles, cache).then(deinfLiteral => { -            const textHiragana = jpKatakanaToHiragana(text); -            if (text === textHiragana) { -                return deinfLiteral; -            } else { -                return this.findTermsDeinflected(textHiragana, titles, cache).then(deinfHiragana => deinfLiteral.concat(deinfHiragana)); -            } -        }).then(deinflections => { -            let definitions = []; -            for (const deinflection of deinflections) { -                for (const definition of deinflection.definitions) { -                    const tags = definition.tags.map(tag => dictTagBuild(tag, definition.tagMeta)); -                    tags.push(dictTagBuildSource(definition.dictionary)); -                    definitions.push({ -                        source: deinflection.source, -                        reasons: deinflection.reasons, -                        score: definition.score, -                        id: definition.id, -                        dictionary: definition.dictionary, -                        expression: definition.expression, -                        reading: definition.reading, -                        glossary: definition.glossary, -                        tags: dictTagsSort(tags) -                    }); -                } -            } - -            definitions = dictTermsUndupe(definitions); -            definitions = dictTermsSort(definitions, dictionaries); - -            let length = 0; -            for (const definition of definitions) { -                length = Math.max(length, definition.source.length); -            } - -            return {length, definitions}; -        }); -    } - -    findTermsGrouped(text, dictionaries, alphanumeric) { -        return this.findTerms(text, dictionaries, alphanumeric).then(({length, definitions}) => { -            return {length, definitions: dictTermsGroup(definitions, dictionaries)}; -        }); -    } - -    findKanji(text, dictionaries) { +        const cache = {};          const titles = Object.keys(dictionaries); -        const processed = {}; -        const promises = []; - -        for (const c of text) { -            if (!processed[c]) { -                promises.push(this.database.findKanji(c, titles)); -                processed[c] = true; -            } +        let deinflections = await this.findTermsDeinflected(text, titles, cache); +        const textHiragana = jpKatakanaToHiragana(text); +        if (text !== textHiragana) { +            deinflections = deinflections.concat(await this.findTermsDeinflected(textHiragana, titles, cache));          } -        return Promise.all(promises).then(defSets => { -            const definitions = defSets.reduce((a, b) => a.concat(b), []); -            for (const definition of definitions) { +        let definitions = []; +        for (const deinflection of deinflections) { +            for (const definition of deinflection.definitions) {                  const tags = definition.tags.map(tag => dictTagBuild(tag, definition.tagMeta));                  tags.push(dictTagBuildSource(definition.dictionary)); -                definition.tags = dictTagsSort(tags); +                definitions.push({ +                    source: deinflection.source, +                    reasons: deinflection.reasons, +                    score: definition.score, +                    id: definition.id, +                    dictionary: definition.dictionary, +                    expression: definition.expression, +                    reading: definition.reading, +                    glossary: definition.glossary, +                    tags: dictTagsSort(tags) +                });              } +        } + +        definitions = dictTermsUndupe(definitions); +        definitions = dictTermsSort(definitions, dictionaries); -            return definitions; -        }); +        let length = 0; +        for (const definition of definitions) { +            length = Math.max(length, definition.source.length); +        } + +        return {length, definitions};      } -    findTermsDeinflected(text, dictionaries, cache) { -        const definer = term => { +    async findTermsDeinflected(text, dictionaries, cache) { +        await this.prepare(); + +        const definer = async term => {              if (cache.hasOwnProperty(term)) { -                return Promise.resolve(cache[term]); +                return cache[term]; +            } else { +                return cache[term] = await this.database.findTerms(term, dictionaries);              } - -            return this.database.findTerms(term, dictionaries).then(definitions => cache[term] = definitions);          }; -        const promises = []; +        let deinflections = [];          for (let i = text.length; i > 0; --i) { -            promises.push(this.deinflector.deinflect(text.slice(0, i), definer)); +            const textSlice = text.slice(0, i); +            deinflections = deinflections.concat(await this.deinflector.deinflect(textSlice, definer));          } -        return Promise.all(promises).then(results => { -            let deinflections = []; -            for (const result of results) { -                deinflections = deinflections.concat(result); -            } - -            return deinflections; -        }); +        return deinflections;      } -    processKanji(definitions) { +    async findKanji(text, dictionaries) { +        await this.prepare(); + +        let definitions = []; +        const processed = {}; +        const titles = Object.keys(dictionaries); +        for (const c of text) { +            if (!processed[c]) { +                definitions = definitions.concat(await this.database.findKanji(c, titles)); +                processed[c] = true; +            } +        } +          for (const definition of definitions) {              const tags = definition.tags.map(tag => dictTagBuild(tag, definition.tagMeta)); +            tags.push(dictTagBuildSource(definition.dictionary));              definition.tags = dictTagsSort(tags);          } |