From 02a34bb4bc81471934e54b5440a20585527d76f5 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Thu, 5 Dec 2019 03:58:35 +0200 Subject: initial text scanner extract --- ext/fg/js/frontend.js | 287 ++-------------------------------------------- ext/fg/js/popup-nested.js | 1 + 2 files changed, 13 insertions(+), 275 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 9a1d507b..43a4830f 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -20,23 +20,14 @@ class Frontend { constructor(popup, ignoreNodes) { this.popup = popup; - this.popupTimerPromise = null; - this.textSourceCurrent = null; - this.pendingLookup = false; + this.textScanner = new TextScanner(window, ignoreNodes, this.popup, this.searchSource.bind(this)); this.options = null; - this.ignoreNodes = (Array.isArray(ignoreNodes) && ignoreNodes.length > 0 ? ignoreNodes.join(',') : null); this.optionsContext = { depth: popup.depth, url: popup.url }; - this.primaryTouchIdentifier = null; - this.preventNextContextMenu = false; - this.preventNextMouseDown = false; - this.preventNextClick = false; - this.preventScroll = false; - this.enabled = false; this.eventListeners = []; @@ -71,162 +62,9 @@ class Frontend { return this.isPreparedPromise; } - onMouseOver(e) { - if (e.target === this.popup.container) { - this.popupTimerClear(); - } - } - - onMouseMove(e) { - this.popupTimerClear(); - - if (this.pendingLookup || DOM.isMouseButtonDown(e, 'primary')) { - return; - } - - const scanningOptions = this.options.scanning; - const scanningModifier = scanningOptions.modifier; - if (!( - Frontend.isScanningModifierPressed(scanningModifier, e) || - (scanningOptions.middleMouse && DOM.isMouseButtonDown(e, 'auxiliary')) - )) { - return; - } - - const search = async () => { - if (scanningModifier === 'none') { - if (!await this.popupTimerWait()) { - // Aborted - return; - } - } - - await this.searchAt(e.clientX, e.clientY, 'mouse'); - }; - - search(); - } - - onMouseDown(e) { - if (this.preventNextMouseDown) { - this.preventNextMouseDown = false; - this.preventNextClick = true; - e.preventDefault(); - e.stopPropagation(); - return false; - } - - if (e.button === 0) { - this.popupTimerClear(); - this.searchClear(true); - } - } - - onMouseOut() { - this.popupTimerClear(); - } - - onClick(e) { - if (this.preventNextClick) { - this.preventNextClick = false; - e.preventDefault(); - e.stopPropagation(); - return false; - } - } - - onAuxClick() { - this.preventNextContextMenu = false; - } - - onContextMenu(e) { - if (this.preventNextContextMenu) { - this.preventNextContextMenu = false; - e.preventDefault(); - e.stopPropagation(); - return false; - } - } - - onTouchStart(e) { - if (this.primaryTouchIdentifier !== null || e.changedTouches.length === 0) { - return; - } - - this.preventScroll = false; - this.preventNextContextMenu = false; - this.preventNextMouseDown = false; - this.preventNextClick = false; - - const primaryTouch = e.changedTouches[0]; - if (DOM.isPointInSelection(primaryTouch.clientX, primaryTouch.clientY, window.getSelection())) { - return; - } - - this.primaryTouchIdentifier = primaryTouch.identifier; - - if (this.pendingLookup) { - return; - } - - const textSourceCurrentPrevious = this.textSourceCurrent !== null ? this.textSourceCurrent.clone() : null; - - this.searchAt(primaryTouch.clientX, primaryTouch.clientY, 'touchStart') - .then(() => { - if ( - this.textSourceCurrent === null || - this.textSourceCurrent.equals(textSourceCurrentPrevious) - ) { - return; - } - - this.preventScroll = true; - this.preventNextContextMenu = true; - this.preventNextMouseDown = true; - }); - } - - onTouchEnd(e) { - if ( - this.primaryTouchIdentifier === null || - this.getIndexOfTouch(e.changedTouches, this.primaryTouchIdentifier) < 0 - ) { - return; - } - - 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) { - this.onTouchEnd(e); - } - - onTouchMove(e) { - if (!this.preventScroll || !e.cancelable || this.primaryTouchIdentifier === null) { - return; - } - - const touches = e.changedTouches; - const index = this.getIndexOfTouch(touches, this.primaryTouchIdentifier); - if (index < 0) { - return; - } - - const primaryTouch = touches[index]; - this.searchAt(primaryTouch.clientX, primaryTouch.clientY, 'touchMove'); - - e.preventDefault(); // Disable scroll - } - async onResize() { - if (this.textSourceCurrent !== null && await this.popup.isVisibleAsync()) { - const textSource = this.textSourceCurrent; + const textSource = this.textScanner.getCurrentTextSource(); + if (textSource !== null && await this.popup.isVisibleAsync()) { this.lastShowPromise = this.popup.showContent( textSource.getRect(), textSource.getWritingMode() @@ -257,6 +95,7 @@ class Frontend { } setEnabled(enabled) { + this.textScanner.setEnabled(enabled); if (enabled) { if (!this.enabled) { this.hookEvents(); @@ -273,21 +112,7 @@ class Frontend { hookEvents() { this.addEventListener(window, 'message', this.onWindowMessage.bind(this)); - this.addEventListener(window, 'mousedown', this.onMouseDown.bind(this)); - this.addEventListener(window, 'mousemove', this.onMouseMove.bind(this)); - this.addEventListener(window, 'mouseover', this.onMouseOver.bind(this)); - this.addEventListener(window, 'mouseout', this.onMouseOut.bind(this)); this.addEventListener(window, 'resize', this.onResize.bind(this)); - - 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)); - this.addEventListener(window, 'touchmove', this.onTouchMove.bind(this), {passive: false}); - this.addEventListener(window, 'contextmenu', this.onContextMenu.bind(this)); - } } addEventListener(node, type, listener, options) { @@ -304,60 +129,16 @@ class Frontend { async updateOptions() { this.options = await apiOptionsGet(this.getOptionsContext()); - this.setEnabled(this.options.general.enable); + this.textScanner.setOptions(this.options); await this.popup.setOptions(this.options); - } - - async popupTimerWait() { - const delay = this.options.scanning.delay; - const promise = promiseTimeout(delay, true); - this.popupTimerPromise = promise; - try { - return await promise; - } finally { - if (this.popupTimerPromise === promise) { - this.popupTimerPromise = null; - } - } - } - - popupTimerClear() { - if (this.popupTimerPromise !== null) { - this.popupTimerPromise.resolve(false); - this.popupTimerPromise = null; - } - } - - async searchAt(x, y, cause) { - try { - this.popupTimerClear(); - - if (this.pendingLookup || await this.popup.containsPoint(x, y)) { - return; - } - - const textSource = docRangeFromPoint(x, y, this.options); - if (this.textSourceCurrent !== null && this.textSourceCurrent.equals(textSource)) { - return; - } - - try { - await this.searchSource(textSource, cause); - } finally { - if (textSource !== null) { - textSource.cleanup(); - } - } - } catch (e) { - this.onError(e); - } + this.setEnabled(this.options.general.enable); } async searchSource(textSource, cause) { let results = null; try { - this.pendingLookup = true; + this.textScanner.pendingLookup = true; if (textSource !== null) { results = ( await this.findTerms(textSource) || @@ -385,7 +166,7 @@ class Frontend { this.searchClear(true); } - this.pendingLookup = false; + this.textScanner.pendingLookup = false; } return results; @@ -401,14 +182,14 @@ class Frontend { {definitions, context: {sentence, url, focus, disableHistory: true}} ); - this.textSourceCurrent = textSource; + this.textScanner.setCurrentTextSource(textSource); if (this.options.scanning.selectText) { textSource.select(); } } async findTerms(textSource) { - this.setTextSourceScanLength(textSource, this.options.scanning.length); + this.textScanner.setTextSourceScanLength(textSource, this.options.scanning.length); const searchText = textSource.text(); if (searchText.length === 0) { return null; } @@ -422,7 +203,7 @@ class Frontend { } async findKanji(textSource) { - this.setTextSourceScanLength(textSource, 1); + this.textScanner.setTextSourceScanLength(textSource, 1); const searchText = textSource.text(); if (searchText.length === 0) { return null; } @@ -436,57 +217,13 @@ class Frontend { searchClear(changeFocus) { this.popup.hide(changeFocus); this.popup.clearAutoPlayTimer(); - - if (this.textSourceCurrent !== null) { - if (this.options.scanning.selectText) { - this.textSourceCurrent.deselect(); - } - - this.textSourceCurrent = null; - } - } - - getIndexOfTouch(touchList, identifier) { - for (const i in touchList) { - const t = touchList[i]; - if (t.identifier === identifier) { - return i; - } - } - return -1; - } - - setTextSourceScanLength(textSource, length) { - textSource.setEndOffset(length); - if (this.ignoreNodes === null || !textSource.range) { - return; - } - - length = textSource.text().length; - while (textSource.range && length > 0) { - const nodes = TextSourceRange.getNodesInRange(textSource.range); - if (!TextSourceRange.anyNodeMatchesSelector(nodes, this.ignoreNodes)) { - break; - } - --length; - textSource.setEndOffset(length); - } + this.textScanner.searchClear(); } getOptionsContext() { this.optionsContext.url = this.popup.url; return this.optionsContext; } - - static isScanningModifierPressed(scanningModifier, mouseEvent) { - switch (scanningModifier) { - case 'alt': return mouseEvent.altKey; - case 'ctrl': return mouseEvent.ctrlKey; - case 'shift': return mouseEvent.shiftKey; - case 'none': return true; - default: return false; - } - } } Frontend.windowMessageHandlers = { diff --git a/ext/fg/js/popup-nested.js b/ext/fg/js/popup-nested.js index 31cb1cda..3df469fe 100644 --- a/ext/fg/js/popup-nested.js +++ b/ext/fg/js/popup-nested.js @@ -41,6 +41,7 @@ async function popupNestedInitialize(id, depth, parentFrameId, url) { window.frontendInitializationData = {id, depth, parentFrameId, ignoreNodes, url, proxy: true}; const scriptSrcs = [ + '/mixed/js/text-scanner.js', '/fg/js/frontend-api-sender.js', '/fg/js/popup.js', '/fg/js/popup-proxy.js', -- cgit v1.2.3 From e5be42d3de14be48c6ef4ef47d06ba130d16fcaf Mon Sep 17 00:00:00 2001 From: siikamiika Date: Thu, 5 Dec 2019 22:12:43 +0200 Subject: scan decoupling --- ext/fg/js/frontend.js | 13 ++++--- ext/mixed/js/text-scanner.js | 88 ++++++++++++++++++++++++++++++++------------ 2 files changed, 73 insertions(+), 28 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 43a4830f..2adbde36 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -20,7 +20,14 @@ class Frontend { constructor(popup, ignoreNodes) { this.popup = popup; - this.textScanner = new TextScanner(window, ignoreNodes, this.popup, this.searchSource.bind(this)); + this.textScanner = new TextScanner( + window, + ignoreNodes, + [this.popup.container], + [(x, y) => this.popup.containsPoint(x, y)] + ); + this.textScanner.subscribe('textSearch', ({textSource, cause}) => this.searchSource(textSource, cause)); + this.textScanner.subscribe('searchClear', () => this.searchClear(true)); this.options = null; this.optionsContext = { @@ -138,7 +145,6 @@ class Frontend { let results = null; try { - this.textScanner.pendingLookup = true; if (textSource !== null) { results = ( await this.findTerms(textSource) || @@ -165,8 +171,6 @@ class Frontend { if (results === null && this.options.scanning.autoHideResults) { this.searchClear(true); } - - this.textScanner.pendingLookup = false; } return results; @@ -182,7 +186,6 @@ class Frontend { {definitions, context: {sentence, url, focus, disableHistory: true}} ); - this.textScanner.setCurrentTextSource(textSource); if (this.options.scanning.selectText) { textSource.select(); } diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index cf6e5397..fc57d6c3 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -18,19 +18,23 @@ class TextScanner { - constructor(node, ignoreNodes, popup, onTextSearch) { + constructor(node, ignoreNodes, ignoreElements, ignorePoints) { this.node = node; this.ignoreNodes = (Array.isArray(ignoreNodes) && ignoreNodes.length > 0 ? ignoreNodes.join(',') : null); - this.popup = popup; - this.onTextSearch = onTextSearch; + this.ignoreElements = ignoreElements; + this.ignorePoints = ignorePoints; - this.popupTimerPromise = null; + this.scanTimerPromise = null; this.textSourceCurrent = null; this.pendingLookup = false; this.options = null; this.enabled = false; this.eventListeners = []; + this.subscribers = { + searchClear: [], + textSearch: [] + }; this.primaryTouchIdentifier = null; this.preventNextContextMenu = false; @@ -40,13 +44,13 @@ class TextScanner { } onMouseOver(e) { - if (this.popup && e.target === this.popup.container) { - this.popupTimerClear(); + if (this.ignoreElements.includes(e.target)) { + this.scanTimerClear(); } } onMouseMove(e) { - this.popupTimerClear(); + this.scanTimerClear(); if (this.pendingLookup || DOM.isMouseButtonDown(e, 'primary')) { return; @@ -63,7 +67,7 @@ class TextScanner { const search = async () => { if (scanningModifier === 'none') { - if (!await this.popupTimerWait()) { + if (!await this.scanTimerWait()) { // Aborted return; } @@ -84,14 +88,14 @@ class TextScanner { return false; } - if (DOM.isMouseButtonPressed(e, 'primary')) { - this.popupTimerClear(); - this.searchClear(); + if (DOM.isMouseButtonDown(e, 'primary')) { + this.scanTimerClear(); + this.onSearchClear(); } } onMouseOut() { - this.popupTimerClear(); + this.scanTimerClear(); } onClick(e) { @@ -192,23 +196,55 @@ class TextScanner { e.preventDefault(); // Disable scroll } - async popupTimerWait() { + async onSearchClear() { + this.searchClear(); + await this.publish('searchClear', {}); + } + + async onTextSearch(textSource, cause) { + this.pendingLookup = true; + const results = await this.publish('textSearch', {textSource, cause}); + if (results.some((r) => r)) { + this.textSourceCurrent = textSource; + } + this.pendingLookup = false; + } + + onError(error) { + logError(error, false); + } + + subscribe(eventName, subscriber) { + if (this.subscribers[eventName].includes(subscriber)) { return; } + this.subscribers[eventName].push(subscriber); + } + + async publish(eventName, data) { + const results = []; + for (const subscriber of this.subscribers[eventName]) { + const result = await subscriber(data); + results.push(result); + } + return results; + } + + async scanTimerWait() { const delay = this.options.scanning.delay; const promise = promiseTimeout(delay, true); - this.popupTimerPromise = promise; + this.scanTimerPromise = promise; try { return await promise; } finally { - if (this.popupTimerPromise === promise) { - this.popupTimerPromise = null; + if (this.scanTimerPromise === promise) { + this.scanTimerPromise = null; } } } - popupTimerClear() { - if (this.popupTimerPromise !== null) { - this.popupTimerPromise.resolve(false); - this.popupTimerPromise = null; + scanTimerClear() { + if (this.scanTimerPromise !== null) { + this.scanTimerPromise.resolve(false); + this.scanTimerPromise = null; } } @@ -223,7 +259,7 @@ class TextScanner { this.clearEventListeners(); this.enabled = false; } - this.searchClear(); + this.onSearchClear(); } } @@ -262,12 +298,18 @@ class TextScanner { async searchAt(x, y, cause) { try { - this.popupTimerClear(); + this.scanTimerClear(); - if (this.pendingLookup || (this.popup && await this.popup.containsPoint(x, y))) { + if (this.pendingLookup) { return; } + for (const ignorePointFn of this.ignorePoints) { + if (await ignorePointFn(x, y)) { + return; + } + } + const textSource = docRangeFromPoint(x, y, this.options); if (this.textSourceCurrent !== null && this.textSourceCurrent.equals(textSource)) { return; -- cgit v1.2.3 From 595636c40bdc344ee34fee55c951e62ba0a24505 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Thu, 5 Dec 2019 22:48:05 +0200 Subject: move text selection to TextScanner --- ext/fg/js/frontend.js | 4 ---- ext/mixed/js/text-scanner.js | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 2adbde36..9ec66fb1 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -185,10 +185,6 @@ class Frontend { type, {definitions, context: {sentence, url, focus, disableHistory: true}} ); - - if (this.options.scanning.selectText) { - textSource.select(); - } } async findTerms(textSource) { diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index fc57d6c3..0adcc0bd 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -206,6 +206,9 @@ class TextScanner { const results = await this.publish('textSearch', {textSource, cause}); if (results.some((r) => r)) { this.textSourceCurrent = textSource; + if (this.options.scanning.selectText) { + textSource.select(); + } } this.pendingLookup = false; } -- cgit v1.2.3 From f6d0503604e66ef89578332f6adb477606dc81f9 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Fri, 6 Dec 2019 21:39:29 +0200 Subject: simplify with inheritance --- ext/fg/js/frontend.js | 72 ++++++++----------------------- ext/mixed/js/text-scanner.js | 100 ++++++++++++++++++++----------------------- 2 files changed, 65 insertions(+), 107 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 9ec66fb1..01f5c13d 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -17,17 +17,16 @@ */ -class Frontend { +class Frontend extends TextScanner { constructor(popup, ignoreNodes) { - this.popup = popup; - this.textScanner = new TextScanner( + super( window, ignoreNodes, - [this.popup.container], + [popup.container], [(x, y) => this.popup.containsPoint(x, y)] ); - this.textScanner.subscribe('textSearch', ({textSource, cause}) => this.searchSource(textSource, cause)); - this.textScanner.subscribe('searchClear', () => this.searchClear(true)); + + this.popup = popup; this.options = null; this.optionsContext = { @@ -35,9 +34,6 @@ class Frontend { url: popup.url }; - this.enabled = false; - this.eventListeners = []; - this.isPreparedPromiseResolve = null; this.isPreparedPromise = new Promise((resolve) => { this.isPreparedPromiseResolve = resolve; }); @@ -70,7 +66,7 @@ class Frontend { } async onResize() { - const textSource = this.textScanner.getCurrentTextSource(); + const textSource = this.textSourceCurrent; if (textSource !== null && await this.popup.isVisibleAsync()) { this.lastShowPromise = this.popup.showContent( textSource.getRect(), @@ -97,51 +93,21 @@ class Frontend { } } - onError(error) { - logError(error, false); - } - - setEnabled(enabled) { - this.textScanner.setEnabled(enabled); - if (enabled) { - if (!this.enabled) { - this.hookEvents(); - this.enabled = true; - } - } else { - if (this.enabled) { - this.clearEventListeners(); - this.enabled = false; - } - this.searchClear(false); - } - } - - hookEvents() { - this.addEventListener(window, 'message', this.onWindowMessage.bind(this)); - this.addEventListener(window, 'resize', this.onResize.bind(this)); - } - - addEventListener(node, type, listener, options) { - node.addEventListener(type, listener, options); - this.eventListeners.push([node, type, listener, options]); - } - - clearEventListeners() { - for (const [node, type, listener, options] of this.eventListeners) { - node.removeEventListener(type, listener, options); - } - this.eventListeners = []; + getMouseEventListeners() { + return [ + ...super.getMouseEventListeners(), + [window, 'message', this.onWindowMessage.bind(this)], + [window, 'resize', this.onResize.bind(this)] + ]; } async updateOptions() { this.options = await apiOptionsGet(this.getOptionsContext()); - this.textScanner.setOptions(this.options); await this.popup.setOptions(this.options); this.setEnabled(this.options.general.enable); } - async searchSource(textSource, cause) { + async onSearchSource(textSource, cause) { let results = null; try { @@ -169,7 +135,7 @@ class Frontend { } } finally { if (results === null && this.options.scanning.autoHideResults) { - this.searchClear(true); + this.onSearchClear(true); } } @@ -188,7 +154,7 @@ class Frontend { } async findTerms(textSource) { - this.textScanner.setTextSourceScanLength(textSource, this.options.scanning.length); + this.setTextSourceScanLength(textSource, this.options.scanning.length); const searchText = textSource.text(); if (searchText.length === 0) { return null; } @@ -202,7 +168,7 @@ class Frontend { } async findKanji(textSource) { - this.textScanner.setTextSourceScanLength(textSource, 1); + this.setTextSourceScanLength(textSource, 1); const searchText = textSource.text(); if (searchText.length === 0) { return null; } @@ -213,10 +179,10 @@ class Frontend { return {definitions, type: 'kanji'}; } - searchClear(changeFocus) { + onSearchClear(changeFocus) { this.popup.hide(changeFocus); this.popup.clearAutoPlayTimer(); - this.textScanner.searchClear(); + super.onSearchClear(changeFocus); } getOptionsContext() { @@ -227,7 +193,7 @@ class Frontend { Frontend.windowMessageHandlers = { popupClose: (self) => { - self.searchClear(true); + self.onSearchClear(true); }, selectionCopy: () => { diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index 0adcc0bd..ac5d68d1 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -31,10 +31,6 @@ class TextScanner { this.enabled = false; this.eventListeners = []; - this.subscribers = { - searchClear: [], - textSearch: [] - }; this.primaryTouchIdentifier = null; this.preventNextContextMenu = false; @@ -90,7 +86,7 @@ class TextScanner { if (DOM.isMouseButtonDown(e, 'primary')) { this.scanTimerClear(); - this.onSearchClear(); + this.onSearchClear(true); } } @@ -196,41 +192,14 @@ class TextScanner { e.preventDefault(); // Disable scroll } - async onSearchClear() { - this.searchClear(); - await this.publish('searchClear', {}); - } - - async onTextSearch(textSource, cause) { - this.pendingLookup = true; - const results = await this.publish('textSearch', {textSource, cause}); - if (results.some((r) => r)) { - this.textSourceCurrent = textSource; - if (this.options.scanning.selectText) { - textSource.select(); - } - } - this.pendingLookup = false; + async onSearchSource(_textSource, _cause) { + throw new Error('Override me'); } onError(error) { logError(error, false); } - subscribe(eventName, subscriber) { - if (this.subscribers[eventName].includes(subscriber)) { return; } - this.subscribers[eventName].push(subscriber); - } - - async publish(eventName, data) { - const results = []; - for (const subscriber of this.subscribers[eventName]) { - const result = await subscriber(data); - results.push(result); - } - return results; - } - async scanTimerWait() { const delay = this.options.scanning.delay; const promise = promiseTimeout(delay, true); @@ -262,35 +231,50 @@ class TextScanner { this.clearEventListeners(); this.enabled = false; } - this.onSearchClear(); + this.onSearchClear(false); } } hookEvents() { - this.addEventListener('mousedown', this.onMouseDown.bind(this)); - this.addEventListener('mousemove', this.onMouseMove.bind(this)); - this.addEventListener('mouseover', this.onMouseOver.bind(this)); - this.addEventListener('mouseout', this.onMouseOut.bind(this)); - + let eventListeners = this.getMouseEventListeners(); if (this.options.scanning.touchInputEnabled) { - this.addEventListener('click', this.onClick.bind(this)); - this.addEventListener('auxclick', this.onAuxClick.bind(this)); - this.addEventListener('touchstart', this.onTouchStart.bind(this)); - this.addEventListener('touchend', this.onTouchEnd.bind(this)); - this.addEventListener('touchcancel', this.onTouchCancel.bind(this)); - this.addEventListener('touchmove', this.onTouchMove.bind(this), {passive: false}); - this.addEventListener('contextmenu', this.onContextMenu.bind(this)); + eventListeners = eventListeners.concat(this.getTouchEventListeners()); + } + + for (const [node, type, listener, options] of eventListeners) { + this.addEventListener(node, type, listener, options); } } - addEventListener(type, listener, options) { - this.node.addEventListener(type, listener, options); - this.eventListeners.push([type, listener, options]); + getMouseEventListeners() { + return [ + [this.node, 'mousedown', this.onMouseDown.bind(this)], + [this.node, 'mousemove', this.onMouseMove.bind(this)], + [this.node, 'mouseover', this.onMouseOver.bind(this)], + [this.node, 'mouseout', this.onMouseOut.bind(this)] + ]; + } + + getTouchEventListeners() { + return [ + [this.node, 'click', this.onClick.bind(this)], + [this.node, 'auxclick', this.onAuxClick.bind(this)], + [this.node, 'touchstart', this.onTouchStart.bind(this)], + [this.node, 'touchend', this.onTouchEnd.bind(this)], + [this.node, 'touchcancel', this.onTouchCancel.bind(this)], + [this.node, 'touchmove', this.onTouchMove.bind(this), {passive: false}], + [this.node, 'contextmenu', this.onContextMenu.bind(this)] + ]; + } + + addEventListener(node, type, listener, options) { + node.addEventListener(type, listener, options); + this.eventListeners.push([node, type, listener, options]); } clearEventListeners() { - for (const [type, listener, options] of this.eventListeners) { - this.node.removeEventListener(type, listener, options); + for (const [node, type, listener, options] of this.eventListeners) { + node.removeEventListener(type, listener, options); } this.eventListeners = []; } @@ -319,7 +303,15 @@ class TextScanner { } try { - await this.onTextSearch(textSource, cause); + this.pendingLookup = true; + const result = await this.onSearchSource(textSource, cause); + if (result !== null) { + this.textSourceCurrent = textSource; + if (this.options.scanning.selectText) { + textSource.select(); + } + } + this.pendingLookup = false; } finally { if (textSource !== null) { textSource.cleanup(); @@ -347,7 +339,7 @@ class TextScanner { } } - searchClear() { + onSearchClear(_) { if (this.textSourceCurrent !== null) { if (this.options.scanning.selectText) { this.textSourceCurrent.deselect(); -- cgit v1.2.3 From f287d686245371ee3ef8483d1027f06c30dc6a5e Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 11 Dec 2019 21:31:21 -0500 Subject: Add showContentCompleted for improved semantic clarity --- ext/bg/js/settings/popup-preview-frame.js | 2 +- ext/fg/js/frontend.js | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index dc85f493..9f642681 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -166,7 +166,7 @@ class SettingsPopupPreview { source.cleanup(); } this.textSource = source; - await this.frontend.lastShowPromise; + await this.frontend.showContentCompleted(); if (this.frontend.popup.isVisible()) { this.popupShown = true; diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 01f5c13d..54e78bf5 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -37,7 +37,7 @@ class Frontend extends TextScanner { this.isPreparedPromiseResolve = null; this.isPreparedPromise = new Promise((resolve) => { this.isPreparedPromiseResolve = resolve; }); - this.lastShowPromise = Promise.resolve(); + this._lastShowPromise = Promise.resolve(); } static create() { @@ -68,7 +68,7 @@ class Frontend extends TextScanner { async onResize() { const textSource = this.textSourceCurrent; if (textSource !== null && await this.popup.isVisibleAsync()) { - this.lastShowPromise = this.popup.showContent( + this._lastShowPromise = this.popup.showContent( textSource.getRect(), textSource.getWritingMode() ); @@ -124,7 +124,7 @@ class Frontend extends TextScanner { } catch (e) { if (window.yomichan_orphaned) { if (textSource !== null && this.options.scanning.modifier !== 'none') { - this.lastShowPromise = this.popup.showContent( + this._lastShowPromise = this.popup.showContent( textSource.getRect(), textSource.getWritingMode(), 'orphaned' @@ -145,7 +145,7 @@ class Frontend extends TextScanner { showContent(textSource, focus, definitions, type) { const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt); const url = window.location.href; - this.lastShowPromise = this.popup.showContent( + this._lastShowPromise = this.popup.showContent( textSource.getRect(), textSource.getWritingMode(), type, @@ -153,6 +153,10 @@ class Frontend extends TextScanner { ); } + showContentCompleted() { + return this._lastShowPromise; + } + async findTerms(textSource) { this.setTextSourceScanLength(textSource, this.options.scanning.length); -- cgit v1.2.3 From 863e36e829e4e01a8c1e7b15384820ad7766d6a8 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 8 Dec 2019 22:20:07 -0500 Subject: Update frontend message handlers --- ext/fg/js/frontend.js | 52 +++++++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 33 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 54e78bf5..6c1dafe5 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -77,20 +77,19 @@ class Frontend extends TextScanner { onWindowMessage(e) { const action = e.data; - const handlers = Frontend.windowMessageHandlers; - if (hasOwn(handlers, action)) { - const handler = handlers[action]; - handler(this); - } + const handler = Frontend._windowMessageHandlers.get(action); + if (typeof handler !== 'function') { return false; } + + handler(this); } onRuntimeMessage({action, params}, sender, callback) { - const handlers = Frontend.runtimeMessageHandlers; - if (hasOwn(handlers, action)) { - const handler = handlers[action]; - const result = handler(this, params); - callback(result); - } + const handler = Frontend._runtimeMessageHandlers.get(action); + if (typeof handler !== 'function') { return false; } + + const result = handler(this, params, sender); + callback(result); + return false; } getMouseEventListeners() { @@ -195,26 +194,13 @@ class Frontend extends TextScanner { } } -Frontend.windowMessageHandlers = { - popupClose: (self) => { - self.onSearchClear(true); - }, +Frontend._windowMessageHandlers = new Map([ + ['popupClose', (self) => self.onSearchClear(true)], + ['selectionCopy', () => document.execCommand('copy')] +]); - selectionCopy: () => { - document.execCommand('copy'); - } -}; - -Frontend.runtimeMessageHandlers = { - optionsUpdate: (self) => { - self.updateOptions(); - }, - - popupSetVisibleOverride: (self, {visible}) => { - self.popup.setVisibleOverride(visible); - }, - - getUrl: () => { - return {url: window.location.href}; - } -}; +Frontend._runtimeMessageHandlers = new Map([ + ['optionsUpdate', (self) => self.updateOptions()], + ['popupSetVisibleOverride', (self, {visible}) => self.popup.setVisibleOverride(visible)], + ['getUrl', () => ({url: window.location.href})] +]); -- cgit v1.2.3 From 5588643988e3154ecd6987bcf4794881e33a4ca2 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 11 Dec 2019 21:43:59 -0500 Subject: Update float message handlers --- ext/fg/js/float.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index ae54be00..f25dfd73 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -48,11 +48,10 @@ class DisplayFloat extends Display { onMessage(e) { const {action, params} = e.data; - const handlers = DisplayFloat.messageHandlers; - if (hasOwn(handlers, action)) { - const handler = handlers[action]; - handler(this, params); - } + const handler = DisplayFloat._messageHandlers.get(action); + if (typeof handler !== 'function') { return; } + + handler(this, params); } onKeyDown(e) { @@ -107,11 +106,11 @@ DisplayFloat.onKeyDownHandlers = { } }; -DisplayFloat.messageHandlers = { - setContent: (self, {type, details}) => self.setContent(type, details), - clearAutoPlayTimer: (self) => self.clearAutoPlayTimer(), - setCustomCss: (self, {css}) => self.setCustomCss(css), - initialize: (self, {options, popupInfo, url, childrenSupported}) => self.initialize(options, popupInfo, url, childrenSupported) -}; +DisplayFloat._messageHandlers = new Map([ + ['setContent', (self, {type, details}) => self.setContent(type, details)], + ['clearAutoPlayTimer', (self) => self.clearAutoPlayTimer()], + ['setCustomCss', (self, {css}) => self.setCustomCss(css)], + ['initialize', (self, {options, popupInfo, url, childrenSupported}) => self.initialize(options, popupInfo, url, childrenSupported)] +]); window.yomichan_display = new DisplayFloat(); -- cgit v1.2.3 From b7144ed879a59b89ee11aa13702e89a6fdaa0e35 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 11 Dec 2019 21:53:27 -0500 Subject: Update display float key handlers --- ext/fg/js/float.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index f25dfd73..74bc58b0 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -56,15 +56,14 @@ class DisplayFloat extends Display { onKeyDown(e) { const key = Display.getKeyFromEvent(e); - const handlers = DisplayFloat.onKeyDownHandlers; - if (hasOwn(handlers, key)) { - const handler = handlers[key]; + const handler = DisplayFloat._onKeyDownHandlers.get(key); + if (typeof handler === 'function') { if (handler(this, e)) { e.preventDefault(); - return; + return true; } } - super.onKeyDown(e); + return super.onKeyDown(e); } getOptionsContext() { @@ -96,15 +95,15 @@ class DisplayFloat extends Display { } } -DisplayFloat.onKeyDownHandlers = { - 'C': (self, e) => { +DisplayFloat._onKeyDownHandlers = new Map([ + ['C', (self, e) => { if (e.ctrlKey && !window.getSelection().toString()) { self.onSelectionCopy(); return true; } return false; - } -}; + }] +]); DisplayFloat._messageHandlers = new Map([ ['setContent', (self, {type, details}) => self.setContent(type, details)], -- cgit v1.2.3 From 573f83b65a8a0f87def6f4200ce503d957464f0d Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 11 Dec 2019 21:59:38 -0500 Subject: Update frontend API receiver handlers --- ext/fg/js/frontend-api-receiver.js | 17 +++++++---------- ext/fg/js/popup-proxy-host.js | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 21 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend-api-receiver.js b/ext/fg/js/frontend-api-receiver.js index 7d38ddd5..8d5e52ee 100644 --- a/ext/fg/js/frontend-api-receiver.js +++ b/ext/fg/js/frontend-api-receiver.js @@ -18,9 +18,9 @@ class FrontendApiReceiver { - constructor(source='', handlers={}) { - this.source = source; - this.handlers = handlers; + constructor(source='', handlers=new Map()) { + this._source = source; + this._handlers = handlers; chrome.runtime.onConnect.addListener(this.onConnect.bind(this)); } @@ -32,16 +32,13 @@ class FrontendApiReceiver { } onMessage(port, {id, action, params, target, senderId}) { - if ( - target !== this.source || - !hasOwn(this.handlers, action) - ) { - return; - } + if (target !== this._source) { return; } + + const handler = this._handlers.get(action); + if (typeof handler !== 'function') { return; } this.sendAck(port, id, senderId); - const handler = this.handlers[action]; handler(params).then( (result) => { this.sendResult(port, id, senderId, {result}); diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index b2f18b97..de182afe 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -36,17 +36,17 @@ class PopupProxyHost { const {frameId} = await this.frameIdPromise; if (typeof frameId !== 'number') { return; } - this.apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${frameId}`, { - createNestedPopup: ({parentId}) => this.createNestedPopup(parentId), - setOptions: ({id, options}) => this.setOptions(id, options), - hide: ({id, changeFocus}) => this.hide(id, changeFocus), - isVisibleAsync: ({id}) => this.isVisibleAsync(id), - setVisibleOverride: ({id, visible}) => this.setVisibleOverride(id, visible), - containsPoint: ({id, x, y}) => this.containsPoint(id, x, y), - showContent: ({id, elementRect, writingMode, type, details}) => this.showContent(id, elementRect, writingMode, type, details), - setCustomCss: ({id, css}) => this.setCustomCss(id, css), - clearAutoPlayTimer: ({id}) => this.clearAutoPlayTimer(id) - }); + this.apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${frameId}`, new Map([ + ['createNestedPopup', ({parentId}) => this.createNestedPopup(parentId)], + ['setOptions', ({id, options}) => this.setOptions(id, options)], + ['hide', ({id, changeFocus}) => this.hide(id, changeFocus)], + ['isVisibleAsync', ({id}) => this.isVisibleAsync(id)], + ['setVisibleOverride', ({id, visible}) => this.setVisibleOverride(id, visible)], + ['containsPoint', ({id, x, y}) => this.containsPoint(id, x, y)], + ['showContent', ({id, elementRect, writingMode, type, details}) => this.showContent(id, elementRect, writingMode, type, details)], + ['setCustomCss', ({id, css}) => this.setCustomCss(id, css)], + ['clearAutoPlayTimer', ({id}) => this.clearAutoPlayTimer(id)] + ])); } createPopup(parentId, depth) { -- cgit v1.2.3 From 4177b6372696d9b424857fedd1be988cc7eb0095 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 8 Dec 2019 22:29:23 -0500 Subject: Remove redundant getUrl handlers --- ext/bg/js/search.js | 17 ----------------- ext/bg/js/settings/main.js | 5 +---- ext/fg/js/frontend.js | 3 +-- ext/mixed/js/core.js | 18 ++++++++++++++++++ 4 files changed, 20 insertions(+), 23 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 67a78075..540b809b 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -238,17 +238,6 @@ class DisplaySearch extends Display { } } - onRuntimeMessage({action, params}, sender, callback) { - const handlers = DisplaySearch.runtimeMessageHandlers; - if (hasOwn(handlers, action)) { - const handler = handlers[action]; - const result = handler(this, params); - callback(result); - } else { - return super.onRuntimeMessage({action, params}, sender, callback); - } - } - initClipboardMonitor() { // ignore copy from search page window.addEventListener('copy', () => { @@ -380,12 +369,6 @@ class DisplaySearch extends Display { } } -DisplaySearch.runtimeMessageHandlers = { - getUrl: () => { - return {url: window.location.href}; - } -}; - DisplaySearch.onKeyDownIgnoreKeys = { 'ANY_MOD': [ 'Tab', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'PageDown', 'PageUp', 'Home', 'End', diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index 7456e7a4..0fd9cb23 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -199,14 +199,11 @@ async function onOptionsUpdate({source}) { await formWrite(options); } -function onMessage({action, params}, sender, callback) { +function onMessage({action, params}) { switch (action) { case 'optionsUpdate': onOptionsUpdate(params); break; - case 'getUrl': - callback({url: window.location.href}); - break; } } diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 6c1dafe5..43b64bb0 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -201,6 +201,5 @@ Frontend._windowMessageHandlers = new Map([ Frontend._runtimeMessageHandlers = new Map([ ['optionsUpdate', (self) => self.updateOptions()], - ['popupSetVisibleOverride', (self, {visible}) => self.popup.setVisibleOverride(visible)], - ['getUrl', () => ({url: window.location.href})] + ['popupSetVisibleOverride', (self, {visible}) => self.popup.setVisibleOverride(visible)] ]); diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index b9536391..36056c36 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -225,3 +225,21 @@ class EventDispatcher { return false; } } + + +/* + * Default message handlers + */ + +(() => { + function onMessage({action}, sender, callback) { + switch (action) { + case 'getUrl': + callback({url: window.location.href}); + break; + } + return false; + } + + chrome.runtime.onMessage.addListener(onMessage); +})(); -- cgit v1.2.3 From 7addf5a2ddd345bceb7aa0ee492ad51c25019e1a Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Mon, 9 Dec 2019 21:00:49 -0500 Subject: Add API calls for optionsGetFull and optionsSave --- ext/bg/js/backend.js | 10 ++++++++++ ext/fg/js/api.js | 8 ++++++++ 2 files changed, 18 insertions(+) (limited to 'ext/fg/js') diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 32b6d4e9..72802ea1 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -190,10 +190,18 @@ class Backend { return apiOptionsGet(optionsContext); } + _onApiOptionsGetFull() { + return apiOptionsGetFull(); + } + _onApiOptionsSet({changedOptions, optionsContext, source}) { return apiOptionsSet(changedOptions, optionsContext, source); } + _onApiOptionsSave({source}) { + return apiOptionsSave(source); + } + _onApiKanjiFind({text, optionsContext}) { return apiKanjiFind(text, optionsContext); } @@ -261,7 +269,9 @@ class Backend { Backend._messageHandlers = new Map([ ['optionsGet', (self, ...args) => self._onApiOptionsGet(...args)], + ['optionsGetFull', (self, ...args) => self._onApiOptionsGetFull(...args)], ['optionsSet', (self, ...args) => self._onApiOptionsSet(...args)], + ['optionsSave', (self, ...args) => self._onApiOptionsSave(...args)], ['kanjiFind', (self, ...args) => self._onApiKanjiFind(...args)], ['termsFind', (self, ...args) => self._onApiTermsFind(...args)], ['textParse', (self, ...args) => self._onApiTextParse(...args)], diff --git a/ext/fg/js/api.js b/ext/fg/js/api.js index 0e100b59..ae74b8dc 100644 --- a/ext/fg/js/api.js +++ b/ext/fg/js/api.js @@ -21,10 +21,18 @@ function apiOptionsGet(optionsContext) { return _apiInvoke('optionsGet', {optionsContext}); } +function apiOptionsGetFull() { + return _apiInvoke('optionsGetFull'); +} + function apiOptionsSet(changedOptions, optionsContext, source) { return _apiInvoke('optionsSet', {changedOptions, optionsContext, source}); } +function apiOptionsSave(source) { + return _apiInvoke('optionsSave', {source}); +} + function apiTermsFind(text, details, optionsContext) { return _apiInvoke('termsFind', {text, details, optionsContext}); } -- cgit v1.2.3 From ce51fe7eca2e893c8631c62ccb39ce3921ad1b6b Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Mon, 9 Dec 2019 22:45:28 -0500 Subject: Use a single api.js --- ext/bg/background.html | 2 +- ext/bg/context.html | 2 +- ext/bg/js/api.js | 98 ----------------------------- ext/bg/search.html | 2 +- ext/bg/settings-popup-preview.html | 2 +- ext/bg/settings.html | 2 +- ext/fg/float.html | 2 +- ext/fg/js/api.js | 126 ------------------------------------- ext/manifest.json | 2 +- ext/mixed/js/api.js | 126 +++++++++++++++++++++++++++++++++++++ 10 files changed, 133 insertions(+), 231 deletions(-) delete mode 100644 ext/bg/js/api.js delete mode 100644 ext/fg/js/api.js create mode 100644 ext/mixed/js/api.js (limited to 'ext/fg/js') diff --git a/ext/bg/background.html b/ext/bg/background.html index 5a6970c3..11838d14 100644 --- a/ext/bg/background.html +++ b/ext/bg/background.html @@ -20,10 +20,10 @@ + - diff --git a/ext/bg/context.html b/ext/bg/context.html index eda09a68..0e50ed7c 100644 --- a/ext/bg/context.html +++ b/ext/bg/context.html @@ -180,8 +180,8 @@ + - diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js deleted file mode 100644 index 095734fb..00000000 --- a/ext/bg/js/api.js +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2016-2017 Alex Yatskov - * Author: Alex Yatskov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -function apiOptionsGet(optionsContext) { - return utilBackend()._onApiOptionsGet({optionsContext}); -} - -function apiOptionsSet(changedOptions, optionsContext, source) { - return utilBackend()._onApiOptionsSet({changedOptions, optionsContext, source}); -} - -function apiOptionsGetFull() { - return utilBackend()._onApiOptionsGetFull(); -} - -function apiOptionsSave(source) { - return utilBackend()._onApiOptionsSave({source}); -} - -function apiTermsFind(text, details, optionsContext) { - return utilBackend()._onApiTermsFind({text, details, optionsContext}); -} - -function apiTextParse(text, optionsContext) { - return utilBackend()._onApiTextParse({text, optionsContext}); -} - -function apiTextParseMecab(text, optionsContext) { - return utilBackend()._onApiTextParseMecab({text, optionsContext}); -} - -function apiKanjiFind(text, optionsContext) { - return utilBackend()._onApiKanjiFind({text, optionsContext}); -} - -function apiDefinitionAdd(definition, mode, context, optionsContext) { - return utilBackend()._onApiDefinitionAdd({definition, mode, context, optionsContext}); -} - -function apiDefinitionsAddable(definitions, modes, optionsContext) { - return utilBackend()._onApiDefinitionsAddable({definitions, modes, optionsContext}); -} - -function apiNoteView(noteId) { - return utilBackend()._onApiNoteView({noteId}); -} - -function apiTemplateRender(template, data, dynamic) { - return utilBackend()._onApiTemplateRender({template, data, dynamic}); -} - -function apiCommandExec(command, params) { - return utilBackend()._onApiCommandExec({command, params}); -} - -function apiAudioGetUrl(definition, source, optionsContext) { - return utilBackend()._onApiAudioGetUrl({definition, source, optionsContext}); -} - -function apiScreenshotGet(options, sender) { - return utilBackend()._onApiScreenshotGet({options}, sender); -} - -function apiForward(action, params, sender) { - return utilBackend()._onApiForward({action, params}, sender); -} - -function apiFrameInformationGet(sender) { - return utilBackend()._onApiFrameInformationGet(null, sender); -} - -function apiInjectStylesheet(css, sender) { - return utilBackend()._onApiInjectStylesheet({css}, sender); -} - -function apiGetEnvironmentInfo() { - return utilBackend()._onApiGetEnvironmentInfo(); -} - -function apiClipboardGet() { - return utilBackend()._onApiClipboardGet(); -} diff --git a/ext/bg/search.html b/ext/bg/search.html index 7b4616da..409243dd 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -62,11 +62,11 @@ + - diff --git a/ext/bg/settings-popup-preview.html b/ext/bg/settings-popup-preview.html index 9b92b4e2..f33ecedf 100644 --- a/ext/bg/settings-popup-preview.html +++ b/ext/bg/settings-popup-preview.html @@ -119,9 +119,9 @@ + - diff --git a/ext/bg/settings.html b/ext/bg/settings.html index ea34b208..a3d8cb0c 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -881,10 +881,10 @@ + - diff --git a/ext/fg/float.html b/ext/fg/float.html index 67ee50b4..886e5e8b 100644 --- a/ext/fg/float.html +++ b/ext/fg/float.html @@ -33,8 +33,8 @@ + - diff --git a/ext/fg/js/api.js b/ext/fg/js/api.js deleted file mode 100644 index ae74b8dc..00000000 --- a/ext/fg/js/api.js +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2016-2017 Alex Yatskov - * Author: Alex Yatskov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -function apiOptionsGet(optionsContext) { - return _apiInvoke('optionsGet', {optionsContext}); -} - -function apiOptionsGetFull() { - return _apiInvoke('optionsGetFull'); -} - -function apiOptionsSet(changedOptions, optionsContext, source) { - return _apiInvoke('optionsSet', {changedOptions, optionsContext, source}); -} - -function apiOptionsSave(source) { - return _apiInvoke('optionsSave', {source}); -} - -function apiTermsFind(text, details, optionsContext) { - return _apiInvoke('termsFind', {text, details, optionsContext}); -} - -function apiTextParse(text, optionsContext) { - return _apiInvoke('textParse', {text, optionsContext}); -} - -function apiTextParseMecab(text, optionsContext) { - return _apiInvoke('textParseMecab', {text, optionsContext}); -} - -function apiKanjiFind(text, optionsContext) { - return _apiInvoke('kanjiFind', {text, optionsContext}); -} - -function apiDefinitionAdd(definition, mode, context, optionsContext) { - return _apiInvoke('definitionAdd', {definition, mode, context, optionsContext}); -} - -function apiDefinitionsAddable(definitions, modes, optionsContext) { - return _apiInvoke('definitionsAddable', {definitions, modes, optionsContext}).catch(() => null); -} - -function apiNoteView(noteId) { - return _apiInvoke('noteView', {noteId}); -} - -function apiTemplateRender(template, data, dynamic) { - return _apiInvoke('templateRender', {data, template, dynamic}); -} - -function apiAudioGetUrl(definition, source, optionsContext) { - return _apiInvoke('audioGetUrl', {definition, source, optionsContext}); -} - -function apiCommandExec(command, params) { - return _apiInvoke('commandExec', {command, params}); -} - -function apiScreenshotGet(options) { - return _apiInvoke('screenshotGet', {options}); -} - -function apiForward(action, params) { - return _apiInvoke('forward', {action, params}); -} - -function apiFrameInformationGet() { - return _apiInvoke('frameInformationGet'); -} - -function apiInjectStylesheet(css) { - return _apiInvoke('injectStylesheet', {css}); -} - -function apiGetEnvironmentInfo() { - return _apiInvoke('getEnvironmentInfo'); -} - -function apiClipboardGet() { - return _apiInvoke('clipboardGet'); -} - -function _apiInvoke(action, params={}) { - const data = {action, params}; - return new Promise((resolve, reject) => { - try { - chrome.runtime.sendMessage(data, (response) => { - _apiCheckLastError(chrome.runtime.lastError); - if (response !== null && typeof response === 'object') { - if (typeof response.error !== 'undefined') { - reject(jsonToError(response.error)); - } else { - resolve(response.result); - } - } else { - const message = response === null ? 'Unexpected null response' : `Unexpected response of type ${typeof response}`; - reject(new Error(`${message} (${JSON.stringify(data)})`)); - } - }); - } catch (e) { - window.yomichan_orphaned = true; - reject(e); - } - }); -} - -function _apiCheckLastError() { - // NOP -} diff --git a/ext/manifest.json b/ext/manifest.json index 225ca441..1e819328 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -20,8 +20,8 @@ "js": [ "mixed/js/core.js", "mixed/js/dom.js", + "mixed/js/api.js", "mixed/js/text-scanner.js", - "fg/js/api.js", "fg/js/document.js", "fg/js/frontend-api-receiver.js", "fg/js/popup.js", diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js new file mode 100644 index 00000000..ae74b8dc --- /dev/null +++ b/ext/mixed/js/api.js @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2016-2017 Alex Yatskov + * Author: Alex Yatskov + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +function apiOptionsGet(optionsContext) { + return _apiInvoke('optionsGet', {optionsContext}); +} + +function apiOptionsGetFull() { + return _apiInvoke('optionsGetFull'); +} + +function apiOptionsSet(changedOptions, optionsContext, source) { + return _apiInvoke('optionsSet', {changedOptions, optionsContext, source}); +} + +function apiOptionsSave(source) { + return _apiInvoke('optionsSave', {source}); +} + +function apiTermsFind(text, details, optionsContext) { + return _apiInvoke('termsFind', {text, details, optionsContext}); +} + +function apiTextParse(text, optionsContext) { + return _apiInvoke('textParse', {text, optionsContext}); +} + +function apiTextParseMecab(text, optionsContext) { + return _apiInvoke('textParseMecab', {text, optionsContext}); +} + +function apiKanjiFind(text, optionsContext) { + return _apiInvoke('kanjiFind', {text, optionsContext}); +} + +function apiDefinitionAdd(definition, mode, context, optionsContext) { + return _apiInvoke('definitionAdd', {definition, mode, context, optionsContext}); +} + +function apiDefinitionsAddable(definitions, modes, optionsContext) { + return _apiInvoke('definitionsAddable', {definitions, modes, optionsContext}).catch(() => null); +} + +function apiNoteView(noteId) { + return _apiInvoke('noteView', {noteId}); +} + +function apiTemplateRender(template, data, dynamic) { + return _apiInvoke('templateRender', {data, template, dynamic}); +} + +function apiAudioGetUrl(definition, source, optionsContext) { + return _apiInvoke('audioGetUrl', {definition, source, optionsContext}); +} + +function apiCommandExec(command, params) { + return _apiInvoke('commandExec', {command, params}); +} + +function apiScreenshotGet(options) { + return _apiInvoke('screenshotGet', {options}); +} + +function apiForward(action, params) { + return _apiInvoke('forward', {action, params}); +} + +function apiFrameInformationGet() { + return _apiInvoke('frameInformationGet'); +} + +function apiInjectStylesheet(css) { + return _apiInvoke('injectStylesheet', {css}); +} + +function apiGetEnvironmentInfo() { + return _apiInvoke('getEnvironmentInfo'); +} + +function apiClipboardGet() { + return _apiInvoke('clipboardGet'); +} + +function _apiInvoke(action, params={}) { + const data = {action, params}; + return new Promise((resolve, reject) => { + try { + chrome.runtime.sendMessage(data, (response) => { + _apiCheckLastError(chrome.runtime.lastError); + if (response !== null && typeof response === 'object') { + if (typeof response.error !== 'undefined') { + reject(jsonToError(response.error)); + } else { + resolve(response.result); + } + } else { + const message = response === null ? 'Unexpected null response' : `Unexpected response of type ${typeof response}`; + reject(new Error(`${message} (${JSON.stringify(data)})`)); + } + }); + } catch (e) { + window.yomichan_orphaned = true; + reject(e); + } + }); +} + +function _apiCheckLastError() { + // NOP +} -- cgit v1.2.3 From bf02eb2ea1ebe5342451f5946fe8328755490a7a Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 16:21:57 -0500 Subject: Mark PopupProxy internal functions as private --- ext/fg/js/popup-proxy.js | 60 +++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 29 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index e62a4868..aec3dbce 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -33,74 +33,76 @@ class PopupProxy { this.apiSender = new FrontendApiSender(); } - getPopupId() { - if (this.idPromise === null) { - this.idPromise = this.getPopupIdAsync(); - } - return this.idPromise; - } - - async getPopupIdAsync() { - const id = await this.invokeHostApi('createNestedPopup', {parentId: this.parentId}); - this.id = id; - return id; - } - async setOptions(options) { - const id = await this.getPopupId(); - return await this.invokeHostApi('setOptions', {id, options}); + const id = await this._getPopupId(); + return await this._invokeHostApi('setOptions', {id, options}); } async hide(changeFocus) { if (this.id === null) { return; } - return await this.invokeHostApi('hide', {id: this.id, changeFocus}); + return await this._invokeHostApi('hide', {id: this.id, changeFocus}); } async isVisibleAsync() { - const id = await this.getPopupId(); - return await this.invokeHostApi('isVisibleAsync', {id}); + const id = await this._getPopupId(); + return await this._invokeHostApi('isVisibleAsync', {id}); } async setVisibleOverride(visible) { - const id = await this.getPopupId(); - return await this.invokeHostApi('setVisibleOverride', {id, visible}); + const id = await this._getPopupId(); + return await this._invokeHostApi('setVisibleOverride', {id, visible}); } async containsPoint(x, y) { if (this.id === null) { return false; } - return await this.invokeHostApi('containsPoint', {id: this.id, x, y}); + return await this._invokeHostApi('containsPoint', {id: this.id, x, y}); } async showContent(elementRect, writingMode, type=null, details=null) { - const id = await this.getPopupId(); - elementRect = PopupProxy.DOMRectToJson(elementRect); - return await this.invokeHostApi('showContent', {id, elementRect, writingMode, type, details}); + const id = await this._getPopupId(); + elementRect = PopupProxy._convertDOMRectToJson(elementRect); + return await this._invokeHostApi('showContent', {id, elementRect, writingMode, type, details}); } async setCustomCss(css) { - const id = await this.getPopupId(); - return await this.invokeHostApi('setCustomCss', {id, css}); + const id = await this._getPopupId(); + return await this._invokeHostApi('setCustomCss', {id, css}); } async clearAutoPlayTimer() { if (this.id === null) { return; } - return await this.invokeHostApi('clearAutoPlayTimer', {id: this.id}); + return await this._invokeHostApi('clearAutoPlayTimer', {id: this.id}); + } + + // Private + + _getPopupId() { + if (this.idPromise === null) { + this.idPromise = this._getPopupIdAsync(); + } + return this.idPromise; + } + + async _getPopupIdAsync() { + const id = await this._invokeHostApi('createNestedPopup', {parentId: this.parentId}); + this.id = id; + return id; } - invokeHostApi(action, params={}) { + _invokeHostApi(action, params={}) { if (typeof this.parentFrameId !== 'number') { return Promise.reject(new Error('Invalid frame')); } return this.apiSender.invoke(action, params, `popup-proxy-host#${this.parentFrameId}`); } - static DOMRectToJson(domRect) { + static _convertDOMRectToJson(domRect) { return { x: domRect.x, y: domRect.y, -- cgit v1.2.3 From 8efbf9bd0dfc112689e0ccd8238a8cd0af5baec3 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 16:34:44 -0500 Subject: Flag members as private --- ext/fg/js/popup-proxy.js | 61 ++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 23 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index aec3dbce..d90d98be 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -19,30 +19,45 @@ class PopupProxy { constructor(depth, parentId, parentFrameId, url) { - this.parentId = parentId; - this.parentFrameId = parentFrameId; - this.id = null; - this.idPromise = null; - this.parent = null; - this.child = null; - this.depth = depth; - this.url = url; + this._parentId = parentId; + this._parentFrameId = parentFrameId; + this._id = null; + this._idPromise = null; + this._depth = depth; + this._url = url; + this._apiSender = new FrontendApiSender(); + } + + // Public properties + + get parent() { + return null; + } - this.container = null; + get child() { + return null; + } + + get depth() { + return this._depth; + } - this.apiSender = new FrontendApiSender(); + get url() { + return this._url; } + // Public functions + async setOptions(options) { const id = await this._getPopupId(); return await this._invokeHostApi('setOptions', {id, options}); } async hide(changeFocus) { - if (this.id === null) { + if (this._id === null) { return; } - return await this._invokeHostApi('hide', {id: this.id, changeFocus}); + return await this._invokeHostApi('hide', {id: this._id, changeFocus}); } async isVisibleAsync() { @@ -56,10 +71,10 @@ class PopupProxy { } async containsPoint(x, y) { - if (this.id === null) { + if (this._id === null) { return false; } - return await this._invokeHostApi('containsPoint', {id: this.id, x, y}); + return await this._invokeHostApi('containsPoint', {id: this._id, x, y}); } async showContent(elementRect, writingMode, type=null, details=null) { @@ -74,32 +89,32 @@ class PopupProxy { } async clearAutoPlayTimer() { - if (this.id === null) { + if (this._id === null) { return; } - return await this._invokeHostApi('clearAutoPlayTimer', {id: this.id}); + return await this._invokeHostApi('clearAutoPlayTimer', {id: this._id}); } // Private _getPopupId() { - if (this.idPromise === null) { - this.idPromise = this._getPopupIdAsync(); + if (this._idPromise === null) { + this._idPromise = this._getPopupIdAsync(); } - return this.idPromise; + return this._idPromise; } async _getPopupIdAsync() { - const id = await this._invokeHostApi('createNestedPopup', {parentId: this.parentId}); - this.id = id; + const id = await this._invokeHostApi('createNestedPopup', {parentId: this._parentId}); + this._id = id; return id; } _invokeHostApi(action, params={}) { - if (typeof this.parentFrameId !== 'number') { + if (typeof this._parentFrameId !== 'number') { return Promise.reject(new Error('Invalid frame')); } - return this.apiSender.invoke(action, params, `popup-proxy-host#${this.parentFrameId}`); + return this._apiSender.invoke(action, params, `popup-proxy-host#${this._parentFrameId}`); } static _convertDOMRectToJson(domRect) { -- cgit v1.2.3 From 88ac8f4ead5f1d23923dd6f526f585c3c38d05a0 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 16:58:44 -0500 Subject: Update PopupProxyHost.popups to use a Map --- ext/fg/js/popup-proxy-host.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index de182afe..f2e2f5d0 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -19,7 +19,7 @@ class PopupProxyHost { constructor() { - this.popups = {}; + this.popups = new Map(); this.nextId = 0; this.apiReceiver = null; this.frameIdPromise = null; @@ -50,7 +50,7 @@ class PopupProxyHost { } createPopup(parentId, depth) { - const parent = (typeof parentId === 'string' && hasOwn(this.popups, parentId) ? this.popups[parentId] : null); + const parent = (typeof parentId === 'string' && this.popups.has(parentId) ? this.popups.get(parentId) : null); const id = `${this.nextId}`; if (parent !== null) { depth = parent.depth + 1; @@ -61,7 +61,7 @@ class PopupProxyHost { popup.parent = parent; parent.child = popup; } - this.popups[id] = popup; + this.popups.set(id, popup); return popup; } @@ -70,11 +70,11 @@ class PopupProxyHost { } getPopup(id) { - if (!hasOwn(this.popups, id)) { + const popup = this.popups.get(id); + if (typeof popup === 'undefined') { throw new Error('Invalid popup ID'); } - - return this.popups[id]; + return popup; } jsonRectToDOMRect(popup, jsonRect) { -- cgit v1.2.3 From 3f8cc83c25ebbb81a6e4cfb44b077fbc2423da7a Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 17:01:29 -0500 Subject: Group nested message handlers together --- ext/fg/js/popup-proxy-host.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index f2e2f5d0..83518f44 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -65,10 +65,6 @@ class PopupProxyHost { return popup; } - async createNestedPopup(parentId) { - return this.createPopup(parentId, 0).id; - } - getPopup(id) { const popup = this.popups.get(id); if (typeof popup === 'undefined') { @@ -88,6 +84,12 @@ class PopupProxyHost { return new DOMRect(x, y, jsonRect.width, jsonRect.height); } + // Message handlers + + async createNestedPopup(parentId) { + return this.createPopup(parentId, 0).id; + } + async setOptions(id, options) { const popup = this.getPopup(id); return await popup.setOptions(options); -- cgit v1.2.3 From 2c8c6866eff1656c3ba5a04638534e4c1582739b Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 17:03:46 -0500 Subject: jsonRectToDOMRect => convertJsonRectToDOMRect Also make static --- ext/fg/js/popup-proxy-host.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 83518f44..e932ae52 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -73,17 +73,6 @@ class PopupProxyHost { return popup; } - jsonRectToDOMRect(popup, jsonRect) { - let x = jsonRect.x; - let y = jsonRect.y; - if (popup.parent !== null) { - const popupRect = popup.parent.container.getBoundingClientRect(); - x += popupRect.x; - y += popupRect.y; - } - return new DOMRect(x, y, jsonRect.width, jsonRect.height); - } - // Message handlers async createNestedPopup(parentId) { @@ -117,7 +106,7 @@ class PopupProxyHost { async showContent(id, elementRect, writingMode, type, details) { const popup = this.getPopup(id); - elementRect = this.jsonRectToDOMRect(popup, elementRect); + elementRect = PopupProxyHost.convertJsonRectToDOMRect(popup, elementRect); if (!PopupProxyHost.popupCanShow(popup)) { return Promise.resolve(false); } return await popup.showContent(elementRect, writingMode, type, details); } @@ -132,6 +121,17 @@ class PopupProxyHost { return popup.clearAutoPlayTimer(); } + static convertJsonRectToDOMRect(popup, jsonRect) { + let x = jsonRect.x; + let y = jsonRect.y; + if (popup.parent !== null) { + const popupRect = popup.parent.container.getBoundingClientRect(); + x += popupRect.x; + y += popupRect.y; + } + return new DOMRect(x, y, jsonRect.width, jsonRect.height); + } + static popupCanShow(popup) { return popup.parent === null || popup.parent.isVisible(); } -- cgit v1.2.3 From 525a3a50d11c282e2b38596dcccc2d6671c0bd63 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 17:05:50 -0500 Subject: Mark private functions --- ext/fg/js/popup-proxy-host.js | 44 +++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index e932ae52..c4217307 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -25,6 +25,8 @@ class PopupProxyHost { this.frameIdPromise = null; } + // Public functions + static create() { const popupProxyHost = new PopupProxyHost(); popupProxyHost.prepare(); @@ -65,14 +67,6 @@ class PopupProxyHost { return popup; } - getPopup(id) { - const popup = this.popups.get(id); - if (typeof popup === 'undefined') { - throw new Error('Invalid popup ID'); - } - return popup; - } - // Message handlers async createNestedPopup(parentId) { @@ -80,48 +74,58 @@ class PopupProxyHost { } async setOptions(id, options) { - const popup = this.getPopup(id); + const popup = this._getPopup(id); return await popup.setOptions(options); } async hide(id, changeFocus) { - const popup = this.getPopup(id); + const popup = this._getPopup(id); return popup.hide(changeFocus); } async isVisibleAsync(id) { - const popup = this.getPopup(id); + const popup = this._getPopup(id); return await popup.isVisibleAsync(); } async setVisibleOverride(id, visible) { - const popup = this.getPopup(id); + const popup = this._getPopup(id); return await popup.setVisibleOverride(visible); } async containsPoint(id, x, y) { - const popup = this.getPopup(id); + const popup = this._getPopup(id); return await popup.containsPoint(x, y); } async showContent(id, elementRect, writingMode, type, details) { - const popup = this.getPopup(id); - elementRect = PopupProxyHost.convertJsonRectToDOMRect(popup, elementRect); - if (!PopupProxyHost.popupCanShow(popup)) { return Promise.resolve(false); } + const popup = this._getPopup(id); + elementRect = PopupProxyHost._convertJsonRectToDOMRect(popup, elementRect); + if (!PopupProxyHost._popupCanShow(popup)) { return Promise.resolve(false); } return await popup.showContent(elementRect, writingMode, type, details); } async setCustomCss(id, css) { - const popup = this.getPopup(id); + const popup = this._getPopup(id); return popup.setCustomCss(css); } async clearAutoPlayTimer(id) { - const popup = this.getPopup(id); + const popup = this._getPopup(id); return popup.clearAutoPlayTimer(); } - static convertJsonRectToDOMRect(popup, jsonRect) { + // Private functions + + _getPopup(id) { + const popup = this.popups.get(id); + if (typeof popup === 'undefined') { + throw new Error('Invalid popup ID'); + } + return popup; + } + + static _convertJsonRectToDOMRect(popup, jsonRect) { let x = jsonRect.x; let y = jsonRect.y; if (popup.parent !== null) { @@ -132,7 +136,7 @@ class PopupProxyHost { return new DOMRect(x, y, jsonRect.width, jsonRect.height); } - static popupCanShow(popup) { + static _popupCanShow(popup) { return popup.parent === null || popup.parent.isVisible(); } } -- cgit v1.2.3 From 8a127e07f32545fdb45e2e8afba4dedd0ae5b955 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 17:06:56 -0500 Subject: Mark private message handlers --- ext/fg/js/popup-proxy-host.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index c4217307..c7c15efe 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -39,15 +39,15 @@ class PopupProxyHost { if (typeof frameId !== 'number') { return; } this.apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${frameId}`, new Map([ - ['createNestedPopup', ({parentId}) => this.createNestedPopup(parentId)], - ['setOptions', ({id, options}) => this.setOptions(id, options)], - ['hide', ({id, changeFocus}) => this.hide(id, changeFocus)], - ['isVisibleAsync', ({id}) => this.isVisibleAsync(id)], - ['setVisibleOverride', ({id, visible}) => this.setVisibleOverride(id, visible)], - ['containsPoint', ({id, x, y}) => this.containsPoint(id, x, y)], - ['showContent', ({id, elementRect, writingMode, type, details}) => this.showContent(id, elementRect, writingMode, type, details)], - ['setCustomCss', ({id, css}) => this.setCustomCss(id, css)], - ['clearAutoPlayTimer', ({id}) => this.clearAutoPlayTimer(id)] + ['createNestedPopup', ({parentId}) => this._onApiCreateNestedPopup(parentId)], + ['setOptions', ({id, options}) => this._onApiSetOptions(id, options)], + ['hide', ({id, changeFocus}) => this._onApiHide(id, changeFocus)], + ['isVisibleAsync', ({id}) => this._onApiIsVisibleAsync(id)], + ['setVisibleOverride', ({id, visible}) => this._onApiSetVisibleOverride(id, visible)], + ['containsPoint', ({id, x, y}) => this._onApiContainsPoint(id, x, y)], + ['showContent', ({id, elementRect, writingMode, type, details}) => this._onApiShowContent(id, elementRect, writingMode, type, details)], + ['setCustomCss', ({id, css}) => this._onApiSetCustomCss(id, css)], + ['clearAutoPlayTimer', ({id}) => this._onApiClearAutoPlayTimer(id)] ])); } @@ -69,48 +69,48 @@ class PopupProxyHost { // Message handlers - async createNestedPopup(parentId) { + async _onApiCreateNestedPopup(parentId) { return this.createPopup(parentId, 0).id; } - async setOptions(id, options) { + async _onApiSetOptions(id, options) { const popup = this._getPopup(id); return await popup.setOptions(options); } - async hide(id, changeFocus) { + async _onApiHide(id, changeFocus) { const popup = this._getPopup(id); return popup.hide(changeFocus); } - async isVisibleAsync(id) { + async _onApiIsVisibleAsync(id) { const popup = this._getPopup(id); return await popup.isVisibleAsync(); } - async setVisibleOverride(id, visible) { + async _onApiSetVisibleOverride(id, visible) { const popup = this._getPopup(id); return await popup.setVisibleOverride(visible); } - async containsPoint(id, x, y) { + async _onApiContainsPoint(id, x, y) { const popup = this._getPopup(id); return await popup.containsPoint(x, y); } - async showContent(id, elementRect, writingMode, type, details) { + async _onApiShowContent(id, elementRect, writingMode, type, details) { const popup = this._getPopup(id); elementRect = PopupProxyHost._convertJsonRectToDOMRect(popup, elementRect); if (!PopupProxyHost._popupCanShow(popup)) { return Promise.resolve(false); } return await popup.showContent(elementRect, writingMode, type, details); } - async setCustomCss(id, css) { + async _onApiSetCustomCss(id, css) { const popup = this._getPopup(id); return popup.setCustomCss(css); } - async clearAutoPlayTimer(id) { + async _onApiClearAutoPlayTimer(id) { const popup = this._getPopup(id); return popup.clearAutoPlayTimer(); } -- cgit v1.2.3 From 2c3a145866106940682dc8a4a1e2377f8ab63013 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 17:07:19 -0500 Subject: Mark private members --- ext/fg/js/popup-proxy-host.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index c7c15efe..ea343c19 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -19,10 +19,10 @@ class PopupProxyHost { constructor() { - this.popups = new Map(); - this.nextId = 0; - this.apiReceiver = null; - this.frameIdPromise = null; + this._popups = new Map(); + this._nextId = 0; + this._apiReceiver = null; + this._frameIdPromise = null; } // Public functions @@ -34,11 +34,11 @@ class PopupProxyHost { } async prepare() { - this.frameIdPromise = apiFrameInformationGet(); - const {frameId} = await this.frameIdPromise; + this._frameIdPromise = apiFrameInformationGet(); + const {frameId} = await this._frameIdPromise; if (typeof frameId !== 'number') { return; } - this.apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${frameId}`, new Map([ + this._apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${frameId}`, new Map([ ['createNestedPopup', ({parentId}) => this._onApiCreateNestedPopup(parentId)], ['setOptions', ({id, options}) => this._onApiSetOptions(id, options)], ['hide', ({id, changeFocus}) => this._onApiHide(id, changeFocus)], @@ -52,18 +52,18 @@ class PopupProxyHost { } createPopup(parentId, depth) { - const parent = (typeof parentId === 'string' && this.popups.has(parentId) ? this.popups.get(parentId) : null); - const id = `${this.nextId}`; + const parent = (typeof parentId === 'string' && this._popups.has(parentId) ? this._popups.get(parentId) : null); + const id = `${this._nextId}`; if (parent !== null) { depth = parent.depth + 1; } - ++this.nextId; - const popup = new Popup(id, depth, this.frameIdPromise); + ++this._nextId; + const popup = new Popup(id, depth, this._frameIdPromise); if (parent !== null) { popup.parent = parent; parent.child = popup; } - this.popups.set(id, popup); + this._popups.set(id, popup); return popup; } @@ -118,7 +118,7 @@ class PopupProxyHost { // Private functions _getPopup(id) { - const popup = this.popups.get(id); + const popup = this._popups.get(id); if (typeof popup === 'undefined') { throw new Error('Invalid popup ID'); } -- cgit v1.2.3 From fab0d703581a57aa7aa6d50a640b291a944708a2 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 17:22:26 -0500 Subject: Move popup public properties --- ext/fg/js/popup.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 42475d96..9e80a379 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -42,6 +42,12 @@ class Popup { this.updateVisibility(); } + // Public properties + + get url() { + return window.location.href; + } + inject() { if (this.injectPromise === null) { this.injectPromise = this.createInjectPromise(); @@ -384,10 +390,6 @@ class Popup { } } - get url() { - return window.location.href; - } - static isOnExtensionPage() { try { const url = chrome.runtime.getURL('/'); -- cgit v1.2.3 From 8164ccfbfc257b81b5c35a38b1629d6c1178498d Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 17:23:27 -0500 Subject: Group poup static functions together --- ext/fg/js/popup.js | 236 ++++++++++++++++++++++++++--------------------------- 1 file changed, 118 insertions(+), 118 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 9e80a379..6aebc68e 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -138,99 +138,6 @@ class Popup { } } - static getPositionForHorizontalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral) { - let x = elementRect.left + optionsGeneral.popupHorizontalOffset; - const overflowX = Math.max(x + width - maxWidth, 0); - if (overflowX > 0) { - if (x >= overflowX) { - x -= overflowX; - } else { - width = maxWidth; - x = 0; - } - } - - const preferBelow = (optionsGeneral.popupHorizontalTextPosition === 'below'); - - const verticalOffset = optionsGeneral.popupVerticalOffset; - const [y, h, below] = Popup.limitGeometry( - elementRect.top - verticalOffset, - elementRect.bottom + verticalOffset, - height, - maxHeight, - preferBelow - ); - - return [x, y, width, h, below]; - } - - static getPositionForVerticalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral, writingMode) { - const preferRight = Popup.isVerticalTextPopupOnRight(optionsGeneral.popupVerticalTextPosition, writingMode); - const horizontalOffset = optionsGeneral.popupHorizontalOffset2; - const verticalOffset = optionsGeneral.popupVerticalOffset2; - - const [x, w] = Popup.limitGeometry( - elementRect.left - horizontalOffset, - elementRect.right + horizontalOffset, - width, - maxWidth, - preferRight - ); - const [y, h, below] = Popup.limitGeometry( - elementRect.bottom - verticalOffset, - elementRect.top + verticalOffset, - height, - maxHeight, - true - ); - return [x, y, w, h, below]; - } - - static isVerticalTextPopupOnRight(positionPreference, writingMode) { - switch (positionPreference) { - case 'before': - return !Popup.isWritingModeLeftToRight(writingMode); - case 'after': - return Popup.isWritingModeLeftToRight(writingMode); - case 'left': - return false; - case 'right': - return true; - } - } - - static isWritingModeLeftToRight(writingMode) { - switch (writingMode) { - case 'vertical-lr': - case 'sideways-lr': - return true; - default: - return false; - } - } - - static limitGeometry(positionBefore, positionAfter, size, limit, preferAfter) { - let after = preferAfter; - let position = 0; - const overflowBefore = Math.max(0, size - positionBefore); - const overflowAfter = Math.max(0, positionAfter + size - limit); - if (overflowAfter > 0 || overflowBefore > 0) { - if (overflowAfter < overflowBefore) { - size = Math.max(0, size - overflowAfter); - position = positionAfter; - after = true; - } else { - size = Math.max(0, size - overflowBefore); - position = Math.max(0, positionBefore - size); - after = false; - } - } else { - position = preferAfter ? positionAfter : positionBefore - size; - } - - return [position, size, after]; - } - hide(changeFocus) { if (!this.isVisible()) { return; @@ -296,31 +203,6 @@ class Popup { return dark ? 'dark' : 'light'; } - static addColor(target, color) { - if (color === null) { return; } - - const a = color[3]; - if (a <= 0.0) { return; } - - const aInv = 1.0 - a; - for (let i = 0; i < 3; ++i) { - target[i] = target[i] * aInv + color[i] * a; - } - } - - static getColorInfo(cssColor) { - const m = /^\s*rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+)\s*)?\)\s*$/.exec(cssColor); - if (m === null) { return null; } - - const m4 = m[4]; - return [ - Number.parseInt(m[1], 10), - Number.parseInt(m[2], 10), - Number.parseInt(m[3], 10), - m4 ? Math.max(0.0, Math.min(1.0, Number.parseFloat(m4))) : 1.0 - ]; - } - async containsPoint(x, y) { for (let popup = this; popup !== null && popup.isVisible(); popup = popup.child) { const rect = popup.container.getBoundingClientRect(); @@ -390,6 +272,124 @@ class Popup { } } + static getPositionForHorizontalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral) { + let x = elementRect.left + optionsGeneral.popupHorizontalOffset; + const overflowX = Math.max(x + width - maxWidth, 0); + if (overflowX > 0) { + if (x >= overflowX) { + x -= overflowX; + } else { + width = maxWidth; + x = 0; + } + } + + const preferBelow = (optionsGeneral.popupHorizontalTextPosition === 'below'); + + const verticalOffset = optionsGeneral.popupVerticalOffset; + const [y, h, below] = Popup.limitGeometry( + elementRect.top - verticalOffset, + elementRect.bottom + verticalOffset, + height, + maxHeight, + preferBelow + ); + + return [x, y, width, h, below]; + } + + static getPositionForVerticalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral, writingMode) { + const preferRight = Popup.isVerticalTextPopupOnRight(optionsGeneral.popupVerticalTextPosition, writingMode); + const horizontalOffset = optionsGeneral.popupHorizontalOffset2; + const verticalOffset = optionsGeneral.popupVerticalOffset2; + + const [x, w] = Popup.limitGeometry( + elementRect.left - horizontalOffset, + elementRect.right + horizontalOffset, + width, + maxWidth, + preferRight + ); + const [y, h, below] = Popup.limitGeometry( + elementRect.bottom - verticalOffset, + elementRect.top + verticalOffset, + height, + maxHeight, + true + ); + return [x, y, w, h, below]; + } + + static isVerticalTextPopupOnRight(positionPreference, writingMode) { + switch (positionPreference) { + case 'before': + return !Popup.isWritingModeLeftToRight(writingMode); + case 'after': + return Popup.isWritingModeLeftToRight(writingMode); + case 'left': + return false; + case 'right': + return true; + } + } + + static isWritingModeLeftToRight(writingMode) { + switch (writingMode) { + case 'vertical-lr': + case 'sideways-lr': + return true; + default: + return false; + } + } + + static limitGeometry(positionBefore, positionAfter, size, limit, preferAfter) { + let after = preferAfter; + let position = 0; + const overflowBefore = Math.max(0, size - positionBefore); + const overflowAfter = Math.max(0, positionAfter + size - limit); + if (overflowAfter > 0 || overflowBefore > 0) { + if (overflowAfter < overflowBefore) { + size = Math.max(0, size - overflowAfter); + position = positionAfter; + after = true; + } else { + size = Math.max(0, size - overflowBefore); + position = Math.max(0, positionBefore - size); + after = false; + } + } else { + position = preferAfter ? positionAfter : positionBefore - size; + } + + return [position, size, after]; + } + + static addColor(target, color) { + if (color === null) { return; } + + const a = color[3]; + if (a <= 0.0) { return; } + + const aInv = 1.0 - a; + for (let i = 0; i < 3; ++i) { + target[i] = target[i] * aInv + color[i] * a; + } + } + + static getColorInfo(cssColor) { + const m = /^\s*rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+)\s*)?\)\s*$/.exec(cssColor); + if (m === null) { return null; } + + const m4 = m[4]; + return [ + Number.parseInt(m[1], 10), + Number.parseInt(m[2], 10), + Number.parseInt(m[3], 10), + m4 ? Math.max(0.0, Math.min(1.0, Number.parseFloat(m4))) : 1.0 + ]; + } + static isOnExtensionPage() { try { const url = chrome.runtime.getURL('/'); -- cgit v1.2.3 From 4014bbab427c9c9441ca778f3cda528e35f054f6 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 20:11:32 -0500 Subject: Reorganize popup public functions to match popup proxy --- ext/fg/js/popup.js | 112 +++++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 55 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 6aebc68e..8226a13a 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -48,6 +48,63 @@ class Popup { return window.location.href; } + // Public functions + + async setOptions(options) { + this.options = options; + this.updateTheme(); + } + + hide(changeFocus) { + if (!this.isVisible()) { + return; + } + + this.setVisible(false); + if (this.child !== null) { + this.child.hide(false); + } + if (changeFocus) { + this.focusParent(); + } + } + + async isVisibleAsync() { + return this.isVisible(); + } + + setVisibleOverride(visible) { + this.visibleOverride = visible; + this.updateVisibility(); + } + + async containsPoint(x, y) { + for (let popup = this; popup !== null && popup.isVisible(); popup = popup.child) { + const rect = popup.container.getBoundingClientRect(); + if (x >= rect.left && y >= rect.top && x < rect.right && y < rect.bottom) { + return true; + } + } + return false; + } + + async showContent(elementRect, writingMode, type=null, details=null) { + if (!this.isInitialized()) { return; } + await this.show(elementRect, writingMode); + if (type === null) { return; } + this.invokeApi('setContent', {type, details}); + } + + async setCustomCss(css) { + this.invokeApi('setCustomCss', {css}); + } + + clearAutoPlayTimer() { + if (this.isInjected) { + this.invokeApi('clearAutoPlayTimer'); + } + } + inject() { if (this.injectPromise === null) { this.injectPromise = this.createInjectPromise(); @@ -91,18 +148,6 @@ class Popup { return this.options !== null; } - async setOptions(options) { - this.options = options; - this.updateTheme(); - } - - async showContent(elementRect, writingMode, type=null, details=null) { - if (!this.isInitialized()) { return; } - await this.show(elementRect, writingMode); - if (type === null) { return; } - this.invokeApi('setContent', {type, details}); - } - async show(elementRect, writingMode) { await this.inject(); @@ -138,24 +183,6 @@ class Popup { } } - hide(changeFocus) { - if (!this.isVisible()) { - return; - } - - this.setVisible(false); - if (this.child !== null) { - this.child.hide(false); - } - if (changeFocus) { - this.focusParent(); - } - } - - async isVisibleAsync() { - return this.isVisible(); - } - isVisible() { return this.isInjected && (this.visibleOverride !== null ? this.visibleOverride : this.visible); } @@ -165,11 +192,6 @@ class Popup { this.updateVisibility(); } - setVisibleOverride(visible) { - this.visibleOverride = visible; - this.updateVisibility(); - } - updateVisibility() { this.container.style.setProperty('visibility', this.isVisible() ? 'visible' : 'hidden', 'important'); } @@ -203,20 +225,6 @@ class Popup { return dark ? 'dark' : 'light'; } - async containsPoint(x, y) { - for (let popup = this; popup !== null && popup.isVisible(); popup = popup.child) { - const rect = popup.container.getBoundingClientRect(); - if (x >= rect.left && y >= rect.top && x < rect.right && y < rect.bottom) { - return true; - } - } - return false; - } - - async setCustomCss(css) { - this.invokeApi('setCustomCss', {css}); - } - async setCustomOuterCss(css, injectDirectly) { // Cannot repeatedly inject stylesheets using web extension APIs since there is no way to remove them. if (this.stylesheetInjectedViaApi) { return; } @@ -234,12 +242,6 @@ class Popup { } } - clearAutoPlayTimer() { - if (this.isInjected) { - this.invokeApi('clearAutoPlayTimer'); - } - } - invokeApi(action, params={}) { this.container.contentWindow.postMessage({action, params}, '*'); } -- cgit v1.2.3 From 44bde5c6765317294af317f7bbbdfa70d0d40b77 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 20:48:52 -0500 Subject: Reorganize popup-only public functions --- ext/fg/js/popup-proxy-host.js | 2 +- ext/fg/js/popup.js | 94 ++++++++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 47 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index ea343c19..bf6604e5 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -101,7 +101,7 @@ class PopupProxyHost { async _onApiShowContent(id, elementRect, writingMode, type, details) { const popup = this._getPopup(id); elementRect = PopupProxyHost._convertJsonRectToDOMRect(popup, elementRect); - if (!PopupProxyHost._popupCanShow(popup)) { return Promise.resolve(false); } + if (!PopupProxyHost._popupCanShow(popup)) { return; } return await popup.showContent(elementRect, writingMode, type, details); } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 8226a13a..9040d568 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -105,6 +105,54 @@ class Popup { } } + // Popup-only public functions + + isVisible() { + return this.isInjected && (this.visibleOverride !== null ? this.visibleOverride : this.visible); + } + + updateTheme() { + this.container.dataset.yomichanTheme = this.options.general.popupOuterTheme; + this.container.dataset.yomichanSiteColor = this.getSiteColor(); + } + + async setCustomOuterCss(css, injectDirectly) { + // Cannot repeatedly inject stylesheets using web extension APIs since there is no way to remove them. + if (this.stylesheetInjectedViaApi) { return; } + + if (injectDirectly || Popup.isOnExtensionPage()) { + Popup.injectOuterStylesheet(css); + } else { + if (!css) { return; } + try { + await apiInjectStylesheet(css); + this.stylesheetInjectedViaApi = true; + } catch (e) { + // NOP + } + } + } + + static injectOuterStylesheet(css) { + if (Popup.outerStylesheet === null) { + if (!css) { return; } + Popup.outerStylesheet = document.createElement('style'); + Popup.outerStylesheet.id = 'yomichan-popup-outer-stylesheet'; + } + + const outerStylesheet = Popup.outerStylesheet; + if (css) { + outerStylesheet.textContent = css; + + const par = document.head; + if (par && outerStylesheet.parentNode !== par) { + par.appendChild(outerStylesheet); + } + } else { + outerStylesheet.textContent = ''; + } + } + inject() { if (this.injectPromise === null) { this.injectPromise = this.createInjectPromise(); @@ -183,10 +231,6 @@ class Popup { } } - isVisible() { - return this.isInjected && (this.visibleOverride !== null ? this.visibleOverride : this.visible); - } - setVisible(visible) { this.visible = visible; this.updateVisibility(); @@ -212,11 +256,6 @@ class Popup { } } - updateTheme() { - this.container.dataset.yomichanTheme = this.options.general.popupOuterTheme; - this.container.dataset.yomichanSiteColor = this.getSiteColor(); - } - getSiteColor() { const color = [255, 255, 255]; Popup.addColor(color, Popup.getColorInfo(window.getComputedStyle(document.documentElement).backgroundColor)); @@ -225,23 +264,6 @@ class Popup { return dark ? 'dark' : 'light'; } - async setCustomOuterCss(css, injectDirectly) { - // Cannot repeatedly inject stylesheets using web extension APIs since there is no way to remove them. - if (this.stylesheetInjectedViaApi) { return; } - - if (injectDirectly || Popup.isOnExtensionPage()) { - Popup.injectOuterStylesheet(css); - } else { - if (!css) { return; } - try { - await apiInjectStylesheet(css); - this.stylesheetInjectedViaApi = true; - } catch (e) { - // NOP - } - } - } - invokeApi(action, params={}) { this.container.contentWindow.postMessage({action, params}, '*'); } @@ -400,26 +422,6 @@ class Popup { // NOP } } - - static injectOuterStylesheet(css) { - if (Popup.outerStylesheet === null) { - if (!css) { return; } - Popup.outerStylesheet = document.createElement('style'); - Popup.outerStylesheet.id = 'yomichan-popup-outer-stylesheet'; - } - - const outerStylesheet = Popup.outerStylesheet; - if (css) { - outerStylesheet.textContent = css; - - const par = document.head; - if (par && outerStylesheet.parentNode !== par) { - par.appendChild(outerStylesheet); - } - } else { - outerStylesheet.textContent = ''; - } - } } Popup.outerStylesheet = null; -- cgit v1.2.3 From c3ea9528447b130517fc75257d07e6a5250c2f82 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 20:54:20 -0500 Subject: Mark private functions --- ext/fg/js/popup.js | 102 +++++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 50 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 9040d568..c3ec4583 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -39,7 +39,7 @@ class Popup { this.visibleOverride = null; this.options = null; this.stylesheetInjectedViaApi = false; - this.updateVisibility(); + this._updateVisibility(); } // Public properties @@ -60,12 +60,12 @@ class Popup { return; } - this.setVisible(false); + this._setVisible(false); if (this.child !== null) { this.child.hide(false); } if (changeFocus) { - this.focusParent(); + this._focusParent(); } } @@ -75,7 +75,7 @@ class Popup { setVisibleOverride(visible) { this.visibleOverride = visible; - this.updateVisibility(); + this._updateVisibility(); } async containsPoint(x, y) { @@ -89,19 +89,19 @@ class Popup { } async showContent(elementRect, writingMode, type=null, details=null) { - if (!this.isInitialized()) { return; } - await this.show(elementRect, writingMode); + if (!this._isInitialized()) { return; } + await this._show(elementRect, writingMode); if (type === null) { return; } - this.invokeApi('setContent', {type, details}); + this._invokeApi('setContent', {type, details}); } async setCustomCss(css) { - this.invokeApi('setCustomCss', {css}); + this._invokeApi('setCustomCss', {css}); } clearAutoPlayTimer() { if (this.isInjected) { - this.invokeApi('clearAutoPlayTimer'); + this._invokeApi('clearAutoPlayTimer'); } } @@ -113,14 +113,14 @@ class Popup { updateTheme() { this.container.dataset.yomichanTheme = this.options.general.popupOuterTheme; - this.container.dataset.yomichanSiteColor = this.getSiteColor(); + this.container.dataset.yomichanSiteColor = this._getSiteColor(); } async setCustomOuterCss(css, injectDirectly) { // Cannot repeatedly inject stylesheets using web extension APIs since there is no way to remove them. if (this.stylesheetInjectedViaApi) { return; } - if (injectDirectly || Popup.isOnExtensionPage()) { + if (injectDirectly || Popup._isOnExtensionPage()) { Popup.injectOuterStylesheet(css); } else { if (!css) { return; } @@ -153,14 +153,16 @@ class Popup { } } - inject() { + // Private functions + + _inject() { if (this.injectPromise === null) { - this.injectPromise = this.createInjectPromise(); + this.injectPromise = this._createInjectPromise(); } return this.injectPromise; } - async createInjectPromise() { + async _createInjectPromise() { try { const {frameId} = await this.frameIdPromise; if (typeof frameId === 'number') { @@ -173,7 +175,7 @@ class Popup { return new Promise((resolve) => { const parentFrameId = (typeof this.frameId === 'number' ? this.frameId : null); this.container.addEventListener('load', () => { - this.invokeApi('initialize', { + this._invokeApi('initialize', { options: this.options, popupInfo: { id: this.id, @@ -185,27 +187,27 @@ class Popup { }); resolve(); }); - this.observeFullscreen(); - this.onFullscreenChanged(); + this._observeFullscreen(); + this._onFullscreenChanged(); this.setCustomOuterCss(this.options.general.customPopupOuterCss, false); this.isInjected = true; }); } - isInitialized() { + _isInitialized() { return this.options !== null; } - async show(elementRect, writingMode) { - await this.inject(); + async _show(elementRect, writingMode) { + await this._inject(); const optionsGeneral = this.options.general; const container = this.container; const containerRect = container.getBoundingClientRect(); const getPosition = ( writingMode === 'horizontal-tb' || optionsGeneral.popupVerticalTextPosition === 'default' ? - Popup.getPositionForHorizontalText : - Popup.getPositionForVerticalText + Popup._getPositionForHorizontalText : + Popup._getPositionForVerticalText ); const [x, y, width, height, below] = getPosition( @@ -225,22 +227,22 @@ class Popup { container.style.width = `${width}px`; container.style.height = `${height}px`; - this.setVisible(true); + this._setVisible(true); if (this.child !== null) { this.child.hide(true); } } - setVisible(visible) { + _setVisible(visible) { this.visible = visible; - this.updateVisibility(); + this._updateVisibility(); } - updateVisibility() { + _updateVisibility() { this.container.style.setProperty('visibility', this.isVisible() ? 'visible' : 'hidden', 'important'); } - focusParent() { + _focusParent() { if (this.parent !== null) { // Chrome doesn't like focusing iframe without contentWindow. const contentWindow = this.parent.container.contentWindow; @@ -256,19 +258,19 @@ class Popup { } } - getSiteColor() { + _getSiteColor() { const color = [255, 255, 255]; - Popup.addColor(color, Popup.getColorInfo(window.getComputedStyle(document.documentElement).backgroundColor)); - Popup.addColor(color, Popup.getColorInfo(window.getComputedStyle(document.body).backgroundColor)); + Popup._addColor(color, Popup._getColorInfo(window.getComputedStyle(document.documentElement).backgroundColor)); + Popup._addColor(color, Popup._getColorInfo(window.getComputedStyle(document.body).backgroundColor)); const dark = (color[0] < 128 && color[1] < 128 && color[2] < 128); return dark ? 'dark' : 'light'; } - invokeApi(action, params={}) { + _invokeApi(action, params={}) { this.container.contentWindow.postMessage({action, params}, '*'); } - observeFullscreen() { + _observeFullscreen() { const fullscreenEvents = [ 'fullscreenchange', 'MSFullscreenChange', @@ -276,11 +278,11 @@ class Popup { 'webkitfullscreenchange' ]; for (const eventName of fullscreenEvents) { - document.addEventListener(eventName, () => this.onFullscreenChanged(), false); + document.addEventListener(eventName, () => this._onFullscreenChanged(), false); } } - getFullscreenElement() { + _getFullscreenElement() { return ( document.fullscreenElement || document.msFullscreenElement || @@ -289,14 +291,14 @@ class Popup { ); } - onFullscreenChanged() { - const parent = (this.getFullscreenElement() || document.body || null); + _onFullscreenChanged() { + const parent = (this._getFullscreenElement() || document.body || null); if (parent !== null && this.container.parentNode !== parent) { parent.appendChild(this.container); } } - static getPositionForHorizontalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral) { + static _getPositionForHorizontalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral) { let x = elementRect.left + optionsGeneral.popupHorizontalOffset; const overflowX = Math.max(x + width - maxWidth, 0); if (overflowX > 0) { @@ -311,7 +313,7 @@ class Popup { const preferBelow = (optionsGeneral.popupHorizontalTextPosition === 'below'); const verticalOffset = optionsGeneral.popupVerticalOffset; - const [y, h, below] = Popup.limitGeometry( + const [y, h, below] = Popup._limitGeometry( elementRect.top - verticalOffset, elementRect.bottom + verticalOffset, height, @@ -322,19 +324,19 @@ class Popup { return [x, y, width, h, below]; } - static getPositionForVerticalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral, writingMode) { - const preferRight = Popup.isVerticalTextPopupOnRight(optionsGeneral.popupVerticalTextPosition, writingMode); + static _getPositionForVerticalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral, writingMode) { + const preferRight = Popup._isVerticalTextPopupOnRight(optionsGeneral.popupVerticalTextPosition, writingMode); const horizontalOffset = optionsGeneral.popupHorizontalOffset2; const verticalOffset = optionsGeneral.popupVerticalOffset2; - const [x, w] = Popup.limitGeometry( + const [x, w] = Popup._limitGeometry( elementRect.left - horizontalOffset, elementRect.right + horizontalOffset, width, maxWidth, preferRight ); - const [y, h, below] = Popup.limitGeometry( + const [y, h, below] = Popup._limitGeometry( elementRect.bottom - verticalOffset, elementRect.top + verticalOffset, height, @@ -344,12 +346,12 @@ class Popup { return [x, y, w, h, below]; } - static isVerticalTextPopupOnRight(positionPreference, writingMode) { + static _isVerticalTextPopupOnRight(positionPreference, writingMode) { switch (positionPreference) { case 'before': - return !Popup.isWritingModeLeftToRight(writingMode); + return !Popup._isWritingModeLeftToRight(writingMode); case 'after': - return Popup.isWritingModeLeftToRight(writingMode); + return Popup._isWritingModeLeftToRight(writingMode); case 'left': return false; case 'right': @@ -357,7 +359,7 @@ class Popup { } } - static isWritingModeLeftToRight(writingMode) { + static _isWritingModeLeftToRight(writingMode) { switch (writingMode) { case 'vertical-lr': case 'sideways-lr': @@ -367,7 +369,7 @@ class Popup { } } - static limitGeometry(positionBefore, positionAfter, size, limit, preferAfter) { + static _limitGeometry(positionBefore, positionAfter, size, limit, preferAfter) { let after = preferAfter; let position = 0; const overflowBefore = Math.max(0, size - positionBefore); @@ -389,7 +391,7 @@ class Popup { return [position, size, after]; } - static addColor(target, color) { + static _addColor(target, color) { if (color === null) { return; } const a = color[3]; @@ -401,7 +403,7 @@ class Popup { } } - static getColorInfo(cssColor) { + static _getColorInfo(cssColor) { const m = /^\s*rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+)\s*)?\)\s*$/.exec(cssColor); if (m === null) { return null; } @@ -414,7 +416,7 @@ class Popup { ]; } - static isOnExtensionPage() { + static _isOnExtensionPage() { try { const url = chrome.runtime.getURL('/'); return window.location.href.substring(0, url.length) === url; -- cgit v1.2.3 From 37da5fef59fcf0b0391e8e0cc12c5d29674e7b47 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:04:53 -0500 Subject: Move container definition --- ext/fg/js/popup.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index c3ec4583..0f6af1a5 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -26,6 +26,13 @@ class Popup { this.parent = null; this.child = null; this.childrenSupported = true; + this.injectPromise = null; + this.isInjected = false; + this.visible = false; + this.visibleOverride = null; + this.options = null; + this.stylesheetInjectedViaApi = false; + this.container = document.createElement('iframe'); this.container.className = 'yomichan-float'; this.container.addEventListener('mousedown', (e) => e.stopPropagation()); @@ -33,12 +40,7 @@ class Popup { this.container.setAttribute('src', chrome.runtime.getURL('/fg/float.html')); this.container.style.width = '0px'; this.container.style.height = '0px'; - this.injectPromise = null; - this.isInjected = false; - this.visible = false; - this.visibleOverride = null; - this.options = null; - this.stylesheetInjectedViaApi = false; + this._updateVisibility(); } -- cgit v1.2.3 From 4ba93b07706745ea4d3ba21598e686275b8fa5f1 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:09:51 -0500 Subject: Add getContainerRect to popup --- ext/fg/js/popup-proxy-host.js | 2 +- ext/fg/js/popup.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index bf6604e5..697c8077 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -129,7 +129,7 @@ class PopupProxyHost { let x = jsonRect.x; let y = jsonRect.y; if (popup.parent !== null) { - const popupRect = popup.parent.container.getBoundingClientRect(); + const popupRect = popup.parent.getContainerRect(); x += popupRect.x; y += popupRect.y; } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 0f6af1a5..46a09548 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -135,6 +135,10 @@ class Popup { } } + getContainerRect() { + return this.container.getBoundingClientRect(); + } + static injectOuterStylesheet(css) { if (Popup.outerStylesheet === null) { if (!css) { return; } -- cgit v1.2.3 From c4719cb7f4013d7425d66f2dd79765e9b56fbd51 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:12:21 -0500 Subject: Add getContainer to popup --- ext/fg/js/frontend.js | 2 +- ext/fg/js/popup.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 43b64bb0..8835df70 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -22,7 +22,7 @@ class Frontend extends TextScanner { super( window, ignoreNodes, - [popup.container], + [popup.getContainer()], [(x, y) => this.popup.containsPoint(x, y)] ); diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 46a09548..2af734a9 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -135,6 +135,10 @@ class Popup { } } + getContainer() { + return this.container; + } + getContainerRect() { return this.container.getBoundingClientRect(); } -- cgit v1.2.3 From 41fadfd0a9efd414bc41fab95b72deffac0d77fc Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:25:06 -0500 Subject: Add setChildrenSupported to popup --- ext/bg/js/settings/popup-preview-frame.js | 2 +- ext/fg/js/popup.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'ext/fg/js') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index a26d3148..b2902af0 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -53,7 +53,7 @@ class SettingsPopupPreview { this.frontend.setEnabled = function () {}; this.frontend.searchClear = function () {}; - this.frontend.popup.childrenSupported = false; + this.frontend.popup.setChildrenSupported(false); await this.frontend.isPrepared(); diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 2af734a9..552bdcf6 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -135,6 +135,10 @@ class Popup { } } + setChildrenSupported(value) { + this.childrenSupported = value; + } + getContainer() { return this.container; } -- cgit v1.2.3 From 289a1849c45464cb23bdcaf42c3653515945fc17 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:31:30 -0500 Subject: Add _createPopupInternal to return both popup and new ID --- ext/fg/js/popup-proxy-host.js | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 697c8077..157097de 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -52,25 +52,13 @@ class PopupProxyHost { } createPopup(parentId, depth) { - const parent = (typeof parentId === 'string' && this._popups.has(parentId) ? this._popups.get(parentId) : null); - const id = `${this._nextId}`; - if (parent !== null) { - depth = parent.depth + 1; - } - ++this._nextId; - const popup = new Popup(id, depth, this._frameIdPromise); - if (parent !== null) { - popup.parent = parent; - parent.child = popup; - } - this._popups.set(id, popup); - return popup; + return this._createPopupInternal(parentId, depth).popup; } // Message handlers async _onApiCreateNestedPopup(parentId) { - return this.createPopup(parentId, 0).id; + return this._createPopupInternal(parentId, 0).id; } async _onApiSetOptions(id, options) { @@ -117,6 +105,22 @@ class PopupProxyHost { // Private functions + _createPopupInternal(parentId, depth) { + const parent = (typeof parentId === 'string' && this._popups.has(parentId) ? this._popups.get(parentId) : null); + const id = `${this._nextId}`; + if (parent !== null) { + depth = parent.depth + 1; + } + ++this._nextId; + const popup = new Popup(id, depth, this._frameIdPromise); + if (parent !== null) { + popup.parent = parent; + parent.child = popup; + } + this._popups.set(id, popup); + return {popup, id}; + } + _getPopup(id) { const popup = this._popups.get(id); if (typeof popup === 'undefined') { -- cgit v1.2.3 From 30e13354b3b58a7d7cfce26487076eaaa7552416 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:34:18 -0500 Subject: Add Popup.isProxy --- ext/fg/js/frontend.js | 2 +- ext/fg/js/popup-proxy.js | 4 ++++ ext/fg/js/popup.js | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 8835df70..2fa69c9d 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -22,7 +22,7 @@ class Frontend extends TextScanner { super( window, ignoreNodes, - [popup.getContainer()], + popup.isProxy() ? [] : [popup.getContainer()], [(x, y) => this.popup.containsPoint(x, y)] ); diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index d90d98be..0471705f 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -48,6 +48,10 @@ class PopupProxy { // Public functions + isProxy() { + return true; + } + async setOptions(options) { const id = await this._getPopupId(); return await this._invokeHostApi('setOptions', {id, options}); diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 552bdcf6..de2c7863 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -52,6 +52,10 @@ class Popup { // Public functions + isProxy() { + return false; + } + async setOptions(options) { this.options = options; this.updateTheme(); -- cgit v1.2.3 From 7c68490d2ea7f106ab79e5bc7ff00b92c95614ff Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:40:06 -0500 Subject: Add setParent to popup --- ext/fg/js/popup-proxy-host.js | 3 +-- ext/fg/js/popup.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 157097de..cb385cc2 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -114,8 +114,7 @@ class PopupProxyHost { ++this._nextId; const popup = new Popup(id, depth, this._frameIdPromise); if (parent !== null) { - popup.parent = parent; - parent.child = popup; + popup.setParent(parent); } this._popups.set(id, popup); return {popup, id}; diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index de2c7863..fafc15aa 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -113,6 +113,20 @@ class Popup { // Popup-only public functions + setParent(parent) { + if (parent === null) { + throw new Error('Cannot set popup parent to null'); + } + if (this.parent !== null) { + throw new Error('Popup already has a parent'); + } + if (parent.child !== null) { + throw new Error('Cannot parent popup to another popup which already has a child'); + } + this.parent = parent; + parent.child = this; + } + isVisible() { return this.isInjected && (this.visibleOverride !== null ? this.visibleOverride : this.visible); } -- cgit v1.2.3 From 801df8000f26961f9870ddfc90929f88bd8c7028 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:43:47 -0500 Subject: Mark private members --- ext/fg/js/popup.js | 144 +++++++++++++++++++++++++++++------------------------ 1 file changed, 78 insertions(+), 66 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index fafc15aa..bdc63b7f 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -19,33 +19,45 @@ class Popup { constructor(id, depth, frameIdPromise) { - this.id = id; - this.depth = depth; - this.frameIdPromise = frameIdPromise; - this.frameId = null; - this.parent = null; - this.child = null; - this.childrenSupported = true; - this.injectPromise = null; - this.isInjected = false; - this.visible = false; - this.visibleOverride = null; - this.options = null; - this.stylesheetInjectedViaApi = false; - - this.container = document.createElement('iframe'); - this.container.className = 'yomichan-float'; - this.container.addEventListener('mousedown', (e) => e.stopPropagation()); - this.container.addEventListener('scroll', (e) => e.stopPropagation()); - this.container.setAttribute('src', chrome.runtime.getURL('/fg/float.html')); - this.container.style.width = '0px'; - this.container.style.height = '0px'; + this._id = id; + this._depth = depth; + this._frameIdPromise = frameIdPromise; + this._frameId = null; + this._parent = null; + this._child = null; + this._childrenSupported = true; + this._injectPromise = null; + this._isInjected = false; + this._visible = false; + this._visibleOverride = null; + this._options = null; + this._stylesheetInjectedViaApi = false; + + this._container = document.createElement('iframe'); + this._container.className = 'yomichan-float'; + this._container.addEventListener('mousedown', (e) => e.stopPropagation()); + this._container.addEventListener('scroll', (e) => e.stopPropagation()); + this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html')); + this._container.style.width = '0px'; + this._container.style.height = '0px'; this._updateVisibility(); } // Public properties + get parent() { + return this._parent; + } + + get child() { + return this._child; + } + + get depth() { + return this._depth; + } + get url() { return window.location.href; } @@ -57,7 +69,7 @@ class Popup { } async setOptions(options) { - this.options = options; + this._options = options; this.updateTheme(); } @@ -67,8 +79,8 @@ class Popup { } this._setVisible(false); - if (this.child !== null) { - this.child.hide(false); + if (this._child !== null) { + this._child.hide(false); } if (changeFocus) { this._focusParent(); @@ -80,13 +92,13 @@ class Popup { } setVisibleOverride(visible) { - this.visibleOverride = visible; + this._visibleOverride = visible; this._updateVisibility(); } async containsPoint(x, y) { - for (let popup = this; popup !== null && popup.isVisible(); popup = popup.child) { - const rect = popup.container.getBoundingClientRect(); + for (let popup = this; popup !== null && popup.isVisible(); popup = popup._child) { + const rect = popup._container.getBoundingClientRect(); if (x >= rect.left && y >= rect.top && x < rect.right && y < rect.bottom) { return true; } @@ -106,7 +118,7 @@ class Popup { } clearAutoPlayTimer() { - if (this.isInjected) { + if (this._isInjected) { this._invokeApi('clearAutoPlayTimer'); } } @@ -117,28 +129,28 @@ class Popup { if (parent === null) { throw new Error('Cannot set popup parent to null'); } - if (this.parent !== null) { + if (this._parent !== null) { throw new Error('Popup already has a parent'); } - if (parent.child !== null) { + if (parent._child !== null) { throw new Error('Cannot parent popup to another popup which already has a child'); } - this.parent = parent; - parent.child = this; + this._parent = parent; + parent._child = this; } isVisible() { - return this.isInjected && (this.visibleOverride !== null ? this.visibleOverride : this.visible); + return this._isInjected && (this._visibleOverride !== null ? this._visibleOverride : this._visible); } updateTheme() { - this.container.dataset.yomichanTheme = this.options.general.popupOuterTheme; - this.container.dataset.yomichanSiteColor = this._getSiteColor(); + this._container.dataset.yomichanTheme = this._options.general.popupOuterTheme; + this._container.dataset.yomichanSiteColor = this._getSiteColor(); } async setCustomOuterCss(css, injectDirectly) { // Cannot repeatedly inject stylesheets using web extension APIs since there is no way to remove them. - if (this.stylesheetInjectedViaApi) { return; } + if (this._stylesheetInjectedViaApi) { return; } if (injectDirectly || Popup._isOnExtensionPage()) { Popup.injectOuterStylesheet(css); @@ -146,7 +158,7 @@ class Popup { if (!css) { return; } try { await apiInjectStylesheet(css); - this.stylesheetInjectedViaApi = true; + this._stylesheetInjectedViaApi = true; } catch (e) { // NOP } @@ -154,15 +166,15 @@ class Popup { } setChildrenSupported(value) { - this.childrenSupported = value; + this._childrenSupported = value; } getContainer() { - return this.container; + return this._container; } getContainerRect() { - return this.container.getBoundingClientRect(); + return this._container.getBoundingClientRect(); } static injectOuterStylesheet(css) { @@ -188,53 +200,53 @@ class Popup { // Private functions _inject() { - if (this.injectPromise === null) { - this.injectPromise = this._createInjectPromise(); + if (this._injectPromise === null) { + this._injectPromise = this._createInjectPromise(); } - return this.injectPromise; + return this._injectPromise; } async _createInjectPromise() { try { - const {frameId} = await this.frameIdPromise; + const {frameId} = await this._frameIdPromise; if (typeof frameId === 'number') { - this.frameId = frameId; + this._frameId = frameId; } } catch (e) { // NOP } return new Promise((resolve) => { - const parentFrameId = (typeof this.frameId === 'number' ? this.frameId : null); - this.container.addEventListener('load', () => { + const parentFrameId = (typeof this._frameId === 'number' ? this._frameId : null); + this._container.addEventListener('load', () => { this._invokeApi('initialize', { - options: this.options, + options: this._options, popupInfo: { - id: this.id, - depth: this.depth, + id: this._id, + depth: this._depth, parentFrameId }, url: this.url, - childrenSupported: this.childrenSupported + childrenSupported: this._childrenSupported }); resolve(); }); this._observeFullscreen(); this._onFullscreenChanged(); - this.setCustomOuterCss(this.options.general.customPopupOuterCss, false); - this.isInjected = true; + this.setCustomOuterCss(this._options.general.customPopupOuterCss, false); + this._isInjected = true; }); } _isInitialized() { - return this.options !== null; + return this._options !== null; } async _show(elementRect, writingMode) { await this._inject(); - const optionsGeneral = this.options.general; - const container = this.container; + const optionsGeneral = this._options.general; + const container = this._container; const containerRect = container.getBoundingClientRect(); const getPosition = ( writingMode === 'horizontal-tb' || optionsGeneral.popupVerticalTextPosition === 'default' ? @@ -260,31 +272,31 @@ class Popup { container.style.height = `${height}px`; this._setVisible(true); - if (this.child !== null) { - this.child.hide(true); + if (this._child !== null) { + this._child.hide(true); } } _setVisible(visible) { - this.visible = visible; + this._visible = visible; this._updateVisibility(); } _updateVisibility() { - this.container.style.setProperty('visibility', this.isVisible() ? 'visible' : 'hidden', 'important'); + this._container.style.setProperty('visibility', this.isVisible() ? 'visible' : 'hidden', 'important'); } _focusParent() { - if (this.parent !== null) { + if (this._parent !== null) { // Chrome doesn't like focusing iframe without contentWindow. - const contentWindow = this.parent.container.contentWindow; + const contentWindow = this._parent.container.contentWindow; if (contentWindow !== null) { contentWindow.focus(); } } else { // Firefox doesn't like focusing window without first blurring the iframe. // this.container.contentWindow.blur() doesn't work on Firefox for some reason. - this.container.blur(); + this._container.blur(); // This is needed for Chrome. window.focus(); } @@ -299,7 +311,7 @@ class Popup { } _invokeApi(action, params={}) { - this.container.contentWindow.postMessage({action, params}, '*'); + this._container.contentWindow.postMessage({action, params}, '*'); } _observeFullscreen() { @@ -325,8 +337,8 @@ class Popup { _onFullscreenChanged() { const parent = (this._getFullscreenElement() || document.body || null); - if (parent !== null && this.container.parentNode !== parent) { - parent.appendChild(this.container); + if (parent !== null && this._container.parentNode !== parent) { + parent.appendChild(this._container); } } -- cgit v1.2.3 From 72ab6f1f454994442bd7bedc9fb35077f7a26327 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:44:03 -0500 Subject: Remove unused child getter --- ext/fg/js/popup-proxy.js | 4 ---- ext/fg/js/popup.js | 4 ---- 2 files changed, 8 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 0471705f..d52cc26d 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -34,10 +34,6 @@ class PopupProxy { return null; } - get child() { - return null; - } - get depth() { return this._depth; } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index bdc63b7f..af380ff8 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -50,10 +50,6 @@ class Popup { return this._parent; } - get child() { - return this._child; - } - get depth() { return this._depth; } -- cgit v1.2.3 From 29734ea6e95ad0c3a7e159a424dd587dc4966fa5 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:48:29 -0500 Subject: isVisible => isVisibleSync --- ext/bg/js/settings/popup-preview-frame.js | 2 +- ext/fg/js/popup-proxy-host.js | 2 +- ext/fg/js/popup.js | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index b2902af0..f65b119c 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -166,7 +166,7 @@ class SettingsPopupPreview { this.textSource = source; await this.frontend.showContentCompleted(); - if (this.frontend.popup.isVisible()) { + if (this.frontend.popup.isVisibleSync()) { this.popupShown = true; } diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index cb385cc2..2f06bb67 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -140,7 +140,7 @@ class PopupProxyHost { } static _popupCanShow(popup) { - return popup.parent === null || popup.parent.isVisible(); + return popup.parent === null || popup.parent.isVisibleSync(); } } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index af380ff8..4b8da979 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -70,7 +70,7 @@ class Popup { } hide(changeFocus) { - if (!this.isVisible()) { + if (!this.isVisibleSync()) { return; } @@ -84,7 +84,7 @@ class Popup { } async isVisibleAsync() { - return this.isVisible(); + return this.isVisibleSync(); } setVisibleOverride(visible) { @@ -93,7 +93,7 @@ class Popup { } async containsPoint(x, y) { - for (let popup = this; popup !== null && popup.isVisible(); popup = popup._child) { + for (let popup = this; popup !== null && popup.isVisibleSync(); popup = popup._child) { const rect = popup._container.getBoundingClientRect(); if (x >= rect.left && y >= rect.top && x < rect.right && y < rect.bottom) { return true; @@ -135,7 +135,7 @@ class Popup { parent._child = this; } - isVisible() { + isVisibleSync() { return this._isInjected && (this._visibleOverride !== null ? this._visibleOverride : this._visible); } @@ -279,7 +279,7 @@ class Popup { } _updateVisibility() { - this._container.style.setProperty('visibility', this.isVisible() ? 'visible' : 'hidden', 'important'); + this._container.style.setProperty('visibility', this.isVisibleSync() ? 'visible' : 'hidden', 'important'); } _focusParent() { -- cgit v1.2.3 From 0fb2357ec7388198134aed021a7014c0c0dda5c9 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:49:20 -0500 Subject: isVisibleAsync => isVisible --- ext/fg/js/frontend.js | 2 +- ext/fg/js/popup-proxy-host.js | 4 ++-- ext/fg/js/popup-proxy.js | 4 ++-- ext/fg/js/popup.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 2fa69c9d..d29e4e4c 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -67,7 +67,7 @@ class Frontend extends TextScanner { async onResize() { const textSource = this.textSourceCurrent; - if (textSource !== null && await this.popup.isVisibleAsync()) { + if (textSource !== null && await this.popup.isVisible()) { this._lastShowPromise = this.popup.showContent( textSource.getRect(), textSource.getWritingMode() diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 2f06bb67..9ff8a8c8 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -42,7 +42,7 @@ class PopupProxyHost { ['createNestedPopup', ({parentId}) => this._onApiCreateNestedPopup(parentId)], ['setOptions', ({id, options}) => this._onApiSetOptions(id, options)], ['hide', ({id, changeFocus}) => this._onApiHide(id, changeFocus)], - ['isVisibleAsync', ({id}) => this._onApiIsVisibleAsync(id)], + ['isVisible', ({id}) => this._onApiIsVisibleAsync(id)], ['setVisibleOverride', ({id, visible}) => this._onApiSetVisibleOverride(id, visible)], ['containsPoint', ({id, x, y}) => this._onApiContainsPoint(id, x, y)], ['showContent', ({id, elementRect, writingMode, type, details}) => this._onApiShowContent(id, elementRect, writingMode, type, details)], @@ -73,7 +73,7 @@ class PopupProxyHost { async _onApiIsVisibleAsync(id) { const popup = this._getPopup(id); - return await popup.isVisibleAsync(); + return await popup.isVisible(); } async _onApiSetVisibleOverride(id, visible) { diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index d52cc26d..e4081e90 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -60,9 +60,9 @@ class PopupProxy { return await this._invokeHostApi('hide', {id: this._id, changeFocus}); } - async isVisibleAsync() { + async isVisible() { const id = await this._getPopupId(); - return await this._invokeHostApi('isVisibleAsync', {id}); + return await this._invokeHostApi('isVisible', {id}); } async setVisibleOverride(visible) { diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 4b8da979..2026b7a5 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -83,7 +83,7 @@ class Popup { } } - async isVisibleAsync() { + async isVisible() { return this.isVisibleSync(); } -- cgit v1.2.3 From d6c64643b1f734905c50e599b3cf95f92c25175a Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 21:51:26 -0500 Subject: Don't return promises for frontend message handlers --- ext/fg/js/frontend.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index d29e4e4c..c8e112a7 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -200,6 +200,6 @@ Frontend._windowMessageHandlers = new Map([ ]); Frontend._runtimeMessageHandlers = new Map([ - ['optionsUpdate', (self) => self.updateOptions()], - ['popupSetVisibleOverride', (self, {visible}) => self.popup.setVisibleOverride(visible)] + ['optionsUpdate', (self) => { self.updateOptions(); }], + ['popupSetVisibleOverride', (self, {visible}) => { self.popup.setVisibleOverride(visible); }] ]); -- cgit v1.2.3 From 68a0293867423898181b0452d842a818ce77824a Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 22:21:01 -0500 Subject: Make PopupProxy functions async enabled status match Popup --- ext/fg/js/popup-proxy.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index e4081e90..0e6a88a7 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -53,11 +53,11 @@ class PopupProxy { return await this._invokeHostApi('setOptions', {id, options}); } - async hide(changeFocus) { + hide(changeFocus) { if (this._id === null) { return; } - return await this._invokeHostApi('hide', {id: this._id, changeFocus}); + this._invokeHostApi('hide', {id: this._id, changeFocus}); } async isVisible() { @@ -65,9 +65,11 @@ class PopupProxy { return await this._invokeHostApi('isVisible', {id}); } - async setVisibleOverride(visible) { - const id = await this._getPopupId(); - return await this._invokeHostApi('setVisibleOverride', {id, visible}); + setVisibleOverride(visible) { + if (this._id === null) { + return; + } + this._invokeHostApi('setVisibleOverride', {id, visible}); } async containsPoint(x, y) { @@ -88,11 +90,11 @@ class PopupProxy { return await this._invokeHostApi('setCustomCss', {id, css}); } - async clearAutoPlayTimer() { + clearAutoPlayTimer() { if (this._id === null) { return; } - return await this._invokeHostApi('clearAutoPlayTimer', {id: this._id}); + this._invokeHostApi('clearAutoPlayTimer', {id: this._id}); } // Private -- cgit v1.2.3 From 9557d8048bea524e22348a2ce5ce2d4a415102ee Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 15 Dec 2019 22:22:13 -0500 Subject: Fix undefined reference --- ext/fg/js/popup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 2026b7a5..4d00f629 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -285,7 +285,7 @@ class Popup { _focusParent() { if (this._parent !== null) { // Chrome doesn't like focusing iframe without contentWindow. - const contentWindow = this._parent.container.contentWindow; + const contentWindow = this._parent._container.contentWindow; if (contentWindow !== null) { contentWindow.focus(); } -- cgit v1.2.3 From ff1f256ffa18e8b463f7ce72ed9bd5b8c3c62ff7 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 17 Dec 2019 20:53:12 -0500 Subject: Only return unique elements from docElementsFromPoint This fixes #294 --- ext/fg/js/document.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js index 10dea7df..97e0d70c 100644 --- a/ext/fg/js/document.js +++ b/ext/fg/js/document.js @@ -97,7 +97,9 @@ function docImposterCreate(element, isTextarea) { function docElementsFromPoint(x, y, all) { if (all) { - return document.elementsFromPoint(x, y); + // document.elementsFromPoint can return duplicates which must be removed. + const elements = document.elementsFromPoint(x, y); + return elements.filter((e, i) => elements.indexOf(e) === i); } const e = document.elementFromPoint(x, y); -- cgit v1.2.3 From 4b5138b96ec2c85273d55cec6da41e36c5647e5d Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 17 Dec 2019 20:54:57 -0500 Subject: Override pointer-events with important --- ext/fg/js/document.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js index 97e0d70c..d54a2e44 100644 --- a/ext/fg/js/document.js +++ b/ext/fg/js/document.js @@ -321,7 +321,7 @@ function disableTransparentElement(elements, i, modifications) { if (isElementTransparent(element)) { const style = element.hasAttribute('style') ? element.getAttribute('style') : null; modifications.push({element, style}); - element.style.pointerEvents = 'none'; + element.style.setProperty('pointer-events', 'none', 'important'); return i; } } -- cgit v1.2.3 From cab2a3998169040a6a6d5bda828d4a8af5592cd6 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 17 Dec 2019 20:56:32 -0500 Subject: Simplify options passed to docRangeFromPoint --- ext/fg/js/document.js | 3 +-- ext/mixed/js/display.js | 2 +- ext/mixed/js/text-scanner.js | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js index d54a2e44..fa7e7cbc 100644 --- a/ext/fg/js/document.js +++ b/ext/fg/js/document.js @@ -106,8 +106,7 @@ function docElementsFromPoint(x, y, all) { return e !== null ? [e] : []; } -function docRangeFromPoint(x, y, options) { - const deepDomScan = options.scanning.deepDomScan; +function docRangeFromPoint(x, y, deepDomScan) { const elements = docElementsFromPoint(x, y, deepDomScan); let imposter = null; let imposterContainer = null; diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index ab0674a9..f3b5dd2a 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -144,7 +144,7 @@ class Display { try { e.preventDefault(); - const textSource = docRangeFromPoint(e.clientX, e.clientY, this.options); + const textSource = docRangeFromPoint(e.clientX, e.clientY, this.options.scanning.deepDomScan); if (textSource === null) { return false; } diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index ac5d68d1..9a739c7e 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -297,7 +297,7 @@ class TextScanner { } } - const textSource = docRangeFromPoint(x, y, this.options); + const textSource = docRangeFromPoint(x, y, this.options.scanning.deepDomScan); if (this.textSourceCurrent !== null && this.textSourceCurrent.equals(textSource)) { return; } -- cgit v1.2.3 From 2a95f1420f08b034ae8e12ecffed86aa6f33e53a Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 20 Dec 2019 13:36:54 -0500 Subject: Move optionsUpdate message handler into Yomichan class --- ext/bg/js/settings/main.js | 10 +--------- ext/fg/js/frontend.js | 2 +- ext/mixed/js/core.js | 11 +++++++++-- ext/mixed/js/display.js | 15 +-------------- 4 files changed, 12 insertions(+), 26 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index 78a5870c..870769e5 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -204,14 +204,6 @@ async function onOptionsUpdate({source}) { await formWrite(options); } -function onMessage({action, params}) { - switch (action) { - case 'optionsUpdate': - onOptionsUpdate(params); - break; - } -} - function showExtensionInformation() { const node = document.getElementById('extension-info'); @@ -235,7 +227,7 @@ async function onReady() { storageInfoInitialize(); - chrome.runtime.onMessage.addListener(onMessage); + yomichan.on('optionsUpdate', onOptionsUpdate); } $(document).ready(() => onReady()); diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index c8e112a7..1d63d928 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -54,6 +54,7 @@ class Frontend extends TextScanner { try { await this.updateOptions(); + yomichan.on('optionsUpdate', () => this.updateOptions()); chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); this.isPreparedPromiseResolve(); } catch (e) { @@ -200,6 +201,5 @@ Frontend._windowMessageHandlers = new Map([ ]); Frontend._runtimeMessageHandlers = new Map([ - ['optionsUpdate', (self) => { self.updateOptions(); }], ['popupSetVisibleOverride', (self, {visible}) => { self.popup.setVisibleOverride(visible); }] ]); diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index edb1f913..a3c8c0b0 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -232,10 +232,13 @@ class EventDispatcher { */ const yomichan = (() => { - class Yomichan { + class Yomichan extends EventDispatcher { constructor() { + super(); + this._messageHandlers = new Map([ - ['getUrl', this._onMessageGetUrl.bind(this)] + ['getUrl', this._onMessageGetUrl.bind(this)], + ['optionsUpdate', this._onMessageOptionsUpdate.bind(this)] ]); chrome.runtime.onMessage.addListener(this._onMessage.bind(this)); @@ -253,6 +256,10 @@ const yomichan = (() => { _onMessageGetUrl() { return {url: window.location.href}; } + + _onMessageOptionsUpdate({source}) { + this.trigger('optionsUpdate', {source}); + } } return new Yomichan(); diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index f3b5dd2a..089941a9 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -225,15 +225,6 @@ class Display { } } - onRuntimeMessage({action, params}, sender, callback) { - const handler = Display._runtimeMessageHandlers.get(action); - if (typeof handler !== 'function') { return false; } - - const result = handler(this, params, sender); - callback(result); - return false; - } - getOptionsContext() { throw new Error('Override me'); } @@ -244,7 +235,7 @@ class Display { async initialize(options=null) { await this.updateOptions(options); - chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); + yomichan.on('optionsUpdate', () => this.updateOptions(null)); } async updateOptions(options) { @@ -878,7 +869,3 @@ Display._onKeyDownHandlers = new Map([ return false; }] ]); - -Display._runtimeMessageHandlers = new Map([ - ['optionsUpdate', (self) => self.updateOptions(null)] -]); -- cgit v1.2.3 From 2519f99f54412933beed8b2c753c76662099f8e0 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 20 Dec 2019 13:44:33 -0500 Subject: Update how orphan state is observed --- ext/fg/js/float.js | 9 ++++++++- ext/fg/js/frontend.js | 8 +++++++- ext/mixed/js/api.js | 2 +- ext/mixed/js/core.js | 8 ++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 74bc58b0..8c7de906 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -27,17 +27,24 @@ class DisplayFloat extends Display { url: window.location.href }; + this._orphaned = false; + + yomichan.on('orphaned', () => this.onOrphaned()); window.addEventListener('message', (e) => this.onMessage(e), false); } onError(error) { - if (window.yomichan_orphaned) { + if (this._orphaned) { this.setContentOrphaned(); } else { logError(error, true); } } + onOrphaned() { + this._orphaned = true; + } + onSearchClear() { window.parent.postMessage('popupClose', '*'); } diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 1d63d928..6b41138f 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -37,6 +37,7 @@ class Frontend extends TextScanner { this.isPreparedPromiseResolve = null; this.isPreparedPromise = new Promise((resolve) => { this.isPreparedPromiseResolve = resolve; }); + this._orphaned = true; this._lastShowPromise = Promise.resolve(); } @@ -54,6 +55,7 @@ class Frontend extends TextScanner { try { await this.updateOptions(); + yomichan.on('orphaned', () => this.onOrphaned()); yomichan.on('optionsUpdate', () => this.updateOptions()); chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); this.isPreparedPromiseResolve(); @@ -93,6 +95,10 @@ class Frontend extends TextScanner { return false; } + onOrphaned() { + this._orphaned = true; + } + getMouseEventListeners() { return [ ...super.getMouseEventListeners(), @@ -122,7 +128,7 @@ class Frontend extends TextScanner { } } } catch (e) { - if (window.yomichan_orphaned) { + if (this._orphaned) { if (textSource !== null && this.options.scanning.modifier !== 'none') { this._lastShowPromise = this.popup.showContent( textSource.getRect(), diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js index ae74b8dc..18b360a3 100644 --- a/ext/mixed/js/api.js +++ b/ext/mixed/js/api.js @@ -115,8 +115,8 @@ function _apiInvoke(action, params={}) { } }); } catch (e) { - window.yomichan_orphaned = true; reject(e); + yomichan.triggerOrphaned(e); } }); } diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index a3c8c0b0..5e560a58 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -244,6 +244,14 @@ const yomichan = (() => { chrome.runtime.onMessage.addListener(this._onMessage.bind(this)); } + // Public + + triggerOrphaned(error) { + this.trigger('orphaned', {error}); + } + + // Private + _onMessage({action, params}, sender, callback) { const handler = this._messageHandlers.get(action); if (typeof handler !== 'function') { return false; } -- cgit v1.2.3 From 8c236cca44dd6d641f9b185e784cfae9641884cc Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 20 Dec 2019 23:20:22 -0500 Subject: Remove unused yomichan_frontend --- ext/bg/js/settings/popup-preview-frame.js | 1 - ext/fg/js/frontend-initialize.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index f65b119c..cabadced 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -48,7 +48,6 @@ class SettingsPopupPreview { // Overwrite frontend this.frontend = Frontend.create(); - window.yomichan_frontend = this.frontend; this.frontend.setEnabled = function () {}; this.frontend.searchClear = function () {}; diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js index 37a82faa..8ffdf528 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -17,4 +17,4 @@ */ -window.yomichan_frontend = Frontend.create(); +Frontend.create(); -- cgit v1.2.3 From b2cc694d95da9fc7b6b9d1e63a118b01877f25e1 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 20 Dec 2019 23:20:42 -0500 Subject: Replace window.yomichan_display with DisplayFloat.instance --- ext/fg/js/float.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 8c7de906..7375b68f 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -119,4 +119,4 @@ DisplayFloat._messageHandlers = new Map([ ['initialize', (self, {options, popupInfo, url, childrenSupported}) => self.initialize(options, popupInfo, url, childrenSupported)] ]); -window.yomichan_display = new DisplayFloat(); +DisplayFloat.instance = new DisplayFloat(); -- cgit v1.2.3 From 7ae05840772c04f1263f851432e21bd5a313b320 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 21 Dec 2019 13:19:31 -0500 Subject: Update initialization --- ext/bg/js/settings/popup-preview-frame.js | 9 +++++---- ext/fg/js/frontend-initialize.js | 11 ++++++++++- ext/fg/js/frontend.js | 18 ------------------ 3 files changed, 15 insertions(+), 23 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index cabadced..53077a83 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -47,14 +47,15 @@ class SettingsPopupPreview { window.apiOptionsGet = (...args) => this.apiOptionsGet(...args); // Overwrite frontend - this.frontend = Frontend.create(); + const popup = PopupProxyHost.instance.createPopup(null, 0); + popup.setChildrenSupported(false); + + this.frontend = new Frontend(popup); this.frontend.setEnabled = function () {}; this.frontend.searchClear = function () {}; - this.frontend.popup.setChildrenSupported(false); - - await this.frontend.isPrepared(); + await this.frontend.prepare(); // Overwrite popup Popup.injectOuterStylesheet = (...args) => this.popupInjectOuterStylesheet(...args); diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js index 8ffdf528..4fef3a2e 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -17,4 +17,13 @@ */ -Frontend.create(); +async function main() { + const data = window.frontendInitializationData || {}; + const {id, depth=0, parentFrameId, ignoreNodes, url, proxy=false} = data; + + const popup = proxy ? new PopupProxy(depth + 1, id, parentFrameId, url) : PopupProxyHost.instance.createPopup(null, depth); + const frontend = new Frontend(popup, ignoreNodes); + await frontend.prepare(); +} + +main(); diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 6b41138f..6239a057 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -34,23 +34,10 @@ class Frontend extends TextScanner { url: popup.url }; - this.isPreparedPromiseResolve = null; - this.isPreparedPromise = new Promise((resolve) => { this.isPreparedPromiseResolve = resolve; }); - this._orphaned = true; this._lastShowPromise = Promise.resolve(); } - static create() { - const data = window.frontendInitializationData || {}; - const {id, depth=0, parentFrameId, ignoreNodes, url, proxy=false} = data; - - const popup = proxy ? new PopupProxy(depth + 1, id, parentFrameId, url) : PopupProxyHost.instance.createPopup(null, depth); - const frontend = new Frontend(popup, ignoreNodes); - frontend.prepare(); - return frontend; - } - async prepare() { try { await this.updateOptions(); @@ -58,16 +45,11 @@ class Frontend extends TextScanner { yomichan.on('orphaned', () => this.onOrphaned()); yomichan.on('optionsUpdate', () => this.updateOptions()); chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); - this.isPreparedPromiseResolve(); } catch (e) { this.onError(e); } } - isPrepared() { - return this.isPreparedPromise; - } - async onResize() { const textSource = this.textSourceCurrent; if (textSource !== null && await this.popup.isVisible()) { -- cgit v1.2.3 From a2175f2c293ef2de41a58acdd9adc202b0302d67 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 21 Dec 2019 13:27:32 -0500 Subject: Move PopupProxyHost initialization --- ext/bg/js/settings/popup-preview-frame.js | 5 ++++- ext/fg/js/frontend-initialize.js | 8 +++++++- ext/fg/js/popup-proxy-host.js | 8 -------- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 53077a83..6d017275 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -47,7 +47,10 @@ class SettingsPopupPreview { window.apiOptionsGet = (...args) => this.apiOptionsGet(...args); // Overwrite frontend - const popup = PopupProxyHost.instance.createPopup(null, 0); + const popupHost = new PopupProxyHost(); + await popupHost.prepare(); + + const popup = popupHost.createPopup(null, 0); popup.setChildrenSupported(false); this.frontend = new Frontend(popup); diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js index 4fef3a2e..c153b5b6 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -21,7 +21,13 @@ async function main() { const data = window.frontendInitializationData || {}; const {id, depth=0, parentFrameId, ignoreNodes, url, proxy=false} = data; - const popup = proxy ? new PopupProxy(depth + 1, id, parentFrameId, url) : PopupProxyHost.instance.createPopup(null, depth); + let popupHost = null; + if (!proxy) { + popupHost = new PopupProxyHost(); + await popupHost.prepare(); + } + + const popup = proxy ? new PopupProxy(depth + 1, id, parentFrameId, url) : popupHost.createPopup(null, depth); const frontend = new Frontend(popup, ignoreNodes); await frontend.prepare(); } diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 9ff8a8c8..e13d6f05 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -27,12 +27,6 @@ class PopupProxyHost { // Public functions - static create() { - const popupProxyHost = new PopupProxyHost(); - popupProxyHost.prepare(); - return popupProxyHost; - } - async prepare() { this._frameIdPromise = apiFrameInformationGet(); const {frameId} = await this._frameIdPromise; @@ -143,5 +137,3 @@ class PopupProxyHost { return popup.parent === null || popup.parent.isVisibleSync(); } } - -PopupProxyHost.instance = PopupProxyHost.create(); -- cgit v1.2.3 From 362e317a5d282cd19ec22531e3a70020d542919e Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 21 Dec 2019 14:30:13 -0500 Subject: Change FrontendApiSender.callbacks to be a map --- ext/fg/js/frontend-api-sender.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'ext/fg/js') diff --git a/ext/fg/js/frontend-api-sender.js b/ext/fg/js/frontend-api-sender.js index af998a8f..b7c2c57c 100644 --- a/ext/fg/js/frontend-api-sender.js +++ b/ext/fg/js/frontend-api-sender.js @@ -22,7 +22,7 @@ class FrontendApiSender { this.senderId = FrontendApiSender.generateId(16); this.ackTimeout = 3000; // 3 seconds this.responseTimeout = 10000; // 10 seconds - this.callbacks = {}; + this.callbacks = new Map(); this.disconnected = false; this.nextId = 0; @@ -43,7 +43,7 @@ class FrontendApiSender { return new Promise((resolve, reject) => { const info = {id, resolve, reject, ack: false, timer: null}; - this.callbacks[id] = info; + this.callbacks.set(id, info); info.timer = setTimeout(() => this.onError(id, 'Timeout (ack)'), this.ackTimeout); this.port.postMessage({id, action, params, target, senderId: this.senderId}); @@ -71,19 +71,18 @@ class FrontendApiSender { onDisconnect() { this.disconnected = true; - const ids = Object.keys(this.callbacks); - for (const id of ids) { + for (const id of this.callbacks.keys()) { this.onError(id, 'Disconnected'); } } onAck(id) { - if (!hasOwn(this.callbacks, id)) { + const info = this.callbacks.get(id); + if (typeof info === 'undefined') { console.warn(`ID ${id} not found for ack`); return; } - const info = this.callbacks[id]; if (info.ack) { console.warn(`Request ${id} already ack'd`); return; @@ -95,18 +94,18 @@ class FrontendApiSender { } onResult(id, data) { - if (!hasOwn(this.callbacks, id)) { + const info = this.callbacks.get(id); + if (typeof info === 'undefined') { console.warn(`ID ${id} not found`); return; } - const info = this.callbacks[id]; if (!info.ack) { console.warn(`Request ${id} not ack'd`); return; } - delete this.callbacks[id]; + this.callbacks.delete(id); clearTimeout(info.timer); info.timer = null; @@ -118,9 +117,9 @@ class FrontendApiSender { } onError(id, reason) { - if (!hasOwn(this.callbacks, id)) { return; } - const info = this.callbacks[id]; - delete this.callbacks[id]; + const info = this.callbacks.get(id); + if (typeof info === 'undefined') { return; } + this.callbacks.delete(id); info.timer = null; info.reject(new Error(reason)); } -- cgit v1.2.3 From 899ef167d184fedb072b727e0dc04f2579b08e1f Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 1 Jan 2020 12:00:00 -0500 Subject: Update copyright --- LICENSE | 2 +- ext/bg/css/settings.css | 2 +- ext/bg/js/anki.js | 2 +- ext/bg/js/api.js | 2 +- ext/bg/js/audio.js | 2 +- ext/bg/js/backend-api-forwarder.js | 2 +- ext/bg/js/backend.js | 2 +- ext/bg/js/conditions.js | 2 +- ext/bg/js/context.js | 2 +- ext/bg/js/database.js | 2 +- ext/bg/js/deinflector.js | 2 +- ext/bg/js/dictionary.js | 2 +- ext/bg/js/handlebars.js | 2 +- ext/bg/js/json-schema.js | 2 +- ext/bg/js/mecab.js | 2 +- ext/bg/js/options.js | 2 +- ext/bg/js/page-exit-prevention.js | 2 +- ext/bg/js/profile-conditions.js | 2 +- ext/bg/js/request.js | 2 +- ext/bg/js/search-frontend.js | 2 +- ext/bg/js/search-query-parser.js | 2 +- ext/bg/js/search.js | 2 +- ext/bg/js/settings/anki-templates.js | 2 +- ext/bg/js/settings/anki.js | 2 +- ext/bg/js/settings/audio-ui.js | 2 +- ext/bg/js/settings/audio.js | 2 +- ext/bg/js/settings/backup.js | 2 +- ext/bg/js/settings/conditions-ui.js | 2 +- ext/bg/js/settings/dictionaries.js | 2 +- ext/bg/js/settings/main.js | 2 +- ext/bg/js/settings/popup-preview-frame.js | 2 +- ext/bg/js/settings/popup-preview.js | 2 +- ext/bg/js/settings/profiles.js | 2 +- ext/bg/js/settings/storage.js | 2 +- ext/bg/js/translator.js | 2 +- ext/bg/js/util.js | 2 +- ext/bg/legal.html | 2 +- ext/fg/css/client.css | 2 +- ext/fg/js/document.js | 2 +- ext/fg/js/float.js | 2 +- ext/fg/js/frontend-api-receiver.js | 2 +- ext/fg/js/frontend-api-sender.js | 2 +- ext/fg/js/frontend-initialize.js | 2 +- ext/fg/js/frontend.js | 2 +- ext/fg/js/popup-nested.js | 2 +- ext/fg/js/popup-proxy-host.js | 2 +- ext/fg/js/popup-proxy.js | 2 +- ext/fg/js/popup.js | 2 +- ext/fg/js/source.js | 2 +- ext/mixed/css/display-dark.css | 2 +- ext/mixed/css/display-default.css | 2 +- ext/mixed/css/display.css | 2 +- ext/mixed/js/api.js | 2 +- ext/mixed/js/audio.js | 2 +- ext/mixed/js/core.js | 2 +- ext/mixed/js/display-context.js | 2 +- ext/mixed/js/display.js | 2 +- ext/mixed/js/dom.js | 2 +- ext/mixed/js/japanese.js | 2 +- ext/mixed/js/scroll.js | 2 +- ext/mixed/js/text-scanner.js | 2 +- ext/mixed/js/timer.js | 2 +- 62 files changed, 62 insertions(+), 62 deletions(-) (limited to 'ext/fg/js') diff --git a/LICENSE b/LICENSE index 811a6915..266e6069 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2016-2019 Alex Yatskov +Copyright 2016-2020 Alex Yatskov This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ext/bg/css/settings.css b/ext/bg/css/settings.css index 8adae47c..ee9d18a1 100644 --- a/ext/bg/css/settings.css +++ b/ext/bg/css/settings.css @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/anki.js b/ext/bg/js/anki.js index 17b93620..48ed66bf 100644 --- a/ext/bg/js/anki.js +++ b/ext/bg/js/anki.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 9f37ccd8..8ad8d0bb 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/audio.js b/ext/bg/js/audio.js index b39b6c9d..0fc2148d 100644 --- a/ext/bg/js/audio.js +++ b/ext/bg/js/audio.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Alex Yatskov + * Copyright (C) 2017-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/backend-api-forwarder.js b/ext/bg/js/backend-api-forwarder.js index db4d30b9..0a387e08 100644 --- a/ext/bg/js/backend-api-forwarder.js +++ b/ext/bg/js/backend-api-forwarder.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 3c8a068b..2060f414 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/conditions.js b/ext/bg/js/conditions.js index c0f0f301..d3d0b465 100644 --- a/ext/bg/js/conditions.js +++ b/ext/bg/js/conditions.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/context.js b/ext/bg/js/context.js index 0b21f662..84368256 100644 --- a/ext/bg/js/context.js +++ b/ext/bg/js/context.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Alex Yatskov + * Copyright (C) 2017-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index 5aee2311..9c44f240 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/deinflector.js b/ext/bg/js/deinflector.js index 51f4723c..752a0959 100644 --- a/ext/bg/js/deinflector.js +++ b/ext/bg/js/deinflector.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/dictionary.js b/ext/bg/js/dictionary.js index 28705513..43971f8a 100644 --- a/ext/bg/js/dictionary.js +++ b/ext/bg/js/dictionary.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/handlebars.js b/ext/bg/js/handlebars.js index b57ba738..7e4b7b8d 100644 --- a/ext/bg/js/handlebars.js +++ b/ext/bg/js/handlebars.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/json-schema.js b/ext/bg/js/json-schema.js index 3238bc3e..d56f8ef9 100644 --- a/ext/bg/js/json-schema.js +++ b/ext/bg/js/json-schema.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/mecab.js b/ext/bg/js/mecab.js index 62111f73..33f9949e 100644 --- a/ext/bg/js/mecab.js +++ b/ext/bg/js/mecab.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index 84e74bd8..63e7c023 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/page-exit-prevention.js b/ext/bg/js/page-exit-prevention.js index aee4e3c2..4143a835 100644 --- a/ext/bg/js/page-exit-prevention.js +++ b/ext/bg/js/page-exit-prevention.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/profile-conditions.js b/ext/bg/js/profile-conditions.js index ebc6680a..20350f4b 100644 --- a/ext/bg/js/profile-conditions.js +++ b/ext/bg/js/profile-conditions.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/request.js b/ext/bg/js/request.js index 7d73d49b..6d05f66e 100644 --- a/ext/bg/js/request.js +++ b/ext/bg/js/request.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Alex Yatskov + * Copyright (C) 2017-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/search-frontend.js b/ext/bg/js/search-frontend.js index fdf7219c..2cf7f5a7 100644 --- a/ext/bg/js/search-frontend.js +++ b/ext/bg/js/search-frontend.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index fc95ddff..fec21d3b 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index cbfce6a5..439cde40 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/anki-templates.js b/ext/bg/js/settings/anki-templates.js index 281383a7..4644214b 100644 --- a/ext/bg/js/settings/anki-templates.js +++ b/ext/bg/js/settings/anki-templates.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/anki.js b/ext/bg/js/settings/anki.js index 25096531..ccce16fe 100644 --- a/ext/bg/js/settings/anki.js +++ b/ext/bg/js/settings/anki.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/audio-ui.js b/ext/bg/js/settings/audio-ui.js index de3be083..dc968628 100644 --- a/ext/bg/js/settings/audio-ui.js +++ b/ext/bg/js/settings/audio-ui.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/audio.js b/ext/bg/js/settings/audio.js index d36876df..5809375c 100644 --- a/ext/bg/js/settings/audio.js +++ b/ext/bg/js/settings/audio.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/backup.js b/ext/bg/js/settings/backup.js index d278b718..3a4d1fd2 100644 --- a/ext/bg/js/settings/backup.js +++ b/ext/bg/js/settings/backup.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/conditions-ui.js b/ext/bg/js/settings/conditions-ui.js index cc9db087..a186a5be 100644 --- a/ext/bg/js/settings/conditions-ui.js +++ b/ext/bg/js/settings/conditions-ui.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index 717d02cb..330e935a 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index 3c7d6fce..70650d8b 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 6d017275..7be3466d 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/popup-preview.js b/ext/bg/js/settings/popup-preview.js index d8579eb1..ba0c979d 100644 --- a/ext/bg/js/settings/popup-preview.js +++ b/ext/bg/js/settings/popup-preview.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/profiles.js b/ext/bg/js/settings/profiles.js index 946d6944..61fe9bff 100644 --- a/ext/bg/js/settings/profiles.js +++ b/ext/bg/js/settings/profiles.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/settings/storage.js b/ext/bg/js/settings/storage.js index 51ca6855..c040a041 100644 --- a/ext/bg/js/settings/storage.js +++ b/ext/bg/js/settings/storage.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alex Yatskov + * Copyright (C) 2019-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index 0f3d0aa0..d6f62fd8 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index 4c989642..09c45c08 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Alex Yatskov + * Copyright (C) 2016-2020 Alex Yatskov * Author: Alex Yatskov * * This program is free software: you can redistribute it and/or modify diff --git a/ext/bg/legal.html b/ext/bg/legal.html index 082239d7..4c9029a0 100644 --- a/ext/bg/legal.html +++ b/ext/bg/legal.html @@ -17,7 +17,7 @@

Yomichan License

-Copyright (C) 2016-2019  Alex Yatskov
+Copyright (C) 2016-2020  Alex Yatskov
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/ext/fg/css/client.css b/ext/fg/css/client.css
index 633c88ef..6f52b676 100644
--- a/ext/fg/css/client.css
+++ b/ext/fg/css/client.css
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016  Alex Yatskov 
+ * Copyright (C) 2016-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js
index fa7e7cbc..d6ef5f29 100644
--- a/ext/fg/js/document.js
+++ b/ext/fg/js/document.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017  Alex Yatskov 
+ * Copyright (C) 2016-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js
index 7375b68f..302bcda1 100644
--- a/ext/fg/js/float.js
+++ b/ext/fg/js/float.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017  Alex Yatskov 
+ * Copyright (C) 2016-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/frontend-api-receiver.js b/ext/fg/js/frontend-api-receiver.js
index 8d5e52ee..72490f2c 100644
--- a/ext/fg/js/frontend-api-receiver.js
+++ b/ext/fg/js/frontend-api-receiver.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/frontend-api-sender.js b/ext/fg/js/frontend-api-sender.js
index b7c2c57c..b90310d6 100644
--- a/ext/fg/js/frontend-api-sender.js
+++ b/ext/fg/js/frontend-api-sender.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js
index c153b5b6..d819688f 100644
--- a/ext/fg/js/frontend-initialize.js
+++ b/ext/fg/js/frontend-initialize.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019  Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js
index 6239a057..0ddcecf1 100644
--- a/ext/fg/js/frontend.js
+++ b/ext/fg/js/frontend.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017  Alex Yatskov 
+ * Copyright (C) 2016-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/popup-nested.js b/ext/fg/js/popup-nested.js
index 3df469fe..df619141 100644
--- a/ext/fg/js/popup-nested.js
+++ b/ext/fg/js/popup-nested.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js
index e13d6f05..3cc8a132 100644
--- a/ext/fg/js/popup-proxy-host.js
+++ b/ext/fg/js/popup-proxy-host.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js
index 0e6a88a7..c29e9e55 100644
--- a/ext/fg/js/popup-proxy.js
+++ b/ext/fg/js/popup-proxy.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js
index 4d00f629..5d445dba 100644
--- a/ext/fg/js/popup.js
+++ b/ext/fg/js/popup.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017  Alex Yatskov 
+ * Copyright (C) 2016-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/fg/js/source.js b/ext/fg/js/source.js
index a84feed4..cea6623d 100644
--- a/ext/fg/js/source.js
+++ b/ext/fg/js/source.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017  Alex Yatskov 
+ * Copyright (C) 2016-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/css/display-dark.css b/ext/mixed/css/display-dark.css
index 681d248c..236f36c4 100644
--- a/ext/mixed/css/display-dark.css
+++ b/ext/mixed/css/display-dark.css
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019  Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/css/display-default.css b/ext/mixed/css/display-default.css
index add0a9c8..b563d831 100644
--- a/ext/mixed/css/display-default.css
+++ b/ext/mixed/css/display-default.css
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019  Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/css/display.css b/ext/mixed/css/display.css
index 70fffdc1..5a7cbf5d 100644
--- a/ext/mixed/css/display.css
+++ b/ext/mixed/css/display.css
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016  Alex Yatskov 
+ * Copyright (C) 2016-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js
index dc901efc..c801baa3 100644
--- a/ext/mixed/js/api.js
+++ b/ext/mixed/js/api.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017  Alex Yatskov 
+ * Copyright (C) 2016-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/js/audio.js b/ext/mixed/js/audio.js
index 35f283a4..d9a72a12 100644
--- a/ext/mixed/js/audio.js
+++ b/ext/mixed/js/audio.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019  Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js
index 5e560a58..9e2b419e 100644
--- a/ext/mixed/js/core.js
+++ b/ext/mixed/js/core.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019  Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/js/display-context.js b/ext/mixed/js/display-context.js
index 4b399881..45c2a823 100644
--- a/ext/mixed/js/display-context.js
+++ b/ext/mixed/js/display-context.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019  Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js
index 089941a9..513d2596 100644
--- a/ext/mixed/js/display.js
+++ b/ext/mixed/js/display.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017  Alex Yatskov 
+ * Copyright (C) 2017-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/js/dom.js b/ext/mixed/js/dom.js
index 4e4d49e3..87448b89 100644
--- a/ext/mixed/js/dom.js
+++ b/ext/mixed/js/dom.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019  Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/js/japanese.js b/ext/mixed/js/japanese.js
index ea1c0065..b046019c 100644
--- a/ext/mixed/js/japanese.js
+++ b/ext/mixed/js/japanese.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016  Alex Yatskov 
+ * Copyright (C) 2016-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/js/scroll.js b/ext/mixed/js/scroll.js
index 824fd92b..869f0945 100644
--- a/ext/mixed/js/scroll.js
+++ b/ext/mixed/js/scroll.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019  Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js
index 9a739c7e..455c756f 100644
--- a/ext/mixed/js/text-scanner.js
+++ b/ext/mixed/js/text-scanner.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019  Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
diff --git a/ext/mixed/js/timer.js b/ext/mixed/js/timer.js
index 87ab62a7..bfa2e087 100644
--- a/ext/mixed/js/timer.js
+++ b/ext/mixed/js/timer.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019  Alex Yatskov 
+ * Copyright (C) 2019-2020  Alex Yatskov 
  * Author: Alex Yatskov 
  *
  * This program is free software: you can redistribute it and/or modify
-- 
cgit v1.2.3


From 0d7ccf25b88abc414358e7cb435a227d43ba548f Mon Sep 17 00:00:00 2001
From: toasted-nutbread 
Date: Wed, 1 Jan 2020 12:00:31 -0500
Subject: Update license info URL

---
 LICENSE                                   | 2 +-
 ext/bg/css/settings.css                   | 2 +-
 ext/bg/js/anki.js                         | 2 +-
 ext/bg/js/api.js                          | 2 +-
 ext/bg/js/audio.js                        | 2 +-
 ext/bg/js/backend-api-forwarder.js        | 2 +-
 ext/bg/js/backend.js                      | 2 +-
 ext/bg/js/conditions.js                   | 2 +-
 ext/bg/js/context.js                      | 2 +-
 ext/bg/js/database.js                     | 2 +-
 ext/bg/js/deinflector.js                  | 2 +-
 ext/bg/js/dictionary.js                   | 2 +-
 ext/bg/js/handlebars.js                   | 2 +-
 ext/bg/js/json-schema.js                  | 2 +-
 ext/bg/js/mecab.js                        | 2 +-
 ext/bg/js/options.js                      | 2 +-
 ext/bg/js/page-exit-prevention.js         | 2 +-
 ext/bg/js/profile-conditions.js           | 2 +-
 ext/bg/js/request.js                      | 2 +-
 ext/bg/js/search-frontend.js              | 2 +-
 ext/bg/js/search-query-parser.js          | 2 +-
 ext/bg/js/search.js                       | 2 +-
 ext/bg/js/settings/anki-templates.js      | 2 +-
 ext/bg/js/settings/anki.js                | 2 +-
 ext/bg/js/settings/audio-ui.js            | 2 +-
 ext/bg/js/settings/audio.js               | 2 +-
 ext/bg/js/settings/backup.js              | 2 +-
 ext/bg/js/settings/conditions-ui.js       | 2 +-
 ext/bg/js/settings/dictionaries.js        | 2 +-
 ext/bg/js/settings/main.js                | 2 +-
 ext/bg/js/settings/popup-preview-frame.js | 2 +-
 ext/bg/js/settings/popup-preview.js       | 2 +-
 ext/bg/js/settings/profiles.js            | 2 +-
 ext/bg/js/settings/storage.js             | 2 +-
 ext/bg/js/translator.js                   | 2 +-
 ext/bg/js/util.js                         | 2 +-
 ext/bg/legal.html                         | 2 +-
 ext/fg/css/client.css                     | 2 +-
 ext/fg/js/document.js                     | 2 +-
 ext/fg/js/float.js                        | 2 +-
 ext/fg/js/frontend-api-receiver.js        | 2 +-
 ext/fg/js/frontend-api-sender.js          | 2 +-
 ext/fg/js/frontend-initialize.js          | 2 +-
 ext/fg/js/frontend.js                     | 2 +-
 ext/fg/js/popup-nested.js                 | 2 +-
 ext/fg/js/popup-proxy-host.js             | 2 +-
 ext/fg/js/popup-proxy.js                  | 2 +-
 ext/fg/js/popup.js                        | 2 +-
 ext/fg/js/source.js                       | 2 +-
 ext/mixed/css/display-dark.css            | 2 +-
 ext/mixed/css/display-default.css         | 2 +-
 ext/mixed/css/display.css                 | 2 +-
 ext/mixed/js/api.js                       | 2 +-
 ext/mixed/js/audio.js                     | 2 +-
 ext/mixed/js/core.js                      | 2 +-
 ext/mixed/js/display-context.js           | 2 +-
 ext/mixed/js/display.js                   | 2 +-
 ext/mixed/js/dom.js                       | 2 +-
 ext/mixed/js/japanese.js                  | 2 +-
 ext/mixed/js/scroll.js                    | 2 +-
 ext/mixed/js/text-scanner.js              | 2 +-
 ext/mixed/js/timer.js                     | 2 +-
 62 files changed, 62 insertions(+), 62 deletions(-)

(limited to 'ext/fg/js')

diff --git a/LICENSE b/LICENSE
index 266e6069..f8531a9f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -11,4 +11,4 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program.  If not, see .
+along with this program.  If not, see .
diff --git a/ext/bg/css/settings.css b/ext/bg/css/settings.css
index ee9d18a1..63cead6b 100644
--- a/ext/bg/css/settings.css
+++ b/ext/bg/css/settings.css
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/anki.js b/ext/bg/js/anki.js
index 48ed66bf..10a07061 100644
--- a/ext/bg/js/anki.js
+++ b/ext/bg/js/anki.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js
index 8ad8d0bb..906aaa30 100644
--- a/ext/bg/js/api.js
+++ b/ext/bg/js/api.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/audio.js b/ext/bg/js/audio.js
index 0fc2148d..36ac413b 100644
--- a/ext/bg/js/audio.js
+++ b/ext/bg/js/audio.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/backend-api-forwarder.js b/ext/bg/js/backend-api-forwarder.js
index 0a387e08..170a6b32 100644
--- a/ext/bg/js/backend-api-forwarder.js
+++ b/ext/bg/js/backend-api-forwarder.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js
index 2060f414..28b0201e 100644
--- a/ext/bg/js/backend.js
+++ b/ext/bg/js/backend.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/conditions.js b/ext/bg/js/conditions.js
index d3d0b465..d4d1c0e0 100644
--- a/ext/bg/js/conditions.js
+++ b/ext/bg/js/conditions.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/context.js b/ext/bg/js/context.js
index 84368256..834174bf 100644
--- a/ext/bg/js/context.js
+++ b/ext/bg/js/context.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js
index 9c44f240..42a143f3 100644
--- a/ext/bg/js/database.js
+++ b/ext/bg/js/database.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/deinflector.js b/ext/bg/js/deinflector.js
index 752a0959..33b2a8b3 100644
--- a/ext/bg/js/deinflector.js
+++ b/ext/bg/js/deinflector.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/dictionary.js b/ext/bg/js/dictionary.js
index 43971f8a..92adc532 100644
--- a/ext/bg/js/dictionary.js
+++ b/ext/bg/js/dictionary.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/handlebars.js b/ext/bg/js/handlebars.js
index 7e4b7b8d..6d1581be 100644
--- a/ext/bg/js/handlebars.js
+++ b/ext/bg/js/handlebars.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/json-schema.js b/ext/bg/js/json-schema.js
index d56f8ef9..5d596a8b 100644
--- a/ext/bg/js/json-schema.js
+++ b/ext/bg/js/json-schema.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/mecab.js b/ext/bg/js/mecab.js
index 33f9949e..8bcbb91c 100644
--- a/ext/bg/js/mecab.js
+++ b/ext/bg/js/mecab.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js
index 63e7c023..8021672b 100644
--- a/ext/bg/js/options.js
+++ b/ext/bg/js/options.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/page-exit-prevention.js b/ext/bg/js/page-exit-prevention.js
index 4143a835..3a320db3 100644
--- a/ext/bg/js/page-exit-prevention.js
+++ b/ext/bg/js/page-exit-prevention.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/profile-conditions.js b/ext/bg/js/profile-conditions.js
index 20350f4b..1fd78e5d 100644
--- a/ext/bg/js/profile-conditions.js
+++ b/ext/bg/js/profile-conditions.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/request.js b/ext/bg/js/request.js
index 6d05f66e..b584c9a9 100644
--- a/ext/bg/js/request.js
+++ b/ext/bg/js/request.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/search-frontend.js b/ext/bg/js/search-frontend.js
index 2cf7f5a7..2fe50a13 100644
--- a/ext/bg/js/search-frontend.js
+++ b/ext/bg/js/search-frontend.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js
index fec21d3b..0b3eccbd 100644
--- a/ext/bg/js/search-query-parser.js
+++ b/ext/bg/js/search-query-parser.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js
index 439cde40..a4103ef2 100644
--- a/ext/bg/js/search.js
+++ b/ext/bg/js/search.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 class DisplaySearch extends Display {
diff --git a/ext/bg/js/settings/anki-templates.js b/ext/bg/js/settings/anki-templates.js
index 4644214b..5e74358f 100644
--- a/ext/bg/js/settings/anki-templates.js
+++ b/ext/bg/js/settings/anki-templates.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/settings/anki.js b/ext/bg/js/settings/anki.js
index ccce16fe..5f7989b8 100644
--- a/ext/bg/js/settings/anki.js
+++ b/ext/bg/js/settings/anki.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/settings/audio-ui.js b/ext/bg/js/settings/audio-ui.js
index dc968628..711c2291 100644
--- a/ext/bg/js/settings/audio-ui.js
+++ b/ext/bg/js/settings/audio-ui.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/settings/audio.js b/ext/bg/js/settings/audio.js
index 5809375c..cff3f521 100644
--- a/ext/bg/js/settings/audio.js
+++ b/ext/bg/js/settings/audio.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/settings/backup.js b/ext/bg/js/settings/backup.js
index 3a4d1fd2..becdc568 100644
--- a/ext/bg/js/settings/backup.js
+++ b/ext/bg/js/settings/backup.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/settings/conditions-ui.js b/ext/bg/js/settings/conditions-ui.js
index a186a5be..4d041451 100644
--- a/ext/bg/js/settings/conditions-ui.js
+++ b/ext/bg/js/settings/conditions-ui.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js
index 330e935a..ed171ae9 100644
--- a/ext/bg/js/settings/dictionaries.js
+++ b/ext/bg/js/settings/dictionaries.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js
index 70650d8b..56828a15 100644
--- a/ext/bg/js/settings/main.js
+++ b/ext/bg/js/settings/main.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 function getOptionsMutable(optionsContext) {
diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js
index 7be3466d..2b727cbd 100644
--- a/ext/bg/js/settings/popup-preview-frame.js
+++ b/ext/bg/js/settings/popup-preview-frame.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/settings/popup-preview.js b/ext/bg/js/settings/popup-preview.js
index ba0c979d..0d20471e 100644
--- a/ext/bg/js/settings/popup-preview.js
+++ b/ext/bg/js/settings/popup-preview.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/settings/profiles.js b/ext/bg/js/settings/profiles.js
index 61fe9bff..c4e68b53 100644
--- a/ext/bg/js/settings/profiles.js
+++ b/ext/bg/js/settings/profiles.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 let currentProfileIndex = 0;
diff --git a/ext/bg/js/settings/storage.js b/ext/bg/js/settings/storage.js
index c040a041..6c10f665 100644
--- a/ext/bg/js/settings/storage.js
+++ b/ext/bg/js/settings/storage.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js
index d6f62fd8..7473c6ad 100644
--- a/ext/bg/js/translator.js
+++ b/ext/bg/js/translator.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js
index 09c45c08..333e814b 100644
--- a/ext/bg/js/util.js
+++ b/ext/bg/js/util.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 function utilIsolate(value) {
diff --git a/ext/bg/legal.html b/ext/bg/legal.html
index 4c9029a0..c1e606d7 100644
--- a/ext/bg/legal.html
+++ b/ext/bg/legal.html
@@ -30,7 +30,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
+along with this program.  If not, see <https://www.gnu.org/licenses/>.
 

EDRDG License

diff --git a/ext/fg/css/client.css b/ext/fg/css/client.css
index 6f52b676..b9c59da7 100644
--- a/ext/fg/css/client.css
+++ b/ext/fg/css/client.css
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js
index d6ef5f29..e068e3ba 100644
--- a/ext/fg/js/document.js
+++ b/ext/fg/js/document.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js
index 302bcda1..513d246b 100644
--- a/ext/fg/js/float.js
+++ b/ext/fg/js/float.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/frontend-api-receiver.js b/ext/fg/js/frontend-api-receiver.js
index 72490f2c..642d96df 100644
--- a/ext/fg/js/frontend-api-receiver.js
+++ b/ext/fg/js/frontend-api-receiver.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/frontend-api-sender.js b/ext/fg/js/frontend-api-sender.js
index b90310d6..93c2e593 100644
--- a/ext/fg/js/frontend-api-sender.js
+++ b/ext/fg/js/frontend-api-sender.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js
index d819688f..9c923fea 100644
--- a/ext/fg/js/frontend-initialize.js
+++ b/ext/fg/js/frontend-initialize.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js
index 0ddcecf1..034d9075 100644
--- a/ext/fg/js/frontend.js
+++ b/ext/fg/js/frontend.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/popup-nested.js b/ext/fg/js/popup-nested.js
index df619141..bacf3b93 100644
--- a/ext/fg/js/popup-nested.js
+++ b/ext/fg/js/popup-nested.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js
index 3cc8a132..c4f0c6ff 100644
--- a/ext/fg/js/popup-proxy-host.js
+++ b/ext/fg/js/popup-proxy-host.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js
index c29e9e55..ae0cffad 100644
--- a/ext/fg/js/popup-proxy.js
+++ b/ext/fg/js/popup-proxy.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js
index 5d445dba..7a0c6133 100644
--- a/ext/fg/js/popup.js
+++ b/ext/fg/js/popup.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/fg/js/source.js b/ext/fg/js/source.js
index cea6623d..5cdf47b5 100644
--- a/ext/fg/js/source.js
+++ b/ext/fg/js/source.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 // \u200c (Zero-width non-joiner) appears on Google Docs from Chrome 76 onwards
diff --git a/ext/mixed/css/display-dark.css b/ext/mixed/css/display-dark.css
index 236f36c4..e26c72aa 100644
--- a/ext/mixed/css/display-dark.css
+++ b/ext/mixed/css/display-dark.css
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/css/display-default.css b/ext/mixed/css/display-default.css
index b563d831..ac237e79 100644
--- a/ext/mixed/css/display-default.css
+++ b/ext/mixed/css/display-default.css
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/css/display.css b/ext/mixed/css/display.css
index 5a7cbf5d..7a00bccb 100644
--- a/ext/mixed/css/display.css
+++ b/ext/mixed/css/display.css
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js
index c801baa3..8ed1d996 100644
--- a/ext/mixed/js/api.js
+++ b/ext/mixed/js/api.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/js/audio.js b/ext/mixed/js/audio.js
index d9a72a12..b0c5fa82 100644
--- a/ext/mixed/js/audio.js
+++ b/ext/mixed/js/audio.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js
index 9e2b419e..54e8a9d2 100644
--- a/ext/mixed/js/core.js
+++ b/ext/mixed/js/core.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/js/display-context.js b/ext/mixed/js/display-context.js
index 45c2a823..c11c2342 100644
--- a/ext/mixed/js/display-context.js
+++ b/ext/mixed/js/display-context.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js
index 513d2596..e756f948 100644
--- a/ext/mixed/js/display.js
+++ b/ext/mixed/js/display.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/js/dom.js b/ext/mixed/js/dom.js
index 87448b89..807a48e1 100644
--- a/ext/mixed/js/dom.js
+++ b/ext/mixed/js/dom.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/js/japanese.js b/ext/mixed/js/japanese.js
index b046019c..23b2bd36 100644
--- a/ext/mixed/js/japanese.js
+++ b/ext/mixed/js/japanese.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/js/scroll.js b/ext/mixed/js/scroll.js
index 869f0945..5829d294 100644
--- a/ext/mixed/js/scroll.js
+++ b/ext/mixed/js/scroll.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js
index 455c756f..a05dd2ee 100644
--- a/ext/mixed/js/text-scanner.js
+++ b/ext/mixed/js/text-scanner.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
diff --git a/ext/mixed/js/timer.js b/ext/mixed/js/timer.js
index bfa2e087..1caf7a05 100644
--- a/ext/mixed/js/timer.js
+++ b/ext/mixed/js/timer.js
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
+ * along with this program.  If not, see .
  */
 
 
-- 
cgit v1.2.3