From 65dfb855fb23d8279367651ab650f3347aa236ac Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 11 Feb 2020 22:21:55 -0500 Subject: Fix undefined id --- ext/fg/js/popup-proxy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg') diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 4cacee53..63aa6bbe 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -69,7 +69,7 @@ class PopupProxy { if (this._id === null) { return; } - this._invokeHostApi('setVisibleOverride', {id, visible}); + this._invokeHostApi('setVisibleOverride', {id: this._id, visible}); } async containsPoint(x, y) { -- cgit v1.2.3 From e2ac478cb7635cbd15d0033bd2c486689a7b4e67 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 11 Feb 2020 22:19:47 -0500 Subject: Define more globals --- .eslintrc.json | 1 + ext/bg/js/backend.js | 2 +- ext/bg/js/clipboard-monitor.js | 1 + ext/bg/js/search-query-parser-generator.js | 1 + ext/bg/js/search-query-parser.js | 2 +- ext/bg/js/search.js | 2 +- ext/bg/js/settings/dictionaries.js | 2 +- ext/fg/js/document.js | 1 + ext/fg/js/float.js | 1 + ext/fg/js/frontend-initialize.js | 1 + ext/fg/js/frontend.js | 1 + ext/fg/js/popup-nested.js | 1 + ext/fg/js/popup-proxy-host.js | 1 + ext/fg/js/popup-proxy.js | 1 + ext/fg/js/popup.js | 1 + 15 files changed, 15 insertions(+), 4 deletions(-) (limited to 'ext/fg') diff --git a/.eslintrc.json b/.eslintrc.json index 9b1a19b3..f502479d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -49,6 +49,7 @@ "stringReverse": "readonly", "promiseTimeout": "readonly", "stringReplaceAsync": "readonly", + "parseUrl": "readonly", "EventDispatcher": "readonly", "EXTENSION_IS_BROWSER_EDGE": "readonly" } diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 1a1dc735..7b2ec46d 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -23,7 +23,7 @@ requestText, requestJson, optionsLoad dictConfigured, dictTermsSort, dictEnabledSet, dictNoteFormat audioGetUrl, audioInject jpConvertReading, jpDistributeFuriganaInflected, jpKatakanaToHiragana -Translator, AnkiConnect, AnkiNull, Mecab, BackendApiForwarder, JsonSchema*/ +Translator, AnkiConnect, AnkiNull, Mecab, BackendApiForwarder, JsonSchema, ClipboardMonitor*/ class Backend { constructor() { diff --git a/ext/bg/js/clipboard-monitor.js b/ext/bg/js/clipboard-monitor.js index b4a27fa2..c2f41385 100644 --- a/ext/bg/js/clipboard-monitor.js +++ b/ext/bg/js/clipboard-monitor.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiClipboardGet, jpIsStringPartiallyJapanese*/ class ClipboardMonitor { constructor() { diff --git a/ext/bg/js/search-query-parser-generator.js b/ext/bg/js/search-query-parser-generator.js index 8d71890b..f842644e 100644 --- a/ext/bg/js/search-query-parser-generator.js +++ b/ext/bg/js/search-query-parser-generator.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiGetQueryParserTemplatesHtml, TemplateHandler*/ class QueryParserGenerator { constructor() { diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index ff0dbaef..49c0bb34 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/*global apiTermsFind, apiOptionsSet, apiTextParse, apiTextParseMecab, apiTemplateRender, TextScanner*/ +/*global apiTermsFind, apiOptionsSet, apiTextParse, apiTextParseMecab, apiTemplateRender, TextScanner, QueryParserGenerator*/ class QueryParser extends TextScanner { constructor(search) { diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 312d1de4..50ec146f 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -17,7 +17,7 @@ */ /*global jpIsStringPartiallyJapanese, apiOptionsSet, apiTermsFind, apiClipboardGet, apiGetEnvironmentInfo -Display, QueryParser*/ +Display, QueryParser, ClipboardMonitor*/ class DisplaySearch extends Display { constructor() { diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index c80aac73..fb459404 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/*global getOptionsContext, getOptionsMutable, getOptionsFullMutable, settingsSaveOptions, apiOptionsGetFull +/*global getOptionsContext, getOptionsMutable, getOptionsFullMutable, settingsSaveOptions, apiOptionsGetFull, apiOptionsGet utilBackgroundIsolate, utilDatabaseDeleteDictionary, utilDatabaseGetDictionaryInfo, utilDatabaseGetDictionaryCounts utilDatabasePurge, utilDatabaseImport storageUpdateStats, storageEstimate diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js index 71654b29..7284cdd1 100644 --- a/ext/fg/js/document.js +++ b/ext/fg/js/document.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global TextSourceElement, TextSourceRange, DOM*/ const REGEX_TRANSPARENT_COLOR = /rgba\s*\([^)]*,\s*0(?:\.0+)?\s*\)/; diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 8d61d8f6..d31b8336 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global popupNestedInitialize, Display*/ class DisplayFloat extends Display { constructor() { diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js index 9c923fea..c32e97d4 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global PopupProxyHost, PopupProxy, Frontend*/ async function main() { const data = window.frontendInitializationData || {}; diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 2286bf19..3611d44e 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiGetZoom, apiOptionsGet, apiTermsFind, apiKanjiFind, docSentenceExtract, TextScanner*/ class Frontend extends TextScanner { constructor(popup, ignoreNodes) { diff --git a/ext/fg/js/popup-nested.js b/ext/fg/js/popup-nested.js index 3f3c945e..3e5f5b80 100644 --- a/ext/fg/js/popup-nested.js +++ b/ext/fg/js/popup-nested.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiOptionsGet*/ let popupNestedInitialized = false; diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 427172c6..98729796 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiFrameInformationGet, FrontendApiReceiver, Popup*/ class PopupProxyHost { constructor() { diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 63aa6bbe..db6dffb1 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global FrontendApiSender*/ class PopupProxy { constructor(depth, parentId, parentFrameId, url) { diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index e7dae93e..0b142dda 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiInjectStylesheet*/ class Popup { constructor(id, depth, frameIdPromise) { -- cgit v1.2.3 From df37acd17f9459c17185552f11dc4cc424e01958 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Thu, 13 Feb 2020 01:59:26 +0200 Subject: rename display initialize methods to prepare --- ext/bg/js/search.js | 2 +- ext/fg/js/float.js | 30 +++++++++++++++--------------- ext/mixed/js/display.js | 24 ++++++++++++------------ 3 files changed, 28 insertions(+), 28 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 6641255f..86ed675a 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -47,7 +47,7 @@ class DisplaySearch extends Display { async prepare() { try { - await this.initialize(); + await super.prepare(); await this.queryParser.prepare(); diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 8d61d8f6..3766d5a4 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -33,6 +33,20 @@ class DisplayFloat extends Display { window.addEventListener('message', (e) => this.onMessage(e), false); } + async prepare(options, popupInfo, url, childrenSupported, scale) { + await super.prepare(options); + + const {id, depth, parentFrameId} = popupInfo; + this.optionsContext.depth = depth; + this.optionsContext.url = url; + + if (childrenSupported) { + popupNestedInitialize(id, depth, parentFrameId, url); + } + + this.setContentScale(scale); + } + onError(error) { if (this._orphaned) { this.setContent('orphaned'); @@ -92,20 +106,6 @@ class DisplayFloat extends Display { setContentScale(scale) { document.body.style.fontSize = `${scale}em`; } - - async initialize(options, popupInfo, url, childrenSupported, scale) { - await super.initialize(options); - - const {id, depth, parentFrameId} = popupInfo; - this.optionsContext.depth = depth; - this.optionsContext.url = url; - - if (childrenSupported) { - popupNestedInitialize(id, depth, parentFrameId, url); - } - - this.setContentScale(scale); - } } DisplayFloat._onKeyDownHandlers = new Map([ @@ -122,7 +122,7 @@ 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, scale}) => self.initialize(options, popupInfo, url, childrenSupported, scale)], + ['initialize', (self, {options, popupInfo, url, childrenSupported, scale}) => self.prepare(options, popupInfo, url, childrenSupported, scale)], ['setContentScale', (self, {scale}) => self.setContentScale(scale)] ]); diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index cee63d9b..8dea625d 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -43,6 +43,16 @@ class Display { this.setInteractive(true); } + async prepare(options=null) { + await this.displayGenerator.prepare(); + await this.updateOptions(options); + yomichan.on('optionsUpdate', () => this.updateOptions(null)); + } + + isPrepared() { + return this.options !== null; + } + onError(_error) { throw new Error('Override me'); } @@ -238,16 +248,6 @@ class Display { throw new Error('Override me'); } - isInitialized() { - return this.options !== null; - } - - async initialize(options=null) { - await this.displayGenerator.prepare(); - await this.updateOptions(options); - yomichan.on('optionsUpdate', () => this.updateOptions(null)); - } - async updateOptions(options) { this.options = options ? options : await apiOptionsGet(this.getOptionsContext()); this.updateDocumentOptions(this.options); @@ -358,7 +358,7 @@ class Display { async setContentTerms(definitions, context, token) { if (!context) { throw new Error('Context expected'); } - if (!this.isInitialized()) { return; } + if (!this.isPrepared()) { return; } this.setEventListenersActive(false); @@ -419,7 +419,7 @@ class Display { async setContentKanji(definitions, context, token) { if (!context) { throw new Error('Context expected'); } - if (!this.isInitialized()) { return; } + if (!this.isPrepared()) { return; } this.setEventListenersActive(false); -- cgit v1.2.3 From c0225f1f844376e5f61222a4d8186a2c914026eb Mon Sep 17 00:00:00 2001 From: siikamiika Date: Thu, 13 Feb 2020 13:18:54 +0200 Subject: notify popup about initialization --- ext/fg/js/float.js | 2 ++ ext/fg/js/popup.js | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'ext/fg') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 3766d5a4..8871160f 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -45,6 +45,8 @@ class DisplayFloat extends Display { } this.setContentScale(scale); + + window.parent.postMessage('initialized', '*'); } onError(error) { diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index e7dae93e..6cfe49e5 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -45,6 +45,8 @@ class Popup { this._container.style.height = '0px'; this._updateVisibility(); + + window.addEventListener('message', (e) => this.onMessage(e), false); } // Public properties @@ -129,6 +131,18 @@ class Popup { } } + onMessage(e) { + const action = e.data; + const handler = Popup._windowMessageHandlers.get(action); + if (typeof handler !== 'function') { return; } + + handler(this); + } + + setInitialized() { + throw new Error('Override me'); + } + // Popup-only public functions setParent(parent) { @@ -237,7 +251,7 @@ class Popup { childrenSupported: this._childrenSupported, scale: this._contentScale }); - resolve(); + this.setInitialized = resolve; }); this._observeFullscreen(); this._onFullscreenChanged(); @@ -535,4 +549,8 @@ class Popup { } } +Popup._windowMessageHandlers = new Map([ + ['initialized', (self) => self.setInitialized()] +]); + Popup.outerStylesheet = null; -- cgit v1.2.3 From 38a6433a46a4259666864a57c5adbd58cb59db86 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Thu, 13 Feb 2020 15:04:10 +0200 Subject: remove isInjected checks from Popup --- ext/fg/js/popup.js | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'ext/fg') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 6cfe49e5..ad4e5181 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -27,8 +27,6 @@ class Popup { this._child = null; this._childrenSupported = true; this._injectPromise = null; - this._isInjected = false; - this._isInjectedAndLoaded = false; this._visible = false; this._visibleOverride = null; this._options = null; @@ -119,16 +117,12 @@ class Popup { } clearAutoPlayTimer() { - if (this._isInjectedAndLoaded) { - this._invokeApi('clearAutoPlayTimer'); - } + this._invokeApi('clearAutoPlayTimer'); } setContentScale(scale) { this._contentScale = scale; - if (this._isInjectedAndLoaded) { - this._invokeApi('setContentScale', {scale}); - } + this._invokeApi('setContentScale', {scale}); } onMessage(e) { @@ -160,7 +154,7 @@ class Popup { } isVisibleSync() { - return this._isInjected && (this._visibleOverride !== null ? this._visibleOverride : this._visible); + return (this._visibleOverride !== null ? this._visibleOverride : this._visible); } updateTheme() { @@ -239,7 +233,6 @@ class Popup { return new Promise((resolve) => { const parentFrameId = (typeof this._frameId === 'number' ? this._frameId : null); this._container.addEventListener('load', () => { - this._isInjectedAndLoaded = true; this._invokeApi('initialize', { options: this._options, popupInfo: { @@ -256,7 +249,6 @@ class Popup { this._observeFullscreen(); this._onFullscreenChanged(); this.setCustomOuterCss(this._options.general.customPopupOuterCss, false); - this._isInjected = true; }); } @@ -341,10 +333,9 @@ class Popup { } _invokeApi(action, params={}) { - if (!this._isInjectedAndLoaded) { - throw new Error('Frame not loaded'); + if (this._container.contentWindow) { + this._container.contentWindow.postMessage({action, params}, '*'); } - this._container.contentWindow.postMessage({action, params}, '*'); } _observeFullscreen() { -- cgit v1.2.3 From 810a7e7d92d15412974810702d954de60453dd31 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Fri, 14 Feb 2020 02:33:54 +0200 Subject: use sendMessage to notify about initialization --- ext/fg/js/float.js | 2 +- ext/fg/js/frontend.js | 3 ++- ext/fg/js/popup-proxy-host.js | 8 +++++++- ext/fg/js/popup-proxy.js | 5 +++++ ext/fg/js/popup.js | 18 ++---------------- 5 files changed, 17 insertions(+), 19 deletions(-) (limited to 'ext/fg') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 8871160f..b42ab8ee 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -46,7 +46,7 @@ class DisplayFloat extends Display { this.setContentScale(scale); - window.parent.postMessage('initialized', '*'); + apiForward('popupSetDisplayInitialized'); } onError(error) { diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 2286bf19..571bbf91 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -243,5 +243,6 @@ Frontend._windowMessageHandlers = new Map([ ]); Frontend._runtimeMessageHandlers = new Map([ - ['popupSetVisibleOverride', (self, {visible}) => { self.popup.setVisibleOverride(visible); }] + ['popupSetVisibleOverride', (self, {visible}) => { self.popup.setVisibleOverride(visible); }], + ['popupSetDisplayInitialized', (self) => { self.popup.setDisplayInitialized(); }] ]); diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 427172c6..8ea70857 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -42,7 +42,8 @@ class PopupProxyHost { ['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)], - ['setContentScale', ({id, scale}) => this._onApiSetContentScale(id, scale)] + ['setContentScale', ({id, scale}) => this._onApiSetContentScale(id, scale)], + ['setDisplayInitialized', ({id}) => this._onApiSetDisplayInitialized(id)] ])); } @@ -103,6 +104,11 @@ class PopupProxyHost { return popup.setContentScale(scale); } + async _onApiSetDisplayInitialized(id) { + const popup = this._getPopup(id); + return popup.setDisplayInitialized(); + } + // Private functions _createPopupInternal(parentId, depth) { diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 63aa6bbe..f1743064 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -102,6 +102,11 @@ class PopupProxy { this._invokeHostApi('setContentScale', {id, scale}); } + async setDisplayInitialized() { + const id = await this._getPopupId(); + this._invokeHostApi('setDisplayInitialized', {id}); + } + // Private _getPopupId() { diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index ad4e5181..b8233cc2 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -43,8 +43,6 @@ class Popup { this._container.style.height = '0px'; this._updateVisibility(); - - window.addEventListener('message', (e) => this.onMessage(e), false); } // Public properties @@ -125,15 +123,7 @@ class Popup { this._invokeApi('setContentScale', {scale}); } - onMessage(e) { - const action = e.data; - const handler = Popup._windowMessageHandlers.get(action); - if (typeof handler !== 'function') { return; } - - handler(this); - } - - setInitialized() { + setDisplayInitialized() { throw new Error('Override me'); } @@ -244,7 +234,7 @@ class Popup { childrenSupported: this._childrenSupported, scale: this._contentScale }); - this.setInitialized = resolve; + this.setDisplayInitialized = resolve; }); this._observeFullscreen(); this._onFullscreenChanged(); @@ -540,8 +530,4 @@ class Popup { } } -Popup._windowMessageHandlers = new Map([ - ['initialized', (self) => self.setInitialized()] -]); - Popup.outerStylesheet = null; -- cgit v1.2.3 From 6194f9f585e268f2bbe8a3e70ac4deb59bc6a5e6 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 13 Feb 2020 20:44:08 -0500 Subject: Comma --- ext/fg/float.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg') diff --git a/ext/fg/float.html b/ext/fg/float.html index bec5ae68..082755f5 100644 --- a/ext/fg/float.html +++ b/ext/fg/float.html @@ -35,7 +35,7 @@

