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(); |