diff options
| -rw-r--r-- | ext/js/background/backend.js | 19 | ||||
| -rw-r--r-- | ext/js/core.js | 15 | ||||
| -rw-r--r-- | ext/js/dom/dom-text-scanner.js | 227 | ||||
| -rw-r--r-- | ext/js/language/text-scanner.js | 12 | ||||
| -rw-r--r-- | ext/js/pages/settings/dictionary-import-controller.js | 9 | ||||
| -rw-r--r-- | types/ext/dictionary-importer.d.ts | 25 | ||||
| -rw-r--r-- | types/ext/dom-text-scanner.d.ts | 39 | ||||
| -rw-r--r-- | types/ext/log.d.ts | 11 | ||||
| -rw-r--r-- | types/ext/text-scanner.d.ts | 13 | 
9 files changed, 250 insertions, 120 deletions
| diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index df4b9777..a4cf6949 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -342,8 +342,9 @@ export class Backend {       * @param {{level: import('log').LogLevel}} params       */      _onLog({level}) { -        const levelValue = this._getErrorLevelValue(level); -        if (levelValue <= this._getErrorLevelValue(this._logErrorLevel)) { return; } +        const levelValue = log.getLogErrorLevelValue(level); +        const currentLogErrorLevel = this._logErrorLevel !== null ? log.getLogErrorLevelValue(this._logErrorLevel) : 0; +        if (levelValue <= currentLogErrorLevel) { return; }          this._logErrorLevel = level;          this._updateBadge(); @@ -1452,20 +1453,6 @@ export class Backend {      }      /** -     * @param {?import('log').LogLevel} errorLevel -     * @returns {number} -     */ -    _getErrorLevelValue(errorLevel) { -        switch (errorLevel) { -            case 'info': return 0; -            case 'debug': return 0; -            case 'warn': return 1; -            case 'error': return 2; -            default: return 0; -        } -    } - -    /**       * @param {import('settings-modifications').OptionsScope} target       * @returns {import('settings').Options|import('settings').ProfileOptions}       * @throws {Error} diff --git a/ext/js/core.js b/ext/js/core.js index 9995ee5b..63c2f527 100644 --- a/ext/js/core.js +++ b/ext/js/core.js @@ -734,6 +734,21 @@ export class Logger extends EventDispatcher {      error(error, context = null) {          this.log(error, 'error', context);      } + +    /** +     * @param {import('log').LogLevel} errorLevel +     * @returns {import('log').LogErrorLevelValue} +     */ +    getLogErrorLevelValue(errorLevel) { +        switch (errorLevel) { +            case 'log': +            case 'info': +            case 'debug': +                return 0; +            case 'warn': return 1; +            case 'error': return 2; +        } +    }  }  /** diff --git a/ext/js/dom/dom-text-scanner.js b/ext/js/dom/dom-text-scanner.js index df097688..6d979515 100644 --- a/ext/js/dom/dom-text-scanner.js +++ b/ext/js/dom/dom-text-scanner.js @@ -170,6 +170,7 @@ export class DOMTextScanner {          const nodeValueLength = nodeValue.length;          const {preserveNewlines, preserveWhitespace} = this._getWhitespaceSettings(textNode); +        let done = false;          let lineHasWhitespace = this._lineHasWhitespace;          let lineHasContent = this._lineHasContent;          let content = this._content; @@ -181,51 +182,11 @@ export class DOMTextScanner {              const char = StringUtil.readCodePointsForward(nodeValue, offset, 1);              offset += char.length;              const charAttributes = DOMTextScanner.getCharacterAttributes(char, preserveNewlines, preserveWhitespace); +            /** @type {import('dom-text-scanner').SeekTextNoteDetails} */ +            const seekTextNoteDetails = {done, lineHasWhitespace, lineHasContent, content, offset, remainder, newlines}; -            if (charAttributes === 0) { -                // Character should be ignored -                continue; -            } else if (charAttributes === 1) { -                // Character is collapsible whitespace -                lineHasWhitespace = true; -            } else { -                // Character should be added to the content -                if (newlines > 0) { -                    if (content.length > 0) { -                        const useNewlineCount = Math.min(remainder, newlines); -                        content += '\n'.repeat(useNewlineCount); -                        remainder -= useNewlineCount; -                        newlines -= useNewlineCount; -                    } else { -                        newlines = 0; -                    } -                    lineHasContent = false; -                    lineHasWhitespace = false; -                    if (remainder <= 0) { -                        offset -= char.length; // Revert character offset -                        break; -                    } -                } - -                lineHasContent = (charAttributes === 2); // 3 = character is a newline - -                if (lineHasWhitespace) { -                    if (lineHasContent) { -                        content += ' '; -                        lineHasWhitespace = false; -                        if (--remainder <= 0) { -                            offset -= char.length; // Revert character offset -                            break; -                        } -                    } else { -                        lineHasWhitespace = false; -                    } -                } - -                content += char; - -                if (--remainder <= 0) { break; } -            } +            ({done, lineHasWhitespace, lineHasContent, content, offset, remainder, newlines} = this._checkCharacterForward(char, charAttributes, seekTextNoteDetails)); +            if (done) { break; }          }          this._lineHasWhitespace = lineHasWhitespace; @@ -256,6 +217,7 @@ export class DOMTextScanner {          const nodeValueLength = nodeValue.length;          const {preserveNewlines, preserveWhitespace} = this._getWhitespaceSettings(textNode); +        let done = false;          let lineHasWhitespace = this._lineHasWhitespace;          let lineHasContent = this._lineHasContent;          let content = this._content; @@ -268,50 +230,11 @@ export class DOMTextScanner {              offset -= char.length;              const charAttributes = DOMTextScanner.getCharacterAttributes(char, preserveNewlines, preserveWhitespace); -            if (charAttributes === 0) { -                // Character should be ignored -                continue; -            } else if (charAttributes === 1) { -                // Character is collapsible whitespace -                lineHasWhitespace = true; -            } else { -                // Character should be added to the content -                if (newlines > 0) { -                    if (content.length > 0) { -                        const useNewlineCount = Math.min(remainder, newlines); -                        content = '\n'.repeat(useNewlineCount) + content; -                        remainder -= useNewlineCount; -                        newlines -= useNewlineCount; -                    } else { -                        newlines = 0; -                    } -                    lineHasContent = false; -                    lineHasWhitespace = false; -                    if (remainder <= 0) { -                        offset += char.length; // Revert character offset -                        break; -                    } -                } - -                lineHasContent = (charAttributes === 2); // 3 = character is a newline +            /** @type {import('dom-text-scanner').SeekTextNoteDetails} */ +            const seekTextNoteDetails = {done, lineHasWhitespace, lineHasContent, content, offset, remainder, newlines}; -                if (lineHasWhitespace) { -                    if (lineHasContent) { -                        content = ' ' + content; -                        lineHasWhitespace = false; -                        if (--remainder <= 0) { -                            offset += char.length; // Revert character offset -                            break; -                        } -                    } else { -                        lineHasWhitespace = false; -                    } -                } - -                content = char + content; - -                if (--remainder <= 0) { break; } -            } +            ({done, lineHasWhitespace, lineHasContent, content, offset, remainder, newlines} = this._checkCharacterBackward(char, charAttributes, seekTextNoteDetails)); +            if (done) { break; }          }          this._lineHasWhitespace = lineHasWhitespace; @@ -350,6 +273,130 @@ export class DOMTextScanner {          return {preserveNewlines: false, preserveWhitespace: false};      } +    /** +     * @param {string} char +     * @param {import('dom-text-scanner').CharacterAttributesEnum} charAttributes +     * @param {import('dom-text-scanner').SeekTextNoteDetails} seekTextNoteDetails +     * @returns {import('dom-text-scanner').SeekTextNoteDetails} +     */ +    _checkCharacterForward(char, charAttributes, seekTextNoteDetails) { +        let {done, lineHasWhitespace, lineHasContent, content, offset, remainder, newlines} = seekTextNoteDetails; + +        switch (charAttributes) { +            case 0: +                break; +            case 1: +                lineHasWhitespace = true; +                break; +            case 2: +            case 3: +                if (newlines > 0) { +                    if (content.length > 0) { +                        const useNewlineCount = Math.min(remainder, newlines); +                        content += '\n'.repeat(useNewlineCount); +                        remainder -= useNewlineCount; +                        newlines -= useNewlineCount; +                    } else { +                        newlines = 0; +                    } +                    lineHasContent = false; +                    lineHasWhitespace = false; +                    if (remainder <= 0) { +                        offset -= char.length; // Revert character offset +                        done = true; +                        break; +                    } +                } + +                lineHasContent = (charAttributes === 2); // 3 = character is a newline + +                if (lineHasWhitespace) { +                    if (lineHasContent) { +                        content += ' '; +                        lineHasWhitespace = false; +                        if (--remainder <= 0) { +                            offset -= char.length; // Revert character offset +                            done = true; +                            break; +                        } +                    } else { +                        lineHasWhitespace = false; +                    } +                } + +                content += char; + +                if (--remainder <= 0) { +                    done = true; +                    break; +                } +        } + +        return {done, lineHasWhitespace, lineHasContent, content, offset, remainder, newlines}; +    } + +    /** +     * @param {string} char +     * @param {import('dom-text-scanner').CharacterAttributesEnum} charAttributes +     * @param {import('dom-text-scanner').SeekTextNoteDetails} seekTextNoteDetails +     * @returns {import('dom-text-scanner').SeekTextNoteDetails} +     */ +    _checkCharacterBackward(char, charAttributes, seekTextNoteDetails) { +        let {done, lineHasWhitespace, lineHasContent, content, offset, remainder, newlines} = seekTextNoteDetails; + +        switch (charAttributes) { +            case 0: +                break; +            case 1: +                lineHasWhitespace = true; +                break; +            case 2: +            case 3: +                if (newlines > 0) { +                    if (content.length > 0) { +                        const useNewlineCount = Math.min(remainder, newlines); +                        content = '\n'.repeat(useNewlineCount) + content; +                        remainder -= useNewlineCount; +                        newlines -= useNewlineCount; +                    } else { +                        newlines = 0; +                    } +                    lineHasContent = false; +                    lineHasWhitespace = false; +                    if (remainder <= 0) { +                        offset += char.length; // Revert character offset +                        done = true; +                        break; +                    } +                } + +                lineHasContent = (charAttributes === 2); // 3 = character is a newline + +                if (lineHasWhitespace) { +                    if (lineHasContent) { +                        content = ' ' + content; +                        lineHasWhitespace = false; +                        if (--remainder <= 0) { +                            offset += char.length; // Revert character offset +                            done = true; +                            break; +                        } +                    } else { +                        lineHasWhitespace = false; +                    } +                } + +                content = char + content; + +                if (--remainder <= 0) { +                    done = true; +                    break; +                } +        } + +        return {done, lineHasWhitespace, lineHasContent, content, offset, remainder, newlines}; +    } +      // Static helpers      /** @@ -468,11 +515,7 @@ export class DOMTextScanner {       * @param {string} character A string containing a single character.       * @param {boolean} preserveNewlines Whether or not newlines should be preserved.       * @param {boolean} preserveWhitespace Whether or not whitespace should be preserved. -     * @returns {number} An integer representing the attributes of the character. -     *   0: Character should be ignored. -     *   1: Character is collapsible whitespace. -     *   2: Character should be added to the content. -     *   3: Character should be added to the content and is a newline. +     * @returns {import('dom-text-scanner').CharacterAttributesEnum} An enum representing the attributes of the character.       */      static getCharacterAttributes(character, preserveNewlines, preserveWhitespace) {          switch (character.charCodeAt(0)) { diff --git a/ext/js/language/text-scanner.js b/ext/js/language/text-scanner.js index 800e3697..164e150e 100644 --- a/ext/js/language/text-scanner.js +++ b/ext/js/language/text-scanner.js @@ -137,8 +137,8 @@ export class TextScanner extends EventDispatcher {          this._preventNextClick = false;          /** @type {boolean} */          this._preventScroll = false; -        /** @type {0|1|2|3} */ -        this._penPointerState = 0; // 0 = not active; 1 = hovering; 2 = touching; 3 = hovering after touching +        /** @type {import('text-scanner').PenPointerState} */ +        this._penPointerState = 0;          /** @type {Map<number, string>} */          this._pointerIdTypeMap = new Map(); @@ -1382,13 +1382,13 @@ export class TextScanner extends EventDispatcher {                  return input.scanOnPenRelease;          }          switch (this._penPointerState) { -            case 1: // hovering +            case 1:                  return input.scanOnPenHover; -            case 2: // touching +            case 2:                  return input.scanOnPenMove; -            case 3: // hovering after touching +            case 3:                  return input.scanOnPenReleaseHover; -            default: // not active +            case 0:                  return false;          }      } diff --git a/ext/js/pages/settings/dictionary-import-controller.js b/ext/js/pages/settings/dictionary-import-controller.js index c478b265..79a62d32 100644 --- a/ext/js/pages/settings/dictionary-import-controller.js +++ b/ext/js/pages/settings/dictionary-import-controller.js @@ -161,6 +161,7 @@ export class DictionaryImportController {              };              let statusPrefix = ''; +            /** @type {import('dictionary-importer.js').ImportStep} */              let stepIndex = -2;              /** @type {import('dictionary-worker').ImportProgressCallback} */              const onProgress = (data) => { @@ -178,8 +179,8 @@ export class DictionaryImportController {                  for (const label of statusLabels) { label.textContent = statusString; }                  switch (stepIndex2) { -                    case -2: // Initialize -                    case 5: // Data import +                    case -2: +                    case 5:                          this._triggerStorageChanged();                          break;                  } @@ -210,11 +211,12 @@ export class DictionaryImportController {      }      /** -     * @param {number} stepIndex +     * @param {import('dictionary-importer').ImportStep} stepIndex       * @returns {string}       */      _getImportLabel(stepIndex) {          switch (stepIndex) { +            case -2: return '';              case -1:              case 0: return 'Loading dictionary';              case 1: return 'Loading schemas'; @@ -222,7 +224,6 @@ export class DictionaryImportController {              case 3: return 'Formatting data';              case 4: return 'Importing media';              case 5: return 'Importing data'; -            default: return '';          }      } diff --git a/types/ext/dictionary-importer.d.ts b/types/ext/dictionary-importer.d.ts index cccfdc42..cda1bd19 100644 --- a/types/ext/dictionary-importer.d.ts +++ b/types/ext/dictionary-importer.d.ts @@ -23,9 +23,30 @@ import type * as StructuredContent from './structured-content';  export type OnProgressCallback = (data: ProgressData) => void; +/** + * An enum representing the import step. + * + * `-2` `-1` Dictionary import is uninitialized. + * + * `0` Load dictionary archive and validate index step. + * + * `1` Load schemas and get archive files step. + * + * `2` Load and validate dictionary data step. + * + * `3` Format dictionary data and extended data support step. + * + * `4` Resolve async requirements and import media step. + * + * `5` Add dictionary descriptor and import data step. + */ +export type ImportStep = -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5; + +export type ImportStepCount = 6; +  export type ProgressData = { -    stepIndex: number; -    stepCount: number; +    stepIndex: ImportStep; +    stepCount: ImportStepCount;      index: number;      count: number;  }; diff --git a/types/ext/dom-text-scanner.d.ts b/types/ext/dom-text-scanner.d.ts new file mode 100644 index 00000000..e3ae4b53 --- /dev/null +++ b/types/ext/dom-text-scanner.d.ts @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023  Yomitan 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/>. + */ + +/** + * An enum representing the attributes of the character. + * + * `0` Character should be ignored. + * + * `1` Character is collapsible whitespace. + * + * `2` Character should be added to the content. + * + * `3` Character should be added to the content and is a newline. + */ +export type CharacterAttributesEnum = 0 | 1 | 2 | 3; + +export type SeekTextNoteDetails = { +    done: boolean; +    lineHasWhitespace: boolean; +    lineHasContent: boolean; +    content: string; +    offset: number; +    remainder: number; +    newlines: number; +}; diff --git a/types/ext/log.d.ts b/types/ext/log.d.ts index ac2f606b..904bf848 100644 --- a/types/ext/log.d.ts +++ b/types/ext/log.d.ts @@ -22,3 +22,14 @@ export type LoggerEventType = 'log';  export type LogContext = {      url: string;  }; + +/** + * An enum representing the log error level. + * + * `0` _log_, _info_, _debug_ level. + * + * `1` _warn_ level. + * + * `2` _error_ level. + */ +export type LogErrorLevelValue = 0 | 1 | 2; diff --git a/types/ext/text-scanner.d.ts b/types/ext/text-scanner.d.ts index 5b806dab..d56d623a 100644 --- a/types/ext/text-scanner.d.ts +++ b/types/ext/text-scanner.d.ts @@ -185,6 +185,19 @@ export type PointerEventType = (      'script'  ); +/** + * An enum representing the pen pointer state. + * + * `0` Not active. + * + * `1` Hovering. + * + * `2` Touching. + * + * `3` Hovering after touching. + */ +export type PenPointerState = 0 | 1 | 2 | 3; +  export type SentenceTerminatorMap = Map<string, [includeCharacterAtStart: boolean, includeCharacterAtEnd: boolean]>;  export type SentenceForwardQuoteMap = Map<string, [character: string, includeCharacterAtStart: boolean]>; |