Yomichan Updated!

The Yomichan extension has been updated to a new version! In order to continue - viewing definitions on this page you must reload this tab or restart your browser. + viewing definitions on this page, you must reload this tab or restart your browser.

-- cgit v1.2.3 From 89cb98e4d14ad4980133f8e8e44b15d56c3ebea5 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 14 Feb 2020 21:50:17 -0500 Subject: Add global apiForward --- ext/fg/js/float.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 418c69b6..46d1314e 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/*global popupNestedInitialize, Display*/ +/*global popupNestedInitialize, apiForward, Display*/ class DisplayFloat extends Display { constructor() { -- cgit v1.2.3 From faf15c08aa6777d1ae2d112c55659e08d53156c6 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 14 Feb 2020 22:34:44 -0500 Subject: Rename optionsUpdate event to optionsUpdated Past tense better indicates that the options were changed, but no data is being included as part of the event. It is also more consistent with the other event names the yomichan object currently provides. --- ext/bg/js/backend.js | 2 +- ext/bg/js/settings/main.js | 4 ++-- ext/fg/js/frontend.js | 2 +- ext/mixed/js/core.js | 6 +++--- ext/mixed/js/display.js | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index da50bade..d1a34f82 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -88,7 +88,7 @@ class Backend { const callback = () => this.checkLastError(chrome.runtime.lastError); chrome.tabs.query({}, (tabs) => { for (const tab of tabs) { - chrome.tabs.sendMessage(tab.id, {action: 'optionsUpdate', params: {source}}, callback); + chrome.tabs.sendMessage(tab.id, {action: 'optionsUpdated', params: {source}}, callback); } }); } diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index 1ba4a7ef..c6683427 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -242,7 +242,7 @@ async function settingsSaveOptions() { await apiOptionsSave(source); } -async function onOptionsUpdate({source}) { +async function onOptionsUpdated({source}) { const thisSource = await settingsGetSource(); if (source === thisSource) { return; } @@ -274,7 +274,7 @@ async function onReady() { storageInfoInitialize(); - yomichan.on('optionsUpdate', onOptionsUpdate); + yomichan.on('optionsUpdated', onOptionsUpdated); } $(document).ready(() => onReady()); diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index a620fb03..c3050514 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -56,7 +56,7 @@ class Frontend extends TextScanner { } yomichan.on('orphaned', () => this.onOrphaned()); - yomichan.on('optionsUpdate', () => this.updateOptions()); + yomichan.on('optionsUpdated', () => this.updateOptions()); yomichan.on('zoomChanged', (e) => this.onZoomChanged(e)); chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index c273bb87..2dd9cf40 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -248,7 +248,7 @@ const yomichan = (() => { this._messageHandlers = new Map([ ['getUrl', this._onMessageGetUrl.bind(this)], - ['optionsUpdate', this._onMessageOptionsUpdate.bind(this)], + ['optionsUpdated', this._onMessageOptionsUpdated.bind(this)], ['zoomChanged', this._onMessageZoomChanged.bind(this)] ]); @@ -276,8 +276,8 @@ const yomichan = (() => { return {url: window.location.href}; } - _onMessageOptionsUpdate({source}) { - this.trigger('optionsUpdate', {source}); + _onMessageOptionsUpdated({source}) { + this.trigger('optionsUpdated', {source}); } _onMessageZoomChanged({oldZoomFactor, newZoomFactor}) { diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index 90b7aaf3..045ce906 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -52,7 +52,7 @@ class Display { const displayGeneratorPromise = this.displayGenerator.prepare(); const updateOptionsPromise = this.updateOptions(options); await Promise.all([displayGeneratorPromise, updateOptionsPromise]); - yomichan.on('optionsUpdate', () => this.updateOptions(null)); + yomichan.on('optionsUpdated', () => this.updateOptions(null)); } onError(_error) { -- cgit v1.2.3 From 10ec165f14e829f73c232b531ea2981c043b17c3 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 15 Feb 2020 20:52:21 -0500 Subject: Check type of other for equals functions Fixes #361 --- ext/fg/js/source.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'ext/fg') diff --git a/ext/fg/js/source.js b/ext/fg/js/source.js index 11d3ff0e..fa785ec4 100644 --- a/ext/fg/js/source.js +++ b/ext/fg/js/source.js @@ -82,7 +82,11 @@ class TextSourceRange { } equals(other) { - if (other === null) { + if (!( + typeof other === 'object' && + other !== null && + other instanceof TextSourceRange + )) { return false; } if (this.imposterSourceElement !== null) { @@ -409,6 +413,12 @@ class TextSourceElement { } equals(other) { - return other && other.element === this.element && other.content === this.content; + return ( + typeof other === 'object' && + other !== null && + other instanceof TextSourceElement && + other.element === this.element && + other.content === this.content + ); } } -- cgit v1.2.3 From 912d59d3dfefde5738b4244d74d944795edcc02c Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 15 Feb 2020 22:39:09 -0500 Subject: Obscure the iframe's URL from the host page --- ext/fg/js/popup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index d077b1f8..55f3e0aa 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -39,7 +39,6 @@ class Popup { this._container.className = 'yomichan-float'; this._container.addEventListener('mousedown', (e) => e.stopPropagation()); this._container.addEventListener('scroll', (e) => e.stopPropagation()); - this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html')); this._container.style.width = '0px'; this._container.style.height = '0px'; @@ -240,6 +239,7 @@ class Popup { this._observeFullscreen(); this._onFullscreenChanged(); this.setCustomOuterCss(this._options.general.customPopupOuterCss, false); + this._container.contentDocument.location.href = chrome.runtime.getURL('/fg/float.html'); }); } -- cgit v1.2.3 From 42f1c2463c8051d9cbbcacd43f06922c2f11ec71 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 11:59:17 -0500 Subject: Move generateId function --- ext/fg/js/frontend-api-sender.js | 10 +--------- ext/mixed/js/core.js | 10 ++++++++++ 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'ext/fg') diff --git a/ext/fg/js/frontend-api-sender.js b/ext/fg/js/frontend-api-sender.js index 93c2e593..8dc6aaf3 100644 --- a/ext/fg/js/frontend-api-sender.js +++ b/ext/fg/js/frontend-api-sender.js @@ -19,7 +19,7 @@ class FrontendApiSender { constructor() { - this.senderId = FrontendApiSender.generateId(16); + this.senderId = yomichan.generateId(16); this.ackTimeout = 3000; // 3 seconds this.responseTimeout = 10000; // 10 seconds this.callbacks = new Map(); @@ -123,12 +123,4 @@ class FrontendApiSender { info.timer = null; info.reject(new Error(reason)); } - - static generateId(length) { - let id = ''; - for (let i = 0; i < length; ++i) { - id += Math.floor(Math.random() * 256).toString(16).padStart(2, '0'); - } - return id; - } } diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index 2dd9cf40..b6ecb48b 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -257,6 +257,16 @@ const yomichan = (() => { // Public + generateId(length) { + const array = new Uint8Array(length); + window.crypto.getRandomValues(array); + let id = ''; + for (const value of array) { + id += value.toString(16).padStart(2, '0'); + } + return id; + } + triggerOrphaned(error) { this.trigger('orphaned', {error}); } -- cgit v1.2.3 From b5d32c73e657c882ba6f70b79d4a5e214684f563 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 12:23:20 -0500 Subject: Simplify process to wait for iframe prepare completion --- ext/fg/js/float.js | 6 +++--- ext/fg/js/frontend.js | 3 +-- ext/fg/js/popup-proxy-host.js | 8 +------- ext/fg/js/popup-proxy.js | 5 ----- ext/fg/js/popup.js | 30 +++++++++++++++++++++++------- 5 files changed, 28 insertions(+), 24 deletions(-) (limited to 'ext/fg') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 46d1314e..35a78d48 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -34,7 +34,7 @@ class DisplayFloat extends Display { window.addEventListener('message', (e) => this.onMessage(e), false); } - async prepare(options, popupInfo, url, childrenSupported, scale) { + async prepare(options, popupInfo, url, childrenSupported, scale, uniqueId) { await super.prepare(options); const {id, depth, parentFrameId} = popupInfo; @@ -47,7 +47,7 @@ class DisplayFloat extends Display { this.setContentScale(scale); - apiForward('popupSetDisplayInitialized'); + apiForward('popupPrepareCompleted', {uniqueId}); } onError(error) { @@ -125,7 +125,7 @@ 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, scale}) => self.prepare(options, popupInfo, url, childrenSupported, scale)], + ['prepare', (self, {options, popupInfo, url, childrenSupported, scale, uniqueId}) => self.prepare(options, popupInfo, url, childrenSupported, scale, uniqueId)], ['setContentScale', (self, {scale}) => self.setContentScale(scale)] ]); diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index c3050514..67045241 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -244,6 +244,5 @@ Frontend._windowMessageHandlers = new Map([ ]); Frontend._runtimeMessageHandlers = new Map([ - ['popupSetVisibleOverride', (self, {visible}) => { self.popup.setVisibleOverride(visible); }], - ['popupSetDisplayInitialized', (self) => { self.popup.setDisplayInitialized(); }] + ['popupSetVisibleOverride', (self, {visible}) => { self.popup.setVisibleOverride(visible); }] ]); diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index f6a3d451..98729796 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -43,8 +43,7 @@ class PopupProxyHost { ['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)], - ['setContentScale', ({id, scale}) => this._onApiSetContentScale(id, scale)], - ['setDisplayInitialized', ({id}) => this._onApiSetDisplayInitialized(id)] + ['setContentScale', ({id, scale}) => this._onApiSetContentScale(id, scale)] ])); } @@ -105,11 +104,6 @@ class PopupProxyHost { return popup.setContentScale(scale); } - async _onApiSetDisplayInitialized(id) { - const popup = this._getPopup(id); - return popup.setDisplayInitialized(); - } - // Private functions _createPopupInternal(parentId, depth) { diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 6f3c0f1c..db6dffb1 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -103,11 +103,6 @@ class PopupProxy { this._invokeHostApi('setContentScale', {id, scale}); } - async setDisplayInitialized() { - const id = await this._getPopupId(); - this._invokeHostApi('setDisplayInitialized', {id}); - } - // Private _getPopupId() { diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 55f3e0aa..5f6a777b 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -123,10 +123,6 @@ class Popup { this._invokeApi('setContentScale', {scale}); } - setDisplayInitialized() { - throw new Error('Override me'); - } - // Popup-only public functions setParent(parent) { @@ -223,7 +219,10 @@ class Popup { return new Promise((resolve) => { const parentFrameId = (typeof this._frameId === 'number' ? this._frameId : null); this._container.addEventListener('load', () => { - this._invokeApi('initialize', { + const uniqueId = yomichan.generateId(32); + Popup._listenForDisplayPrepareCompleted(uniqueId, resolve); + + this._invokeApi('prepare', { options: this._options, popupInfo: { id: this._id, @@ -232,9 +231,9 @@ class Popup { }, url: this.url, childrenSupported: this._childrenSupported, - scale: this._contentScale + scale: this._contentScale, + uniqueId }); - this.setDisplayInitialized = resolve; }); this._observeFullscreen(); this._onFullscreenChanged(); @@ -357,6 +356,23 @@ class Popup { } } + static _listenForDisplayPrepareCompleted(uniqueId, resolve) { + const runtimeMessageCallback = ({action, params}, sender, callback) => { + if ( + action === 'popupPrepareCompleted' && + typeof params === 'object' && + params !== null && + params.uniqueId === uniqueId + ) { + chrome.runtime.onMessage.removeListener(runtimeMessageCallback); + callback(); + resolve(); + return false; + } + }; + chrome.runtime.onMessage.addListener(runtimeMessageCallback); + } + static _getPositionForHorizontalText(elementRect, width, height, viewport, offsetScale, optionsGeneral) { const preferBelow = (optionsGeneral.popupHorizontalTextPosition === 'below'); const horizontalOffset = optionsGeneral.popupHorizontalOffset * offsetScale; -- cgit v1.2.3 From 6df5220e0249fa06865034a44c690f7c640a38ed Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 12:23:40 -0500 Subject: Prevent multiple prepare calls --- ext/fg/js/float.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ext/fg') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 35a78d48..440a9731 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -29,12 +29,16 @@ class DisplayFloat extends Display { }; this._orphaned = false; + this._prepareInvoked = false; yomichan.on('orphaned', () => this.onOrphaned()); window.addEventListener('message', (e) => this.onMessage(e), false); } async prepare(options, popupInfo, url, childrenSupported, scale, uniqueId) { + if (this._prepareInvoked) { return; } + this._prepareInvoked = true; + await super.prepare(options); const {id, depth, parentFrameId} = popupInfo; -- cgit v1.2.3 From 36605f74c3d48a98500d198636112454b36063f6 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 18:47:46 -0500 Subject: Undo "Obscure the iframe's URL from the host page" There are some additional issues which cause the frame to be reset to about:blank on certain occasions which must be fixed before this can be used. --- ext/fg/js/popup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 5f6a777b..211b649e 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -238,7 +238,7 @@ class Popup { this._observeFullscreen(); this._onFullscreenChanged(); this.setCustomOuterCss(this._options.general.customPopupOuterCss, false); - this._container.contentDocument.location.href = chrome.runtime.getURL('/fg/float.html'); + this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html')); }); } -- cgit v1.2.3 From 5d3c13ee98c49de8b3bd57892d93bd4eca2cf7ee Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 18:52:04 -0500 Subject: Tweak how fullscreen changes are observed --- ext/fg/js/popup.js | 56 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 21 deletions(-) (limited to 'ext/fg') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 211b649e..0fc40475 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -42,6 +42,8 @@ class Popup { this._container.style.width = '0px'; this._container.style.height = '0px'; + this._fullscreenEventListeners = new EventListenerCollection(); + this._updateVisibility(); } @@ -242,6 +244,36 @@ class Popup { }); } + _observeFullscreen(observe) { + if (!observe) { + this._fullscreenEventListeners.removeAllEventListeners(); + return; + } + + if (this._fullscreenEventListeners.size > 0) { + // Already observing + return; + } + + const fullscreenEvents = [ + 'fullscreenchange', + 'MSFullscreenChange', + 'mozfullscreenchange', + 'webkitfullscreenchange' + ]; + const onFullscreenChanged = () => this._onFullscreenChanged(); + for (const eventName of fullscreenEvents) { + this._fullscreenEventListeners.addEventListener(document, eventName, onFullscreenChanged, false); + } + } + + _onFullscreenChanged() { + const parent = (Popup._getFullscreenElement() || document.body || null); + if (parent !== null && this._container.parentNode !== parent) { + parent.appendChild(this._container); + } + } + async _show(elementRect, writingMode) { await this._inject(); @@ -328,34 +360,16 @@ class Popup { } } - _observeFullscreen() { - const fullscreenEvents = [ - 'fullscreenchange', - 'MSFullscreenChange', - 'mozfullscreenchange', - 'webkitfullscreenchange' - ]; - for (const eventName of fullscreenEvents) { - document.addEventListener(eventName, () => this._onFullscreenChanged(), false); - } - } - - _getFullscreenElement() { + static _getFullscreenElement() { return ( document.fullscreenElement || document.msFullscreenElement || document.mozFullScreenElement || - document.webkitFullscreenElement + document.webkitFullscreenElement || + null ); } - _onFullscreenChanged() { - const parent = (this._getFullscreenElement() || document.body || null); - if (parent !== null && this._container.parentNode !== parent) { - parent.appendChild(this._container); - } - } - static _listenForDisplayPrepareCompleted(uniqueId, resolve) { const runtimeMessageCallback = ({action, params}, sender, callback) => { if ( -- cgit v1.2.3 From dcd243c9e9f3af3fedb0bb0db9795f377f175587 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 17:27:55 -0500 Subject: Update how popups are created --- ext/bg/js/settings/popup-preview-frame.js | 2 +- ext/fg/js/frontend-initialize.js | 11 ++++-- ext/fg/js/popup-proxy-host.js | 64 +++++++++++++++++++++---------- ext/fg/js/popup-proxy.js | 6 +-- ext/fg/js/popup.js | 8 ++++ 5 files changed, 62 insertions(+), 29 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 042f335f..8fd06222 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -50,7 +50,7 @@ class SettingsPopupPreview { const popupHost = new PopupProxyHost(); await popupHost.prepare(); - const popup = popupHost.createPopup(null, 0); + const popup = popupHost.getOrCreatePopup(); 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 c32e97d4..54b874f2 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -22,13 +22,16 @@ async function main() { const data = window.frontendInitializationData || {}; const {id, depth=0, parentFrameId, ignoreNodes, url, proxy=false} = data; - let popupHost = null; - if (!proxy) { - popupHost = new PopupProxyHost(); + let popup; + if (proxy) { + popup = new PopupProxy(null, depth + 1, id, parentFrameId, url); + } else { + const popupHost = new PopupProxyHost(); await popupHost.prepare(); + + popup = popupHost.getOrCreatePopup(); } - 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 98729796..e55801ff 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -34,7 +34,7 @@ class PopupProxyHost { if (typeof frameId !== 'number') { return; } this._apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${frameId}`, new Map([ - ['createNestedPopup', ({parentId}) => this._onApiCreateNestedPopup(parentId)], + ['getOrCreatePopup', ({id, parentId}) => this._onApiGetOrCreatePopup(id, parentId)], ['setOptions', ({id, options}) => this._onApiSetOptions(id, options)], ['hide', ({id, changeFocus}) => this._onApiHide(id, changeFocus)], ['isVisible', ({id}) => this._onApiIsVisibleAsync(id)], @@ -47,14 +47,51 @@ class PopupProxyHost { ])); } - createPopup(parentId, depth) { - return this._createPopupInternal(parentId, depth).popup; + getOrCreatePopup(id=null, parentId=null) { + // Find by existing id + if (id !== null) { + const popup = this._popups.get(id); + if (typeof popup !== 'undefined') { + return popup; + } + } + + // Find by existing parent id + let parent = null; + if (parentId !== null) { + parent = this._popups.get(parentId); + if (typeof parent !== 'undefined') { + const popup = parent.child; + if (popup !== null) { + return popup; + } + } else { + parent = null; + } + } + + // New unique id + if (id === null) { + id = this._nextId++; + } + + // Create new popup + const depth = (parent !== null ? parent.depth + 1 : 0); + const popup = new Popup(id, depth, this._frameIdPromise); + if (parent !== null) { + popup.setParent(parent); + } + this._popups.set(id, popup); + return popup; } // Message handlers - async _onApiCreateNestedPopup(parentId) { - return this._createPopupInternal(parentId, 0).id; + async _onApiGetOrCreatePopup(id, parentId) { + const popup = this.getOrCreatePopup(id, parentId); + return { + id: popup.id + }; } async _onApiSetOptions(id, options) { @@ -106,25 +143,10 @@ 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.setParent(parent); - } - this._popups.set(id, popup); - return {popup, id}; - } - _getPopup(id) { const popup = this._popups.get(id); if (typeof popup === 'undefined') { - throw new Error('Invalid popup ID'); + throw new Error(`Invalid popup ID ${id}`); } return popup; } diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index db6dffb1..093cdd2e 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -19,10 +19,10 @@ /*global FrontendApiSender*/ class PopupProxy { - constructor(depth, parentId, parentFrameId, url) { + constructor(id, depth, parentId, parentFrameId, url) { this._parentId = parentId; this._parentFrameId = parentFrameId; - this._id = null; + this._id = id; this._idPromise = null; this._depth = depth; this._url = url; @@ -113,7 +113,7 @@ class PopupProxy { } async _getPopupIdAsync() { - const id = await this._invokeHostApi('createNestedPopup', {parentId: this._parentId}); + const {id} = await this._invokeHostApi('getOrCreatePopup', {id: this._id, parentId: this._parentId}); this._id = id; return id; } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 0fc40475..8d4d2b14 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -49,10 +49,18 @@ class Popup { // Public properties + get id() { + return this._id; + } + get parent() { return this._parent; } + get child() { + return this._child; + } + get depth() { return this._depth; } -- cgit v1.2.3 From c6efa656268b93c612f3f4f9c5de0a2523506902 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 19:09:33 -0500 Subject: Fix missing argument --- ext/fg/js/popup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 8d4d2b14..de05f9f5 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -245,7 +245,7 @@ class Popup { uniqueId }); }); - this._observeFullscreen(); + this._observeFullscreen(true); this._onFullscreenChanged(); this.setCustomOuterCss(this._options.general.customPopupOuterCss, false); this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html')); -- cgit v1.2.3 From 1c6ed1d2866d9912b3b65d9e5addf710a6f26b38 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 19:16:31 -0500 Subject: Set URL before adding to the document --- ext/fg/js/popup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index de05f9f5..45203c03 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -228,6 +228,7 @@ class Popup { return new Promise((resolve) => { const parentFrameId = (typeof this._frameId === 'number' ? this._frameId : null); + this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html')); this._container.addEventListener('load', () => { const uniqueId = yomichan.generateId(32); Popup._listenForDisplayPrepareCompleted(uniqueId, resolve); @@ -248,7 +249,6 @@ class Popup { this._observeFullscreen(true); this._onFullscreenChanged(); this.setCustomOuterCss(this._options.general.customPopupOuterCss, false); - this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html')); }); } -- cgit v1.2.3 From 2c3f510010ca2910b8c227a9888e2c3584840402 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 13:13:04 -0500 Subject: Allow apiInjectStylesheet to inject a URL --- ext/bg/js/backend.js | 23 ++++++++++++++++------- ext/fg/js/popup.js | 2 +- ext/mixed/js/api.js | 4 ++-- 3 files changed, 19 insertions(+), 10 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index d1a34f82..eeed841c 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -499,19 +499,28 @@ class Backend { return Promise.resolve({frameId}); } - _onApiInjectStylesheet({css}, sender) { + _onApiInjectStylesheet({type, value}, sender) { if (!sender.tab) { return Promise.reject(new Error('Invalid tab')); } const tabId = sender.tab.id; const frameId = sender.frameId; - const details = { - code: css, - runAt: 'document_start', - cssOrigin: 'user', - allFrames: false - }; + const details = ( + type === 'file' ? + { + file: value, + runAt: 'document_start', + cssOrigin: 'author', + allFrames: false + } : + { + code: value, + runAt: 'document_start', + cssOrigin: 'user', + allFrames: false + } + ); if (typeof frameId === 'number') { details.frameId = frameId; } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 45203c03..970c5343 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -167,7 +167,7 @@ class Popup { } else { if (!css) { return; } try { - await apiInjectStylesheet(css); + await apiInjectStylesheet('code', css); this._stylesheetInjectedViaApi = true; } catch (e) { // NOP diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js index 86bdc73c..14900ecf 100644 --- a/ext/mixed/js/api.js +++ b/ext/mixed/js/api.js @@ -89,8 +89,8 @@ function apiFrameInformationGet() { return _apiInvoke('frameInformationGet'); } -function apiInjectStylesheet(css) { - return _apiInvoke('injectStylesheet', {css}); +function apiInjectStylesheet(type, value) { + return _apiInvoke('injectStylesheet', {type, value}); } function apiGetEnvironmentInfo() { -- cgit v1.2.3 From b6a50e234cf4fc6179725082f9f53ddd7325ba01 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 13:29:55 -0500 Subject: Change parameter name --- ext/bg/js/settings/popup-preview-frame.js | 2 +- ext/fg/js/popup.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 8fd06222..a7863b3a 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -137,7 +137,7 @@ class SettingsPopupPreview { setCustomOuterCss(css) { if (this.frontend === null) { return; } - this.frontend.popup.setCustomOuterCss(css, true); + this.frontend.popup.setCustomOuterCss(css, false); } async updateSearch() { diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 970c5343..6fbab62b 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -158,11 +158,11 @@ class Popup { this._container.dataset.yomichanSiteColor = this._getSiteColor(); } - async setCustomOuterCss(css, injectDirectly) { + async setCustomOuterCss(css, useWebExtensionApi) { // 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 (!useWebExtensionApi || Popup._isOnExtensionPage()) { Popup.injectOuterStylesheet(css); } else { if (!css) { return; } -- cgit v1.2.3 From 9fd6ee382d35fb5fcfc3e6d0f4fab711b37b693e Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 13:48:06 -0500 Subject: Create more generic function for injecting stylesheets --- ext/bg/js/settings/popup-preview-frame.js | 5 +- ext/fg/js/popup.js | 132 +++++++++++++++++++----------- 2 files changed, 88 insertions(+), 49 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 8c354bf7..e900d4e2 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -88,10 +88,9 @@ class SettingsPopupPreview { // This simulates the stylesheet priorities when injecting using the web extension API. const result = await this.popupSetCustomOuterCssOld.call(this.popup, ...args); - const outerStylesheet = Popup.outerStylesheet; const node = document.querySelector('#client-css'); - if (node !== null && outerStylesheet !== null) { - node.parentNode.insertBefore(outerStylesheet, node); + if (node !== null && result !== null) { + node.parentNode.insertBefore(result, node); } return result; diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 6fbab62b..d799e371 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -31,7 +31,6 @@ class Popup { this._visible = false; this._visibleOverride = null; this._options = null; - this._stylesheetInjectedViaApi = false; this._contentScale = 1.0; this._containerSizeContentScale = null; @@ -159,20 +158,12 @@ class Popup { } async setCustomOuterCss(css, useWebExtensionApi) { - // Cannot repeatedly inject stylesheets using web extension APIs since there is no way to remove them. - if (this._stylesheetInjectedViaApi) { return; } - - if (!useWebExtensionApi || Popup._isOnExtensionPage()) { - Popup.injectOuterStylesheet(css); - } else { - if (!css) { return; } - try { - await apiInjectStylesheet('code', css); - this._stylesheetInjectedViaApi = true; - } catch (e) { - // NOP - } - } + return await Popup._injectStylesheet( + 'yomichan-popup-outer-user-stylesheet', + 'code', + css, + useWebExtensionApi + ); } setChildrenSupported(value) { @@ -187,26 +178,6 @@ class Popup { return this._container.getBoundingClientRect(); } - 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 = ''; - } - } - // Private functions _inject() { @@ -248,7 +219,11 @@ class Popup { }); this._observeFullscreen(true); this._onFullscreenChanged(); - this.setCustomOuterCss(this._options.general.customPopupOuterCss, false); + try { + this.setCustomOuterCss(this._options.general.customPopupOuterCss, true); + } catch (e) { + // NOP + } }); } @@ -526,15 +501,6 @@ class Popup { ]; } - static _isOnExtensionPage() { - try { - const url = chrome.runtime.getURL('/'); - return window.location.href.substring(0, url.length) === url; - } catch (e) { - // NOP - } - } - static _getViewport(useVisualViewport) { const visualViewport = window.visualViewport; if (visualViewport !== null && typeof visualViewport === 'object') { @@ -567,6 +533,80 @@ class Popup { bottom: window.innerHeight }; } + + static _isOnExtensionPage() { + try { + const url = chrome.runtime.getURL('/'); + return window.location.href.substring(0, url.length) === url; + } catch (e) { + // NOP + } + } + + static async _injectStylesheet(id, type, value, useWebExtensionApi) { + const injectedStylesheets = Popup._injectedStylesheets; + + if (Popup._isOnExtensionPage()) { + // Permissions error will occur if trying to use the WebExtension API to inject + // into an extension page. + useWebExtensionApi = false; + } + + let styleNode = injectedStylesheets.get(id); + if (typeof styleNode !== 'undefined') { + if (styleNode === null) { + // Previously injected via WebExtension API + throw new Error(`Stylesheet with id ${id} has already been injected using the WebExtension API`); + } + } else { + styleNode = null; + } + + if (useWebExtensionApi) { + // Inject via WebExtension API + if (styleNode !== null && styleNode.parentNode !== null) { + styleNode.parentNode.removeChild(styleNode); + } + + await apiInjectStylesheet(type, value); + + injectedStylesheets.set(id, null); + return null; + } + + // Create node in document + const parentNode = document.head; + if (parentNode === null) { + throw new Error('No parent node'); + } + + // Create or reuse node + const isFile = (type === 'file'); + const tagName = isFile ? 'link' : 'style'; + if (styleNode === null || styleNode.nodeName.toLowerCase() !== tagName) { + if (styleNode !== null && styleNode.parentNode !== null) { + styleNode.parentNode.removeChild(styleNode); + } + styleNode = document.createElement(tagName); + styleNode.id = id; + } + + // Update node style + if (isFile) { + styleNode.rel = value; + } else { + styleNode.textContent = value; + } + + // Update parent + if (styleNode.parentNode !== parentNode) { + parentNode.appendChild(styleNode); + } + + // Add to map + injectedStylesheets.set(id, styleNode); + return styleNode; + } } -Popup.outerStylesheet = null; +Popup._injectedStylesheets = new Map(); -- cgit v1.2.3 From 3d27e80ae646bcc9c421cbc8aa281008f47c8992 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 13:53:19 -0500 Subject: Delay CSS injection until a popup is created --- ext/fg/js/popup.js | 1 + ext/manifest.json | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/fg') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index d799e371..dc538b02 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -220,6 +220,7 @@ class Popup { this._observeFullscreen(true); this._onFullscreenChanged(); try { + Popup._injectStylesheet('yomichan-popup-outer-stylesheet', 'file', '/fg/css/client.css', true); this.setCustomOuterCss(this._options.general.customPopupOuterCss, true); } catch (e) { // NOP diff --git a/ext/manifest.json b/ext/manifest.json index 68a8adb4..b86459f9 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -30,7 +30,6 @@ "fg/js/frontend.js", "fg/js/frontend-initialize.js" ], - "css": ["fg/css/client.css"], "match_about_blank": true, "all_frames": true }], -- cgit v1.2.3 From ae4ee9ddee0b791c1039595250db6106e66709fa Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 21:49:28 -0500 Subject: Fix error handling on style injection --- ext/fg/js/popup.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'ext/fg') diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index dc538b02..59c46ab8 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -219,15 +219,24 @@ class Popup { }); this._observeFullscreen(true); this._onFullscreenChanged(); - try { - Popup._injectStylesheet('yomichan-popup-outer-stylesheet', 'file', '/fg/css/client.css', true); - this.setCustomOuterCss(this._options.general.customPopupOuterCss, true); - } catch (e) { - // NOP - } + this._injectStyles(); }); } + async _injectStyles() { + try { + await Popup._injectStylesheet('yomichan-popup-outer-stylesheet', 'file', '/fg/css/client.css', true); + } catch (e) { + // NOP + } + + try { + await this.setCustomOuterCss(this._options.general.customPopupOuterCss, true); + } catch (e) { + // NOP + } + } + _observeFullscreen(observe) { if (!observe) { this._fullscreenEventListeners.removeAllEventListeners(); -- cgit v1.2.3 From aee16c443195ff8ab2b0f5f5e8551e44895d48a1 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 23:41:17 -0500 Subject: Check origin on window messages --- ext/bg/js/settings/popup-preview-frame.js | 3 +++ ext/bg/js/settings/popup-preview.js | 8 +++++--- ext/fg/js/popup.js | 3 ++- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index e900d4e2..890b8c96 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -27,6 +27,7 @@ class SettingsPopupPreview { this.popupShown = false; this.themeChangeTimeout = null; this.textSource = null; + this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, ''); } static create() { @@ -97,6 +98,8 @@ class SettingsPopupPreview { } onMessage(e) { + if (e.origin !== this._targetOrigin) { return; } + const {action, params} = e.data; const handler = SettingsPopupPreview._messageHandlers.get(action); if (typeof handler !== 'function') { return; } diff --git a/ext/bg/js/settings/popup-preview.js b/ext/bg/js/settings/popup-preview.js index 0d20471e..d1d2ff5e 100644 --- a/ext/bg/js/settings/popup-preview.js +++ b/ext/bg/js/settings/popup-preview.js @@ -40,20 +40,22 @@ function showAppearancePreview() { window.wanakana.bind(text[0]); + const targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, ''); + text.on('input', () => { const action = 'setText'; const params = {text: text.val()}; - frame.contentWindow.postMessage({action, params}, '*'); + frame.contentWindow.postMessage({action, params}, targetOrigin); }); customCss.on('input', () => { const action = 'setCustomCss'; const params = {css: customCss.val()}; - frame.contentWindow.postMessage({action, params}, '*'); + frame.contentWindow.postMessage({action, params}, targetOrigin); }); customOuterCss.on('input', () => { const action = 'setCustomOuterCss'; const params = {css: customOuterCss.val()}; - frame.contentWindow.postMessage({action, params}, '*'); + frame.contentWindow.postMessage({action, params}, targetOrigin); }); container.append(frame); diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 59c46ab8..900e7325 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -33,6 +33,7 @@ class Popup { this._options = null; this._contentScale = 1.0; this._containerSizeContentScale = null; + this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, ''); this._container = document.createElement('iframe'); this._container.className = 'yomichan-float'; @@ -349,7 +350,7 @@ class Popup { _invokeApi(action, params={}) { if (this._container.contentWindow) { - this._container.contentWindow.postMessage({action, params}, '*'); + this._container.contentWindow.postMessage({action, params}, this._targetOrigin); } } -- cgit v1.2.3 From 0f46e3a093e7f0c07ad310d8c17e2582bdfd2741 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Mon, 17 Feb 2020 11:02:21 -0500 Subject: Use a token to ensure that messages are coming from Yomichan --- ext/bg/js/backend.js | 9 ++++++++- ext/fg/js/float.js | 50 ++++++++++++++++++++++++++++++++++++++++++++------ ext/fg/js/popup.js | 15 +++++++++++---- ext/mixed/js/api.js | 4 ++++ 4 files changed, 67 insertions(+), 11 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 458ea483..a4d085e0 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -46,6 +46,8 @@ class Backend { this.popupWindow = null; this.apiForwarder = new BackendApiForwarder(); + + this.messageToken = yomichan.generateId(16); } async prepare() { @@ -614,6 +616,10 @@ class Backend { }); } + async _onApiGetMessageToken() { + return this.messageToken; + } + // Command handlers async _onCommandSearch(params) { @@ -875,7 +881,8 @@ Backend._messageHandlers = new Map([ ['clipboardGet', (self, ...args) => self._onApiClipboardGet(...args)], ['getDisplayTemplatesHtml', (self, ...args) => self._onApiGetDisplayTemplatesHtml(...args)], ['getQueryParserTemplatesHtml', (self, ...args) => self._onApiGetQueryParserTemplatesHtml(...args)], - ['getZoom', (self, ...args) => self._onApiGetZoom(...args)] + ['getZoom', (self, ...args) => self._onApiGetZoom(...args)], + ['getMessageToken', (self, ...args) => self._onApiGetMessageToken(...args)] ]); Backend._commandHandlers = new Map([ diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 440a9731..8f21a9c5 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/*global popupNestedInitialize, apiForward, Display*/ +/*global popupNestedInitialize, apiForward, apiGetMessageToken, Display*/ class DisplayFloat extends Display { constructor() { @@ -30,6 +30,8 @@ class DisplayFloat extends Display { this._orphaned = false; this._prepareInvoked = false; + this._messageToken = null; + this._messageTokenPromise = null; yomichan.on('orphaned', () => this.onOrphaned()); window.addEventListener('message', (e) => this.onMessage(e), false); @@ -75,11 +77,23 @@ class DisplayFloat extends Display { } onMessage(e) { - const {action, params} = e.data; - const handler = DisplayFloat._messageHandlers.get(action); - if (typeof handler !== 'function') { return; } - - handler(this, params); + const data = e.data; + if (typeof data !== 'object' || data === null) { return; } // Invalid data + + const token = data.token; + if (typeof token !== 'string') { return; } // Invalid data + + if (this._messageToken === null) { + // Async + this.getMessageToken() + .then( + () => { this.handleAction(token, data); }, + () => {} + ); + } else { + // Sync + this.handleAction(token, data); + } } onKeyDown(e) { @@ -94,6 +108,30 @@ class DisplayFloat extends Display { return super.onKeyDown(e); } + async getMessageToken() { + // this._messageTokenPromise is used to ensure that only one call to apiGetMessageToken is made. + if (this._messageTokenPromise === null) { + this._messageTokenPromise = apiGetMessageToken(); + } + const messageToken = await this._messageTokenPromise; + if (this._messageToken === null) { + this._messageToken = messageToken; + } + this._messageTokenPromise = null; + } + + handleAction(token, {action, params}) { + if (token !== this._messageToken) { + // Invalid token + return; + } + + const handler = DisplayFloat._messageHandlers.get(action); + if (typeof handler !== 'function') { return; } + + handler(this, params); + } + getOptionsContext() { return this.optionsContext; } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 900e7325..4927f4bd 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/*global apiInjectStylesheet*/ +/*global apiInjectStylesheet, apiGetMessageToken*/ class Popup { constructor(id, depth, frameIdPromise) { @@ -34,6 +34,7 @@ class Popup { this._contentScale = 1.0; this._containerSizeContentScale = null; this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, ''); + this._messageToken = null; this._container = document.createElement('iframe'); this._container.className = 'yomichan-float'; @@ -198,6 +199,10 @@ class Popup { // NOP } + if (this._messageToken === null) { + this._messageToken = await apiGetMessageToken(); + } + return new Promise((resolve) => { const parentFrameId = (typeof this._frameId === 'number' ? this._frameId : null); this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html')); @@ -349,9 +354,11 @@ class Popup { } _invokeApi(action, params={}) { - if (this._container.contentWindow) { - this._container.contentWindow.postMessage({action, params}, this._targetOrigin); - } + const token = this._messageToken; + const contentWindow = this._container.contentWindow; + if (token === null || contentWindow === null) { return; } + + contentWindow.postMessage({action, params, token}, this._targetOrigin); } static _getFullscreenElement() { diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js index 14900ecf..7ea68d59 100644 --- a/ext/mixed/js/api.js +++ b/ext/mixed/js/api.js @@ -113,6 +113,10 @@ function apiGetZoom() { return _apiInvoke('getZoom'); } +function apiGetMessageToken() { + return _apiInvoke('getMessageToken'); +} + function _apiInvoke(action, params={}) { const data = {action, params}; return new Promise((resolve, reject) => { -- cgit v1.2.3 From 6d75637ace341b79a6a12c7854b13fb1c279498f Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 15 Feb 2020 19:48:02 -0500 Subject: Fix brace style issues --- ext/bg/js/backend.js | 21 +++++++++++++++------ ext/fg/js/document.js | 3 +-- 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 16dffc85..7c71f82c 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -801,8 +801,11 @@ class Backend { await new Promise((resolve, reject) => { chrome.tabs.update(tab.id, {active: true}, () => { const e = chrome.runtime.lastError; - if (e) { reject(e); } - else { resolve(); } + if (e) { + reject(e); + } else { + resolve(); + } }); }); @@ -815,16 +818,22 @@ class Backend { const tabWindow = await new Promise((resolve, reject) => { chrome.windows.get(tab.windowId, {}, (tabWindow) => { const e = chrome.runtime.lastError; - if (e) { reject(e); } - else { resolve(tabWindow); } + if (e) { + reject(e); + } else { + resolve(tabWindow); + } }); }); if (!tabWindow.focused) { await new Promise((resolve, reject) => { chrome.windows.update(tab.windowId, {focused: true}, () => { const e = chrome.runtime.lastError; - if (e) { reject(e); } - else { resolve(); } + if (e) { + reject(e); + } else { + resolve(); + } }); }); } diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js index 7284cdd1..ea9ac965 100644 --- a/ext/fg/js/document.js +++ b/ext/fg/js/document.js @@ -192,8 +192,7 @@ function docSentenceExtract(source, extent) { if (terminators.includes(c)) { endPos = i + 1; break; - } - else if (c in quotesBwd) { + } else if (c in quotesBwd) { endPos = i; break; } -- cgit v1.2.3 From 53220af68eabdda27b35224056f3bd589e8c4785 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 23 Feb 2020 11:49:52 -0500 Subject: Don't use innerHTML --- ext/bg/js/search-query-parser.js | 2 +- ext/fg/js/source.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index 8c434990..0d4aaa50 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -164,7 +164,7 @@ class QueryParser extends TextScanner { } renderParserSelect() { - this.queryParserSelect.innerHTML = ''; + this.queryParserSelect.textContent = ''; if (this.parseResults.length > 1) { const select = this.queryParserGenerator.createParserSelect(this.parseResults, this.selectedParser); select.addEventListener('change', this.onParserChange.bind(this)); diff --git a/ext/fg/js/source.js b/ext/fg/js/source.js index fa785ec4..6dc482bd 100644 --- a/ext/fg/js/source.js +++ b/ext/fg/js/source.js @@ -366,7 +366,7 @@ class TextSourceElement { setEndOffset(length) { switch (this.element.nodeName.toUpperCase()) { case 'BUTTON': - this.content = this.element.innerHTML; + this.content = this.element.textContent; break; case 'IMG': this.content = this.element.getAttribute('alt'); -- cgit v1.2.3 From 5a5c18371ca6df5473f9d5ef9a391acde6c2e168 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 23 Feb 2020 11:58:17 -0500 Subject: Use textContent instead of innerText --- ext/bg/js/audio.js | 2 +- ext/bg/js/search-query-parser-generator.js | 6 +++--- ext/fg/js/document.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'ext/fg') diff --git a/ext/bg/js/audio.js b/ext/bg/js/audio.js index 0ecfd5c4..d300570b 100644 --- a/ext/bg/js/audio.js +++ b/ext/bg/js/audio.js @@ -52,7 +52,7 @@ const audioUrlBuilders = new Map([ for (const row of dom.getElementsByClassName('dc-result-row')) { try { const url = row.querySelector('audio>source[src]').getAttribute('src'); - const reading = row.getElementsByClassName('dc-vocab_kana').item(0).innerText; + const reading = row.getElementsByClassName('dc-vocab_kana').item(0).textContent; if (url && reading && (!definition.reading || definition.reading === reading)) { return audioUrlNormalize(url, 'https://www.japanesepod101.com', '/learningcenter/reference/'); } diff --git a/ext/bg/js/search-query-parser-generator.js b/ext/bg/js/search-query-parser-generator.js index f842644e..1ab23a82 100644 --- a/ext/bg/js/search-query-parser-generator.js +++ b/ext/bg/js/search-query-parser-generator.js @@ -50,7 +50,7 @@ class QueryParserGenerator { const segmentTextContainer = segmentContainer.querySelector('.query-parser-segment-text'); const segmentReadingContainer = segmentContainer.querySelector('.query-parser-segment-reading'); segmentTextContainer.appendChild(this.createSegmentText(segment.text)); - segmentReadingContainer.innerText = segment.reading; + segmentReadingContainer.textContent = segment.reading; return segmentContainer; } @@ -58,7 +58,7 @@ class QueryParserGenerator { const fragment = document.createDocumentFragment(); for (const chr of text) { const charContainer = this._templateHandler.instantiate('char'); - charContainer.innerText = chr; + charContainer.textContent = chr; fragment.appendChild(charContainer); } return fragment; @@ -69,7 +69,7 @@ class QueryParserGenerator { for (const parseResult of parseResults) { const optionContainer = this._templateHandler.instantiate('select-option'); optionContainer.value = parseResult.id; - optionContainer.innerText = parseResult.name; + optionContainer.textContent = parseResult.name; optionContainer.defaultSelected = selectedParser === parseResult.id; selectContainer.appendChild(optionContainer); } diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js index ea9ac965..1a3e8791 100644 --- a/ext/fg/js/document.js +++ b/ext/fg/js/document.js @@ -50,7 +50,7 @@ function docImposterCreate(element, isTextarea) { const imposter = document.createElement('div'); const imposterStyle = imposter.style; - imposter.innerText = element.value; + imposter.textContent = element.value; for (let i = 0, ii = elementStyle.length; i < ii; ++i) { const property = elementStyle[i]; -- cgit v1.2.3 From 0c4aa2eeb96a3d57555865576f9e5285d3c49fb7 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 23 Feb 2020 13:04:55 -0500 Subject: Fix trailing newlines not actually generating a new line in the imposter This was causing vertical scroll offset issues --- ext/fg/js/document.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ext/fg') diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js index 1a3e8791..35861475 100644 --- a/ext/fg/js/document.js +++ b/ext/fg/js/document.js @@ -50,7 +50,9 @@ function docImposterCreate(element, isTextarea) { const imposter = document.createElement('div'); const imposterStyle = imposter.style; - imposter.textContent = element.value; + let value = element.value; + if (value.endsWith('\n')) { value += '\n'; } + imposter.textContent = value; for (let i = 0, ii = elementStyle.length; i < ii; ++i) { const property = elementStyle[i]; -- cgit v1.2.3 From a0b2e11c10f76844d37a3ebab1a2c8a0f4ab18a9 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 23 Feb 2020 16:18:13 -0500 Subject: Use TemplateHandler for DisplayGenerator --- ext/fg/float.html | 1 + ext/mixed/js/display-generator.js | 77 +++++++++------------------------------ 2 files changed, 19 insertions(+), 59 deletions(-) (limited to 'ext/fg') diff --git a/ext/fg/float.html b/ext/fg/float.html index 082755f5..352a866a 100644 --- a/ext/fg/float.html +++ b/ext/fg/float.html @@ -51,6 +51,7 @@ + diff --git a/ext/mixed/js/display-generator.js b/ext/mixed/js/display-generator.js index 46f3d17e..5023c191 100644 --- a/ext/mixed/js/display-generator.js +++ b/ext/mixed/js/display-generator.js @@ -16,23 +16,11 @@ * along with this program. If not, see . */ -/*global apiGetDisplayTemplatesHtml*/ +/*global apiGetDisplayTemplatesHtml, TemplateHandler*/ class DisplayGenerator { constructor() { - this._termEntryTemplate = null; - this._termExpressionTemplate = null; - this._termDefinitionItemTemplate = null; - this._termDefinitionOnlyTemplate = null; - this._termGlossaryItemTemplate = null; - this._termReasonTemplate = null; - - this._kanjiEntryTemplate = null; - this._kanjiInfoTableTemplate = null; - this._kanjiInfoTableItemTemplate = null; - this._kanjiInfoTableEmptyTemplate = null; - this._kanjiGlossaryItemTemplate = null; - this._kanjiReadingTemplate = null; + this._templateHandler = null; this._tagTemplate = null; this._tagFrequencyTemplate = null; @@ -40,12 +28,11 @@ class DisplayGenerator { async prepare() { const html = await apiGetDisplayTemplatesHtml(); - const doc = new DOMParser().parseFromString(html, 'text/html'); - this._setTemplates(doc); + this._templateHandler = new TemplateHandler(html); } createTermEntry(details) { - const node = DisplayGenerator._instantiateTemplate(this._termEntryTemplate); + const node = this._templateHandler.instantiate('term-entry'); const expressionsContainer = node.querySelector('.term-expression-list'); const reasonsContainer = node.querySelector('.term-reasons'); @@ -78,7 +65,7 @@ class DisplayGenerator { } createTermExpression([details, termTags]) { - const node = DisplayGenerator._instantiateTemplate(this._termExpressionTemplate); + const node = this._templateHandler.instantiate('term-expression'); const expressionContainer = node.querySelector('.term-expression-text'); const tagContainer = node.querySelector('.tags'); @@ -112,7 +99,7 @@ class DisplayGenerator { } createTermReason(reason) { - const fragment = DisplayGenerator._instantiateTemplateFragment(this._termReasonTemplate); + const fragment = this._templateHandler.instantiateFragment('term-reason'); const node = fragment.querySelector('.term-reason'); node.textContent = reason; node.dataset.reason = reason; @@ -120,7 +107,7 @@ class DisplayGenerator { } createTermDefinitionItem(details) { - const node = DisplayGenerator._instantiateTemplate(this._termDefinitionItemTemplate); + const node = this._templateHandler.instantiate('term-definition-item'); const tagListContainer = node.querySelector('.term-definition-tag-list'); const onlyListContainer = node.querySelector('.term-definition-only-list'); @@ -136,7 +123,7 @@ class DisplayGenerator { } createTermGlossaryItem(glossary) { - const node = DisplayGenerator._instantiateTemplate(this._termGlossaryItemTemplate); + const node = this._templateHandler.instantiate('term-glossary-item'); const container = node.querySelector('.term-glossary'); if (container !== null) { DisplayGenerator._appendMultilineText(container, glossary); @@ -145,7 +132,7 @@ class DisplayGenerator { } createTermOnly(only) { - const node = DisplayGenerator._instantiateTemplate(this._termDefinitionOnlyTemplate); + const node = this._templateHandler.instantiate('term-definition-only'); node.dataset.only = only; node.textContent = only; return node; @@ -160,7 +147,7 @@ class DisplayGenerator { } createKanjiEntry(details) { - const node = DisplayGenerator._instantiateTemplate(this._kanjiEntryTemplate); + const node = this._templateHandler.instantiate('kanji-entry'); const glyphContainer = node.querySelector('.kanji-glyph'); const frequenciesContainer = node.querySelector('.frequencies'); @@ -205,7 +192,7 @@ class DisplayGenerator { } createKanjiGlossaryItem(glossary) { - const node = DisplayGenerator._instantiateTemplate(this._kanjiGlossaryItemTemplate); + const node = this._templateHandler.instantiate('kanji-glossary-item'); const container = node.querySelector('.kanji-glossary'); if (container !== null) { DisplayGenerator._appendMultilineText(container, glossary); @@ -214,13 +201,13 @@ class DisplayGenerator { } createKanjiReading(reading) { - const node = DisplayGenerator._instantiateTemplate(this._kanjiReadingTemplate); + const node = this._templateHandler.instantiate('kanji-reading'); node.textContent = reading; return node; } createKanjiInfoTable(details) { - const node = DisplayGenerator._instantiateTemplate(this._kanjiInfoTableTemplate); + const node = this._templateHandler.instantiate('kanji-info-table'); const container = node.querySelector('.kanji-info-table-body'); @@ -236,7 +223,7 @@ class DisplayGenerator { } createKanjiInfoTableItem(details) { - const node = DisplayGenerator._instantiateTemplate(this._kanjiInfoTableItemTemplate); + const node = this._templateHandler.instantiate('kanji-info-table-item'); const nameNode = node.querySelector('.kanji-info-table-item-header'); const valueNode = node.querySelector('.kanji-info-table-item-value'); if (nameNode !== null) { @@ -249,11 +236,11 @@ class DisplayGenerator { } createKanjiInfoTableItemEmpty() { - return DisplayGenerator._instantiateTemplate(this._kanjiInfoTableEmptyTemplate); + return this._templateHandler.instantiate('kanji-info-table-empty'); } createTag(details) { - const node = DisplayGenerator._instantiateTemplate(this._tagTemplate); + const node = this._templateHandler.instantiate('tag'); const inner = node.querySelector('.tag-inner'); @@ -265,7 +252,7 @@ class DisplayGenerator { } createSearchTag(details) { - const node = DisplayGenerator._instantiateTemplate(this._tagSearchTemplate); + const node = this._templateHandler.instantiate('tag-search'); node.textContent = details.query; @@ -275,7 +262,7 @@ class DisplayGenerator { } createFrequencyTag(details) { - const node = DisplayGenerator._instantiateTemplate(this._tagFrequencyTemplate); + const node = this._templateHandler.instantiate('tag-frequency'); let n = node.querySelector('.term-frequency-dictionary-name'); if (n !== null) { @@ -293,26 +280,6 @@ class DisplayGenerator { return node; } - _setTemplates(doc) { - this._termEntryTemplate = doc.querySelector('#term-entry-template'); - this._termExpressionTemplate = doc.querySelector('#term-expression-template'); - this._termDefinitionItemTemplate = doc.querySelector('#term-definition-item-template'); - this._termDefinitionOnlyTemplate = doc.querySelector('#term-definition-only-template'); - this._termGlossaryItemTemplate = doc.querySelector('#term-glossary-item-template'); - this._termReasonTemplate = doc.querySelector('#term-reason-template'); - - this._kanjiEntryTemplate = doc.querySelector('#kanji-entry-template'); - this._kanjiInfoTableTemplate = doc.querySelector('#kanji-info-table-template'); - this._kanjiInfoTableItemTemplate = doc.querySelector('#kanji-info-table-item-template'); - this._kanjiInfoTableEmptyTemplate = doc.querySelector('#kanji-info-table-empty-template'); - this._kanjiGlossaryItemTemplate = doc.querySelector('#kanji-glossary-item-template'); - this._kanjiReadingTemplate = doc.querySelector('#kanji-reading-template'); - - this._tagTemplate = doc.querySelector('#tag-template'); - this._tagSearchTemplate = doc.querySelector('#tag-search-template'); - this._tagFrequencyTemplate = doc.querySelector('#tag-frequency-template'); - } - _appendKanjiLinks(container, text) { let part = ''; for (const c of text) { @@ -382,12 +349,4 @@ class DisplayGenerator { container.appendChild(document.createTextNode(parts[i])); } } - - static _instantiateTemplate(template) { - return document.importNode(template.content.firstChild, true); - } - - static _instantiateTemplateFragment(template) { - return document.importNode(template.content, true); - } } -- cgit v1.2.3