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:
parent
af33fff6fb
commit
7b6a4c4e36
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user