diff options
| -rw-r--r-- | ext/bg/background.html | 2 | ||||
| -rw-r--r-- | ext/bg/js/dictionary.js | 233 | ||||
| -rw-r--r-- | ext/bg/js/util.js | 237 | ||||
| -rw-r--r-- | ext/bg/popup.html | 2 | ||||
| -rw-r--r-- | ext/bg/search.html | 2 | ||||
| -rw-r--r-- | ext/bg/settings.html | 2 | ||||
| -rw-r--r-- | ext/mixed/js/japanese.js | 31 | 
7 files changed, 272 insertions, 237 deletions
| diff --git a/ext/bg/background.html b/ext/bg/background.html index a9071cc7..3cfd894e 100644 --- a/ext/bg/background.html +++ b/ext/bg/background.html @@ -11,6 +11,8 @@          <script src="/mixed/js/audio.js"></script>          <script src="/bg/js/templates.js"></script>          <script src="/bg/js/util.js"></script> +        <script src="/bg/js/dictionary.js"></script> +        <script src="/mixed/js/japanese.js"></script>          <script src="/bg/js/options.js"></script>          <script src="/bg/js/anki-connect.js"></script>          <script src="/bg/js/anki-null.js"></script> diff --git a/ext/bg/js/dictionary.js b/ext/bg/js/dictionary.js new file mode 100644 index 00000000..6f4ec809 --- /dev/null +++ b/ext/bg/js/dictionary.js @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2016  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 <http://www.gnu.org/licenses/>. + */ + + +function dictEnabledSet(options) { +    const dictionaries = {}; +    for (const title in options.dictionaries) { +        const dictionary = options.dictionaries[title]; +        if (dictionary.enabled) { +            dictionaries[title] = dictionary; +        } +    } + +    return dictionaries; +} + +function dictConfigured(options) { +    for (const title in options.dictionaries) { +        if (options.dictionaries[title].enabled) { +            return true; +        } +    } + +    return false; +} + +function dictRowsSort(rows, options) { +    return rows.sort((ra, rb) => { +        const pa = (options.dictionaries[ra.title] || {}).priority || 0; +        const pb = (options.dictionaries[rb.title] || {}).priority || 0; +        if (pa > pb) { +            return -1; +        } else if (pa < pb) { +            return 1; +        } else { +            return 0; +        } +    }); +} + +function dictTermsSort(definitions, dictionaries=null) { +    return definitions.sort((v1, v2) => { +        const sl1 = v1.source.length; +        const sl2 = v2.source.length; +        if (sl1 > sl2) { +            return -1; +        } else if (sl1 < sl2) { +            return 1; +        } + +        if (dictionaries !== null) { +            const p1 = (dictionaries[v1.dictionary] || {}).priority || 0; +            const p2 = (dictionaries[v2.dictionary] || {}).priority || 0; +            if (p1 > p2) { +                return -1; +            } else if (p1 < p2) { +                return 1; +            } +        } + +        const s1 = v1.score; +        const s2 = v2.score; +        if (s1 > s2) { +            return -1; +        } else if (s1 < s2) { +            return 1; +        } + +        const rl1 = v1.reasons.length; +        const rl2 = v2.reasons.length; +        if (rl1 < rl2) { +            return -1; +        } else if (rl1 > rl2) { +            return 1; +        } + +        return v2.expression.localeCompare(v1.expression); +    }); +} + +function dictTermsUndupe(definitions) { +    const definitionGroups = {}; +    for (const definition of definitions) { +        const definitionExisting = definitionGroups[definition.id]; +        if (!definitionGroups.hasOwnProperty(definition.id) || definition.expression.length > definitionExisting.expression.length) { +            definitionGroups[definition.id] = definition; +        } +    } + +    const definitionsUnique = []; +    for (const key in definitionGroups) { +        definitionsUnique.push(definitionGroups[key]); +    } + +    return definitionsUnique; +} + +function dictTermsGroup(definitions, dictionaries) { +    const groups = {}; +    for (const definition of definitions) { +        const key = [definition.source, definition.expression].concat(definition.reasons); +        if (definition.reading) { +            key.push(definition.reading); +        } + +        const group = groups[key]; +        if (group) { +            group.push(definition); +        } else { +            groups[key] = [definition]; +        } +    } + +    const results = []; +    for (const key in groups) { +        const groupDefs = groups[key]; +        const firstDef = groupDefs[0]; +        dictTermsSort(groupDefs, dictionaries); +        results.push({ +            definitions: groupDefs, +            expression: firstDef.expression, +            reading: firstDef.reading, +            reasons: firstDef.reasons, +            score: groupDefs.reduce((p, v) => v.score > p ? v.score : p, Number.MIN_SAFE_INTEGER), +            source: firstDef.source +        }); +    } + +    return dictTermsSort(results); +} + +function dictTagBuildSource(name) { +    return dictTagSanitize({name, category: 'dictionary', order: 100}); +} + +function dictTagBuild(name, meta) { +    const tag = {name}; +    const symbol = name.split(':')[0]; +    for (const prop in meta[symbol] || {}) { +        tag[prop] = meta[symbol][prop]; +    } + +    return dictTagSanitize(tag); +} + +function dictTagSanitize(tag) { +    tag.name = tag.name || 'untitled'; +    tag.category = tag.category || 'default'; +    tag.notes = tag.notes || ''; +    tag.order = tag.order || 0; +    return tag; +} + +function dictTagsSort(tags) { +    return tags.sort((v1, v2) => { +        const order1 = v1.order; +        const order2 = v2.order; +        if (order1 < order2) { +            return -1; +        } else if (order1 > order2) { +            return 1; +        } + +        const name1 = v1.name; +        const name2 = v2.name; +        if (name1 < name2) { +            return -1; +        } else if (name1 > name2) { +            return 1; +        } + +        return 0; +    }); +} + +function dictFieldSplit(field) { +    return field.length === 0 ? [] : field.split(' '); +} + +function dictFieldFormat(field, definition, mode, options) { +    const markers = [ +        'audio', +        'character', +        'cloze-body', +        'cloze-prefix', +        'cloze-suffix', +        'dictionary', +        'expression', +        'furigana', +        'glossary', +        'glossary-brief', +        'kunyomi', +        'onyomi', +        'reading', +        'sentence', +        'tags', +        'url' +    ]; + +    for (const marker of markers) { +        const data = { +            marker, +            definition, +            group: options.general.groupResults, +            html: options.anki.htmlCards, +            modeTermKanji: mode === 'term-kanji', +            modeTermKana: mode === 'term-kana', +            modeKanji: mode === 'kanji' +        }; + +        field = field.replace( +            `{${marker}}`, +            Handlebars.templates['fields.html'](data).trim() +        ); +    } + +    return field; +} diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index 5d80fdb7..0a4592ea 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -31,24 +31,6 @@ function promiseCallback(promise, callback) {  /* - * Japanese - */ - -function jpIsKanji(c) { -    const code = c.charCodeAt(0); -    return code >= 0x4e00 && code < 0x9fb0 || code >= 0x3400 && code < 0x4dc0; -} - -function jpIsKana(c) { -    return wanakana.isKana(c); -} - -function jpKatakanaToHiragana(text) { -    return wanakana._katakanaToHiragana(text); -} - - -/*   * Commands   */ @@ -92,225 +74,6 @@ function fgOptionsSet(options) {  /* - * Dictionary - */ - -function dictEnabledSet(options) { -    const dictionaries = {}; -    for (const title in options.dictionaries) { -        const dictionary = options.dictionaries[title]; -        if (dictionary.enabled) { -            dictionaries[title] = dictionary; -        } -    } - -    return dictionaries; -} - -function dictConfigured(options) { -    for (const title in options.dictionaries) { -        if (options.dictionaries[title].enabled) { -            return true; -        } -    } - -    return false; -} - -function dictRowsSort(rows, options) { -    return rows.sort((ra, rb) => { -        const pa = (options.dictionaries[ra.title] || {}).priority || 0; -        const pb = (options.dictionaries[rb.title] || {}).priority || 0; -        if (pa > pb) { -            return -1; -        } else if (pa < pb) { -            return 1; -        } else { -            return 0; -        } -    }); -} - -function dictTermsSort(definitions, dictionaries=null) { -    return definitions.sort((v1, v2) => { -        const sl1 = v1.source.length; -        const sl2 = v2.source.length; -        if (sl1 > sl2) { -            return -1; -        } else if (sl1 < sl2) { -            return 1; -        } - -        if (dictionaries !== null) { -            const p1 = (dictionaries[v1.dictionary] || {}).priority || 0; -            const p2 = (dictionaries[v2.dictionary] || {}).priority || 0; -            if (p1 > p2) { -                return -1; -            } else if (p1 < p2) { -                return 1; -            } -        } - -        const s1 = v1.score; -        const s2 = v2.score; -        if (s1 > s2) { -            return -1; -        } else if (s1 < s2) { -            return 1; -        } - -        const rl1 = v1.reasons.length; -        const rl2 = v2.reasons.length; -        if (rl1 < rl2) { -            return -1; -        } else if (rl1 > rl2) { -            return 1; -        } - -        return v2.expression.localeCompare(v1.expression); -    }); -} - -function dictTermsUndupe(definitions) { -    const definitionGroups = {}; -    for (const definition of definitions) { -        const definitionExisting = definitionGroups[definition.id]; -        if (!definitionGroups.hasOwnProperty(definition.id) || definition.expression.length > definitionExisting.expression.length) { -            definitionGroups[definition.id] = definition; -        } -    } - -    const definitionsUnique = []; -    for (const key in definitionGroups) { -        definitionsUnique.push(definitionGroups[key]); -    } - -    return definitionsUnique; -} - -function dictTermsGroup(definitions, dictionaries) { -    const groups = {}; -    for (const definition of definitions) { -        const key = [definition.source, definition.expression].concat(definition.reasons); -        if (definition.reading) { -            key.push(definition.reading); -        } - -        const group = groups[key]; -        if (group) { -            group.push(definition); -        } else { -            groups[key] = [definition]; -        } -    } - -    const results = []; -    for (const key in groups) { -        const groupDefs = groups[key]; -        const firstDef = groupDefs[0]; -        dictTermsSort(groupDefs, dictionaries); -        results.push({ -            definitions: groupDefs, -            expression: firstDef.expression, -            reading: firstDef.reading, -            reasons: firstDef.reasons, -            score: groupDefs.reduce((p, v) => v.score > p ? v.score : p, Number.MIN_SAFE_INTEGER), -            source: firstDef.source -        }); -    } - -    return dictTermsSort(results); -} - -function dictTagBuildSource(name) { -    return dictTagSanitize({name, category: 'dictionary', order: 100}); -} - -function dictTagBuild(name, meta) { -    const tag = {name}; -    const symbol = name.split(':')[0]; -    for (const prop in meta[symbol] || {}) { -        tag[prop] = meta[symbol][prop]; -    } - -    return dictTagSanitize(tag); -} - -function dictTagSanitize(tag) { -    tag.name = tag.name || 'untitled'; -    tag.category = tag.category || 'default'; -    tag.notes = tag.notes || ''; -    tag.order = tag.order || 0; -    return tag; -} - -function dictTagsSort(tags) { -    return tags.sort((v1, v2) => { -        const order1 = v1.order; -        const order2 = v2.order; -        if (order1 < order2) { -            return -1; -        } else if (order1 > order2) { -            return 1; -        } - -        const name1 = v1.name; -        const name2 = v2.name; -        if (name1 < name2) { -            return -1; -        } else if (name1 > name2) { -            return 1; -        } - -        return 0; -    }); -} - -function dictFieldSplit(field) { -    return field.length === 0 ? [] : field.split(' '); -} - -function dictFieldFormat(field, definition, mode, options) { -    const markers = [ -        'audio', -        'character', -        'cloze-body', -        'cloze-prefix', -        'cloze-suffix', -        'dictionary', -        'expression', -        'furigana', -        'glossary', -        'glossary-brief', -        'kunyomi', -        'onyomi', -        'reading', -        'sentence', -        'tags', -        'url' -    ]; - -    for (const marker of markers) { -        const data = { -            marker, -            definition, -            group: options.general.groupResults, -            html: options.anki.htmlCards, -            modeTermKanji: mode === 'term-kanji', -            modeTermKana: mode === 'term-kana', -            modeKanji: mode === 'kanji' -        }; - -        field = field.replace( -            `{${marker}}`, -            Handlebars.templates['fields.html'](data).trim() -        ); -    } - -    return field; -} - -/*   * JSON   */ diff --git a/ext/bg/popup.html b/ext/bg/popup.html index ab2ee1e0..db9097bd 100644 --- a/ext/bg/popup.html +++ b/ext/bg/popup.html @@ -31,6 +31,8 @@          <script src="/mixed/lib/bootstrap-toggle/bootstrap-toggle.min.js"></script>          <script src="/mixed/lib/handlebars.min.js"></script>          <script src="/bg/js/util.js"></script> +        <script src="/bg/js/dictionary.js"></script> +        <script src="/mixed/js/japanese.js"></script>          <script src="/bg/js/options.js"></script>          <script src="/bg/js/popup.js"></script>      </body> diff --git a/ext/bg/search.html b/ext/bg/search.html index 0fc3caf7..b30b8910 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -34,6 +34,8 @@          <script src="/mixed/lib/jquery.min.js"></script>          <script src="/bg/js/util.js"></script> +        <script src="/bg/js/dictionary.js"></script> +        <script src="/mixed/js/japanese.js"></script>          <script src="/mixed/js/audio.js"></script>          <script src="/mixed/js/display.js"></script>          <script src="/mixed/lib/wanakana.min.js"></script> diff --git a/ext/bg/settings.html b/ext/bg/settings.html index ada3299b..8135ca9a 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -277,6 +277,8 @@          <script src="/mixed/lib/handlebars.min.js"></script>          <script src="/bg/js/templates.js"></script>          <script src="/bg/js/util.js"></script> +        <script src="/bg/js/dictionary.js"></script> +        <script src="/mixed/js/japanese.js"></script>          <script src="/bg/js/options.js"></script>          <script src="/bg/js/settings.js"></script>      </body> diff --git a/ext/mixed/js/japanese.js b/ext/mixed/js/japanese.js new file mode 100644 index 00000000..779e3d35 --- /dev/null +++ b/ext/mixed/js/japanese.js @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016  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 <http://www.gnu.org/licenses/>. + */ + + +function jpIsKanji(c) { +    const code = c.charCodeAt(0); +    return code >= 0x4e00 && code < 0x9fb0 || code >= 0x3400 && code < 0x4dc0; +} + +function jpIsKana(c) { +    return wanakana.isKana(c); +} + +function jpKatakanaToHiragana(text) { +    return wanakana._katakanaToHiragana(text); +} |