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(); +}); |