From 7a3315d75d91e37f69cf23faa0e5b189ad548e52 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 22 Oct 2019 20:23:03 -0400 Subject: Use chrome.runtime.getURL instead of chrome.extension.getURL --- ext/bg/js/api.js | 4 ++-- ext/bg/js/backend.js | 2 +- ext/bg/js/context.js | 4 ++-- ext/bg/js/translator.js | 2 +- ext/fg/js/popup.js | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 93d9c155..999ea337 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -153,7 +153,7 @@ async function apiCommandExec(command, params) { } apiCommandExec.handlers = { search: async (params) => { - const url = chrome.extension.getURL('/bg/search.html'); + const url = chrome.runtime.getURL('/bg/search.html'); if (!(params && params.newTab)) { try { const tab = await apiFindTab(1000, (url2) => ( @@ -181,7 +181,7 @@ apiCommandExec.handlers = { chrome.runtime.openOptionsPage(); } else { const manifest = chrome.runtime.getManifest(); - const url = chrome.extension.getURL(manifest.options_ui.page); + const url = chrome.runtime.getURL(manifest.options_ui.page); chrome.tabs.create({url}); } }, diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index f29230a2..23d876f6 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -45,7 +45,7 @@ class Backend { const options = this.getOptionsSync(this.optionsContext); if (options.general.showGuide) { - chrome.tabs.create({url: chrome.extension.getURL('/bg/guide.html')}); + chrome.tabs.create({url: chrome.runtime.getURL('/bg/guide.html')}); } this.isPreparedResolve(); diff --git a/ext/bg/js/context.js b/ext/bg/js/context.js index 8e1dbce6..3fb27f0d 100644 --- a/ext/bg/js/context.js +++ b/ext/bg/js/context.js @@ -55,8 +55,8 @@ $(document).ready(utilAsync(() => { const manifest = chrome.runtime.getManifest(); - setupButtonEvents('.action-open-search', 'search', chrome.extension.getURL('/bg/search.html')); - setupButtonEvents('.action-open-options', 'options', chrome.extension.getURL(manifest.options_ui.page)); + setupButtonEvents('.action-open-search', 'search', chrome.runtime.getURL('/bg/search.html')); + setupButtonEvents('.action-open-options', 'options', chrome.runtime.getURL(manifest.options_ui.page)); setupButtonEvents('.action-open-help', 'help'); const optionsContext = { diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index ee012d96..9d90136b 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -31,7 +31,7 @@ class Translator { } if (!this.deinflector) { - const url = chrome.extension.getURL('/bg/lang/deinflect.json'); + const url = chrome.runtime.getURL('/bg/lang/deinflect.json'); const reasons = await requestJson(url, 'GET'); this.deinflector = new Deinflector(reasons); } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index b5eb9fe2..1f9317e0 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -30,7 +30,7 @@ class Popup { this.container.className = 'yomichan-float'; this.container.addEventListener('mousedown', e => e.stopPropagation()); this.container.addEventListener('scroll', e => e.stopPropagation()); - this.container.setAttribute('src', chrome.extension.getURL('/fg/float.html')); + this.container.setAttribute('src', chrome.runtime.getURL('/fg/float.html')); this.container.style.width = '0px'; this.container.style.height = '0px'; this.injectPromise = null; -- cgit v1.2.3 From aeac7bf2a87c10f01eafb85949633fc7ce17260c Mon Sep 17 00:00:00 2001 From: Danny Date: Wed, 23 Oct 2019 07:46:43 -0400 Subject: Proper spacing for Anki in {furigana-plain} This should fix #264 Note it does not address broken segmentation, just representation within Anki itself to work properly. --- ext/bg/js/handlebars.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/bg/js/handlebars.js b/ext/bg/js/handlebars.js index 92764a20..fba437da 100644 --- a/ext/bg/js/handlebars.js +++ b/ext/bg/js/handlebars.js @@ -49,13 +49,13 @@ function handlebarsFuriganaPlain(options) { let result = ''; for (const seg of segs) { if (seg.furigana) { - result += `${seg.text}[${seg.furigana}]`; + result += ` ${seg.text}[${seg.furigana}]`; } else { result += seg.text; } } - return result; + return result.trimLeft(); } function handlebarsKanjiLinks(options) { -- cgit v1.2.3 From a716a52cab143ae2e02b54c2f075a8731de16193 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 26 Oct 2019 01:26:56 +0300 Subject: make non-hotkey keys focus input on search page The issue was that scanning on search page introduced a way to lose focus of the query input, and the new feature that the search page hotkey focuses an existing search page instead of opening a new one made it more obvious. Now every key that isn't a hotkey focuses the query input, and typing text into the box scrolls it into view in case it wasn't there when searching. There is an accessibility issue that this can cause, because now tab also focuses the query input before it focuses the next element. I didn't implement a workaround for that because it would have been more complicated than this simple fix. Fixes #263 --- ext/bg/js/search.js | 7 +++++++ ext/mixed/js/display.js | 2 ++ 2 files changed, 9 insertions(+) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 431478c9..5c0bffed 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -79,6 +79,7 @@ class DisplaySearch extends Display { onSearchInput() { this.updateSearchButton(); + this.query.scrollIntoView(); } onSearch(e) { @@ -94,6 +95,12 @@ class DisplaySearch extends Display { this.onSearchQueryUpdated(query, true); } + onKeyDown(e) { + if (!super.onKeyDown(e)) { + this.query.focus({preventScroll: true}); + } + } + async onSearchQueryUpdated(query, animate) { try { const valid = (query.length > 0); diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index b40228b0..bdc5e962 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -157,8 +157,10 @@ class Display { const handler = handlers[key]; if (handler(this, e)) { e.preventDefault(); + return true; } } + return false; } onWheel(e) { -- cgit v1.2.3 From 3a70346eb37ce234e49460ed0c97acb3affe68cc Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 26 Oct 2019 03:26:24 +0300 Subject: fix various unwanted focus issues on search page Don't focus input if a modifier or specific keys are pressed --- ext/bg/js/search.js | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 5c0bffed..f0bbf203 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -96,7 +96,34 @@ class DisplaySearch extends Display { } onKeyDown(e) { - if (!super.onKeyDown(e)) { + const key = Display.getKeyFromEvent(e); + + let activeModifierMap = { + 'Control': e.ctrlKey, + 'Meta': e.metaKey + }; + // true if no known modifier is pressed + activeModifierMap[undefined] = !Object.values(activeModifierMap).includes(true); + + const ignoreKeys = { + undefined: ['Tab'], + 'Control': ['C', 'A', 'V'], + 'Meta': ['C', 'A', 'V'], + 'OS': [], + 'Alt': [], + 'Shift': [] + } + + let preventFocus = false; + for (const [modifier, keys] of Object.entries(ignoreKeys)) { + const modifierActive = activeModifierMap[modifier]; + if (key === modifier || (modifierActive && keys.includes(key))) { + preventFocus = true; + break; + } + } + + if (!super.onKeyDown(e) && !preventFocus) { this.query.focus({preventScroll: true}); } } -- cgit v1.2.3 From fe8eb76928de8ce72689b6ae3eb3a90c626c3720 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 26 Oct 2019 03:39:08 +0300 Subject: tweak ignored keys on search page --- ext/bg/js/search.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index f0bbf203..d74998d6 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -107,8 +107,8 @@ class DisplaySearch extends Display { const ignoreKeys = { undefined: ['Tab'], - 'Control': ['C', 'A', 'V'], - 'Meta': ['C', 'A', 'V'], + 'Control': ['C', 'A', 'Z', 'Y', 'X', 'F'], + 'Meta': ['C', 'A', 'Z', 'Y', 'X', 'F'], 'OS': [], 'Alt': [], 'Shift': [] -- cgit v1.2.3 From 9132814ccf15ec2d1272c14e4840f4affad94706 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 26 Oct 2019 14:30:36 +0300 Subject: focus and scroll to input only when it's needed --- ext/bg/js/search.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index d74998d6..1a6822f6 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -79,7 +79,11 @@ class DisplaySearch extends Display { onSearchInput() { this.updateSearchButton(); - this.query.scrollIntoView(); + + const queryElementRect = this.query.getBoundingClientRect(); + if (queryElementRect.top < 0 || queryElementRect.bottom > window.innerHeight) { + this.query.scrollIntoView(); + } } onSearch(e) { @@ -123,7 +127,7 @@ class DisplaySearch extends Display { } } - if (!super.onKeyDown(e) && !preventFocus) { + if (!super.onKeyDown(e) && !preventFocus && document.activeElement !== this.query) { this.query.focus({preventScroll: true}); } } -- cgit v1.2.3 From 50769feea71943051eaf12f1d96bc6305746959f Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 26 Oct 2019 15:15:12 +0300 Subject: ignore more keys on search page --- ext/bg/js/search.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 1a6822f6..6481e16a 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -104,17 +104,21 @@ class DisplaySearch extends Display { let activeModifierMap = { 'Control': e.ctrlKey, - 'Meta': e.metaKey + 'Meta': e.metaKey, + 'ANY_MOD': true }; - // true if no known modifier is pressed - activeModifierMap[undefined] = !Object.values(activeModifierMap).includes(true); const ignoreKeys = { - undefined: ['Tab'], - 'Control': ['C', 'A', 'Z', 'Y', 'X', 'F'], - 'Meta': ['C', 'A', 'Z', 'Y', 'X', 'F'], + 'ANY_MOD': ['Tab', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'PageDown', 'PageUp', 'Home', 'End'] + .concat( + Array.from(Array(24).keys()) + .map(i => `F${i + 1}`) + ), + 'Control': ['C', 'A', 'Z', 'Y', 'X', 'F', 'G'], + 'Meta': ['C', 'A', 'Z', 'Y', 'X', 'F', 'G'], 'OS': [], 'Alt': [], + 'AltGraph': [], 'Shift': [] } -- cgit v1.2.3 From bebd70b4e2d8da54b556b488d68a5111f3ff20c1 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 26 Oct 2019 16:39:43 +0300 Subject: remember search history --- ext/bg/js/search.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 6481e16a..d66e68b8 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -58,6 +58,8 @@ class DisplaySearch extends Display { window.wanakana.bind(this.query); } + window.addEventListener('popstate', (e) => this.onPopState(e)); + this.updateSearchButton(); } catch (e) { this.onError(e); @@ -95,10 +97,23 @@ class DisplaySearch extends Display { const query = this.query.value; const queryString = query.length > 0 ? `?query=${encodeURIComponent(query)}` : ''; - window.history.replaceState(null, '', `${window.location.pathname}${queryString}`); + window.history.pushState({query}, '', `${window.location.pathname}${queryString}`); this.onSearchQueryUpdated(query, true); } + onPopState(e) { + let query = ''; + if (e.state && e.state.query) { + query = e.state.query + } + + if (this.query !== null) { + this.query.value = query; + } + + this.onSearchQueryUpdated(query, false); + } + onKeyDown(e) { const key = Display.getKeyFromEvent(e); -- cgit v1.2.3 From 704864b7b2365de488150c947d50e27c97d3bc4c Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 26 Oct 2019 18:15:28 +0300 Subject: add clipboard monitor to search page Related to issue #262 about APIs --- ext/bg/js/search.js | 44 +++++++++++++++++++++++++++++++++++++++++++- ext/bg/search.html | 9 ++++++++- ext/manifest.json | 1 + 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index d66e68b8..2d130522 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -29,8 +29,13 @@ class DisplaySearch extends Display { this.search = document.querySelector('#search'); this.query = document.querySelector('#query'); this.intro = document.querySelector('#intro'); + this.clipboardMonitorCheck = document.querySelector('#clipboard-monitor'); + this.introVisible = true; this.introAnimationTimer = null; + + this.clipboardMonitorIntervalId = null; + this.clipboardPrevText = null; } static create() { @@ -57,10 +62,20 @@ class DisplaySearch extends Display { window.wanakana.bind(this.query); } + if (this.clipboardMonitorCheck !== null) { + this.clipboardMonitorCheck.addEventListener('change', (e) => { + if (e.target.checked) { + this.startClipboardMonitor(); + } else { + this.stopClipboardMonitor(); + } + }); + } window.addEventListener('popstate', (e) => this.onPopState(e)); this.updateSearchButton(); + this.initClipboardMonitor(); } catch (e) { this.onError(e); } @@ -93,7 +108,9 @@ class DisplaySearch extends Display { return; } - e.preventDefault(); + if (e) { + e.preventDefault(); + } const query = this.query.value; const queryString = query.length > 0 ? `?query=${encodeURIComponent(query)}` : ''; @@ -182,6 +199,31 @@ class DisplaySearch extends Display { } } + initClipboardMonitor() { + // ignore copy from search page + window.addEventListener('copy', (e) => { + this.clipboardPrevText = document.getSelection().toString().trim(); + }); + } + + startClipboardMonitor() { + this.clipboardMonitorIntervalId = setInterval(async () => { + const curText = (await navigator.clipboard.readText()).trim(); + if (curText && (curText !== this.clipboardPrevText)) { + this.query.value = curText; + this.onSearch(); + this.clipboardPrevText = curText; + } + }, 100); + } + + stopClipboardMonitor() { + if (this.clipboardMonitorIntervalId) { + clearInterval(this.clipboardMonitorIntervalId); + this.clipboardMonitorIntervalId = null; + } + } + getOptionsContext() { return this.optionsContext; } diff --git a/ext/bg/search.html b/ext/bg/search.html index 9d28b358..1e650be0 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -19,7 +19,14 @@

Search your installed dictionaries by entering a Japanese expression into the field below.

-
+
+ + + + +
+ + diff --git a/ext/manifest.json b/ext/manifest.json index e913c2b0..2b7fc105 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -41,6 +41,7 @@ "permissions": [ "", "storage", + "clipboardRead", "clipboardWrite", "unlimitedStorage" ], -- cgit v1.2.3 From 303205dc124a1dde981db5b6401961f797e3a6d4 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 26 Oct 2019 18:42:57 +0300 Subject: keep url query in history --- ext/bg/js/search.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 2d130522..8d2e7bf2 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -57,6 +57,7 @@ class DisplaySearch extends Display { const query = DisplaySearch.getSearchQueryFromLocation(window.location.href); if (query !== null) { this.query.value = window.wanakana.toKana(query); + window.history.replaceState({query}, ''); this.onSearchQueryUpdated(query, false); } -- cgit v1.2.3 From bbbd23c842fae4a6f21afcf91fb797dd6f5709f7 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 26 Oct 2019 19:12:13 +0300 Subject: add button to enable/disable wanakana IME --- ext/bg/js/search.js | 40 +++++++++++++++++++++++++++++++--------- ext/bg/search.html | 8 ++++++-- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 8d2e7bf2..11d1d871 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -29,7 +29,8 @@ class DisplaySearch extends Display { this.search = document.querySelector('#search'); this.query = document.querySelector('#query'); this.intro = document.querySelector('#intro'); - this.clipboardMonitorCheck = document.querySelector('#clipboard-monitor'); + this.clipboardMonitorEnable = document.querySelector('#clipboard-monitor-enable'); + this.wanakanaEnable = document.querySelector('#wanakana-enable'); this.introVisible = true; this.introAnimationTimer = null; @@ -54,17 +55,31 @@ class DisplaySearch extends Display { if (this.query !== null) { this.query.addEventListener('input', () => this.onSearchInput(), false); - const query = DisplaySearch.getSearchQueryFromLocation(window.location.href); + if (this.wanakanaEnable !== null) { + if (this.wanakanaEnable.checked) { + window.wanakana.bind(this.query); + } + this.wanakanaEnable.addEventListener('change', (e) => { + if (e.target.checked) { + window.wanakana.bind(this.query); + } else { + window.wanakana.unbind(this.query); + } + }); + } + + let query = DisplaySearch.getSearchQueryFromLocation(window.location.href); if (query !== null) { - this.query.value = window.wanakana.toKana(query); + if (this.wanakanaEnable !== null && this.wanakanaEnable.checked) { + query = window.wanakana.toKana(query); + } + this.query.value = query; window.history.replaceState({query}, ''); this.onSearchQueryUpdated(query, false); } - - window.wanakana.bind(this.query); } - if (this.clipboardMonitorCheck !== null) { - this.clipboardMonitorCheck.addEventListener('change', (e) => { + if (this.clipboardMonitorEnable !== null) { + this.clipboardMonitorEnable.addEventListener('change', (e) => { if (e.target.checked) { this.startClipboardMonitor(); } else { @@ -203,13 +218,20 @@ class DisplaySearch extends Display { initClipboardMonitor() { // ignore copy from search page window.addEventListener('copy', (e) => { - this.clipboardPrevText = document.getSelection().toString().trim(); + let prevText = document.getSelection().toString().trim(); + if (this.wanakanaEnable !== null && this.wanakanaEnable.checked) { + prevText = window.wanakana.toKana(prevText); + } + this.clipboardPrevText = prevText; }); } startClipboardMonitor() { this.clipboardMonitorIntervalId = setInterval(async () => { - const curText = (await navigator.clipboard.readText()).trim(); + let curText = (await navigator.clipboard.readText()).trim(); + if (this.wanakanaEnable !== null && this.wanakanaEnable.checked) { + curText = window.wanakana.toKana(curText); + } if (curText && (curText !== this.clipboardPrevText)) { this.query.value = curText; this.onSearch(); diff --git a/ext/bg/search.html b/ext/bg/search.html index 1e650be0..11dca5a2 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -20,9 +20,13 @@
+ + + + - - + +
-- cgit v1.2.3 From 01ffb052e6bfc04c2a0e260769ac9183b2bd60a0 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 26 Oct 2019 19:32:41 +0300 Subject: simplify search history state handling --- ext/bg/js/search.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 11d1d871..bfd88552 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -74,7 +74,6 @@ class DisplaySearch extends Display { query = window.wanakana.toKana(query); } this.query.value = query; - window.history.replaceState({query}, ''); this.onSearchQueryUpdated(query, false); } } @@ -130,16 +129,12 @@ class DisplaySearch extends Display { const query = this.query.value; const queryString = query.length > 0 ? `?query=${encodeURIComponent(query)}` : ''; - window.history.pushState({query}, '', `${window.location.pathname}${queryString}`); + window.history.pushState(null, '', `${window.location.pathname}${queryString}`); this.onSearchQueryUpdated(query, true); } onPopState(e) { - let query = ''; - if (e.state && e.state.query) { - query = e.state.query - } - + const query = DisplaySearch.getSearchQueryFromLocation(window.location.href) || ''; if (this.query !== null) { this.query.value = query; } -- cgit v1.2.3 From 7ee87265cd937a8dd584c509d3c8ed45c96c221f Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 27 Oct 2019 01:26:17 +0300 Subject: refactor and tune wanakana toggling --- ext/bg/js/search.js | 54 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index bfd88552..8484e042 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -60,21 +60,26 @@ class DisplaySearch extends Display { window.wanakana.bind(this.query); } this.wanakanaEnable.addEventListener('change', (e) => { + let query = DisplaySearch.getSearchQueryFromLocation(window.location.href); if (e.target.checked) { window.wanakana.bind(this.query); + this.query.value = window.wanakana.toKana(query); } else { window.wanakana.unbind(this.query); + this.query.value = query; } + this.onSearchQueryUpdated(this.query.value, false); }); } - let query = DisplaySearch.getSearchQueryFromLocation(window.location.href); + const query = DisplaySearch.getSearchQueryFromLocation(window.location.href); if (query !== null) { - if (this.wanakanaEnable !== null && this.wanakanaEnable.checked) { - query = window.wanakana.toKana(query); + if (this.isWanakanaEnabled()) { + this.query.value = window.wanakana.toKana(query); + } else { + this.query.value = query; } - this.query.value = query; - this.onSearchQueryUpdated(query, false); + this.onSearchQueryUpdated(this.query.value, false); } } if (this.clipboardMonitorEnable !== null) { @@ -123,9 +128,7 @@ class DisplaySearch extends Display { return; } - if (e) { - e.preventDefault(); - } + e.preventDefault(); const query = this.query.value; const queryString = query.length > 0 ? `?query=${encodeURIComponent(query)}` : ''; @@ -136,10 +139,14 @@ class DisplaySearch extends Display { onPopState(e) { const query = DisplaySearch.getSearchQueryFromLocation(window.location.href) || ''; if (this.query !== null) { - this.query.value = query; + if (this.isWanakanaEnabled()) { + this.query.value = window.wanakana.toKana(query); + } else { + this.query.value = query; + } } - this.onSearchQueryUpdated(query, false); + this.onSearchQueryUpdated(this.query.value, false); } onKeyDown(e) { @@ -213,23 +220,24 @@ class DisplaySearch extends Display { initClipboardMonitor() { // ignore copy from search page window.addEventListener('copy', (e) => { - let prevText = document.getSelection().toString().trim(); - if (this.wanakanaEnable !== null && this.wanakanaEnable.checked) { - prevText = window.wanakana.toKana(prevText); - } - this.clipboardPrevText = prevText; + this.clipboardPrevText = document.getSelection().toString().trim(); }); } startClipboardMonitor() { this.clipboardMonitorIntervalId = setInterval(async () => { - let curText = (await navigator.clipboard.readText()).trim(); - if (this.wanakanaEnable !== null && this.wanakanaEnable.checked) { - curText = window.wanakana.toKana(curText); - } + const curText = (await navigator.clipboard.readText()).trim(); if (curText && (curText !== this.clipboardPrevText)) { - this.query.value = curText; - this.onSearch(); + if (this.isWanakanaEnabled()) { + this.query.value = window.wanakana.toKana(curText); + } else { + this.query.value = curText; + } + + const queryString = curText.length > 0 ? `?query=${encodeURIComponent(curText)}` : ''; + window.history.pushState(null, '', `${window.location.pathname}${queryString}`); + this.onSearchQueryUpdated(this.query.value, true); + this.clipboardPrevText = curText; } }, 100); @@ -242,6 +250,10 @@ class DisplaySearch extends Display { } } + isWanakanaEnabled() { + return this.wanakanaEnable !== null && this.wanakanaEnable.checked; + } + getOptionsContext() { return this.optionsContext; } -- cgit v1.2.3 From d3f51690f8bb236d1ba3c79c20b3a60d3e62dc52 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 27 Oct 2019 01:51:18 +0300 Subject: make clipboardRead an optional permission --- ext/bg/js/search.js | 11 ++++++++++- ext/manifest.json | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 8484e042..a09ca822 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -85,7 +85,16 @@ class DisplaySearch extends Display { if (this.clipboardMonitorEnable !== null) { this.clipboardMonitorEnable.addEventListener('change', (e) => { if (e.target.checked) { - this.startClipboardMonitor(); + chrome.permissions.request( + {permissions: ['clipboardRead']}, + (granted) => { + if (granted) { + this.startClipboardMonitor(); + } else { + e.target.checked = false; + } + } + ); } else { this.stopClipboardMonitor(); } diff --git a/ext/manifest.json b/ext/manifest.json index 2b7fc105..6390cbfb 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -41,10 +41,12 @@ "permissions": [ "", "storage", - "clipboardRead", "clipboardWrite", "unlimitedStorage" ], + "optional_permissions": [ + "clipboardRead" + ], "commands": { "toggle": { "suggested_key": { -- cgit v1.2.3 From 48776145d6bdb8aff82e82546583c790353e75b6 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 27 Oct 2019 15:46:27 +0200 Subject: add workaround to Chrome clipboard.readText For some reason this doesn't work on Firefox, so keep using the new API for Firefox --- ext/bg/background.html | 2 ++ ext/bg/js/api.js | 8 ++++++++ ext/bg/js/backend.js | 5 ++++- ext/bg/js/search.js | 14 +++++++++++++- ext/fg/js/api.js | 4 ++++ 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/ext/bg/background.html b/ext/bg/background.html index 194d4a45..30b3db48 100644 --- a/ext/bg/background.html +++ b/ext/bg/background.html @@ -5,6 +5,8 @@ +
+ diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 999ea337..88eef431 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -401,3 +401,11 @@ async function apiFocusTab(tab) { // Edge throws exception for no reason here. } } + +async function apiClipboardGet() { + const clipboardPasteTarget = utilBackend().clipboardPasteTarget; + clipboardPasteTarget.innerText = ''; + clipboardPasteTarget.focus(); + document.execCommand('paste'); + return clipboardPasteTarget.innerText; +} diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 23d876f6..7192d026 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -30,6 +30,8 @@ class Backend { this.isPreparedResolve = null; this.isPreparedPromise = new Promise((resolve) => (this.isPreparedResolve = resolve)); + this.clipboardPasteTarget = document.querySelector('#clipboard-paste-target'); + this.apiForwarder = new BackendApiForwarder(); } @@ -187,7 +189,8 @@ Backend.messageHandlers = { forward: ({action, params}, sender) => apiForward(action, params, sender), frameInformationGet: (params, sender) => apiFrameInformationGet(sender), injectStylesheet: ({css}, sender) => apiInjectStylesheet(css, sender), - getEnvironmentInfo: () => apiGetEnvironmentInfo() + getEnvironmentInfo: () => apiGetEnvironmentInfo(), + clipboardGet: () => apiClipboardGet() }; window.yomichan_backend = new Backend(); diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index a09ca822..dca4e8fa 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -17,6 +17,12 @@ */ +let IS_FIREFOX = null; +(async () => { + const {browser} = await apiGetEnvironmentInfo(); + IS_FIREFOX = ['firefox', 'firefox-mobile'].includes(browser); +})(); + class DisplaySearch extends Display { constructor() { super(document.querySelector('#spinner'), document.querySelector('#content')); @@ -235,7 +241,13 @@ class DisplaySearch extends Display { startClipboardMonitor() { this.clipboardMonitorIntervalId = setInterval(async () => { - const curText = (await navigator.clipboard.readText()).trim(); + let curText = null; + // TODO get rid of this and figure out why apiClipboardGet doesn't work on Firefox + if (IS_FIREFOX) { + curText = (await navigator.clipboard.readText()).trim(); + } else if (IS_FIREFOX === false) { + curText = (await apiClipboardGet()).trim(); + } if (curText && (curText !== this.clipboardPrevText)) { if (this.isWanakanaEnabled()) { this.query.value = window.wanakana.toKana(curText); diff --git a/ext/fg/js/api.js b/ext/fg/js/api.js index b0746b85..bbc9b5fc 100644 --- a/ext/fg/js/api.js +++ b/ext/fg/js/api.js @@ -72,3 +72,7 @@ function apiInjectStylesheet(css) { function apiGetEnvironmentInfo() { return utilInvoke('getEnvironmentInfo'); } + +function apiClipboardGet() { + return utilInvoke('clipboardGet'); +} -- cgit v1.2.3 From 70418202cf2739258a4e95fdc7f0fbe4c7c46821 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 27 Oct 2019 20:11:23 +0200 Subject: make search page checkbox options persist --- ext/bg/js/api.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ ext/bg/js/backend.js | 1 + ext/bg/js/options.js | 4 +++- ext/bg/js/search.js | 15 ++++++++++++++- ext/bg/search.html | 2 +- ext/fg/js/api.js | 4 ++++ 6 files changed, 72 insertions(+), 3 deletions(-) diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 88eef431..6c109614 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -21,6 +21,55 @@ function apiOptionsGet(optionsContext) { return utilBackend().getOptions(optionsContext); } +async function apiOptionsSet(changedOptions, optionsContext, source) { + const backend = utilBackend(); + const {depth} = optionsContext; + let options = await apiOptionsGetFull(); + + function getValuePaths(obj) { + let valuePaths = []; + let nodes = [{ + obj: changedOptions, + path: [] + }]; + while (nodes.length > 0) { + let node = nodes.pop(); + Object.keys(node.obj).forEach((key) => { + let path = node.path.concat(key); + let value = node.obj[key]; + if (typeof value === 'object') { + nodes.unshift({ + obj: value, + path: path + }); + } else { + valuePaths.push([value, path]); + } + }); + } + return valuePaths; + } + + function modifyOption(path, value, options) { + let pivot = options; + for (let pathKey of path.slice(0, -1)) { + if (!(pathKey in pivot)) { + return false; + } + pivot = pivot[pathKey]; + } + pivot[path[path.length - 1]] = value; + return true; + } + + for (let [value, path] of getValuePaths(changedOptions)) { + modifyOption(path, value, options.profiles[depth].options); + } + + await optionsSave(options); + backend.onOptionsUpdated(source); +} + function apiOptionsGetFull() { return utilBackend().getFullOptions(); } diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 7192d026..71393467 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -177,6 +177,7 @@ class Backend { Backend.messageHandlers = { optionsGet: ({optionsContext}) => apiOptionsGet(optionsContext), + optionsSet: ({changedOptions, optionsContext, source}) => apiOptionsSet(changedOptions, optionsContext, source), kanjiFind: ({text, optionsContext}) => apiKanjiFind(text, optionsContext), termsFind: ({text, optionsContext}) => apiTermsFind(text, optionsContext), definitionAdd: ({definition, mode, context, optionsContext}) => apiDefinitionAdd(definition, mode, context, optionsContext), diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index 4854cd65..be1ccfbb 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -279,7 +279,9 @@ function profileOptionsCreateDefaults() { popupTheme: 'default', popupOuterTheme: 'default', customPopupCss: '', - customPopupOuterCss: '' + customPopupOuterCss: '', + enableWanakana: true, + enableClipboardMonitor: false }, audio: { diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index dca4e8fa..65cca002 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -62,17 +62,22 @@ class DisplaySearch extends Display { this.query.addEventListener('input', () => this.onSearchInput(), false); if (this.wanakanaEnable !== null) { - if (this.wanakanaEnable.checked) { + if (this.options.general.enableWanakana === true) { + this.wanakanaEnable.checked = true; window.wanakana.bind(this.query); + } else { + this.wanakanaEnable.checked = false; } this.wanakanaEnable.addEventListener('change', (e) => { let query = DisplaySearch.getSearchQueryFromLocation(window.location.href); if (e.target.checked) { window.wanakana.bind(this.query); this.query.value = window.wanakana.toKana(query); + apiOptionsSet({general: {enableWanakana: true}}, this.getOptionsContext()); } else { window.wanakana.unbind(this.query); this.query.value = query; + apiOptionsSet({general: {enableWanakana: false}}, this.getOptionsContext()); } this.onSearchQueryUpdated(this.query.value, false); }); @@ -89,6 +94,12 @@ class DisplaySearch extends Display { } } if (this.clipboardMonitorEnable !== null) { + if (this.options.general.enableClipboardMonitor === true) { + this.clipboardMonitorEnable.checked = true; + this.startClipboardMonitor(); + } else { + this.clipboardMonitorEnable.checked = false; + } this.clipboardMonitorEnable.addEventListener('change', (e) => { if (e.target.checked) { chrome.permissions.request( @@ -96,6 +107,7 @@ class DisplaySearch extends Display { (granted) => { if (granted) { this.startClipboardMonitor(); + apiOptionsSet({general: {enableClipboardMonitor: true}}, this.getOptionsContext()); } else { e.target.checked = false; } @@ -103,6 +115,7 @@ class DisplaySearch extends Display { ); } else { this.stopClipboardMonitor(); + apiOptionsSet({general: {enableClipboardMonitor: false}}, this.getOptionsContext()); } }); } diff --git a/ext/bg/search.html b/ext/bg/search.html index 11dca5a2..8b339cc7 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -22,7 +22,7 @@
- + diff --git a/ext/fg/js/api.js b/ext/fg/js/api.js index bbc9b5fc..54818702 100644 --- a/ext/fg/js/api.js +++ b/ext/fg/js/api.js @@ -21,6 +21,10 @@ function apiOptionsGet(optionsContext) { return utilInvoke('optionsGet', {optionsContext}); } +function apiOptionsSet(changedOptions, optionsContext, source) { + return utilInvoke('optionsSet', {changedOptions, optionsContext, source}); +} + function apiTermsFind(text, optionsContext) { return utilInvoke('termsFind', {text, optionsContext}); } -- cgit v1.2.3 From 51c35c9f306e48093fc769713675dca5b02d1398 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 27 Oct 2019 22:43:20 +0200 Subject: modify correct profile apiOptionsSet --- ext/bg/js/api.js | 4 ++-- ext/bg/js/backend.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 6c109614..95787d7d 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -23,7 +23,7 @@ function apiOptionsGet(optionsContext) { async function apiOptionsSet(changedOptions, optionsContext, source) { const backend = utilBackend(); - const {depth} = optionsContext; + const {profileIndex} = backend.getProfileFromContext(optionsContext); let options = await apiOptionsGetFull(); function getValuePaths(obj) { @@ -63,7 +63,7 @@ async function apiOptionsSet(changedOptions, optionsContext, source) { } for (let [value, path] of getValuePaths(changedOptions)) { - modifyOption(path, value, options.profiles[depth].options); + modifyOption(path, value, options.profiles[profileIndex].options); } await optionsSave(options); diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 71393467..6d2e736e 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -122,15 +122,15 @@ class Backend { if (typeof optionsContext.index === 'number') { return profiles[optionsContext.index]; } - const profile = this.getProfileFromContext(optionsContext); + const {profile} = this.getProfileFromContext(optionsContext); return profile !== null ? profile : this.options.profiles[this.options.profileCurrent]; } getProfileFromContext(optionsContext) { - for (const profile of this.options.profiles) { + for (const [profileIndex, profile] of this.options.profiles.entries()) { const conditionGroups = profile.conditionGroups; if (conditionGroups.length > 0 && Backend.testConditionGroups(conditionGroups, optionsContext)) { - return profile; + return {profileIndex, profile}; } } return null; -- cgit v1.2.3 From 9641747ba173eb6cc64b5881759d225253935e4a Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 27 Oct 2019 23:02:41 +0200 Subject: Revert "modify correct profile apiOptionsSet" This reverts commit 51c35c9f306e48093fc769713675dca5b02d1398. --- ext/bg/js/api.js | 4 ++-- ext/bg/js/backend.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 95787d7d..6c109614 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -23,7 +23,7 @@ function apiOptionsGet(optionsContext) { async function apiOptionsSet(changedOptions, optionsContext, source) { const backend = utilBackend(); - const {profileIndex} = backend.getProfileFromContext(optionsContext); + const {depth} = optionsContext; let options = await apiOptionsGetFull(); function getValuePaths(obj) { @@ -63,7 +63,7 @@ async function apiOptionsSet(changedOptions, optionsContext, source) { } for (let [value, path] of getValuePaths(changedOptions)) { - modifyOption(path, value, options.profiles[profileIndex].options); + modifyOption(path, value, options.profiles[depth].options); } await optionsSave(options); diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 6d2e736e..71393467 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -122,15 +122,15 @@ class Backend { if (typeof optionsContext.index === 'number') { return profiles[optionsContext.index]; } - const {profile} = this.getProfileFromContext(optionsContext); + const profile = this.getProfileFromContext(optionsContext); return profile !== null ? profile : this.options.profiles[this.options.profileCurrent]; } getProfileFromContext(optionsContext) { - for (const [profileIndex, profile] of this.options.profiles.entries()) { + for (const profile of this.options.profiles) { const conditionGroups = profile.conditionGroups; if (conditionGroups.length > 0 && Backend.testConditionGroups(conditionGroups, optionsContext)) { - return {profileIndex, profile}; + return profile; } } return null; -- cgit v1.2.3 From 68179607b3ac8ed34f32a4a7699fb95c7826249b Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 27 Oct 2019 23:34:50 +0200 Subject: use apiOptionsGet to modify the correct profile --- ext/bg/js/api.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 6c109614..14fc0279 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -22,9 +22,7 @@ function apiOptionsGet(optionsContext) { } async function apiOptionsSet(changedOptions, optionsContext, source) { - const backend = utilBackend(); - const {depth} = optionsContext; - let options = await apiOptionsGetFull(); + let options = await apiOptionsGet(optionsContext); function getValuePaths(obj) { let valuePaths = []; @@ -63,11 +61,10 @@ async function apiOptionsSet(changedOptions, optionsContext, source) { } for (let [value, path] of getValuePaths(changedOptions)) { - modifyOption(path, value, options.profiles[depth].options); + modifyOption(path, value, options); } - await optionsSave(options); - backend.onOptionsUpdated(source); + await apiOptionsSave(source); } function apiOptionsGetFull() { -- cgit v1.2.3 From d62d04f806d2e6e5f2c3ac69a7d62f00cc31bd1b Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 27 Oct 2019 23:52:16 +0200 Subject: fix wanakana toggle on empty input --- ext/bg/js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 65cca002..dbfcb15d 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -69,7 +69,7 @@ class DisplaySearch extends Display { this.wanakanaEnable.checked = false; } this.wanakanaEnable.addEventListener('change', (e) => { - let query = DisplaySearch.getSearchQueryFromLocation(window.location.href); + const query = DisplaySearch.getSearchQueryFromLocation(window.location.href) || ''; if (e.target.checked) { window.wanakana.bind(this.query); this.query.value = window.wanakana.toKana(query); -- cgit v1.2.3 From a31ee0a0e9b4f1198cb9ac43d205267b8cf45bb2 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Mon, 28 Oct 2019 00:09:36 +0200 Subject: refactoring --- ext/bg/js/api.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 14fc0279..3209cc31 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -22,12 +22,12 @@ function apiOptionsGet(optionsContext) { } async function apiOptionsSet(changedOptions, optionsContext, source) { - let options = await apiOptionsGet(optionsContext); + const options = await apiOptionsGet(optionsContext); function getValuePaths(obj) { let valuePaths = []; let nodes = [{ - obj: changedOptions, + obj, path: [] }]; while (nodes.length > 0) { -- cgit v1.2.3 From f6d3f739a85367058a45581c7d7e4f9fffcca776 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Mon, 28 Oct 2019 01:13:05 +0200 Subject: improve search page checkbox usability Disable text selection and make the entire area clickable, including whitespace --- ext/bg/search.html | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ext/bg/search.html b/ext/bg/search.html index 8b339cc7..9853ee5e 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -19,14 +19,18 @@

Search your installed dictionaries by entering a Japanese expression into the field below.

-
+
- - + - - +
-- cgit v1.2.3 From 1039536cfb6279aadb9241c5905aa64790cd6fac Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 19:35:41 -0400 Subject: Create promise version of setTimeout --- ext/mixed/js/extension.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/ext/mixed/js/extension.js b/ext/mixed/js/extension.js index 861e52a5..54862e19 100644 --- a/ext/mixed/js/extension.js +++ b/ext/mixed/js/extension.js @@ -95,3 +95,41 @@ if (EXTENSION_IS_BROWSER_EDGE) { // Edge does not have chrome defined. chrome = browser; } + +function promiseTimeout(delay, resolveValue) { + if (delay <= 0) { + return Promise.resolve(resolveValue); + } + + let timer = null; + let promiseResolve = null; + let promiseReject = null; + + const complete = (callback, value) => { + if (callback === null) { return; } + if (timer !== null) { + window.clearTimeout(timer); + timer = null; + } + promiseResolve = null; + promiseReject = null; + callback(value); + }; + + const resolve = (value) => complete(promiseResolve, value); + const reject = (value) => complete(promiseReject, value); + + const promise = new Promise((resolve, reject) => { + promiseResolve = resolve; + promiseReject = reject; + }); + timer = window.setTimeout(() => { + timer = null; + resolve(resolveValue); + }, delay); + + promise.resolve = resolve; + promise.reject = reject; + + return promise; +} -- cgit v1.2.3 From d608657495d59469b17fbae9027772c26848a95e Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 19:38:06 -0400 Subject: Move onError catch into searchAt --- ext/fg/js/frontend.js | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index e854f74e..c8a7d254 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -99,11 +99,7 @@ class Frontend { } const search = async () => { - try { - await this.searchAt(e.clientX, e.clientY, 'mouse'); - } catch (e) { - this.onError(e); - } + await this.searchAt(e.clientX, e.clientY, 'mouse'); }; if (scanningModifier === 'none') { @@ -314,12 +310,16 @@ class Frontend { } async searchAt(x, y, cause) { - if (this.pendingLookup || await this.popup.containsPoint(x, y)) { - return; - } + try { + if (this.pendingLookup || await this.popup.containsPoint(x, y)) { + return; + } - const textSource = docRangeFromPoint(x, y, this.options); - return await this.searchSource(textSource, cause); + const textSource = docRangeFromPoint(x, y, this.options); + return await this.searchSource(textSource, cause); + } catch (e) { + this.onError(e); + } } async searchSource(textSource, cause) { @@ -503,15 +503,7 @@ class Frontend { return; } - const search = async () => { - try { - await this.searchAt(x, y, cause); - } catch (e) { - this.onError(e); - } - }; - - search(); + this.searchAt(x, y, cause); } selectionContainsPoint(selection, x, y) { -- cgit v1.2.3 From 185963899b4176b31a14ab141f1335c17a2de9c4 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 19:38:29 -0400 Subject: Use promiseTimeout --- ext/fg/js/frontend.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index c8a7d254..897c7b73 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -20,7 +20,7 @@ class Frontend { constructor(popup, ignoreNodes) { this.popup = popup; - this.popupTimer = null; + this.popupTimerPromise = null; this.textSourceLast = null; this.pendingLookup = false; this.options = null; @@ -74,7 +74,7 @@ class Frontend { } onMouseOver(e) { - if (e.target === this.popup.container && this.popupTimer !== null) { + if (e.target === this.popup.container) { this.popupTimerClear(); } } @@ -99,14 +99,17 @@ class Frontend { } const search = async () => { + if (scanningModifier === 'none') { + if (!await this.popupTimerWait()) { + // Aborted + return; + } + } + await this.searchAt(e.clientX, e.clientY, 'mouse'); }; - if (scanningModifier === 'none') { - this.popupTimerSet(search); - } else { - search(); - } + search(); } onMouseDown(e) { @@ -293,19 +296,19 @@ class Frontend { await this.popup.setOptions(this.options); } - popupTimerSet(callback) { + async popupTimerWait() { const delay = this.options.scanning.delay; - if (delay > 0) { - this.popupTimer = window.setTimeout(callback, delay); - } else { - Promise.resolve().then(callback); + this.popupTimerPromise = promiseTimeout(delay, true); + try { + return await this.popupTimerPromise; + } finally { + this.popupTimerPromise = null; } } popupTimerClear() { - if (this.popupTimer !== null) { - window.clearTimeout(this.popupTimer); - this.popupTimer = null; + if (this.popupTimerPromise !== null) { + this.popupTimerPromise.resolve(false); } } -- cgit v1.2.3 From dcb6f68826bd64d6cb41d2d7a0d5da1a58da9a1b Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 20:01:04 -0400 Subject: Don't pass null textSource into searchSource --- ext/bg/js/settings-popup-preview.js | 7 ++++++- ext/fg/js/frontend.js | 17 +++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ext/bg/js/settings-popup-preview.js b/ext/bg/js/settings-popup-preview.js index b12fb726..ce6da4c0 100644 --- a/ext/bg/js/settings-popup-preview.js +++ b/ext/bg/js/settings-popup-preview.js @@ -158,9 +158,14 @@ class SettingsPopupPreview { const range = document.createRange(); range.selectNode(textNode); const source = new TextSourceRange(range, range.toString(), null); + if (source === null) { return; } this.frontend.textSourceLast = null; - await this.frontend.searchSource(source, 'script'); + try { + await this.frontend.searchSource(source, 'script'); + } finally { + source.cleanup(); + } await this.frontend.lastShowPromise; if (this.frontend.popup.isVisible()) { diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 897c7b73..5e2ef529 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -319,19 +319,27 @@ class Frontend { } const textSource = docRangeFromPoint(x, y, this.options); - return await this.searchSource(textSource, cause); + if (textSource === null) { + return; + } + + try { + return await this.searchSource(textSource, cause); + } finally { + textSource.cleanup(); + } } catch (e) { this.onError(e); } } async searchSource(textSource, cause) { - let hideResults = textSource === null; + let hideResults = false; let searched = false; let success = false; try { - if (!hideResults && (!this.textSourceLast || !this.textSourceLast.equals(textSource))) { + if (!this.textSourceLast || !this.textSourceLast.equals(textSource)) { searched = true; this.pendingLookup = true; const focus = (cause === 'mouse'); @@ -351,9 +359,6 @@ class Frontend { this.onError(e); } } finally { - if (textSource !== null) { - textSource.cleanup(); - } if (hideResults && this.options.scanning.autoHideResults) { this.searchClear(true); } -- cgit v1.2.3 From 1f0a434e965aabad6b10bff4970a8c44a61961be Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 20:02:15 -0400 Subject: Remove unused vars --- ext/fg/js/frontend.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 5e2ef529..957f57c9 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -212,7 +212,7 @@ class Frontend { } } - onAfterSearch(newRange, cause, searched, success) { + onAfterSearch(newRange, cause) { if (cause === 'mouse') { return; } @@ -335,16 +335,12 @@ class Frontend { async searchSource(textSource, cause) { let hideResults = false; - let searched = false; - let success = false; try { if (!this.textSourceLast || !this.textSourceLast.equals(textSource)) { - searched = true; this.pendingLookup = true; const focus = (cause === 'mouse'); hideResults = !await this.searchTerms(textSource, focus) && !await this.searchKanji(textSource, focus); - success = true; } } catch (e) { if (window.yomichan_orphaned) { @@ -364,7 +360,7 @@ class Frontend { } this.pendingLookup = false; - this.onAfterSearch(this.textSourceLast, cause, searched, success); + this.onAfterSearch(this.textSourceLast, cause); } } -- cgit v1.2.3 From f927f806ba602867948654947dce4d27dfc07ebf Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 20:07:17 -0400 Subject: Move check --- ext/bg/js/settings-popup-preview.js | 1 - ext/fg/js/frontend.js | 13 +++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ext/bg/js/settings-popup-preview.js b/ext/bg/js/settings-popup-preview.js index ce6da4c0..b7b3acc5 100644 --- a/ext/bg/js/settings-popup-preview.js +++ b/ext/bg/js/settings-popup-preview.js @@ -160,7 +160,6 @@ class SettingsPopupPreview { const source = new TextSourceRange(range, range.toString(), null); if (source === null) { return; } - this.frontend.textSourceLast = null; try { await this.frontend.searchSource(source, 'script'); } finally { diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 957f57c9..1ab3c1a1 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -319,7 +319,10 @@ class Frontend { } const textSource = docRangeFromPoint(x, y, this.options); - if (textSource === null) { + if ( + textSource === null || + (this.textSourceLast !== null && this.textSourceLast.equals(textSource)) + ) { return; } @@ -337,11 +340,9 @@ class Frontend { let hideResults = false; try { - if (!this.textSourceLast || !this.textSourceLast.equals(textSource)) { - this.pendingLookup = true; - const focus = (cause === 'mouse'); - hideResults = !await this.searchTerms(textSource, focus) && !await this.searchKanji(textSource, focus); - } + this.pendingLookup = true; + const focus = (cause === 'mouse'); + hideResults = !await this.searchTerms(textSource, focus) && !await this.searchKanji(textSource, focus); } catch (e) { if (window.yomichan_orphaned) { if (textSource && this.options.scanning.modifier !== 'none') { -- cgit v1.2.3 From be27781c150bc081cc65c06b0a08d7b49044cbf3 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 20:21:21 -0400 Subject: Update how definitions are searched for --- ext/fg/js/frontend.js | 72 +++++++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 1ab3c1a1..52fdaacf 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -337,12 +337,18 @@ class Frontend { } async searchSource(textSource, cause) { - let hideResults = false; + let results = null; try { this.pendingLookup = true; - const focus = (cause === 'mouse'); - hideResults = !await this.searchTerms(textSource, focus) && !await this.searchKanji(textSource, focus); + results = ( + await this.findTerms(textSource) || + await this.findKanji(textSource) + ); + if (results !== null) { + const focus = (cause === 'mouse'); + this.showContent(textSource, focus, results.definitions, results.type); + } } catch (e) { if (window.yomichan_orphaned) { if (textSource && this.options.scanning.modifier !== 'none') { @@ -356,7 +362,7 @@ class Frontend { this.onError(e); } } finally { - if (hideResults && this.options.scanning.autoHideResults) { + if (results === null && this.options.scanning.autoHideResults) { this.searchClear(true); } @@ -365,27 +371,13 @@ class Frontend { } } - async searchTerms(textSource, focus) { - this.setTextSourceScanLength(textSource, this.options.scanning.length); - - const searchText = textSource.text(); - if (searchText.length === 0) { - return false; - } - - const {definitions, length} = await apiTermsFind(searchText, this.getOptionsContext()); - if (definitions.length === 0) { - return false; - } - - textSource.setEndOffset(length); - + showContent(textSource, focus, definitions, type) { const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt); const url = window.location.href; this.lastShowPromise = this.popup.showContent( textSource.getRect(), textSource.getWritingMode(), - 'terms', + type, {definitions, context: {sentence, url, focus}} ); @@ -393,38 +385,32 @@ class Frontend { if (this.options.scanning.selectText) { textSource.select(); } + } + + async findTerms(textSource) { + this.setTextSourceScanLength(textSource, this.options.scanning.length); + + const searchText = textSource.text(); + if (searchText.length === 0) { return null; } + + const {definitions, length} = await apiTermsFind(searchText, this.getOptionsContext()); + if (definitions.length === 0) { return null; } + + textSource.setEndOffset(length); - return true; + return {definitions, type: 'terms'}; } - async searchKanji(textSource, focus) { + async findKanji(textSource) { this.setTextSourceScanLength(textSource, 1); const searchText = textSource.text(); - if (searchText.length === 0) { - return false; - } + if (searchText.length === 0) { return null; } const definitions = await apiKanjiFind(searchText, this.getOptionsContext()); - if (definitions.length === 0) { - return false; - } - - const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt); - const url = window.location.href; - this.lastShowPromise = this.popup.showContent( - textSource.getRect(), - textSource.getWritingMode(), - 'kanji', - {definitions, context: {sentence, url, focus}} - ); - - this.textSourceLast = textSource; - if (this.options.scanning.selectText) { - textSource.select(); - } + if (definitions.length === 0) { return null; } - return true; + return {definitions, type: 'kanji'}; } searchClear(changeFocus) { -- cgit v1.2.3 From e91bcf5f553eb4199fff067044413064c46d1844 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 20:45:30 -0400 Subject: Rename textSourceLast to textSourceCurrent --- ext/fg/js/frontend.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 52fdaacf..5ab69b9a 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -21,7 +21,7 @@ class Frontend { constructor(popup, ignoreNodes) { this.popup = popup; this.popupTimerPromise = null; - this.textSourceLast = null; + this.textSourceCurrent = null; this.pendingLookup = false; this.options = null; this.ignoreNodes = (Array.isArray(ignoreNodes) && ignoreNodes.length > 0 ? ignoreNodes.join(',') : null); @@ -139,8 +139,8 @@ class Frontend { } async onResize() { - if (this.textSourceLast !== null && await this.popup.isVisibleAsync()) { - const textSource = this.textSourceLast; + if (this.textSourceCurrent !== null && await this.popup.isVisibleAsync()) { + const textSource = this.textSourceCurrent; this.lastShowPromise = this.popup.showContent( textSource.getRect(), textSource.getWritingMode() @@ -321,7 +321,7 @@ class Frontend { const textSource = docRangeFromPoint(x, y, this.options); if ( textSource === null || - (this.textSourceLast !== null && this.textSourceLast.equals(textSource)) + (this.textSourceCurrent !== null && this.textSourceCurrent.equals(textSource)) ) { return; } @@ -367,8 +367,10 @@ class Frontend { } this.pendingLookup = false; - this.onAfterSearch(this.textSourceLast, cause); + this.onAfterSearch(this.textSourceCurrent, cause); } + + return results !== null; } showContent(textSource, focus, definitions, type) { @@ -381,7 +383,7 @@ class Frontend { {definitions, context: {sentence, url, focus}} ); - this.textSourceLast = textSource; + this.textSourceCurrent = textSource; if (this.options.scanning.selectText) { textSource.select(); } @@ -417,11 +419,13 @@ class Frontend { this.popup.hide(changeFocus); this.popup.clearAutoPlayTimer(); - if (this.options.scanning.selectText && this.textSourceLast) { - this.textSourceLast.deselect(); - } + if (this.textSourceCurrent !== null) { + if (this.options.scanning.selectText) { + this.textSourceCurrent.deselect(); + } - this.textSourceLast = null; + this.textSourceCurrent = null; + } } getPrimaryTouch(touchList) { @@ -460,7 +464,7 @@ class Frontend { } else { this.primaryTouchIdentifier = touch.identifier; - this.contextMenuPreviousRange = this.textSourceLast ? this.textSourceLast.clone() : null; + this.contextMenuPreviousRange = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; this.contextMenuChecking = true; this.scrollPrevent = false; this.setContextMenuPrevent(false, false); -- cgit v1.2.3 From 8c5240d7a6cc325a628b32cf9e73ac6221517049 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:03:50 -0400 Subject: Simplify how touch events use onAfterSearch --- ext/fg/js/frontend.js | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 5ab69b9a..07c1f0dc 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -32,7 +32,6 @@ class Frontend { }; this.primaryTouchIdentifier = null; - this.contextMenuChecking = false; this.contextMenuPrevent = false; this.contextMenuPreviousRange = null; this.mouseDownPrevent = false; @@ -212,26 +211,6 @@ class Frontend { } } - onAfterSearch(newRange, cause) { - if (cause === 'mouse') { - return; - } - - if ( - !this.contextMenuChecking || - (this.contextMenuPreviousRange === null ? newRange === null : this.contextMenuPreviousRange.equals(newRange))) { - return; - } - - if (cause === 'touchStart' && newRange !== null) { - this.scrollPrevent = true; - } - - this.setContextMenuPrevent(true, false); - this.setMouseDownPrevent(true, false); - this.contextMenuChecking = false; - } - onRuntimeMessage({action, params}, sender, callback) { const handlers = Frontend.runtimeMessageHandlers; if (handlers.hasOwnProperty(action)) { @@ -367,7 +346,6 @@ class Frontend { } this.pendingLookup = false; - this.onAfterSearch(this.textSourceCurrent, cause); } return results !== null; @@ -456,7 +434,6 @@ class Frontend { if (touch === null) { this.primaryTouchIdentifier = null; this.contextMenuPreviousRange = null; - this.contextMenuChecking = false; this.scrollPrevent = false; this.setContextMenuPrevent(false, true); this.setMouseDownPrevent(false, true); @@ -465,13 +442,27 @@ class Frontend { else { this.primaryTouchIdentifier = touch.identifier; this.contextMenuPreviousRange = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; - this.contextMenuChecking = true; this.scrollPrevent = false; this.setContextMenuPrevent(false, false); this.setMouseDownPrevent(false, false); this.setClickPrevent(false); - this.searchFromTouch(touch.clientX, touch.clientY, 'touchStart'); + const textSourceCurrentPrevious = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; + + this.searchFromTouch(touch.clientX, touch.clientY, 'touchStart') + .then(() => { + if ( + this.pendingLookup || + this.textSourceCurrent === null || + this.textSourceCurrent.equals(textSourceCurrentPrevious) + ) { + return; + } + + this.scrollPrevent = true; + this.setContextMenuPrevent(true, false); + this.setMouseDownPrevent(true, false); + }); } } @@ -495,10 +486,10 @@ class Frontend { this.popupTimerClear(); if (this.pendingLookup) { - return; + return Promise.resolve(); } - this.searchAt(x, y, cause); + return this.searchAt(x, y, cause); } selectionContainsPoint(selection, x, y) { -- cgit v1.2.3 From f2dec4ca20c1eddeda86ceb5c13795d4bacf19d6 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:05:29 -0400 Subject: Remove searchFromTouch --- ext/fg/js/frontend.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 07c1f0dc..bc4e8cc3 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -197,7 +197,7 @@ class Frontend { } const touch = touches[index]; - this.searchFromTouch(touch.clientX, touch.clientY, 'touchMove'); + this.searchAt(touch.clientX, touch.clientY, 'touchMove'); e.preventDefault(); // Disable scroll } @@ -293,6 +293,8 @@ class Frontend { async searchAt(x, y, cause) { try { + this.popupTimerClear(); + if (this.pendingLookup || await this.popup.containsPoint(x, y)) { return; } @@ -449,7 +451,7 @@ class Frontend { const textSourceCurrentPrevious = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; - this.searchFromTouch(touch.clientX, touch.clientY, 'touchStart') + this.searchAt(touch.clientX, touch.clientY, 'touchStart') .then(() => { if ( this.pendingLookup || @@ -482,16 +484,6 @@ class Frontend { this.clickPrevent = value; } - searchFromTouch(x, y, cause) { - this.popupTimerClear(); - - if (this.pendingLookup) { - return Promise.resolve(); - } - - return this.searchAt(x, y, cause); - } - selectionContainsPoint(selection, x, y) { for (let i = 0; i < selection.rangeCount; ++i) { const range = selection.getRangeAt(i); -- cgit v1.2.3 From c74c466c36cc3183e4044e8a7583a0a95609f0e1 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:06:54 -0400 Subject: Remove unused variable --- ext/fg/js/frontend.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index bc4e8cc3..e7f0bbf7 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -33,7 +33,6 @@ class Frontend { this.primaryTouchIdentifier = null; this.contextMenuPrevent = false; - this.contextMenuPreviousRange = null; this.mouseDownPrevent = false; this.clickPrevent = false; this.scrollPrevent = false; @@ -435,7 +434,6 @@ class Frontend { setPrimaryTouch(touch) { if (touch === null) { this.primaryTouchIdentifier = null; - this.contextMenuPreviousRange = null; this.scrollPrevent = false; this.setContextMenuPrevent(false, true); this.setMouseDownPrevent(false, true); @@ -443,7 +441,6 @@ class Frontend { } else { this.primaryTouchIdentifier = touch.identifier; - this.contextMenuPreviousRange = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; this.scrollPrevent = false; this.setContextMenuPrevent(false, false); this.setMouseDownPrevent(false, false); -- cgit v1.2.3 From 9178636613461c1e333abbb9c67e7c82948fdfeb Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:15:02 -0400 Subject: Remove setters --- ext/fg/js/frontend.js | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index e7f0bbf7..6d4ba4f8 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -112,8 +112,8 @@ class Frontend { onMouseDown(e) { if (this.mouseDownPrevent) { - this.setMouseDownPrevent(false, false); - this.setClickPrevent(true); + this.mouseDownPrevent = false; + this.clickPrevent = true; e.preventDefault(); e.stopPropagation(); return false; @@ -148,7 +148,7 @@ class Frontend { onClick(e) { if (this.clickPrevent) { - this.setClickPrevent(false); + this.clickPrevent = false; e.preventDefault(); e.stopPropagation(); return false; @@ -203,7 +203,7 @@ class Frontend { onContextMenu(e) { if (this.contextMenuPrevent) { - this.setContextMenuPrevent(false, false); + this.contextMenuPrevent = false; e.preventDefault(); e.stopPropagation(); return false; @@ -435,16 +435,18 @@ class Frontend { if (touch === null) { this.primaryTouchIdentifier = null; this.scrollPrevent = false; - this.setContextMenuPrevent(false, true); - this.setMouseDownPrevent(false, true); - this.setClickPrevent(false); + this.clickPrevent = false; + // Don't revert context menu and mouse down prevention, + // since these events can occur after the touch has ended. + // this.contextMenuPrevent = false; + // this.mouseDownPrevent = false; } else { this.primaryTouchIdentifier = touch.identifier; this.scrollPrevent = false; - this.setContextMenuPrevent(false, false); - this.setMouseDownPrevent(false, false); - this.setClickPrevent(false); + this.contextMenuPrevent = false; + this.mouseDownPrevent = false; + this.clickPrevent = false; const textSourceCurrentPrevious = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; @@ -459,28 +461,12 @@ class Frontend { } this.scrollPrevent = true; - this.setContextMenuPrevent(true, false); - this.setMouseDownPrevent(true, false); + this.contextMenuPrevent = true; + this.mouseDownPrevent = true; }); } } - setContextMenuPrevent(value, delay) { - if (!delay) { - this.contextMenuPrevent = value; - } - } - - setMouseDownPrevent(value, delay) { - if (!delay) { - this.mouseDownPrevent = value; - } - } - - setClickPrevent(value) { - this.clickPrevent = value; - } - selectionContainsPoint(selection, x, y) { for (let i = 0; i < selection.rangeCount; ++i) { const range = selection.getRangeAt(i); -- cgit v1.2.3 From a648e0509120d401611d8f3f1a7f518d200930d2 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:16:23 -0400 Subject: Improve naming --- ext/fg/js/frontend.js | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 6d4ba4f8..0743628c 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -32,10 +32,10 @@ class Frontend { }; this.primaryTouchIdentifier = null; - this.contextMenuPrevent = false; - this.mouseDownPrevent = false; - this.clickPrevent = false; - this.scrollPrevent = false; + this.preventNextContextMenu = false; + this.preventNextMouseDown = false; + this.preventNextClick = false; + this.preventScroll = false; this.enabled = false; this.eventListeners = []; @@ -111,9 +111,9 @@ class Frontend { } onMouseDown(e) { - if (this.mouseDownPrevent) { - this.mouseDownPrevent = false; - this.clickPrevent = true; + if (this.preventNextMouseDown) { + this.preventNextMouseDown = false; + this.preventNextClick = true; e.preventDefault(); e.stopPropagation(); return false; @@ -147,8 +147,8 @@ class Frontend { } onClick(e) { - if (this.clickPrevent) { - this.clickPrevent = false; + if (this.preventNextClick) { + this.preventNextClick = false; e.preventDefault(); e.stopPropagation(); return false; @@ -185,7 +185,7 @@ class Frontend { } onTouchMove(e) { - if (!this.scrollPrevent || !e.cancelable || this.primaryTouchIdentifier === null) { + if (!this.preventScroll || !e.cancelable || this.primaryTouchIdentifier === null) { return; } @@ -202,8 +202,8 @@ class Frontend { } onContextMenu(e) { - if (this.contextMenuPrevent) { - this.contextMenuPrevent = false; + if (this.preventNextContextMenu) { + this.preventNextContextMenu = false; e.preventDefault(); e.stopPropagation(); return false; @@ -434,19 +434,19 @@ class Frontend { setPrimaryTouch(touch) { if (touch === null) { this.primaryTouchIdentifier = null; - this.scrollPrevent = false; - this.clickPrevent = false; + this.preventScroll = false; + this.preventNextClick = false; // Don't revert context menu and mouse down prevention, // since these events can occur after the touch has ended. - // this.contextMenuPrevent = false; - // this.mouseDownPrevent = false; + // this.preventNextContextMenu = false; + // this.preventNextMouseDown = false; } else { this.primaryTouchIdentifier = touch.identifier; - this.scrollPrevent = false; - this.contextMenuPrevent = false; - this.mouseDownPrevent = false; - this.clickPrevent = false; + this.preventScroll = false; + this.preventNextContextMenu = false; + this.preventNextMouseDown = false; + this.preventNextClick = false; const textSourceCurrentPrevious = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; @@ -460,9 +460,9 @@ class Frontend { return; } - this.scrollPrevent = true; - this.contextMenuPrevent = true; - this.mouseDownPrevent = true; + this.preventScroll = true; + this.preventNextContextMenu = true; + this.preventNextMouseDown = true; }); } } -- cgit v1.2.3 From 131dc8397dd453839843dbdc493dc721e51496fb Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:27:35 -0400 Subject: Make selectionContainsPoint static --- ext/fg/js/frontend.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 0743628c..8a08f105 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -161,7 +161,7 @@ class Frontend { } let touch = this.getPrimaryTouch(e.changedTouches); - if (this.selectionContainsPoint(window.getSelection(), touch.clientX, touch.clientY)) { + if (Frontend.selectionContainsPoint(window.getSelection(), touch.clientX, touch.clientY)) { touch = null; } @@ -467,7 +467,7 @@ class Frontend { } } - selectionContainsPoint(selection, x, y) { + static selectionContainsPoint(selection, x, y) { for (let i = 0; i < selection.rangeCount; ++i) { const range = selection.getRangeAt(i); for (const rect of range.getClientRects()) { -- cgit v1.2.3 From 80eb3575276e6499824b4ac71782f1a6c87c43ac Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:36:18 -0400 Subject: Simplify touch event implementation --- ext/fg/js/frontend.js | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 8a08f105..223088a1 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -156,28 +156,30 @@ class Frontend { } onTouchStart(e) { - if (this.primaryTouchIdentifier !== null && this.getIndexOfTouch(e.touches, this.primaryTouchIdentifier) >= 0) { + if ( + this.primaryTouchIdentifier !== null || + e.changedTouches.length === 0 + ) { return; } - let touch = this.getPrimaryTouch(e.changedTouches); - if (Frontend.selectionContainsPoint(window.getSelection(), touch.clientX, touch.clientY)) { - touch = null; + const primaryTouch = e.changedTouches[0]; + if (Frontend.selectionContainsPoint(window.getSelection(), primaryTouch.clientX, primaryTouch.clientY)) { + return; } - this.setPrimaryTouch(touch); + this.setPrimaryTouch(primaryTouch); } onTouchEnd(e) { - if (this.primaryTouchIdentifier === null) { - return; - } - - if (this.getIndexOfTouch(e.changedTouches, this.primaryTouchIdentifier) < 0) { + if ( + this.primaryTouchIdentifier === null || + this.getIndexOfTouch(e.changedTouches, this.primaryTouchIdentifier) < 0 + ) { return; } - this.setPrimaryTouch(this.getPrimaryTouch(this.excludeTouches(e.touches, e.changedTouches))); + this.setPrimaryTouch(null); } onTouchCancel(e) { @@ -195,8 +197,8 @@ class Frontend { return; } - const touch = touches[index]; - this.searchAt(touch.clientX, touch.clientY, 'touchMove'); + const primaryTouch = touches[index]; + this.searchAt(primaryTouch.clientX, primaryTouch.clientY, 'touchMove'); e.preventDefault(); // Disable scroll } @@ -407,10 +409,6 @@ class Frontend { } } - getPrimaryTouch(touchList) { - return touchList.length > 0 ? touchList[0] : null; - } - getIndexOfTouch(touchList, identifier) { for (let i in touchList) { let t = touchList[i]; @@ -421,16 +419,6 @@ class Frontend { return -1; } - excludeTouches(touchList, excludeTouchList) { - const result = []; - for (let r of touchList) { - if (this.getIndexOfTouch(excludeTouchList, r.identifier) < 0) { - result.push(r); - } - } - return result; - } - setPrimaryTouch(touch) { if (touch === null) { this.primaryTouchIdentifier = null; -- cgit v1.2.3 From 9703e123bf7467fc990e6d38e59bcc5fd46645b8 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:38:19 -0400 Subject: Remove setPrimaryTouch --- ext/fg/js/frontend.js | 67 ++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 223088a1..8d51c1df 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -168,7 +168,28 @@ class Frontend { return; } - this.setPrimaryTouch(primaryTouch); + this.primaryTouchIdentifier = primaryTouch.identifier; + this.preventScroll = false; + this.preventNextContextMenu = false; + this.preventNextMouseDown = false; + this.preventNextClick = false; + + const textSourceCurrentPrevious = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; + + this.searchAt(primaryTouch.clientX, primaryTouch.clientY, 'touchStart') + .then(() => { + if ( + this.pendingLookup || + this.textSourceCurrent === null || + this.textSourceCurrent.equals(textSourceCurrentPrevious) + ) { + return; + } + + this.preventScroll = true; + this.preventNextContextMenu = true; + this.preventNextMouseDown = true; + }); } onTouchEnd(e) { @@ -179,7 +200,13 @@ class Frontend { return; } - this.setPrimaryTouch(null); + this.primaryTouchIdentifier = null; + this.preventScroll = false; + this.preventNextClick = false; + // Don't revert context menu and mouse down prevention, + // since these events can occur after the touch has ended. + // this.preventNextContextMenu = false; + // this.preventNextMouseDown = false; } onTouchCancel(e) { @@ -419,42 +446,6 @@ class Frontend { return -1; } - setPrimaryTouch(touch) { - if (touch === null) { - this.primaryTouchIdentifier = null; - this.preventScroll = false; - this.preventNextClick = false; - // Don't revert context menu and mouse down prevention, - // since these events can occur after the touch has ended. - // this.preventNextContextMenu = false; - // this.preventNextMouseDown = false; - } - else { - this.primaryTouchIdentifier = touch.identifier; - this.preventScroll = false; - this.preventNextContextMenu = false; - this.preventNextMouseDown = false; - this.preventNextClick = false; - - const textSourceCurrentPrevious = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; - - this.searchAt(touch.clientX, touch.clientY, 'touchStart') - .then(() => { - if ( - this.pendingLookup || - this.textSourceCurrent === null || - this.textSourceCurrent.equals(textSourceCurrentPrevious) - ) { - return; - } - - this.preventScroll = true; - this.preventNextContextMenu = true; - this.preventNextMouseDown = true; - }); - } - } - static selectionContainsPoint(selection, x, y) { for (let i = 0; i < selection.rangeCount; ++i) { const range = selection.getRangeAt(i); -- cgit v1.2.3 From e542f381102785aa564f13162e58481d153aa1fc Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:39:23 -0400 Subject: Check pendingLookup earlier --- ext/fg/js/frontend.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 8d51c1df..cfeee64f 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -174,12 +174,13 @@ class Frontend { this.preventNextMouseDown = false; this.preventNextClick = false; + if (this.pendingLookup) { return; } + const textSourceCurrentPrevious = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; this.searchAt(primaryTouch.clientX, primaryTouch.clientY, 'touchStart') .then(() => { if ( - this.pendingLookup || this.textSourceCurrent === null || this.textSourceCurrent.equals(textSourceCurrentPrevious) ) { -- cgit v1.2.3 From c365101ec28be0aa2638325ecfda4abe1474eb0f Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:41:13 -0400 Subject: Reset preventions earlier --- ext/fg/js/frontend.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index cfeee64f..f788f431 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -163,16 +163,17 @@ class Frontend { return; } + this.preventScroll = false; + this.preventNextContextMenu = false; + this.preventNextMouseDown = false; + this.preventNextClick = false; + const primaryTouch = e.changedTouches[0]; if (Frontend.selectionContainsPoint(window.getSelection(), primaryTouch.clientX, primaryTouch.clientY)) { return; } this.primaryTouchIdentifier = primaryTouch.identifier; - this.preventScroll = false; - this.preventNextContextMenu = false; - this.preventNextMouseDown = false; - this.preventNextClick = false; if (this.pendingLookup) { return; } -- cgit v1.2.3 From d2644c0776c4058ec8b029650ecf911150e35993 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 24 Oct 2019 21:41:58 -0400 Subject: Style update --- ext/fg/js/frontend.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index f788f431..9fdd9671 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -156,10 +156,7 @@ class Frontend { } onTouchStart(e) { - if ( - this.primaryTouchIdentifier !== null || - e.changedTouches.length === 0 - ) { + if (this.primaryTouchIdentifier !== null || e.changedTouches.length === 0) { return; } @@ -175,7 +172,9 @@ class Frontend { this.primaryTouchIdentifier = primaryTouch.identifier; - if (this.pendingLookup) { return; } + if (this.pendingLookup) { + return; + } const textSourceCurrentPrevious = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; -- cgit v1.2.3 From 6d85dae68d9820265887405666163eb19219c477 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 25 Oct 2019 20:01:42 -0400 Subject: Fix some issues with the context menu --- ext/fg/js/frontend.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 9fdd9671..a963bd92 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -119,8 +119,10 @@ class Frontend { return false; } - this.popupTimerClear(); - this.searchClear(true); + if (e.button === 0) { + this.popupTimerClear(); + this.searchClear(true); + } } onMouseOut(e) { @@ -231,6 +233,10 @@ class Frontend { e.preventDefault(); // Disable scroll } + onAuxClick(e) { + this.preventNextContextMenu = false; + } + onContextMenu(e) { if (this.preventNextContextMenu) { this.preventNextContextMenu = false; @@ -278,6 +284,7 @@ class Frontend { if (this.options.scanning.touchInputEnabled) { this.addEventListener(window, 'click', this.onClick.bind(this)); + this.addEventListener(window, 'auxclick', this.onAuxClick.bind(this)); this.addEventListener(window, 'touchstart', this.onTouchStart.bind(this)); this.addEventListener(window, 'touchend', this.onTouchEnd.bind(this)); this.addEventListener(window, 'touchcancel', this.onTouchCancel.bind(this)); -- cgit v1.2.3 From bcffe80a1e8342da1bdcca3ee08f0d005a01a2c3 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 25 Oct 2019 20:11:44 -0400 Subject: Group similar functions together --- ext/fg/js/frontend.js | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index a963bd92..94c318d7 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -129,28 +129,22 @@ class Frontend { this.popupTimerClear(); } - onWindowMessage(e) { - const action = e.data; - const handlers = Frontend.windowMessageHandlers; - if (handlers.hasOwnProperty(action)) { - const handler = handlers[action]; - handler(this); + onClick(e) { + if (this.preventNextClick) { + this.preventNextClick = false; + e.preventDefault(); + e.stopPropagation(); + return false; } } - async onResize() { - if (this.textSourceCurrent !== null && await this.popup.isVisibleAsync()) { - const textSource = this.textSourceCurrent; - this.lastShowPromise = this.popup.showContent( - textSource.getRect(), - textSource.getWritingMode() - ); - } + onAuxClick(e) { + this.preventNextContextMenu = false; } - onClick(e) { - if (this.preventNextClick) { - this.preventNextClick = false; + onContextMenu(e) { + if (this.preventNextContextMenu) { + this.preventNextContextMenu = false; e.preventDefault(); e.stopPropagation(); return false; @@ -233,16 +227,22 @@ class Frontend { e.preventDefault(); // Disable scroll } - onAuxClick(e) { - this.preventNextContextMenu = false; + async onResize() { + if (this.textSourceCurrent !== null && await this.popup.isVisibleAsync()) { + const textSource = this.textSourceCurrent; + this.lastShowPromise = this.popup.showContent( + textSource.getRect(), + textSource.getWritingMode() + ); + } } - onContextMenu(e) { - if (this.preventNextContextMenu) { - this.preventNextContextMenu = false; - e.preventDefault(); - e.stopPropagation(); - return false; + onWindowMessage(e) { + const action = e.data; + const handlers = Frontend.windowMessageHandlers; + if (handlers.hasOwnProperty(action)) { + const handler = handlers[action]; + handler(this); } } -- cgit v1.2.3 From 60c0a002dfe7101d0619df16bd492b2452526957 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Mon, 28 Oct 2019 17:33:30 -0400 Subject: Force LF line endings for template files --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..2000050e --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +tmpl/*.html text eol=lf -- cgit v1.2.3 From 7de24dd355f0ab27e43509929d66c60e07e7eee4 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 2 Nov 2019 10:10:03 -0400 Subject: Add favicons --- ext/bg/background.html | 7 +++++++ ext/bg/context.html | 6 ++++++ ext/bg/guide.html | 6 ++++++ ext/bg/legal.html | 6 ++++++ ext/bg/search.html | 6 ++++++ ext/bg/settings-popup-preview.html | 6 ++++++ ext/bg/settings.html | 6 ++++++ ext/fg/float.html | 6 ++++++ 8 files changed, 49 insertions(+) diff --git a/ext/bg/background.html b/ext/bg/background.html index 30b3db48..3ab68639 100644 --- a/ext/bg/background.html +++ b/ext/bg/background.html @@ -3,6 +3,13 @@ + Background + + + + + +
diff --git a/ext/bg/context.html b/ext/bg/context.html index 48fa463f..7e08dddd 100644 --- a/ext/bg/context.html +++ b/ext/bg/context.html @@ -3,6 +3,12 @@ + + + + + + diff --git a/ext/bg/guide.html b/ext/bg/guide.html index 2a602f1f..ff9c71ee 100644 --- a/ext/bg/guide.html +++ b/ext/bg/guide.html @@ -4,6 +4,12 @@ Welcome to Yomichan! + + + + + + diff --git a/ext/bg/legal.html b/ext/bg/legal.html index 26ac033d..30927da6 100644 --- a/ext/bg/legal.html +++ b/ext/bg/legal.html @@ -4,6 +4,12 @@ Yomichan Legal + + + + + + diff --git a/ext/bg/search.html b/ext/bg/search.html index 9853ee5e..91140b95 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -4,6 +4,12 @@ Yomichan Search + + + + + + diff --git a/ext/bg/settings-popup-preview.html b/ext/bg/settings-popup-preview.html index 07caa271..d27a9a33 100644 --- a/ext/bg/settings-popup-preview.html +++ b/ext/bg/settings-popup-preview.html @@ -4,6 +4,12 @@ Yomichan Popup Preview + + + + + +