diff options
-rw-r--r-- | ext/js/app/content-script-main.js | 67 | ||||
-rw-r--r-- | ext/js/application.js | 92 | ||||
-rw-r--r-- | ext/js/background/background-main.js | 7 | ||||
-rw-r--r-- | ext/js/comm/cross-frame-api.js | 11 | ||||
-rw-r--r-- | ext/js/display/popup-main.js | 51 | ||||
-rw-r--r-- | ext/js/display/search-main.js | 56 | ||||
-rw-r--r-- | ext/js/pages/action-popup-main.js | 12 | ||||
-rw-r--r-- | ext/js/pages/info-main.js | 83 | ||||
-rw-r--r-- | ext/js/pages/permissions-main.js | 82 | ||||
-rw-r--r-- | ext/js/pages/settings/popup-preview-frame-main.js | 43 | ||||
-rw-r--r-- | ext/js/pages/settings/settings-main.js | 165 | ||||
-rw-r--r-- | ext/js/pages/welcome-main.js | 83 |
12 files changed, 327 insertions, 425 deletions
diff --git a/ext/js/app/content-script-main.js b/ext/js/app/content-script-main.js index d77f1fa0..23d36b48 100644 --- a/ext/js/app/content-script-main.js +++ b/ext/js/app/content-script-main.js @@ -17,49 +17,36 @@ */ import {Application} from '../application.js'; -import {log} from '../core/logger.js'; import {HotkeyHandler} from '../input/hotkey-handler.js'; import {Frontend} from './frontend.js'; import {PopupFactory} from './popup-factory.js'; -/** Entry point. */ -async function main() { - try { - const application = new Application(); - await application.prepare(); - - const {tabId, frameId} = await application.api.frameInformationGet(); - if (typeof frameId !== 'number') { - throw new Error('Failed to get frameId'); - } - - const hotkeyHandler = new HotkeyHandler(); - hotkeyHandler.prepare(application.crossFrame); - - const popupFactory = new PopupFactory(application, frameId); - popupFactory.prepare(); - - const frontend = new Frontend({ - application, - tabId, - frameId, - popupFactory, - depth: 0, - parentPopupId: null, - parentFrameId: null, - useProxyPopup: false, - pageType: 'web', - canUseWindowPopup: true, - allowRootFramePopupProxy: true, - childrenSupported: true, - hotkeyHandler - }); - await frontend.prepare(); - - application.ready(); - } catch (e) { - log.error(e); +await Application.main(async (application) => { + const {tabId, frameId} = await application.api.frameInformationGet(); + if (typeof frameId !== 'number') { + throw new Error('Failed to get frameId'); } -} -await main(); + const hotkeyHandler = new HotkeyHandler(); + hotkeyHandler.prepare(application.crossFrame); + + const popupFactory = new PopupFactory(application, frameId); + popupFactory.prepare(); + + const frontend = new Frontend({ + application, + tabId, + frameId, + popupFactory, + depth: 0, + parentPopupId: null, + parentFrameId: null, + useProxyPopup: false, + pageType: 'web', + canUseWindowPopup: true, + allowRootFramePopupProxy: true, + childrenSupported: true, + hotkeyHandler + }); + await frontend.prepare(); +}); diff --git a/ext/js/application.js b/ext/js/application.js index 87bd0e86..13938aa8 100644 --- a/ext/js/application.js +++ b/ext/js/application.js @@ -58,8 +58,10 @@ if (checkChromeNotAvailable()) { export class Application extends EventDispatcher { /** * Creates a new instance. The instance should not be used until it has been fully prepare()'d. + * @param {API} api + * @param {CrossFrameAPI} crossFrameApi */ - constructor() { + constructor(api, crossFrameApi) { super(); /** @type {WebExtension} */ @@ -84,24 +86,17 @@ export class Application extends EventDispatcher { /** @type {?boolean} */ this._isBackground = null; - /** @type {?API} */ - this._api = null; - /** @type {?CrossFrameAPI} */ - this._crossFrame = null; + /** @type {API} */ + this._api = api; + /** @type {CrossFrameAPI} */ + this._crossFrame = crossFrameApi; /** @type {boolean} */ this._isReady = false; - const {promise, resolve} = /** @type {import('core').DeferredPromiseDetails<void>} */ (deferPromise()); - /** @type {Promise<void>} */ - this._isBackendReadyPromise = promise; - /** @type {?(() => void)} */ - this._isBackendReadyPromiseResolve = resolve; - /* eslint-disable no-multi-spaces */ /** @type {import('application').ApiMap} */ this._apiMap = createApiMap([ ['applicationIsReady', this._onMessageIsReady.bind(this)], - ['applicationBackendReady', this._onMessageBackendReady.bind(this)], ['applicationGetUrl', this._onMessageGetUrl.bind(this)], ['applicationOptionsUpdated', this._onMessageOptionsUpdated.bind(this)], ['applicationDatabaseUpdated', this._onMessageDatabaseUpdated.bind(this)], @@ -116,15 +111,6 @@ export class Application extends EventDispatcher { } /** - * Whether the current frame is the background page/service worker or not. - * @type {boolean} - */ - get isBackground() { - if (this._isBackground === null) { throw new Error('Not prepared'); } - return /** @type {boolean} */ (this._isBackground); - } - - /** * Gets the API instance for communicating with the backend. * This value will be null on the background page/service worker. * @type {API} @@ -146,23 +132,10 @@ export class Application extends EventDispatcher { /** * Prepares the instance for use. - * @param {boolean} [isBackground=false] Assigns whether this instance is being used from the background page/service worker. */ - async prepare(isBackground = false) { - this._isBackground = isBackground; + prepare() { chrome.runtime.onMessage.addListener(this._onMessage.bind(this)); - - if (!isBackground) { - this._api = new API(this._webExtension); - - await this._webExtension.sendMessagePromise({action: 'requestBackendReadySignal'}); - await this._isBackendReadyPromise; - - this._crossFrame = new CrossFrameAPI(this._api); - await this._crossFrame.prepare(); - - log.on('log', this._onForwardLog.bind(this)); - } + log.on('log', this._onForwardLog.bind(this)); } /** @@ -170,6 +143,7 @@ export class Application extends EventDispatcher { * setup has completed. */ ready() { + if (this._isReady) { return; } this._isReady = true; this._webExtension.sendMessagePromise({action: 'applicationReady'}); } @@ -193,6 +167,45 @@ export class Application extends EventDispatcher { this.trigger('closePopups', {}); } + /** + * @param {(application: Application) => (Promise<void>)} mainFunction + */ + static async main(mainFunction) { + const webExtension = new WebExtension(); + const api = new API(webExtension); + await this.waitForBackendReady(webExtension); + const {tabId = null, frameId = null} = await api.frameInformationGet(); + const crossFrameApi = new CrossFrameAPI(api, tabId, frameId); + crossFrameApi.prepare(); + const application = new Application(api, crossFrameApi); + application.prepare(); + try { + await mainFunction(application); + } catch (error) { + log.error(error); + } finally { + application.ready(); + } + } + + /** + * @param {WebExtension} webExtension + */ + static async waitForBackendReady(webExtension) { + const {promise, resolve} = /** @type {import('core').DeferredPromiseDetails<void>} */ (deferPromise()); + /** @type {import('application').ApiMap} */ + const apiMap = createApiMap([['applicationBackendReady', () => { resolve(); }]]); + /** @type {import('extension').ChromeRuntimeOnMessageCallback<import('application').ApiMessageAny>} */ + const onMessage = ({action, params}, _sender, callback) => invokeApiMapHandler(apiMap, action, params, [], callback); + chrome.runtime.onMessage.addListener(onMessage); + try { + await webExtension.sendMessagePromise({action: 'requestBackendReadySignal'}); + await promise; + } finally { + chrome.runtime.onMessage.removeListener(onMessage); + } + } + // Private /** @@ -212,13 +225,6 @@ export class Application extends EventDispatcher { return this._isReady; } - /** @type {import('application').ApiHandler<'applicationBackendReady'>} */ - _onMessageBackendReady() { - if (this._isBackendReadyPromiseResolve === null) { return; } - this._isBackendReadyPromiseResolve(); - this._isBackendReadyPromiseResolve = null; - } - /** @type {import('application').ApiHandler<'applicationGetUrl'>} */ _onMessageGetUrl() { return {url: this._getUrl()}; diff --git a/ext/js/background/background-main.js b/ext/js/background/background-main.js index b63b4396..0f1ddeeb 100644 --- a/ext/js/background/background-main.js +++ b/ext/js/background/background-main.js @@ -16,15 +16,14 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import {Application} from '../application.js'; +import {WebExtension} from '../extension/web-extension.js'; import {Backend} from './backend.js'; /** Entry point. */ async function main() { - const application = new Application(); - application.prepare(true); + const webExtension = new WebExtension(); - const backend = new Backend(application.webExtension); + const backend = new Backend(webExtension); await backend.prepare(); } diff --git a/ext/js/comm/cross-frame-api.js b/ext/js/comm/cross-frame-api.js index eb9bed38..8fbee20c 100644 --- a/ext/js/comm/cross-frame-api.js +++ b/ext/js/comm/cross-frame-api.js @@ -291,8 +291,10 @@ export class CrossFrameAPIPort extends EventDispatcher { export class CrossFrameAPI { /** * @param {import('../comm/api.js').API} api + * @param {?number} tabId + * @param {?number} frameId */ - constructor(api) { + constructor(api, tabId, frameId) { /** @type {import('../comm/api.js').API} */ this._api = api; /** @type {number} */ @@ -306,15 +308,14 @@ export class CrossFrameAPI { /** @type {(port: CrossFrameAPIPort) => void} */ this._onDisconnectBind = this._onDisconnect.bind(this); /** @type {?number} */ - this._tabId = null; + this._tabId = tabId; /** @type {?number} */ - this._frameId = null; + this._frameId = frameId; } /** */ - async prepare() { + prepare() { chrome.runtime.onConnect.addListener(this._onConnect.bind(this)); - ({tabId: this._tabId = null, frameId: this._frameId = null} = await this._api.frameInformationGet()); } /** diff --git a/ext/js/display/popup-main.js b/ext/js/display/popup-main.js index 2ca2fcd3..a244c2e0 100644 --- a/ext/js/display/popup-main.js +++ b/ext/js/display/popup-main.js @@ -17,7 +17,6 @@ */ import {Application} from '../application.js'; -import {log} from '../core/logger.js'; import {DocumentFocusController} from '../dom/document-focus-controller.js'; import {HotkeyHandler} from '../input/hotkey-handler.js'; import {DisplayAnki} from './display-anki.js'; @@ -26,43 +25,31 @@ import {DisplayProfileSelection} from './display-profile-selection.js'; import {DisplayResizer} from './display-resizer.js'; import {Display} from './display.js'; -/** Entry point. */ -async function main() { - try { - const documentFocusController = new DocumentFocusController(); - documentFocusController.prepare(); +await Application.main(async (application) => { + const documentFocusController = new DocumentFocusController(); + documentFocusController.prepare(); - const application = new Application(); - await application.prepare(); + const {tabId, frameId} = await application.api.frameInformationGet(); - const {tabId, frameId} = await application.api.frameInformationGet(); + const hotkeyHandler = new HotkeyHandler(); + hotkeyHandler.prepare(application.crossFrame); - const hotkeyHandler = new HotkeyHandler(); - hotkeyHandler.prepare(application.crossFrame); + const display = new Display(application, tabId, frameId, 'popup', documentFocusController, hotkeyHandler); + await display.prepare(); - const display = new Display(application, tabId, frameId, 'popup', documentFocusController, hotkeyHandler); - await display.prepare(); + const displayAudio = new DisplayAudio(display); + displayAudio.prepare(); - const displayAudio = new DisplayAudio(display); - displayAudio.prepare(); + const displayAnki = new DisplayAnki(display, displayAudio); + displayAnki.prepare(); - const displayAnki = new DisplayAnki(display, displayAudio); - displayAnki.prepare(); + const displayProfileSelection = new DisplayProfileSelection(display); + displayProfileSelection.prepare(); - const displayProfileSelection = new DisplayProfileSelection(display); - displayProfileSelection.prepare(); + const displayResizer = new DisplayResizer(display); + displayResizer.prepare(); - const displayResizer = new DisplayResizer(display); - displayResizer.prepare(); + display.initializeState(); - display.initializeState(); - - document.documentElement.dataset.loaded = 'true'; - - application.ready(); - } catch (e) { - log.error(e); - } -} - -await main(); + document.documentElement.dataset.loaded = 'true'; +}); diff --git a/ext/js/display/search-main.js b/ext/js/display/search-main.js index dc4f1b7e..5c6a31ca 100644 --- a/ext/js/display/search-main.js +++ b/ext/js/display/search-main.js @@ -17,7 +17,6 @@ */ import {Application} from '../application.js'; -import {log} from '../core/logger.js'; import {DocumentFocusController} from '../dom/document-focus-controller.js'; import {HotkeyHandler} from '../input/hotkey-handler.js'; import {DisplayAnki} from './display-anki.js'; @@ -27,47 +26,34 @@ import {SearchActionPopupController} from './search-action-popup-controller.js'; import {SearchDisplayController} from './search-display-controller.js'; import {SearchPersistentStateController} from './search-persistent-state-controller.js'; -/** Entry point. */ -async function main() { - try { - const application = new Application(); +await Application.main(async (application) => { + const documentFocusController = new DocumentFocusController('#search-textbox'); + documentFocusController.prepare(); - const documentFocusController = new DocumentFocusController('#search-textbox'); - documentFocusController.prepare(); + const searchPersistentStateController = new SearchPersistentStateController(); + searchPersistentStateController.prepare(); - const searchPersistentStateController = new SearchPersistentStateController(); - searchPersistentStateController.prepare(); + const searchActionPopupController = new SearchActionPopupController(searchPersistentStateController); + searchActionPopupController.prepare(); - const searchActionPopupController = new SearchActionPopupController(searchPersistentStateController); - searchActionPopupController.prepare(); + const {tabId, frameId} = await application.api.frameInformationGet(); - await application.prepare(); + const hotkeyHandler = new HotkeyHandler(); + hotkeyHandler.prepare(application.crossFrame); - const {tabId, frameId} = await application.api.frameInformationGet(); + const display = new Display(application, tabId, frameId, 'search', documentFocusController, hotkeyHandler); + await display.prepare(); - const hotkeyHandler = new HotkeyHandler(); - hotkeyHandler.prepare(application.crossFrame); + const displayAudio = new DisplayAudio(display); + displayAudio.prepare(); - const display = new Display(application, tabId, frameId, 'search', documentFocusController, hotkeyHandler); - await display.prepare(); + const displayAnki = new DisplayAnki(display, displayAudio); + displayAnki.prepare(); - const displayAudio = new DisplayAudio(display); - displayAudio.prepare(); + const searchDisplayController = new SearchDisplayController(tabId, frameId, display, displayAudio, searchPersistentStateController); + await searchDisplayController.prepare(); - const displayAnki = new DisplayAnki(display, displayAudio); - displayAnki.prepare(); + display.initializeState(); - const searchDisplayController = new SearchDisplayController(tabId, frameId, display, displayAudio, searchPersistentStateController); - await searchDisplayController.prepare(); - - display.initializeState(); - - document.documentElement.dataset.loaded = 'true'; - - application.ready(); - } catch (e) { - log.error(e); - } -} - -await main(); + document.documentElement.dataset.loaded = 'true'; +}); diff --git a/ext/js/pages/action-popup-main.js b/ext/js/pages/action-popup-main.js index 6d2c85ab..e5738878 100644 --- a/ext/js/pages/action-popup-main.js +++ b/ext/js/pages/action-popup-main.js @@ -305,17 +305,9 @@ class DisplayController { } } -/** Entry point. */ -async function main() { - const application = new Application(); - await application.prepare(); - +await Application.main(async (application) => { application.api.logIndicatorClear(); const displayController = new DisplayController(application.api); displayController.prepare(); - - application.ready(); -} - -await main(); +}); diff --git a/ext/js/pages/info-main.js b/ext/js/pages/info-main.js index ca5094b1..7d7d56a5 100644 --- a/ext/js/pages/info-main.js +++ b/ext/js/pages/info-main.js @@ -17,7 +17,6 @@ */ import {Application} from '../application.js'; -import {log} from '../core/logger.js'; import {promiseTimeout} from '../core/utilities.js'; import {DocumentFocusController} from '../dom/document-focus-controller.js'; import {querySelectorNotNull} from '../dom/query-selector.js'; @@ -116,59 +115,49 @@ async function showDictionaryInfo(api) { container.appendChild(fragment); } -/** Entry point. */ -async function main() { - try { - const documentFocusController = new DocumentFocusController(); - documentFocusController.prepare(); - - const manifest = chrome.runtime.getManifest(); - const language = chrome.i18n.getUILanguage(); - - const application = new Application(); - await application.prepare(); +await Application.main(async (application) => { + const documentFocusController = new DocumentFocusController(); + documentFocusController.prepare(); - const {userAgent} = navigator; - const {name, version} = manifest; - const {browser, platform: {os}} = await application.api.getEnvironmentInfo(); + const manifest = chrome.runtime.getManifest(); + const language = chrome.i18n.getUILanguage(); - /** @type {HTMLLinkElement} */ - const thisVersionLink = querySelectorNotNull(document, '#release-notes-this-version-link'); - const {hrefFormat} = thisVersionLink.dataset; - thisVersionLink.href = typeof hrefFormat === 'string' ? hrefFormat.replace(/\{version\}/g, version) : ''; + const {userAgent} = navigator; + const {name, version} = manifest; + const {browser, platform: {os}} = await application.api.getEnvironmentInfo(); - /** @type {HTMLElement} */ - const versionElement = querySelectorNotNull(document, '#version'); - /** @type {HTMLElement} */ - const browserElement = querySelectorNotNull(document, '#browser'); - /** @type {HTMLElement} */ - const platformElement = querySelectorNotNull(document, '#platform'); - /** @type {HTMLElement} */ - const languageElement = querySelectorNotNull(document, '#language'); - /** @type {HTMLElement} */ - const userAgentElement = querySelectorNotNull(document, '#user-agent'); + /** @type {HTMLLinkElement} */ + const thisVersionLink = querySelectorNotNull(document, '#release-notes-this-version-link'); + const {hrefFormat} = thisVersionLink.dataset; + thisVersionLink.href = typeof hrefFormat === 'string' ? hrefFormat.replace(/\{version\}/g, version) : ''; - versionElement.textContent = `${name} ${version}`; - browserElement.textContent = getBrowserDisplayName(browser); - platformElement.textContent = getOperatingSystemDisplayName(os); - languageElement.textContent = `${language}`; - userAgentElement.textContent = userAgent; + /** @type {HTMLElement} */ + const versionElement = querySelectorNotNull(document, '#version'); + /** @type {HTMLElement} */ + const browserElement = querySelectorNotNull(document, '#browser'); + /** @type {HTMLElement} */ + const platformElement = querySelectorNotNull(document, '#platform'); + /** @type {HTMLElement} */ + const languageElement = querySelectorNotNull(document, '#language'); + /** @type {HTMLElement} */ + const userAgentElement = querySelectorNotNull(document, '#user-agent'); - showAnkiConnectInfo(application.api); - showDictionaryInfo(application.api); + versionElement.textContent = `${name} ${version}`; + browserElement.textContent = getBrowserDisplayName(browser); + platformElement.textContent = getOperatingSystemDisplayName(os); + languageElement.textContent = `${language}`; + userAgentElement.textContent = userAgent; - const settingsController = new SettingsController(application); - await settingsController.prepare(); + showAnkiConnectInfo(application.api); + showDictionaryInfo(application.api); - const backupController = new BackupController(settingsController, null); - await backupController.prepare(); + const settingsController = new SettingsController(application); + await settingsController.prepare(); - await promiseTimeout(100); + const backupController = new BackupController(settingsController, null); + await backupController.prepare(); - document.documentElement.dataset.loaded = 'true'; - } catch (e) { - log.error(e); - } -} + await promiseTimeout(100); -await main(); + document.documentElement.dataset.loaded = 'true'; +}); diff --git a/ext/js/pages/permissions-main.js b/ext/js/pages/permissions-main.js index 1659bea5..3092782b 100644 --- a/ext/js/pages/permissions-main.js +++ b/ext/js/pages/permissions-main.js @@ -17,7 +17,6 @@ */ import {Application} from '../application.js'; -import {log} from '../core/logger.js'; import {promiseTimeout} from '../core/utilities.js'; import {DocumentFocusController} from '../dom/document-focus-controller.js'; import {querySelectorNotNull} from '../dom/query-selector.js'; @@ -87,63 +86,52 @@ function setupPermissionsToggles() { } } -/** Entry point. */ -async function main() { - try { - const application = new Application(); +await Application.main(async (application) => { + const documentFocusController = new DocumentFocusController(); + documentFocusController.prepare(); - const documentFocusController = new DocumentFocusController(); - documentFocusController.prepare(); + const extensionContentController = new ExtensionContentController(); + extensionContentController.prepare(); - const extensionContentController = new ExtensionContentController(); - extensionContentController.prepare(); + setupPermissionsToggles(); - setupPermissionsToggles(); + setupEnvironmentInfo(application.api); - await application.prepare(); + /** @type {HTMLInputElement} */ + const permissionCheckbox1 = querySelectorNotNull(document, '#permission-checkbox-allow-in-private-windows'); + /** @type {HTMLInputElement} */ + const permissionCheckbox2 = querySelectorNotNull(document, '#permission-checkbox-allow-file-url-access'); + /** @type {HTMLInputElement[]} */ + const permissionsCheckboxes = [permissionCheckbox1, permissionCheckbox2]; - setupEnvironmentInfo(application.api); + const permissions = await Promise.all([ + isAllowedIncognitoAccess(), + isAllowedFileSchemeAccess() + ]); - /** @type {HTMLInputElement} */ - const permissionCheckbox1 = querySelectorNotNull(document, '#permission-checkbox-allow-in-private-windows'); - /** @type {HTMLInputElement} */ - const permissionCheckbox2 = querySelectorNotNull(document, '#permission-checkbox-allow-file-url-access'); - /** @type {HTMLInputElement[]} */ - const permissionsCheckboxes = [permissionCheckbox1, permissionCheckbox2]; - - const permissions = await Promise.all([ - isAllowedIncognitoAccess(), - isAllowedFileSchemeAccess() - ]); - - for (let i = 0, ii = permissions.length; i < ii; ++i) { - permissionsCheckboxes[i].checked = permissions[i]; - } - - const modalController = new ModalController(); - modalController.prepare(); + for (let i = 0, ii = permissions.length; i < ii; ++i) { + permissionsCheckboxes[i].checked = permissions[i]; + } - const settingsController = new SettingsController(application); - await settingsController.prepare(); + const modalController = new ModalController(); + modalController.prepare(); - const permissionsToggleController = new PermissionsToggleController(settingsController); - permissionsToggleController.prepare(); + const settingsController = new SettingsController(application); + await settingsController.prepare(); - const permissionsOriginController = new PermissionsOriginController(settingsController); - permissionsOriginController.prepare(); + const permissionsToggleController = new PermissionsToggleController(settingsController); + permissionsToggleController.prepare(); - const persistentStorageController = new PersistentStorageController(application); - persistentStorageController.prepare(); + const permissionsOriginController = new PermissionsOriginController(settingsController); + permissionsOriginController.prepare(); - await promiseTimeout(100); + const persistentStorageController = new PersistentStorageController(application); + persistentStorageController.prepare(); - document.documentElement.dataset.loaded = 'true'; + await promiseTimeout(100); - const settingsDisplayController = new SettingsDisplayController(settingsController, modalController); - settingsDisplayController.prepare(); - } catch (e) { - log.error(e); - } -} + document.documentElement.dataset.loaded = 'true'; -await main(); + const settingsDisplayController = new SettingsDisplayController(settingsController, modalController); + settingsDisplayController.prepare(); +}); diff --git a/ext/js/pages/settings/popup-preview-frame-main.js b/ext/js/pages/settings/popup-preview-frame-main.js index fd08bf1d..cffbf01b 100644 --- a/ext/js/pages/settings/popup-preview-frame-main.js +++ b/ext/js/pages/settings/popup-preview-frame-main.js @@ -18,37 +18,26 @@ import {PopupFactory} from '../../app/popup-factory.js'; import {Application} from '../../application.js'; -import {log} from '../../core/logger.js'; import {HotkeyHandler} from '../../input/hotkey-handler.js'; import {PopupPreviewFrame} from './popup-preview-frame.js'; -/** Entry point. */ -async function main() { - try { - const application = new Application(); - await application.prepare(); - - const {tabId, frameId} = await application.api.frameInformationGet(); - if (typeof tabId === 'undefined') { - throw new Error('Failed to get tabId'); - } - if (typeof frameId === 'undefined') { - throw new Error('Failed to get frameId'); - } - - const hotkeyHandler = new HotkeyHandler(); - hotkeyHandler.prepare(application.crossFrame); +await Application.main(async (application) => { + const {tabId, frameId} = await application.api.frameInformationGet(); + if (typeof tabId === 'undefined') { + throw new Error('Failed to get tabId'); + } + if (typeof frameId === 'undefined') { + throw new Error('Failed to get frameId'); + } - const popupFactory = new PopupFactory(application, frameId); - popupFactory.prepare(); + const hotkeyHandler = new HotkeyHandler(); + hotkeyHandler.prepare(application.crossFrame); - const preview = new PopupPreviewFrame(application, tabId, frameId, popupFactory, hotkeyHandler); - await preview.prepare(); + const popupFactory = new PopupFactory(application, frameId); + popupFactory.prepare(); - document.documentElement.dataset.loaded = 'true'; - } catch (e) { - log.error(e); - } -} + const preview = new PopupPreviewFrame(application, tabId, frameId, popupFactory, hotkeyHandler); + await preview.prepare(); -await main(); + document.documentElement.dataset.loaded = 'true'; +}); diff --git a/ext/js/pages/settings/settings-main.js b/ext/js/pages/settings/settings-main.js index c3391173..dc4b36c9 100644 --- a/ext/js/pages/settings/settings-main.js +++ b/ext/js/pages/settings/settings-main.js @@ -17,7 +17,6 @@ */ import {Application} from '../../application.js'; -import {log} from '../../core/logger.js'; import {DocumentFocusController} from '../../dom/document-focus-controller.js'; import {querySelectorNotNull} from '../../dom/query-selector.js'; import {ExtensionContentController} from '../common/extension-content-controller.js'; @@ -58,124 +57,114 @@ async function setupGenericSettingController(genericSettingController) { await genericSettingController.refresh(); } -/** Entry point. */ -async function main() { - try { - const documentFocusController = new DocumentFocusController(); - documentFocusController.prepare(); +await Application.main(async (application) => { + const documentFocusController = new DocumentFocusController(); + documentFocusController.prepare(); - const extensionContentController = new ExtensionContentController(); - extensionContentController.prepare(); + const extensionContentController = new ExtensionContentController(); + extensionContentController.prepare(); - /** @type {HTMLElement} */ - const statusFooterElement = querySelectorNotNull(document, '.status-footer-container'); - const statusFooter = new StatusFooter(statusFooterElement); - statusFooter.prepare(); + /** @type {HTMLElement} */ + const statusFooterElement = querySelectorNotNull(document, '.status-footer-container'); + const statusFooter = new StatusFooter(statusFooterElement); + statusFooter.prepare(); - /** @type {?number} */ - let prepareTimer = window.setTimeout(() => { - prepareTimer = null; - document.documentElement.dataset.loadingStalled = 'true'; - }, 1000); + /** @type {?number} */ + let prepareTimer = window.setTimeout(() => { + prepareTimer = null; + document.documentElement.dataset.loadingStalled = 'true'; + }, 1000); - const application = new Application(); - await application.prepare(); - - if (prepareTimer !== null) { - clearTimeout(prepareTimer); - prepareTimer = null; - } - delete document.documentElement.dataset.loadingStalled; - - const preparePromises = []; + if (prepareTimer !== null) { + clearTimeout(prepareTimer); + prepareTimer = null; + } + delete document.documentElement.dataset.loadingStalled; - const modalController = new ModalController(); - modalController.prepare(); + const preparePromises = []; - const settingsController = new SettingsController(application); - await settingsController.prepare(); + const modalController = new ModalController(); + modalController.prepare(); - const persistentStorageController = new PersistentStorageController(application); - persistentStorageController.prepare(); + const settingsController = new SettingsController(application); + await settingsController.prepare(); - const storageController = new StorageController(persistentStorageController); - storageController.prepare(); + const persistentStorageController = new PersistentStorageController(application); + persistentStorageController.prepare(); - const dictionaryController = new DictionaryController(settingsController, modalController, statusFooter); - dictionaryController.prepare(); + const storageController = new StorageController(persistentStorageController); + storageController.prepare(); - const dictionaryImportController = new DictionaryImportController(settingsController, modalController, statusFooter); - dictionaryImportController.prepare(); + const dictionaryController = new DictionaryController(settingsController, modalController, statusFooter); + dictionaryController.prepare(); - const genericSettingController = new GenericSettingController(settingsController); - preparePromises.push(setupGenericSettingController(genericSettingController)); + const dictionaryImportController = new DictionaryImportController(settingsController, modalController, statusFooter); + dictionaryImportController.prepare(); - const audioController = new AudioController(settingsController, modalController); - audioController.prepare(); + const genericSettingController = new GenericSettingController(settingsController); + preparePromises.push(setupGenericSettingController(genericSettingController)); - const profileController = new ProfileController(settingsController, modalController); - profileController.prepare(); + const audioController = new AudioController(settingsController, modalController); + audioController.prepare(); - const settingsBackup = new BackupController(settingsController, modalController); - settingsBackup.prepare(); + const profileController = new ProfileController(settingsController, modalController); + profileController.prepare(); - const ankiController = new AnkiController(settingsController); - ankiController.prepare(); + const settingsBackup = new BackupController(settingsController, modalController); + settingsBackup.prepare(); - const ankiTemplatesController = new AnkiTemplatesController(settingsController, modalController, ankiController); - ankiTemplatesController.prepare(); + const ankiController = new AnkiController(settingsController); + ankiController.prepare(); - const popupPreviewController = new PopupPreviewController(settingsController); - popupPreviewController.prepare(); + const ankiTemplatesController = new AnkiTemplatesController(settingsController, modalController, ankiController); + ankiTemplatesController.prepare(); - const scanInputsController = new ScanInputsController(settingsController); - scanInputsController.prepare(); + const popupPreviewController = new PopupPreviewController(settingsController); + popupPreviewController.prepare(); - const simpleScanningInputController = new ScanInputsSimpleController(settingsController); - simpleScanningInputController.prepare(); + const scanInputsController = new ScanInputsController(settingsController); + scanInputsController.prepare(); - const nestedPopupsController = new NestedPopupsController(settingsController); - nestedPopupsController.prepare(); + const simpleScanningInputController = new ScanInputsSimpleController(settingsController); + simpleScanningInputController.prepare(); - const permissionsToggleController = new PermissionsToggleController(settingsController); - permissionsToggleController.prepare(); + const nestedPopupsController = new NestedPopupsController(settingsController); + nestedPopupsController.prepare(); - const secondarySearchDictionaryController = new SecondarySearchDictionaryController(settingsController); - secondarySearchDictionaryController.prepare(); + const permissionsToggleController = new PermissionsToggleController(settingsController); + permissionsToggleController.prepare(); - const translationTextReplacementsController = new TranslationTextReplacementsController(settingsController); - translationTextReplacementsController.prepare(); + const secondarySearchDictionaryController = new SecondarySearchDictionaryController(settingsController); + secondarySearchDictionaryController.prepare(); - const sentenceTerminationCharactersController = new SentenceTerminationCharactersController(settingsController); - sentenceTerminationCharactersController.prepare(); + const translationTextReplacementsController = new TranslationTextReplacementsController(settingsController); + translationTextReplacementsController.prepare(); - const keyboardShortcutController = new KeyboardShortcutController(settingsController); - keyboardShortcutController.prepare(); + const sentenceTerminationCharactersController = new SentenceTerminationCharactersController(settingsController); + sentenceTerminationCharactersController.prepare(); - const extensionKeyboardShortcutController = new ExtensionKeyboardShortcutController(settingsController); - extensionKeyboardShortcutController.prepare(); + const keyboardShortcutController = new KeyboardShortcutController(settingsController); + keyboardShortcutController.prepare(); - const popupWindowController = new PopupWindowController(application.api); - popupWindowController.prepare(); + const extensionKeyboardShortcutController = new ExtensionKeyboardShortcutController(settingsController); + extensionKeyboardShortcutController.prepare(); - const mecabController = new MecabController(application.api); - mecabController.prepare(); + const popupWindowController = new PopupWindowController(application.api); + popupWindowController.prepare(); - const collapsibleDictionaryController = new CollapsibleDictionaryController(settingsController); - collapsibleDictionaryController.prepare(); + const mecabController = new MecabController(application.api); + mecabController.prepare(); - const sortFrequencyDictionaryController = new SortFrequencyDictionaryController(settingsController); - sortFrequencyDictionaryController.prepare(); + const collapsibleDictionaryController = new CollapsibleDictionaryController(settingsController); + collapsibleDictionaryController.prepare(); - await Promise.all(preparePromises); + const sortFrequencyDictionaryController = new SortFrequencyDictionaryController(settingsController); + sortFrequencyDictionaryController.prepare(); - document.documentElement.dataset.loaded = 'true'; + await Promise.all(preparePromises); - const settingsDisplayController = new SettingsDisplayController(settingsController, modalController); - settingsDisplayController.prepare(); - } catch (e) { - log.error(e); - } -} + document.documentElement.dataset.loaded = 'true'; -await main(); + const settingsDisplayController = new SettingsDisplayController(settingsController, modalController); + settingsDisplayController.prepare(); +}); diff --git a/ext/js/pages/welcome-main.js b/ext/js/pages/welcome-main.js index 030d2826..82afaacb 100644 --- a/ext/js/pages/welcome-main.js +++ b/ext/js/pages/welcome-main.js @@ -17,7 +17,6 @@ */ import {Application} from '../application.js'; -import {log} from '../core/logger.js'; import {DocumentFocusController} from '../dom/document-focus-controller.js'; import {querySelectorNotNull} from '../dom/query-selector.js'; import {ExtensionContentController} from './common/extension-content-controller.js'; @@ -50,64 +49,54 @@ async function setupGenericSettingsController(genericSettingController) { await genericSettingController.refresh(); } -/** Entry point. */ -async function main() { - try { - const documentFocusController = new DocumentFocusController(); - documentFocusController.prepare(); +await Application.main(async (application) => { + const documentFocusController = new DocumentFocusController(); + documentFocusController.prepare(); - const extensionContentController = new ExtensionContentController(); - extensionContentController.prepare(); + const extensionContentController = new ExtensionContentController(); + extensionContentController.prepare(); - /** @type {HTMLElement} */ - const statusFooterElement = querySelectorNotNull(document, '.status-footer-container'); - const statusFooter = new StatusFooter(statusFooterElement); - statusFooter.prepare(); + /** @type {HTMLElement} */ + const statusFooterElement = querySelectorNotNull(document, '.status-footer-container'); + const statusFooter = new StatusFooter(statusFooterElement); + statusFooter.prepare(); - const application = new Application(); - await application.prepare(); + setupEnvironmentInfo(application.api); - setupEnvironmentInfo(application.api); + chrome.storage.session.get({'needsCustomTemplatesWarning': false}).then((result) => { + if (result.needsCustomTemplatesWarning) { + document.documentElement.dataset.warnCustomTemplates = 'true'; + chrome.storage.session.remove(['needsCustomTemplatesWarning']); + } + }); - chrome.storage.session.get({'needsCustomTemplatesWarning': false}).then((result) => { - if (result.needsCustomTemplatesWarning) { - document.documentElement.dataset.warnCustomTemplates = 'true'; - chrome.storage.session.remove(['needsCustomTemplatesWarning']); - } - }); + const preparePromises = []; - const preparePromises = []; + const modalController = new ModalController(); + modalController.prepare(); - const modalController = new ModalController(); - modalController.prepare(); + const settingsController = new SettingsController(application); + await settingsController.prepare(); - const settingsController = new SettingsController(application); - await settingsController.prepare(); + const dictionaryController = new DictionaryController(settingsController, modalController, statusFooter); + dictionaryController.prepare(); - const dictionaryController = new DictionaryController(settingsController, modalController, statusFooter); - dictionaryController.prepare(); + const dictionaryImportController = new DictionaryImportController(settingsController, modalController, statusFooter); + dictionaryImportController.prepare(); - const dictionaryImportController = new DictionaryImportController(settingsController, modalController, statusFooter); - dictionaryImportController.prepare(); + const genericSettingController = new GenericSettingController(settingsController); + preparePromises.push(setupGenericSettingsController(genericSettingController)); - const genericSettingController = new GenericSettingController(settingsController); - preparePromises.push(setupGenericSettingsController(genericSettingController)); + const simpleScanningInputController = new ScanInputsSimpleController(settingsController); + simpleScanningInputController.prepare(); - const simpleScanningInputController = new ScanInputsSimpleController(settingsController); - simpleScanningInputController.prepare(); + const recommendedPermissionsController = new RecommendedPermissionsController(settingsController); + recommendedPermissionsController.prepare(); - const recommendedPermissionsController = new RecommendedPermissionsController(settingsController); - recommendedPermissionsController.prepare(); + await Promise.all(preparePromises); - await Promise.all(preparePromises); + document.documentElement.dataset.loaded = 'true'; - document.documentElement.dataset.loaded = 'true'; - - const settingsDisplayController = new SettingsDisplayController(settingsController, modalController); - settingsDisplayController.prepare(); - } catch (e) { - log.error(e); - } -} - -await main(); + const settingsDisplayController = new SettingsDisplayController(settingsController, modalController); + settingsDisplayController.prepare(); +}); |