Merge branch 'master' into dev
This commit is contained in:
commit
a9cc121860
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
ZIP=yomichan.zip
|
||||
rm -f $ZIP
|
||||
7z a $ZIP ./ext/*
|
||||
7za a $ZIP ./ext/*
|
||||
|
@ -24,39 +24,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 <http://www.gnu.org/licenses/>.
|
||||
</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>
|
||||
|
@ -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"},
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
this.audioCache[url] = audio;
|
||||
audio.play();
|
||||
};
|
||||
}
|
||||
}).catch(this.handleError.bind(this)).then(() => this.spinner.hide());
|
||||
}
|
||||
|
||||
audioBuildUrl(definition) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const response = this.responseCache[definition.expression];
|
||||
if (response) {
|
||||
resolve(response);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = {
|
||||
post: 'dictionary_reference',
|
||||
match_type: 'exact',
|
||||
search_query: definition.expression
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static entryIndexFind(element) {
|
||||
return $('.entry').index(element.closest('.entry'));
|
||||
}
|
||||
const params = [];
|
||||
for (const key in data) {
|
||||
params.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`);
|
||||
}
|
||||
|
||||
static adderButtonFind(index, mode) {
|
||||
return $('.entry').eq(index).find(`.action-add-note[data-mode="${mode}"]`);
|
||||
}
|
||||
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);
|
||||
});
|
||||
|
||||
static audioBuildUrl(definition) {
|
||||
let kana = definition.reading;
|
||||
let kanji = definition.expression;
|
||||
xhr.send(params.join('&'));
|
||||
}).then(response => {
|
||||
const dom = new DOMParser().parseFromString(response, 'text/html');
|
||||
const entries = [];
|
||||
|
||||
if (!kana && !kanji) {
|
||||
return null;
|
||||
}
|
||||
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;
|
||||
|
||||
if (!kana && wanakana.isHiragana(kanji)) {
|
||||
kana = kanji;
|
||||
kanji = null;
|
||||
}
|
||||
if (url && expression && reading) {
|
||||
entries.push({url, expression, reading});
|
||||
}
|
||||
} catch (e) {
|
||||
// NOP
|
||||
}
|
||||
}
|
||||
|
||||
const params = [];
|
||||
if (kanji) {
|
||||
params.push(`kanji=${encodeURIComponent(kanji)}`);
|
||||
}
|
||||
if (kana) {
|
||||
params.push(`kana=${encodeURIComponent(kana)}`);
|
||||
}
|
||||
|
||||
return `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`;
|
||||
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}"]`);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user