More display updates (#1050)

* Use grid for layout

* Add data-count attribute

* Fix scroll issues during focus

* Add index to entries

* Simplify audio playback
This commit is contained in:
toasted-nutbread 2020-11-21 21:17:39 -05:00 committed by GitHub
parent af33fff6fb
commit 7b6a4c4e36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 69 deletions

View File

@ -44,7 +44,7 @@ class DisplaySearch extends Display {
}); });
this._onKeyDownIgnoreKeys = new Map([ this._onKeyDownIgnoreKeys = new Map([
['ANY_MOD', new Set([ ['ANY_MOD', new Set([
'Tab', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'PageDown', 'PageUp', 'Home', 'End', 'Enter', 'Tab', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'PageDown', 'PageUp', 'Home', 'End', 'Enter', 'Escape',
'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10',
'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20',
'F21', 'F22', 'F23', 'F24' 'F21', 'F22', 'F23', 'F24'
@ -157,7 +157,7 @@ class DisplaySearch extends Display {
case 'kanji': case 'kanji':
animate = content.animate; animate = content.animate;
valid = content.definitions.length > 0; valid = content.definitions.length > 0;
this._queryInput.blur(); this.blurElement(this._queryInput);
break; break;
case 'clear': case 'clear':
valid = false; valid = false;
@ -183,7 +183,7 @@ class DisplaySearch extends Display {
// Search // Search
e.preventDefault(); e.preventDefault();
e.stopImmediatePropagation(); e.stopImmediatePropagation();
e.currentTarget.blur(); this.blurElement(e.currentTarget);
this._search(); this._search();
} }

View File

@ -240,15 +240,16 @@ a {
.content { .content {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex;
flex-flow: column nowrap;
position: relative; position: relative;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
grid-template-areas: "main";
justify-items: stretch;
align-items: stretch; align-items: stretch;
justify-content: flex-start;
} }
.content-scroll { .content-scroll {
width: 100%; grid-area: main;
height: 100%;
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;
overflow-x: hidden; overflow-x: hidden;

View File

@ -473,11 +473,15 @@ class DisplayGenerator {
_appendMultiple(container, createItem, detailsArray, ...args) { _appendMultiple(container, createItem, detailsArray, ...args) {
let count = 0; let count = 0;
const {ELEMENT_NODE} = Node;
if (Array.isArray(detailsArray)) { if (Array.isArray(detailsArray)) {
for (const details of detailsArray) { for (const details of detailsArray) {
const item = createItem(details, ...args); const item = createItem(details, ...args);
if (item === null) { continue; } if (item === null) { continue; }
container.appendChild(item); container.appendChild(item);
if (item.nodeType === ELEMENT_NODE) {
item.dataset.index = `${count}`;
}
++count; ++count;
} }
} }

View File

@ -183,8 +183,6 @@ class Display extends EventDispatcher {
['popupMessage', {async: 'dynamic', handler: this._onDirectMessage.bind(this)}] ['popupMessage', {async: 'dynamic', handler: this._onDirectMessage.bind(this)}]
]); ]);
window.addEventListener('focus', this._onWindowFocus.bind(this), false); 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._updateFocusedElement();
this._progressIndicatorVisible.on('change', this._onProgressIndicatorVisibleChanged.bind(this)); this._progressIndicatorVisible.on('change', this._onProgressIndicatorVisibleChanged.bind(this));
} }
@ -283,11 +281,7 @@ class Display extends EventDispatcher {
if (this._definitions.length === 0) { return; } if (this._definitions.length === 0) { return; }
const definition = this._definitions[0]; const callback = () => this._playAudio(0, 0);
const expressionIndex = this._getFirstExpressionIndex();
const callback = () => {
this._audioPlay(definition, expressionIndex, 0);
};
if (this._autoPlayAudioDelay > 0) { if (this._autoPlayAudioDelay > 0) {
this._autoPlayAudioTimer = setTimeout(callback, this._autoPlayAudioDelay); this._autoPlayAudioTimer = setTimeout(callback, this._autoPlayAudioDelay);
@ -413,6 +407,11 @@ class Display extends EventDispatcher {
// NOP // NOP
} }
blurElement(element) {
element.blur();
this._updateFocusedElement();
}
// Message handlers // Message handlers
_onMessage({action, params}, sender, callback) { _onMessage({action, params}, sender, callback) {
@ -588,14 +587,6 @@ class Display extends EventDispatcher {
this._updateFocusedElement(); this._updateFocusedElement();
} }
_onDocumentFocusIn() {
this._updateFocusedElement();
}
_onDocumentFocusOut() {
this._updateFocusedElement();
}
async _onKanjiLookup(e) { async _onKanjiLookup(e) {
try { try {
e.preventDefault(); e.preventDefault();
@ -604,7 +595,7 @@ class Display extends EventDispatcher {
const link = e.target; const link = e.target;
const {state} = this._history; const {state} = this._history;
state.focusEntry = this._entryIndexFind(link); state.focusEntry = this._getClosestDefinitionIndex(link);
state.scrollX = this._windowScroll.x; state.scrollX = this._windowScroll.x;
state.scrollY = this._windowScroll.y; state.scrollY = this._windowScroll.y;
this._historyStateUpdate(state); this._historyStateUpdate(state);
@ -664,7 +655,7 @@ class Display extends EventDispatcher {
const layoutAwareScan = this._options.scanning.layoutAwareScan; const layoutAwareScan = this._options.scanning.layoutAwareScan;
const sentence = this._documentUtil.extractSentence(textSource, sentenceExtent, 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.scrollX = this._windowScroll.x;
state.scrollY = this._windowScroll.y; state.scrollY = this._windowScroll.y;
this._historyStateUpdate(state); this._historyStateUpdate(state);
@ -715,23 +706,16 @@ class Display extends EventDispatcher {
_onAudioPlay(e) { _onAudioPlay(e) {
e.preventDefault(); e.preventDefault();
const link = e.currentTarget; const link = e.currentTarget;
const entry = link.closest('.entry'); const definitionIndex = this._getClosestDefinitionIndex(link);
const index = this._entryIndexFind(entry); if (definitionIndex < 0) { return; }
if (index < 0 || index >= this._definitions.length) { return; } const expressionIndex = Math.max(0, this._getClosestExpressionIndex(link));
this._playAudio(definitionIndex, expressionIndex);
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
);
} }
_onNoteAdd(e) { _onNoteAdd(e) {
e.preventDefault(); e.preventDefault();
const link = e.currentTarget; const link = e.currentTarget;
const index = this._entryIndexFind(link); const index = this._getClosestDefinitionIndex(link);
if (index < 0 || index >= this._definitions.length) { return; } if (index < 0 || index >= this._definitions.length) { return; }
this._noteAdd(this._definitions[index], link.dataset.mode); this._noteAdd(this._definitions[index], link.dataset.mode);
@ -770,7 +754,7 @@ class Display extends EventDispatcher {
_onDebugLogClick(e) { _onDebugLogClick(e) {
const link = e.currentTarget; const link = e.currentTarget;
const index = this._entryIndexFind(link); const index = this._getClosestDefinitionIndex(link);
if (index < 0 || index >= this._definitions.length) { return; } if (index < 0 || index >= this._definitions.length) { return; }
const definition = this._definitions[index]; const definition = this._definitions[index];
console.log(definition); console.log(definition);
@ -937,6 +921,7 @@ class Display extends EventDispatcher {
this._displayGenerator.createTermEntry(definitions[i]) : this._displayGenerator.createTermEntry(definitions[i]) :
this._displayGenerator.createKanjiEntry(definitions[i]) this._displayGenerator.createKanjiEntry(definitions[i])
); );
entry.dataset.index = `${i}`;
container.appendChild(entry); 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); const overrideToken = this._progressIndicatorVisible.setOverride(true);
try { try {
const {expression, reading} = expressionIndex === -1 ? definition : definition.expressions[expressionIndex];
this._stopPlayingAudio(); this._stopPlayingAudio();
let audio, info; let audio, info;
@ -1208,7 +1201,7 @@ class Display extends EventDispatcher {
info = 'Could not find audio'; info = 'Could not find audio';
} }
const button = this._audioButtonFindImage(entryIndex, expressionIndex); const button = this._audioButtonFindImage(definitionIndex, expressionIndex);
if (button !== null) { if (button !== null) {
let titleDefault = button.dataset.titleDefault; let titleDefault = button.dataset.titleDefault;
if (!titleDefault) { if (!titleDefault) {
@ -1239,6 +1232,10 @@ class Display extends EventDispatcher {
} }
} }
async _playAudioCurrent() {
return await this._playAudio(this._index, 0);
}
_stopPlayingAudio() { _stopPlayingAudio() {
if (this._audioPlaying !== null) { if (this._audioPlaying !== null) {
this._audioPlaying.pause(); this._audioPlaying.pause();
@ -1246,10 +1243,6 @@ class Display extends EventDispatcher {
} }
} }
_getFirstExpressionIndex() {
return this._options.general.resultOutputMode === 'merge' ? 0 : -1;
}
_getEntry(index) { _getEntry(index) {
const entries = this._container.querySelectorAll('.entry'); const entries = this._container.querySelectorAll('.entry');
return index >= 0 && index < entries.length ? entries[index] : null; return index >= 0 && index < entries.length ? entries[index] : null;
@ -1271,9 +1264,19 @@ class Display extends EventDispatcher {
}; };
} }
_entryIndexFind(element) { _getClosestDefinitionIndex(element) {
const entry = element.closest('.entry'); return this._getClosestIndex(element, '.entry');
return entry !== null ? this._indexOf(this._container.querySelectorAll('.entry'), entry) : -1; }
_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) { _adderButtonFind(index, mode) {
@ -1307,15 +1310,6 @@ class Display extends EventDispatcher {
return container !== null ? container.querySelector('.action-play-audio>img') : null; 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) { _getElementTop(element) {
const elementRect = element.getBoundingClientRect(); const elementRect = element.getBoundingClientRect();
const documentRect = this._contentScrollBodyElement.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() { _historyHasState() {
return isObject(this._history.state); return isObject(this._history.state);
} }
@ -1581,7 +1565,7 @@ class Display extends EventDispatcher {
activeElement === document.documentElement || activeElement === document.documentElement ||
activeElement === document.body activeElement === document.body
) { ) {
target.focus(); target.focus({preventScroll: true});
} }
} }
} }