diff options
Diffstat (limited to 'ext/js')
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(); |