diff options
Diffstat (limited to 'ext/mixed/js/display.js')
-rw-r--r-- | ext/mixed/js/display.js | 163 |
1 files changed, 112 insertions, 51 deletions
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index f231fab5..c32852ad 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -42,7 +42,7 @@ class Display { this.setInteractive(true); } - onError(error) { + onError(_error) { throw new Error('Override me'); } @@ -55,26 +55,24 @@ class Display { this.sourceTermView(); } + onNextTermView(e) { + e.preventDefault(); + this.nextTermView(); + } + async onKanjiLookup(e) { try { e.preventDefault(); if (!this.context) { return; } const link = e.target; - this.windowScroll.toY(0); + this.context.update({ + index: this.entryIndexFind(link), + scroll: this.windowScroll.y + }); const context = { - source: { - type: 'terms', - details: { - definitions: this.definitions, - context: Object.assign({}, this.context, { - index: this.entryIndexFind(link), - scroll: this.windowScroll.y - }) - } - }, - sentence: this.context.sentence, - url: this.context.url + sentence: this.context.get('sentence'), + url: this.context.get('url') }; const definitions = await apiKanjiFind(link.textContent, this.getOptionsContext()); @@ -85,17 +83,17 @@ class Display { } onGlossaryMouseDown(e) { - if (Frontend.isMouseButtonPressed('primary', e)) { + if (DOM.isMouseButtonPressed(e, 'primary')) { this.clickScanPrevent = false; } } - onGlossaryMouseMove(e) { + onGlossaryMouseMove() { this.clickScanPrevent = true; } onGlossaryMouseUp(e) { - if (!this.clickScanPrevent && Frontend.isMouseButtonPressed('primary', e)) { + if (!this.clickScanPrevent && DOM.isMouseButtonPressed(e, 'primary')) { this.onTermLookup(e); } } @@ -103,6 +101,7 @@ class Display { async onTermLookup(e, {disableScroll, selectText, disableHistory}={}) { try { if (!this.context) { return; } + const termLookupResults = await this.termLookup(e); if (!termLookupResults) { return; } const {textSource, definitions} = termLookupResults; @@ -110,25 +109,26 @@ class Display { const scannedElement = e.target; const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt); - if (!disableScroll) { - this.windowScroll.toY(0); - } - + this.context.update({ + index: this.entryIndexFind(scannedElement), + scroll: this.windowScroll.y + }); const context = { - source: disableHistory ? this.context.source : { - type: 'terms', - details: { - definitions: this.definitions, - context: Object.assign({}, this.context, { - index: this.entryIndexFind(scannedElement), - scroll: this.windowScroll.y - }) - } - }, disableScroll, + disableHistory, sentence, - url: this.context.url + url: this.context.get('url') }; + if (disableHistory) { + Object.assign(context, { + previous: this.context.previous, + next: this.context.next + }); + } else { + Object.assign(context, { + previous: this.context + }); + } this.setContentTerms(definitions, context); @@ -194,7 +194,7 @@ class Display { onKeyDown(e) { const key = Display.getKeyFromEvent(e); const handlers = Display.onKeyDownHandlers; - if (handlers.hasOwnProperty(key)) { + if (hasOwn(handlers, key)) { const handler = handlers[key]; if (handler(this, e)) { e.preventDefault(); @@ -206,9 +206,17 @@ class Display { onWheel(e) { if (e.altKey) { - const delta = e.deltaY; - if (delta !== 0) { - this.entryScrollIntoView(this.index + (delta > 0 ? 1 : -1), null, true); + if (e.deltaY !== 0) { + this.entryScrollIntoView(this.index + (e.deltaY > 0 ? 1 : -1), null, true); + e.preventDefault(); + } + } else if (e.shiftKey) { + const delta = -e.deltaX || e.deltaY; + if (delta > 0) { + this.sourceTermView(); + e.preventDefault(); + } else if (delta < 0) { + this.nextTermView(); e.preventDefault(); } } @@ -216,7 +224,7 @@ class Display { onRuntimeMessage({action, params}, sender, callback) { const handlers = Display.runtimeMessageHandlers; - if (handlers.hasOwnProperty(action)) { + if (hasOwn(handlers, action)) { const handler = handlers[action]; const result = handler(this, params); callback(result); @@ -292,6 +300,7 @@ class Display { this.addEventListeners('.action-play-audio', 'click', this.onAudioPlay.bind(this)); this.addEventListeners('.kanji-link', 'click', this.onKanjiLookup.bind(this)); this.addEventListeners('.source-term', 'click', this.onSourceTermView.bind(this)); + this.addEventListeners('.next-term', 'click', this.onNextTermView.bind(this)); if (this.options.scanning.enablePopupSearch) { this.addEventListeners('.glossary-item', 'mouseup', this.onGlossaryMouseUp.bind(this)); this.addEventListeners('.glossary-item', 'mousedown', this.onGlossaryMouseDown.bind(this)); @@ -335,12 +344,18 @@ class Display { } this.definitions = definitions; - this.context = context; + if (context.disableHistory) { + delete context.disableHistory; + this.context = new DisplayContext('terms', definitions, context); + } else { + this.context = DisplayContext.push(this.context, 'terms', definitions, context); + } const sequence = ++this.sequence; const params = { definitions, - source: context.source, + source: this.context.previous, + next: this.context.next, addable: options.anki.enable, grouped: options.general.resultOutputMode === 'group', merged: options.general.resultOutputMode === 'merge', @@ -359,6 +374,9 @@ class Display { const {index, scroll, disableScroll} = context; if (!disableScroll) { this.entryScrollIntoView(index || 0, scroll); + } else { + delete context.disableScroll; + this.entrySetCurrent(index || 0); } if (options.audio.enabled && options.audio.autoPlay) { @@ -387,12 +405,18 @@ class Display { } this.definitions = definitions; - this.context = context; + if (context.disableHistory) { + delete context.disableHistory; + this.context = new DisplayContext('kanji', definitions, context); + } else { + this.context = DisplayContext.push(this.context, 'kanji', definitions, context); + } const sequence = ++this.sequence; const params = { definitions, - source: context.source, + source: this.context.previous, + next: this.context.next, addable: options.anki.enable, debug: options.general.debugInfo }; @@ -464,7 +488,7 @@ class Display { } } - entryScrollIntoView(index, scroll, smooth) { + entrySetCurrent(index) { index = Math.min(index, this.definitions.length - 1); index = Math.max(index, 0); @@ -478,13 +502,20 @@ class Display { entry.classList.add('entry-current'); } + this.index = index; + + return entry; + } + + entryScrollIntoView(index, scroll, smooth) { this.windowScroll.stop(); - let target; - if (scroll) { + const entry = this.entrySetCurrent(index); + let target; + if (scroll !== null) { target = scroll; } else { - target = index === 0 || entry === null ? 0 : Display.getElementTop(entry); + target = this.index === 0 || entry === null ? 0 : Display.getElementTop(entry); } if (smooth) { @@ -492,14 +523,36 @@ class Display { } else { this.windowScroll.toY(target); } - - this.index = index; } sourceTermView() { - if (!this.context || !this.context.source) { return; } - const {type, details} = this.context.source; - this.setContent(type, details); + if (!this.context || !this.context.previous) { return; } + this.context.update({ + index: this.index, + scroll: this.windowScroll.y + }); + const previousContext = this.context.previous; + previousContext.set('disableHistory', true); + const details = { + definitions: previousContext.definitions, + context: previousContext.context + }; + this.setContent(previousContext.type, details); + } + + nextTermView() { + if (!this.context || !this.context.next) { return; } + this.context.update({ + index: this.index, + scroll: this.windowScroll.y + }); + const nextContext = this.context.next; + nextContext.set('disableHistory', true); + const details = { + definitions: nextContext.definitions, + context: nextContext.context + }; + this.setContent(nextContext.type, details); } noteTryAdd(mode) { @@ -574,7 +627,7 @@ class Display { if (button !== null) { let titleDefault = button.dataset.titleDefault; if (!titleDefault) { - titleDefault = button.title || ""; + titleDefault = button.title || ''; button.dataset.titleDefault = titleDefault; } button.title = `${titleDefault}\n${info}`; @@ -770,6 +823,14 @@ Display.onKeyDownHandlers = { return false; }, + 'F': (self, e) => { + if (e.altKey) { + self.nextTermView(); + return true; + } + return false; + }, + 'E': (self, e) => { if (e.altKey) { self.noteTryAdd('term-kanji'); |