aboutsummaryrefslogtreecommitdiff
path: root/ext/js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2024-02-14 22:26:29 -0500
committerGitHub <noreply@github.com>2024-02-15 03:26:29 +0000
commit6bf7b0055765c4f2011c9614753d6714dc09be65 (patch)
tree0e782ae66556eaa61a34d9f32d77c831b2443ce5 /ext/js
parent7a4096240ce4faf70a785d047945388baa0daab3 (diff)
Eslint rule updates (#673)
* Install unicorn * Add rules * Fix issues * Install sonarjs * Set up rules * Fix issues * Install eslint-plugin-import and fix import extensions * Simplify permitted error names
Diffstat (limited to 'ext/js')
-rw-r--r--ext/js/accessibility/google-docs-util.js2
-rw-r--r--ext/js/app/frontend.js6
-rw-r--r--ext/js/app/popup.js6
-rw-r--r--ext/js/app/theme-controller.js6
-rw-r--r--ext/js/background/backend.js10
-rw-r--r--ext/js/background/offscreen-proxy.js3
-rw-r--r--ext/js/background/offscreen.js3
-rw-r--r--ext/js/core/extension-error.js2
-rw-r--r--ext/js/data/json-schema.js24
-rw-r--r--ext/js/data/permissions-util.js6
-rw-r--r--ext/js/display/display-anki.js2
-rw-r--r--ext/js/display/display-audio.js6
-rw-r--r--ext/js/display/display.js17
-rw-r--r--ext/js/display/element-overflow-controller.js10
-rw-r--r--ext/js/display/sandbox/structured-content-generator.js2
-rw-r--r--ext/js/display/search-display-controller.js5
-rw-r--r--ext/js/dom/document-util.js4
-rw-r--r--ext/js/dom/dom-text-scanner.js4
-rw-r--r--ext/js/dom/panel-element.js26
-rw-r--r--ext/js/dom/popup-menu.js4
-rw-r--r--ext/js/dom/scroll-element.js6
-rw-r--r--ext/js/dom/selector-observer.js2
-rw-r--r--ext/js/dom/text-source-generator.js6
-rw-r--r--ext/js/general/object-property-accessor.js6
-rw-r--r--ext/js/input/hotkey-handler.js2
-rw-r--r--ext/js/language/ja/japanese.js2
-rw-r--r--ext/js/language/text-scanner.js8
-rw-r--r--ext/js/language/translator.js12
-rw-r--r--ext/js/pages/action-popup-main.js2
-rw-r--r--ext/js/pages/info-main.js2
-rw-r--r--ext/js/pages/permissions-main.js2
-rw-r--r--ext/js/pages/settings/anki-controller.js7
-rw-r--r--ext/js/pages/settings/audio-controller.js2
-rw-r--r--ext/js/pages/settings/backup-controller.js4
-rw-r--r--ext/js/pages/settings/collapsible-dictionary-controller.js4
-rw-r--r--ext/js/pages/settings/dictionary-controller.js6
-rw-r--r--ext/js/pages/settings/dictionary-import-controller.js6
-rw-r--r--ext/js/pages/settings/extension-keyboard-shortcuts-controller.js2
-rw-r--r--ext/js/pages/settings/keyboard-shortcuts-controller.js2
-rw-r--r--ext/js/pages/settings/profile-controller.js4
-rw-r--r--ext/js/pages/settings/sentence-termination-characters-controller.js5
-rw-r--r--ext/js/pages/settings/settings-controller.js4
-rw-r--r--ext/js/pages/settings/settings-display-controller.js4
-rw-r--r--ext/js/templates/sandbox/anki-template-renderer.js10
44 files changed, 127 insertions, 131 deletions
diff --git a/ext/js/accessibility/google-docs-util.js b/ext/js/accessibility/google-docs-util.js
index 969e650e..31ae5982 100644
--- a/ext/js/accessibility/google-docs-util.js
+++ b/ext/js/accessibility/google-docs-util.js
@@ -86,6 +86,8 @@ export class GoogleDocsUtil {
const content = document.createTextNode(text);
const svgText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
const transform = element.getAttribute('transform') || '';
+ // Using getAttribute instead of dataset because element is an SVG element
+ // eslint-disable-next-line unicorn/prefer-dom-node-dataset
const font = element.getAttribute('data-font-css') || '';
const elementX = element.getAttribute('x');
const elementY = element.getAttribute('y');
diff --git a/ext/js/app/frontend.js b/ext/js/app/frontend.js
index 27e7700e..84a8f1e6 100644
--- a/ext/js/app/frontend.js
+++ b/ext/js/app/frontend.js
@@ -82,9 +82,9 @@ export class Frontend {
/** @type {?import('settings').ProfileOptions} */
this._options = null;
/** @type {number} */
- this._pageZoomFactor = 1.0;
+ this._pageZoomFactor = 1;
/** @type {number} */
- this._contentScale = 1.0;
+ this._contentScale = 1;
/** @type {Promise<void>} */
this._lastShowPromise = Promise.resolve();
/** @type {TextSourceGenerator} */
@@ -788,7 +788,7 @@ export class Frontend {
}
if (popupScaleRelativeToVisualViewport) {
const {visualViewport} = window;
- const visualViewportScale = (typeof visualViewport !== 'undefined' && visualViewport !== null ? visualViewport.scale : 1.0);
+ const visualViewportScale = (typeof visualViewport !== 'undefined' && visualViewport !== null ? visualViewport.scale : 1);
contentScale /= visualViewportScale;
}
if (contentScale === this._contentScale) { return; }
diff --git a/ext/js/app/popup.js b/ext/js/app/popup.js
index 08ff0661..103a5468 100644
--- a/ext/js/app/popup.js
+++ b/ext/js/app/popup.js
@@ -68,7 +68,7 @@ export class Popup extends EventDispatcher {
/** @type {?import('settings').OptionsContext} */
this._optionsContext = null;
/** @type {number} */
- this._contentScale = 1.0;
+ this._contentScale = 1;
/** @type {string} */
this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, '');
@@ -777,7 +777,7 @@ export class Popup extends EventDispatcher {
_getPosition(sourceRects, writingMode, viewport) {
sourceRects = this._convertSourceRectsCoordinateSpace(sourceRects);
const contentScale = this._contentScale;
- const scaleRatio = this._frameSizeContentScale === null ? 1.0 : contentScale / this._frameSizeContentScale;
+ const scaleRatio = this._frameSizeContentScale === null ? 1 : contentScale / this._frameSizeContentScale;
this._frameSizeContentScale = contentScale;
const frameRect = this._frame.getBoundingClientRect();
const frameWidth = Math.max(frameRect.width * scaleRatio, this._initialWidth * contentScale);
@@ -1133,6 +1133,8 @@ class PopupError extends ExtensionError {
*/
constructor(message, source) {
super(message);
+ /** @type {string} */
+ this.name = 'PopupError';
/** @type {Popup} */
this._source = source;
}
diff --git a/ext/js/app/theme-controller.js b/ext/js/app/theme-controller.js
index 559a6e57..384fbcc8 100644
--- a/ext/js/app/theme-controller.js
+++ b/ext/js/app/theme-controller.js
@@ -190,9 +190,9 @@ export class ThemeController {
if (color === null) { return; }
const a = color[3];
- if (a <= 0.0) { return; }
+ if (a <= 0) { return; }
- const aInv = 1.0 - a;
+ const aInv = 1 - a;
for (let i = 0; i < 3; ++i) {
target[i] = target[i] * aInv + color[i] * a;
}
@@ -212,7 +212,7 @@ export class ThemeController {
Number.parseInt(m[1], 10),
Number.parseInt(m[2], 10),
Number.parseInt(m[3], 10),
- m4 ? Math.max(0.0, Math.min(1.0, Number.parseFloat(m4))) : 1.0
+ m4 ? Math.max(0, Math.min(1, Number.parseFloat(m4))) : 1
];
}
}
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js
index 090ba7b3..8ab56232 100644
--- a/ext/js/background/backend.js
+++ b/ext/js/background/backend.js
@@ -701,7 +701,7 @@ export class Backend {
typeof chrome.tabs.getZoom === 'function'
)) {
// Not supported
- resolve({zoomFactor: 1.0});
+ resolve({zoomFactor: 1});
return;
}
chrome.tabs.getZoom(tabId, (zoomFactor) => {
@@ -1701,10 +1701,8 @@ export class Backend {
// NOP
}
- if (okay && !done) {
- if (add(item)) {
- done = true;
- }
+ if (okay && !done && add(item)) {
+ done = true;
}
};
@@ -2294,7 +2292,7 @@ export class Backend {
*/
_replaceInvalidFileNameCharacters(fileName) {
// eslint-disable-next-line no-control-regex
- return fileName.replace(/[<>:"/\\|?*\x00-\x1F]/g, '-');
+ return fileName.replace(/[<>:"/\\|?*\u0000-\u001F]/g, '-');
}
/**
diff --git a/ext/js/background/offscreen-proxy.js b/ext/js/background/offscreen-proxy.js
index 8c3f63c9..2351cb96 100644
--- a/ext/js/background/offscreen-proxy.js
+++ b/ext/js/background/offscreen-proxy.js
@@ -144,8 +144,7 @@ export class DictionaryDatabaseProxy {
*/
async getMedia(targets) {
const serializedMedia = /** @type {import('dictionary-database').Media<string>[]} */ (await this._offscreen.sendMessagePromise({action: 'databaseGetMediaOffscreen', params: {targets}}));
- const media = serializedMedia.map((m) => ({...m, content: base64ToArrayBuffer(m.content)}));
- return media;
+ return serializedMedia.map((m) => ({...m, content: base64ToArrayBuffer(m.content)}));
}
}
diff --git a/ext/js/background/offscreen.js b/ext/js/background/offscreen.js
index 754db517..dbdb9773 100644
--- a/ext/js/background/offscreen.js
+++ b/ext/js/background/offscreen.js
@@ -109,8 +109,7 @@ export class Offscreen {
/** @type {import('offscreen').ApiHandler<'databaseGetMediaOffscreen'>} */
async _getMediaHandler({targets}) {
const media = await this._dictionaryDatabase.getMedia(targets);
- const serializedMedia = media.map((m) => ({...m, content: arrayBufferToBase64(m.content)}));
- return serializedMedia;
+ return media.map((m) => ({...m, content: arrayBufferToBase64(m.content)}));
}
/** @type {import('offscreen').ApiHandler<'translatorPrepareOffscreen'>} */
diff --git a/ext/js/core/extension-error.js b/ext/js/core/extension-error.js
index ab1c9dd7..6458f477 100644
--- a/ext/js/core/extension-error.js
+++ b/ext/js/core/extension-error.js
@@ -26,6 +26,8 @@ export class ExtensionError extends Error {
*/
constructor(message) {
super(message);
+ /** @type {string} */
+ this.name = 'ExtensionError';
/** @type {unknown} */
this._data = void 0;
}
diff --git a/ext/js/data/json-schema.js b/ext/js/data/json-schema.js
index 3342e387..9e1497e9 100644
--- a/ext/js/data/json-schema.js
+++ b/ext/js/data/json-schema.js
@@ -27,6 +27,8 @@ export class JsonSchemaError extends Error {
*/
constructor(message, valueStack, schemaStack) {
super(message);
+ /** @type {string} */
+ this.name = 'JsonSchemaError';
/** @type {import('ext/json-schema').ValueStackItem[]} */
this._valueStack = valueStack;
/** @type {import('ext/json-schema').SchemaStackItem[]} */
@@ -371,18 +373,16 @@ export class JsonSchema {
return {schema, stack: [{schema, path: null}]};
}
const {prefixItems} = schema;
- if (typeof prefixItems !== 'undefined') {
- if (index >= 0 && index < prefixItems.length) {
- const itemSchema = prefixItems[index];
- if (typeof itemSchema !== 'undefined') {
- return {
- schema: itemSchema,
- stack: [
- {schema: prefixItems, path: 'prefixItems'},
- {schema: itemSchema, path: index}
- ]
- };
- }
+ if (typeof prefixItems !== 'undefined' && index >= 0 && index < prefixItems.length) {
+ const itemSchema = prefixItems[index];
+ if (typeof itemSchema !== 'undefined') {
+ return {
+ schema: itemSchema,
+ stack: [
+ {schema: prefixItems, path: 'prefixItems'},
+ {schema: itemSchema, path: index}
+ ]
+ };
}
}
const {items} = schema;
diff --git a/ext/js/data/permissions-util.js b/ext/js/data/permissions-util.js
index 837b6d5f..097fe34d 100644
--- a/ext/js/data/permissions-util.js
+++ b/ext/js/data/permissions-util.js
@@ -113,10 +113,8 @@ export function getRequiredPermissionsForAnkiFieldValue(fieldValue) {
export function hasRequiredPermissionsForOptions(permissions, options) {
const permissionsSet = new Set(permissions.permissions);
- if (!permissionsSet.has('nativeMessaging')) {
- if (options.parsing.enableMecabParser) {
- return false;
- }
+ if (!permissionsSet.has('nativeMessaging') && options.parsing.enableMecabParser) {
+ return false;
}
if (!permissionsSet.has('clipboardRead')) {
diff --git a/ext/js/display/display-anki.js b/ext/js/display/display-anki.js
index 4766f1ae..d37efa85 100644
--- a/ext/js/display/display-anki.js
+++ b/ext/js/display/display-anki.js
@@ -953,6 +953,8 @@ class DisplayAnkiError extends Error {
*/
constructor(message) {
super(message);
+ /** @type {string} */
+ this.name = 'DisplayAnkiError';
/** @type {?import('anki-note-builder').Requirement[]} */
this._requirements = null;
/** @type {?import('anki-note-builder').Requirement[]} */
diff --git a/ext/js/display/display-audio.js b/ext/js/display/display-audio.js
index 7d75d6b0..5f4131d0 100644
--- a/ext/js/display/display-audio.js
+++ b/ext/js/display/display-audio.js
@@ -33,7 +33,7 @@ export class DisplayAudio {
/** @type {AudioSystem} */
this._audioSystem = new AudioSystem();
/** @type {number} */
- this._playbackVolume = 1.0;
+ this._playbackVolume = 1;
/** @type {boolean} */
this._autoPlay = false;
/** @type {?import('core').Timeout} */
@@ -166,7 +166,7 @@ export class DisplayAudio {
_onOptionsUpdated({options}) {
const {enabled, autoPlay, volume, sources} = options.audio;
this._autoPlay = enabled && autoPlay;
- this._playbackVolume = Number.isFinite(volume) ? Math.max(0.0, Math.min(1.0, volume / 100.0)) : 1.0;
+ this._playbackVolume = Number.isFinite(volume) ? Math.max(0, Math.min(1, volume / 100)) : 1;
/** @type {Set<import('settings').AudioSourceType>} */
const requiredAudioSources = new Set([
@@ -534,7 +534,7 @@ export class DisplayAudio {
if (headwordNode !== null) {
const {index} = headwordNode.dataset;
if (typeof index === 'string') {
- const headwordIndex = parseInt(index, 10);
+ const headwordIndex = Number.parseInt(index, 10);
if (Number.isFinite(headwordIndex)) { return headwordIndex; }
}
}
diff --git a/ext/js/display/display.js b/ext/js/display/display.js
index a5dad2d1..d30ed8a0 100644
--- a/ext/js/display/display.js
+++ b/ext/js/display/display.js
@@ -619,7 +619,7 @@ export class Display extends EventDispatcher {
if (node === null) { return -1; }
const {index} = node.dataset;
if (typeof index !== 'string') { return -1; }
- const indexNumber = parseInt(index, 10);
+ const indexNumber = Number.parseInt(index, 10);
return Number.isFinite(indexNumber) ? indexNumber : -1;
}
@@ -1020,7 +1020,7 @@ export class Display extends EventDispatcher {
const node = /** @type {HTMLElement} */ (e.currentTarget);
const {index} = node.dataset;
if (typeof index !== 'string') { return; }
- const indexNumber = parseInt(index, 10);
+ const indexNumber = Number.parseInt(index, 10);
if (!Number.isFinite(indexNumber)) { return; }
this._entrySetCurrent(indexNumber);
}
@@ -1146,8 +1146,7 @@ export class Display extends EventDispatcher {
*/
async _findDictionaryEntries(isKanji, source, wildcardsEnabled, optionsContext) {
if (isKanji) {
- const dictionaryEntries = await this._application.api.kanjiFind(source, optionsContext);
- return dictionaryEntries;
+ return await this._application.api.kanjiFind(source, optionsContext);
} else {
/** @type {import('api').FindTermsDetails} */
const findDetails = {};
@@ -1555,11 +1554,11 @@ export class Display extends EventDispatcher {
* @returns {boolean}
*/
_relativeTermView(next) {
- if (next) {
- return this._history.hasNext() && this._history.forward();
- } else {
- return this._history.hasPrevious() && this._history.back();
- }
+ return (
+ next ?
+ this._history.hasNext() && this._history.forward() :
+ this._history.hasPrevious() && this._history.back()
+ );
}
/**
diff --git a/ext/js/display/element-overflow-controller.js b/ext/js/display/element-overflow-controller.js
index e0b9035e..eb83dda4 100644
--- a/ext/js/display/element-overflow-controller.js
+++ b/ext/js/display/element-overflow-controller.js
@@ -157,11 +157,11 @@ export class ElementOverflowController {
* @returns {number|import('core').Timeout}
*/
_requestIdleCallback(callback, timeout) {
- if (typeof requestIdleCallback === 'function') {
- return requestIdleCallback(callback, {timeout});
- } else {
- return setTimeout(callback, timeout);
- }
+ return (
+ typeof requestIdleCallback === 'function' ?
+ requestIdleCallback(callback, {timeout}) :
+ setTimeout(callback, timeout)
+ );
}
/**
diff --git a/ext/js/display/sandbox/structured-content-generator.js b/ext/js/display/sandbox/structured-content-generator.js
index a04feaf2..1dfde39b 100644
--- a/ext/js/display/sandbox/structured-content-generator.js
+++ b/ext/js/display/sandbox/structured-content-generator.js
@@ -137,7 +137,7 @@ export class StructuredContentGenerator {
imageContainer.title = title;
}
- aspectRatioSizer.style.paddingTop = `${invAspectRatio * 100.0}%`;
+ aspectRatioSizer.style.paddingTop = `${invAspectRatio * 100}%`;
if (this._contentManager !== null) {
this._contentManager.loadMedia(
diff --git a/ext/js/display/search-display-controller.js b/ext/js/display/search-display-controller.js
index ed2061e2..6767dce7 100644
--- a/ext/js/display/search-display-controller.js
+++ b/ext/js/display/search-display-controller.js
@@ -322,7 +322,7 @@ export class SearchDisplayController {
*/
async _onProfileSelectChange(event) {
const node = /** @type {HTMLInputElement} */ (event.currentTarget);
- const value = parseInt(node.value, 10);
+ const value = Number.parseInt(node.value, 10);
const optionsFull = await this._display.application.api.optionsGetFull();
if (typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= optionsFull.profiles.length) {
this._setPrimaryProfileIndex(value);
@@ -574,8 +574,7 @@ export class SearchDisplayController {
case 'select':
return true;
}
- if (element instanceof HTMLElement && element.isContentEditable) { return true; }
- return false;
+ return element instanceof HTMLElement && !!element.isContentEditable;
}
/**
diff --git a/ext/js/dom/document-util.js b/ext/js/dom/document-util.js
index 1ec699e6..a98bfe86 100644
--- a/ext/js/dom/document-util.js
+++ b/ext/js/dom/document-util.js
@@ -18,7 +18,9 @@
/**
* This class contains utility functions related to the HTML document.
+ * TODO : This class should be made non-static
*/
+// eslint-disable-next-line unicorn/no-static-only-class
export class DocumentUtil {
/** @type {?boolean} */
static _cssZoomSupported = null;
@@ -460,7 +462,7 @@ export class DocumentUtil {
if (typeof value !== 'string' || value.length === 0) {
return null;
}
- value = parseFloat(value);
+ value = Number.parseFloat(value);
}
return !Number.isNaN(value) ? value : null;
}
diff --git a/ext/js/dom/dom-text-scanner.js b/ext/js/dom/dom-text-scanner.js
index f1dc3661..5b3ea564 100644
--- a/ext/js/dom/dom-text-scanner.js
+++ b/ext/js/dom/dom-text-scanner.js
@@ -488,8 +488,8 @@ export class DOMTextScanner {
static isStyleVisible(style) {
return !(
style.visibility === 'hidden' ||
- parseFloat(style.opacity) <= 0 ||
- parseFloat(style.fontSize) <= 0 ||
+ Number.parseFloat(style.opacity) <= 0 ||
+ Number.parseFloat(style.fontSize) <= 0 ||
(
!DOMTextScanner.isStyleSelectable(style) &&
(
diff --git a/ext/js/dom/panel-element.js b/ext/js/dom/panel-element.js
index 9c1289d7..0f2801e6 100644
--- a/ext/js/dom/panel-element.js
+++ b/ext/js/dom/panel-element.js
@@ -89,16 +89,14 @@ export class PanelElement extends EventDispatcher {
* @param {(details: import('core').EventArgument<import('panel-element').Events, TName>) => void} callback
*/
on(eventName, callback) {
- if (eventName === 'visibilityChanged') {
- if (this._mutationObserver === null) {
- this._visible = this.isVisible();
- this._mutationObserver = new MutationObserver(this._onMutation.bind(this));
- this._mutationObserver.observe(this._node, {
- attributes: true,
- attributeFilter: ['hidden'],
- attributeOldValue: true
- });
- }
+ if (eventName === 'visibilityChanged' && this._mutationObserver === null) {
+ this._visible = this.isVisible();
+ this._mutationObserver = new MutationObserver(this._onMutation.bind(this));
+ this._mutationObserver.observe(this._node, {
+ attributes: true,
+ attributeFilter: ['hidden'],
+ attributeOldValue: true
+ });
}
super.on(eventName, callback);
}
@@ -111,11 +109,9 @@ export class PanelElement extends EventDispatcher {
*/
off(eventName, callback) {
const result = super.off(eventName, callback);
- if (eventName === 'visibilityChanged' && !this.hasListeners(eventName)) {
- if (this._mutationObserver !== null) {
- this._mutationObserver.disconnect();
- this._mutationObserver = null;
- }
+ if (eventName === 'visibilityChanged' && !this.hasListeners(eventName) && this._mutationObserver !== null) {
+ this._mutationObserver.disconnect();
+ this._mutationObserver = null;
}
return result;
}
diff --git a/ext/js/dom/popup-menu.js b/ext/js/dom/popup-menu.js
index 8a8a19ba..28bcc309 100644
--- a/ext/js/dom/popup-menu.js
+++ b/ext/js/dom/popup-menu.js
@@ -219,8 +219,8 @@ export class PopupMenu extends EventDispatcher {
(bottom - top) * ((-vertical + 1) * -0.5)
);
- x = Math.max(0.0, Math.min(containerNodeRect.width - menuRect.width, x));
- y = Math.max(0.0, Math.min(containerNodeRect.height - menuRect.height, y));
+ x = Math.max(0, Math.min(containerNodeRect.width - menuRect.width, x));
+ y = Math.max(0, Math.min(containerNodeRect.height - menuRect.height, y));
menu.style.left = `${x}px`;
menu.style.top = `${y}px`;
diff --git a/ext/js/dom/scroll-element.js b/ext/js/dom/scroll-element.js
index 8005469b..7cd00f01 100644
--- a/ext/js/dom/scroll-element.js
+++ b/ext/js/dom/scroll-element.js
@@ -133,10 +133,10 @@ export class ScrollElement {
*/
_easeInOutCubic(t) {
if (t < 0.5) {
- return (4.0 * t * t * t);
+ return (4 * t * t * t);
} else {
- t = 1.0 - t;
- return 1.0 - (4.0 * t * t * t);
+ t = 1 - t;
+ return 1 - (4 * t * t * t);
}
}
diff --git a/ext/js/dom/selector-observer.js b/ext/js/dom/selector-observer.js
index 791ce627..86607130 100644
--- a/ext/js/dom/selector-observer.js
+++ b/ext/js/dom/selector-observer.js
@@ -170,7 +170,7 @@ export class SelectorObserver {
if (
this._onChildrenUpdated !== null &&
- (addedNodes.length !== 0 || addedNodes.length !== 0)
+ (removedNodes.length > 0 || addedNodes.length > 0)
) {
for (let node = /** @type {?Node} */ (target); node !== null; node = node.parentNode) {
const observer = this._elementMap.get(node);
diff --git a/ext/js/dom/text-source-generator.js b/ext/js/dom/text-source-generator.js
index a5529779..83c7271c 100644
--- a/ext/js/dom/text-source-generator.js
+++ b/ext/js/dom/text-source-generator.js
@@ -307,8 +307,8 @@ export class TextSourceGenerator {
// Adjust size
const imposterRect = imposter.getBoundingClientRect();
if (imposterRect.width !== elementRect.width || imposterRect.height !== elementRect.height) {
- const width = parseFloat(elementStyle.width) + (elementRect.width - imposterRect.width);
- const height = parseFloat(elementStyle.height) + (elementRect.height - imposterRect.height);
+ const width = Number.parseFloat(elementStyle.width) + (elementRect.width - imposterRect.width);
+ const height = Number.parseFloat(elementStyle.height) + (elementRect.height - imposterRect.height);
this._setImposterStyle(imposterStyle, 'width', `${width}px`);
this._setImposterStyle(imposterStyle, 'height', `${height}px`);
}
@@ -614,7 +614,7 @@ export class TextSourceGenerator {
}
const style = window.getComputedStyle(element);
return (
- parseFloat(style.opacity) <= 0 ||
+ Number.parseFloat(style.opacity) <= 0 ||
style.visibility === 'hidden' ||
(style.backgroundImage === 'none' && this._isColorTransparent(style.backgroundColor))
);
diff --git a/ext/js/general/object-property-accessor.js b/ext/js/general/object-property-accessor.js
index d50948d9..ac9e2a54 100644
--- a/ext/js/general/object-property-accessor.js
+++ b/ext/js/general/object-property-accessor.js
@@ -117,14 +117,14 @@ export class ObjectPropertyAccessor {
/** @type {import('core').SerializableObject} */ (target1)[key1] = value2;
try {
/** @type {import('core').SerializableObject} */ (target2)[key2] = value1;
- } catch (e) {
+ } catch (error) {
// Revert
try {
/** @type {import('core').SerializableObject} */ (target1)[key1] = value1;
- } catch (e2) {
+ } catch (error2) {
// NOP
}
- throw e;
+ throw error;
}
}
diff --git a/ext/js/input/hotkey-handler.js b/ext/js/input/hotkey-handler.js
index 9caedcc2..6d7d3d7a 100644
--- a/ext/js/input/hotkey-handler.js
+++ b/ext/js/input/hotkey-handler.js
@@ -254,7 +254,7 @@ export class HotkeyHandler extends EventDispatcher {
*/
_updateEventHandlers() {
if (this._isPrepared && (this._hotkeys.size > 0 || this._hasEventListeners)) {
- if (this._eventListeners.size !== 0) { return; }
+ if (this._eventListeners.size > 0) { return; }
this._eventListeners.addEventListener(document, 'keydown', this._onKeyDown.bind(this), false);
} else {
this._eventListeners.removeAllEventListeners();
diff --git a/ext/js/language/ja/japanese.js b/ext/js/language/ja/japanese.js
index a4508040..818daa0b 100644
--- a/ext/js/language/ja/japanese.js
+++ b/ext/js/language/ja/japanese.js
@@ -92,7 +92,7 @@ const JAPANESE_RANGES = [
[0xffe0, 0xffee] // Currency markers
];
-const SMALL_KANA_SET = new Set(Array.from('ぁぃぅぇぉゃゅょゎァィゥェォャュョヮ'));
+const SMALL_KANA_SET = new Set('ぁぃぅぇぉゃゅょゎァィゥェォャュョヮ');
const HALFWIDTH_KATAKANA_MAPPING = new Map([
['ヲ', 'ヲヺ-'],
diff --git a/ext/js/language/text-scanner.js b/ext/js/language/text-scanner.js
index 811c7987..1cf346a9 100644
--- a/ext/js/language/text-scanner.js
+++ b/ext/js/language/text-scanner.js
@@ -1294,11 +1294,9 @@ export class TextScanner extends EventDispatcher {
async _searchAtFromMouseMove(x, y, inputInfo) {
if (this._pendingLookup) { return; }
- if (inputInfo.passive) {
- if (!await this._scanTimerWait()) {
- // Aborted
- return;
- }
+ if (inputInfo.passive && !await this._scanTimerWait()) {
+ // Aborted
+ return;
}
await this._searchAt(x, y, inputInfo);
diff --git a/ext/js/language/translator.js b/ext/js/language/translator.js
index 007a7d1e..2ba1ce0d 100644
--- a/ext/js/language/translator.js
+++ b/ext/js/language/translator.js
@@ -491,11 +491,11 @@ export class Translator {
* @returns {number}
*/
_getNextSubstringLength(searchResolution, currentLength, source) {
- if (searchResolution === 'word') {
- return source.search(/[^\p{Letter}][\p{Letter}\p{Number}]*$/u);
- } else {
- return currentLength - 1;
- }
+ return (
+ searchResolution === 'word' ?
+ source.search(/[^\p{Letter}][\p{Letter}\p{Number}]*$/u) :
+ currentLength - 1
+ );
}
/**
@@ -620,7 +620,7 @@ export class Translator {
for (const group of groupedDictionaryEntries) {
this._sortTermDictionaryEntriesById(group.dictionaryEntries);
}
- if (ungroupedDictionaryEntriesMap.size !== 0 || secondarySearchDictionaryMap.size !== 0) {
+ if (ungroupedDictionaryEntriesMap.size > 0 || secondarySearchDictionaryMap.size > 0) {
await this._addSecondaryRelatedDictionaryEntries(groupedDictionaryEntries, ungroupedDictionaryEntriesMap, enabledDictionaryMap, secondarySearchDictionaryMap, tagAggregator);
}
}
diff --git a/ext/js/pages/action-popup-main.js b/ext/js/pages/action-popup-main.js
index b5728215..f58083a7 100644
--- a/ext/js/pages/action-popup-main.js
+++ b/ext/js/pages/action-popup-main.js
@@ -238,7 +238,7 @@ class DisplayController {
*/
_onProfileSelectChange(event) {
const node = /** @type {HTMLInputElement} */ (event.currentTarget);
- const value = parseInt(node.value, 10);
+ const value = Number.parseInt(node.value, 10);
if (typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= /** @type {import('settings').Options} */ (this._optionsFull).profiles.length) {
this._setPrimaryProfileIndex(value);
}
diff --git a/ext/js/pages/info-main.js b/ext/js/pages/info-main.js
index 7d7d56a5..0bc84d97 100644
--- a/ext/js/pages/info-main.js
+++ b/ext/js/pages/info-main.js
@@ -108,7 +108,7 @@ async function showDictionaryInfo(api) {
/** @type {HTMLElement} */
const noneElement = querySelectorNotNull(document, '#installed-dictionaries-none');
- noneElement.hidden = (dictionaryInfos.length !== 0);
+ noneElement.hidden = (dictionaryInfos.length > 0);
/** @type {HTMLElement} */
const container = querySelectorNotNull(document, '#installed-dictionaries');
container.textContent = '';
diff --git a/ext/js/pages/permissions-main.js b/ext/js/pages/permissions-main.js
index 3092782b..17169c12 100644
--- a/ext/js/pages/permissions-main.js
+++ b/ext/js/pages/permissions-main.js
@@ -102,6 +102,8 @@ await Application.main(async (application) => {
/** @type {HTMLInputElement} */
const permissionCheckbox2 = querySelectorNotNull(document, '#permission-checkbox-allow-file-url-access');
/** @type {HTMLInputElement[]} */
+ // This collection is actually used, not sure why this eslint-disable is needed.
+ // eslint-disable-next-line sonarjs/no-unused-collection
const permissionsCheckboxes = [permissionCheckbox1, permissionCheckbox2];
const permissions = await Promise.all([
diff --git a/ext/js/pages/settings/anki-controller.js b/ext/js/pages/settings/anki-controller.js
index 3a6345ed..e161d86b 100644
--- a/ext/js/pages/settings/anki-controller.js
+++ b/ext/js/pages/settings/anki-controller.js
@@ -401,11 +401,11 @@ export class AnkiController {
if (typeof data !== 'undefined') {
details += `${JSON.stringify(data, null, 4)}\n\n`;
}
- details += `${error.stack}`.trimRight();
+ details += `${error.stack}`.trimEnd();
/** @type {HTMLElement} */ (this._ankiErrorMessageDetailsNode).textContent = details;
/** @type {HTMLElement} */ (this._ankiErrorMessageDetailsContainer).hidden = true;
- /** @type {HTMLElement} */ (this._ankiErrorInvalidResponseInfo).hidden = (errorString.indexOf('Invalid response') < 0);
+ /** @type {HTMLElement} */ (this._ankiErrorInvalidResponseInfo).hidden = !errorString.includes('Invalid response');
/** @type {HTMLElement} */ (this._ankiErrorMessageDetailsToggle).hidden = false;
}
@@ -762,7 +762,8 @@ class AnkiCardController {
const ELEMENT_NODE = Node.ELEMENT_NODE;
const container = this._ankiCardFieldsContainer;
if (container !== null) {
- for (const node of [...container.childNodes]) {
+ const childNodesFrozen = [...container.childNodes];
+ for (const node of childNodesFrozen) {
if (node.nodeType === ELEMENT_NODE && node instanceof HTMLElement && node.dataset.persistent === 'true') { continue; }
container.removeChild(node);
}
diff --git a/ext/js/pages/settings/audio-controller.js b/ext/js/pages/settings/audio-controller.js
index 9633c4b3..5b597d33 100644
--- a/ext/js/pages/settings/audio-controller.js
+++ b/ext/js/pages/settings/audio-controller.js
@@ -144,7 +144,7 @@ export class AudioController extends EventDispatcher {
const text = input.value || '';
const voiceUri = input.dataset.voice;
const audio = this._audioSystem.createTextToSpeechAudio(text, typeof voiceUri === 'string' ? voiceUri : '');
- audio.volume = 1.0;
+ audio.volume = 1;
audio.play();
} catch (e) {
// NOP
diff --git a/ext/js/pages/settings/backup-controller.js b/ext/js/pages/settings/backup-controller.js
index 59bcaed9..2bab00e3 100644
--- a/ext/js/pages/settings/backup-controller.js
+++ b/ext/js/pages/settings/backup-controller.js
@@ -144,7 +144,7 @@ export class BackupController {
}
}
- const data = {
+ return {
version: this._currentVersion,
date: this._getSettingsExportDateString(date, '-', ' ', ':', 6),
url: chrome.runtime.getURL('/'),
@@ -154,8 +154,6 @@ export class BackupController {
permissions,
options: optionsFull
};
-
- return data;
}
/**
diff --git a/ext/js/pages/settings/collapsible-dictionary-controller.js b/ext/js/pages/settings/collapsible-dictionary-controller.js
index 5ba61e0c..62f84b96 100644
--- a/ext/js/pages/settings/collapsible-dictionary-controller.js
+++ b/ext/js/pages/settings/collapsible-dictionary-controller.js
@@ -156,9 +156,7 @@ export class CollapsibleDictionaryController {
const versionNode = querySelectorNotNull(node, '.dictionary-version');
versionNode.textContent = version;
- /** @type {HTMLSelectElement} */
- const select = querySelectorNotNull(node, '.definitions-collapsible');
- return select;
+ return querySelectorNotNull(node, '.definitions-collapsible');
}
/** */
diff --git a/ext/js/pages/settings/dictionary-controller.js b/ext/js/pages/settings/dictionary-controller.js
index 1d3c1730..5020dc7c 100644
--- a/ext/js/pages/settings/dictionary-controller.js
+++ b/ext/js/pages/settings/dictionary-controller.js
@@ -558,7 +558,7 @@ export class DictionaryController {
const {profiles} = optionsFull;
for (let i = 0, ii = profiles.length; i < ii; ++i) {
let modified = false;
- const missingDictionaries = new Set([...installedDictionaries]);
+ const missingDictionaries = new Set(installedDictionaries);
const dictionaryOptionsArray = profiles[i].options.dictionaries;
for (let j = dictionaryOptionsArray.length - 1; j >= 0; --j) {
const {name} = dictionaryOptionsArray[j];
@@ -871,8 +871,8 @@ export class DictionaryController {
const onProgress = ({processed, count, storeCount, storesProcesed}) => {
const percent = (
(count > 0 && storesProcesed > 0) ?
- (processed / count) * (storesProcesed / storeCount) * 100.0 :
- 0.0
+ (processed / count) * (storesProcesed / storeCount) * 100 :
+ 0
);
const cssString = `${percent}%`;
const statusString = `${percent.toFixed(0)}%`;
diff --git a/ext/js/pages/settings/dictionary-import-controller.js b/ext/js/pages/settings/dictionary-import-controller.js
index 0484001d..34e21c5d 100644
--- a/ext/js/pages/settings/dictionary-import-controller.js
+++ b/ext/js/pages/settings/dictionary-import-controller.js
@@ -172,7 +172,7 @@ export class DictionaryImportController {
for (const label of infoLabels) { label.textContent = labelText; }
}
- const percent = count > 0 ? (index / count * 100.0) : 0.0;
+ const percent = count > 0 ? (index / count * 100) : 0;
const cssString = `${percent}%`;
const statusString = `${Math.floor(percent).toFixed(0)}%`;
for (const progressBar of progressBars) { progressBar.style.width = cssString; }
@@ -199,8 +199,8 @@ export class DictionaryImportController {
await this._importDictionary(files[i], importDetails, onProgress);
}
- } catch (err) {
- this._showErrors([toError(err)]);
+ } catch (error) {
+ this._showErrors([toError(error)]);
} finally {
prevention.end();
for (const progress of progressContainers) { progress.hidden = true; }
diff --git a/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js b/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js
index 61eefffa..b9d107ae 100644
--- a/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js
+++ b/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js
@@ -353,7 +353,7 @@ class ExtensionKeyboardShortcutHotkeyEntry {
* @param {boolean} updateInput
*/
async _tryUpdateInput(key, modifiers, updateInput) {
- let okay = (key === null ? (modifiers.length === 0) : (modifiers.length !== 0));
+ let okay = (key === null ? (modifiers.length === 0) : (modifiers.length > 0));
if (okay) {
try {
await this._parent.updateCommand(this._name, key, modifiers);
diff --git a/ext/js/pages/settings/keyboard-shortcuts-controller.js b/ext/js/pages/settings/keyboard-shortcuts-controller.js
index 7b28a322..907cf4a1 100644
--- a/ext/js/pages/settings/keyboard-shortcuts-controller.js
+++ b/ext/js/pages/settings/keyboard-shortcuts-controller.js
@@ -183,7 +183,7 @@ export class KeyboardShortcutController {
const listContainer = /** @type {HTMLElement} */ (this._listContainer);
listContainer.appendChild(fragment);
listContainer.hidden = (hotkeys.length === 0);
- /** @type {HTMLElement} */ (this._emptyIndicator).hidden = (hotkeys.length !== 0);
+ /** @type {HTMLElement} */ (this._emptyIndicator).hidden = (hotkeys.length > 0);
}
/**
diff --git a/ext/js/pages/settings/profile-controller.js b/ext/js/pages/settings/profile-controller.js
index 5a7b5ed4..a82a4b4e 100644
--- a/ext/js/pages/settings/profile-controller.js
+++ b/ext/js/pages/settings/profile-controller.js
@@ -544,7 +544,7 @@ export class ProfileController {
*/
_tryGetValidProfileIndex(stringValue) {
if (typeof stringValue !== 'string') { return null; }
- const intValue = parseInt(stringValue, 10);
+ const intValue = Number.parseInt(stringValue, 10);
return (
Number.isFinite(intValue) &&
intValue >= 0 &&
@@ -573,7 +573,7 @@ export class ProfileController {
suffix = match[5];
if (typeof match[2] === 'string') {
space = match[3];
- index = parseInt(match[4], 10) + 1;
+ index = Number.parseInt(match[4], 10) + 1;
} else {
space = ' ';
index = 2;
diff --git a/ext/js/pages/settings/sentence-termination-characters-controller.js b/ext/js/pages/settings/sentence-termination-characters-controller.js
index c393aaa1..4ceed22b 100644
--- a/ext/js/pages/settings/sentence-termination-characters-controller.js
+++ b/ext/js/pages/settings/sentence-termination-characters-controller.js
@@ -125,8 +125,9 @@ export class SentenceTerminationCharactersController {
entry.prepare();
}
- /** @type {HTMLElement} */ (this._listTable).hidden = (terminationCharacters.length === 0);
- /** @type {HTMLElement} */ (this._emptyIndicator).hidden = (terminationCharacters.length !== 0);
+ const empty = terminationCharacters.length === 0;
+ /** @type {HTMLElement} */ (this._listTable).hidden = empty;
+ /** @type {HTMLElement} */ (this._emptyIndicator).hidden = !empty;
}
/**
diff --git a/ext/js/pages/settings/settings-controller.js b/ext/js/pages/settings/settings-controller.js
index 3f389271..c835f8e6 100644
--- a/ext/js/pages/settings/settings-controller.js
+++ b/ext/js/pages/settings/settings-controller.js
@@ -195,6 +195,7 @@ export class SettingsController extends EventDispatcher {
*/
preventPageExit() {
/** @type {import('settings-controller').PageExitPrevention} */
+ // eslint-disable-next-line sonarjs/prefer-object-literal
const obj = {};
obj.end = this._endPreventPageExit.bind(this, obj);
if (this._pageExitPreventionEventListeners.size === 0) {
@@ -226,8 +227,7 @@ export class SettingsController extends EventDispatcher {
async getDefaultOptions() {
const optionsUtil = new OptionsUtil();
await optionsUtil.prepare();
- const optionsFull = optionsUtil.getDefault();
- return optionsFull;
+ return optionsUtil.getDefault();
}
// Private
diff --git a/ext/js/pages/settings/settings-display-controller.js b/ext/js/pages/settings/settings-display-controller.js
index 0a729d96..47aa9c9c 100644
--- a/ext/js/pages/settings/settings-display-controller.js
+++ b/ext/js/pages/settings/settings-display-controller.js
@@ -290,7 +290,7 @@ export class SettingsDisplayController {
*/
_getMoreContainer(link) {
const v = link.dataset.parentDistance;
- const distance = v ? parseInt(v, 10) : 1;
+ const distance = v ? Number.parseInt(v, 10) : 1;
if (Number.isNaN(distance)) { return null; }
/** @type {?Element} */
@@ -338,7 +338,7 @@ export class SettingsDisplayController {
let indent = '\t';
if (args.length > 1) {
- const count = parseInt(args[1], 10);
+ const count = Number.parseInt(args[1], 10);
indent = (Number.isFinite(count) && count >= 0 ? ' '.repeat(count) : args[1]);
}
diff --git a/ext/js/templates/sandbox/anki-template-renderer.js b/ext/js/templates/sandbox/anki-template-renderer.js
index 2320a0b1..ad2b0042 100644
--- a/ext/js/templates/sandbox/anki-template-renderer.js
+++ b/ext/js/templates/sandbox/anki-template-renderer.js
@@ -171,11 +171,11 @@ export class AnkiTemplateRenderer {
for (const {text, reading: reading2} of segments) {
const safeText = this._escape(text);
const safeReading = this._escape(reading2);
- if (safeReading.length > 0) {
- result += `<ruby>${safeText}<rt>${safeReading}</rt></ruby>`;
- } else {
- result += safeText;
- }
+ result += (
+ safeReading.length > 0 ?
+ `<ruby>${safeText}<rt>${safeReading}</rt></ruby>` :
+ safeText
+ );
}
return this._safeString(result);