From 516c7f5381700700dcfdfb06682f11de8205137b Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sun, 16 Jul 2017 12:48:27 -0700 Subject: refactor mixed/js/util.js --- ext/bg/background.html | 2 +- ext/bg/search.html | 2 +- ext/fg/frame.html | 2 +- ext/mixed/js/audio.js | 130 ++++++++++++++++++++++++++++++++++++++++++ ext/mixed/js/display.js | 18 +++++- ext/mixed/js/util.js | 149 ------------------------------------------------ 6 files changed, 149 insertions(+), 154 deletions(-) create mode 100644 ext/mixed/js/audio.js delete mode 100644 ext/mixed/js/util.js diff --git a/ext/bg/background.html b/ext/bg/background.html index 4410c249..4a2d8c8d 100644 --- a/ext/bg/background.html +++ b/ext/bg/background.html @@ -8,7 +8,7 @@ - + diff --git a/ext/bg/search.html b/ext/bg/search.html index 4c07ee61..0fc3caf7 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -34,7 +34,7 @@ - + diff --git a/ext/fg/frame.html b/ext/fg/frame.html index c20745af..ecaee323 100644 --- a/ext/fg/frame.html +++ b/ext/fg/frame.html @@ -33,7 +33,7 @@ - + diff --git a/ext/mixed/js/audio.js b/ext/mixed/js/audio.js new file mode 100644 index 00000000..451fe1d9 --- /dev/null +++ b/ext/mixed/js/audio.js @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2017 Alex Yatskov + * Author: Alex Yatskov + * + * 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 . + */ + + +/* + * Audio + */ + +async function audioBuildUrl(definition, mode, cache={}) { + if (mode === 'jpod101') { + let kana = definition.reading; + let kanji = definition.expression; + + if (!kana && wanakana.isHiragana(kanji)) { + kana = kanji; + kanji = null; + } + + const params = []; + if (kanji) { + params.push(`kanji=${encodeURIComponent(kanji)}`); + } + if (kana) { + params.push(`kana=${encodeURIComponent(kana)}`); + } + + const url = `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`; + return Promise.resolve(url); + } else if (mode === 'jpod101-alternate') { + return new Promise((resolve, reject) => { + const response = cache[definition.expression]; + if (response) { + resolve(response); + } else { + const data = { + post: 'dictionary_reference', + match_type: 'exact', + search_query: definition.expression + }; + + const params = []; + for (const key in data) { + params.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`); + } + + const xhr = new XMLHttpRequest(); + xhr.open('POST', 'https://www.japanesepod101.com/learningcenter/reference/dictionary_post'); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xhr.addEventListener('error', () => reject('failed to scrape audio data')); + xhr.addEventListener('load', () => { + cache[definition.expression] = xhr.responseText; + resolve(xhr.responseText); + }); + + xhr.send(params.join('&')); + } + }).then(response => { + const dom = new DOMParser().parseFromString(response, 'text/html'); + for (const row of dom.getElementsByClassName('dc-result-row')) { + try { + const url = row.getElementsByClassName('ill-onebuttonplayer').item(0).getAttribute('data-url'); + const reading = row.getElementsByClassName('dc-vocab_kana').item(0).innerText; + if (url && reading && (!definition.reading || definition.reading === reading)) { + return url; + } + } catch (e) { + // NOP + } + } + }); + } else { + return Promise.resolve(); + } +} + +function audioBuildFilename(definition) { + if (definition.reading || definition.expression) { + let filename = 'yomichan'; + if (definition.reading) { + filename += `_${definition.reading}`; + } + if (definition.expression) { + filename += `_${definition.expression}`; + } + + return filename += '.mp3'; + } +} + +async function audioInject(definition, fields, mode) { + let usesAudio = false; + for (const name in fields) { + if (fields[name].includes('{audio}')) { + usesAudio = true; + break; + } + } + + if (!usesAudio) { + return true; + } + + try { + const url = await audioBuildUrl(definition, mode); + const filename = audioBuildFilename(definition); + + if (url && filename) { + definition.audio = {url, filename}; + } + + return true; + } catch (e) { + return false; + } +} diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index da0cd351..e54bc0f9 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -80,7 +80,7 @@ class Display { if (context) { for (const definition of definitions) { if (context.sentence) { - definition.cloze = clozeBuild(context.sentence, definition.source); + definition.cloze = Display.clozeBuild(context.sentence, definition.source); } definition.url = context.url; @@ -119,7 +119,7 @@ class Display { if (context) { for (const definition of definitions) { if (context.sentence) { - definition.cloze = clozeBuild(context.sentence); + definition.cloze = Display.clozeBuild(context.sentence); } definition.url = context.url; @@ -394,6 +394,20 @@ class Display { }).catch(this.handleError.bind(this)).then(() => this.spinner.hide()); } + static clozeBuild(sentence, source) { + const result = { + sentence: sentence.text.trim() + }; + + if (source) { + result.prefix = sentence.text.substring(0, sentence.offset).trim(); + result.body = source.trim(); + result.suffix = sentence.text.substring(sentence.offset + source.length).trim(); + } + + return result; + } + static entryIndexFind(element) { return $('.entry').index(element.closest('.entry')); } diff --git a/ext/mixed/js/util.js b/ext/mixed/js/util.js deleted file mode 100644 index 0a8c914d..00000000 --- a/ext/mixed/js/util.js +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2017 Alex Yatskov - * Author: Alex Yatskov - * - * 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 . - */ - - -/* - * Cloze - */ - -function clozeBuild(sentence, source) { - const result = { - sentence: sentence.text.trim() - }; - - if (source) { - result.prefix = sentence.text.substring(0, sentence.offset).trim(); - result.body = source.trim(); - result.suffix = sentence.text.substring(sentence.offset + source.length).trim(); - } - - return result; -} - - -/* - * Audio - */ - -async function audioBuildUrl(definition, mode, cache={}) { - if (mode === 'jpod101') { - let kana = definition.reading; - let kanji = definition.expression; - - if (!kana && wanakana.isHiragana(kanji)) { - kana = kanji; - kanji = null; - } - - const params = []; - if (kanji) { - params.push(`kanji=${encodeURIComponent(kanji)}`); - } - if (kana) { - params.push(`kana=${encodeURIComponent(kana)}`); - } - - const url = `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`; - return Promise.resolve(url); - } else if (mode === 'jpod101-alternate') { - return new Promise((resolve, reject) => { - const response = cache[definition.expression]; - if (response) { - resolve(response); - } else { - const data = { - post: 'dictionary_reference', - match_type: 'exact', - search_query: definition.expression - }; - - const params = []; - for (const key in data) { - params.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`); - } - - const xhr = new XMLHttpRequest(); - xhr.open('POST', 'https://www.japanesepod101.com/learningcenter/reference/dictionary_post'); - xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - xhr.addEventListener('error', () => reject('failed to scrape audio data')); - xhr.addEventListener('load', () => { - cache[definition.expression] = xhr.responseText; - resolve(xhr.responseText); - }); - - xhr.send(params.join('&')); - } - }).then(response => { - const dom = new DOMParser().parseFromString(response, 'text/html'); - for (const row of dom.getElementsByClassName('dc-result-row')) { - try { - const url = row.getElementsByClassName('ill-onebuttonplayer').item(0).getAttribute('data-url'); - const reading = row.getElementsByClassName('dc-vocab_kana').item(0).innerText; - if (url && reading && (!definition.reading || definition.reading === reading)) { - return url; - } - } catch (e) { - // NOP - } - } - }); - } else { - return Promise.resolve(); - } -} - -function audioBuildFilename(definition) { - if (definition.reading || definition.expression) { - let filename = 'yomichan'; - if (definition.reading) { - filename += `_${definition.reading}`; - } - if (definition.expression) { - filename += `_${definition.expression}`; - } - - return filename += '.mp3'; - } -} - -async function audioInject(definition, fields, mode) { - let usesAudio = false; - for (const name in fields) { - if (fields[name].includes('{audio}')) { - usesAudio = true; - break; - } - } - - if (!usesAudio) { - return true; - } - - try { - const url = await audioBuildUrl(definition, mode); - const filename = audioBuildFilename(definition); - - if (url && filename) { - definition.audio = {url, filename}; - } - - return true; - } catch (e) { - return false; - } -} -- cgit v1.2.3