Improve performance of DisplaySearch's clipboard monitor
This commit is contained in:
parent
362e317a5d
commit
bf93d9f5f9
@ -16,13 +16,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
let IS_FIREFOX = null;
|
|
||||||
(async () => {
|
|
||||||
const {browser} = await apiGetEnvironmentInfo();
|
|
||||||
IS_FIREFOX = ['firefox', 'firefox-mobile'].includes(browser);
|
|
||||||
})();
|
|
||||||
|
|
||||||
class DisplaySearch extends Display {
|
class DisplaySearch extends Display {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(document.querySelector('#spinner'), document.querySelector('#content'));
|
super(document.querySelector('#spinner'), document.querySelector('#content'));
|
||||||
@ -43,8 +36,12 @@ class DisplaySearch extends Display {
|
|||||||
this.introVisible = true;
|
this.introVisible = true;
|
||||||
this.introAnimationTimer = null;
|
this.introAnimationTimer = null;
|
||||||
|
|
||||||
this.clipboardMonitorIntervalId = null;
|
this.isFirefox = false;
|
||||||
this.clipboardPrevText = null;
|
|
||||||
|
this.clipboardMonitorTimerId = null;
|
||||||
|
this.clipboardMonitorTimerToken = null;
|
||||||
|
this.clipboardInterval = 250;
|
||||||
|
this.clipboardPreviousText = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static create() {
|
static create() {
|
||||||
@ -56,6 +53,7 @@ class DisplaySearch extends Display {
|
|||||||
async prepare() {
|
async prepare() {
|
||||||
try {
|
try {
|
||||||
await this.initialize();
|
await this.initialize();
|
||||||
|
this.isFirefox = await DisplaySearch._isFirefox();
|
||||||
|
|
||||||
if (this.search !== null) {
|
if (this.search !== null) {
|
||||||
this.search.addEventListener('click', (e) => this.onSearch(e), false);
|
this.search.addEventListener('click', (e) => this.onSearch(e), false);
|
||||||
@ -241,39 +239,63 @@ class DisplaySearch extends Display {
|
|||||||
initClipboardMonitor() {
|
initClipboardMonitor() {
|
||||||
// ignore copy from search page
|
// ignore copy from search page
|
||||||
window.addEventListener('copy', () => {
|
window.addEventListener('copy', () => {
|
||||||
this.clipboardPrevText = document.getSelection().toString().trim();
|
this.clipboardPreviousText = document.getSelection().toString().trim();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
startClipboardMonitor() {
|
startClipboardMonitor() {
|
||||||
this.clipboardMonitorIntervalId = setInterval(async () => {
|
const token = {};
|
||||||
let curText = null;
|
const intervalCallback = async () => {
|
||||||
// TODO get rid of this and figure out why apiClipboardGet doesn't work on Firefox
|
this.clipboardMonitorTimerId = null;
|
||||||
if (IS_FIREFOX) {
|
|
||||||
curText = (await navigator.clipboard.readText()).trim();
|
let text = await this.getClipboardText();
|
||||||
} else if (IS_FIREFOX === false) {
|
if (this.clipboardMonitorTimerToken !== token) { return; }
|
||||||
curText = (await apiClipboardGet()).trim();
|
|
||||||
}
|
if (
|
||||||
if (curText && (curText !== this.clipboardPrevText) && jpIsJapaneseText(curText)) {
|
typeof text === 'string' &&
|
||||||
if (this.isWanakanaEnabled()) {
|
(text = text.trim()).length > 0 &&
|
||||||
this.setQuery(window.wanakana.toKana(curText));
|
text !== this.clipboardPreviousText
|
||||||
} else {
|
) {
|
||||||
this.setQuery(curText);
|
this.clipboardPreviousText = text;
|
||||||
|
if (jpIsJapaneseText(text)) {
|
||||||
|
this.setQuery(this.isWanakanaEnabled() ? window.wanakana.toKana(text) : text);
|
||||||
|
window.history.pushState(null, '', `${window.location.pathname}?query=${encodeURIComponent(text)}`);
|
||||||
|
this.onSearchQueryUpdated(this.query.value, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
|
this.clipboardMonitorTimerId = setTimeout(intervalCallback, this.clipboardInterval);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clipboardMonitorTimerToken = token;
|
||||||
|
|
||||||
|
intervalCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
stopClipboardMonitor() {
|
stopClipboardMonitor() {
|
||||||
if (this.clipboardMonitorIntervalId) {
|
this.clipboardMonitorTimerToken = null;
|
||||||
clearInterval(this.clipboardMonitorIntervalId);
|
if (this.clipboardMonitorTimerId !== null) {
|
||||||
this.clipboardMonitorIntervalId = null;
|
clearTimeout(this.clipboardMonitorTimerId);
|
||||||
|
this.clipboardMonitorTimerId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getClipboardText() {
|
||||||
|
/*
|
||||||
|
Notes:
|
||||||
|
apiClipboardGet doesn't work on firefox because document.execCommand('paste') requires
|
||||||
|
user interaction. Therefore, navigator.clipboard.readText() is used.
|
||||||
|
|
||||||
|
navigator.clipboard.readText() can't be used in Chrome for two reasons:
|
||||||
|
* Requires page to be focused, else it rejects with an exception.
|
||||||
|
* When the page is focused, Chrome will request clipboard permission, despite already
|
||||||
|
being an extension with clipboard permissions. It effectively asks for the
|
||||||
|
non-extension permission for clipboard access.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
return this.isFirefox ? await navigator.clipboard.readText() : await apiClipboardGet();
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,6 +389,17 @@ class DisplaySearch extends Display {
|
|||||||
const match = /^[^?#]*\?(?:[^&#]*&)?query=([^&#]*)/.exec(url);
|
const match = /^[^?#]*\?(?:[^&#]*&)?query=([^&#]*)/.exec(url);
|
||||||
return match !== null ? decodeURIComponent(match[1]) : null;
|
return match !== null ? decodeURIComponent(match[1]) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async _isFirefox() {
|
||||||
|
const {browser} = await apiGetEnvironmentInfo();
|
||||||
|
switch (browser) {
|
||||||
|
case 'firefox':
|
||||||
|
case 'firefox-mobile':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplaySearch.onKeyDownIgnoreKeys = {
|
DisplaySearch.onKeyDownIgnoreKeys = {
|
||||||
|
Loading…
Reference in New Issue
Block a user