Display scroll refactor (#694)
* Cache navigation header * Create _focusEntry * Update scroll restoration * Require explicit entry focus index
This commit is contained in:
parent
104650627d
commit
0512258c8e
@ -250,6 +250,7 @@ class DisplaySearch extends Display {
|
|||||||
query
|
query
|
||||||
},
|
},
|
||||||
state: {
|
state: {
|
||||||
|
focusEntry: 0,
|
||||||
sentence: {text: query, offset: 0},
|
sentence: {text: query, offset: 0},
|
||||||
url: window.location.href
|
url: window.location.href
|
||||||
},
|
},
|
||||||
|
@ -435,6 +435,7 @@ class Frontend {
|
|||||||
wildcards: 'off'
|
wildcards: 'off'
|
||||||
},
|
},
|
||||||
state: {
|
state: {
|
||||||
|
focusEntry: 0,
|
||||||
sentence,
|
sentence,
|
||||||
url
|
url
|
||||||
},
|
},
|
||||||
|
@ -67,15 +67,16 @@ class Display extends EventDispatcher {
|
|||||||
this._history = new DisplayHistory({clearable: true, useBrowserHistory: false});
|
this._history = new DisplayHistory({clearable: true, useBrowserHistory: false});
|
||||||
this._historyChangeIgnore = false;
|
this._historyChangeIgnore = false;
|
||||||
this._historyHasChanged = false;
|
this._historyHasChanged = false;
|
||||||
|
this._navigationHeader = document.querySelector('#navigation-header');
|
||||||
|
|
||||||
this.registerActions([
|
this.registerActions([
|
||||||
['close', () => { this.onEscape(); }],
|
['close', () => { this.onEscape(); }],
|
||||||
['next-entry', () => { this._entryScrollIntoView(this._index + 1, null, true); }],
|
['next-entry', () => { this._focusEntry(this._index + 1, true); }],
|
||||||
['next-entry-x3', () => { this._entryScrollIntoView(this._index + 3, null, true); }],
|
['next-entry-x3', () => { this._focusEntry(this._index + 3, true); }],
|
||||||
['previous-entry', () => { this._entryScrollIntoView(this._index - 1, null, true); }],
|
['previous-entry', () => { this._focusEntry(this._index - 1, true); }],
|
||||||
['previous-entry-x3', () => { this._entryScrollIntoView(this._index - 3, null, true); }],
|
['previous-entry-x3', () => { this._focusEntry(this._index - 3, true); }],
|
||||||
['last-entry', () => { this._entryScrollIntoView(this._definitions.length - 1, null, true); }],
|
['last-entry', () => { this._focusEntry(this._definitions.length - 1, true); }],
|
||||||
['first-entry', () => { this._entryScrollIntoView(0, null, true); }],
|
['first-entry', () => { this._focusEntry(0, true); }],
|
||||||
['history-backward', () => { this._sourceTermView(); }],
|
['history-backward', () => { this._sourceTermView(); }],
|
||||||
['history-forward', () => { this._nextTermView(); }],
|
['history-forward', () => { this._nextTermView(); }],
|
||||||
['add-note-kanji', () => { this._noteTryAdd('kanji'); }],
|
['add-note-kanji', () => { this._noteTryAdd('kanji'); }],
|
||||||
@ -454,8 +455,9 @@ class Display extends EventDispatcher {
|
|||||||
const link = e.target;
|
const link = e.target;
|
||||||
const {state} = this._history;
|
const {state} = this._history;
|
||||||
|
|
||||||
state.index = this._entryIndexFind(link);
|
state.focusEntry = this._entryIndexFind(link);
|
||||||
state.scroll = this._windowScroll.y;
|
state.scrollX = this._windowScroll.x;
|
||||||
|
state.scrollY = this._windowScroll.y;
|
||||||
this._historyStateUpdate(state);
|
this._historyStateUpdate(state);
|
||||||
|
|
||||||
const query = link.textContent;
|
const query = link.textContent;
|
||||||
@ -469,6 +471,7 @@ class Display extends EventDispatcher {
|
|||||||
wildcards: 'off'
|
wildcards: 'off'
|
||||||
},
|
},
|
||||||
state: {
|
state: {
|
||||||
|
focusEntry: 0,
|
||||||
sentence: state.sentence,
|
sentence: state.sentence,
|
||||||
url: state.url
|
url: state.url
|
||||||
},
|
},
|
||||||
@ -512,8 +515,9 @@ class Display extends EventDispatcher {
|
|||||||
const layoutAwareScan = this._options.scanning.layoutAwareScan;
|
const layoutAwareScan = this._options.scanning.layoutAwareScan;
|
||||||
const sentence = docSentenceExtract(textSource, sentenceExtent, layoutAwareScan);
|
const sentence = docSentenceExtract(textSource, sentenceExtent, layoutAwareScan);
|
||||||
|
|
||||||
state.index = this._entryIndexFind(scannedElement);
|
state.focusEntry = this._entryIndexFind(scannedElement);
|
||||||
state.scroll = this._windowScroll.y;
|
state.scrollX = this._windowScroll.x;
|
||||||
|
state.scrollY = this._windowScroll.y;
|
||||||
this._historyStateUpdate(state);
|
this._historyStateUpdate(state);
|
||||||
|
|
||||||
this.setContent({
|
this.setContent({
|
||||||
@ -525,6 +529,7 @@ class Display extends EventDispatcher {
|
|||||||
wildcards: 'off'
|
wildcards: 'off'
|
||||||
},
|
},
|
||||||
state: {
|
state: {
|
||||||
|
focusEntry: 0,
|
||||||
sentence,
|
sentence,
|
||||||
url: state.url
|
url: state.url
|
||||||
},
|
},
|
||||||
@ -601,7 +606,7 @@ class Display extends EventDispatcher {
|
|||||||
_onWheel(e) {
|
_onWheel(e) {
|
||||||
if (e.altKey) {
|
if (e.altKey) {
|
||||||
if (e.deltaY !== 0) {
|
if (e.deltaY !== 0) {
|
||||||
this._entryScrollIntoView(this._index + (e.deltaY > 0 ? 1 : -1), null, true);
|
this._focusEntry(this._index + (e.deltaY > 0 ? 1 : -1), true);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
} else if (e.shiftKey) {
|
} else if (e.shiftKey) {
|
||||||
@ -647,7 +652,6 @@ class Display extends EventDispatcher {
|
|||||||
if (interactive) {
|
if (interactive) {
|
||||||
const actionPrevious = document.querySelector('.action-previous');
|
const actionPrevious = document.querySelector('.action-previous');
|
||||||
const actionNext = document.querySelector('.action-next');
|
const actionNext = document.querySelector('.action-next');
|
||||||
// const navigationHeader = document.querySelector('.navigation-header');
|
|
||||||
|
|
||||||
this._persistentEventListeners.addEventListener(document, 'keydown', this.onKeyDown.bind(this), false);
|
this._persistentEventListeners.addEventListener(document, 'keydown', this.onKeyDown.bind(this), false);
|
||||||
this._persistentEventListeners.addEventListener(document, 'wheel', this._onWheel.bind(this), {passive: false});
|
this._persistentEventListeners.addEventListener(document, 'wheel', this._onWheel.bind(this), {passive: false});
|
||||||
@ -657,10 +661,6 @@ class Display extends EventDispatcher {
|
|||||||
if (actionNext !== null) {
|
if (actionNext !== null) {
|
||||||
this._persistentEventListeners.addEventListener(actionNext, 'click', this._onNextTermView.bind(this));
|
this._persistentEventListeners.addEventListener(actionNext, 'click', this._onNextTermView.bind(this));
|
||||||
}
|
}
|
||||||
// temporarily disabled
|
|
||||||
// if (navigationHeader !== null) {
|
|
||||||
// this.persistentEventListeners.addEventListener(navigationHeader, 'wheel', this.onHistoryWheel.bind(this), {passive: false});
|
|
||||||
// }
|
|
||||||
} else {
|
} else {
|
||||||
this._persistentEventListeners.removeAllEventListeners();
|
this._persistentEventListeners.removeAllEventListeners();
|
||||||
}
|
}
|
||||||
@ -711,7 +711,7 @@ class Display extends EventDispatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _setContentTermsOrKanji(token, isTerms, definitions, {sentence=null, url=null, index=0, scroll=null}) {
|
async _setContentTermsOrKanji(token, isTerms, definitions, {sentence=null, url=null, focusEntry=null, scrollX=null, scrollY=null}) {
|
||||||
if (typeof url !== 'string') { url = window.location.href; }
|
if (typeof url !== 'string') { url = window.location.href; }
|
||||||
sentence = this._getValidSentenceData(sentence);
|
sentence = this._getValidSentenceData(sentence);
|
||||||
|
|
||||||
@ -744,7 +744,16 @@ class Display extends EventDispatcher {
|
|||||||
container.appendChild(entry);
|
container.appendChild(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._entryScrollIntoView(index, scroll);
|
if (typeof focusEntry === 'number') {
|
||||||
|
this._focusEntry(focusEntry, false);
|
||||||
|
}
|
||||||
|
if (typeof scrollX === 'number' || typeof scrollY === 'number') {
|
||||||
|
let {x, y} = this._windowScroll;
|
||||||
|
if (typeof scrollX === 'number') { x = scrollX; }
|
||||||
|
if (typeof scrollY === 'number') { y = scrollY; }
|
||||||
|
this._windowScroll.stop();
|
||||||
|
this._windowScroll.to(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isTerms &&
|
isTerms &&
|
||||||
@ -792,12 +801,10 @@ class Display extends EventDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_updateNavigation(previous, next) {
|
_updateNavigation(previous, next) {
|
||||||
const navigation = document.querySelector('#navigation-header');
|
if (this._navigationHeader === null) { return; }
|
||||||
if (navigation !== null) {
|
this._navigationHeader.hidden = !(previous || next);
|
||||||
navigation.hidden = !(previous || next);
|
this._navigationHeader.dataset.hasPrevious = `${!!previous}`;
|
||||||
navigation.dataset.hasPrevious = `${!!previous}`;
|
this._navigationHeader.dataset.hasNext = `${!!next}`;
|
||||||
navigation.dataset.hasNext = `${!!next}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateAdderButtons(states) {
|
_updateAdderButtons(states) {
|
||||||
@ -840,22 +847,15 @@ class Display extends EventDispatcher {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
_entryScrollIntoView(index, scroll, smooth) {
|
_focusEntry(index, smooth) {
|
||||||
this._windowScroll.stop();
|
|
||||||
|
|
||||||
const entry = this._entrySetCurrent(index);
|
const entry = this._entrySetCurrent(index);
|
||||||
let target;
|
let target = index === 0 || entry === null ? 0 : this._getElementTop(entry);
|
||||||
if (typeof scroll === 'number') {
|
|
||||||
target = scroll;
|
|
||||||
} else {
|
|
||||||
target = this._index === 0 || entry === null ? 0 : this._getElementTop(entry);
|
|
||||||
|
|
||||||
const header = document.querySelector('#navigation-header');
|
if (this._navigationHeader !== null) {
|
||||||
if (header !== null) {
|
target -= this._navigationHeader.getBoundingClientRect().height;
|
||||||
target -= header.getBoundingClientRect().height;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._windowScroll.stop();
|
||||||
if (smooth) {
|
if (smooth) {
|
||||||
this._windowScroll.animate(this._windowScroll.x, target, 200);
|
this._windowScroll.animate(this._windowScroll.x, target, 200);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user