diff options
-rw-r--r-- | ext/js/app/content-script-main.js | 7 | ||||
-rw-r--r-- | ext/js/background/background-main.js | 9 | ||||
-rw-r--r-- | ext/js/background/offscreen-main.js | 7 | ||||
-rw-r--r-- | ext/js/core.js | 298 | ||||
-rw-r--r-- | ext/js/display/popup-main.js | 7 | ||||
-rw-r--r-- | ext/js/display/search-main.js | 7 | ||||
-rw-r--r-- | ext/js/language/dictionary-worker-main.js | 7 | ||||
-rw-r--r-- | ext/js/language/sandbox/japanese-util.js | 42 | ||||
-rw-r--r-- | ext/js/pages/action-popup-main.js | 9 | ||||
-rw-r--r-- | ext/js/pages/generic-page-main.js | 7 | ||||
-rw-r--r-- | ext/js/pages/info-main.js | 116 | ||||
-rw-r--r-- | ext/js/pages/permissions-main.js | 7 | ||||
-rw-r--r-- | ext/js/pages/settings/popup-preview-frame-main.js | 7 | ||||
-rw-r--r-- | ext/js/pages/settings/settings-main.js | 7 | ||||
-rw-r--r-- | ext/js/pages/welcome-main.js | 7 | ||||
-rw-r--r-- | ext/js/templates/sandbox/template-renderer-frame-main.js | 7 | ||||
-rw-r--r-- | jsconfig.json | 4 |
17 files changed, 288 insertions, 267 deletions
diff --git a/ext/js/app/content-script-main.js b/ext/js/app/content-script-main.js index 972d032c..7b76fda0 100644 --- a/ext/js/app/content-script-main.js +++ b/ext/js/app/content-script-main.js @@ -22,7 +22,8 @@ import {yomitan} from '../yomitan.js'; import {Frontend} from './frontend.js'; import {PopupFactory} from './popup-factory.js'; -(async () => { +/** Entry point. */ +async function main() { try { await yomitan.prepare(); @@ -57,4 +58,6 @@ import {PopupFactory} from './popup-factory.js'; } catch (e) { log.error(e); } -})(); +} + +await main(); diff --git a/ext/js/background/background-main.js b/ext/js/background/background-main.js index 8e32a53f..29c256d3 100644 --- a/ext/js/background/background-main.js +++ b/ext/js/background/background-main.js @@ -19,9 +19,12 @@ import {yomitan} from '../yomitan.js'; import {Backend} from './backend.js'; -(() => { +/** Entry point. */ +async function main() { yomitan.prepare(true); const backend = new Backend(); - backend.prepare(); -})(); + await backend.prepare(); +} + +main(); diff --git a/ext/js/background/offscreen-main.js b/ext/js/background/offscreen-main.js index dcbf978f..f85908bd 100644 --- a/ext/js/background/offscreen-main.js +++ b/ext/js/background/offscreen-main.js @@ -18,6 +18,9 @@ import {Offscreen} from './offscreen.js'; -(() => { +/** Entry point. */ +async function main() { new Offscreen(); -})(); +} + +await main(); diff --git a/ext/js/core.js b/ext/js/core.js index 5c0c964b..c95eae01 100644 --- a/ext/js/core.js +++ b/ext/js/core.js @@ -53,101 +53,91 @@ export function stringReverse(string) { * @returns {T} A new clone of the value. * @throws An error if the value is circular and cannot be cloned. */ -export const clone = (() => { - /** - * @template T - * @param {T} value - * @returns {T} - */ - // eslint-disable-next-line no-shadow, @typescript-eslint/no-shadow - function clone(value) { - if (value === null) { return /** @type {T} */ (null); } - switch (typeof value) { - case 'boolean': - case 'number': - case 'string': - case 'bigint': - case 'symbol': - case 'undefined': - return value; - default: - return cloneInternal(value, new Set()); - } +export function clone(value) { + if (value === null) { return /** @type {T} */ (null); } + switch (typeof value) { + case 'boolean': + case 'number': + case 'string': + case 'bigint': + case 'symbol': + case 'undefined': + return value; + default: + return cloneInternal(value, new Set()); } +} - /** - * @template [T=unknown] - * @param {T} value - * @param {Set<unknown>} visited - * @returns {T} - * @throws {Error} - */ - function cloneInternal(value, visited) { - if (value === null) { return /** @type {T} */ (null); } - switch (typeof value) { - case 'boolean': - case 'number': - case 'string': - case 'bigint': - case 'symbol': - case 'undefined': - return value; - case 'object': - return /** @type {T} */ ( +/** + * @template [T=unknown] + * @param {T} value + * @param {Set<unknown>} visited + * @returns {T} + * @throws {Error} + */ +function cloneInternal(value, visited) { + if (value === null) { return /** @type {T} */ (null); } + switch (typeof value) { + case 'boolean': + case 'number': + case 'string': + case 'bigint': + case 'symbol': + case 'undefined': + return value; + case 'object': + return /** @type {T} */ ( Array.isArray(value) ? cloneArray(value, visited) : cloneObject(/** @type {import('core').SerializableObject} */ (value), visited) - ); - default: - throw new Error(`Cannot clone object of type ${typeof value}`); - } + ); + default: + throw new Error(`Cannot clone object of type ${typeof value}`); } +} - /** - * @param {unknown[]} value - * @param {Set<unknown>} visited - * @returns {unknown[]} - * @throws {Error} - */ - function cloneArray(value, visited) { - if (visited.has(value)) { throw new Error('Circular'); } - try { - visited.add(value); - const result = []; - for (const item of value) { - result.push(cloneInternal(item, visited)); - } - return result; - } finally { - visited.delete(value); +/** + * @param {unknown[]} value + * @param {Set<unknown>} visited + * @returns {unknown[]} + * @throws {Error} + */ +function cloneArray(value, visited) { + if (visited.has(value)) { throw new Error('Circular'); } + try { + visited.add(value); + const result = []; + for (const item of value) { + result.push(cloneInternal(item, visited)); } + return result; + } finally { + visited.delete(value); } +} - /** - * @param {import('core').SerializableObject} value - * @param {Set<unknown>} visited - * @returns {import('core').SerializableObject} - * @throws {Error} - */ - function cloneObject(value, visited) { - if (visited.has(value)) { throw new Error('Circular'); } - try { - visited.add(value); - /** @type {import('core').SerializableObject} */ - const result = {}; - for (const key in value) { - if (Object.prototype.hasOwnProperty.call(value, key)) { - result[key] = cloneInternal(value[key], visited); - } +/** + * @param {import('core').SerializableObject} value + * @param {Set<unknown>} visited + * @returns {import('core').SerializableObject} + * @throws {Error} + */ +function cloneObject(value, visited) { + if (visited.has(value)) { throw new Error('Circular'); } + try { + visited.add(value); + /** @type {import('core').SerializableObject} */ + const result = {}; + for (const key in value) { + if (Object.prototype.hasOwnProperty.call(value, key)) { + result[key] = cloneInternal(value[key], visited); } - return result; - } finally { - visited.delete(value); } + return result; + } finally { + visited.delete(value); } - - return clone; -})(); +} /** * Checks if an object or value is deeply equal to another object or value. @@ -155,98 +145,88 @@ export const clone = (() => { * @param {unknown} value2 The second value to check. * @returns {boolean} `true` if the values are the same object, or deeply equal without cycles. `false` otherwise. */ -export const deepEqual = (() => { - /** - * @param {unknown} value1 - * @param {unknown} value2 - * @returns {boolean} - */ - // eslint-disable-next-line no-shadow, @typescript-eslint/no-shadow - function deepEqual(value1, value2) { - if (value1 === value2) { return true; } - - const type = typeof value1; - if (typeof value2 !== type) { return false; } - - switch (type) { - case 'object': - case 'function': - return deepEqualInternal(value1, value2, new Set()); - default: - return false; - } +export function deepEqual(value1, value2) { + if (value1 === value2) { return true; } + + const type = typeof value1; + if (typeof value2 !== type) { return false; } + + switch (type) { + case 'object': + case 'function': + return deepEqualInternal(value1, value2, new Set()); + default: + return false; } +} - /** - * @param {unknown} value1 - * @param {unknown} value2 - * @param {Set<unknown>} visited1 - * @returns {boolean} - */ - function deepEqualInternal(value1, value2, visited1) { - if (value1 === value2) { return true; } - - const type = typeof value1; - if (typeof value2 !== type) { return false; } - - switch (type) { - case 'object': - case 'function': - { - if (value1 === null || value2 === null) { return false; } - const array = Array.isArray(value1); - if (array !== Array.isArray(value2)) { return false; } - if (visited1.has(value1)) { return false; } - visited1.add(value1); - return ( +/** + * @param {unknown} value1 + * @param {unknown} value2 + * @param {Set<unknown>} visited1 + * @returns {boolean} + */ +function deepEqualInternal(value1, value2, visited1) { + if (value1 === value2) { return true; } + + const type = typeof value1; + if (typeof value2 !== type) { return false; } + + switch (type) { + case 'object': + case 'function': + { + if (value1 === null || value2 === null) { return false; } + const array = Array.isArray(value1); + if (array !== Array.isArray(value2)) { return false; } + if (visited1.has(value1)) { return false; } + visited1.add(value1); + return ( array ? areArraysEqual(/** @type {unknown[]} */ (value1), /** @type {unknown[]} */ (value2), visited1) : areObjectsEqual(/** @type {import('core').UnknownObject} */ (value1), /** @type {import('core').UnknownObject} */ (value2), visited1) - ); - } - default: - return false; + ); } + default: + return false; } +} - /** - * @param {import('core').UnknownObject} value1 - * @param {import('core').UnknownObject} value2 - * @param {Set<unknown>} visited1 - * @returns {boolean} - */ - function areObjectsEqual(value1, value2, visited1) { - const keys1 = Object.keys(value1); - const keys2 = Object.keys(value2); - if (keys1.length !== keys2.length) { return false; } - - const keys1Set = new Set(keys1); - for (const key of keys2) { - if (!keys1Set.has(key) || !deepEqualInternal(value1[key], value2[key], visited1)) { return false; } - } +/** + * @param {import('core').UnknownObject} value1 + * @param {import('core').UnknownObject} value2 + * @param {Set<unknown>} visited1 + * @returns {boolean} + */ +function areObjectsEqual(value1, value2, visited1) { + const keys1 = Object.keys(value1); + const keys2 = Object.keys(value2); + if (keys1.length !== keys2.length) { return false; } - return true; + const keys1Set = new Set(keys1); + for (const key of keys2) { + if (!keys1Set.has(key) || !deepEqualInternal(value1[key], value2[key], visited1)) { return false; } } - /** - * @param {unknown[]} value1 - * @param {unknown[]} value2 - * @param {Set<unknown>} visited1 - * @returns {boolean} - */ - function areArraysEqual(value1, value2, visited1) { - const length = value1.length; - if (length !== value2.length) { return false; } + return true; +} - for (let i = 0; i < length; ++i) { - if (!deepEqualInternal(value1[i], value2[i], visited1)) { return false; } - } +/** + * @param {unknown[]} value1 + * @param {unknown[]} value2 + * @param {Set<unknown>} visited1 + * @returns {boolean} + */ +function areArraysEqual(value1, value2, visited1) { + const length = value1.length; + if (length !== value2.length) { return false; } - return true; + for (let i = 0; i < length; ++i) { + if (!deepEqualInternal(value1[i], value2[i], visited1)) { return false; } } - return deepEqual; -})(); + return true; +} /** * Creates a new base-16 (lower case) string of a sequence of random bytes of the given length. diff --git a/ext/js/display/popup-main.js b/ext/js/display/popup-main.js index 6b07b63f..fdb95508 100644 --- a/ext/js/display/popup-main.js +++ b/ext/js/display/popup-main.js @@ -27,7 +27,8 @@ import {DisplayProfileSelection} from './display-profile-selection.js'; import {DisplayResizer} from './display-resizer.js'; import {Display} from './display.js'; -(async () => { +/** Entry point. */ +async function main() { try { const documentFocusController = new DocumentFocusController(); documentFocusController.prepare(); @@ -64,4 +65,6 @@ import {Display} from './display.js'; } catch (e) { log.error(e); } -})(); +} + +await main(); diff --git a/ext/js/display/search-main.js b/ext/js/display/search-main.js index 5eee08d1..fae7306a 100644 --- a/ext/js/display/search-main.js +++ b/ext/js/display/search-main.js @@ -29,7 +29,8 @@ import {SearchActionPopupController} from './search-action-popup-controller.js'; import {SearchDisplayController} from './search-display-controller.js'; import {SearchPersistentStateController} from './search-persistent-state-controller.js'; -(async () => { +/** Entry point. */ +async function main() { try { const documentFocusController = new DocumentFocusController('#search-textbox'); documentFocusController.prepare(); @@ -69,4 +70,6 @@ import {SearchPersistentStateController} from './search-persistent-state-control } catch (e) { log.error(e); } -})(); +} + +await main(); diff --git a/ext/js/language/dictionary-worker-main.js b/ext/js/language/dictionary-worker-main.js index 6d2386aa..8ae283b8 100644 --- a/ext/js/language/dictionary-worker-main.js +++ b/ext/js/language/dictionary-worker-main.js @@ -19,11 +19,14 @@ import {log} from '../core.js'; import {DictionaryWorkerHandler} from './dictionary-worker-handler.js'; -(() => { +/** Entry point. */ +function main() { try { const dictionaryWorkerHandler = new DictionaryWorkerHandler(); dictionaryWorkerHandler.prepare(); } catch (e) { log.error(e); } -})(); +} + +main(); diff --git a/ext/js/language/sandbox/japanese-util.js b/ext/js/language/sandbox/japanese-util.js index 9d36497a..7d9413a6 100644 --- a/ext/js/language/sandbox/japanese-util.js +++ b/ext/js/language/sandbox/japanese-util.js @@ -161,32 +161,26 @@ const VOWEL_TO_KANA_MAPPING = new Map([ ['', 'のノ'] ]); -const KANA_TO_VOWEL_MAPPING = (() => { - /** @type {Map<string, string>} */ - const map = new Map(); - for (const [vowel, characters] of VOWEL_TO_KANA_MAPPING) { - for (const character of characters) { - map.set(character, vowel); - } +/** @type {Map<string, string>} */ +const KANA_TO_VOWEL_MAPPING = new Map(); +for (const [vowel, characters] of VOWEL_TO_KANA_MAPPING) { + for (const character of characters) { + KANA_TO_VOWEL_MAPPING.set(character, vowel); } - return map; -})(); - -const DIACRITIC_MAPPING = (() => { - const kana = 'うゔ-かが-きぎ-くぐ-けげ-こご-さざ-しじ-すず-せぜ-そぞ-ただ-ちぢ-つづ-てで-とど-はばぱひびぴふぶぷへべぺほぼぽワヷ-ヰヸ-ウヴ-ヱヹ-ヲヺ-カガ-キギ-クグ-ケゲ-コゴ-サザ-シジ-スズ-セゼ-ソゾ-タダ-チヂ-ツヅ-テデ-トド-ハバパヒビピフブプヘベペホボポ'; - /** @type {Map<string, {character: string, type: import('japanese-util').DiacriticType}>} */ - const map = new Map(); - for (let i = 0, ii = kana.length; i < ii; i += 3) { - const character = kana[i]; - const dakuten = kana[i + 1]; - const handakuten = kana[i + 2]; - map.set(dakuten, {character, type: 'dakuten'}); - if (handakuten !== '-') { - map.set(handakuten, {character, type: 'handakuten'}); - } +} + +const kana = 'うゔ-かが-きぎ-くぐ-けげ-こご-さざ-しじ-すず-せぜ-そぞ-ただ-ちぢ-つづ-てで-とど-はばぱひびぴふぶぷへべぺほぼぽワヷ-ヰヸ-ウヴ-ヱヹ-ヲヺ-カガ-キギ-クグ-ケゲ-コゴ-サザ-シジ-スズ-セゼ-ソゾ-タダ-チヂ-ツヅ-テデ-トド-ハバパヒビピフブプヘベペホボポ'; +/** @type {Map<string, {character: string, type: import('japanese-util').DiacriticType}>} */ +const DIACRITIC_MAPPING = new Map(); +for (let i = 0, ii = kana.length; i < ii; i += 3) { + const character = kana[i]; + const dakuten = kana[i + 1]; + const handakuten = kana[i + 2]; + DIACRITIC_MAPPING.set(dakuten, {character, type: 'dakuten'}); + if (handakuten !== '-') { + DIACRITIC_MAPPING.set(handakuten, {character, type: 'handakuten'}); } - return map; -})(); +} /** diff --git a/ext/js/pages/action-popup-main.js b/ext/js/pages/action-popup-main.js index f8dd865f..9f72cc82 100644 --- a/ext/js/pages/action-popup-main.js +++ b/ext/js/pages/action-popup-main.js @@ -21,7 +21,7 @@ import {querySelectorNotNull} from '../dom/query-selector.js'; import {HotkeyHelpController} from '../input/hotkey-help-controller.js'; import {yomitan} from '../yomitan.js'; -export class DisplayController { +class DisplayController { constructor() { /** @type {?import('settings').Options} */ this._optionsFull = null; @@ -302,7 +302,8 @@ export class DisplayController { } } -(async () => { +/** Entry point. */ +async function main() { await yomitan.prepare(); yomitan.api.logIndicatorClear(); @@ -311,4 +312,6 @@ export class DisplayController { displayController.prepare(); yomitan.ready(); -})(); +} + +await main(); diff --git a/ext/js/pages/generic-page-main.js b/ext/js/pages/generic-page-main.js index 176537ae..4bb4c7ac 100644 --- a/ext/js/pages/generic-page-main.js +++ b/ext/js/pages/generic-page-main.js @@ -19,7 +19,8 @@ import {DocumentFocusController} from '../dom/document-focus-controller.js'; import {ExtensionContentController} from './common/extension-content-controller.js'; -(() => { +/** Entry point. */ +function main() { const documentFocusController = new DocumentFocusController(); documentFocusController.prepare(); @@ -27,4 +28,6 @@ import {ExtensionContentController} from './common/extension-content-controller. extensionContentController.prepare(); document.documentElement.dataset.loaded = 'true'; -})(); +} + +main(); diff --git a/ext/js/pages/info-main.js b/ext/js/pages/info-main.js index 7445354f..593b7460 100644 --- a/ext/js/pages/info-main.js +++ b/ext/js/pages/info-main.js @@ -56,7 +56,63 @@ function getOperatingSystemDisplayName(os) { } } -(async () => { +/** */ +async function showAnkiConnectInfo() { + let ankiConnectVersion = null; + try { + ankiConnectVersion = await yomitan.api.getAnkiConnectVersion(); + } catch (e) { + // NOP + } + + /** @type {HTMLElement} */ + const ankiVersionElement = querySelectorNotNull(document, '#anki-connect-version'); + /** @type {HTMLElement} */ + const ankiVersionContainerElement = querySelectorNotNull(document, '#anki-connect-version-container'); + /** @type {HTMLElement} */ + const ankiVersionUnknownElement = querySelectorNotNull(document, '#anki-connect-version-unknown-message'); + + ankiVersionElement.textContent = (ankiConnectVersion !== null ? `${ankiConnectVersion}` : 'Unknown'); + ankiVersionContainerElement.dataset.hasError = `${ankiConnectVersion === null}`; + ankiVersionUnknownElement.hidden = (ankiConnectVersion !== null); +} + +/** */ +async function showDictionaryInfo() { + let dictionaryInfos; + try { + dictionaryInfos = await yomitan.api.getDictionaryInfo(); + } catch (e) { + return; + } + + const fragment = document.createDocumentFragment(); + let first = true; + for (const {title} of dictionaryInfos) { + if (first) { + first = false; + } else { + fragment.appendChild(document.createTextNode(', ')); + } + + const node = document.createElement('span'); + node.className = 'installed-dictionary'; + node.textContent = title; + fragment.appendChild(node); + } + + /** @type {HTMLElement} */ + const noneElement = querySelectorNotNull(document, '#installed-dictionaries-none'); + + noneElement.hidden = (dictionaryInfos.length !== 0); + /** @type {HTMLElement} */ + const container = querySelectorNotNull(document, '#installed-dictionaries'); + container.textContent = ''; + container.appendChild(fragment); +} + +/** Entry point. */ +async function main() { try { const documentFocusController = new DocumentFocusController(); documentFocusController.prepare(); @@ -92,58 +148,8 @@ function getOperatingSystemDisplayName(os) { languageElement.textContent = `${language}`; userAgentElement.textContent = userAgent; - (async () => { - let ankiConnectVersion = null; - try { - ankiConnectVersion = await yomitan.api.getAnkiConnectVersion(); - } catch (e) { - // NOP - } - - /** @type {HTMLElement} */ - const ankiVersionElement = querySelectorNotNull(document, '#anki-connect-version'); - /** @type {HTMLElement} */ - const ankiVersionContainerElement = querySelectorNotNull(document, '#anki-connect-version-container'); - /** @type {HTMLElement} */ - const ankiVersionUnknownElement = querySelectorNotNull(document, '#anki-connect-version-unknown-message'); - - ankiVersionElement.textContent = (ankiConnectVersion !== null ? `${ankiConnectVersion}` : 'Unknown'); - ankiVersionContainerElement.dataset.hasError = `${ankiConnectVersion === null}`; - ankiVersionUnknownElement.hidden = (ankiConnectVersion !== null); - })(); - - (async () => { - let dictionaryInfos; - try { - dictionaryInfos = await yomitan.api.getDictionaryInfo(); - } catch (e) { - return; - } - - const fragment = document.createDocumentFragment(); - let first = true; - for (const {title} of dictionaryInfos) { - if (first) { - first = false; - } else { - fragment.appendChild(document.createTextNode(', ')); - } - - const node = document.createElement('span'); - node.className = 'installed-dictionary'; - node.textContent = title; - fragment.appendChild(node); - } - - /** @type {HTMLElement} */ - const noneElement = querySelectorNotNull(document, '#installed-dictionaries-none'); - - noneElement.hidden = (dictionaryInfos.length !== 0); - /** @type {HTMLElement} */ - const container = querySelectorNotNull(document, '#installed-dictionaries'); - container.textContent = ''; - container.appendChild(fragment); - })(); + showAnkiConnectInfo(); + showDictionaryInfo(); const settingsController = new SettingsController(); await settingsController.prepare(); @@ -157,4 +163,6 @@ function getOperatingSystemDisplayName(os) { } catch (e) { log.error(e); } -})(); +} + +await main(); diff --git a/ext/js/pages/permissions-main.js b/ext/js/pages/permissions-main.js index 58dae310..e4ac3f3d 100644 --- a/ext/js/pages/permissions-main.js +++ b/ext/js/pages/permissions-main.js @@ -86,7 +86,8 @@ function setupPermissionsToggles() { } } -(async () => { +/** Entry point. */ +async function main() { try { const documentFocusController = new DocumentFocusController(); documentFocusController.prepare(); @@ -140,4 +141,6 @@ function setupPermissionsToggles() { } catch (e) { log.error(e); } -})(); +} + +await main(); diff --git a/ext/js/pages/settings/popup-preview-frame-main.js b/ext/js/pages/settings/popup-preview-frame-main.js index bce485fe..7b42e11a 100644 --- a/ext/js/pages/settings/popup-preview-frame-main.js +++ b/ext/js/pages/settings/popup-preview-frame-main.js @@ -22,7 +22,8 @@ import {HotkeyHandler} from '../../input/hotkey-handler.js'; import {yomitan} from '../../yomitan.js'; import {PopupPreviewFrame} from './popup-preview-frame.js'; -(async () => { +/** Entry point. */ +async function main() { try { await yomitan.prepare(); @@ -47,4 +48,6 @@ import {PopupPreviewFrame} from './popup-preview-frame.js'; } catch (e) { log.error(e); } -})(); +} + +await main(); diff --git a/ext/js/pages/settings/settings-main.js b/ext/js/pages/settings/settings-main.js index 3f0dac3f..3abe3bcf 100644 --- a/ext/js/pages/settings/settings-main.js +++ b/ext/js/pages/settings/settings-main.js @@ -58,7 +58,8 @@ async function setupGenericSettingsController(genericSettingController) { await genericSettingController.refresh(); } -(async () => { +/** Entry point. */ +async function main() { try { const documentFocusController = new DocumentFocusController(); documentFocusController.prepare(); @@ -174,4 +175,6 @@ async function setupGenericSettingsController(genericSettingController) { } catch (e) { log.error(e); } -})(); +} + +await main(); diff --git a/ext/js/pages/welcome-main.js b/ext/js/pages/welcome-main.js index d208e996..fbb60fe8 100644 --- a/ext/js/pages/welcome-main.js +++ b/ext/js/pages/welcome-main.js @@ -48,7 +48,8 @@ async function setupGenericSettingsController(genericSettingController) { await genericSettingController.refresh(); } -(async () => { +/** Entry point. */ +async function main() { try { const documentFocusController = new DocumentFocusController(); documentFocusController.prepare(); @@ -104,4 +105,6 @@ async function setupGenericSettingsController(genericSettingController) { } catch (e) { log.error(e); } -})(); +} + +await main(); diff --git a/ext/js/templates/sandbox/template-renderer-frame-main.js b/ext/js/templates/sandbox/template-renderer-frame-main.js index 43b17b1e..f5868aff 100644 --- a/ext/js/templates/sandbox/template-renderer-frame-main.js +++ b/ext/js/templates/sandbox/template-renderer-frame-main.js @@ -19,9 +19,12 @@ import {AnkiTemplateRenderer} from './anki-template-renderer.js'; import {TemplateRendererFrameApi} from './template-renderer-frame-api.js'; -(async () => { +/** Entry point. */ +async function main() { const ankiTemplateRenderer = new AnkiTemplateRenderer(); await ankiTemplateRenderer.prepare(); const templateRendererFrameApi = new TemplateRendererFrameApi(ankiTemplateRenderer.templateRenderer); templateRendererFrameApi.prepare(); -})(); +} + +await main(); diff --git a/jsconfig.json b/jsconfig.json index 0f780ead..82048af1 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { - "module": "ES2020", - "target": "ES2020", + "module": "ES2022", + "target": "ES2022", "checkJs": true, "moduleResolution": "node", "strict": true, |