aboutsummaryrefslogtreecommitdiff
path: root/ext/mixed/js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-11-21 21:17:39 -0500
committerGitHub <noreply@github.com>2020-11-21 21:17:39 -0500
commit7b6a4c4e36ce65af376cd87f5f9e7c657ef2a12c (patch)
treec5fad23e1f1aa689958fbfab8cd8ffbaea7c0b64 /ext/mixed/js
parentaf33fff6fb10f77eb08b0bce572a18c2bff6c846 (diff)
More display updates (#1050)
* Use grid for layout * Add data-count attribute * Fix scroll issues during focus * Add index to entries * Simplify audio playback
Diffstat (limited to 'ext/mixed/js')
-rw-r--r--ext/mixed/js/display-generator.js4
-rw-r--r--ext/mixed/js/display.js106
2 files changed, 49 insertions, 61 deletions
diff --git a/ext/mixed/js/display-generator.js b/ext/mixed/js/display-generator.js
index 5a563024..e90d003a 100644
--- a/ext/mixed/js/display-generator.js
+++ b/ext/mixed/js/display-generator.js
@@ -473,11 +473,15 @@ class DisplayGenerator {
_appendMultiple(container, createItem, detailsArray, ...args) {
let count = 0;
+ const {ELEMENT_NODE} = Node;
if (Array.isArray(detailsArray)) {
for (const details of detailsArray) {
const item = createItem(details, ...args);
if (item === null) { continue; }
container.appendChild(item);
+ if (item.nodeType === ELEMENT_NODE) {
+ item.dataset.index = `${count}`;
+ }
++count;
}
}
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js
index 9297f46b..19df9a61 100644
--- a/ext/mixed/js/display.js
+++ b/ext/mixed/js/display.js
@@ -183,8 +183,6 @@ class Display extends EventDispatcher {
['popupMessage', {async: 'dynamic', handler: this._onDirectMessage.bind(this)}]
]);
window.addEventListener('focus', this._onWindowFocus.bind(this), false);
- document.documentElement.addEventListener('focusin', this._onDocumentFocusIn.bind(this), false);
- document.documentElement.addEventListener('focusout', this._onDocumentFocusOut.bind(this), false);
this._updateFocusedElement();
this._progressIndicatorVisible.on('change', this._onProgressIndicatorVisibleChanged.bind(this));
}
@@ -283,11 +281,7 @@ class Display extends EventDispatcher {
if (this._definitions.length === 0) { return; }
- const definition = this._definitions[0];
- const expressionIndex = this._getFirstExpressionIndex();
- const callback = () => {
- this._audioPlay(definition, expressionIndex, 0);
- };
+ const callback = () => this._playAudio(0, 0);
if (this._autoPlayAudioDelay > 0) {
this._autoPlayAudioTimer = setTimeout(callback, this._autoPlayAudioDelay);
@@ -413,6 +407,11 @@ class Display extends EventDispatcher {
// NOP
}
+ blurElement(element) {
+ element.blur();
+ this._updateFocusedElement();
+ }
+
// Message handlers
_onMessage({action, params}, sender, callback) {
@@ -588,14 +587,6 @@ class Display extends EventDispatcher {
this._updateFocusedElement();
}
- _onDocumentFocusIn() {
- this._updateFocusedElement();
- }
-
- _onDocumentFocusOut() {
- this._updateFocusedElement();
- }
-
async _onKanjiLookup(e) {
try {
e.preventDefault();
@@ -604,7 +595,7 @@ class Display extends EventDispatcher {
const link = e.target;
const {state} = this._history;
- state.focusEntry = this._entryIndexFind(link);
+ state.focusEntry = this._getClosestDefinitionIndex(link);
state.scrollX = this._windowScroll.x;
state.scrollY = this._windowScroll.y;
this._historyStateUpdate(state);
@@ -664,7 +655,7 @@ class Display extends EventDispatcher {
const layoutAwareScan = this._options.scanning.layoutAwareScan;
const sentence = this._documentUtil.extractSentence(textSource, sentenceExtent, layoutAwareScan);
- state.focusEntry = this._entryIndexFind(scannedElement);
+ state.focusEntry = this._getClosestDefinitionIndex(scannedElement);
state.scrollX = this._windowScroll.x;
state.scrollY = this._windowScroll.y;
this._historyStateUpdate(state);
@@ -715,23 +706,16 @@ class Display extends EventDispatcher {
_onAudioPlay(e) {
e.preventDefault();
const link = e.currentTarget;
- const entry = link.closest('.entry');
- const index = this._entryIndexFind(entry);
- if (index < 0 || index >= this._definitions.length) { return; }
-
- const expressionIndex = this._indexOf(entry.querySelectorAll('.term-expression .action-play-audio'), link);
- this._audioPlay(
- this._definitions[index],
- // expressionIndex is used in audioPlay to detect result output mode
- Math.max(expressionIndex, this._options.general.resultOutputMode === 'merge' ? 0 : -1),
- index
- );
+ const definitionIndex = this._getClosestDefinitionIndex(link);
+ if (definitionIndex < 0) { return; }
+ const expressionIndex = Math.max(0, this._getClosestExpressionIndex(link));
+ this._playAudio(definitionIndex, expressionIndex);
}
_onNoteAdd(e) {
e.preventDefault();
const link = e.currentTarget;
- const index = this._entryIndexFind(link);
+ const index = this._getClosestDefinitionIndex(link);
if (index < 0 || index >= this._definitions.length) { return; }
this._noteAdd(this._definitions[index], link.dataset.mode);
@@ -770,7 +754,7 @@ class Display extends EventDispatcher {
_onDebugLogClick(e) {
const link = e.currentTarget;
- const index = this._entryIndexFind(link);
+ const index = this._getClosestDefinitionIndex(link);
if (index < 0 || index >= this._definitions.length) { return; }
const definition = this._definitions[index];
console.log(definition);
@@ -937,6 +921,7 @@ class Display extends EventDispatcher {
this._displayGenerator.createTermEntry(definitions[i]) :
this._displayGenerator.createKanjiEntry(definitions[i])
);
+ entry.dataset.index = `${i}`;
container.appendChild(entry);
}
@@ -1187,11 +1172,19 @@ class Display extends EventDispatcher {
}
}
- async _audioPlay(definition, expressionIndex, entryIndex) {
+ async _playAudio(definitionIndex, expressionIndex) {
+ if (definitionIndex < 0 || definitionIndex >= this._definitions.length) { return; }
+
+ const definition = this._definitions[definitionIndex];
+ if (definition.type === 'kanji') { return; }
+
+ const {expressions} = definition;
+ if (expressionIndex < 0 || expressionIndex >= expressions.length) { return; }
+
+ const {expression, reading} = expressions[expressionIndex];
+
const overrideToken = this._progressIndicatorVisible.setOverride(true);
try {
- const {expression, reading} = expressionIndex === -1 ? definition : definition.expressions[expressionIndex];
-
this._stopPlayingAudio();
let audio, info;
@@ -1208,7 +1201,7 @@ class Display extends EventDispatcher {
info = 'Could not find audio';
}
- const button = this._audioButtonFindImage(entryIndex, expressionIndex);
+ const button = this._audioButtonFindImage(definitionIndex, expressionIndex);
if (button !== null) {
let titleDefault = button.dataset.titleDefault;
if (!titleDefault) {
@@ -1239,6 +1232,10 @@ class Display extends EventDispatcher {
}
}
+ async _playAudioCurrent() {
+ return await this._playAudio(this._index, 0);
+ }
+
_stopPlayingAudio() {
if (this._audioPlaying !== null) {
this._audioPlaying.pause();
@@ -1246,10 +1243,6 @@ class Display extends EventDispatcher {
}
}
- _getFirstExpressionIndex() {
- return this._options.general.resultOutputMode === 'merge' ? 0 : -1;
- }
-
_getEntry(index) {
const entries = this._container.querySelectorAll('.entry');
return index >= 0 && index < entries.length ? entries[index] : null;
@@ -1271,9 +1264,19 @@ class Display extends EventDispatcher {
};
}
- _entryIndexFind(element) {
- const entry = element.closest('.entry');
- return entry !== null ? this._indexOf(this._container.querySelectorAll('.entry'), entry) : -1;
+ _getClosestDefinitionIndex(element) {
+ return this._getClosestIndex(element, '.entry');
+ }
+
+ _getClosestExpressionIndex(element) {
+ return this._getClosestIndex(element, '.term-expression');
+ }
+
+ _getClosestIndex(element, selector) {
+ const node = element.closest(selector);
+ if (node === null) { return -1; }
+ const index = parseInt(node.dataset.index, 10);
+ return Number.isFinite(index) ? index : -1;
}
_adderButtonFind(index, mode) {
@@ -1307,15 +1310,6 @@ class Display extends EventDispatcher {
return container !== null ? container.querySelector('.action-play-audio>img') : null;
}
- _indexOf(nodeList, node) {
- for (let i = 0, ii = nodeList.length; i < ii; ++i) {
- if (nodeList[i] === node) {
- return i;
- }
- }
- return -1;
- }
-
_getElementTop(element) {
const elementRect = element.getBoundingClientRect();
const documentRect = this._contentScrollBodyElement.getBoundingClientRect();
@@ -1331,16 +1325,6 @@ class Display extends EventDispatcher {
};
}
- _playAudioCurrent() {
- const index = this._index;
- if (index < 0 || index >= this._definitions.length) { return; }
-
- const entry = this._getEntry(index);
- if (entry !== null && entry.dataset.type === 'term') {
- this._audioPlay(this._definitions[index], this._getFirstExpressionIndex(), index);
- }
- }
-
_historyHasState() {
return isObject(this._history.state);
}
@@ -1581,7 +1565,7 @@ class Display extends EventDispatcher {
activeElement === document.documentElement ||
activeElement === document.body
) {
- target.focus();
+ target.focus({preventScroll: true});
}
}
}