summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Yatskov <alex@foosoft.net>2017-03-23 21:13:29 -0700
committerAlex Yatskov <alex@foosoft.net>2017-03-23 21:13:29 -0700
commita9cc1218607fe8c9e49090723928a9d8b64916c4 (patch)
treea060e28bc4395eafa8b8b869bcba84c755deb6e6
parent55309c1cb39241e1f40aedb6986c77f410213b97 (diff)
parent3a1959bfffcf869e65a55cdeb902fd3cbed21aa7 (diff)
Merge branch 'master' into dev
-rwxr-xr-xbuild_zip.sh2
-rw-r--r--ext/bg/legal.html33
-rw-r--r--ext/manifest.json2
-rw-r--r--ext/mixed/js/display.js152
4 files changed, 96 insertions, 93 deletions
diff --git a/build_zip.sh b/build_zip.sh
index be34255d..fd4e494a 100755
--- a/build_zip.sh
+++ b/build_zip.sh
@@ -1,4 +1,4 @@
#!/bin/sh
ZIP=yomichan.zip
rm -f $ZIP
-7z a $ZIP ./ext/*
+7za a $ZIP ./ext/*
diff --git a/ext/bg/legal.html b/ext/bg/legal.html
index f3ca4e01..4b0a3649 100644
--- a/ext/bg/legal.html
+++ b/ext/bg/legal.html
@@ -25,39 +25,6 @@ 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 &lt;http://www.gnu.org/licenses/&gt;.
</pre>
- <h3>VLGothic License</h3>
-<pre>
-Copyright (c) 1990-2003 Wada Laboratory, the University of Tokyo.
-Copyright (c) 2003-2004 Electronic Font Open Laboratory (/efont/).
-Copyright (C) 2002-2013 M+ FONTS PROJECT
-Copyright (C) 2006-2013 Daisuke SUZUKI .
-Copyright (C) 2006-2013 Project Vine .
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright notice,
-this list of conditions and the following disclaimer in the documentation
-and/or other materials provided with the distribution.
-3. Neither the name of the Wada Laboratory, the University of Tokyo nor
-the names of its contributors may be used to endorse or promote products
-derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY WADA LABORATORY, THE UNIVERSITY OF TOKYO AND
-CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LABORATORY OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-</pre>
<h3>EDRDG License</h3>
<pre>
This package uses the <a href="http://www.csse.monash.edu.au/~jwb/edict.html">EDICT</a> and <a href="http://www.csse.monash.edu.au/~jwb/kanjidic.html">KANJIDIC</a> dictionary files. These files are
diff --git a/ext/manifest.json b/ext/manifest.json
index 3357e661..215397d0 100644
--- a/ext/manifest.json
+++ b/ext/manifest.json
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Yomichan",
- "version": "1.1.6",
+ "version": "1.1.7",
"description": "Japanese dictionary with Anki integration",
"icons": {"16": "mixed/img/icon16.png", "48": "mixed/img/icon48.png", "128": "mixed/img/icon128.png"},
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}"]`);
+ }
}