diff options
Diffstat (limited to 'ext/bg/js/util.js')
| -rw-r--r-- | ext/bg/js/util.js | 154 | 
1 files changed, 131 insertions, 23 deletions
| diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index 059f3160..504deeda 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -21,7 +21,7 @@ function kanjiLinks(options) {      let result = '';      for (const c of options.fn(this)) {          if (isKanji(c)) { -            result += Handlebars.templates['kanji-link.html']({kanji: c}).trim(); +            result += `<a href="#" class="kanji-link">${c}</a>`;          } else {              result += c;          } @@ -30,6 +30,10 @@ function kanjiLinks(options) {      return result;  } +function multiLine(options) { +    return options.fn(this).split('\n').join('<br>'); +} +  function isKanji(c) {      const code = c.charCodeAt(0);      return code >= 0x4e00 && code < 0x9fb0 || code >= 0x3400 && code < 0x4dc0; @@ -44,28 +48,6 @@ function promiseCallback(promise, callback) {      });  } -function sortTags(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 sortTermDefs(definitions) {      return definitions.sort((v1, v2) => {          const sl1 = v1.source.length; @@ -113,6 +95,43 @@ function undupeTermDefs(definitions) {      return definitionsUnique;  } +function groupTermDefs(definitions) { +    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]; +        results.push({ +            definitions: groupDefs, +            expression: firstDef.expression, +            reading: firstDef.reading, +            reasons: firstDef.reasons, +            score: groupDefs.reduce((x, y) => x > y ? x : y, Number.MIN_SAFE_INTEGER), +            source: firstDef.source, +        }); +    } + +    return sortTermDefs(results); +} + +function buildDictTag(name) { +    return sanitizeTag({name, category: 'dictionary', order: 100}); +} +  function buildTag(name, meta) {      const tag = {name};      const symbol = name.split(':')[0]; @@ -135,6 +154,95 @@ function splitField(field) {      return field.length === 0 ? [] : field.split(' ');  } +function sortTags(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 formatField(field, definition, mode) { +    const markers = [ +        'audio', +        'character', +        'dictionary', +        'expression', +        'expression-furigana', +        'glossary', +        'glossary-list', +        'kunyomi', +        'onyomi', +        'reading', +        'sentence', +        'tags', +        'url', +    ]; + +    for (const marker of markers) { +        let value = definition[marker] || null; +        switch (marker) { +            case 'expression': +                if (mode === 'term_kana' && definition.reading) { +                    value = definition.reading; +                } +                break; +            case 'expression-furigana': +                if (mode === 'term_kana' && definition.reading) { +                    value = definition.reading; +                } else { +                    value = `<ruby>${definition.expression}<rt>${definition.reading}</rt></ruby>`; +                } +                break; +            case 'reading': +                if (mode === 'term_kana') { +                    value = null; +                } +                break; +            case 'glossary-list': +                if (definition.glossary) { +                    if (definition.glossary.length > 1) { +                        value = '<ol style="white-space: pre; text-align: left; overflow-x: auto;">'; +                        for (const gloss of definition.glossary) { +                            value += `<li>${gloss}</li>`; +                        } +                        value += '</ol>'; +                    } else { +                        value = `<p style="white-space: pre; overflow-x: auto;">${definition.glossary.join('')}</p>`; +                    } +                } +                break; +            case 'tags': +                if (definition.tags) { +                    value = definition.tags.map(t => t.name); +                } +                break; +        } + +        if (value !== null && typeof(value) !== 'string') { +            value = value.join(', '); +        } + +        field = field.replace(`{${marker}}`, value || ''); +    } + +    return field; +} +  function loadJson(url) {      return new Promise((resolve, reject) => {          const xhr = new XMLHttpRequest(); |