aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/js/background/backend.js19
-rw-r--r--ext/js/core.js15
-rw-r--r--ext/js/dom/dom-text-scanner.js227
-rw-r--r--ext/js/language/text-scanner.js12
-rw-r--r--ext/js/pages/settings/dictionary-import-controller.js9
-rw-r--r--types/ext/dictionary-importer.d.ts25
-rw-r--r--types/ext/dom-text-scanner.d.ts39
-rw-r--r--types/ext/log.d.ts11
-rw-r--r--types/ext/text-scanner.d.ts13
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]>;