From 1e8938ceff546a14498aefa82e70df2f54e5cc7f Mon Sep 17 00:00:00 2001 From: filtered <176114999+webfiltered@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:18:25 +1100 Subject: [PATCH] Add unicorn lint rules - DOM built-in functions (#628) - Prefer append(), remove(), replaceAll() - Wrap nested ternaries in parenthesis --- eslint.config.js | 6 +++++ src/ContextMenu.ts | 10 +++---- src/CurveEditor.ts | 2 +- src/LGraphCanvas.ts | 52 ++++++++++++++++++------------------- src/LGraphNode.ts | 4 +-- src/LiteGraphGlobal.ts | 16 ++++++------ src/litegraph.ts | 2 +- src/types/globalEnums.ts | 2 +- src/widgets/ComboWidget.ts | 4 +-- src/widgets/KnobWidget.ts | 8 +++--- src/widgets/NumberWidget.ts | 10 +++---- 11 files changed, 60 insertions(+), 56 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index fbc2c1e0b..aaa28c243 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -62,6 +62,12 @@ export default tseslint.config( { rules: { "unicorn/better-regex": "error", + "unicorn/prefer-dom-node-append": "error", + "unicorn/prefer-dom-node-remove": "error", + "unicorn/no-array-for-each": "error", + "unicorn/empty-brace-spaces": "error", + "unicorn/no-nested-ternary": "error", + "unicorn/prefer-string-replace-all": "error", // Node rules: dev dependency config, etc. "unicorn/prefer-node-protocol": "error", diff --git a/src/ContextMenu.ts b/src/ContextMenu.ts index 9db948f03..56f9a790c 100644 --- a/src/ContextMenu.ts +++ b/src/ContextMenu.ts @@ -122,7 +122,7 @@ export class ContextMenu { const element = document.createElement("div") element.className = "litemenu-title" element.innerHTML = options.title - root.appendChild(element) + root.append(element) } // entries @@ -132,7 +132,7 @@ export class ContextMenu { if (typeof name !== "string") { name = name != null - ? name.content === undefined ? String(name) : name.content + ? (name.content === undefined ? String(name) : name.content) : name } @@ -151,9 +151,9 @@ export class ContextMenu { const root_document = ownerDocument || document if (root_document.fullscreenElement) - root_document.fullscreenElement.appendChild(root) + root_document.fullscreenElement.append(root) else - root_document.body.appendChild(root) + root_document.body.append(root) // compute best position let left = options.left || 0 @@ -231,7 +231,7 @@ export class ContextMenu { } } - this.root.appendChild(element) + this.root.append(element) if (!disabled) element.addEventListener("click", inner_onclick) if (!disabled && options.autoopen) element.addEventListener("pointerenter", inner_over) diff --git a/src/CurveEditor.ts b/src/CurveEditor.ts index f4946fec9..ae3a38225 100644 --- a/src/CurveEditor.ts +++ b/src/CurveEditor.ts @@ -81,7 +81,7 @@ export class CurveEditor { for (const [i, p] of points.entries()) { ctx.fillStyle = this.selected == i ? "#FFF" - : this.nearest == i ? "#DDD" : "#AAA" + : (this.nearest == i ? "#DDD" : "#AAA") ctx.beginPath() ctx.arc(p[0] * w, (1.0 - p[1]) * h, 2, 0, Math.PI * 2) ctx.fill() diff --git a/src/LGraphCanvas.ts b/src/LGraphCanvas.ts index eb9c3ee89..c5173b0ea 100644 --- a/src/LGraphCanvas.ts +++ b/src/LGraphCanvas.ts @@ -1213,7 +1213,7 @@ export class LGraphCanvas implements ConnectionColorContext { dialog.innerHTML = "" dialog.close = function () { - dialog.parentNode?.removeChild(dialog) + dialog.remove() } const title = dialog.querySelector(".name") title.innerText = property @@ -1261,7 +1261,7 @@ export class LGraphCanvas implements ConnectionColorContext { const button = dialog.querySelector("button") button.addEventListener("click", inner) - canvasEl.parentNode.appendChild(dialog) + canvasEl.parentNode.append(dialog) input?.focus() @@ -1293,7 +1293,7 @@ export class LGraphCanvas implements ConnectionColorContext { value = Boolean(value) } node[property] = value - dialog.parentNode?.removeChild(dialog) + dialog.remove() canvas.setDirty(true, true) } } @@ -5924,13 +5924,13 @@ export class LGraphCanvas implements ConnectionColorContext { dialog.close = function () { that.prompt_box = null if (dialog.parentNode) { - dialog.parentNode.removeChild(dialog) + dialog.remove() } } const graphcanvas = LGraphCanvas.active_canvas const canvas = graphcanvas.canvas - canvas.parentNode.appendChild(dialog) + canvas.parentNode.append(dialog) if (this.ds.scale > 1) dialog.style.transform = "scale(" + this.ds.scale + ")" @@ -6079,9 +6079,9 @@ export class LGraphCanvas implements ConnectionColorContext { dialog.innerHTML += "
" if (root_document.fullscreenElement) { - root_document.fullscreenElement.appendChild(dialog) + root_document.fullscreenElement.append(dialog) } else { - root_document.body.appendChild(dialog) + root_document.body.append(dialog) root_document.body.style.overflow = "hidden" } @@ -6104,7 +6104,7 @@ export class LGraphCanvas implements ConnectionColorContext { setTimeout(function () { that.canvas.focus() }, 20) - dialog.parentNode?.removeChild(dialog) + dialog.remove() } if (this.ds.scale > 1) { @@ -6222,7 +6222,7 @@ export class LGraphCanvas implements ConnectionColorContext { const opt = document.createElement("option") opt.value = aSlots[iK] opt.innerHTML = aSlots[iK] - selIn.appendChild(opt) + selIn.append(opt) if ( // @ts-expect-error options.type_filter_in !== false && @@ -6258,7 +6258,7 @@ export class LGraphCanvas implements ConnectionColorContext { const opt = document.createElement("option") opt.value = aSlots[iK] opt.innerHTML = aSlots[iK] - selOut.appendChild(opt) + selOut.append(opt) if ( options.type_filter_out !== false && (options.type_filter_out + "").toLowerCase() == @@ -6561,7 +6561,7 @@ export class LGraphCanvas implements ConnectionColorContext { help.addEventListener("click", function () { select(unescape(this.dataset["type"])) }) - helper.appendChild(help) + helper.append(help) } } @@ -6744,7 +6744,7 @@ export class LGraphCanvas implements ConnectionColorContext { dialog.style.left = offsetx + "px" dialog.style.top = offsety + "px" - this.canvas.parentNode.appendChild(dialog) + this.canvas.parentNode.append(dialog) // acheck for input and use default behaviour: save on enter, close on esc if (options.checkForInput) { @@ -6772,7 +6772,7 @@ export class LGraphCanvas implements ConnectionColorContext { dialog.is_modified = true } dialog.close = function () { - dialog.parentNode?.removeChild(dialog) + dialog.remove() } let dialogCloseTimer = null @@ -6832,7 +6832,7 @@ export class LGraphCanvas implements ConnectionColorContext { close.addEventListener("click", function () { root.close() }) - root.header.appendChild(close) + root.header.append(close) } root.title_element = root.querySelector(".dialog-title") root.title_element.innerText = title @@ -6842,10 +6842,8 @@ export class LGraphCanvas implements ConnectionColorContext { root.close = function () { if (typeof root.onClose == "function") root.onClose() - root.parentNode?.removeChild(root) - /* XXX CHECK THIS */ - this.parentNode?.removeChild(this) - /* XXX this was not working, was fixed with an IF, check this */ + root.remove() + this.remove() } // function to swap panel content @@ -6881,8 +6879,8 @@ export class LGraphCanvas implements ConnectionColorContext { const elem = document.createElement("div") if (classname) elem.className = classname elem.innerHTML = code - if (on_footer) root.footer.appendChild(elem) - else root.content.appendChild(elem) + if (on_footer) root.footer.append(elem) + else root.content.append(elem) return elem } @@ -6893,14 +6891,14 @@ export class LGraphCanvas implements ConnectionColorContext { elem.options = options elem.classList.add("btn") elem.addEventListener("click", callback) - root.footer.appendChild(elem) + root.footer.append(elem) return elem } root.addSeparator = function () { const elem = document.createElement("div") elem.className = "separator" - root.content.appendChild(elem) + root.content.append(elem) } root.addWidget = function (type, name, value, options, callback) { @@ -6982,7 +6980,7 @@ export class LGraphCanvas implements ConnectionColorContext { }) } - root.content.appendChild(elem) + root.content.append(elem) function innerChange(name, value) { options.callback?.(name, value, options) @@ -7105,7 +7103,7 @@ export class LGraphCanvas implements ConnectionColorContext { const fDoneWith = function () { panel.toggleAltContent(false) panel.toggleFooterVisibility(true) - textarea.parentNode.removeChild(textarea) + textarea.remove() panel.classList.add("settings") panel.classList.remove("centered") inner_refresh() @@ -7125,15 +7123,15 @@ export class LGraphCanvas implements ConnectionColorContext { node.setProperty(propname, textarea.value) fDoneWith() }) - panel.alt_content.appendChild(assign) + panel.alt_content.append(assign) const button = panel.addButton("Close", fDoneWith) button.style.float = "right" - panel.alt_content.appendChild(button) + panel.alt_content.append(button) } inner_refresh() - this.canvas.parentNode.appendChild(panel) + this.canvas.parentNode.append(panel) } checkPanels(): void { diff --git a/src/LGraphNode.ts b/src/LGraphNode.ts index 0e0f041ad..129e84d42 100644 --- a/src/LGraphNode.ts +++ b/src/LGraphNode.ts @@ -231,9 +231,9 @@ export class LGraphNode implements Positionable, IPinnable, IColorable { if (LiteGraph.node_box_coloured_when_on) { colState = this.action_triggered ? "#FFF" - : this.execute_triggered + : (this.execute_triggered ? "#AAA" - : colState + : colState) } return this.boxcolor || colState || LiteGraph.NODE_DEFAULT_BOXCOLOR diff --git a/src/LiteGraphGlobal.ts b/src/LiteGraphGlobal.ts index bd91e97e8..c3d76b34f 100644 --- a/src/LiteGraphGlobal.ts +++ b/src/LiteGraphGlobal.ts @@ -552,8 +552,8 @@ export class LiteGraphGlobal { const dynamicScript = document.createElement("script") dynamicScript.type = "text/javascript" dynamicScript.src = src - docHeadObj.appendChild(dynamicScript) - docHeadObj.removeChild(script_file) + docHeadObj.append(dynamicScript) + script_file.remove() } catch (err) { if (this.throw_errors) throw err if (this.debug) console.log("Error while reloading " + src) @@ -583,7 +583,7 @@ export class LiteGraphGlobal { */ uuidv4(): string { // @ts-ignore - return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, a => + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replaceAll(/[018]/g, a => (a ^ ((Math.random() * 16) >> (a / 4))).toString(16)) } @@ -632,12 +632,12 @@ export class LiteGraphGlobal { // used to create nodes from wrapping functions getParameterNames(func: (...args: any) => any): string[] { return (func + "") - .replace(/\/\/.*$/gm, "") // strip single-line comments - .replace(/\s+/g, "") // strip white space - .replace(/\/\*[^*/]*\*\//g, "") // strip multi-line comments /**/ + .replaceAll(/\/\/.*$/gm, "") // strip single-line comments + .replaceAll(/\s+/g, "") // strip white space + .replaceAll(/\/\*[^*/]*\*\//g, "") // strip multi-line comments /**/ .split("){", 1)[0] .replace(/^[^(]*\(/, "") // extract the parameters - .replace(/=[^,]+/g, "") // strip any ES6 defaults + .replaceAll(/=[^,]+/g, "") // strip any ES6 defaults .split(",") .filter(Boolean) // split & filter [""] } @@ -836,7 +836,7 @@ export class LiteGraphGlobal { if ("close" in result && typeof result.close === "function") { result.close() } else if (result.parentNode) { - result.parentNode.removeChild(result) + result.remove() } } } diff --git a/src/litegraph.ts b/src/litegraph.ts index f0c92cec7..4591eac1d 100644 --- a/src/litegraph.ts +++ b/src/litegraph.ts @@ -91,7 +91,7 @@ export type { } from "./types/serialisation" export function clamp(v: number, a: number, b: number): number { - return a > v ? a : b < v ? b : v + return a > v ? a : (b < v ? b : v) } // Load legacy polyfills diff --git a/src/types/globalEnums.ts b/src/types/globalEnums.ts index e61bd737e..45ccca39c 100644 --- a/src/types/globalEnums.ts +++ b/src/types/globalEnums.ts @@ -27,7 +27,7 @@ export enum CanvasItem { /** No items / none */ Nothing = 0, /** At least one node */ - Node = 1 << 0, + Node = 1, /** At least one group */ Group = 1 << 1, /** A reroute (not its path) */ diff --git a/src/widgets/ComboWidget.ts b/src/widgets/ComboWidget.ts index cc573cf15..8887b9c5a 100644 --- a/src/widgets/ComboWidget.ts +++ b/src/widgets/ComboWidget.ts @@ -147,9 +147,9 @@ export class ComboWidget extends BaseWidget implements IComboWidget { // Determine if clicked on left/right arrows const delta = x < 40 ? -1 - : x > width - 40 + : (x > width - 40 ? 1 - : 0 + : 0) // Get values let values = this.options.values diff --git a/src/widgets/KnobWidget.ts b/src/widgets/KnobWidget.ts index 336950551..b084e3924 100644 --- a/src/widgets/KnobWidget.ts +++ b/src/widgets/KnobWidget.ts @@ -140,10 +140,10 @@ export class KnobWidget extends BaseWidget implements IKnobWidget { arc_center.y, ) const gs = gradient_stops.split(";") - gs.forEach((stop, index) => { + for (const [index, stop] of gs.entries()) { console.log(stop) gradient.addColorStop(index, stop.trim()) - }) + } ctx.strokeStyle = gradient const value_end_angle = @@ -240,9 +240,9 @@ export class KnobWidget extends BaseWidget implements IKnobWidget { const step_with_shift_modifier = e.shiftKey ? step_for.shift - : use_y + : (use_y ? step_for.delta_y - : step + : step) // HACK: For some reason, the front-end multiplies step by 10, this brings it down to the advertised value // SEE: src/utils/mathUtil.ts@getNumberDefaults in front end const deltaValue = adjustment * step_with_shift_modifier / 10 diff --git a/src/widgets/NumberWidget.ts b/src/widgets/NumberWidget.ts index 96e61c7c3..233024780 100644 --- a/src/widgets/NumberWidget.ts +++ b/src/widgets/NumberWidget.ts @@ -105,9 +105,9 @@ export class NumberWidget extends BaseWidget implements INumericWidget { // Determine if clicked on left/right arrows const delta = x < 40 ? -1 - : x > width - 40 + : (x > width - 40 ? 1 - : 0 + : 0) if (delta) { // Handle left/right arrow clicks @@ -131,7 +131,7 @@ export class NumberWidget extends BaseWidget implements INumericWidget { // Solve the equation if possible try { v = eval(v) - } catch { } + } catch {} } const newValue = Number(v) if (!isNaN(newValue)) { @@ -154,9 +154,9 @@ export class NumberWidget extends BaseWidget implements INumericWidget { const x = e.canvasX - node.pos[0] const delta = x < 40 ? -1 - : x > width - 40 + : (x > width - 40 ? 1 - : 0 + : 0) if (delta && (x > -3 && x < width + 3)) return