aboutsummaryrefslogtreecommitdiff
path: root/ext/mixed
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mixed')
-rw-r--r--ext/mixed/js/display.js152
1 files changed, 94 insertions, 58 deletions
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js
index 25a095e0..45c1e08c 100644
--- a/ext/mixed/js/display.js
+++ b/ext/mixed/js/display.js
@@ -23,6 +23,7 @@ class Display {
this.container = container;
this.definitions = [];
this.audioCache = {};
+ this.responseCache = {};
this.sequence = 0;
this.index = 0;
@@ -261,91 +262,118 @@ class Display {
noteAdd(index, mode) {
this.spinner.show();
-
const definition = this.definitions[index];
+
+ let promise = Promise.resolve();
if (mode !== 'kanji') {
- const url = Display.audioBuildUrl(definition);
const filename = Display.audioBuildFilename(definition);
- if (url && filename) {
- definition.audio = {url, filename};
+ if (filename) {
+ promise = this.audioBuildUrl(definition).then(url => definition.audio = {url, filename}).catch(() => {});
}
}
- this.definitionAdd(definition, mode).then(success => {
- if (success) {
- Display.adderButtonFind(index, mode).addClass('disabled');
- } else {
- this.handleError('note could not be added');
- }
+ promise.then(() => {
+ return this.definitionAdd(definition, mode).then(success => {
+ if (success) {
+ Display.adderButtonFind(index, mode).addClass('disabled');
+ } else {
+ this.handleError('note could not be added');
+ }
+ });
}).catch(this.handleError.bind(this)).then(() => this.spinner.hide());
}
audioPlay(index) {
- for (const key in this.audioCache) {
- const audio = this.audioCache[key];
- if (audio !== null) {
- audio.pause();
- }
- }
-
+ this.spinner.show();
const definition = this.definitions[index];
- const url = Display.audioBuildUrl(definition);
- if (!url) {
- return;
+
+ for (const key in this.audioCache) {
+ this.audioCache[key].pause();
}
- let audio = this.audioCache[url];
- if (audio) {
- audio.currentTime = 0;
- audio.play();
- } else {
- audio = new Audio(url);
- audio.onloadeddata = () => {
- if (audio.duration === 5.694694 || audio.duration === 5.720718) {
- audio = new Audio('/mixed/mp3/button.mp3');
- }
+ this.audioBuildUrl(definition).then(url => {
+ if (!url) {
+ url = '/mixed/mp3/button.mp3';
+ }
- this.audioCache[url] = audio;
+ let audio = this.audioCache[url];
+ if (audio) {
+ audio.currentTime = 0;
audio.play();
- };
- }
- }
+ } else {
+ audio = new Audio(url);
+ audio.onloadeddata = () => {
+ if (audio.duration === 5.694694 || audio.duration === 5.720718) {
+ audio = new Audio('/mixed/mp3/button.mp3');
+ }
- static entryIndexFind(element) {
- return $('.entry').index(element.closest('.entry'));
+ this.audioCache[url] = audio;
+ audio.play();
+ };
+ }
+ }).catch(this.handleError.bind(this)).then(() => this.spinner.hide());
}
- static adderButtonFind(index, mode) {
- return $('.entry').eq(index).find(`.action-add-note[data-mode="${mode}"]`);
- }
+ audioBuildUrl(definition) {
+ return new Promise((resolve, reject) => {
+ const response = this.responseCache[definition.expression];
+ if (response) {
+ resolve(response);
+ return;
+ }
- static audioBuildUrl(definition) {
- let kana = definition.reading;
- let kanji = definition.expression;
+ const data = {
+ post: 'dictionary_reference',
+ match_type: 'exact',
+ search_query: definition.expression
+ };
- if (!kana && !kanji) {
- return null;
- }
+ const params = [];
+ for (const key in data) {
+ params.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`);
+ }
- if (!kana && wanakana.isHiragana(kanji)) {
- kana = kanji;
- kanji = null;
- }
+ 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', () => {
+ this.responseCache[definition.expression] = xhr.responseText;
+ resolve(xhr.responseText);
+ });
- const params = [];
- if (kanji) {
- params.push(`kanji=${encodeURIComponent(kanji)}`);
- }
- if (kana) {
- params.push(`kana=${encodeURIComponent(kana)}`);
- }
+ xhr.send(params.join('&'));
+ }).then(response => {
+ const dom = new DOMParser().parseFromString(response, 'text/html');
+ const entries = [];
+
+ for (const row of dom.getElementsByClassName('dc-result-row')) {
+ try {
+ const url = row.getElementsByClassName('ill-onebuttonplayer').item(0).getAttribute('data-url');
+ const expression = dom.getElementsByClassName('dc-vocab').item(0).innerText;
+ const reading = dom.getElementsByClassName('dc-vocab_kana').item(0).innerText;
- return `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`;
+ if (url && expression && reading) {
+ entries.push({url, expression, reading});
+ }
+ } catch (e) {
+ // NOP
+ }
+ }
+
+ return entries;
+ }).then(entries => {
+ for (const entry of entries) {
+ if (!definition.reading || definition.reading === entry.reading) {
+ return entry.url;
+ }
+ }
+ });
}
static audioBuildFilename(definition) {
if (!definition.reading && !definition.expression) {
- return null;
+ return;
}
let filename = 'yomichan';
@@ -358,4 +386,12 @@ class Display {
return filename += '.mp3';
}
+
+ static entryIndexFind(element) {
+ return $('.entry').index(element.closest('.entry'));
+ }
+
+ static adderButtonFind(index, mode) {
+ return $('.entry').eq(index).find(`.action-add-note[data-mode="${mode}"]`);
+ }
}