diff --git a/abstract/ActivityBlock.js b/abstract/ActivityBlock.js index 6878ed45e..89bb5fb1b 100644 --- a/abstract/ActivityBlock.js +++ b/abstract/ActivityBlock.js @@ -1,6 +1,6 @@ // @ts-check -import { debounce } from '../blocks/utils/debounce.js'; import { EventType } from '../blocks/UploadCtxProvider/EventEmitter.js'; +import { debounce } from '../blocks/utils/debounce.js'; import { Block } from './Block.js'; import { activityBlockCtx } from './CTX.js'; @@ -15,7 +15,7 @@ export class ActivityBlock extends Block { /** @private */ _deactivate() { - let actDesc = ActivityBlock._activityCallbacks.get(this); + const actDesc = ActivityBlock._activityCallbacks.get(this); this[ACTIVE_PROP] = false; this.removeAttribute(ACTIVE_ATTR); actDesc?.deactivateCallback?.(); @@ -23,7 +23,7 @@ export class ActivityBlock extends Block { /** @private */ _activate() { - let actDesc = ActivityBlock._activityCallbacks.get(this); + const actDesc = ActivityBlock._activityCallbacks.get(this); this.$['*historyBack'] = this.historyBack.bind(this); /** @private */ this[ACTIVE_PROP] = true; @@ -167,7 +167,7 @@ export class ActivityBlock extends Block { historyBack() { /** @type {String[]} */ - let history = this.$['*history']; + const history = this.$['*history']; if (history) { let nextActivity = history.pop(); while (nextActivity === this.activityType) { diff --git a/abstract/Block.js b/abstract/Block.js index f4e68c554..3c45777ca 100644 --- a/abstract/Block.js +++ b/abstract/Block.js @@ -3,16 +3,16 @@ import { BaseComponent, Data } from '@symbiotejs/symbiote'; import { initialConfig } from '../blocks/Config/initialConfig.js'; import { EventEmitter } from '../blocks/UploadCtxProvider/EventEmitter.js'; import { WindowHeightTracker } from '../utils/WindowHeightTracker.js'; -import { extractFilename, extractCdnUrlModifiers, extractUuid } from '../utils/cdn-utils.js'; +import { extractCdnUrlModifiers, extractFilename, extractUuid } from '../utils/cdn-utils.js'; import { getLocaleDirection } from '../utils/getLocaleDirection.js'; import { getPluralForm } from '../utils/getPluralForm.js'; import { applyTemplateData, getPluralObjects } from '../utils/template-utils.js'; import { waitForAttribute } from '../utils/waitForAttribute.js'; import { blockCtx } from './CTX.js'; import { LocaleManager, localeStateKey } from './LocaleManager.js'; +import { A11y } from './a11y.js'; import { l10nProcessor } from './l10nProcessor.js'; import { sharedConfigKey } from './sharedConfigKey.js'; -import { A11y } from './a11y.js'; const TAG_PREFIX = 'lr-'; @@ -39,15 +39,15 @@ export class Block extends BaseComponent { if (!str) { return ''; } - let template = this.$[localeStateKey(str)] || str; - let pluralObjects = getPluralObjects(template); - for (let pluralObject of pluralObjects) { + const template = this.$[localeStateKey(str)] || str; + const pluralObjects = getPluralObjects(template); + for (const pluralObject of pluralObjects) { variables[pluralObject.variable] = this.pluralize( pluralObject.pluralKey, Number(variables[pluralObject.countVariable]), ); } - let result = applyTemplateData(template, variables); + const result = applyTemplateData(template, variables); return result; } @@ -97,7 +97,7 @@ export class Block extends BaseComponent { * @returns {Boolean} */ hasBlockInCtx(callback) { - for (let block of this.blocksRegistry) { + for (const block of this.blocksRegistry) { if (callback(block)) { return true; } @@ -129,13 +129,13 @@ export class Block extends BaseComponent { connectedCallback() { const styleAttrs = /** @type {typeof Block} */ (this.constructor).styleAttrs; - styleAttrs.forEach((attr) => { + for (const attr of styleAttrs) { this.setAttribute(attr, ''); - }); + } if (this.hasAttribute('retpl')) { // @ts-ignore TODO: fix this - this.constructor['template'] = null; + this.constructor.template = null; this.processInnerHtml = true; } if (this.requireCtxName) { @@ -168,7 +168,7 @@ export class Block extends BaseComponent { this.add('*blocksRegistry', new Set()); } - let blocksRegistry = this.$['*blocksRegistry']; + const blocksRegistry = this.$['*blocksRegistry']; blocksRegistry.add(this); if (!this.has('*eventEmitter')) { @@ -204,7 +204,7 @@ export class Block extends BaseComponent { } destroyCallback() { - let blocksRegistry = this.blocksRegistry; + const blocksRegistry = this.blocksRegistry; blocksRegistry.delete(this); this.localeManager?.destroyL10nBindings(this); @@ -239,7 +239,7 @@ export class Block extends BaseComponent { * @param {Number} [decimals] */ fileSizeFmt(bytes, decimals = 2) { - let units = ['B', 'KB', 'MB', 'GB', 'TB']; + const units = ['B', 'KB', 'MB', 'GB', 'TB']; /** * @param {String} str * @returns {String} @@ -247,10 +247,10 @@ export class Block extends BaseComponent { if (bytes === 0) { return `0 ${units[0]}`; } - let k = 1024; - let dm = decimals < 0 ? 0 : decimals; - let i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / k ** i).toFixed(dm)) + ' ' + units[i]; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return `${Number.parseFloat((bytes / k ** i).toFixed(dm))} ${units[i]}`; } /** @@ -283,7 +283,7 @@ export class Block extends BaseComponent { /** @returns {import('../types').ConfigType} } */ get cfg() { if (!this.__cfgProxy) { - let o = Object.create(null); + const o = Object.create(null); /** @private */ this.__cfgProxy = new Proxy(o, { set: (obj, key, value) => { @@ -342,10 +342,10 @@ export class Block extends BaseComponent { /** @param {String} [name] */ static reg(name) { if (!name) { - super.reg(); + BaseComponent.reg(); return; } - super.reg(name.startsWith(TAG_PREFIX) ? name : TAG_PREFIX + name); + BaseComponent.reg(name.startsWith(TAG_PREFIX) ? name : TAG_PREFIX + name); } } diff --git a/abstract/SolutionBlock.js b/abstract/SolutionBlock.js index f9c883587..20cc3a7da 100644 --- a/abstract/SolutionBlock.js +++ b/abstract/SolutionBlock.js @@ -14,7 +14,7 @@ export class SolutionBlock extends Block { } static set template(value) { - SolutionBlock._template = `${svgIconsSprite + value}`; + SolutionBlock._template = /* HTML */ `${svgIconsSprite + value}`; } static get template() { diff --git a/abstract/a11y.js b/abstract/a11y.js index f29f1dce6..dd4eae043 100644 --- a/abstract/a11y.js +++ b/abstract/a11y.js @@ -1,5 +1,5 @@ // @ts-check -import { startKeyUX, hiddenKeyUX, jumpKeyUX, focusGroupKeyUX, pressKeyUX } from 'keyux'; +import { focusGroupKeyUX, hiddenKeyUX, jumpKeyUX, pressKeyUX, startKeyUX } from 'keyux'; /** * MinimalWindow interface is not exported by keyux, so we import it here using tricky way. diff --git a/biome.json b/biome.json index e6f7a2f8c..edba65634 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,8 @@ { "$schema": "https://biomejs.dev/schemas/1.8.2/schema.json", + "files": { + "ignore": ["**/web", "./index.ssr.js", "**/svg-sprite.js"] + }, "formatter": { "enabled": true, "formatWithErrors": false, @@ -17,8 +20,7 @@ "enabled": true, "rules": { "recommended": true - }, - "ignore": ["**/web", "index.ssr.js"] + } }, "javascript": { "formatter": { diff --git a/blocks/CloudImageEditor/src/CropFrame.js b/blocks/CloudImageEditor/src/CropFrame.js index 8b1f79842..6055be672 100644 --- a/blocks/CloudImageEditor/src/CropFrame.js +++ b/blocks/CloudImageEditor/src/CropFrame.js @@ -49,7 +49,7 @@ export class CropFrame extends Block { * @param {import('./types.js').Direction} direction */ _shouldThumbBeDisabled(direction) { - let imageBox = this.$['*imageBox']; + const imageBox = this.$['*imageBox']; if (!imageBox) { return; } @@ -58,30 +58,30 @@ export class CropFrame extends Block { return true; } - let tooHigh = imageBox.height <= MIN_CROP_SIZE && (direction.includes('n') || direction.includes('s')); - let tooWide = imageBox.width <= MIN_CROP_SIZE && (direction.includes('e') || direction.includes('w')); + const tooHigh = imageBox.height <= MIN_CROP_SIZE && (direction.includes('n') || direction.includes('s')); + const tooWide = imageBox.width <= MIN_CROP_SIZE && (direction.includes('e') || direction.includes('w')); return tooHigh || tooWide; } /** @private */ _createBackdrop() { /** @type {import('./types.js').Rectangle} */ - let cropBox = this.$['*cropBox']; + const cropBox = this.$['*cropBox']; if (!cropBox) { return; } - let { x, y, width, height } = cropBox; - let svg = this.ref['svg-el']; + const { x, y, width, height } = cropBox; + const svg = this.ref['svg-el']; - let mask = createSvgNode('mask', { id: 'backdrop-mask' }); - let maskRectOuter = createSvgNode('rect', { + const mask = createSvgNode('mask', { id: 'backdrop-mask' }); + const maskRectOuter = createSvgNode('rect', { x: 0, y: 0, width: '100%', height: '100%', fill: 'white', }); - let maskRectInner = createSvgNode('rect', { + const maskRectInner = createSvgNode('rect', { x, y, width, @@ -91,7 +91,7 @@ export class CropFrame extends Block { mask.appendChild(maskRectOuter); mask.appendChild(maskRectInner); - let backdropRect = createSvgNode('rect', { + const backdropRect = createSvgNode('rect', { x: 0, y: 0, width: '100%', @@ -126,11 +126,11 @@ export class CropFrame extends Block { /** @private */ _updateBackdrop() { /** @type {import('./types.js').Rectangle} */ - let cropBox = this.$['*cropBox']; + const cropBox = this.$['*cropBox']; if (!cropBox) { return; } - let { x, y, width, height } = cropBox; + const { x, y, width, height } = cropBox; this._backdropMaskInner && setSvgNodeAttrs(this._backdropMaskInner, { x, y, width, height }); } @@ -138,16 +138,16 @@ export class CropFrame extends Block { /** @private */ _updateFrame() { /** @type {import('./types.js').Rectangle} */ - let cropBox = this.$['*cropBox']; + const cropBox = this.$['*cropBox']; if (!cropBox || !this._frameGuides || !this._frameThumbs) { return; } - for (let thumb of Object.values(this._frameThumbs)) { - let { direction, pathNode, interactionNode, groupNode } = thumb; - let isCenter = direction === ''; - let isCorner = direction.length === 2; - let { x, y, width, height } = cropBox; + for (const thumb of Object.values(this._frameThumbs)) { + const { direction, pathNode, interactionNode, groupNode } = thumb; + const isCenter = direction === ''; + const isCorner = direction.length === 2; + const { x, y, width, height } = cropBox; if (isCenter) { const moveThumbRect = { @@ -164,7 +164,7 @@ export class CropFrame extends Block { 1, ); - let { d, center } = isCorner + const { d, center } = isCorner ? cornerPath(cropBox, direction, thumbSizeMultiplier) : sidePath( cropBox, @@ -184,7 +184,7 @@ export class CropFrame extends Block { setSvgNodeAttrs(pathNode, { d }); } - let disableThumb = this._shouldThumbBeDisabled(direction); + const disableThumb = this._shouldThumbBeDisabled(direction); groupNode.setAttribute( 'class', classNames('thumb', { @@ -218,14 +218,14 @@ export class CropFrame extends Block { for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { - let direction = /** @type {import('./types.js').Direction} */ (`${['n', '', 's'][i]}${['w', '', 'e'][j]}`); - let groupNode = createSvgNode('g'); + const direction = /** @type {import('./types.js').Direction} */ (`${['n', '', 's'][i]}${['w', '', 'e'][j]}`); + const groupNode = createSvgNode('g'); groupNode.classList.add('thumb'); groupNode.setAttribute('with-effects', ''); - let interactionNode = createSvgNode('rect', { + const interactionNode = createSvgNode('rect', { fill: 'transparent', }); - let pathNode = createSvgNode('path', { + const pathNode = createSvgNode('path', { stroke: 'currentColor', fill: 'none', 'stroke-width': THUMB_STROKE_WIDTH, @@ -248,9 +248,9 @@ export class CropFrame extends Block { /** @private */ _createGuides() { - let svg = createSvgNode('svg'); + const svg = createSvgNode('svg'); - let rect = createSvgNode('rect', { + const rect = createSvgNode('rect', { x: 0, y: 0, width: '100%', @@ -263,11 +263,11 @@ export class CropFrame extends Block { svg.appendChild(rect); for (let i = 1; i <= 2; i++) { - let line = createSvgNode('line', { + const line = createSvgNode('line', { x1: `${GUIDE_THIRD * i}%`, - y1: `0%`, + y1: '0%', x2: `${GUIDE_THIRD * i}%`, - y2: `100%`, + y2: '100%', stroke: 'currentColor', 'stroke-width': GUIDE_STROKE_WIDTH, 'stroke-opacity': 0.3, @@ -276,10 +276,10 @@ export class CropFrame extends Block { } for (let i = 1; i <= 2; i++) { - let line = createSvgNode('line', { - x1: `0%`, + const line = createSvgNode('line', { + x1: '0%', y1: `${GUIDE_THIRD * i}%`, - x2: `100%`, + x2: '100%', y2: `${GUIDE_THIRD * i}%`, stroke: 'currentColor', 'stroke-width': GUIDE_STROKE_WIDTH, @@ -295,14 +295,14 @@ export class CropFrame extends Block { /** @private */ _createFrame() { - let svg = this.ref['svg-el']; - let fr = document.createDocumentFragment(); + const svg = this.ref['svg-el']; + const fr = document.createDocumentFragment(); - let frameGuides = this._createGuides(); + const frameGuides = this._createGuides(); fr.appendChild(frameGuides); - let frameThumbs = this._createThumbs(); - for (let { groupNode } of Object.values(frameThumbs)) { + const frameThumbs = this._createThumbs(); + for (const { groupNode } of Object.values(frameThumbs)) { fr.appendChild(groupNode); } @@ -318,15 +318,15 @@ export class CropFrame extends Block { */ _handlePointerDown(direction, e) { if (!this._frameThumbs) return; - let thumb = this._frameThumbs[direction]; + const thumb = this._frameThumbs[direction]; if (this._shouldThumbBeDisabled(direction)) { return; } - let cropBox = this.$['*cropBox']; - let { x: svgX, y: svgY } = this.ref['svg-el'].getBoundingClientRect(); - let x = e.x - svgX; - let y = e.y - svgY; + const cropBox = this.$['*cropBox']; + const { x: svgX, y: svgY } = this.ref['svg-el'].getBoundingClientRect(); + const x = e.x - svgX; + const y = e.y - svgY; this.$.dragging = true; this._draggingThumb = thumb; @@ -362,13 +362,13 @@ export class CropFrame extends Block { e.stopPropagation(); e.preventDefault(); - let svg = this.ref['svg-el']; - let { x: svgX, y: svgY } = svg.getBoundingClientRect(); - let x = e.x - svgX; - let y = e.y - svgY; - let dx = x - this._dragStartPoint[0]; - let dy = y - this._dragStartPoint[1]; - let { direction } = this._draggingThumb; + const svg = this.ref['svg-el']; + const { x: svgX, y: svgY } = svg.getBoundingClientRect(); + const x = e.x - svgX; + const y = e.y - svgY; + const dx = x - this._dragStartPoint[0]; + const dy = y - this._dragStartPoint[1]; + const { direction } = this._draggingThumb; const movedCropBox = this._calcCropBox(direction, [dx, dy]); if (movedCropBox) { @@ -384,7 +384,7 @@ export class CropFrame extends Block { _calcCropBox(direction, delta) { const [dx, dy] = delta; /** @type {import('./types.js').Rectangle} */ - let imageBox = this.$['*imageBox']; + const imageBox = this.$['*imageBox']; let rect = /** @type {import('./types.js').Rectangle} */ (this._dragStartCrop) ?? this.$['*cropBox']; /** @type {import('./types.js').CropPresetList[0]} */ const cropPreset = this.$['*cropPresetList']?.[0]; @@ -412,19 +412,19 @@ export class CropFrame extends Block { _handleSvgPointerMove_(e) { if (!this._frameThumbs) return; - let hoverThumb = Object.values(this._frameThumbs).find((thumb) => { + const hoverThumb = Object.values(this._frameThumbs).find((thumb) => { if (this._shouldThumbBeDisabled(thumb.direction)) { return false; } - let node = thumb.interactionNode; - let bounds = node.getBoundingClientRect(); - let rect = { + const node = thumb.interactionNode; + const bounds = node.getBoundingClientRect(); + const rect = { x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height, }; - let hover = rectContainsPoint(rect, [e.x, e.y]); + const hover = rectContainsPoint(rect, [e.x, e.y]); return hover; }); @@ -434,7 +434,7 @@ export class CropFrame extends Block { /** @private */ _updateCursor() { - let hoverThumb = this._hoverThumb; + const hoverThumb = this._hoverThumb; this.ref['svg-el'].style.cursor = hoverThumb ? thumbCursor(hoverThumb.direction) : 'initial'; } @@ -447,17 +447,17 @@ export class CropFrame extends Block { /** @param {boolean} visible */ toggleThumbs(visible) { if (!this._frameThumbs) return; - Object.values(this._frameThumbs) - .map(({ groupNode }) => groupNode) - .forEach((groupNode) => { - groupNode.setAttribute( - 'class', - classNames('thumb', { - 'thumb--hidden': !visible, - 'thumb--visible': visible, - }), - ); - }); + + for (const thumb of Object.values(this._frameThumbs)) { + const { groupNode } = thumb; + groupNode.setAttribute( + 'class', + classNames('thumb', { + 'thumb--hidden': !visible, + 'thumb--visible': visible, + }), + ); + } } initCallback() { diff --git a/blocks/CloudImageEditor/src/EditorScroller.js b/blocks/CloudImageEditor/src/EditorScroller.js index ccdb9f6c2..d2f3acda4 100644 --- a/blocks/CloudImageEditor/src/EditorScroller.js +++ b/blocks/CloudImageEditor/src/EditorScroller.js @@ -11,7 +11,7 @@ export class EditorScroller extends Block { (e) => { e.preventDefault(); - let { deltaY, deltaX } = e; + const { deltaY, deltaX } = e; if (Math.abs(deltaX) > X_THRESHOLD) { this.scrollLeft += deltaX; } else { @@ -30,4 +30,5 @@ export class EditorScroller extends Block { } } -EditorScroller.template = /* HTML */ ` `; +// biome-ignore lint/style/noUnusedTemplateLiteral: This is HTML template +EditorScroller.template = /* HTML */ ``; diff --git a/blocks/CloudImageEditor/src/EditorToolbar.js b/blocks/CloudImageEditor/src/EditorToolbar.js index 587ec51f1..2cb6662a5 100644 --- a/blocks/CloudImageEditor/src/EditorToolbar.js +++ b/blocks/CloudImageEditor/src/EditorToolbar.js @@ -1,5 +1,5 @@ -import { Block } from '../../../abstract/Block.js'; // @ts-check +import { Block } from '../../../abstract/Block.js'; import { debounce } from '../../utils/debounce.js'; import { EditorCropButtonControl } from './EditorCropButtonControl.js'; import { EditorFilterControl } from './EditorFilterControl.js'; diff --git a/blocks/CloudImageEditor/src/elements/presence-toggle/PresenceToggle.js b/blocks/CloudImageEditor/src/elements/presence-toggle/PresenceToggle.js index 575aabe53..30598d036 100644 --- a/blocks/CloudImageEditor/src/elements/presence-toggle/PresenceToggle.js +++ b/blocks/CloudImageEditor/src/elements/presence-toggle/PresenceToggle.js @@ -1,5 +1,5 @@ -import { applyClassNames } from '../../lib/classNames.js'; import { Block } from '../../../../../abstract/Block.js'; +import { applyClassNames } from '../../lib/classNames.js'; /** * @typedef {Object} Style @@ -68,4 +68,5 @@ export class PresenceToggle extends Block { }, 0); } } -PresenceToggle.template = /* HTML */ ` `; +// biome-ignore lint/style/noUnusedTemplateLiteral: This is HTML template +PresenceToggle.template = /* HTML */ ``; diff --git a/blocks/ExternalSource/ExternalSource.js b/blocks/ExternalSource/ExternalSource.js index 871e63675..f6f4259da 100644 --- a/blocks/ExternalSource/ExternalSource.js +++ b/blocks/ExternalSource/ExternalSource.js @@ -70,7 +70,7 @@ export class ExternalSource extends UploaderBlock { super.initCallback(); this.registerActivity(this.activityType, { onActivate: () => { - let { externalSourceType } = /** @type {ActivityParams} */ (this.activityParams); + const { externalSourceType } = /** @type {ActivityParams} */ (this.activityParams); this.set$({ activityCaption: `${externalSourceType?.[0].toUpperCase()}${externalSourceType?.slice(1)}`, @@ -147,13 +147,13 @@ export class ExternalSource extends UploaderBlock { * @param {string} propName */ getCssValue(propName) { - let style = window.getComputedStyle(this); + const style = window.getComputedStyle(this); return style.getPropertyValue(propName).trim(); } /** @private */ applyStyles() { - let colors = { + const colors = { radius: this.getCssValue('--uc-radius'), backgroundColor: this.getCssValue('--uc-background'), textColor: this.getCssValue('--uc-foreground'), @@ -193,7 +193,7 @@ export class ExternalSource extends UploaderBlock { mountIframe() { /** @type {HTMLIFrameElement} */ // @ts-ignore - let iframe = create({ + const iframe = create({ tag: 'iframe', attributes: { src: this.remoteUrl(), diff --git a/blocks/ExternalSource/buildStyles.js b/blocks/ExternalSource/buildStyles.js index 388d349f4..40ed3b712 100644 --- a/blocks/ExternalSource/buildStyles.js +++ b/blocks/ExternalSource/buildStyles.js @@ -9,9 +9,9 @@ const styleToCss = (style) => { const propertiesObj = style[selector]; const propertiesStr = Object.keys(propertiesObj).reduce((acc, prop) => { const value = propertiesObj[prop]; - return acc + `${prop}: ${value};`; + return `${acc}${prop}: ${value};`; }, ''); - return acc + `${selector}{${propertiesStr}}`; + return `${acc}${selector}{${propertiesStr}}`; }, ''); return css; }; diff --git a/blocks/FileItem/FileItem.js b/blocks/FileItem/FileItem.js index 9ff9f7a81..29b9a3efe 100644 --- a/blocks/FileItem/FileItem.js +++ b/blocks/FileItem/FileItem.js @@ -1,13 +1,13 @@ // @ts-check -import { CancelError, uploadFile } from '@uploadcare/upload-client'; import { shrinkFile } from '@uploadcare/image-shrink'; +import { CancelError, uploadFile } from '@uploadcare/upload-client'; import { ActivityBlock } from '../../abstract/ActivityBlock.js'; import { UploaderBlock } from '../../abstract/UploaderBlock.js'; import { createCdnUrl, createCdnUrlModifiers, createOriginalUrl } from '../../utils/cdn-utils.js'; +import { parseShrink } from '../../utils/parseShrink.js'; import { fileCssBg } from '../svg-backgrounds/svg-backgrounds.js'; import { debounce } from '../utils/debounce.js'; import { generateThumb } from '../utils/resizeImage.js'; -import { parseShrink } from '../../utils/parseShrink.js'; const FileItemState = Object.freeze({ FINISHED: Symbol(0), @@ -75,7 +75,7 @@ export class FileItem extends UploaderBlock { } _reset() { - for (let sub of this._entrySubs) { + for (const sub of this._entrySubs) { sub.remove(); } @@ -90,7 +90,7 @@ export class FileItem extends UploaderBlock { * @param {IntersectionObserverEntry[]} entries */ _observerCallback(entries) { - let [entry] = entries; + const [entry] = entries; this._isIntersecting = entry.isIntersecting; if (entry.isIntersecting && !this._renderedOnce) { @@ -109,7 +109,7 @@ export class FileItem extends UploaderBlock { if (!this._entry) { return; } - let entry = this._entry; + const entry = this._entry; let state = FileItemState.IDLE; if (entry.getValue('errors').length > 0) { @@ -128,17 +128,17 @@ export class FileItem extends UploaderBlock { if (!this._entry) { return; } - let entry = this._entry; + const entry = this._entry; if (entry.getValue('fileInfo') && entry.getValue('isImage')) { - let size = this.cfg.thumbSize; - let thumbUrl = this.proxyUrl( + const size = this.cfg.thumbSize; + const thumbUrl = this.proxyUrl( createCdnUrl( createOriginalUrl(this.cfg.cdnCname, this._entry.getValue('uuid')), createCdnUrlModifiers(entry.getValue('cdnUrlModifiers'), `scale_crop/${size}x${size}/center`), ), ); - let currentThumbUrl = entry.getValue('thumbUrl'); + const currentThumbUrl = entry.getValue('thumbUrl'); if (currentThumbUrl !== thumbUrl) { entry.setValue('thumbUrl', thumbUrl); currentThumbUrl?.startsWith('blob:') && URL.revokeObjectURL(currentThumbUrl); @@ -152,14 +152,14 @@ export class FileItem extends UploaderBlock { if (entry.getValue('file')?.type.includes('image')) { try { - let thumbUrl = await generateThumb(entry.getValue('file'), this.cfg.thumbSize); + const thumbUrl = await generateThumb(entry.getValue('file'), this.cfg.thumbSize); entry.setValue('thumbUrl', thumbUrl); } catch (err) { - let color = window.getComputedStyle(this).getPropertyValue('--uc-muted-foreground'); + const color = window.getComputedStyle(this).getPropertyValue('--uc-muted-foreground'); entry.setValue('thumbUrl', fileCssBg(color)); } } else { - let color = window.getComputedStyle(this).getPropertyValue('--uc-muted-foreground'); + const color = window.getComputedStyle(this).getPropertyValue('--uc-muted-foreground'); entry.setValue('thumbUrl', fileCssBg(color)); } } @@ -170,7 +170,7 @@ export class FileItem extends UploaderBlock { * @param {(value: any) => void} handler */ _subEntry(prop, handler) { - let sub = this._entry.subscribe( + const sub = this._entry.subscribe( prop, /** @param {any} value */ (value) => { if (this.isConnected) { @@ -189,7 +189,7 @@ export class FileItem extends UploaderBlock { this._reset(); /** @type {import('../../abstract/TypedData.js').TypedData} */ - let entry = this.uploadCollection?.read(id); + const entry = this.uploadCollection?.read(id); this._entry = entry; if (!entry) { @@ -251,13 +251,13 @@ export class FileItem extends UploaderBlock { this.subConfigValue('useCloudImageEditor', () => this._debouncedCalculateState()); this.onclick = () => { - FileItem.activeInstances.forEach((inst) => { - if (inst === this) { - inst.setAttribute('focused', ''); + for (const instance of FileItem.activeInstances) { + if (instance === this) { + instance.setAttribute('focused', ''); } else { - inst.removeAttribute('focused'); + instance.removeAttribute('focused'); } - }); + } }; this.sub( @@ -335,7 +335,7 @@ export class FileItem extends UploaderBlock { } async upload() { - let entry = this._entry; + const entry = this._entry; if (!this.uploadCollection.read(entry.uid)) { return; @@ -354,7 +354,7 @@ export class FileItem extends UploaderBlock { entry.setValue('errors', []); try { - let abortController = new AbortController(); + const abortController = new AbortController(); entry.setValue('abortController', abortController); const uploadTask = async () => { @@ -372,7 +372,7 @@ export class FileItem extends UploaderBlock { source: entry.getValue('source'), onProgress: (progress) => { if (progress.isComputable) { - let percentage = progress.value * 100; + const percentage = progress.value * 100; entry.setValue('uploadProgress', percentage); } }, @@ -384,7 +384,7 @@ export class FileItem extends UploaderBlock { }; /** @type {import('@uploadcare/upload-client').UploadcareFile} */ - let fileInfo = await this.$['*uploadQueue'].add(uploadTask); + const fileInfo = await this.$['*uploadQueue'].add(uploadTask); entry.setMultipleValues({ fileInfo, isUploading: false, diff --git a/blocks/SourceBtn/SourceBtn.js b/blocks/SourceBtn/SourceBtn.js index 36283c08a..ddab47bfc 100644 --- a/blocks/SourceBtn/SourceBtn.js +++ b/blocks/SourceBtn/SourceBtn.js @@ -1,5 +1,5 @@ -import { ActivityBlock } from '../../abstract/ActivityBlock.js'; // @ts-check +import { ActivityBlock } from '../../abstract/ActivityBlock.js'; import { UploaderBlock } from '../../abstract/UploaderBlock.js'; const L10N_PREFIX = 'src-type-'; diff --git a/blocks/StartFrom/StartFrom.js b/blocks/StartFrom/StartFrom.js index 18ac4a098..cb5587a8d 100644 --- a/blocks/StartFrom/StartFrom.js +++ b/blocks/StartFrom/StartFrom.js @@ -1,8 +1,9 @@ +// @ts-check import { ActivityBlock } from '../../abstract/ActivityBlock.js'; export class StartFrom extends ActivityBlock { historyTracked = true; - /** @type {import('../../abstract/ActivityBlock.js').ActivityType} */ + /** @type {NonNullable} */ activityType = 'start-from'; initCallback() { @@ -11,4 +12,4 @@ export class StartFrom extends ActivityBlock { } } -StartFrom.template = /* HTML */ `
`; +StartFrom.template = /* HTML */ `
`; diff --git a/build-ssr-stubs.js b/build-ssr-stubs.js index eec8616ea..43d731ab3 100644 --- a/build-ssr-stubs.js +++ b/build-ssr-stubs.js @@ -23,7 +23,7 @@ const getClassStaticProperties = (klass) => { return; } - for (const name of Object.getOwnPropertySymbols(proto)) { + for (const name of Object.getOwnPropertyNames(proto)) { const isPublic = !name.startsWith('_'); const isOwn = !['arguments', 'prototype', 'caller', 'constructor', 'name', 'length'].includes(name); const isDefined = isOwn && !!proto[name]; diff --git a/build.js b/build.js index 6ffadde12..92cf60098 100644 --- a/build.js +++ b/build.js @@ -1,7 +1,7 @@ +// @ts-check import fs from 'node:fs'; import path, { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; -// @ts-check import esbuild from 'esbuild'; import { buildItems } from './build-items.js'; diff --git a/types/jsx.d.ts b/types/jsx.d.ts index e1e61b1a9..5b5e819f1 100644 --- a/types/jsx.d.ts +++ b/types/jsx.d.ts @@ -15,39 +15,42 @@ type CommonHtmlAttributes = Partial< Pick, 'id' | 'children' | 'hidden'> & { class: React.HTMLAttributes['className'] } >; -type CustomElement = React.DetailedHTMLProps, C> & A; +type CustomElement = React.DetailedHTMLProps, C> & A; + +// biome-ignore lint/suspicious/noExplicitAny: +type UntypedElement = any; declare namespace JSX { interface IntrinsicElements { - 'lr-crop-frame': any; - 'lr-editor-crop-button-control': any; - 'lr-editor-filter-control': any; - 'lr-editor-operation-control': any; - 'lr-editor-image-cropper': any; - 'lr-editor-image-fader': any; - 'lr-editor-scroller': any; - 'lr-editor-slider': any; - 'lr-editor-toolbar': any; - 'lr-lr-btn-ui': any; - 'lr-line-loader-ui': any; - 'lr-presence-toggle': any; - 'lr-slider-ui': any; - 'lr-icon': any; - 'lr-img': any; - 'lr-simple-btn': any; - 'lr-start-from': any; - 'lr-drop-area': any; - 'lr-source-btn': any; - 'lr-source-list': any; - 'lr-file-item': any; - 'lr-modal': any; - 'lr-upload-list': any; - 'lr-url-source': any; - 'lr-camera-source': any; - 'lr-progress-bar-common': any; - 'lr-progress-bar': any; - 'lr-external-source': any; - 'lr-cloud-image-editor-activity': any; + 'lr-crop-frame': UntypedElement; + 'lr-editor-crop-button-control': UntypedElement; + 'lr-editor-filter-control': UntypedElement; + 'lr-editor-operation-control': UntypedElement; + 'lr-editor-image-cropper': UntypedElement; + 'lr-editor-image-fader': UntypedElement; + 'lr-editor-scroller': UntypedElement; + 'lr-editor-slider': UntypedElement; + 'lr-editor-toolbar': UntypedElement; + 'lr-lr-btn-ui': UntypedElement; + 'lr-line-loader-ui': UntypedElement; + 'lr-presence-toggle': UntypedElement; + 'lr-slider-ui': UntypedElement; + 'lr-icon': UntypedElement; + 'lr-img': UntypedElement; + 'lr-simple-btn': UntypedElement; + 'lr-start-from': UntypedElement; + 'lr-drop-area': UntypedElement; + 'lr-source-btn': UntypedElement; + 'lr-source-list': UntypedElement; + 'lr-file-item': UntypedElement; + 'lr-modal': UntypedElement; + 'lr-upload-list': UntypedElement; + 'lr-url-source': UntypedElement; + 'lr-camera-source': UntypedElement; + 'lr-progress-bar-common': UntypedElement; + 'lr-progress-bar': UntypedElement; + 'lr-external-source': UntypedElement; + 'lr-cloud-image-editor-activity': UntypedElement; 'lr-cloud-image-editor-block': CustomElement< CloudImageEditorBlock, CtxAttributes & ({ uuid: string } | { 'cdn-url': string }) & Partial<{ tabs: string; 'crop-preset': string }>