aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2024-02-07 02:55:48 -0500
committerGitHub <noreply@github.com>2024-02-07 07:55:48 +0000
commitdc22c0260e55121b2930f8bf8761271ba977503f (patch)
tree1c5cf6d59fb600dfc03e46f11d3fba3dfb30c8f1
parent376bac7195bf2114da8b234ffa64af9751b4466d (diff)
Update application init process (#634)
-rw-r--r--ext/js/app/content-script-main.js67
-rw-r--r--ext/js/application.js92
-rw-r--r--ext/js/background/background-main.js7
-rw-r--r--ext/js/comm/cross-frame-api.js11
-rw-r--r--ext/js/display/popup-main.js51
-rw-r--r--ext/js/display/search-main.js56
-rw-r--r--ext/js/pages/action-popup-main.js12
-rw-r--r--ext/js/pages/info-main.js83
-rw-r--r--ext/js/pages/permissions-main.js82
-rw-r--r--ext/js/pages/settings/popup-preview-frame-main.js43
-rw-r--r--ext/js/pages/settings/settings-main.js165
-rw-r--r--ext/js/pages/welcome-main.js83
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();
+});