summaryrefslogtreecommitdiff
path: root/ext/mixed
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mixed')
-rw-r--r--ext/mixed/img/add-kanji.pngbin733 -> 0 bytes
-rw-r--r--ext/mixed/img/add-term-kana.pngbin286 -> 0 bytes
-rw-r--r--ext/mixed/img/add-term-kana.svg23
-rw-r--r--ext/mixed/img/add-term-kanji.pngbin733 -> 0 bytes
-rw-r--r--ext/mixed/img/add-term-kanji.svg24
-rw-r--r--ext/mixed/img/entry-current.pngbin743 -> 0 bytes
-rw-r--r--ext/mixed/img/entry-current.svg16
-rw-r--r--ext/mixed/img/play-audio.pngbin610 -> 0 bytes
-rw-r--r--ext/mixed/img/play-audio.svg27
-rw-r--r--ext/mixed/img/source-term.pngbin680 -> 0 bytes
-rw-r--r--ext/mixed/img/source-term.svg31
-rw-r--r--ext/mixed/img/view-note.pngbin622 -> 0 bytes
-rw-r--r--ext/mixed/img/view-note.svg22
-rw-r--r--ext/mixed/js/audio.js60
-rw-r--r--ext/mixed/js/display.js107
-rw-r--r--ext/mixed/js/extension.js35
16 files changed, 304 insertions, 41 deletions
diff --git a/ext/mixed/img/add-kanji.png b/ext/mixed/img/add-kanji.png
deleted file mode 100644
index 6332fefe..00000000
--- a/ext/mixed/img/add-kanji.png
+++ /dev/null
Binary files differ
diff --git a/ext/mixed/img/add-term-kana.png b/ext/mixed/img/add-term-kana.png
deleted file mode 100644
index 41ff8335..00000000
--- a/ext/mixed/img/add-term-kana.png
+++ /dev/null
Binary files differ
diff --git a/ext/mixed/img/add-term-kana.svg b/ext/mixed/img/add-term-kana.svg
new file mode 100644
index 00000000..bb964476
--- /dev/null
+++ b/ext/mixed/img/add-term-kana.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <linearGradient id="linearGradient4719" x1="-1.7198" x2="-1.7198" y1="2.7781" y2="1.4552" gradientTransform="matrix(3.7795 0 0 3.7795 14 .5)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#8dba64" offset="0"/>
+ <stop stop-color="#b4d495" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient4745-5" x1="2.1167" x2="1.4552" y1="2.3812" y2="1.7198" gradientTransform="scale(3.7795 3.7795)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#376b19" offset="0"/>
+ <stop stop-color="#81ab61" offset="1"/>
+ </linearGradient>
+ <radialGradient id="radialGradient4770-4" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(2.2677 -7.9311e-7 7.9312e-7 2.2677 2.7 3.7)" gradientUnits="userSpaceOnUse">
+ <stop stop-opacity=".28986" offset="0"/>
+ <stop stop-opacity="0" offset="1"/>
+ </radialGradient>
+ </defs>
+ <g>
+ <circle cx="7.5" cy="8.5" r="3" fill="url(#linearGradient4719)"/>
+ <circle cx="7.5" cy="8.5" r="3" fill="none" stroke="url(#linearGradient4745-5)"/>
+ <circle cx="7.5" cy="8.5" r="1.5" fill="url(#radialGradient4770-4)"/>
+ <path d="m6 8h1v-1h1v1h1v1h-1v1h-1v-1h-1v-1" fill="#fff"/>
+ </g>
+</svg>
diff --git a/ext/mixed/img/add-term-kanji.png b/ext/mixed/img/add-term-kanji.png
deleted file mode 100644
index 6332fefe..00000000
--- a/ext/mixed/img/add-term-kanji.png
+++ /dev/null
Binary files differ
diff --git a/ext/mixed/img/add-term-kanji.svg b/ext/mixed/img/add-term-kanji.svg
new file mode 100644
index 00000000..3737eaec
--- /dev/null
+++ b/ext/mixed/img/add-term-kanji.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <linearGradient id="linearGradient4582" x1="-1.7198" x2="-1.7198" y1="3.5719" y2=".79375" gradientTransform="matrix(3.7795 0 0 3.7795 14.5 -6.308e-7)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#6fb558" offset="0"/>
+ <stop stop-color="#a5db9b" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient4758-7" x1="7.5406" x2="5.1594" y1="3.3073" y2=".92604" gradientTransform="matrix(3.7795 0 0 3.7795 -16 -6e-7)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#34812c" offset="0"/>
+ <stop stop-color="#87b870" offset="1"/>
+ </linearGradient>
+ <radialGradient id="radialGradient4683-3" cx="2.1167" cy="2.1167" r=".66146" gradientTransform="matrix(4.5354 8.0301e-7 -8.0301e-7 4.5354 -1.6 -1.6)" gradientUnits="userSpaceOnUse">
+ <stop stop-opacity=".28986" offset="0"/>
+ <stop stop-opacity="0" offset="1"/>
+ </radialGradient>
+ </defs>
+ <g>
+ <circle cx="8" cy="8" r="6.5" fill="url(#linearGradient4582)"/>
+ <circle cx="8" cy="8" r="5.75" fill="none" stroke="#fff" stroke-opacity=".50196" stroke-width="1.5"/>
+ <circle cx="8" cy="8" r="6.5" fill="none" stroke="url(#linearGradient4758-7)"/>
+ <circle cx="8" cy="8" r="3" fill="url(#radialGradient4683-3)"/>
+ <path d="m5 7h2v-2h2v2h2v2h-2v2h-2v-2h-2v-2" fill="#fff"/>
+ </g>
+</svg>
diff --git a/ext/mixed/img/entry-current.png b/ext/mixed/img/entry-current.png
deleted file mode 100644
index bab7cc9b..00000000
--- a/ext/mixed/img/entry-current.png
+++ /dev/null
Binary files differ
diff --git a/ext/mixed/img/entry-current.svg b/ext/mixed/img/entry-current.svg
new file mode 100644
index 00000000..abf3f76d
--- /dev/null
+++ b/ext/mixed/img/entry-current.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <linearGradient id="linearGradient4930" x1="3.175" x2="1.0583" y1="3.7042" y2=".52917" gradientTransform="scale(3.7795 3.7795)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#c47a00" offset="0"/>
+ <stop stop-color="#fcbf00" offset="1"/>
+ </linearGradient>
+ <radialGradient id="radialGradient4938" cx="2.1167" cy="2.1167" r="1.9976" gradientTransform="matrix(3.7795 0 0 3.7753 -5.7066e-7 .0088978)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#ffeeb5" offset="0"/>
+ <stop stop-color="#ffe079" offset="1"/>
+ </radialGradient>
+ </defs>
+ <g>
+ <path d="m10.25 9.375 3 4.5-2.25 1.5-3-4.5-3 4.5-2.25-1.5 3-4.5h-5.25v-2.75h5.25l-3-4.5 2.25-1.5 3 4.5 3-4.5 2.25 1.5-3 4.5h5.25v2.75z" fill="url(#radialGradient4938)" stroke="url(#linearGradient4930)" stroke-linejoin="bevel" stroke-opacity=".93333"/>
+ </g>
+</svg>
diff --git a/ext/mixed/img/play-audio.png b/ext/mixed/img/play-audio.png
deleted file mode 100644
index 6056d234..00000000
--- a/ext/mixed/img/play-audio.png
+++ /dev/null
Binary files differ
diff --git a/ext/mixed/img/play-audio.svg b/ext/mixed/img/play-audio.svg
new file mode 100644
index 00000000..1d5e2d9c
--- /dev/null
+++ b/ext/mixed/img/play-audio.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <linearGradient id="linearGradient4825" x1="-.39687" x2="-1.1906" y1="3.2411" y2="1.1906" gradientTransform="matrix(3.7795 0 0 3.7795 8.5 -6.308e-7)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#777772" offset="0"/>
+ <stop stop-color="#a9a9a9" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient4869-7" x1=".52917" x2=".52917" y1="2.6458" y2="1.4552" gradientTransform="scale(3.7795 3.7795)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#fff" stop-opacity="0" offset="0"/>
+ <stop stop-color="#fff" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient4853-9" x1="-.26458" x2="-1.5875" y1="3.4396" y2=".7276" gradientTransform="matrix(3.7795 0 0 3.7795 8.5 -2.9535e-7)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#5d5d5a" offset="0"/>
+ <stop stop-color="#90908f" offset="1"/>
+ </linearGradient>
+ <radialGradient id="radialGradient4898-9" cx="15" cy="8.5578" r="3.7188" gradientTransform="matrix(2.4322e-8 -2.1513 1.6807 1.9002e-8 1.3671 40.269)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#e1293b" offset="0"/>
+ <stop stop-color="#e9505a" offset="1"/>
+ </radialGradient>
+ </defs>
+ <g>
+ <path d="m0.5 8v2.5h3.5l3.5 3v-11l-3.5 3h-3.5v2.5" fill="url(#linearGradient4825)"/>
+ <path d="m1.25 10.5v-4.25h3l3-2.75" fill="none" stroke="url(#linearGradient4869-7)" stroke-opacity=".50196" stroke-width="1.5"/>
+ <path d="m0.5 8v2.5h3.5l3.5 3v-11l-3.5 3h-3.5v2.5" fill="none" stroke="url(#linearGradient4853-9)" stroke-linecap="round" stroke-linejoin="round"/>
+ <path d="m12.75 2.75c1.5 3 1.5 7.5 0 10.5 4.25-1.75 4.25-8.75 0-10.5m-2 2c0.75 1.5 0.75 5 0 6.5 3-1.25 3-5.25 0-6.5m-0.75 1.5-1.5 1.75 1.5 1.75c0.5-1 0.5-2.5 0-3.5" fill="url(#radialGradient4898-9)"/>
+ </g>
+</svg>
diff --git a/ext/mixed/img/source-term.png b/ext/mixed/img/source-term.png
deleted file mode 100644
index 2e53c698..00000000
--- a/ext/mixed/img/source-term.png
+++ /dev/null
Binary files differ
diff --git a/ext/mixed/img/source-term.svg b/ext/mixed/img/source-term.svg
new file mode 100644
index 00000000..a70938f2
--- /dev/null
+++ b/ext/mixed/img/source-term.svg
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <linearGradient id="linearGradient5205" x2="-3.9688" y1="3.7042" y2="1.0583" gradientTransform="matrix(3.7795 0 0 3.7795 20.5 -.5)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#012e5b" offset="0"/>
+ <stop stop-color="#6399c6" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient5138-3" x1="3.8365" x2=".39687" y1="3.0427" y2=".59531" gradientTransform="matrix(3.7795 0 0 3.7795 5 -6e-7)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#012e5b" offset="0"/>
+ <stop stop-color="#6399c6" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient5227-0" x1="2.6458" x2=".52917" y1="3.9688" y2="3.3734" gradientTransform="matrix(3.7795 0 0 3.7795 -5.7066e-7 -7)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#7cbe76" offset="0"/>
+ <stop stop-color="#abd8a2" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient5219-8" x1="2.7781" x2=".13229" y1="4.101" y2="3.175" gradientTransform="matrix(3.7795 0 0 3.7795 -5.7066e-7 -7)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#205e1d" offset="0"/>
+ <stop stop-color="#74c768" offset="1"/>
+ </linearGradient>
+ </defs>
+ <g>
+ <path d="m16 3.5h-1.5l-1 1h-1l-1-1h-6v10h5.75l1 1h1.5l1-1h1.25" fill="#5d8bb3" stroke="url(#linearGradient5205)" stroke-width="1px"/>
+ <path d="m16 2.25h-1.5l-1 1h-1l-1-1h-5v9.25h5l1 1h1l1-1h1.5" fill="#f8f8f8" stroke="url(#linearGradient5138-3)" stroke-width="1px"/>
+ <g fill="none" stroke-width="1px">
+ <path d="m15 8.75h1m-1-2h1m-1-2h1m-8 4h3m-3-2h3m-3-2h3" stroke="#bdbdbd"/>
+ <path d="m12.5 10.25v-4.75" stroke="#a6a6a6"/>
+ <path d="m13.5 5.75v4.25" stroke="#d8d8d8"/>
+ </g>
+ <path d="m10.5 7v-1.5h-7v-2l-3 3v1l3 3v-2h7v-1.5" fill="url(#linearGradient5227-0)" stroke="url(#linearGradient5219-8)" stroke-linejoin="round"/>
+ </g>
+</svg>
diff --git a/ext/mixed/img/view-note.png b/ext/mixed/img/view-note.png
deleted file mode 100644
index 7d863f94..00000000
--- a/ext/mixed/img/view-note.png
+++ /dev/null
Binary files differ
diff --git a/ext/mixed/img/view-note.svg b/ext/mixed/img/view-note.svg
new file mode 100644
index 00000000..3e6f1dce
--- /dev/null
+++ b/ext/mixed/img/view-note.svg
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <linearGradient id="linearGradient5010" x2="-3.9688" y1="3.7042" y2="1.0583" gradientTransform="matrix(3.7795 0 0 3.7795 15.5 -.5)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#012e5b" offset="0"/>
+ <stop stop-color="#6399c6" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient5018-3" x1="3.8365" x2=".39687" y1="3.0427" y2=".59531" gradientTransform="scale(3.7795 3.7795)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#012e5b" offset="0"/>
+ <stop stop-color="#6399c6" offset="1"/>
+ </linearGradient>
+ </defs>
+ <g stroke-width="1px">
+ <path d="m9.75 13.5-1 1h-1.5l-1-1h-5.75v-10h6l1 1h1l1-1h6v10z" fill="#5d8bb3" stroke="url(#linearGradient5010)"/>
+ <path d="m14.5 11.5h-5l-1 1h-1l-1-1h-5v-9.25h5l1 1h1l1-1h5v9.25" fill="#f8f8f8" stroke="url(#linearGradient5018-3)"/>
+ <g fill="none">
+ <path d="m10 8.75h3m-3-2h3m-3-2h3m-10 4h3m-3-2h3m-3-2h3" stroke="#bdbdbd"/>
+ <path d="m7.5 10.25v-4.75" stroke="#a6a6a6"/>
+ <path d="m8.5 5.75v4.25" stroke="#d8d8d8"/>
+ </g>
+ </g>
+</svg>
diff --git a/ext/mixed/js/audio.js b/ext/mixed/js/audio.js
new file mode 100644
index 00000000..b905140c
--- /dev/null
+++ b/ext/mixed/js/audio.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 Alex Yatskov <alex@foosoft.net>
+ * Author: Alex Yatskov <alex@foosoft.net>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+function audioGetFromUrl(url) {
+ return new Promise((resolve, reject) => {
+ const audio = new Audio(url);
+ audio.addEventListener('loadeddata', () => {
+ if (audio.duration === 5.694694 || audio.duration === 5.720718) {
+ // Hardcoded values for invalid audio
+ reject(new Error('Could not retrieve audio'));
+ } else {
+ resolve(audio);
+ }
+ });
+ audio.addEventListener('error', () => reject(audio.error));
+ });
+}
+
+async function audioGetFromSources(expression, sources, optionsContext, createAudioObject, cache=null) {
+ const key = `${expression.expression}:${expression.reading}`;
+ if (cache !== null && cache.hasOwnProperty(expression)) {
+ return cache[key];
+ }
+
+ for (let i = 0, ii = sources.length; i < ii; ++i) {
+ const source = sources[i];
+ const url = await apiAudioGetUrl(expression, source, optionsContext);
+ if (url === null) {
+ continue;
+ }
+
+ try {
+ const audio = createAudioObject ? await audioGetFromUrl(url) : null;
+ const result = {audio, url, source};
+ if (cache !== null) {
+ cache[key] = result;
+ }
+ return result;
+ } catch (e) {
+ // NOP
+ }
+ }
+ return {audio: null, source: null};
+}
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js
index dc64dbea..22181301 100644
--- a/ext/mixed/js/display.js
+++ b/ext/mixed/js/display.js
@@ -26,6 +26,8 @@ class Display {
this.context = null;
this.sequence = 0;
this.index = 0;
+ this.audioPlaying = null;
+ this.audioFallback = null;
this.audioCache = {};
this.optionsContext = {};
this.eventListeners = [];
@@ -39,11 +41,11 @@ class Display {
}
onError(error) {
- throw 'Override me';
+ throw new Error('Override me');
}
onSearchClear() {
- throw 'Override me';
+ throw new Error('Override me');
}
onSourceTermView(e) {
@@ -133,7 +135,7 @@ class Display {
const entry = link.closest('.entry');
const definitionIndex = this.entryIndexFind(entry);
const expressionIndex = Display.indexOf(entry.querySelectorAll('.expression .action-play-audio'), link);
- this.audioPlay(this.definitions[definitionIndex], expressionIndex);
+ this.audioPlay(this.definitions[definitionIndex], expressionIndex, definitionIndex);
}
onNoteAdd(e) {
@@ -189,7 +191,7 @@ class Display {
addable: options.anki.enable,
grouped: options.general.resultOutputMode === 'group',
merged: options.general.resultOutputMode === 'merge',
- playback: options.general.audioSource !== 'disabled',
+ playback: options.audio.enabled,
compactGlossaries: options.general.compactGlossaries,
debug: options.general.debugInfo
};
@@ -209,7 +211,7 @@ class Display {
const {index, scroll} = context || {};
this.entryScrollIntoView(index || 0, scroll);
- if (this.options.general.autoPlayAudio && this.options.general.audioSource !== 'disabled') {
+ if (this.options.audio.enabled && this.options.audio.autoPlay) {
this.autoPlayAudio();
}
@@ -274,7 +276,7 @@ class Display {
}
autoPlayAudio() {
- this.audioPlay(this.definitions[0], this.firstExpressionIndex);
+ this.audioPlay(this.definitions[0], this.firstExpressionIndex, 0);
}
async adderButtonUpdate(modes, sequence) {
@@ -286,15 +288,23 @@ class Display {
for (let i = 0; i < states.length; ++i) {
const state = states[i];
+ let noteId = null;
for (const mode in state) {
const button = this.adderButtonFind(i, mode);
if (button === null) {
continue;
}
- button.classList.toggle('disabled', !state[mode]);
+ const info = state[mode];
+ if (!info.canAdd && noteId === null && info.noteId) {
+ noteId = info.noteId;
+ }
+ button.classList.toggle('disabled', !info.canAdd);
button.classList.remove('pending');
}
+ if (noteId !== null) {
+ this.viewerButtonShow(i, noteId);
+ }
}
} catch (e) {
this.onError(e);
@@ -380,13 +390,9 @@ class Display {
if (adderButton !== null) {
adderButton.classList.add('disabled');
}
- const viewerButton = this.viewerButtonFind(index);
- if (viewerButton !== null) {
- viewerButton.classList.remove('pending', 'disabled');
- viewerButton.dataset.noteId = noteId;
- }
+ this.viewerButtonShow(index, noteId);
} else {
- throw 'Note could note be added';
+ throw new Error('Note could not be added');
}
} catch (e) {
this.onError(e);
@@ -395,37 +401,44 @@ class Display {
}
}
- async audioPlay(definition, expressionIndex) {
+ async audioPlay(definition, expressionIndex, entryIndex) {
try {
this.setSpinnerVisible(true);
const expression = expressionIndex === -1 ? definition : definition.expressions[expressionIndex];
- let url = await apiAudioGetUrl(expression, this.options.general.audioSource);
- if (!url) {
- url = '/mixed/mp3/button.mp3';
- }
- for (const key in this.audioCache) {
- this.audioCache[key].pause();
+ if (this.audioPlaying !== null) {
+ this.audioPlaying.pause();
+ this.audioPlaying = null;
}
- let audio = this.audioCache[url];
- if (audio) {
- audio.currentTime = 0;
- audio.volume = this.options.general.audioVolume / 100.0;
- audio.play();
+ const sources = this.options.audio.sources;
+ let {audio, source} = await audioGetFromSources(expression, sources, this.optionsContext, true, this.audioCache);
+ let info;
+ if (audio === null) {
+ if (this.audioFallback === null) {
+ this.audioFallback = new Audio('/mixed/mp3/button.mp3');
+ }
+ audio = this.audioFallback;
+ info = 'Could not find audio';
} else {
- audio = new Audio(url);
- audio.onloadeddata = () => {
- if (audio.duration === 5.694694 || audio.duration === 5.720718) {
- audio = new Audio('/mixed/mp3/button.mp3');
- }
+ info = `From source ${1 + sources.indexOf(source)}: ${source}`;
+ }
- this.audioCache[url] = audio;
- audio.volume = this.options.general.audioVolume / 100.0;
- audio.play();
- };
+ const button = this.audioButtonFindImage(entryIndex);
+ if (button !== null) {
+ let titleDefault = button.dataset.titleDefault;
+ if (!titleDefault) {
+ titleDefault = button.title || "";
+ button.dataset.titleDefault = titleDefault;
+ }
+ button.title = `${titleDefault}\n${info}`;
}
+
+ this.audioPlaying = audio;
+ audio.currentTime = 0;
+ audio.volume = this.options.audio.volume / 100.0;
+ audio.play();
} catch (e) {
this.onError(e);
} finally {
@@ -445,7 +458,7 @@ class Display {
async getScreenshot() {
try {
- await this.setPopupVisible(false);
+ await this.setPopupVisibleOverride(false);
await Display.delay(1); // Wait for popup to be hidden.
const {format, quality} = this.options.anki.screenshot;
@@ -454,7 +467,7 @@ class Display {
return {dataUrl, format};
} finally {
- await this.setPopupVisible(true);
+ await this.setPopupVisibleOverride(null);
}
}
@@ -462,8 +475,8 @@ class Display {
return this.options.general.resultOutputMode === 'merge' ? 0 : -1;
}
- setPopupVisible(visible) {
- return apiForward('popupSetVisible', {visible});
+ setPopupVisibleOverride(visible) {
+ return apiForward('popupSetVisibleOverride', {visible});
}
setSpinnerVisible(visible) {
@@ -504,6 +517,20 @@ class Display {
return entry !== null ? entry.querySelector('.action-view-note') : null;
}
+ viewerButtonShow(index, noteId) {
+ const viewerButton = this.viewerButtonFind(index);
+ if (viewerButton === null) {
+ return;
+ }
+ viewerButton.classList.remove('pending', 'disabled');
+ viewerButton.dataset.noteId = noteId;
+ }
+
+ audioButtonFindImage(index) {
+ const entry = this.getEntry(index);
+ return entry !== null ? entry.querySelector('.action-play-audio>img') : null;
+ }
+
static delay(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
@@ -539,7 +566,7 @@ class Display {
static getKeyFromEvent(event) {
const key = event.key;
- return key.length === 1 ? key.toUpperCase() : key;
+ return (typeof key === 'string' ? (key.length === 1 ? key.toUpperCase() : key) : '');
}
}
@@ -633,7 +660,7 @@ Display.onKeyDownHandlers = {
if (e.altKey) {
const entry = self.getEntry(self.index);
if (entry !== null && entry.dataset.type === 'term') {
- self.audioPlay(self.definitions[self.index], self.firstExpressionIndex);
+ self.audioPlay(self.definitions[self.index], self.firstExpressionIndex, self.index);
}
return true;
}
diff --git a/ext/mixed/js/extension.js b/ext/mixed/js/extension.js
index 5c803132..861e52a5 100644
--- a/ext/mixed/js/extension.js
+++ b/ext/mixed/js/extension.js
@@ -34,7 +34,7 @@ function toIterable(value) {
}
}
- throw 'Could not convert to iterable';
+ throw new Error('Could not convert to iterable');
}
function extensionHasChrome() {
@@ -53,6 +53,39 @@ function extensionHasBrowser() {
}
}
+function errorToJson(error) {
+ return {
+ name: error.name,
+ message: error.message,
+ stack: error.stack
+ };
+}
+
+function jsonToError(jsonError) {
+ const error = new Error(jsonError.message);
+ error.name = jsonError.name;
+ error.stack = jsonError.stack;
+ return error;
+}
+
+function logError(error, alert) {
+ const manifest = chrome.runtime.getManifest();
+ let errorMessage = `${manifest.name} v${manifest.version} has encountered an error.\n`;
+ errorMessage += `Originating URL: ${window.location.href}\n`;
+
+ const errorString = `${error.toString ? error.toString() : error}`;
+ const stack = `${error.stack}`.trimRight();
+ errorMessage += (!stack.startsWith(errorString) ? `${errorString}\n${stack}` : `${stack}`);
+
+ errorMessage += '\n\nIssues can be reported at https://github.com/FooSoft/yomichan/issues';
+
+ console.error(errorMessage);
+
+ if (alert) {
+ window.alert(`${errorString}\n\nCheck the developer console for more details.`);
+ }
+}
+
const EXTENSION_IS_BROWSER_EDGE = (
extensionHasBrowser() &&
(!extensionHasChrome() || (typeof chrome.runtime === 'undefined' && typeof browser.runtime !== 'undefined'))