From 6bf7b0055765c4f2011c9614753d6714dc09be65 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 14 Feb 2024 22:26:29 -0500 Subject: 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 --- ext/js/accessibility/google-docs-util.js | 2 ++ ext/js/app/frontend.js | 6 ++--- ext/js/app/popup.js | 6 +++-- ext/js/app/theme-controller.js | 6 ++--- ext/js/background/backend.js | 10 ++++----- ext/js/background/offscreen-proxy.js | 3 +-- ext/js/background/offscreen.js | 3 +-- ext/js/core/extension-error.js | 2 ++ ext/js/data/json-schema.js | 24 ++++++++++---------- ext/js/data/permissions-util.js | 6 ++--- ext/js/display/display-anki.js | 2 ++ ext/js/display/display-audio.js | 6 ++--- ext/js/display/display.js | 17 +++++++------- ext/js/display/element-overflow-controller.js | 10 ++++----- .../sandbox/structured-content-generator.js | 2 +- ext/js/display/search-display-controller.js | 5 ++--- ext/js/dom/document-util.js | 4 +++- ext/js/dom/dom-text-scanner.js | 4 ++-- ext/js/dom/panel-element.js | 26 +++++++++------------- ext/js/dom/popup-menu.js | 4 ++-- ext/js/dom/scroll-element.js | 6 ++--- ext/js/dom/selector-observer.js | 2 +- ext/js/dom/text-source-generator.js | 6 ++--- ext/js/general/object-property-accessor.js | 6 ++--- ext/js/input/hotkey-handler.js | 2 +- ext/js/language/ja/japanese.js | 2 +- ext/js/language/text-scanner.js | 8 +++---- ext/js/language/translator.js | 12 +++++----- ext/js/pages/action-popup-main.js | 2 +- ext/js/pages/info-main.js | 2 +- ext/js/pages/permissions-main.js | 2 ++ ext/js/pages/settings/anki-controller.js | 7 +++--- ext/js/pages/settings/audio-controller.js | 2 +- ext/js/pages/settings/backup-controller.js | 4 +--- .../settings/collapsible-dictionary-controller.js | 4 +--- ext/js/pages/settings/dictionary-controller.js | 6 ++--- .../pages/settings/dictionary-import-controller.js | 6 ++--- .../extension-keyboard-shortcuts-controller.js | 2 +- .../settings/keyboard-shortcuts-controller.js | 2 +- ext/js/pages/settings/profile-controller.js | 4 ++-- .../sentence-termination-characters-controller.js | 5 +++-- ext/js/pages/settings/settings-controller.js | 4 ++-- .../pages/settings/settings-display-controller.js | 4 ++-- ext/js/templates/sandbox/anki-template-renderer.js | 10 ++++----- 44 files changed, 127 insertions(+), 131 deletions(-) (limited to 'ext') 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} */ 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[]} */ (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} */ 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) => 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 += `${safeText}${safeReading}`; - } else { - result += safeText; - } + result += ( + safeReading.length > 0 ? + `${safeText}${safeReading}` : + safeText + ); } return this._safeString(result); -- cgit v1.2.3