aboutsummaryrefslogtreecommitdiff
path: root/ext/js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/js')
-rw-r--r--ext/js/accessibility/accessibility-controller.js5
-rw-r--r--ext/js/accessibility/google-docs-util.js9
-rw-r--r--ext/js/app/content-script-main.js10
-rw-r--r--ext/js/app/content-script-wrapper.js23
-rw-r--r--ext/js/app/frontend.js18
-rw-r--r--ext/js/app/popup-factory.js14
-rw-r--r--ext/js/app/popup-proxy.js7
-rw-r--r--ext/js/app/popup-window.js6
-rw-r--r--ext/js/app/popup.js14
-rw-r--r--ext/js/app/theme-controller.js2
-rw-r--r--ext/js/background/backend.js46
-rw-r--r--ext/js/background/background-main.js5
-rw-r--r--ext/js/background/offscreen-main.js4
-rw-r--r--ext/js/background/offscreen.js8
-rw-r--r--ext/js/background/profile-conditions-util.js6
-rw-r--r--ext/js/background/request-builder.js2
-rw-r--r--ext/js/background/script-manager.js3
-rw-r--r--ext/js/comm/anki-connect.js7
-rw-r--r--ext/js/comm/api.js4
-rw-r--r--ext/js/comm/clipboard-monitor.js4
-rw-r--r--ext/js/comm/clipboard-reader.js6
-rw-r--r--ext/js/comm/cross-frame-api.js5
-rw-r--r--ext/js/comm/frame-ancestry-handler.js5
-rw-r--r--ext/js/comm/frame-client.js4
-rw-r--r--ext/js/comm/frame-endpoint.js5
-rw-r--r--ext/js/comm/frame-offset-forwarder.js7
-rw-r--r--ext/js/comm/mecab.js4
-rw-r--r--ext/js/core.js34
-rw-r--r--ext/js/data/anki-note-builder.js10
-rw-r--r--ext/js/data/anki-util.js4
-rw-r--r--ext/js/data/database.js2
-rw-r--r--ext/js/data/json-schema.js7
-rw-r--r--ext/js/data/options-util.js9
-rw-r--r--ext/js/data/permissions-util.js6
-rw-r--r--ext/js/data/sandbox/anki-note-data-creator.js6
-rw-r--r--ext/js/data/sandbox/array-buffer-util.js2
-rw-r--r--ext/js/data/sandbox/string-util.js2
-rw-r--r--ext/js/debug/timer.js2
-rw-r--r--ext/js/display/display-anki.js12
-rw-r--r--ext/js/display/display-audio.js7
-rw-r--r--ext/js/display/display-content-manager.js8
-rw-r--r--ext/js/display/display-generator.js16
-rw-r--r--ext/js/display/display-history.js4
-rw-r--r--ext/js/display/display-notification.js4
-rw-r--r--ext/js/display/display-profile-selection.js8
-rw-r--r--ext/js/display/display-resizer.js4
-rw-r--r--ext/js/display/display.js40
-rw-r--r--ext/js/display/element-overflow-controller.js4
-rw-r--r--ext/js/display/option-toggle-hotkey-handler.js5
-rw-r--r--ext/js/display/popup-main.js11
-rw-r--r--ext/js/display/query-parser.js8
-rw-r--r--ext/js/display/sandbox/pronunciation-generator.js2
-rw-r--r--ext/js/display/sandbox/structured-content-generator.js2
-rw-r--r--ext/js/display/search-action-popup-controller.js2
-rw-r--r--ext/js/display/search-display-controller.js10
-rw-r--r--ext/js/display/search-main.js24
-rw-r--r--ext/js/display/search-persistent-state-controller.js4
-rw-r--r--ext/js/dom/document-focus-controller.js2
-rw-r--r--ext/js/dom/document-util.js11
-rw-r--r--ext/js/dom/dom-data-binder.js10
-rw-r--r--ext/js/dom/dom-text-scanner.js6
-rw-r--r--ext/js/dom/html-template-collection.js2
-rw-r--r--ext/js/dom/native-simple-dom-parser.js2
-rw-r--r--ext/js/dom/panel-element.js4
-rw-r--r--ext/js/dom/popup-menu.js4
-rw-r--r--ext/js/dom/sandbox/css-style-applier.js2
-rw-r--r--ext/js/dom/scroll-element.js2
-rw-r--r--ext/js/dom/selector-observer.js2
-rw-r--r--ext/js/dom/simple-dom-parser.js6
-rw-r--r--ext/js/dom/text-source-element.js9
-rw-r--r--ext/js/dom/text-source-range.js9
-rw-r--r--ext/js/extension/environment.js2
-rw-r--r--ext/js/general/cache-map.js3
-rw-r--r--ext/js/general/object-property-accessor.js2
-rw-r--r--ext/js/general/regex-util.js3
-rw-r--r--ext/js/general/task-accumulator.js4
-rw-r--r--ext/js/general/text-source-map.js2
-rw-r--r--ext/js/input/hotkey-handler.js8
-rw-r--r--ext/js/input/hotkey-help-controller.js8
-rw-r--r--ext/js/input/hotkey-util.js2
-rw-r--r--ext/js/language/__mocks__/dictionary-importer-media-loader.js24
-rw-r--r--ext/js/language/deinflector.js2
-rw-r--r--ext/js/language/dictionary-database.js7
-rw-r--r--ext/js/language/dictionary-importer-media-loader.js4
-rw-r--r--ext/js/language/dictionary-importer.js163
-rw-r--r--ext/js/language/dictionary-worker-handler.js11
-rw-r--r--ext/js/language/dictionary-worker-main.js18
-rw-r--r--ext/js/language/dictionary-worker-media-loader.js4
-rw-r--r--ext/js/language/dictionary-worker.js9
-rw-r--r--ext/js/language/sandbox/dictionary-data-util.js2
-rw-r--r--ext/js/language/sandbox/japanese-util.js2
-rw-r--r--ext/js/language/text-scanner.js8
-rw-r--r--ext/js/language/translator.js11
-rw-r--r--ext/js/media/audio-downloader.js14
-rw-r--r--ext/js/media/audio-system.js7
-rw-r--r--ext/js/media/media-util.js2
-rw-r--r--ext/js/media/text-to-speech-audio.js2
-rw-r--r--ext/js/pages/action-popup-main.js9
-rw-r--r--ext/js/pages/common/extension-content-controller.js6
-rw-r--r--ext/js/pages/generic-page-main.js6
-rw-r--r--ext/js/pages/info-main.js10
-rw-r--r--ext/js/pages/permissions-main.js20
-rw-r--r--ext/js/pages/settings/anki-controller.js16
-rw-r--r--ext/js/pages/settings/anki-templates-controller.js10
-rw-r--r--ext/js/pages/settings/audio-controller.js7
-rw-r--r--ext/js/pages/settings/backup-controller.js16
-rw-r--r--ext/js/pages/settings/collapsible-dictionary-controller.js7
-rw-r--r--ext/js/pages/settings/dictionary-controller.js6
-rw-r--r--ext/js/pages/settings/dictionary-import-controller.js10
-rw-r--r--ext/js/pages/settings/extension-keyboard-shortcuts-controller.js10
-rw-r--r--ext/js/pages/settings/generic-setting-controller.js9
-rw-r--r--ext/js/pages/settings/keyboard-mouse-input-field.js9
-rw-r--r--ext/js/pages/settings/keyboard-shortcuts-controller.js12
-rw-r--r--ext/js/pages/settings/mecab-controller.js4
-rw-r--r--ext/js/pages/settings/modal-controller.js6
-rw-r--r--ext/js/pages/settings/modal.js6
-rw-r--r--ext/js/pages/settings/nested-popups-controller.js6
-rw-r--r--ext/js/pages/settings/permissions-origin-controller.js4
-rw-r--r--ext/js/pages/settings/permissions-toggle-controller.js6
-rw-r--r--ext/js/pages/settings/persistent-storage-controller.js5
-rw-r--r--ext/js/pages/settings/popup-preview-controller.js2
-rw-r--r--ext/js/pages/settings/popup-preview-frame-main.js6
-rw-r--r--ext/js/pages/settings/popup-preview-frame.js11
-rw-r--r--ext/js/pages/settings/popup-window-controller.js4
-rw-r--r--ext/js/pages/settings/profile-conditions-ui.js7
-rw-r--r--ext/js/pages/settings/profile-controller.js8
-rw-r--r--ext/js/pages/settings/recommended-permissions-controller.js4
-rw-r--r--ext/js/pages/settings/scan-inputs-controller.js8
-rw-r--r--ext/js/pages/settings/scan-inputs-simple-controller.js11
-rw-r--r--ext/js/pages/settings/secondary-search-dictionary-controller.js7
-rw-r--r--ext/js/pages/settings/sentence-termination-characters-controller.js4
-rw-r--r--ext/js/pages/settings/settings-controller.js12
-rw-r--r--ext/js/pages/settings/settings-display-controller.js10
-rw-r--r--ext/js/pages/settings/settings-main.js64
-rw-r--r--ext/js/pages/settings/sort-frequency-dictionary-controller.js4
-rw-r--r--ext/js/pages/settings/status-footer.js6
-rw-r--r--ext/js/pages/settings/storage-controller.js4
-rw-r--r--ext/js/pages/settings/translation-text-replacements-controller.js4
-rw-r--r--ext/js/pages/welcome-main.js26
-rw-r--r--ext/js/script/dynamic-loader-sentinel.js2
-rw-r--r--ext/js/script/dynamic-loader.js5
-rw-r--r--ext/js/templates/__mocks__/template-renderer-proxy.js80
-rw-r--r--ext/js/templates/sandbox/anki-template-renderer-content-manager.js2
-rw-r--r--ext/js/templates/sandbox/anki-template-renderer.js24
-rw-r--r--ext/js/templates/sandbox/template-renderer-frame-api.js2
-rw-r--r--ext/js/templates/sandbox/template-renderer-frame-main.js6
-rw-r--r--ext/js/templates/sandbox/template-renderer-media-provider.js2
-rw-r--r--ext/js/templates/sandbox/template-renderer.js10
-rw-r--r--ext/js/templates/template-patcher.js2
-rw-r--r--ext/js/templates/template-renderer-proxy.js4
-rw-r--r--ext/js/yomichan.js9
151 files changed, 787 insertions, 650 deletions
diff --git a/ext/js/accessibility/accessibility-controller.js b/ext/js/accessibility/accessibility-controller.js
index aa27cbf4..e9a24880 100644
--- a/ext/js/accessibility/accessibility-controller.js
+++ b/ext/js/accessibility/accessibility-controller.js
@@ -16,10 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {ScriptManager} from '../background/script-manager.js';
+import {log} from '../core.js';
+
/**
* This class controls the registration of accessibility handlers.
*/
-class AccessibilityController {
+export class AccessibilityController {
/**
* Creates a new instance.
* @param {ScriptManager} scriptManager An instance of the `ScriptManager` class.
diff --git a/ext/js/accessibility/google-docs-util.js b/ext/js/accessibility/google-docs-util.js
index 3d9818ef..e170f334 100644
--- a/ext/js/accessibility/google-docs-util.js
+++ b/ext/js/accessibility/google-docs-util.js
@@ -16,15 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- * TextSourceRange
- */
+import {DocumentUtil} from '../dom/document-util.js';
+import {TextSourceElement} from '../dom/text-source-element.js';
+import {TextSourceRange} from '../dom/text-source-range.js';
/**
* This class is a helper for handling Google Docs content in content scripts.
*/
-class GoogleDocsUtil {
+export class GoogleDocsUtil {
/**
* Scans the document for text or elements with text information at the given coordinate.
* Coordinates are provided in [client space](https://developer.mozilla.org/en-US/docs/Web/CSS/CSSOM_View/Coordinate_systems).
diff --git a/ext/js/app/content-script-main.js b/ext/js/app/content-script-main.js
index 0006a244..d5ae0d93 100644
--- a/ext/js/app/content-script-main.js
+++ b/ext/js/app/content-script-main.js
@@ -16,11 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * Frontend
- * HotkeyHandler
- * PopupFactory
- */
+import {log} from '../core.js';
+import {HotkeyHandler} from '../input/hotkey-handler.js';
+import {yomichan} from '../yomichan.js';
+import {Frontend} from './frontend.js';
+import {PopupFactory} from './popup-factory.js';
(async () => {
try {
diff --git a/ext/js/app/content-script-wrapper.js b/ext/js/app/content-script-wrapper.js
new file mode 100644
index 00000000..795d3d8b
--- /dev/null
+++ b/ext/js/app/content-script-wrapper.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ * Copyright (C) 2019-2022 Yomichan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+(async () => {
+ const src = chrome.runtime.getURL('js/app/content-script-main.js');
+ // eslint-disable-next-line no-unsanitized/method
+ await import(src);
+})();
diff --git a/ext/js/app/frontend.js b/ext/js/app/frontend.js
index dc16701d..acc70667 100644
--- a/ext/js/app/frontend.js
+++ b/ext/js/app/frontend.js
@@ -16,17 +16,21 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- * GoogleDocsUtil
- * TextScanner
- * TextSourceRange
- */
+import {GoogleDocsUtil} from '../accessibility/google-docs-util.js';
+import {EventListenerCollection, invokeMessageHandler, isObject, log, promiseAnimationFrame} from '../core.js';
+import {DocumentUtil} from '../dom/document-util.js';
+import {TextSourceElement} from '../dom/text-source-element.js';
+import {TextSourceRange} from '../dom/text-source-range.js';
+import {HotkeyHandler} from '../input/hotkey-handler.js';
+import {TextScanner} from '../language/text-scanner.js';
+import {yomichan} from '../yomichan.js';
+import {PopupFactory} from './popup-factory.js';
+import {Popup} from './popup.js';
/**
* This is the main class responsible for scanning and handling webpage content.
*/
-class Frontend {
+export class Frontend {
/**
* Creates a new instance.
* @param {object} details Details about how to set up the instance.
diff --git a/ext/js/app/popup-factory.js b/ext/js/app/popup-factory.js
index c3c98162..7a17c106 100644
--- a/ext/js/app/popup-factory.js
+++ b/ext/js/app/popup-factory.js
@@ -16,17 +16,17 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * FrameOffsetForwarder
- * Popup
- * PopupProxy
- * PopupWindow
- */
+import {FrameOffsetForwarder} from '../comm/frame-offset-forwarder.js';
+import {generateId} from '../core.js';
+import {yomichan} from '../yomichan.js';
+import {PopupProxy} from './popup-proxy.js';
+import {PopupWindow} from './popup-window.js';
+import {Popup} from './popup.js';
/**
* A class which is used to generate and manage popups.
*/
-class PopupFactory {
+export class PopupFactory {
/**
* Creates a new instance.
* @param {number} frameId The frame ID of the host frame.
diff --git a/ext/js/app/popup-proxy.js b/ext/js/app/popup-proxy.js
index e7e51ddf..d16a16f1 100644
--- a/ext/js/app/popup-proxy.js
+++ b/ext/js/app/popup-proxy.js
@@ -16,11 +16,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {FrameOffsetForwarder} from '../comm/frame-offset-forwarder.js';
+import {EventDispatcher, log} from '../core.js';
+import {yomichan} from '../yomichan.js';
+import {Popup} from './popup.js';
+
/**
* This class is a proxy for a Popup that is hosted in a different frame.
* It effectively forwards all API calls to the underlying Popup.
*/
-class PopupProxy extends EventDispatcher {
+export class PopupProxy extends EventDispatcher {
/**
* Creates a new instance.
* @param {object} details Details about how to set up the instance.
diff --git a/ext/js/app/popup-window.js b/ext/js/app/popup-window.js
index 32e8b250..b5fd9eb6 100644
--- a/ext/js/app/popup-window.js
+++ b/ext/js/app/popup-window.js
@@ -16,10 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {EventDispatcher} from '../core.js';
+import {yomichan} from '../yomichan.js';
+import {Popup} from './popup.js';
+
/**
* This class represents a popup that is hosted in a new native window.
*/
-class PopupWindow extends EventDispatcher {
+export class PopupWindow extends EventDispatcher {
/**
* Creates a new instance.
* @param {object} details Details about how to set up the instance.
diff --git a/ext/js/app/popup.js b/ext/js/app/popup.js
index 8d140064..6f1807a6 100644
--- a/ext/js/app/popup.js
+++ b/ext/js/app/popup.js
@@ -16,17 +16,17 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- * FrameClient
- * ThemeController
- * dynamicLoader
- */
+import {FrameClient} from '../comm/frame-client.js';
+import {DynamicProperty, EventDispatcher, EventListenerCollection, deepEqual} from '../core.js';
+import {DocumentUtil} from '../dom/document-util.js';
+import {dynamicLoader} from '../script/dynamic-loader.js';
+import {yomichan} from '../yomichan.js';
+import {ThemeController} from './theme-controller.js';
/**
* This class is the container which hosts the display of search results.
*/
-class Popup extends EventDispatcher {
+export class Popup extends EventDispatcher {
/**
* Information about how popup content should be shown, specifically related to the outer popup frame.
* @typedef {object} ContentDetails
diff --git a/ext/js/app/theme-controller.js b/ext/js/app/theme-controller.js
index f8d5410b..f403a534 100644
--- a/ext/js/app/theme-controller.js
+++ b/ext/js/app/theme-controller.js
@@ -19,7 +19,7 @@
/**
* This class is used to control theme attributes on DOM elements.
*/
-class ThemeController {
+export class ThemeController {
/**
* Creates a new instance of the class.
* @param {?Element} element A DOM element which theme properties are applied to.
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js
index 8e8e6945..cccfcbb3 100644
--- a/ext/js/background/backend.js
+++ b/ext/js/background/backend.js
@@ -16,34 +16,34 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * AccessibilityController
- * AnkiConnect
- * AnkiUtil
- * ArrayBufferUtil
- * AudioDownloader
- * ClipboardMonitor
- * ClipboardReader
- * DictionaryDatabase
- * Environment
- * JapaneseUtil
- * Mecab
- * MediaUtil
- * ObjectPropertyAccessor
- * OptionsUtil
- * PermissionsUtil
- * ProfileConditionsUtil
- * RequestBuilder
- * ScriptManager
- * Translator
- * wanakana
- */
+import * as wanakana from '../../lib/wanakana.js';
+import {AccessibilityController} from '../accessibility/accessibility-controller.js';
+import {AnkiConnect} from '../comm/anki-connect.js';
+import {ClipboardMonitor} from '../comm/clipboard-monitor.js';
+import {ClipboardReader} from '../comm/clipboard-reader.js';
+import {Mecab} from '../comm/mecab.js';
+import {clone, deferPromise, deserializeError, generateId, invokeMessageHandler, isObject, log, promiseTimeout, serializeError} from '../core.js';
+import {AnkiUtil} from '../data/anki-util.js';
+import {OptionsUtil} from '../data/options-util.js';
+import {PermissionsUtil} from '../data/permissions-util.js';
+import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js';
+import {Environment} from '../extension/environment.js';
+import {ObjectPropertyAccessor} from '../general/object-property-accessor.js';
+import {DictionaryDatabase} from '../language/dictionary-database.js';
+import {JapaneseUtil} from '../language/sandbox/japanese-util.js';
+import {Translator} from '../language/translator.js';
+import {AudioDownloader} from '../media/audio-downloader.js';
+import {MediaUtil} from '../media/media-util.js';
+import {yomichan} from '../yomichan.js';
+import {ProfileConditionsUtil} from './profile-conditions-util.js';
+import {RequestBuilder} from './request-builder.js';
+import {ScriptManager} from './script-manager.js';
/**
* This class controls the core logic of the extension, including API calls
* and various forms of communication between browser tabs and external applications.
*/
-class Backend {
+export class Backend {
/**
* Creates a new instance.
*/
diff --git a/ext/js/background/background-main.js b/ext/js/background/background-main.js
index 3b1d42eb..6c30aa7a 100644
--- a/ext/js/background/background-main.js
+++ b/ext/js/background/background-main.js
@@ -16,9 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * Backend
- */
+import {yomichan} from '../yomichan.js';
+import {Backend} from './backend.js';
(() => {
yomichan.prepare(true);
diff --git a/ext/js/background/offscreen-main.js b/ext/js/background/offscreen-main.js
index 808e7766..dcbf978f 100644
--- a/ext/js/background/offscreen-main.js
+++ b/ext/js/background/offscreen-main.js
@@ -16,9 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * Offscreen
- */
+import {Offscreen} from './offscreen.js';
(() => {
new Offscreen();
diff --git a/ext/js/background/offscreen.js b/ext/js/background/offscreen.js
index bc41d189..c37cdedc 100644
--- a/ext/js/background/offscreen.js
+++ b/ext/js/background/offscreen.js
@@ -16,15 +16,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * ClipboardReader
- */
+import {ClipboardReader} from '../comm/clipboard-reader.js';
+import {invokeMessageHandler} from '../core.js';
+import {yomichan} from '../yomichan.js';
/**
* This class controls the core logic of the extension, including API calls
* and various forms of communication between browser tabs and external applications.
*/
-class Offscreen {
+export class Offscreen {
/**
* Creates a new instance.
*/
diff --git a/ext/js/background/profile-conditions-util.js b/ext/js/background/profile-conditions-util.js
index 1e2c01f8..55b287d7 100644
--- a/ext/js/background/profile-conditions-util.js
+++ b/ext/js/background/profile-conditions-util.js
@@ -16,14 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * JsonSchema
- */
+import {JsonSchema} from '../data/json-schema.js';
/**
* Utility class to help processing profile conditions.
*/
-class ProfileConditionsUtil {
+export class ProfileConditionsUtil {
/**
* A group of conditions.
* @typedef {object} ProfileConditionGroup
diff --git a/ext/js/background/request-builder.js b/ext/js/background/request-builder.js
index 7ee89539..f4f685be 100644
--- a/ext/js/background/request-builder.js
+++ b/ext/js/background/request-builder.js
@@ -20,7 +20,7 @@
* This class is used to generate `fetch()` requests on the background page
* with additional controls over anonymity and error handling.
*/
-class RequestBuilder {
+export class RequestBuilder {
/**
* A progress callback for a fetch read.
* @callback ProgressCallback
diff --git a/ext/js/background/script-manager.js b/ext/js/background/script-manager.js
index 694b64db..3671b854 100644
--- a/ext/js/background/script-manager.js
+++ b/ext/js/background/script-manager.js
@@ -16,10 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {isObject} from '../core.js';
/**
* This class is used to manage script injection into content tabs.
*/
-class ScriptManager {
+export class ScriptManager {
/**
* Creates a new instance of the class.
*/
diff --git a/ext/js/comm/anki-connect.js b/ext/js/comm/anki-connect.js
index b5e4d16d..09838ea5 100644
--- a/ext/js/comm/anki-connect.js
+++ b/ext/js/comm/anki-connect.js
@@ -16,14 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * AnkiUtil
- */
+import {isObject} from '../core.js';
+import {AnkiUtil} from '../data/anki-util.js';
/**
* This class controls communication with Anki via the AnkiConnect plugin.
*/
-class AnkiConnect {
+export class AnkiConnect {
/**
* Creates a new instance.
*/
diff --git a/ext/js/comm/api.js b/ext/js/comm/api.js
index 72d2ba07..8e5cd5cc 100644
--- a/ext/js/comm/api.js
+++ b/ext/js/comm/api.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class API {
+import {deferPromise, deserializeError, isObject} from '../core.js';
+
+export class API {
constructor(yomichan) {
this._yomichan = yomichan;
}
diff --git a/ext/js/comm/clipboard-monitor.js b/ext/js/comm/clipboard-monitor.js
index fbf56432..c5046046 100644
--- a/ext/js/comm/clipboard-monitor.js
+++ b/ext/js/comm/clipboard-monitor.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class ClipboardMonitor extends EventDispatcher {
+import {EventDispatcher} from '../core.js';
+
+export class ClipboardMonitor extends EventDispatcher {
constructor({japaneseUtil, clipboardReader}) {
super();
this._japaneseUtil = japaneseUtil;
diff --git a/ext/js/comm/clipboard-reader.js b/ext/js/comm/clipboard-reader.js
index 1ea507b8..8139cc11 100644
--- a/ext/js/comm/clipboard-reader.js
+++ b/ext/js/comm/clipboard-reader.js
@@ -16,14 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * MediaUtil
- */
+import {MediaUtil} from '../media/media-util.js';
/**
* Class which can read text and images from the clipboard.
*/
-class ClipboardReader {
+export class ClipboardReader {
/**
* Creates a new instances of a clipboard reader.
* @param {object} details Details about how to set up the instance.
diff --git a/ext/js/comm/cross-frame-api.js b/ext/js/comm/cross-frame-api.js
index fb2a1718..c7d9ae68 100644
--- a/ext/js/comm/cross-frame-api.js
+++ b/ext/js/comm/cross-frame-api.js
@@ -16,6 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {EventDispatcher, EventListenerCollection, deserializeError, invokeMessageHandler, log, serializeError} from '../core.js';
+import {yomichan} from '../yomichan.js';
+
class CrossFrameAPIPort extends EventDispatcher {
constructor(otherTabId, otherFrameId, port, messageHandlers) {
super();
@@ -217,7 +220,7 @@ class CrossFrameAPIPort extends EventDispatcher {
}
}
-class CrossFrameAPI {
+export class CrossFrameAPI {
constructor() {
this._ackTimeout = 3000; // 3 seconds
this._responseTimeout = 10000; // 10 seconds
diff --git a/ext/js/comm/frame-ancestry-handler.js b/ext/js/comm/frame-ancestry-handler.js
index c2e79733..1934c4ac 100644
--- a/ext/js/comm/frame-ancestry-handler.js
+++ b/ext/js/comm/frame-ancestry-handler.js
@@ -16,13 +16,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {generateId} from '../core.js';
+import {yomichan} from '../yomichan.js';
+
/**
* This class is used to return the ancestor frame IDs for the current frame.
* This is a workaround to using the `webNavigation.getAllFrames` API, which
* would require an additional permission that is otherwise unnecessary.
* It is also used to track the correlation between child frame elements and their IDs.
*/
-class FrameAncestryHandler {
+export class FrameAncestryHandler {
/**
* Creates a new instance.
* @param {number} frameId The frame ID of the current frame the instance is instantiated in.
diff --git a/ext/js/comm/frame-client.js b/ext/js/comm/frame-client.js
index 46b1f502..0ca37feb 100644
--- a/ext/js/comm/frame-client.js
+++ b/ext/js/comm/frame-client.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class FrameClient {
+import {deferPromise, generateId, isObject} from '../core.js';
+
+export class FrameClient {
constructor() {
this._secret = null;
this._token = null;
diff --git a/ext/js/comm/frame-endpoint.js b/ext/js/comm/frame-endpoint.js
index dad9f40e..0e8a5c00 100644
--- a/ext/js/comm/frame-endpoint.js
+++ b/ext/js/comm/frame-endpoint.js
@@ -16,7 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class FrameEndpoint {
+import {EventListenerCollection, generateId, isObject} from '../core.js';
+import {yomichan} from '../yomichan.js';
+
+export class FrameEndpoint {
constructor() {
this._secret = generateId(16);
this._token = null;
diff --git a/ext/js/comm/frame-offset-forwarder.js b/ext/js/comm/frame-offset-forwarder.js
index 87c6a9ce..5eea2ba6 100644
--- a/ext/js/comm/frame-offset-forwarder.js
+++ b/ext/js/comm/frame-offset-forwarder.js
@@ -16,11 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * FrameAncestryHandler
- */
+import {yomichan} from '../yomichan.js';
+import {FrameAncestryHandler} from './frame-ancestry-handler.js';
-class FrameOffsetForwarder {
+export class FrameOffsetForwarder {
constructor(frameId) {
this._frameId = frameId;
this._frameAncestryHandler = new FrameAncestryHandler(frameId);
diff --git a/ext/js/comm/mecab.js b/ext/js/comm/mecab.js
index bdc8c588..50f13ddf 100644
--- a/ext/js/comm/mecab.js
+++ b/ext/js/comm/mecab.js
@@ -16,11 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {EventListenerCollection} from '../core.js';
+
/**
* This class is used to connect Yomichan to a native component that is
* used to parse text into individual terms.
*/
-class Mecab {
+export class Mecab {
/**
* The resulting data from an invocation of `parseText`.
* @typedef {object} ParseResult
diff --git a/ext/js/core.js b/ext/js/core.js
index 1e749c7d..fb164795 100644
--- a/ext/js/core.js
+++ b/ext/js/core.js
@@ -21,7 +21,7 @@
* @param {*} error An error object to convert.
* @returns {{name: string, message: string, stack: string, data?: *}|{value: *, hasValue: boolean}} A simple object which can be serialized by `JSON.stringify()`.
*/
-function serializeError(error) {
+export function serializeError(error) {
try {
if (typeof error === 'object' && error !== null) {
const result = {
@@ -48,7 +48,7 @@ function serializeError(error) {
* @param {{name: string, message: string, stack: string, data?: *}|{value: *, hasValue: boolean}} serializedError A simple object which was initially generated by serializeError.
* @returns {Error|*} A new `Error` instance.
*/
-function deserializeError(serializedError) {
+export function deserializeError(serializedError) {
if (serializedError.hasValue) {
return serializedError.value;
}
@@ -66,7 +66,7 @@ function deserializeError(serializedError) {
* @param {*} value The value to check.
* @returns {boolean} `true` if the value is an object and not an array, `false` otherwise.
*/
-function isObject(value) {
+export function isObject(value) {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
@@ -76,7 +76,7 @@ function isObject(value) {
* @param {string} string The string to convert to a valid regular expression.
* @returns {string} The escaped string.
*/
-function escapeRegExp(string) {
+export function escapeRegExp(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&');
}
@@ -85,7 +85,7 @@ function escapeRegExp(string) {
* @param {string} string The string to reverse.
* @returns {string} The returned string, which retains proper UTF-16 surrogate pair order.
*/
-function stringReverse(string) {
+export function stringReverse(string) {
return [...string].reverse().join('');
}
@@ -95,7 +95,7 @@ function stringReverse(string) {
* @returns {*} A new clone of the value.
* @throws An error if the value is circular and cannot be cloned.
*/
-const clone = (() => {
+export const clone = (() => {
// eslint-disable-next-line no-shadow
function clone(value) {
if (value === null) { return null; }
@@ -168,7 +168,7 @@ const clone = (() => {
* @param {*} value2 The second value to check.
* @returns {boolean} `true` if the values are the same object, or deeply equal without cycles. `false` otherwise.
*/
-const deepEqual = (() => {
+export const deepEqual = (() => {
// eslint-disable-next-line no-shadow
function deepEqual(value1, value2) {
if (value1 === value2) { return true; }
@@ -239,7 +239,7 @@ const deepEqual = (() => {
* @param {number} length The number of bytes the string represents. The returned string's length will be twice as long.
* @returns {string} A string of random characters.
*/
-function generateId(length) {
+export function generateId(length) {
const array = new Uint8Array(length);
crypto.getRandomValues(array);
let id = '';
@@ -253,7 +253,7 @@ function generateId(length) {
* Creates an unresolved promise that can be resolved later, outside the promise's executor function.
* @returns {{promise: Promise, resolve: Function, reject: Function}} An object `{promise, resolve, reject}`, containing the promise and the resolve/reject functions.
*/
-function deferPromise() {
+export function deferPromise() {
let resolve;
let reject;
const promise = new Promise((resolve2, reject2) => {
@@ -269,7 +269,7 @@ function deferPromise() {
* @param {*} [resolveValue] The value returned when the promise is resolved.
* @returns {Promise} A promise with two additional properties: `resolve` and `reject`, which can be used to complete the promise early.
*/
-function promiseTimeout(delay, resolveValue) {
+export function promiseTimeout(delay, resolveValue) {
if (delay <= 0) {
const promise = Promise.resolve(resolveValue);
promise.resolve = () => {}; // NOP
@@ -312,7 +312,7 @@ function promiseTimeout(delay, resolveValue) {
* and `timeout` is a boolean indicating whether the cause was a timeout or not.
* @throws The promise throws an error if animation is not supported in this context, such as in a service worker.
*/
-function promiseAnimationFrame(timeout=null) {
+export function promiseAnimationFrame(timeout=null) {
return new Promise((resolve, reject) => {
if (typeof cancelAnimationFrame !== 'function' || typeof requestAnimationFrame !== 'function') {
reject(new Error('Animation not supported in this context'));
@@ -362,7 +362,7 @@ function promiseAnimationFrame(timeout=null) {
* @param {...*} extraArgs Additional arguments which are passed to the `handler` function.
* @returns {boolean} `true` if the function is invoked asynchronously, `false` otherwise.
*/
-function invokeMessageHandler({handler, async}, params, callback, ...extraArgs) {
+export function invokeMessageHandler({handler, async}, params, callback, ...extraArgs) {
try {
let promiseOrResult = handler(params, ...extraArgs);
if (async === 'dynamic') {
@@ -387,7 +387,7 @@ function invokeMessageHandler({handler, async}, params, callback, ...extraArgs)
/**
* Base class controls basic event dispatching.
*/
-class EventDispatcher {
+export class EventDispatcher {
/**
* Creates a new instance.
*/
@@ -462,7 +462,7 @@ class EventDispatcher {
/**
* Class which stores event listeners added to various objects, making it easy to remove them in bulk.
*/
-class EventListenerCollection {
+export class EventListenerCollection {
/**
* Creates a new instance.
*/
@@ -551,7 +551,7 @@ class EventListenerCollection {
* Class representing a generic value with an override stack.
* Changes can be observed by listening to the 'change' event.
*/
-class DynamicProperty extends EventDispatcher {
+export class DynamicProperty extends EventDispatcher {
/**
* Creates a new instance with the specified value.
* @param {*} value The value to assign.
@@ -657,7 +657,7 @@ class DynamicProperty extends EventDispatcher {
* This class handles logging of messages to the console and triggering
* an event for log calls.
*/
-class Logger extends EventDispatcher {
+export class Logger extends EventDispatcher {
/**
* Creates a new instance.
*/
@@ -759,4 +759,4 @@ class Logger extends EventDispatcher {
/**
* This object is the default logger used by the runtime.
*/
-const log = new Logger();
+export const log = new Logger();
diff --git a/ext/js/data/anki-note-builder.js b/ext/js/data/anki-note-builder.js
index c1b58cc2..7fbbf03c 100644
--- a/ext/js/data/anki-note-builder.js
+++ b/ext/js/data/anki-note-builder.js
@@ -16,12 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * AnkiUtil
- * TemplateRendererProxy
- */
+import {deferPromise, deserializeError} from '../core.js';
+import {TemplateRendererProxy} from '../templates/template-renderer-proxy.js';
+import {yomichan} from '../yomichan.js';
+import {AnkiUtil} from './anki-util.js';
-class AnkiNoteBuilder {
+export class AnkiNoteBuilder {
constructor({japaneseUtil}) {
this._japaneseUtil = japaneseUtil;
this._markerPattern = AnkiUtil.cloneFieldMarkerPattern(true);
diff --git a/ext/js/data/anki-util.js b/ext/js/data/anki-util.js
index 3b433dc9..c08b562e 100644
--- a/ext/js/data/anki-util.js
+++ b/ext/js/data/anki-util.js
@@ -16,10 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {isObject} from '../core.js';
+
/**
* This class has some general utility functions for working with Anki data.
*/
-class AnkiUtil {
+export class AnkiUtil {
/**
* Gets the root deck name of a full deck name. If the deck is a root deck,
* the same name is returned. Nested decks are separated using '::'.
diff --git a/ext/js/data/database.js b/ext/js/data/database.js
index 205f6385..8e818d8b 100644
--- a/ext/js/data/database.js
+++ b/ext/js/data/database.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class Database {
+export class Database {
constructor() {
this._db = null;
this._isOpening = false;
diff --git a/ext/js/data/json-schema.js b/ext/js/data/json-schema.js
index c22a0e1a..93c8cd59 100644
--- a/ext/js/data/json-schema.js
+++ b/ext/js/data/json-schema.js
@@ -16,11 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * CacheMap
- */
+import {clone} from '../core.js';
+import {CacheMap} from '../general/cache-map.js';
-class JsonSchema {
+export class JsonSchema {
constructor(schema, rootSchema) {
this._schema = null;
this._startSchema = schema;
diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js
index e0cd0362..42e31b5f 100644
--- a/ext/js/data/options-util.js
+++ b/ext/js/data/options-util.js
@@ -16,12 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * JsonSchema
- * TemplatePatcher
- */
+import {escapeRegExp, isObject} from '../core.js';
+import {TemplatePatcher} from '../templates/template-patcher.js';
+import {JsonSchema} from './json-schema.js';
-class OptionsUtil {
+export class OptionsUtil {
constructor() {
this._templatePatcher = null;
this._optionsSchema = null;
diff --git a/ext/js/data/permissions-util.js b/ext/js/data/permissions-util.js
index afec470c..d645f21e 100644
--- a/ext/js/data/permissions-util.js
+++ b/ext/js/data/permissions-util.js
@@ -16,11 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * AnkiUtil
- */
+import {AnkiUtil} from './anki-util.js';
-class PermissionsUtil {
+export class PermissionsUtil {
constructor() {
this._ankiFieldMarkersRequiringClipboardPermission = new Set([
'clipboard-image',
diff --git a/ext/js/data/sandbox/anki-note-data-creator.js b/ext/js/data/sandbox/anki-note-data-creator.js
index 33b4af6f..371a62a2 100644
--- a/ext/js/data/sandbox/anki-note-data-creator.js
+++ b/ext/js/data/sandbox/anki-note-data-creator.js
@@ -16,15 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DictionaryDataUtil
- */
+import {DictionaryDataUtil} from '../../language/sandbox/dictionary-data-util.js';
/**
* This class is used to convert the internal dictionary entry format to the
* format used by Anki, for backwards compatibility.
*/
-class AnkiNoteDataCreator {
+export class AnkiNoteDataCreator {
/**
* Creates a new instance.
* @param {JapaneseUtil} japaneseUtil An instance of `JapaneseUtil`.
diff --git a/ext/js/data/sandbox/array-buffer-util.js b/ext/js/data/sandbox/array-buffer-util.js
index f96406bc..20715bd6 100644
--- a/ext/js/data/sandbox/array-buffer-util.js
+++ b/ext/js/data/sandbox/array-buffer-util.js
@@ -19,7 +19,7 @@
/**
* Class containing generic ArrayBuffer utility functions.
*/
-class ArrayBufferUtil {
+export class ArrayBufferUtil {
/**
* Decodes the contents of an ArrayBuffer using UTF8.
* @param {ArrayBuffer} arrayBuffer The input ArrayBuffer.
diff --git a/ext/js/data/sandbox/string-util.js b/ext/js/data/sandbox/string-util.js
index c158fd1a..096ecffe 100644
--- a/ext/js/data/sandbox/string-util.js
+++ b/ext/js/data/sandbox/string-util.js
@@ -19,7 +19,7 @@
/**
* Class containing generic string utility functions.
*/
-class StringUtil {
+export class StringUtil {
/**
* Reads code points from a string in the forward direction.
* @param {string} text The text to read the code points from.
diff --git a/ext/js/debug/timer.js b/ext/js/debug/timer.js
index f57e9e79..acf3621b 100644
--- a/ext/js/debug/timer.js
+++ b/ext/js/debug/timer.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class Timer {
+export class Timer {
constructor(name) {
this.samples = [];
this.parent = null;
diff --git a/ext/js/display/display-anki.js b/ext/js/display/display-anki.js
index 9a1aae23..a25008a2 100644
--- a/ext/js/display/display-anki.js
+++ b/ext/js/display/display-anki.js
@@ -16,13 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * AnkiNoteBuilder
- * AnkiUtil
- * PopupMenu
- */
+import {EventListenerCollection, deferPromise, isObject} from '../core.js';
+import {AnkiNoteBuilder} from '../data/anki-note-builder.js';
+import {AnkiUtil} from '../data/anki-util.js';
+import {PopupMenu} from '../dom/popup-menu.js';
+import {yomichan} from '../yomichan.js';
-class DisplayAnki {
+export class DisplayAnki {
constructor(display, displayAudio, japaneseUtil) {
this._display = display;
this._displayAudio = displayAudio;
diff --git a/ext/js/display/display-audio.js b/ext/js/display/display-audio.js
index c0b3859d..6ab5773f 100644
--- a/ext/js/display/display-audio.js
+++ b/ext/js/display/display-audio.js
@@ -16,12 +16,17 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {EventListenerCollection} from '../core.js';
+import {PopupMenu} from '../dom/popup-menu.js';
+import {AudioSystem} from '../media/audio-system.js';
+import {yomichan} from '../yomichan.js';
+
/* global
* AudioSystem
* PopupMenu
*/
-class DisplayAudio {
+export class DisplayAudio {
constructor(display) {
this._display = display;
this._audioPlaying = null;
diff --git a/ext/js/display/display-content-manager.js b/ext/js/display/display-content-manager.js
index 2abff98a..6cba1783 100644
--- a/ext/js/display/display-content-manager.js
+++ b/ext/js/display/display-content-manager.js
@@ -16,9 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * ArrayBufferUtil
- */
+import {EventListenerCollection} from '../core.js';
+import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js';
+import {yomichan} from '../yomichan.js';
/**
* A callback used when a media file has been loaded.
@@ -35,7 +35,7 @@
/**
* The content manager which is used when generating HTML display content.
*/
-class DisplayContentManager {
+export class DisplayContentManager {
/**
* Creates a new instance of the class.
* @param {Display} display The display instance that owns this object.
diff --git a/ext/js/display/display-generator.js b/ext/js/display/display-generator.js
index 293cb725..25df9745 100644
--- a/ext/js/display/display-generator.js
+++ b/ext/js/display/display-generator.js
@@ -16,14 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DictionaryDataUtil
- * HtmlTemplateCollection
- * PronunciationGenerator
- * StructuredContentGenerator
- */
-
-class DisplayGenerator {
+import {isObject} from '../core.js';
+import {HtmlTemplateCollection} from '../dom/html-template-collection.js';
+import {DictionaryDataUtil} from '../language/sandbox/dictionary-data-util.js';
+import {yomichan} from '../yomichan.js';
+import {PronunciationGenerator} from './sandbox/pronunciation-generator.js';
+import {StructuredContentGenerator} from './sandbox/structured-content-generator.js';
+
+export class DisplayGenerator {
constructor({japaneseUtil, contentManager, hotkeyHelpController=null}) {
this._japaneseUtil = japaneseUtil;
this._contentManager = contentManager;
diff --git a/ext/js/display/display-history.js b/ext/js/display/display-history.js
index 71882ca3..a983346c 100644
--- a/ext/js/display/display-history.js
+++ b/ext/js/display/display-history.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class DisplayHistory extends EventDispatcher {
+import {EventDispatcher, generateId, isObject} from '../core.js';
+
+export class DisplayHistory extends EventDispatcher {
constructor({clearable=true, useBrowserHistory=false}) {
super();
this._clearable = clearable;
diff --git a/ext/js/display/display-notification.js b/ext/js/display/display-notification.js
index d5c77b04..0c26c613 100644
--- a/ext/js/display/display-notification.js
+++ b/ext/js/display/display-notification.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class DisplayNotification {
+import {EventListenerCollection} from '../core.js';
+
+export class DisplayNotification {
constructor(container, node) {
this._container = container;
this._node = node;
diff --git a/ext/js/display/display-profile-selection.js b/ext/js/display/display-profile-selection.js
index b14b4d8b..c0b642e8 100644
--- a/ext/js/display/display-profile-selection.js
+++ b/ext/js/display/display-profile-selection.js
@@ -16,11 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * PanelElement
- */
+import {EventListenerCollection, generateId} from '../core.js';
+import {PanelElement} from '../dom/panel-element.js';
+import {yomichan} from '../yomichan.js';
-class DisplayProfileSelection {
+export class DisplayProfileSelection {
constructor(display) {
this._display = display;
this._profielList = document.querySelector('#profile-list');
diff --git a/ext/js/display/display-resizer.js b/ext/js/display/display-resizer.js
index 1356c0a7..2925561f 100644
--- a/ext/js/display/display-resizer.js
+++ b/ext/js/display/display-resizer.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class DisplayResizer {
+import {EventListenerCollection} from '../core.js';
+
+export class DisplayResizer {
constructor(display) {
this._display = display;
this._token = null;
diff --git a/ext/js/display/display.js b/ext/js/display/display.js
index 693bd201..b86b877d 100644
--- a/ext/js/display/display.js
+++ b/ext/js/display/display.js
@@ -16,26 +16,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DisplayContentManager
- * DisplayGenerator
- * DisplayHistory
- * DisplayNotification
- * ElementOverflowController
- * FrameEndpoint
- * Frontend
- * HotkeyHelpController
- * OptionToggleHotkeyHandler
- * PopupFactory
- * PopupMenu
- * QueryParser
- * ScrollElement
- * TextScanner
- * ThemeController
- * dynamicLoader
- */
-
-class Display extends EventDispatcher {
+import {Frontend} from '../app/frontend.js';
+import {PopupFactory} from '../app/popup-factory.js';
+import {ThemeController} from '../app/theme-controller.js';
+import {FrameEndpoint} from '../comm/frame-endpoint.js';
+import {DynamicProperty, EventDispatcher, EventListenerCollection, clone, deepEqual, invokeMessageHandler, isObject, log, promiseTimeout} from '../core.js';
+import {PopupMenu} from '../dom/popup-menu.js';
+import {ScrollElement} from '../dom/scroll-element.js';
+import {HotkeyHelpController} from '../input/hotkey-help-controller.js';
+import {TextScanner} from '../language/text-scanner.js';
+import {dynamicLoader} from '../script/dynamic-loader.js';
+import {yomichan} from '../yomichan.js';
+import {DisplayContentManager} from './display-content-manager.js';
+import {DisplayGenerator} from './display-generator.js';
+import {DisplayHistory} from './display-history.js';
+import {DisplayNotification} from './display-notification.js';
+import {ElementOverflowController} from './element-overflow-controller.js';
+import {OptionToggleHotkeyHandler} from './option-toggle-hotkey-handler.js';
+import {QueryParser} from './query-parser.js';
+
+export class Display extends EventDispatcher {
/**
* Information about how popup content should be shown, specifically related to the inner popup content.
* @typedef {object} ContentDetails
diff --git a/ext/js/display/element-overflow-controller.js b/ext/js/display/element-overflow-controller.js
index 9fb3d26f..0a62906b 100644
--- a/ext/js/display/element-overflow-controller.js
+++ b/ext/js/display/element-overflow-controller.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class ElementOverflowController {
+import {EventListenerCollection} from '../core.js';
+
+export class ElementOverflowController {
constructor() {
this._elements = [];
this._checkTimer = null;
diff --git a/ext/js/display/option-toggle-hotkey-handler.js b/ext/js/display/option-toggle-hotkey-handler.js
index 251e03fa..360b0894 100644
--- a/ext/js/display/option-toggle-hotkey-handler.js
+++ b/ext/js/display/option-toggle-hotkey-handler.js
@@ -16,7 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class OptionToggleHotkeyHandler {
+import {deserializeError} from '../core.js';
+import {yomichan} from '../yomichan.js';
+
+export class OptionToggleHotkeyHandler {
constructor(display) {
this._display = display;
this._notification = null;
diff --git a/ext/js/display/popup-main.js b/ext/js/display/popup-main.js
index 4d7c8c86..0599b736 100644
--- a/ext/js/display/popup-main.js
+++ b/ext/js/display/popup-main.js
@@ -16,6 +16,17 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {log} from '../core.js';
+import {DocumentFocusController} from '../dom/document-focus-controller.js';
+import {HotkeyHandler} from '../input/hotkey-handler.js';
+import {JapaneseUtil} from '../language/sandbox/japanese-util.js';
+import {yomichan} from '../yomichan.js';
+import {DisplayAnki} from './display-anki.js';
+import {DisplayAudio} from './display-audio.js';
+import {DisplayProfileSelection} from './display-profile-selection.js';
+import {DisplayResizer} from './display-resizer.js';
+import {Display} from './display.js';
+
/* global
* Display
* DisplayAnki
diff --git a/ext/js/display/query-parser.js b/ext/js/display/query-parser.js
index 205be579..6eee55b2 100644
--- a/ext/js/display/query-parser.js
+++ b/ext/js/display/query-parser.js
@@ -16,11 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * TextScanner
- */
+import {EventDispatcher, log} from '../core.js';
+import {TextScanner} from '../language/text-scanner.js';
+import {yomichan} from '../yomichan.js';
-class QueryParser extends EventDispatcher {
+export class QueryParser extends EventDispatcher {
constructor({getSearchContext, japaneseUtil}) {
super();
this._getSearchContext = getSearchContext;
diff --git a/ext/js/display/sandbox/pronunciation-generator.js b/ext/js/display/sandbox/pronunciation-generator.js
index 027771f6..76d5e2b1 100644
--- a/ext/js/display/sandbox/pronunciation-generator.js
+++ b/ext/js/display/sandbox/pronunciation-generator.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class PronunciationGenerator {
+export class PronunciationGenerator {
constructor(japaneseUtil) {
this._japaneseUtil = japaneseUtil;
}
diff --git a/ext/js/display/sandbox/structured-content-generator.js b/ext/js/display/sandbox/structured-content-generator.js
index 2d3a620d..227892d6 100644
--- a/ext/js/display/sandbox/structured-content-generator.js
+++ b/ext/js/display/sandbox/structured-content-generator.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class StructuredContentGenerator {
+export class StructuredContentGenerator {
constructor(contentManager, japaneseUtil, document) {
this._contentManager = contentManager;
this._japaneseUtil = japaneseUtil;
diff --git a/ext/js/display/search-action-popup-controller.js b/ext/js/display/search-action-popup-controller.js
index e29ac0f4..e8fb9f1b 100644
--- a/ext/js/display/search-action-popup-controller.js
+++ b/ext/js/display/search-action-popup-controller.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class SearchActionPopupController {
+export class SearchActionPopupController {
constructor(searchPersistentStateController) {
this._searchPersistentStateController = searchPersistentStateController;
}
diff --git a/ext/js/display/search-display-controller.js b/ext/js/display/search-display-controller.js
index 5a271e05..9e190c85 100644
--- a/ext/js/display/search-display-controller.js
+++ b/ext/js/display/search-display-controller.js
@@ -16,12 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * ClipboardMonitor
- * wanakana
- */
+import * as wanakana from '../../lib/wanakana.js';
+import {ClipboardMonitor} from '../comm/clipboard-monitor.js';
+import {EventListenerCollection, invokeMessageHandler} from '../core.js';
+import {yomichan} from '../yomichan.js';
-class SearchDisplayController {
+export class SearchDisplayController {
constructor(tabId, frameId, display, displayAudio, japaneseUtil, searchPersistentStateController) {
this._tabId = tabId;
this._frameId = frameId;
diff --git a/ext/js/display/search-main.js b/ext/js/display/search-main.js
index 77b96804..67552229 100644
--- a/ext/js/display/search-main.js
+++ b/ext/js/display/search-main.js
@@ -16,18 +16,18 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * Display
- * DisplayAnki
- * DisplayAudio
- * DocumentFocusController
- * HotkeyHandler
- * JapaneseUtil
- * SearchActionPopupController
- * SearchDisplayController
- * SearchPersistentStateController
- * wanakana
- */
+import * as wanakana from '../../lib/wanakana.js';
+import {log} from '../core.js';
+import {DocumentFocusController} from '../dom/document-focus-controller.js';
+import {HotkeyHandler} from '../input/hotkey-handler.js';
+import {JapaneseUtil} from '../language/sandbox/japanese-util.js';
+import {yomichan} from '../yomichan.js';
+import {DisplayAnki} from './display-anki.js';
+import {DisplayAudio} from './display-audio.js';
+import {Display} from './display.js';
+import {SearchActionPopupController} from './search-action-popup-controller.js';
+import {SearchDisplayController} from './search-display-controller.js';
+import {SearchPersistentStateController} from './search-persistent-state-controller.js';
(async () => {
try {
diff --git a/ext/js/display/search-persistent-state-controller.js b/ext/js/display/search-persistent-state-controller.js
index 2b651ffa..60155143 100644
--- a/ext/js/display/search-persistent-state-controller.js
+++ b/ext/js/display/search-persistent-state-controller.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class SearchPersistentStateController extends EventDispatcher {
+import {EventDispatcher} from '../core.js';
+
+export class SearchPersistentStateController extends EventDispatcher {
constructor() {
super();
this._mode = null;
diff --git a/ext/js/dom/document-focus-controller.js b/ext/js/dom/document-focus-controller.js
index 937a7c13..501d1fad 100644
--- a/ext/js/dom/document-focus-controller.js
+++ b/ext/js/dom/document-focus-controller.js
@@ -22,7 +22,7 @@
* keyboard shortcuts (e.g. arrow keys) not controlling page scroll. Instead, this class will manually
* focus a dummy element inside the main content, which gives keyboard scroll focus to that element.
*/
-class DocumentFocusController {
+export class DocumentFocusController {
/**
* Creates a new instance of the class.
* @param {?string} autofocusElementSelector A selector string which can be used to specify an element which
diff --git a/ext/js/dom/document-util.js b/ext/js/dom/document-util.js
index 9bca951b..d379192c 100644
--- a/ext/js/dom/document-util.js
+++ b/ext/js/dom/document-util.js
@@ -16,16 +16,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DOMTextScanner
- * TextSourceElement
- * TextSourceRange
- */
+import {EventListenerCollection} from '../core.js';
+import {DOMTextScanner} from './dom-text-scanner.js';
+import {TextSourceElement} from './text-source-element.js';
+import {TextSourceRange} from './text-source-range.js';
/**
* This class contains utility functions related to the HTML document.
*/
-class DocumentUtil {
+export class DocumentUtil {
/**
* Options to configure how element detection is performed.
* @typedef {object} GetRangeFromPointOptions
diff --git a/ext/js/dom/dom-data-binder.js b/ext/js/dom/dom-data-binder.js
index fca5cd9f..4da5b0c2 100644
--- a/ext/js/dom/dom-data-binder.js
+++ b/ext/js/dom/dom-data-binder.js
@@ -16,13 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- * SelectorObserver
- * TaskAccumulator
- */
+import {TaskAccumulator} from '../general/task-accumulator.js';
+import {DocumentUtil} from './document-util.js';
+import {SelectorObserver} from './selector-observer.js';
-class DOMDataBinder {
+export class DOMDataBinder {
constructor({selector, createElementMetadata, compareElementMetadata, getValues, setValues, onError=null}) {
this._selector = selector;
this._createElementMetadata = createElementMetadata;
diff --git a/ext/js/dom/dom-text-scanner.js b/ext/js/dom/dom-text-scanner.js
index ec4c7bd6..ccd1c90b 100644
--- a/ext/js/dom/dom-text-scanner.js
+++ b/ext/js/dom/dom-text-scanner.js
@@ -16,14 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * StringUtil
- */
+import {StringUtil} from '../data/sandbox/string-util.js';
/**
* A class used to scan text in a document.
*/
-class DOMTextScanner {
+export class DOMTextScanner {
/**
* Creates a new instance of a DOMTextScanner.
* @param {Node} node The DOM Node to start at.
diff --git a/ext/js/dom/html-template-collection.js b/ext/js/dom/html-template-collection.js
index 4cdcf938..100ba55c 100644
--- a/ext/js/dom/html-template-collection.js
+++ b/ext/js/dom/html-template-collection.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class HtmlTemplateCollection {
+export class HtmlTemplateCollection {
constructor(source) {
this._templates = new Map();
diff --git a/ext/js/dom/native-simple-dom-parser.js b/ext/js/dom/native-simple-dom-parser.js
index 245386bd..882469a0 100644
--- a/ext/js/dom/native-simple-dom-parser.js
+++ b/ext/js/dom/native-simple-dom-parser.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class NativeSimpleDOMParser {
+export class NativeSimpleDOMParser {
constructor(content) {
this._document = new DOMParser().parseFromString(content, 'text/html');
}
diff --git a/ext/js/dom/panel-element.js b/ext/js/dom/panel-element.js
index ac283d02..9b056920 100644
--- a/ext/js/dom/panel-element.js
+++ b/ext/js/dom/panel-element.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class PanelElement extends EventDispatcher {
+import {EventDispatcher} from '../core.js';
+
+export class PanelElement extends EventDispatcher {
constructor({node, closingAnimationDuration}) {
super();
this._node = node;
diff --git a/ext/js/dom/popup-menu.js b/ext/js/dom/popup-menu.js
index 4ab1e049..7cae1dff 100644
--- a/ext/js/dom/popup-menu.js
+++ b/ext/js/dom/popup-menu.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class PopupMenu extends EventDispatcher {
+import {EventDispatcher, EventListenerCollection} from '../core.js';
+
+export class PopupMenu extends EventDispatcher {
constructor(sourceElement, containerNode) {
super();
this._sourceElement = sourceElement;
diff --git a/ext/js/dom/sandbox/css-style-applier.js b/ext/js/dom/sandbox/css-style-applier.js
index a47ef6ef..4f570bb7 100644
--- a/ext/js/dom/sandbox/css-style-applier.js
+++ b/ext/js/dom/sandbox/css-style-applier.js
@@ -20,7 +20,7 @@
* This class is used to apply CSS styles to elements using a consistent method
* that is the same across different browsers.
*/
-class CssStyleApplier {
+export class CssStyleApplier {
/**
* A CSS rule.
* @typedef {object} CssRule
diff --git a/ext/js/dom/scroll-element.js b/ext/js/dom/scroll-element.js
index e7526db0..4b2ac70d 100644
--- a/ext/js/dom/scroll-element.js
+++ b/ext/js/dom/scroll-element.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class ScrollElement {
+export class ScrollElement {
constructor(node) {
this._node = node;
this._animationRequestId = null;
diff --git a/ext/js/dom/selector-observer.js b/ext/js/dom/selector-observer.js
index 56f97202..e0e3d4ff 100644
--- a/ext/js/dom/selector-observer.js
+++ b/ext/js/dom/selector-observer.js
@@ -19,7 +19,7 @@
/**
* Class which is used to observe elements matching a selector in specific element.
*/
-class SelectorObserver {
+export class SelectorObserver {
/**
* @function OnAddedCallback
* @param {Element} element The element which was added.
diff --git a/ext/js/dom/simple-dom-parser.js b/ext/js/dom/simple-dom-parser.js
index 266a465c..3e84b783 100644
--- a/ext/js/dom/simple-dom-parser.js
+++ b/ext/js/dom/simple-dom-parser.js
@@ -16,11 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* globals
- * parse5
- */
+import * as parse5 from '../../lib/parse5.js';
-class SimpleDOMParser {
+export class SimpleDOMParser {
constructor(content) {
this._document = parse5.parse(content);
this._patternHtmlWhitespace = /[\t\r\n\f ]+/g;
diff --git a/ext/js/dom/text-source-element.js b/ext/js/dom/text-source-element.js
index e37a3582..95534975 100644
--- a/ext/js/dom/text-source-element.js
+++ b/ext/js/dom/text-source-element.js
@@ -16,16 +16,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- * StringUtil
- */
+import {StringUtil} from '../data/sandbox/string-util.js';
+import {DocumentUtil} from './document-util.js';
+import {TextSourceRange} from './text-source-range.js';
/**
* This class represents a text source that is attached to a HTML element, such as an <img>
* with alt text or a <button>.
*/
-class TextSourceElement {
+export class TextSourceElement {
/**
* Creates a new instance of the class.
* @param {Element} element The source element.
diff --git a/ext/js/dom/text-source-range.js b/ext/js/dom/text-source-range.js
index 8d6856b2..d5e70052 100644
--- a/ext/js/dom/text-source-range.js
+++ b/ext/js/dom/text-source-range.js
@@ -16,17 +16,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DOMTextScanner
- * DocumentUtil
- */
+import {DocumentUtil} from './document-util.js';
+import {DOMTextScanner} from './dom-text-scanner.js';
+import {TextSourceElement} from './text-source-element.js';
/**
* This class represents a text source that comes from text nodes in the document.
* Sometimes a temporary "imposter" element is created and used to store the text.
* This element is typically hidden from the page and removed after scanning has completed.
*/
-class TextSourceRange {
+export class TextSourceRange {
/**
* Creates a new instance of the class.
* @param {Range} range The selection range.
diff --git a/ext/js/extension/environment.js b/ext/js/extension/environment.js
index ad5a19ae..8c43f1a0 100644
--- a/ext/js/extension/environment.js
+++ b/ext/js/extension/environment.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class Environment {
+export class Environment {
constructor() {
this._cachedEnvironmentInfo = null;
}
diff --git a/ext/js/general/cache-map.js b/ext/js/general/cache-map.js
index 817626ab..1ee385bf 100644
--- a/ext/js/general/cache-map.js
+++ b/ext/js/general/cache-map.js
@@ -16,10 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+
/**
* Class which caches a map of values, keeping the most recently accessed values.
*/
-class CacheMap {
+export class CacheMap {
/**
* Creates a new CacheMap.
* @param {number} maxSize The maximum number of entries able to be stored in the cache.
diff --git a/ext/js/general/object-property-accessor.js b/ext/js/general/object-property-accessor.js
index 12b91935..b8309ed2 100644
--- a/ext/js/general/object-property-accessor.js
+++ b/ext/js/general/object-property-accessor.js
@@ -19,7 +19,7 @@
/**
* Class used to get and mutate generic properties of an object by using path strings.
*/
-class ObjectPropertyAccessor {
+export class ObjectPropertyAccessor {
/**
* Create a new accessor for a specific object.
* @param {object} target The object which the getter and mutation methods are applied to.
diff --git a/ext/js/general/regex-util.js b/ext/js/general/regex-util.js
index 6e466864..298189d4 100644
--- a/ext/js/general/regex-util.js
+++ b/ext/js/general/regex-util.js
@@ -16,10 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+
/**
* This class provides some general utility functions for regular expressions.
*/
-class RegexUtil {
+export class RegexUtil {
/**
* Applies string.replace using a regular expression and replacement string as arguments.
* A source map of the changes is also maintained.
diff --git a/ext/js/general/task-accumulator.js b/ext/js/general/task-accumulator.js
index b1185316..cae58b94 100644
--- a/ext/js/general/task-accumulator.js
+++ b/ext/js/general/task-accumulator.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class TaskAccumulator {
+import {log} from '../core.js';
+
+export class TaskAccumulator {
constructor(runTasks) {
this._deferPromise = null;
this._activePromise = null;
diff --git a/ext/js/general/text-source-map.js b/ext/js/general/text-source-map.js
index 473fd0d0..6a136451 100644
--- a/ext/js/general/text-source-map.js
+++ b/ext/js/general/text-source-map.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class TextSourceMap {
+export class TextSourceMap {
constructor(source, mapping=null) {
this._source = source;
this._mapping = (mapping !== null ? TextSourceMap.normalizeMapping(mapping) : null);
diff --git a/ext/js/input/hotkey-handler.js b/ext/js/input/hotkey-handler.js
index 26a80b77..f05351bb 100644
--- a/ext/js/input/hotkey-handler.js
+++ b/ext/js/input/hotkey-handler.js
@@ -16,14 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- */
+import {EventDispatcher, EventListenerCollection} from '../core.js';
+import {DocumentUtil} from '../dom/document-util.js';
+import {yomichan} from '../yomichan.js';
/**
* Class which handles hotkey events and actions.
*/
-class HotkeyHandler extends EventDispatcher {
+export class HotkeyHandler extends EventDispatcher {
/**
* Information describing a hotkey.
* @typedef {object} HotkeyDefinition
diff --git a/ext/js/input/hotkey-help-controller.js b/ext/js/input/hotkey-help-controller.js
index e5ea75df..67df9f84 100644
--- a/ext/js/input/hotkey-help-controller.js
+++ b/ext/js/input/hotkey-help-controller.js
@@ -16,11 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * HotkeyUtil
- */
+import {isObject} from '../core.js';
+import {yomichan} from '../yomichan.js';
+import {HotkeyUtil} from './hotkey-util.js';
-class HotkeyHelpController {
+export class HotkeyHelpController {
constructor() {
this._hotkeyUtil = new HotkeyUtil();
this._localActionHotseys = new Map();
diff --git a/ext/js/input/hotkey-util.js b/ext/js/input/hotkey-util.js
index eacbc553..e23849e0 100644
--- a/ext/js/input/hotkey-util.js
+++ b/ext/js/input/hotkey-util.js
@@ -19,7 +19,7 @@
/**
* Utility class to help display hotkeys and convert to/from commands.
*/
-class HotkeyUtil {
+export class HotkeyUtil {
/**
* Creates a new instance.
* @param {?string} os The operating system for this instance.
diff --git a/ext/js/language/__mocks__/dictionary-importer-media-loader.js b/ext/js/language/__mocks__/dictionary-importer-media-loader.js
new file mode 100644
index 00000000..96f0f6dd
--- /dev/null
+++ b/ext/js/language/__mocks__/dictionary-importer-media-loader.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ * Copyright (C) 2021-2022 Yomichan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export class DictionaryImporterMediaLoader {
+ async getImageDetails(content) {
+ // Placeholder values
+ return {content, width: 100, height: 100};
+ }
+}
diff --git a/ext/js/language/deinflector.js b/ext/js/language/deinflector.js
index b11aa918..3012c29a 100644
--- a/ext/js/language/deinflector.js
+++ b/ext/js/language/deinflector.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class Deinflector {
+export class Deinflector {
constructor(reasons) {
this.reasons = Deinflector.normalizeReasons(reasons);
}
diff --git a/ext/js/language/dictionary-database.js b/ext/js/language/dictionary-database.js
index 9f2b9e45..da365da7 100644
--- a/ext/js/language/dictionary-database.js
+++ b/ext/js/language/dictionary-database.js
@@ -16,11 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * Database
- */
+import {log, stringReverse} from '../core.js';
+import {Database} from '../data/database.js';
-class DictionaryDatabase {
+export class DictionaryDatabase {
constructor() {
this._db = new Database();
this._dbName = 'dict';
diff --git a/ext/js/language/dictionary-importer-media-loader.js b/ext/js/language/dictionary-importer-media-loader.js
index 4024d0b3..7d4f798c 100644
--- a/ext/js/language/dictionary-importer-media-loader.js
+++ b/ext/js/language/dictionary-importer-media-loader.js
@@ -16,10 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {EventListenerCollection} from '../core.js';
+
/**
* Class used for loading and validating media during the dictionary import process.
*/
-class DictionaryImporterMediaLoader {
+export class DictionaryImporterMediaLoader {
/**
* Attempts to load an image using an ArrayBuffer and a media type to return details about it.
* @param {ArrayBuffer} content The binary content for the image, encoded as an ArrayBuffer.
diff --git a/ext/js/language/dictionary-importer.js b/ext/js/language/dictionary-importer.js
index 718d9f1c..791d1a77 100644
--- a/ext/js/language/dictionary-importer.js
+++ b/ext/js/language/dictionary-importer.js
@@ -16,13 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * JSZip
- * JsonSchema
- * MediaUtil
- */
-
-class DictionaryImporter {
+import * as ajvSchemas from '../../lib/validate-schemas.js';
+import {BlobWriter, TextWriter, Uint8ArrayReader, ZipReader, configure} from '../../lib/zip.js';
+import {stringReverse} from '../core.js';
+import {MediaUtil} from '../media/media-util.js';
+export class DictionaryImporter {
constructor(mediaLoader, onProgress) {
this._mediaLoader = mediaLoader;
this._onProgress = typeof onProgress === 'function' ? onProgress : () => {};
@@ -39,20 +37,36 @@ class DictionaryImporter {
this._progressReset();
- // Read archive
- const archive = await JSZip.loadAsync(archiveContent);
+ configure({
+ workerScripts: {
+ deflate: ['../../lib/z-worker.js'],
+ inflate: ['../../lib/z-worker.js']
+ }
+ });
+ // Read archive
+ const zipFileReader = new Uint8ArrayReader(new Uint8Array(archiveContent));
+ const zipReader = new ZipReader(zipFileReader);
+ const zipEntries = await zipReader.getEntries();
+ const zipEntriesObject = {};
+ for (const entry of zipEntries) {
+ zipEntriesObject[entry.filename] = entry;
+ }
// Read and validate index
const indexFileName = 'index.json';
- const indexFile = archive.file(indexFileName);
+ const indexFile = zipEntriesObject[indexFileName];
if (!indexFile) {
throw new Error('No dictionary index found in archive');
}
- const index = JSON.parse(await indexFile.async('string'));
+ const indexContent = await indexFile.getData(
+ new TextWriter()
+ );
+ const index = JSON.parse(indexContent);
- const indexSchema = await this._getSchema('/data/schemas/dictionary-index-schema.json');
- this._validateJsonSchema(index, indexSchema, indexFileName);
+ if (!ajvSchemas.dictionaryIndex(index)) {
+ throw this._formatAjvSchemaError(ajvSchemas.dictionaryIndex, indexFileName);
+ }
const dictionaryTitle = index.title;
const version = index.format || index.version;
@@ -75,15 +89,14 @@ class DictionaryImporter {
// Load schemas
this._progressNextStep(0);
- const dataBankSchemaPaths = this._getDataBankSchemaPaths(version);
- const dataBankSchemas = await Promise.all(dataBankSchemaPaths.map((path) => this._getSchema(path)));
+ const dataBankSchemas = this._getDataBankSchemas(version);
// Files
- const termFiles = this._getArchiveFiles(archive, 'term_bank_?.json');
- const termMetaFiles = this._getArchiveFiles(archive, 'term_meta_bank_?.json');
- const kanjiFiles = this._getArchiveFiles(archive, 'kanji_bank_?.json');
- const kanjiMetaFiles = this._getArchiveFiles(archive, 'kanji_meta_bank_?.json');
- const tagFiles = this._getArchiveFiles(archive, 'tag_bank_?.json');
+ const termFiles = this._getArchiveFiles(zipEntriesObject, 'term_bank_?.json');
+ const termMetaFiles = this._getArchiveFiles(zipEntriesObject, 'term_meta_bank_?.json');
+ const kanjiFiles = this._getArchiveFiles(zipEntriesObject, 'kanji_bank_?.json');
+ const kanjiMetaFiles = this._getArchiveFiles(zipEntriesObject, 'kanji_meta_bank_?.json');
+ const tagFiles = this._getArchiveFiles(zipEntriesObject, 'tag_bank_?.json');
// Load data
this._progressNextStep(termFiles.length + termMetaFiles.length + kanjiFiles.length + kanjiMetaFiles.length + tagFiles.length);
@@ -124,7 +137,7 @@ class DictionaryImporter {
// Async requirements
this._progressNextStep(requirements.length);
- const {media} = await this._resolveAsyncRequirements(requirements, archive);
+ const {media} = await this._resolveAsyncRequirements(requirements, zipEntriesObject);
// Add dictionary descriptor
this._progressNextStep(termList.length + termMetaList.length + kanjiList.length + kanjiMetaList.length + tagList.length + media.length);
@@ -214,68 +227,27 @@ class DictionaryImporter {
return summary;
}
- async _getSchema(fileName) {
- const schema = await this._fetchJsonAsset(fileName);
- return new JsonSchema(schema);
- }
-
- _validateJsonSchema(value, schema, fileName) {
- try {
- schema.validate(value);
- } catch (e) {
- throw this._formatSchemaError(e, fileName);
- }
- }
-
- _formatSchemaError(e, fileName) {
- const valuePathString = this._getSchemaErrorPathString(e.valueStack, 'dictionary');
- const schemaPathString = this._getSchemaErrorPathString(e.schemaStack, 'schema');
-
- const e2 = new Error(`Dictionary has invalid data in '${fileName}' for value '${valuePathString}', validated against '${schemaPathString}': ${e.message}`);
- e2.data = e;
+ _formatAjvSchemaError(schema, fileName) {
+ const e2 = new Error(`Dictionary has invalid data in '${fileName}'`);
+ e2.data = schema.errors;
return e2;
}
- _getSchemaErrorPathString(infoList, base='') {
- let result = base;
- for (const {path} of infoList) {
- const pathArray = Array.isArray(path) ? path : [path];
- for (const pathPart of pathArray) {
- if (pathPart === null) {
- result = base;
- } else {
- switch (typeof pathPart) {
- case 'string':
- if (result.length > 0) {
- result += '.';
- }
- result += pathPart;
- break;
- case 'number':
- result += `[${pathPart}]`;
- break;
- }
- }
- }
- }
- return result;
- }
-
- _getDataBankSchemaPaths(version) {
+ _getDataBankSchemas(version) {
const termBank = (
version === 1 ?
- '/data/schemas/dictionary-term-bank-v1-schema.json' :
- '/data/schemas/dictionary-term-bank-v3-schema.json'
+ 'dictionaryTermBankV1' :
+ 'dictionaryTermBankV3'
);
- const termMetaBank = '/data/schemas/dictionary-term-meta-bank-v3-schema.json';
+ const termMetaBank = 'dictionaryTermMetaBankV3';
const kanjiBank = (
version === 1 ?
- '/data/schemas/dictionary-kanji-bank-v1-schema.json' :
- '/data/schemas/dictionary-kanji-bank-v3-schema.json'
+ 'dictionaryKanjiBankV1' :
+ 'dictionaryKanjiBankV3'
);
- const kanjiMetaBank = '/data/schemas/dictionary-kanji-meta-bank-v3-schema.json';
- const tagBank = '/data/schemas/dictionary-tag-bank-v3-schema.json';
+ const kanjiMetaBank = 'dictionaryKanjiMetaBankV3';
+ const tagBank = 'dictionaryTagBankV3';
return [termBank, termMetaBank, kanjiBank, kanjiMetaBank, tagBank];
}
@@ -335,9 +307,9 @@ class DictionaryImporter {
return target;
}
- async _resolveAsyncRequirements(requirements, archive) {
+ async _resolveAsyncRequirements(requirements, zipEntriesObject) {
const media = new Map();
- const context = {archive, media};
+ const context = {zipEntriesObject, media};
for (const requirement of requirements) {
await this._resolveAsyncRequirement(context, requirement);
@@ -427,13 +399,16 @@ class DictionaryImporter {
}
// Find file in archive
- const file = context.archive.file(path);
+ const file = context.zipEntriesObject[path];
if (file === null) {
throw createError('Could not find image');
}
// Load file content
- let content = await file.async('arraybuffer');
+ let content = await (await file.getData(
+ new BlobWriter()
+ )).arrayBuffer();
+
const mediaType = MediaUtil.getImageMediaTypeFromFileName(path);
if (mediaType === null) {
throw createError('Could not determine media type for image');
@@ -525,42 +500,36 @@ class DictionaryImporter {
}
}
- _getArchiveFiles(archive, fileNameFormat) {
+ _getArchiveFiles(zipEntriesObject, fileNameFormat) {
const indexPosition = fileNameFormat.indexOf('?');
const prefix = fileNameFormat.substring(0, indexPosition);
const suffix = fileNameFormat.substring(indexPosition + 1);
const results = [];
- for (let i = 1; true; ++i) {
- const fileName = `${prefix}${i}${suffix}`;
- const file = archive.file(fileName);
- if (!file) { break; }
- results.push(file);
+ for (const f of Object.keys(zipEntriesObject)) {
+ if (f.startsWith(prefix) && f.endsWith(suffix)) {
+ results.push(zipEntriesObject[f]);
+ }
}
return results;
}
- async _readFileSequence(files, convertEntry, schema, dictionaryTitle) {
+ async _readFileSequence(files, convertEntry, schemaName, dictionaryTitle) {
const progressData = this._progressData;
- let count = 0;
let startIndex = 0;
- if (typeof this._onProgress === 'function') {
- schema.progressInterval = 1000;
- schema.progress = (s) => {
- const index = s.getValueStackLength() > 1 ? s.getValueStackItem(1).path : 0;
- progressData.index = startIndex + (index / count);
- this._progress();
- };
- }
const results = [];
- for (const file of files) {
- const entries = JSON.parse(await file.async('string'));
+ for (const fileName of Object.keys(files)) {
+ const content = await files[fileName].getData(
+ new TextWriter()
+ );
+ const entries = JSON.parse(content);
- count = Array.isArray(entries) ? Math.max(entries.length, 1) : 1;
startIndex = progressData.index;
this._progress();
- this._validateJsonSchema(entries, schema, file.name);
+ if (!ajvSchemas[schemaName](entries)) {
+ throw this._formatAjvSchemaError(ajvSchemas[schemaName], fileName);
+ }
progressData.index = startIndex + 1;
this._progress();
diff --git a/ext/js/language/dictionary-worker-handler.js b/ext/js/language/dictionary-worker-handler.js
index 0e3e8495..b8c41b26 100644
--- a/ext/js/language/dictionary-worker-handler.js
+++ b/ext/js/language/dictionary-worker-handler.js
@@ -16,13 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DictionaryDatabase
- * DictionaryImporter
- * DictionaryWorkerMediaLoader
- */
+import {serializeError} from '../core.js';
+import {DictionaryDatabase} from './dictionary-database.js';
+import {DictionaryImporter} from './dictionary-importer.js';
+import {DictionaryWorkerMediaLoader} from './dictionary-worker-media-loader.js';
-class DictionaryWorkerHandler {
+export class DictionaryWorkerHandler {
constructor() {
this._mediaLoader = new DictionaryWorkerMediaLoader();
}
diff --git a/ext/js/language/dictionary-worker-main.js b/ext/js/language/dictionary-worker-main.js
index cbb3247c..6d2386aa 100644
--- a/ext/js/language/dictionary-worker-main.js
+++ b/ext/js/language/dictionary-worker-main.js
@@ -16,22 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DictionaryWorkerHandler
- */
-
-self.importScripts(
- '/lib/jszip.min.js',
- '/js/core.js',
- '/js/data/database.js',
- '/js/data/json-schema.js',
- '/js/general/cache-map.js',
- '/js/language/dictionary-database.js',
- '/js/language/dictionary-importer.js',
- '/js/language/dictionary-worker-handler.js',
- '/js/language/dictionary-worker-media-loader.js',
- '/js/media/media-util.js'
-);
+import {log} from '../core.js';
+import {DictionaryWorkerHandler} from './dictionary-worker-handler.js';
(() => {
try {
diff --git a/ext/js/language/dictionary-worker-media-loader.js b/ext/js/language/dictionary-worker-media-loader.js
index d2ef4fae..d58e46c5 100644
--- a/ext/js/language/dictionary-worker-media-loader.js
+++ b/ext/js/language/dictionary-worker-media-loader.js
@@ -16,11 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {deserializeError, generateId} from '../core.js';
+
/**
* Class used for loading and validating media from a worker thread
* during the dictionary import process.
*/
-class DictionaryWorkerMediaLoader {
+export class DictionaryWorkerMediaLoader {
/**
* Creates a new instance of the media loader.
*/
diff --git a/ext/js/language/dictionary-worker.js b/ext/js/language/dictionary-worker.js
index b415a346..18c300af 100644
--- a/ext/js/language/dictionary-worker.js
+++ b/ext/js/language/dictionary-worker.js
@@ -16,11 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DictionaryImporterMediaLoader
- */
+import {deserializeError, serializeError} from '../core.js';
+import {DictionaryImporterMediaLoader} from './dictionary-importer-media-loader.js';
-class DictionaryWorker {
+export class DictionaryWorker {
constructor() {
this._dictionaryImporterMediaLoader = new DictionaryImporterMediaLoader();
}
@@ -47,7 +46,7 @@ class DictionaryWorker {
_invoke(action, params, transfer, onProgress, formatResult) {
return new Promise((resolve, reject) => {
- const worker = new Worker('/js/language/dictionary-worker-main.js', {});
+ const worker = new Worker('/js/language/dictionary-worker-main.js', {type: 'module'});
const details = {
complete: false,
worker,
diff --git a/ext/js/language/sandbox/dictionary-data-util.js b/ext/js/language/sandbox/dictionary-data-util.js
index 323076e8..1b71346a 100644
--- a/ext/js/language/sandbox/dictionary-data-util.js
+++ b/ext/js/language/sandbox/dictionary-data-util.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class DictionaryDataUtil {
+export class DictionaryDataUtil {
static groupTermTags(dictionaryEntry) {
const {headwords} = dictionaryEntry;
const headwordCount = headwords.length;
diff --git a/ext/js/language/sandbox/japanese-util.js b/ext/js/language/sandbox/japanese-util.js
index eee70f9c..316b1c2e 100644
--- a/ext/js/language/sandbox/japanese-util.js
+++ b/ext/js/language/sandbox/japanese-util.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-const JapaneseUtil = (() => {
+export const JapaneseUtil = (() => {
const HIRAGANA_SMALL_TSU_CODE_POINT = 0x3063;
const KATAKANA_SMALL_TSU_CODE_POINT = 0x30c3;
const KATAKANA_SMALL_KA_CODE_POINT = 0x30f5;
diff --git a/ext/js/language/text-scanner.js b/ext/js/language/text-scanner.js
index af5cc8fe..bd5b0fbe 100644
--- a/ext/js/language/text-scanner.js
+++ b/ext/js/language/text-scanner.js
@@ -16,11 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- */
+import {EventDispatcher, EventListenerCollection, clone, isObject, log, promiseTimeout} from '../core.js';
+import {DocumentUtil} from '../dom/document-util.js';
+import {yomichan} from '../yomichan.js';
-class TextScanner extends EventDispatcher {
+export class TextScanner extends EventDispatcher {
constructor({
node,
getSearchContext,
diff --git a/ext/js/language/translator.js b/ext/js/language/translator.js
index 3b47cc51..4044f379 100644
--- a/ext/js/language/translator.js
+++ b/ext/js/language/translator.js
@@ -16,16 +16,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * Deinflector
- * RegexUtil
- * TextSourceMap
- */
+import {RegexUtil} from '../general/regex-util.js';
+import {TextSourceMap} from '../general/text-source-map.js';
+import {Deinflector} from './deinflector.js';
+import {DictionaryDatabase} from './dictionary-database.js';
/**
* Class which finds term and kanji dictionary entries for text.
*/
-class Translator {
+export class Translator {
/**
* Information about how popup content should be shown, specifically related to the outer popup frame.
* @typedef {object} TermFrequency
diff --git a/ext/js/media/audio-downloader.js b/ext/js/media/audio-downloader.js
index 32048553..1720a5d9 100644
--- a/ext/js/media/audio-downloader.js
+++ b/ext/js/media/audio-downloader.js
@@ -16,15 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * ArrayBufferUtil
- * JsonSchema
- * NativeSimpleDOMParser
- * RequestBuilder
- * SimpleDOMParser
- */
+import {RequestBuilder} from '../background/request-builder.js';
+import {JsonSchema} from '../data/json-schema.js';
+import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js';
+import {NativeSimpleDOMParser} from '../dom/native-simple-dom-parser.js';
+import {SimpleDOMParser} from '../dom/simple-dom-parser.js';
-class AudioDownloader {
+export class AudioDownloader {
constructor({japaneseUtil, requestBuilder}) {
this._japaneseUtil = japaneseUtil;
this._requestBuilder = requestBuilder;
diff --git a/ext/js/media/audio-system.js b/ext/js/media/audio-system.js
index d8b78fdc..55812bec 100644
--- a/ext/js/media/audio-system.js
+++ b/ext/js/media/audio-system.js
@@ -16,11 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * TextToSpeechAudio
- */
+import {EventDispatcher} from '../core.js';
+import {TextToSpeechAudio} from './text-to-speech-audio.js';
-class AudioSystem extends EventDispatcher {
+export class AudioSystem extends EventDispatcher {
constructor() {
super();
this._fallbackAudio = null;
diff --git a/ext/js/media/media-util.js b/ext/js/media/media-util.js
index eb7f95f8..843dc11c 100644
--- a/ext/js/media/media-util.js
+++ b/ext/js/media/media-util.js
@@ -19,7 +19,7 @@
/**
* MediaUtil is a class containing helper methods related to media processing.
*/
-class MediaUtil {
+export class MediaUtil {
/**
* Gets the file extension of a file path. URL search queries and hash
* fragments are not handled.
diff --git a/ext/js/media/text-to-speech-audio.js b/ext/js/media/text-to-speech-audio.js
index 35a0b9b1..ae717519 100644
--- a/ext/js/media/text-to-speech-audio.js
+++ b/ext/js/media/text-to-speech-audio.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class TextToSpeechAudio {
+export class TextToSpeechAudio {
constructor(text, voice) {
this._text = text;
this._voice = voice;
diff --git a/ext/js/pages/action-popup-main.js b/ext/js/pages/action-popup-main.js
index 9af5f64b..163c226a 100644
--- a/ext/js/pages/action-popup-main.js
+++ b/ext/js/pages/action-popup-main.js
@@ -16,12 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * HotkeyHelpController
- * PermissionsUtil
- */
+import {PermissionsUtil} from '../data/permissions-util.js';
+import {HotkeyHelpController} from '../input/hotkey-help-controller.js';
+import {yomichan} from '../yomichan.js';
-class DisplayController {
+export class DisplayController {
constructor() {
this._optionsFull = null;
this._permissionsUtil = new PermissionsUtil();
diff --git a/ext/js/pages/common/extension-content-controller.js b/ext/js/pages/common/extension-content-controller.js
index c50a6d23..3792130c 100644
--- a/ext/js/pages/common/extension-content-controller.js
+++ b/ext/js/pages/common/extension-content-controller.js
@@ -16,11 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * Environment
- */
+import {Environment} from '../../extension/environment.js';
-class ExtensionContentController {
+export class ExtensionContentController {
prepare() {
this._prepareSpecialUrls();
this._prepareExtensionIdExamples();
diff --git a/ext/js/pages/generic-page-main.js b/ext/js/pages/generic-page-main.js
index 6cc6b9db..176537ae 100644
--- a/ext/js/pages/generic-page-main.js
+++ b/ext/js/pages/generic-page-main.js
@@ -16,10 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentFocusController
- * ExtensionContentController
- */
+import {DocumentFocusController} from '../dom/document-focus-controller.js';
+import {ExtensionContentController} from './common/extension-content-controller.js';
(() => {
const documentFocusController = new DocumentFocusController();
diff --git a/ext/js/pages/info-main.js b/ext/js/pages/info-main.js
index 06ad10e8..58366d4c 100644
--- a/ext/js/pages/info-main.js
+++ b/ext/js/pages/info-main.js
@@ -16,11 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * BackupController
- * DocumentFocusController
- * SettingsController
- */
+import {log, promiseTimeout} from '../core.js';
+import {DocumentFocusController} from '../dom/document-focus-controller.js';
+import {yomichan} from '../yomichan.js';
+import {BackupController} from './settings/backup-controller.js';
+import {SettingsController} from './settings/settings-controller.js';
function getBrowserDisplayName(browser) {
switch (browser) {
diff --git a/ext/js/pages/permissions-main.js b/ext/js/pages/permissions-main.js
index 57dbd2ee..b242ff63 100644
--- a/ext/js/pages/permissions-main.js
+++ b/ext/js/pages/permissions-main.js
@@ -16,16 +16,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentFocusController
- * ExtensionContentController
- * ModalController
- * PermissionsOriginController
- * PermissionsToggleController
- * PersistentStorageController
- * SettingsController
- * SettingsDisplayController
- */
+import {log, promiseTimeout} from '../core.js';
+import {DocumentFocusController} from '../dom/document-focus-controller.js';
+import {yomichan} from '../yomichan.js';
+import {ExtensionContentController} from './common/extension-content-controller.js';
+import {ModalController} from './settings/modal-controller.js';
+import {PermissionsOriginController} from './settings/permissions-origin-controller.js';
+import {PermissionsToggleController} from './settings/permissions-toggle-controller.js';
+import {PersistentStorageController} from './settings/persistent-storage-controller.js';
+import {SettingsController} from './settings/settings-controller.js';
+import {SettingsDisplayController} from './settings/settings-display-controller.js';
async function setupEnvironmentInfo() {
const {manifest_version: manifestVersion} = chrome.runtime.getManifest();
diff --git a/ext/js/pages/settings/anki-controller.js b/ext/js/pages/settings/anki-controller.js
index c66dfece..0ad047aa 100644
--- a/ext/js/pages/settings/anki-controller.js
+++ b/ext/js/pages/settings/anki-controller.js
@@ -16,14 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * AnkiConnect
- * AnkiUtil
- * ObjectPropertyAccessor
- * SelectorObserver
- */
-
-class AnkiController {
+import {AnkiConnect} from '../../comm/anki-connect.js';
+import {EventListenerCollection, log} from '../../core.js';
+import {AnkiUtil} from '../../data/anki-util.js';
+import {SelectorObserver} from '../../dom/selector-observer.js';
+import {ObjectPropertyAccessor} from '../../general/object-property-accessor.js';
+import {yomichan} from '../../yomichan.js';
+
+export class AnkiController {
constructor(settingsController) {
this._settingsController = settingsController;
this._ankiConnect = new AnkiConnect();
diff --git a/ext/js/pages/settings/anki-templates-controller.js b/ext/js/pages/settings/anki-templates-controller.js
index e66def9f..83b1b0bb 100644
--- a/ext/js/pages/settings/anki-templates-controller.js
+++ b/ext/js/pages/settings/anki-templates-controller.js
@@ -16,12 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * AnkiNoteBuilder
- * JapaneseUtil
- */
+import {isObject} from '../../core.js';
+import {AnkiNoteBuilder} from '../../data/anki-note-builder.js';
+import {JapaneseUtil} from '../../language/sandbox/japanese-util.js';
+import {yomichan} from '../../yomichan.js';
-class AnkiTemplatesController {
+export class AnkiTemplatesController {
constructor(settingsController, modalController, ankiController) {
this._settingsController = settingsController;
this._modalController = modalController;
diff --git a/ext/js/pages/settings/audio-controller.js b/ext/js/pages/settings/audio-controller.js
index 82caff74..fb54ee6b 100644
--- a/ext/js/pages/settings/audio-controller.js
+++ b/ext/js/pages/settings/audio-controller.js
@@ -16,11 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * AudioSystem
- */
+import {EventDispatcher, EventListenerCollection} from '../../core.js';
+import {AudioSystem} from '../../media/audio-system.js';
-class AudioController extends EventDispatcher {
+export class AudioController extends EventDispatcher {
constructor(settingsController, modalController) {
super();
this._settingsController = settingsController;
diff --git a/ext/js/pages/settings/backup-controller.js b/ext/js/pages/settings/backup-controller.js
index bd089fb1..e429f9c7 100644
--- a/ext/js/pages/settings/backup-controller.js
+++ b/ext/js/pages/settings/backup-controller.js
@@ -16,14 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * ArrayBufferUtil
- * Dexie
- * DictionaryController
- * OptionsUtil
- */
-
-class BackupController {
+import * as Dexie from '../../../lib/dexie.js';
+import {isObject, log} from '../../core.js';
+import {OptionsUtil} from '../../data/options-util.js';
+import {ArrayBufferUtil} from '../../data/sandbox/array-buffer-util.js';
+import {yomichan} from '../../yomichan.js';
+import {DictionaryController} from './dictionary-controller.js';
+
+export class BackupController {
constructor(settingsController, modalController) {
this._settingsController = settingsController;
this._modalController = modalController;
diff --git a/ext/js/pages/settings/collapsible-dictionary-controller.js b/ext/js/pages/settings/collapsible-dictionary-controller.js
index 949df0de..37d5e6c9 100644
--- a/ext/js/pages/settings/collapsible-dictionary-controller.js
+++ b/ext/js/pages/settings/collapsible-dictionary-controller.js
@@ -16,7 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class CollapsibleDictionaryController {
+import {EventListenerCollection} from '../../core.js';
+import {yomichan} from '../../yomichan.js';
+
+export class CollapsibleDictionaryController {
constructor(settingsController) {
this._settingsController = settingsController;
this._getDictionaryInfoToken = null;
@@ -155,4 +158,4 @@ class CollapsibleDictionaryController {
select.value = value;
}
}
-} \ No newline at end of file
+}
diff --git a/ext/js/pages/settings/dictionary-controller.js b/ext/js/pages/settings/dictionary-controller.js
index 3a70a614..a9403e39 100644
--- a/ext/js/pages/settings/dictionary-controller.js
+++ b/ext/js/pages/settings/dictionary-controller.js
@@ -16,6 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {EventListenerCollection, log} from '../../core.js';
+import {DictionaryWorker} from '../../language/dictionary-worker.js';
+import {yomichan} from '../../yomichan.js';
+
/* global
* DictionaryWorker
*/
@@ -245,7 +249,7 @@ class DictionaryExtraInfo {
}
}
-class DictionaryController {
+export class DictionaryController {
constructor(settingsController, modalController, statusFooter) {
this._settingsController = settingsController;
this._modalController = modalController;
diff --git a/ext/js/pages/settings/dictionary-import-controller.js b/ext/js/pages/settings/dictionary-import-controller.js
index 4708ee5f..57fe1cd4 100644
--- a/ext/js/pages/settings/dictionary-import-controller.js
+++ b/ext/js/pages/settings/dictionary-import-controller.js
@@ -16,12 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DictionaryController
- * DictionaryWorker
- */
+import {deserializeError, log} from '../../core.js';
+import {DictionaryWorker} from '../../language/dictionary-worker.js';
+import {yomichan} from '../../yomichan.js';
+import {DictionaryController} from './dictionary-controller.js';
-class DictionaryImportController {
+export class DictionaryImportController {
constructor(settingsController, modalController, statusFooter) {
this._settingsController = settingsController;
this._modalController = modalController;
diff --git a/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js b/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js
index 3ac036a3..6e84fa0e 100644
--- a/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js
+++ b/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js
@@ -16,12 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * HotkeyUtil
- * KeyboardMouseInputField
- */
+import {EventListenerCollection, isObject} from '../../core.js';
+import {HotkeyUtil} from '../../input/hotkey-util.js';
+import {yomichan} from '../../yomichan.js';
+import {KeyboardMouseInputField} from './keyboard-mouse-input-field.js';
-class ExtensionKeyboardShortcutController {
+export class ExtensionKeyboardShortcutController {
constructor(settingsController) {
this._settingsController = settingsController;
this._resetButton = null;
diff --git a/ext/js/pages/settings/generic-setting-controller.js b/ext/js/pages/settings/generic-setting-controller.js
index c416d1a7..c4104874 100644
--- a/ext/js/pages/settings/generic-setting-controller.js
+++ b/ext/js/pages/settings/generic-setting-controller.js
@@ -16,12 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* globals
- * DOMDataBinder
- * DocumentUtil
- */
+import {deserializeError, isObject} from '../../core.js';
+import {DocumentUtil} from '../../dom/document-util.js';
+import {DOMDataBinder} from '../../dom/dom-data-binder.js';
-class GenericSettingController {
+export class GenericSettingController {
constructor(settingsController) {
this._settingsController = settingsController;
this._defaultScope = 'profile';
diff --git a/ext/js/pages/settings/keyboard-mouse-input-field.js b/ext/js/pages/settings/keyboard-mouse-input-field.js
index d4680eb1..aee01a36 100644
--- a/ext/js/pages/settings/keyboard-mouse-input-field.js
+++ b/ext/js/pages/settings/keyboard-mouse-input-field.js
@@ -16,12 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- * HotkeyUtil
- */
+import {EventDispatcher, EventListenerCollection} from '../../core.js';
+import {DocumentUtil} from '../../dom/document-util.js';
+import {HotkeyUtil} from '../../input/hotkey-util.js';
-class KeyboardMouseInputField extends EventDispatcher {
+export class KeyboardMouseInputField extends EventDispatcher {
constructor(inputNode, mouseButton, os, isPointerTypeSupported=null) {
super();
this._inputNode = inputNode;
diff --git a/ext/js/pages/settings/keyboard-shortcuts-controller.js b/ext/js/pages/settings/keyboard-shortcuts-controller.js
index e1c00080..3f91d2f9 100644
--- a/ext/js/pages/settings/keyboard-shortcuts-controller.js
+++ b/ext/js/pages/settings/keyboard-shortcuts-controller.js
@@ -16,13 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- * KeyboardMouseInputField
- * ObjectPropertyAccessor
- */
+import {EventListenerCollection} from '../../core.js';
+import {DocumentUtil} from '../../dom/document-util.js';
+import {ObjectPropertyAccessor} from '../../general/object-property-accessor.js';
+import {yomichan} from '../../yomichan.js';
+import {KeyboardMouseInputField} from './keyboard-mouse-input-field.js';
-class KeyboardShortcutController {
+export class KeyboardShortcutController {
constructor(settingsController) {
this._settingsController = settingsController;
this._entries = [];
diff --git a/ext/js/pages/settings/mecab-controller.js b/ext/js/pages/settings/mecab-controller.js
index 8b00c72d..6f9f15ed 100644
--- a/ext/js/pages/settings/mecab-controller.js
+++ b/ext/js/pages/settings/mecab-controller.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class MecabController {
+import {yomichan} from '../../yomichan.js';
+
+export class MecabController {
constructor(settingsController) {
this._settingsController = settingsController;
this._testButton = null;
diff --git a/ext/js/pages/settings/modal-controller.js b/ext/js/pages/settings/modal-controller.js
index 645485d5..517a19b3 100644
--- a/ext/js/pages/settings/modal-controller.js
+++ b/ext/js/pages/settings/modal-controller.js
@@ -16,11 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * Modal
- */
+import {Modal} from './modal.js';
-class ModalController {
+export class ModalController {
constructor() {
this._modals = [];
this._modalMap = new Map();
diff --git a/ext/js/pages/settings/modal.js b/ext/js/pages/settings/modal.js
index 74e22fa4..4d1c098d 100644
--- a/ext/js/pages/settings/modal.js
+++ b/ext/js/pages/settings/modal.js
@@ -16,11 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * PanelElement
- */
+import {PanelElement} from '../../dom/panel-element.js';
-class Modal extends PanelElement {
+export class Modal extends PanelElement {
constructor(node) {
super({
node,
diff --git a/ext/js/pages/settings/nested-popups-controller.js b/ext/js/pages/settings/nested-popups-controller.js
index a46c8f16..b9621ef0 100644
--- a/ext/js/pages/settings/nested-popups-controller.js
+++ b/ext/js/pages/settings/nested-popups-controller.js
@@ -16,11 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- */
+import {DocumentUtil} from '../../dom/document-util.js';
-class NestedPopupsController {
+export class NestedPopupsController {
constructor(settingsController) {
this._settingsController = settingsController;
this._popupNestingMaxDepth = 0;
diff --git a/ext/js/pages/settings/permissions-origin-controller.js b/ext/js/pages/settings/permissions-origin-controller.js
index e31f75d1..d234faa0 100644
--- a/ext/js/pages/settings/permissions-origin-controller.js
+++ b/ext/js/pages/settings/permissions-origin-controller.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class PermissionsOriginController {
+import {EventListenerCollection} from '../../core.js';
+
+export class PermissionsOriginController {
constructor(settingsController) {
this._settingsController = settingsController;
this._originContainer = null;
diff --git a/ext/js/pages/settings/permissions-toggle-controller.js b/ext/js/pages/settings/permissions-toggle-controller.js
index 8bf9dc18..0e486c1e 100644
--- a/ext/js/pages/settings/permissions-toggle-controller.js
+++ b/ext/js/pages/settings/permissions-toggle-controller.js
@@ -16,11 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * ObjectPropertyAccessor
- */
+import {ObjectPropertyAccessor} from '../../general/object-property-accessor.js';
-class PermissionsToggleController {
+export class PermissionsToggleController {
constructor(settingsController) {
this._settingsController = settingsController;
this._toggles = null;
diff --git a/ext/js/pages/settings/persistent-storage-controller.js b/ext/js/pages/settings/persistent-storage-controller.js
index 45169240..1c3bc276 100644
--- a/ext/js/pages/settings/persistent-storage-controller.js
+++ b/ext/js/pages/settings/persistent-storage-controller.js
@@ -16,7 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class PersistentStorageController {
+import {isObject} from '../../core.js';
+import {yomichan} from '../../yomichan.js';
+
+export class PersistentStorageController {
constructor() {
this._persistentStorageCheckbox = false;
}
diff --git a/ext/js/pages/settings/popup-preview-controller.js b/ext/js/pages/settings/popup-preview-controller.js
index 6f52613b..a0cb696e 100644
--- a/ext/js/pages/settings/popup-preview-controller.js
+++ b/ext/js/pages/settings/popup-preview-controller.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class PopupPreviewController {
+export class PopupPreviewController {
constructor(settingsController) {
this._settingsController = settingsController;
this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, '');
diff --git a/ext/js/pages/settings/popup-preview-frame-main.js b/ext/js/pages/settings/popup-preview-frame-main.js
index 4a2e5fda..d10910fc 100644
--- a/ext/js/pages/settings/popup-preview-frame-main.js
+++ b/ext/js/pages/settings/popup-preview-frame-main.js
@@ -16,6 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {PopupFactory} from '../../app/popup-factory.js';
+import {log} from '../../core.js';
+import {HotkeyHandler} from '../../input/hotkey-handler.js';
+import {yomichan} from '../../yomichan.js';
+import {PopupPreviewFrame} from './popup-preview-frame.js';
+
/* global
* HotkeyHandler
* PopupFactory
diff --git a/ext/js/pages/settings/popup-preview-frame.js b/ext/js/pages/settings/popup-preview-frame.js
index f24e1485..c0d4358d 100644
--- a/ext/js/pages/settings/popup-preview-frame.js
+++ b/ext/js/pages/settings/popup-preview-frame.js
@@ -16,13 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * Frontend
- * TextSourceRange
- * wanakana
- */
+import * as wanakana from '../../../lib/wanakana.js';
+import {Frontend} from '../../app/frontend.js';
+import {TextSourceRange} from '../../dom/text-source-range.js';
+import {yomichan} from '../../yomichan.js';
-class PopupPreviewFrame {
+export class PopupPreviewFrame {
constructor(tabId, frameId, popupFactory, hotkeyHandler) {
this._tabId = tabId;
this._frameId = frameId;
diff --git a/ext/js/pages/settings/popup-window-controller.js b/ext/js/pages/settings/popup-window-controller.js
index af74de4b..6f4d9ec3 100644
--- a/ext/js/pages/settings/popup-window-controller.js
+++ b/ext/js/pages/settings/popup-window-controller.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class PopupWindowController {
+import {yomichan} from '../../yomichan.js';
+
+export class PopupWindowController {
prepare() {
const testLink = document.querySelector('#test-window-open-link');
testLink.addEventListener('click', this._onTestWindowOpenLinkClick.bind(this), false);
diff --git a/ext/js/pages/settings/profile-conditions-ui.js b/ext/js/pages/settings/profile-conditions-ui.js
index 6865f27b..bd790b1b 100644
--- a/ext/js/pages/settings/profile-conditions-ui.js
+++ b/ext/js/pages/settings/profile-conditions-ui.js
@@ -16,11 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * KeyboardMouseInputField
- */
+import {EventDispatcher, EventListenerCollection} from '../../core.js';
+import {KeyboardMouseInputField} from './keyboard-mouse-input-field.js';
-class ProfileConditionsUI extends EventDispatcher {
+export class ProfileConditionsUI extends EventDispatcher {
constructor(settingsController) {
super();
this._settingsController = settingsController;
diff --git a/ext/js/pages/settings/profile-controller.js b/ext/js/pages/settings/profile-controller.js
index d9e25fcf..a4a64e60 100644
--- a/ext/js/pages/settings/profile-controller.js
+++ b/ext/js/pages/settings/profile-controller.js
@@ -16,11 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * ProfileConditionsUI
- */
+import {clone, EventListenerCollection} from '../../core.js';
+import {yomichan} from '../../yomichan.js';
+import {ProfileConditionsUI} from './profile-conditions-ui.js';
-class ProfileController {
+export class ProfileController {
constructor(settingsController, modalController) {
this._settingsController = settingsController;
this._modalController = modalController;
diff --git a/ext/js/pages/settings/recommended-permissions-controller.js b/ext/js/pages/settings/recommended-permissions-controller.js
index 3d25d5eb..e04dbdf7 100644
--- a/ext/js/pages/settings/recommended-permissions-controller.js
+++ b/ext/js/pages/settings/recommended-permissions-controller.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class RecommendedPermissionsController {
+import {EventListenerCollection} from '../../core.js';
+
+export class RecommendedPermissionsController {
constructor(settingsController) {
this._settingsController = settingsController;
this._originToggleNodes = null;
diff --git a/ext/js/pages/settings/scan-inputs-controller.js b/ext/js/pages/settings/scan-inputs-controller.js
index 3ee6aed0..ea8d500a 100644
--- a/ext/js/pages/settings/scan-inputs-controller.js
+++ b/ext/js/pages/settings/scan-inputs-controller.js
@@ -16,11 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * KeyboardMouseInputField
- */
+import {EventListenerCollection} from '../../core.js';
+import {yomichan} from '../../yomichan.js';
+import {KeyboardMouseInputField} from './keyboard-mouse-input-field.js';
-class ScanInputsController {
+export class ScanInputsController {
constructor(settingsController) {
this._settingsController = settingsController;
this._os = null;
diff --git a/ext/js/pages/settings/scan-inputs-simple-controller.js b/ext/js/pages/settings/scan-inputs-simple-controller.js
index 8edb9a86..79ffb773 100644
--- a/ext/js/pages/settings/scan-inputs-simple-controller.js
+++ b/ext/js/pages/settings/scan-inputs-simple-controller.js
@@ -16,12 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * HotkeyUtil
- * ScanInputsController
- */
+import {HotkeyUtil} from '../../input/hotkey-util.js';
+import {yomichan} from '../../yomichan.js';
+import {ScanInputsController} from './scan-inputs-controller.js';
-class ScanInputsSimpleController {
+export class ScanInputsSimpleController {
constructor(settingsController) {
this._settingsController = settingsController;
this._middleMouseButtonScan = null;
@@ -244,4 +243,4 @@ class ScanInputsSimpleController {
this._mainScanModifierKeyInputHasOther = !hasMainScanInput;
this._populateSelect(this._mainScanModifierKeyInput, this._mainScanModifierKeyInputHasOther);
}
-} \ No newline at end of file
+}
diff --git a/ext/js/pages/settings/secondary-search-dictionary-controller.js b/ext/js/pages/settings/secondary-search-dictionary-controller.js
index f8e2fb78..30575526 100644
--- a/ext/js/pages/settings/secondary-search-dictionary-controller.js
+++ b/ext/js/pages/settings/secondary-search-dictionary-controller.js
@@ -16,7 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class SecondarySearchDictionaryController {
+import {EventListenerCollection} from '../../core.js';
+import {yomichan} from '../../yomichan.js';
+
+export class SecondarySearchDictionaryController {
constructor(settingsController) {
this._settingsController = settingsController;
this._getDictionaryInfoToken = null;
@@ -91,4 +94,4 @@ class SecondarySearchDictionaryController {
const options = await this._settingsController.getOptions();
this._onOptionsChanged({options});
}
-} \ No newline at end of file
+}
diff --git a/ext/js/pages/settings/sentence-termination-characters-controller.js b/ext/js/pages/settings/sentence-termination-characters-controller.js
index a243d2f8..f901b82c 100644
--- a/ext/js/pages/settings/sentence-termination-characters-controller.js
+++ b/ext/js/pages/settings/sentence-termination-characters-controller.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class SentenceTerminationCharactersController {
+import {EventListenerCollection} from '../../core.js';
+
+export class SentenceTerminationCharactersController {
constructor(settingsController) {
this._settingsController = settingsController;
this._entries = [];
diff --git a/ext/js/pages/settings/settings-controller.js b/ext/js/pages/settings/settings-controller.js
index f27135c4..6f83c4c0 100644
--- a/ext/js/pages/settings/settings-controller.js
+++ b/ext/js/pages/settings/settings-controller.js
@@ -16,13 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * HtmlTemplateCollection
- * OptionsUtil
- * PermissionsUtil
- */
+import {EventDispatcher, EventListenerCollection, generateId, isObject} from '../../core.js';
+import {OptionsUtil} from '../../data/options-util.js';
+import {PermissionsUtil} from '../../data/permissions-util.js';
+import {HtmlTemplateCollection} from '../../dom/html-template-collection.js';
+import {yomichan} from '../../yomichan.js';
-class SettingsController extends EventDispatcher {
+export class SettingsController extends EventDispatcher {
constructor() {
super();
this._profileIndex = 0;
diff --git a/ext/js/pages/settings/settings-display-controller.js b/ext/js/pages/settings/settings-display-controller.js
index 3f1f6b6b..e23e355d 100644
--- a/ext/js/pages/settings/settings-display-controller.js
+++ b/ext/js/pages/settings/settings-display-controller.js
@@ -16,13 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DocumentUtil
- * PopupMenu
- * SelectorObserver
- */
+import {DocumentUtil} from '../../dom/document-util.js';
+import {PopupMenu} from '../../dom/popup-menu.js';
+import {SelectorObserver} from '../../dom/selector-observer.js';
-class SettingsDisplayController {
+export class SettingsDisplayController {
constructor(settingsController, modalController) {
this._settingsController = settingsController;
this._modalController = modalController;
diff --git a/ext/js/pages/settings/settings-main.js b/ext/js/pages/settings/settings-main.js
index a4832220..1cd0b0a9 100644
--- a/ext/js/pages/settings/settings-main.js
+++ b/ext/js/pages/settings/settings-main.js
@@ -16,38 +16,38 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * AnkiController
- * AnkiTemplatesController
- * AudioController
- * BackupController
- * CollapsibleDictionaryController
- * DictionaryController
- * DictionaryImportController
- * DocumentFocusController
- * ExtensionContentController
- * ExtensionKeyboardShortcutController
- * GenericSettingController
- * KeyboardShortcutController
- * MecabController
- * ModalController
- * NestedPopupsController
- * PermissionsToggleController
- * PersistentStorageController
- * PopupPreviewController
- * PopupWindowController
- * ProfileController
- * ScanInputsController
- * ScanInputsSimpleController
- * SecondarySearchDictionaryController
- * SentenceTerminationCharactersController
- * SettingsController
- * SettingsDisplayController
- * SortFrequencyDictionaryController
- * StatusFooter
- * StorageController
- * TranslationTextReplacementsController
- */
+import {log} from '../../core.js';
+import {DocumentFocusController} from '../../dom/document-focus-controller.js';
+import {yomichan} from '../../yomichan.js';
+import {ExtensionContentController} from '../common/extension-content-controller.js';
+import {AnkiController} from './anki-controller.js';
+import {AnkiTemplatesController} from './anki-templates-controller.js';
+import {AudioController} from './audio-controller.js';
+import {BackupController} from './backup-controller.js';
+import {CollapsibleDictionaryController} from './collapsible-dictionary-controller.js';
+import {DictionaryController} from './dictionary-controller.js';
+import {DictionaryImportController} from './dictionary-import-controller.js';
+import {ExtensionKeyboardShortcutController} from './extension-keyboard-shortcuts-controller.js';
+import {GenericSettingController} from './generic-setting-controller.js';
+import {KeyboardShortcutController} from './keyboard-shortcuts-controller.js';
+import {MecabController} from './mecab-controller.js';
+import {ModalController} from './modal-controller.js';
+import {NestedPopupsController} from './nested-popups-controller.js';
+import {PermissionsToggleController} from './permissions-toggle-controller.js';
+import {PersistentStorageController} from './persistent-storage-controller.js';
+import {PopupPreviewController} from './popup-preview-controller.js';
+import {PopupWindowController} from './popup-window-controller.js';
+import {ProfileController} from './profile-controller.js';
+import {ScanInputsController} from './scan-inputs-controller.js';
+import {ScanInputsSimpleController} from './scan-inputs-simple-controller.js';
+import {SecondarySearchDictionaryController} from './secondary-search-dictionary-controller.js';
+import {SentenceTerminationCharactersController} from './sentence-termination-characters-controller.js';
+import {SettingsController} from './settings-controller.js';
+import {SettingsDisplayController} from './settings-display-controller.js';
+import {SortFrequencyDictionaryController} from './sort-frequency-dictionary-controller.js';
+import {StatusFooter} from './status-footer.js';
+import {StorageController} from './storage-controller.js';
+import {TranslationTextReplacementsController} from './translation-text-replacements-controller.js';
async function setupGenericSettingsController(genericSettingController) {
await genericSettingController.prepare();
diff --git a/ext/js/pages/settings/sort-frequency-dictionary-controller.js b/ext/js/pages/settings/sort-frequency-dictionary-controller.js
index 9a3fc237..c946400f 100644
--- a/ext/js/pages/settings/sort-frequency-dictionary-controller.js
+++ b/ext/js/pages/settings/sort-frequency-dictionary-controller.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class SortFrequencyDictionaryController {
+import {yomichan} from '../../yomichan.js';
+
+export class SortFrequencyDictionaryController {
constructor(settingsController) {
this._settingsController = settingsController;
this._sortFrequencyDictionarySelect = null;
diff --git a/ext/js/pages/settings/status-footer.js b/ext/js/pages/settings/status-footer.js
index 5c6ecbc8..6c64794f 100644
--- a/ext/js/pages/settings/status-footer.js
+++ b/ext/js/pages/settings/status-footer.js
@@ -16,11 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * PanelElement
- */
+import {PanelElement} from '../../dom/panel-element.js';
-class StatusFooter extends PanelElement {
+export class StatusFooter extends PanelElement {
constructor(node) {
super({
node,
diff --git a/ext/js/pages/settings/storage-controller.js b/ext/js/pages/settings/storage-controller.js
index 49ee7361..8bc63725 100644
--- a/ext/js/pages/settings/storage-controller.js
+++ b/ext/js/pages/settings/storage-controller.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class StorageController {
+import {yomichan} from '../../yomichan.js';
+
+export class StorageController {
constructor(persistentStorageController) {
this._persistentStorageController = persistentStorageController;
this._mostRecentStorageEstimate = null;
diff --git a/ext/js/pages/settings/translation-text-replacements-controller.js b/ext/js/pages/settings/translation-text-replacements-controller.js
index 1a98c406..4a860b52 100644
--- a/ext/js/pages/settings/translation-text-replacements-controller.js
+++ b/ext/js/pages/settings/translation-text-replacements-controller.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class TranslationTextReplacementsController {
+import {EventListenerCollection} from '../../core.js';
+
+export class TranslationTextReplacementsController {
constructor(settingsController) {
this._settingsController = settingsController;
this._entryContainer = null;
diff --git a/ext/js/pages/welcome-main.js b/ext/js/pages/welcome-main.js
index 8039dae5..d2596921 100644
--- a/ext/js/pages/welcome-main.js
+++ b/ext/js/pages/welcome-main.js
@@ -16,19 +16,19 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * DictionaryController
- * DictionaryImportController
- * DocumentFocusController
- * ExtensionContentController
- * GenericSettingController
- * ModalController
- * RecommendedPermissionsController
- * ScanInputsSimpleController
- * SettingsController
- * SettingsDisplayController
- * StatusFooter
- */
+import {log} from '../core.js';
+import {DocumentFocusController} from '../dom/document-focus-controller.js';
+import {yomichan} from '../yomichan.js';
+import {ExtensionContentController} from './common/extension-content-controller.js';
+import {DictionaryController} from './settings/dictionary-controller.js';
+import {DictionaryImportController} from './settings/dictionary-import-controller.js';
+import {GenericSettingController} from './settings/generic-setting-controller.js';
+import {ModalController} from './settings/modal-controller.js';
+import {RecommendedPermissionsController} from './settings/recommended-permissions-controller.js';
+import {ScanInputsSimpleController} from './settings/scan-inputs-simple-controller.js';
+import {SettingsController} from './settings/settings-controller.js';
+import {SettingsDisplayController} from './settings/settings-display-controller.js';
+import {StatusFooter} from './settings/status-footer.js';
async function setupEnvironmentInfo() {
const {manifest_version: manifestVersion} = chrome.runtime.getManifest();
diff --git a/ext/js/script/dynamic-loader-sentinel.js b/ext/js/script/dynamic-loader-sentinel.js
index 9e049d7a..7f08c503 100644
--- a/ext/js/script/dynamic-loader-sentinel.js
+++ b/ext/js/script/dynamic-loader-sentinel.js
@@ -16,4 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {yomichan} from '../yomichan.js';
+
yomichan.trigger('dynamicLoaderSentinel', {script: document.currentScript});
diff --git a/ext/js/script/dynamic-loader.js b/ext/js/script/dynamic-loader.js
index 7f3e77a4..2eced077 100644
--- a/ext/js/script/dynamic-loader.js
+++ b/ext/js/script/dynamic-loader.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-const dynamicLoader = (() => {
+import {yomichan} from '../yomichan.js';
+
+export const dynamicLoader = (() => {
const injectedStylesheets = new Map();
const injectedStylesheetsWithParent = new WeakMap();
@@ -146,6 +148,7 @@ const dynamicLoader = (() => {
yomichan.on(sentinelEventName, sentinelEventCallback);
try {
+ script.type = 'module';
script.async = false;
script.src = '/js/script/dynamic-loader-sentinel.js';
parent.appendChild(script);
diff --git a/ext/js/templates/__mocks__/template-renderer-proxy.js b/ext/js/templates/__mocks__/template-renderer-proxy.js
new file mode 100644
index 00000000..bcacf13b
--- /dev/null
+++ b/ext/js/templates/__mocks__/template-renderer-proxy.js
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ * Copyright (C) 2021-2022 Yomichan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import {AnkiTemplateRenderer} from '../sandbox/anki-template-renderer.js';
+
+export class TemplateRendererProxy {
+ constructor() {
+ this._preparePromise = null;
+ this._ankiTemplateRenderer = new AnkiTemplateRenderer();
+ }
+
+ async render(template, data, type) {
+ await this._prepare();
+ return await this._ankiTemplateRenderer.templateRenderer.render(template, data, type);
+ }
+
+ async renderMulti(items) {
+ await this._prepare();
+ return await this._serializeMulti(this._ankiTemplateRenderer.templateRenderer.renderMulti(items));
+ }
+
+ _prepare() {
+ if (this._preparePromise === null) {
+ this._preparePromise = this._prepareInternal();
+ }
+ return this._preparePromise;
+ }
+
+ async _prepareInternal() {
+ await this._ankiTemplateRenderer.prepare();
+ }
+
+ _serializeError(error) {
+ try {
+ if (typeof error === 'object' && error !== null) {
+ const result = {
+ name: error.name,
+ message: error.message,
+ stack: error.stack
+ };
+ if (Object.prototype.hasOwnProperty.call(error, 'data')) {
+ result.data = error.data;
+ }
+ return result;
+ }
+ } catch (e) {
+ // NOP
+ }
+ return {
+ value: error,
+ hasValue: true
+ };
+ }
+
+ _serializeMulti(array) {
+ for (let i = 0, ii = array.length; i < ii; ++i) {
+ const value = array[i];
+ const {error} = value;
+ if (typeof error !== 'undefined') {
+ value.error = this._serializeError(error);
+ }
+ }
+ return array;
+ }
+}
diff --git a/ext/js/templates/sandbox/anki-template-renderer-content-manager.js b/ext/js/templates/sandbox/anki-template-renderer-content-manager.js
index c51f01b3..596fa499 100644
--- a/ext/js/templates/sandbox/anki-template-renderer-content-manager.js
+++ b/ext/js/templates/sandbox/anki-template-renderer-content-manager.js
@@ -31,7 +31,7 @@
/**
* The content manager which is used when generating content for Anki.
*/
-class AnkiTemplateRendererContentManager {
+export class AnkiTemplateRendererContentManager {
/**
* Creates a new instance of the class.
* @param {TemplateRendererMediaProvider} mediaProvider The media provider for the object.
diff --git a/ext/js/templates/sandbox/anki-template-renderer.js b/ext/js/templates/sandbox/anki-template-renderer.js
index 766c7798..10f69745 100644
--- a/ext/js/templates/sandbox/anki-template-renderer.js
+++ b/ext/js/templates/sandbox/anki-template-renderer.js
@@ -16,24 +16,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * AnkiNoteDataCreator
- * AnkiTemplateRendererContentManager
- * CssStyleApplier
- * DictionaryDataUtil
- * Handlebars
- * JapaneseUtil
- * PronunciationGenerator
- * StructuredContentGenerator
- * TemplateRenderer
- * TemplateRendererMediaProvider
- */
+import {Handlebars} from '../../../lib/handlebars.js';
+import {AnkiNoteDataCreator} from '../../data/sandbox/anki-note-data-creator.js';
+import {PronunciationGenerator} from '../../display/sandbox/pronunciation-generator.js';
+import {StructuredContentGenerator} from '../../display/sandbox/structured-content-generator.js';
+import {CssStyleApplier} from '../../dom/sandbox/css-style-applier.js';
+import {DictionaryDataUtil} from '../../language/sandbox/dictionary-data-util.js';
+import {JapaneseUtil} from '../../language/sandbox/japanese-util.js';
+import {AnkiTemplateRendererContentManager} from './anki-template-renderer-content-manager.js';
+import {TemplateRendererMediaProvider} from './template-renderer-media-provider.js';
+import {TemplateRenderer} from './template-renderer.js';
/**
* This class contains all Anki-specific template rendering functionality. It is built on
* the generic TemplateRenderer class and various other Anki-related classes.
*/
-class AnkiTemplateRenderer {
+export class AnkiTemplateRenderer {
/**
* Creates a new instance of the class.
*/
diff --git a/ext/js/templates/sandbox/template-renderer-frame-api.js b/ext/js/templates/sandbox/template-renderer-frame-api.js
index d8f2714b..7ce2d909 100644
--- a/ext/js/templates/sandbox/template-renderer-frame-api.js
+++ b/ext/js/templates/sandbox/template-renderer-frame-api.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class TemplateRendererFrameApi {
+export class TemplateRendererFrameApi {
constructor(templateRenderer) {
this._templateRenderer = templateRenderer;
this._windowMessageHandlers = new Map([
diff --git a/ext/js/templates/sandbox/template-renderer-frame-main.js b/ext/js/templates/sandbox/template-renderer-frame-main.js
index df5b65ca..43b17b1e 100644
--- a/ext/js/templates/sandbox/template-renderer-frame-main.js
+++ b/ext/js/templates/sandbox/template-renderer-frame-main.js
@@ -16,10 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* globals
- * AnkiTemplateRenderer
- * TemplateRendererFrameApi
- */
+import {AnkiTemplateRenderer} from './anki-template-renderer.js';
+import {TemplateRendererFrameApi} from './template-renderer-frame-api.js';
(async () => {
const ankiTemplateRenderer = new AnkiTemplateRenderer();
diff --git a/ext/js/templates/sandbox/template-renderer-media-provider.js b/ext/js/templates/sandbox/template-renderer-media-provider.js
index f430fa27..9d77dd1f 100644
--- a/ext/js/templates/sandbox/template-renderer-media-provider.js
+++ b/ext/js/templates/sandbox/template-renderer-media-provider.js
@@ -20,7 +20,7 @@
* Handlebars
*/
-class TemplateRendererMediaProvider {
+export class TemplateRendererMediaProvider {
constructor() {
this._requirements = null;
}
diff --git a/ext/js/templates/sandbox/template-renderer.js b/ext/js/templates/sandbox/template-renderer.js
index 7179f366..8d8a2765 100644
--- a/ext/js/templates/sandbox/template-renderer.js
+++ b/ext/js/templates/sandbox/template-renderer.js
@@ -16,12 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * Handlebars
- * handlebarsCompileFnName
- */
+import {Handlebars} from '../../../lib/handlebars.js';
-class TemplateRenderer {
+export class TemplateRenderer {
constructor() {
this._cache = new Map();
this._cacheMaxSize = 5;
@@ -31,7 +28,6 @@ class TemplateRenderer {
}
registerHelpers(helpers) {
- Handlebars.partials = Handlebars.templates;
for (const [name, helper] of helpers) {
this._registerHelper(name, helper);
}
@@ -84,7 +80,7 @@ class TemplateRenderer {
let instance = cache.get(template);
if (typeof instance === 'undefined') {
this._updateCacheSize(this._cacheMaxSize - 1);
- instance = Handlebars[handlebarsCompileFnName](template);
+ instance = Handlebars.compileAST(template);
cache.set(template, instance);
}
diff --git a/ext/js/templates/template-patcher.js b/ext/js/templates/template-patcher.js
index 1e6b0110..6bc012bc 100644
--- a/ext/js/templates/template-patcher.js
+++ b/ext/js/templates/template-patcher.js
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class TemplatePatcher {
+export class TemplatePatcher {
constructor() {
this._diffPattern1 = /\n?\{\{<<<<<<<\}\}\n/g;
this._diffPattern2 = /\n\{\{=======\}\}\n/g;
diff --git a/ext/js/templates/template-renderer-proxy.js b/ext/js/templates/template-renderer-proxy.js
index b504daf2..c46d05f9 100644
--- a/ext/js/templates/template-renderer-proxy.js
+++ b/ext/js/templates/template-renderer-proxy.js
@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-class TemplateRendererProxy {
+import {deserializeError, generateId} from '../core.js';
+
+export class TemplateRendererProxy {
constructor() {
this._frame = null;
this._frameNeedsLoad = true;
diff --git a/ext/js/yomichan.js b/ext/js/yomichan.js
index a4feaa23..985e3f5b 100644
--- a/ext/js/yomichan.js
+++ b/ext/js/yomichan.js
@@ -16,10 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-/* global
- * API
- * CrossFrameAPI
- */
+import {API} from './comm/api.js';
+import {CrossFrameAPI} from './comm/cross-frame-api.js';
+import {EventDispatcher, deferPromise, invokeMessageHandler, log, serializeError} from './core.js';
// Set up chrome alias if it's not available (Edge Legacy)
if ((() => {
@@ -239,4 +238,4 @@ class Yomichan extends EventDispatcher {
/**
* The default Yomichan class instance.
*/
-const yomichan = new Yomichan();
+export const yomichan = new Yomichan();