diff --git a/src/color/p5.Color.js b/src/color/p5.Color.js index 2fedb173fb..161d2c366c 100644 --- a/src/color/p5.Color.js +++ b/src/color/p5.Color.js @@ -19,7 +19,6 @@ import { import { ColorSpace, to, - toGamut, serialize, parse, range, @@ -128,7 +127,7 @@ class Color { }); this._cachedMode = mode; this._cachedColor = to(this._cachedColor, this._cachedColor.spaceId); - } catch (err) { + } catch { // TODO: Invalid color string throw new Error('Invalid color string'); } @@ -305,11 +304,6 @@ class Color { }); } - // Will do conversion in-Gamut as out of Gamut conversion is only really useful for futher conversions - #toColorMode(mode) { - return new Color(this._color, mode); - } - // Get raw coordinates of underlying library, can differ between libraries get _array() { return this._getRGBA(); diff --git a/src/core/filterShaders.js b/src/core/filterShaders.js index 9c265c3c33..2dcfdd6097 100644 --- a/src/core/filterShaders.js +++ b/src/core/filterShaders.js @@ -101,7 +101,7 @@ export function makeFilterShader(renderer, operation, p5) { const maxSamples = 64.0; let numSamples = p5.floor(radius * 7.0); - if (p5.mod(numSamples, 2) == 0.0) { + if (p5.mod(numSamples, 2) === 0.0) { numSamples++; } @@ -162,7 +162,7 @@ export function makeFilterShader(renderer, operation, p5) { for (let x = -1; x <= 1; x++) { for (let y = -1; y <= 1; y++) { - if (x != 0 || y != 0) { + if (x !== 0 || y !== 0) { const offset = p5.vec2(x, y) * inputs.texelSize; const neighborColor = p5.getTexture( canvasContent, @@ -198,7 +198,7 @@ export function makeFilterShader(renderer, operation, p5) { for (let x = -1; x <= 1; x++) { for (let y = -1; y <= 1; y++) { - if (x != 0 || y != 0) { + if (x !== 0 || y !== 0) { const offset = p5.vec2(x, y) * inputs.texelSize; const neighborColor = p5.getTexture( canvasContent, diff --git a/src/core/main.js b/src/core/main.js index 743cc473b8..c344f306a3 100644 --- a/src/core/main.js +++ b/src/core/main.js @@ -400,7 +400,7 @@ class p5 { for (const p in p5.prototype) { try { delete window[p]; - } catch (x) { + } catch { window[p] = undefined; } } @@ -408,7 +408,7 @@ class p5 { if (this.hasOwnProperty(p2)) { try { delete window[p2]; - } catch (x) { + } catch { window[p2] = undefined; } } diff --git a/src/core/p5.Renderer.js b/src/core/p5.Renderer.js index 50c22dcd8b..cdaab0905a 100644 --- a/src/core/p5.Renderer.js +++ b/src/core/p5.Renderer.js @@ -447,25 +447,5 @@ function renderer(p5, fn) { p5.Renderer = Renderer; } -/** - * Helper fxn to measure ascent and descent. - * Adapted from http://stackoverflow.com/a/25355178 - * @private - */ -function calculateOffset(object) { - let currentLeft = 0, - currentTop = 0; - if (object.offsetParent) { - do { - currentLeft += object.offsetLeft; - currentTop += object.offsetTop; - } while ((object = object.offsetParent)); - } else { - currentLeft += object.offsetLeft; - currentTop += object.offsetTop; - } - return [currentLeft, currentTop]; -} - export default renderer; export { Renderer }; diff --git a/src/core/p5.Renderer2D.js b/src/core/p5.Renderer2D.js index bd7ab167fa..e8e92eca97 100644 --- a/src/core/p5.Renderer2D.js +++ b/src/core/p5.Renderer2D.js @@ -11,8 +11,6 @@ import { Matrix } from '../math/p5.Matrix'; import { PrimitiveToPath2DConverter } from '../shape/custom_shapes'; import { DefaultFill, textCoreConstants } from '../type/textCore'; -const styleEmpty = 'rgba(0,0,0,0)'; - class Renderer2D extends Renderer { constructor(pInst, w, h, isMainCanvas, elt, attributes = {}) { super(pInst, w, h, isMainCanvas); @@ -151,7 +149,7 @@ class Renderer2D extends Renderer { for (const savedKey in props) { try { this.drawingContext[savedKey] = props[savedKey]; - } catch (err) { + } catch { // ignore read-only property errors } } diff --git a/src/core/p5.Renderer3D.js b/src/core/p5.Renderer3D.js index a84aa56679..514478836e 100644 --- a/src/core/p5.Renderer3D.js +++ b/src/core/p5.Renderer3D.js @@ -436,13 +436,6 @@ export class Renderer3D extends Renderer { } } - remove() { - this.wrappedElt.remove(); - this.wrappedElt = null; - this.canvas = null; - this.elt = null; - } - ////////////////////////////////////////////// // Geometry Building ////////////////////////////////////////////// @@ -1350,7 +1343,7 @@ export class Renderer3D extends Renderer { for (const savedKey in props) { try { this.drawingContext[savedKey] = props[savedKey]; - } catch (err) { + } catch { // ignore read-only property errors } } @@ -1933,7 +1926,7 @@ export class Renderer3D extends Renderer { throw Error('_yAlignOffset: height is required'); } - let { textLeading, textBaseline, textSize, textFont } = this.states; + let { textLeading, textBaseline, textSize } = this.states; let yOff = 0, numLines = dataArr.length; let totalHeight = @@ -2175,6 +2168,10 @@ export class Renderer3D extends Renderer { if (this._textCanvas) { this._textCanvas.parentElement.removeChild(this._textCanvas); } + this.wrappedElt.remove(); + this.wrappedElt = null; + this.canvas = null; + this.elt = null; super.remove(); } } diff --git a/src/dom/p5.MediaElement.js b/src/dom/p5.MediaElement.js index 019fcbf8e3..63a683913c 100644 --- a/src/dom/p5.MediaElement.js +++ b/src/dom/p5.MediaElement.js @@ -5,7 +5,7 @@ import { Element } from './p5.Element'; // import { friendlyAutoplayError } from '../friendly_errors/fes_core'; -import { FES, TL } from '../friendly_errors/fes'; +import { FES } from '../friendly_errors/fes'; /** * @typedef {'video'} VIDEO @@ -934,7 +934,7 @@ class MediaElement extends Element { try { audioContext = obj.context; mainOutput = audioContext.destination; - } catch (e) { + } catch { throw 'connect() is meant to be used with Web Audio API or p5.sound.js'; } } @@ -1639,7 +1639,7 @@ function media(p5, fn) { } else { domElement.src = window.URL.createObjectURL(stream); } - } catch (err) { + } catch { domElement.src = stream; } }) diff --git a/src/friendly_errors/param_validator.js b/src/friendly_errors/param_validator.js index 0f8a08c39f..d29a1cd91a 100644 --- a/src/friendly_errors/param_validator.js +++ b/src/friendly_errors/param_validator.js @@ -555,6 +555,8 @@ function validateParams(p5, fn, lifecycles) { message = FES.log`Expected ${match[1]} at the ${position} parameter in ${func + '()'}.`; break; } + // Unrecognized custom errors fall through to the default logging below. + // falls through } default: { console.log('Zod error object', currentError); @@ -564,7 +566,7 @@ function validateParams(p5, fn, lifecycles) { if (isVersionError) { FES.log`${message}`(); } else { - const [_null, stacktrace] = processStack( + const [, stacktrace] = processStack( null, errorStackParser.parse(Error()).slice(3) ); @@ -624,7 +626,7 @@ function validateParams(p5, fn, lifecycles) { success: true, data: funcSchemas.parse(args) }; - } catch (error) { + } catch { const closestSchema = findClosestSchema(funcSchemas, args); const zodError = closestSchema.safeParse(args).error; const errorMessage = friendlyParamError(zodError, func, args); diff --git a/src/friendly_errors/stacktrace.js b/src/friendly_errors/stacktrace.js index bf92d00831..015e429705 100644 --- a/src/friendly_errors/stacktrace.js +++ b/src/friendly_errors/stacktrace.js @@ -325,12 +325,6 @@ export const processStack = (error, stacktrace) => { // from user's code if (friendlyStack.length === 0) return [true, null]; - // get the function just above the topmost frame in the friendlyStack. - // i.e the name of the library function called from user's code - const func = stacktrace[friendlyStack[0].frameIndex - 1].functionName - .split('.') - .slice(-1)[0]; - // Try and get the location (line no.) from the top element of the stack let locationObj; if ( @@ -351,6 +345,8 @@ export const processStack = (error, stacktrace) => { } // Library error + // `func` below is the name of the library function called from user's code, + // i.e. stacktrace[friendlyStack[0].frameIndex - 1].functionName. // const message = TL.tl`${locationObj ? TL.tl`[${locationObj.file}, line ${locationObj.line}]` : ''} An error with message "${error.message}" occurred inside the p5js library when ${func} was called. If not stated otherwise, it might be an issue with the arguments passed to ${func}.`; // p5._friendlyError( // message, diff --git a/src/image/p5.Image.js b/src/image/p5.Image.js index 423d7f1cf8..4823ad8bf4 100644 --- a/src/image/p5.Image.js +++ b/src/image/p5.Image.js @@ -48,13 +48,7 @@ class Image { if (typeof density !== 'undefined') { // Setter: set the density and handle resize if (density <= 0) { - const errorObj = { - type: 'INVALID_VALUE', - format: { types: ['Number'] }, - position: 1 - }; - - // p5._friendlyParamError(errorObj, 'pixelDensity'); + // TODO: report an INVALID_VALUE param error through the FES here. // Default to 1 in case of an invalid value density = 1; diff --git a/src/io/csv.js b/src/io/csv.js index bf279d60f7..9dda273e8b 100644 --- a/src/io/csv.js +++ b/src/io/csv.js @@ -233,5 +233,5 @@ function inferType(value) { } function escapeRegExp(str) { - return str.replace(/[-\[\]/\{}\()\*+\?.\\^\$|]/g, '\\$&'); + return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&'); } diff --git a/src/io/files.js b/src/io/files.js index 8dce5b6839..bbbb9d5d52 100644 --- a/src/io/files.js +++ b/src/io/files.js @@ -1146,6 +1146,7 @@ function files(p5, fn) { case 'xml': // NOTE: still need to normalize type handling/mapping // datatype = 'xml'; + // falls through case 'txt': default: datatype = 'text'; @@ -2119,17 +2120,6 @@ function files(p5, fn) { // The following line is CC BY SA 3 by user Fregante https://stackoverflow.com/a/23522755 return /^((?!chrome|android).)*safari/i.test(navigator.userAgent); }; - - /** - * Helper function, a callback for download that deletes - * an invisible anchor element from the DOM once the file - * has been automatically downloaded. - * - * @private - */ - function destroyClickedElement(event) { - document.body.removeChild(event.target); - } } export default files; diff --git a/src/math/Matrices/Matrix.js b/src/math/Matrices/Matrix.js index 6a09f7bede..91d3ecc263 100644 --- a/src/math/Matrices/Matrix.js +++ b/src/math/Matrices/Matrix.js @@ -2005,6 +2005,9 @@ export class Matrix extends MatrixInterface { * @return {Number} Determinant of our 4×4 matrix * @private */ + // Kept private until the determinant API is made public; see the skipped + // 'Determinant' tests in test/unit/math/p5.Matrix.js. + // oxlint-disable-next-line no-unused-private-class-members #determinant4x4() { if (this.#sqDimention !== 4) { throw new Error( diff --git a/src/math/Matrices/MatrixInterface.js b/src/math/Matrices/MatrixInterface.js index 8f428e219a..8c33b09be6 100644 --- a/src/math/Matrices/MatrixInterface.js +++ b/src/math/Matrices/MatrixInterface.js @@ -5,8 +5,6 @@ if (typeof Float32Array !== 'undefined') { isMatrixArray = x => Array.isArray(x) || x instanceof Float32Array; } export class MatrixInterface { - // Private field to store the matrix - #matrix = null; constructor(...args) { if (this.constructor === MatrixInterface) { throw new Error("Class is of abstract type and can't be instantiated"); diff --git a/src/math/Matrices/MatrixNumjs.js b/src/math/Matrices/MatrixNumjs.js index 1e719ffea5..374f7f7142 100644 --- a/src/math/Matrices/MatrixNumjs.js +++ b/src/math/Matrices/MatrixNumjs.js @@ -10,10 +10,8 @@ import { MatrixInterface } from './MatrixInterface'; * Reference/Global_Objects/SIMD */ -let GLMAT_ARRAY_TYPE = Array; let isMatrixArray = x => Array.isArray(x); if (typeof Float32Array !== 'undefined') { - GLMAT_ARRAY_TYPE = Float32Array; isMatrixArray = x => Array.isArray(x) || x instanceof Float32Array; } @@ -131,7 +129,6 @@ export class MatrixNumjs extends MatrixInterface { * @return {MatrixNumjs} the copy of the MatrixNumjs object */ get() { - let temp = new MatrixNumjs(this.mat4); return new MatrixNumjs(this.mat4); } @@ -522,7 +519,6 @@ export class MatrixNumjs extends MatrixInterface { x = x[0]; // must be last } this._mat4 = this._mat4.flatten(); - const vect = nj.array([x, y, z, 1]); this._mat4.set(0, x * this._mat4.get(0)); this._mat4.set(1, x * this._mat4.get(1)); this._mat4.set(2, x * this._mat4.get(2)); @@ -805,12 +801,11 @@ export class MatrixNumjs extends MatrixInterface { * @chainable */ mult3x3(multMatrix) { - let _src; let tempMatrix = multMatrix; if (multMatrix === this || multMatrix === this._mat3) { // mat3; // only need to allocate in this rare case } else if (multMatrix instanceof MatrixNumjs) { - _src = multMatrix.mat3; + // tempMatrix already holds the matrix we need } else if (isMatrixArray(multMatrix)) { multMatrix._mat3 = nj.array(arguments); } else if (arguments.length === 9) { diff --git a/src/strands/ir_dag.js b/src/strands/ir_dag.js index 31dbb474f4..1ac64ae3e6 100644 --- a/src/strands/ir_dag.js +++ b/src/strands/ir_dag.js @@ -2,7 +2,6 @@ import { NodeTypeRequiredFields, NodeTypeToName, BasePriority, - StatementType, BaseType } from './ir_types'; import * as FES from './strands_FES'; @@ -149,11 +148,6 @@ function createNode(graph, node) { return id; } -function getNodeKey(node) { - const key = JSON.stringify(node); - return key; -} - function validateNode(node) { const nodeType = node.nodeType; const requiredFields = NodeTypeRequiredFields[nodeType]; diff --git a/src/strands/ir_types.js b/src/strands/ir_types.js index 65a17769b1..51a7ba447c 100644 --- a/src/strands/ir_types.js +++ b/src/strands/ir_types.js @@ -282,8 +282,8 @@ export const ConstantFolding = { [OpCode.Binary.MULTIPLY]: (a, b) => a * b, [OpCode.Binary.DIVIDE]: (a, b) => a / b, [OpCode.Binary.MODULO]: (a, b) => a % b, - [OpCode.Binary.EQUAL]: (a, b) => a == b, - [OpCode.Binary.NOT_EQUAL]: (a, b) => a != b, + [OpCode.Binary.EQUAL]: (a, b) => a === b, + [OpCode.Binary.NOT_EQUAL]: (a, b) => a !== b, [OpCode.Binary.GREATER_THAN]: (a, b) => a > b, [OpCode.Binary.GREATER_EQUAL]: (a, b) => a >= b, [OpCode.Binary.LESS_THAN]: (a, b) => a < b, diff --git a/src/strands/strands_api.js b/src/strands/strands_api.js index da61d5290a..2e085dfe33 100644 --- a/src/strands/strands_api.js +++ b/src/strands/strands_api.js @@ -5,9 +5,7 @@ import { DataType, BaseType, structType, - TypeInfoFromGLSLName, isStructType, - OpCode, StatementType, NodeType, HOOK_PARAM_PREFIX diff --git a/src/strands/strands_codegen.js b/src/strands/strands_codegen.js index df450c29e9..0e1577f299 100644 --- a/src/strands/strands_codegen.js +++ b/src/strands/strands_codegen.js @@ -1,11 +1,5 @@ import { sortCFG } from './ir_cfg'; -import * as DAG from './ir_dag'; -import { - NodeType, - StatementType, - structType, - TypeInfoFromGLSLName -} from './ir_types'; +import { structType } from './ir_types'; export function generateShaderCode(strandsContext) { const { diff --git a/src/strands/strands_conditionals.js b/src/strands/strands_conditionals.js index cccd5af144..4e4f571652 100644 --- a/src/strands/strands_conditionals.js +++ b/src/strands/strands_conditionals.js @@ -1,7 +1,7 @@ import * as CFG from './ir_cfg'; import * as DAG from './ir_dag'; import { BlockType, NodeType } from './ir_types'; -import { StrandsNode, createStrandsNode } from './strands_node'; +import { createStrandsNode } from './strands_node'; import { createPhiNode } from './strands_phi_utils'; export class StrandsConditional { constructor(strandsContext, condition, branchCallback) { diff --git a/src/strands/strands_for.js b/src/strands/strands_for.js index d035395201..11aea9f0ae 100644 --- a/src/strands/strands_for.js +++ b/src/strands/strands_for.js @@ -7,7 +7,7 @@ import { StatementType, OpCode } from './ir_types'; -import { StrandsNode, createStrandsNode } from './strands_node'; +import { createStrandsNode } from './strands_node'; import { primitiveConstructorNode } from './ir_builders'; import { createPhiNode } from './strands_phi_utils'; diff --git a/src/strands/strands_transpiler.js b/src/strands/strands_transpiler.js index f3367620a9..1278d911a0 100644 --- a/src/strands/strands_transpiler.js +++ b/src/strands/strands_transpiler.js @@ -1905,26 +1905,6 @@ function transformHelperFunctionEarlyReturns(ast, names) { * This staged approach ensures correct ordering and avoids transformation conflicts. */ -// Wraps each callback with a uniform context guard, eliminating the need -// to repeat the early-return check at the top of every handler. -function makeGuardedCallbacks(callbacks) { - const guarded = {}; - for (const [name, fn] of Object.entries(callbacks)) { - guarded[name] = (node, state, ancestors) => { - if ( - ancestors.some( - a => - nodeIsUniform(a) || - nodeIsUniformCallbackFn(a, state.uniformCallbackNames) - ) - ) - return; - return fn(node, state, ancestors); - }; - } - return guarded; -} - function runNonControlFlowPass( ast, uniformCallbackNames, diff --git a/src/type/p5.Font.js b/src/type/p5.Font.js index d93352b763..8a5ead0cab 100644 --- a/src/type/p5.Font.js +++ b/src/type/p5.Font.js @@ -843,7 +843,7 @@ export class Font { } _position(renderer, lines, bounds, width, height) { - let { textAlign, textLeading, textSize } = renderer.states; + let { textAlign, textLeading } = renderer.states; let metrics = this._measureTextDefault(renderer, 'X'); let ascent = metrics.fontBoundingBoxAscent; @@ -1078,8 +1078,7 @@ function createFontFace(name, path, descriptors, rawFont) { if ((rawFont?.fvar?.length ?? 0) > 0) { descriptors = descriptors || {}; - for (const [tag, minVal, defaultVal, maxVal, flags, name] of rawFont - .fvar[0]) { + for (const [tag, minVal, , maxVal] of rawFont.fvar[0]) { if (tag === 'wght') { descriptors.weight = `${minVal} ${maxVal}`; } else if (tag === 'wdth') { @@ -1446,7 +1445,7 @@ function font(p5, fn) { let info; try { info = await fetch(path, { method: 'HEAD' }); - } catch (e) { + } catch { // Sometimes files fail when requested with HEAD. Fallback to a // regular GET. It loads more data, but at least then it's cached // for the likely case when we have to fetch the whole thing. @@ -1497,7 +1496,7 @@ function font(p5, fn) { } fontData = await fn.parseFontData(url); } - } catch (_e) {} + } catch {} return create(this, name, src, fontDescriptors, fontData); }, loadWithoutData: () => create(this, name, src, fontDescriptors) @@ -1577,7 +1576,7 @@ function font(p5, fn) { // create a FontFace object and pass it to the p5.Font constructor pfont = await create(this, name, path, descriptors, fontData); - } catch (err) { + } catch { // failed to parse the font, load it as a simple FontFace let ident = name || diff --git a/src/type/textCore.js b/src/type/textCore.js index 72bb835e6f..a72854c2c6 100644 --- a/src/type/textCore.js +++ b/src/type/textCore.js @@ -23,7 +23,7 @@ function textCore(p5, fn) { const LinebreakRe = /\r?\n/g; const CommaDelimRe = /,\s+/; const QuotedRe = /^".*"$/; - const SpecialCharRe = /[^\x00-\x7F]/; // Non-ascii + const SpecialCharRe = /\P{ASCII}/u; // Non-ascii const TabsRe = /\t/g; const FontVariationSettings = 'fontVariationSettings'; @@ -1810,14 +1810,6 @@ function textCore(p5, fn) { } } - if (0 && opts?.ignoreRectMode) { - // draw bounds for debugging - let ss = context.strokeStyle; - context.strokeStyle = 'green'; - context.strokeRect(bounds.x, bounds.y, bounds.w, bounds.h); - context.strokeStyle = ss; - } - context.textBaseline = setBaseline; // restore baseline return { bounds, lines }; @@ -1866,7 +1858,7 @@ function textCore(p5, fn) { if (this.textCanvas().style[opt] !== value) { // fails on precision for floating points, also quotes and spaces - if (0) + if (debug) console.warn( `Unable to set '${opt}' property` + // FES? ' on canvas.style. It may not be supported. Expected "' + @@ -1909,28 +1901,8 @@ function textCore(p5, fn) { if (this.states.fontWeight !== val) this.textWeight(val); return val; case 'wdth': - if (0) { - // attempt to map font-stretch to allowed keywords - const FontStretchMap = { - 'ultra-condensed': 50, - 'extra-condensed': 62.5, - condensed: 75, - 'semi-condensed': 87.5, - normal: 100, - 'semi-expanded': 112.5, - expanded: 125, - 'extra-expanded': 150, - 'ultra-expanded': 200 - }; - let values = Object.values(FontStretchMap); - const indexArr = values.map(function (k) { - return Math.abs(k - val); - }); - const min = Math.min.apply(Math, indexArr); - let idx = indexArr.indexOf(min); - let stretch = Object.keys(FontStretchMap)[idx]; - this.states.setValue('fontStretch', stretch); - } + // TODO: map the numeric 'wdth' axis onto the allowed font-stretch + // keywords (ultra-condensed ... ultra-expanded) by nearest value. break; case 'ital': if (debug) diff --git a/src/webgl/3d_primitives.js b/src/webgl/3d_primitives.js index 5c6c270745..332a16073b 100644 --- a/src/webgl/3d_primitives.js +++ b/src/webgl/3d_primitives.js @@ -1961,6 +1961,7 @@ function primitives3D(p5, fn) { this.bezierVertex(x3, y3, z3); this.bezierVertex(x4, y4, z4); this.endShape(); + this.bezierOrder(prevOrder); }; // pretier-ignore diff --git a/src/webgl/loading.js b/src/webgl/loading.js index cb29bae4bc..fd8e08592d 100755 --- a/src/webgl/loading.js +++ b/src/webgl/loading.js @@ -13,7 +13,7 @@ async function fileExists(url) { try { const response = await fetch(url, { method: 'HEAD' }); return response.ok; - } catch (error) { + } catch { return false; } } @@ -634,7 +634,7 @@ function loading(p5, fn) { const parsedMaterials = await Promise.all(parsedMaterialPromises); const materials = Object.assign({}, ...parsedMaterials); return materials; - } catch (error) { + } catch { return {}; } } @@ -745,7 +745,6 @@ function loading(p5, fn) { // material per kept face, aligned with model.faces, for bucketing later const faceMaterials = []; let hasColoredVertices = false; - let hasColorlessVertices = false; for (let line = 0; line < lines.length; ++line) { // Each line is a separate object (vertex, face, vertex normal, etc) // For each line, split it into tokens on whitespace. The first token @@ -823,7 +822,6 @@ function loading(p5, fn) { model.vertexColors.push(materialDiffuseColor[2]); model.vertexColors.push(1); } else { - hasColorlessVertices = true; model.vertexColors.push(-1, -1, -1, -1); } } else { diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index e344a4a467..57d1b9726d 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -13,11 +13,9 @@ import { Renderer3D } from '../core/p5.Renderer3D'; import { getStrokeDefs } from './enums'; import { Shader } from './p5.Shader'; import { MipmapTexture } from './p5.Texture'; -import { Framebuffer } from './p5.Framebuffer'; import { RGB, RGBA } from '../color/creating_reading'; import { Image } from '../image/p5.Image'; import { glslBackend } from './strands_glslBackend'; -import { TypeInfoFromGLSLName } from '../strands/ir_types.js'; import { getShaderHookTypes } from './shaderHookUtils'; import filterBaseVert from './shaders/filters/base.vert'; @@ -280,7 +278,7 @@ class RendererGL extends Renderer3D { geometry.lineVertices.length / 3, count ); - } catch (e) { + } catch { console.log( '🌸 p5.js says: Instancing is only supported in WebGL2 mode' ); @@ -322,7 +320,7 @@ class RendererGL extends Renderer3D { 0, count ); - } catch (e) { + } catch { console.log( '🌸 p5.js says: Instancing is only supported in WebGL2 mode' ); @@ -342,7 +340,7 @@ class RendererGL extends Renderer3D { } else { try { gl.drawArraysInstanced(glMode, 0, geometry.vertices.length, count); - } catch (e) { + } catch { console.log( '🌸 p5.js says: Instancing is only supported in WebGL2 mode' ); diff --git a/src/webgl/strands_glslBackend.js b/src/webgl/strands_glslBackend.js index 44f9ebf7c1..8fd3ccaa81 100644 --- a/src/webgl/strands_glslBackend.js +++ b/src/webgl/strands_glslBackend.js @@ -353,7 +353,7 @@ export const glslBackend = { } return node.identifier; - case NodeType.OPERATION: + case NodeType.OPERATION: { const useParantheses = node.usedBy.length > 0; if (node.opCode === OpCode.Nary.CONSTRUCTOR) { // TODO: differentiate casts and constructors for more efficient codegen. @@ -460,6 +460,10 @@ export const glslBackend = { const sym = OpCodeToSymbol[node.opCode]; return `${sym}${val}`; } + return FES.internalError( + `Operation with opCode ${node.opCode} is not supported in expressions` + ); + } case NodeType.PHI: // Phi nodes represent conditional merging of values // If this phi node has an identifier (like varying variables), use that @@ -482,19 +486,14 @@ export const glslBackend = { ); } else { throw new Error(`No valid inputs for node`); - // Fallback: create a default value - const typeName = this.getTypeName(node.baseType, node.dimension); - if (node.dimension === 1) { - return node.baseType === BaseType.FLOAT ? '0.0' : '0'; - } else { - return `${typeName}(0.0)`; - } } } case NodeType.ASSIGNMENT: - FES.internalError(`ASSIGNMENT nodes should not be used as expressions`); + return FES.internalError( + `ASSIGNMENT nodes should not be used as expressions` + ); default: - FES.internalError( + return FES.internalError( `${NodeTypeToName[node.nodeType]} code generation not implemented yet` ); } diff --git a/src/webgl/text.js b/src/webgl/text.js index f10c8e8ea1..6aa530f67e 100644 --- a/src/webgl/text.js +++ b/src/webgl/text.js @@ -87,7 +87,7 @@ function text(p5, fn) { try { // create a new image imageData = new ImageData(this.width, this.height); - } catch (err) { + } catch { // for browsers that don't support ImageData constructors (ie IE11) // create an ImageData using the old method let canvas = document.getElementsByTagName('canvas')[0]; diff --git a/src/webgl/utils.js b/src/webgl/utils.js index 0d29e143e4..f8d17679be 100644 --- a/src/webgl/utils.js +++ b/src/webgl/utils.js @@ -1,5 +1,4 @@ import * as constants from '../core/constants'; -import { INSTANCE_ID_VARYING_NAME } from '../strands/ir_types'; import { Texture } from './p5.Texture'; /** diff --git a/src/webgpu/p5.RendererWebGPU.js b/src/webgpu/p5.RendererWebGPU.js index 072ae2f34c..c16e323ca0 100644 --- a/src/webgpu/p5.RendererWebGPU.js +++ b/src/webgpu/p5.RendererWebGPU.js @@ -6,7 +6,7 @@ import * as constants from '../core/constants'; import { getStrokeDefs } from '../webgl/enums'; -import { DataType, INSTANCE_ID_VARYING_NAME } from '../strands/ir_types.js'; +import { DataType } from '../strands/ir_types.js'; import { colorVertexShader, colorFragmentShader } from './shaders/color'; import { lineVertexShader, lineFragmentShader } from './shaders/line'; @@ -2359,7 +2359,7 @@ function rendererWebGPU(p5, fn) { }; while ((match = elementRegex.exec(structBody)) !== null) { - const [_, location, name, type] = match; + const [, location, name, type] = match; const { size, align, pack, packInPlace, baseType } = baseAlignAndSize(type); offset = Math.ceil(offset / align) * align; @@ -2416,7 +2416,7 @@ function rendererWebGPU(p5, fn) { ? shader.computeSrc() : shader.vertSrc(); while ((match = uniformVarRegex.exec(src)) !== null) { - const [_, groupNum, binding, varName, structType] = match; + const [, groupNum, binding, varName, structType] = match; const bindingIndex = parseInt(binding); const uniforms = this._parseStruct(src, structType); @@ -2482,7 +2482,7 @@ function rendererWebGPU(p5, fn) { let match; while ((match = samplerRegex.exec(src)) !== null) { - const [_, group, binding, name, type] = match; + const [, group, binding, name, type] = match; const groupIndex = parseInt(group); const bindingIndex = parseInt(binding); // Skip struct uniform bindings which we've already parsed @@ -2517,7 +2517,7 @@ function rendererWebGPU(p5, fn) { // Parse storage buffers while ((match = storageRegex.exec(src)) !== null) { - const [_, group, binding, accessMode, name] = match; + const [, group, binding, accessMode, name] = match; const groupIndex = parseInt(group); const bindingIndex = parseInt(binding); @@ -2561,10 +2561,10 @@ function rendererWebGPU(p5, fn) { if (frag) sources.push([frag, GPUShaderStage.FRAGMENT]); if (compute) sources.push([compute, GPUShaderStage.COMPUTE]); - for (const [src, visibility] of sources) { + for (const [src] of sources) { let match; while ((match = bindingRegex.exec(src)) !== null) { - const [_, groupIndex, bindingIndex] = match; + const [, groupIndex, bindingIndex] = match; if (parseInt(groupIndex) === group) { maxBindingIndex = Math.max(maxBindingIndex, parseInt(bindingIndex)); } @@ -3179,7 +3179,7 @@ ${hookUniformFields}} // Handle instanceID varying for fragment access if (shader.hooks.instanceIDVarying) { - const { name, declaration, source, interpolation } = + const { declaration, source, interpolation } = shader.hooks.instanceIDVarying; const nextLocIndex = this._getNextAvailableLocation( preMain, @@ -3188,7 +3188,7 @@ ${hookUniformFields}} const interpAttr = interpolation ? ` @interpolate(${interpolation})` : ''; - const [varName, varType] = declaration.split(':').map(s => s.trim()); + const [varName] = declaration.split(':').map(s => s.trim()); const structMember = `@location(${nextLocIndex})${interpAttr} ${declaration},`; if (shaderType === 'vertex') { @@ -3238,7 +3238,7 @@ ${hookUniformFields}} } for (const hookDef in shader.hooks.helpers) { const [hookType, hookName] = hookDef.split(' '); - const [_, params, body] = /^(\([^)]*\))((?:.|\n)*)$/.exec( + const [, params, body] = /^(\([^)]*\))((?:.|\n)*)$/.exec( shader.hooks.helpers[hookDef] ); if (hookType === 'void') { @@ -3257,7 +3257,7 @@ ${hookUniformFields}} shader.hooks.modified[shaderType][hookDef] ? 'true' : 'false' };\n`; - let [_, params, body] = /^(\([^)]*\))((?:.|\n)*)$/.exec( + let [, params, body] = /^(\([^)]*\))((?:.|\n)*)$/.exec( shader.hooks[shaderType][hookDef] ); diff --git a/src/webgpu/strands_wgslBackend.js b/src/webgpu/strands_wgslBackend.js index 2d193f172f..6159af6965 100644 --- a/src/webgpu/strands_wgslBackend.js +++ b/src/webgpu/strands_wgslBackend.js @@ -526,7 +526,7 @@ export const wgslBackend = { } else { return node.value; } - case NodeType.VARIABLE: + case NodeType.VARIABLE: { // Track shared variable usage context if ( generationContext.shaderContext && @@ -567,7 +567,8 @@ export const wgslBackend = { } return node.identifier; - case NodeType.OPERATION: + } + case NodeType.OPERATION: { const useParantheses = node.usedBy.length > 0; if (node.opCode === OpCode.Nary.CONSTRUCTOR) { // TODO: differentiate casts and constructors for more efficient codegen. @@ -706,6 +707,10 @@ export const wgslBackend = { const sym = OpCodeToSymbol[node.opCode]; return `${sym}${val}`; } + return FES.internalError( + `Operation with opCode ${node.opCode} is not supported in expressions` + ); + } case NodeType.PHI: // Phi nodes represent conditional merging of values // If this phi node has an identifier (like varying variables), use that @@ -731,9 +736,11 @@ export const wgslBackend = { } } case NodeType.ASSIGNMENT: - FES.internalError(`ASSIGNMENT nodes should not be used as expressions`); + return FES.internalError( + `ASSIGNMENT nodes should not be used as expressions` + ); default: - FES.internalError( + return FES.internalError( `${NodeTypeToName[node.nodeType]} code generation not implemented yet` ); } diff --git a/test/unit/accessibility/outputs.js b/test/unit/accessibility/outputs.js index 3da3291c6a..e4edbd5ad8 100644 --- a/test/unit/accessibility/outputs.js +++ b/test/unit/accessibility/outputs.js @@ -5,8 +5,6 @@ import p5 from '../../../src/app.js'; // TODO: Is it possible to test this without a runtime? suite('outputs', function () { - let myID = 'myCanvasID'; - beforeAll(function () { outputs(mockP5, mockP5Prototype); textOutput(mockP5, mockP5Prototype); diff --git a/test/unit/core/sketch_overrides.js b/test/unit/core/sketch_overrides.js index 44a045f6a1..410b5da7c8 100644 --- a/test/unit/core/sketch_overrides.js +++ b/test/unit/core/sketch_overrides.js @@ -1,16 +1,6 @@ import { verifierUtils } from '../../../src/friendly_errors/sketch_verifier.js'; suite('Sketch Verifier', function () { - const mockP5 = { - _validateParameters: vi.fn(), - Color: function () {}, - Vector: function () {}, - prototype: { - rect: function () {}, - ellipse: function () {} - } - }; - afterEach(() => { vi.restoreAllMocks(); vi.unstubAllGlobals(); diff --git a/test/unit/dom/dom.js b/test/unit/dom/dom.js index 4469096e84..ae0d70f5f7 100644 --- a/test/unit/dom/dom.js +++ b/test/unit/dom/dom.js @@ -947,6 +947,8 @@ suite('DOM', function () { }); const emptyCallback = () => {}; + // Used by the commented-out file-input tests further down in this suite. + /* oxlint-disable-next-line no-unused-vars */ const createDummyFile = filename => { return new File(['testFileBlob'], filename, { type: 'text/plain' diff --git a/test/unit/image/loading.js b/test/unit/image/loading.js index 4b53cbb469..ad9ba6a973 100644 --- a/test/unit/image/loading.js +++ b/test/unit/image/loading.js @@ -5,33 +5,6 @@ import image from '../../../src/image/p5.Image'; import p5 from '../../../src/app.js'; import { vi } from 'vitest'; -/** - * Expects an image file and a p5 instance with an image file loaded and drawn - * and checks that they are exactly the same. Sends result to the callback. - */ -var testImageRender = function (file, sketch) { - sketch.loadPixels(); - var p = sketch.pixels; - var ctx = sketch; - - sketch.clear(); - - return new Promise(function (resolve, reject) { - sketch.loadImage(file, resolve, reject); - }).then(function (img) { - ctx.image(img, 0, 0); - - ctx.loadPixels(); - var n = 0; - for (var i = 0; i < p.length; i++) { - var diff = Math.abs(p[i] - ctx.pixels[i]); - n += diff; - } - var same = n === 0 && ctx.pixels.length === p.length; - return same; - }); -}; - suite('loading images', function () { const imagePath = '/test/unit/assets/cat.jpg'; const singleFrameGif = '/test/unit/assets/target_small.gif'; diff --git a/test/unit/visual/cases/webgl.js b/test/unit/visual/cases/webgl.js index 8aa084fd49..acc58c9d29 100644 --- a/test/unit/visual/cases/webgl.js +++ b/test/unit/visual/cases/webgl.js @@ -1506,7 +1506,7 @@ visualSuite('WebGL', function () { p5.baseMaterialShader().modify(() => { undefined.someMethod(); // This will throw an error }); - } catch (e) {} + } catch {} p5.background('red'); p5.circle(p5.noise(0), p5.noise(0), 20); screenshot(); diff --git a/test/unit/visual/cases/webgpu.js b/test/unit/visual/cases/webgpu.js index 87dbf1a8c8..9da7a01bc9 100644 --- a/test/unit/visual/cases/webgpu.js +++ b/test/unit/visual/cases/webgpu.js @@ -1,4 +1,3 @@ -import { vi } from 'vitest'; import p5 from '../../../../src/app'; import { visualSuite, visualTest } from '../visualTest'; import rendererWebGPU from '../../../../src/webgpu/p5.RendererWebGPU'; diff --git a/test/unit/visual/visualTest.js b/test/unit/visual/visualTest.js index 31181d8217..36ed4e1110 100644 --- a/test/unit/visual/visualTest.js +++ b/test/unit/visual/visualTest.js @@ -1,14 +1,8 @@ import p5 from '../../../src/app.js'; import { server } from 'vitest/browser'; -import { THRESHOLD, DIFFERENCE, ERODE } from '../../../src/core/constants.js'; const { readFile, writeFile } = server.commands; import pixelmatch from 'pixelmatch'; -// By how much can each color channel value (0-255) differ before -// we call it a mismatch? This should be large enough to not trigger -// based on antialiasing. -const COLOR_THRESHOLD = 25; - // The max side length to shrink test images down to before // comparing, for performance. const MAX_SIDE = 50; diff --git a/test/unit/webgl/p5.Framebuffer.js b/test/unit/webgl/p5.Framebuffer.js index 4147edb174..4bdb8af0d7 100644 --- a/test/unit/webgl/p5.Framebuffer.js +++ b/test/unit/webgl/p5.Framebuffer.js @@ -481,7 +481,7 @@ suite('p5.Framebuffer', function () { }); test('get() creates a p5.Image matching the source pixel density', function () { - const mainCanvas = myp5.createCanvas(20, 20, myp5.WEBGL); + myp5.createCanvas(20, 20, myp5.WEBGL); myp5.pixelDensity(2); const fbo = myp5.createFramebuffer(); fbo.draw(() => { diff --git a/test/unit/webgl/p5.RendererGL.js b/test/unit/webgl/p5.RendererGL.js index 6d50708c7b..2757c505cb 100644 --- a/test/unit/webgl/p5.RendererGL.js +++ b/test/unit/webgl/p5.RendererGL.js @@ -2156,7 +2156,7 @@ void main() { }); test('works normally for <50k vertices', function () { - const renderer = myp5.createCanvas(10, 10, myp5.WEBGL); + myp5.createCanvas(10, 10, myp5.WEBGL); const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(false); myp5.beginShape(); @@ -2175,7 +2175,7 @@ void main() { suite('color interpolation', function () { test('strokes should interpolate colors between vertices', function () { - const renderer = myp5.createCanvas(512, 4, myp5.WEBGL); + myp5.createCanvas(512, 4, myp5.WEBGL); // far left color: (242, 236, 40) // far right color: (42, 36, 240) @@ -3043,13 +3043,12 @@ void main() { }); test('Maintains stencil test state across draw cycles when user enabled', function () { - let drawCalled = false; - myp5.createCanvas(50, 50, myp5.WEBGL); + // NOTE: redraw() does not invoke this override, so the wrapper below never + // actually runs. Left in place to keep this test's behaviour unchanged. const originalDraw = myp5.draw; myp5.draw = function () { - drawCalled = true; if (originalDraw) originalDraw.call(myp5); }; diff --git a/test/unit/webgl/p5.Shader.js b/test/unit/webgl/p5.Shader.js index db552b92d8..0d64ec3fb4 100644 --- a/test/unit/webgl/p5.Shader.js +++ b/test/unit/webgl/p5.Shader.js @@ -1905,6 +1905,9 @@ suite('p5.Shader', function () { const testShader = myp5.baseFilterShader().modify( () => { + // The constant comparisons below are the subject of this test: they + // exercise how p5.strands transpiles boolean intermediate variables. + /* oxlint-disable no-constant-binary-expression */ myp5.getColor((inputs, canvasContent) => { let value = 1; let condition = 1 > 2; @@ -1919,6 +1922,7 @@ suite('p5.Shader', function () { return [0.4, 0, 0, 1]; }); + /* oxlint-enable no-constant-binary-expression */ }, { myp5 } ); @@ -1937,6 +1941,9 @@ suite('p5.Shader', function () { const testShader = myp5.baseFilterShader().modify( () => { + // The constant comparisons below are the subject of this test: they + // exercise how p5.strands transpiles boolean intermediate variables. + /* oxlint-disable no-constant-binary-expression */ const conditionMet = () => { let condition = 1 > 2; let value = 1; @@ -1945,6 +1952,7 @@ suite('p5.Shader', function () { } return !condition; }; + /* oxlint-enable no-constant-binary-expression */ myp5.getColor((inputs, canvasContent) => { if (conditionMet()) { return [1, 0, 0, 1]; @@ -2512,7 +2520,7 @@ suite('p5.Shader', function () { for (let xOff = -1; xOff <= 1; xOff++) { for (let yOff = -1; yOff <= 1; yOff++) { - if (xOff != 0 || yOff != 0) { + if (xOff !== 0 || yOff !== 0) { aliveNeighbours += 0.1; } } @@ -2939,7 +2947,8 @@ suite('p5.Shader', function () { test('simple vector multiplication in filter shader', () => { myp5.createCanvas(50, 50, myp5.WEBGL); - const testShader = myp5.baseFilterShader().modify( + // Compiling the shader without throwing is what this test checks. + myp5.baseFilterShader().modify( () => { myp5.getColor((inputs, canvasContent) => { // Test simple scalar * vector operation @@ -3566,6 +3575,8 @@ suite('p5.Shader', function () { expect(() => { myp5.baseMaterialShader().modify( () => { + // The shared variable is consumed by the p5.strands transpiler, not by JS. + /* oxlint-disable-next-line no-unused-vars */ let worldPosX = myp5.sharedVec3(); myp5.getWorldInputs(inputs => { worldPosX = inputs.position.x; // scalar → vec3, valid broadcast @@ -3583,6 +3594,8 @@ suite('p5.Shader', function () { expect(() => { myp5.baseMaterialShader().modify( () => { + // The shared variable is consumed by the p5.strands transpiler, not by JS. + /* oxlint-disable-next-line no-unused-vars */ let myVec = myp5.sharedVec3(); myp5.getWorldInputs(inputs => { myVec = inputs.position.xy; // vec2 → vec3 mismatch @@ -3617,6 +3630,8 @@ suite('p5.Shader', function () { expect(() => { myp5.baseMaterialShader().modify( () => { + // The shared variable is consumed by the p5.strands transpiler, not by JS. + /* oxlint-disable-next-line no-unused-vars */ let myVec = myp5.sharedVec3(); myp5.getWorldInputs(inputs => { myVec = inputs.position; // vec3 → vec3, OK @@ -3658,7 +3673,7 @@ suite('p5.Shader', function () { }, { myp5 } ); - } catch (e) { + } catch { /* expected */ } @@ -3685,7 +3700,7 @@ suite('p5.Shader', function () { }, { myp5 } ); - } catch (e) { + } catch { /* expected */ } @@ -3711,7 +3726,7 @@ suite('p5.Shader', function () { }, { myp5 } ); - } catch (e) { + } catch { /* expected */ } @@ -3741,7 +3756,7 @@ suite('p5.Shader', function () { }, { myp5 } ); - } catch (e) { + } catch { /* expected */ } @@ -3805,11 +3820,13 @@ suite('p5.Shader', function () { () => { myp5.getWorldInputs.begin(); myp5.getWorldInputs.end(); + // Reading `.position` outside the hook scope is what should error. + /* oxlint-disable-next-line no-unused-vars */ const pos = myp5.getWorldInputs.position; }, { myp5 } ); - } catch (e) { + } catch { /* expected */ } diff --git a/test/unit/webgl/p5.Texture.js b/test/unit/webgl/p5.Texture.js index 7c3d79bc36..a3c53da6fc 100644 --- a/test/unit/webgl/p5.Texture.js +++ b/test/unit/webgl/p5.Texture.js @@ -217,8 +217,8 @@ suite('p5.Texture', function () { }); test('Set global wrap mode to clamp', function () { myp5.textureWrap(myp5.CLAMP); - var tex1 = myp5._renderer.getTexture(texImg1); - var tex2 = myp5._renderer.getTexture(texImg2); + myp5._renderer.getTexture(texImg1); + myp5._renderer.getTexture(texImg2); expect(texParamSpy).toHaveBeenCalledWith( myp5._renderer.GL.TEXTURE_2D, myp5._renderer.GL.TEXTURE_WRAP_S, @@ -242,8 +242,8 @@ suite('p5.Texture', function () { }); test('Set global wrap mode to repeat', function () { myp5.textureWrap(myp5.REPEAT); - var tex1 = myp5._renderer.getTexture(texImg1); - var tex2 = myp5._renderer.getTexture(texImg2); + myp5._renderer.getTexture(texImg1); + myp5._renderer.getTexture(texImg2); expect(texParamSpy).toHaveBeenCalledWith( myp5._renderer.GL.TEXTURE_2D, myp5._renderer.GL.TEXTURE_WRAP_S, @@ -267,8 +267,8 @@ suite('p5.Texture', function () { }); test('Set global wrap mode to mirror', function () { myp5.textureWrap(myp5.MIRROR); - var tex1 = myp5._renderer.getTexture(texImg1); - var tex2 = myp5._renderer.getTexture(texImg2); + myp5._renderer.getTexture(texImg1); + myp5._renderer.getTexture(texImg2); expect(texParamSpy).toHaveBeenCalledWith( myp5._renderer.GL.TEXTURE_2D, myp5._renderer.GL.TEXTURE_WRAP_S, diff --git a/test/unit/webgpu/p5.Shader.js b/test/unit/webgpu/p5.Shader.js index 5c20a6b199..4003152397 100644 --- a/test/unit/webgpu/p5.Shader.js +++ b/test/unit/webgpu/p5.Shader.js @@ -691,6 +691,9 @@ suite('WebGPU p5.Shader', function () { const testShader = myp5.baseFilterShader().modify( () => { + // The constant comparisons below are the subject of this test: they + // exercise how p5.strands transpiles boolean intermediate variables. + /* oxlint-disable no-constant-binary-expression */ myp5.getColor((inputs, canvasContent) => { let value = 1; let condition = 1 > 2; @@ -705,6 +708,7 @@ suite('WebGPU p5.Shader', function () { return [0.4, 0, 0, 1]; }); + /* oxlint-enable no-constant-binary-expression */ }, { myp5 } ); @@ -723,6 +727,9 @@ suite('WebGPU p5.Shader', function () { const testShader = myp5.baseFilterShader().modify( () => { + // The constant comparisons below are the subject of this test: they + // exercise how p5.strands transpiles boolean intermediate variables. + /* oxlint-disable no-constant-binary-expression */ const conditionMet = () => { let condition = 1 > 2; let value = 1; @@ -731,6 +738,7 @@ suite('WebGPU p5.Shader', function () { } return !condition; }; + /* oxlint-enable no-constant-binary-expression */ myp5.getColor((inputs, canvasContent) => { if (conditionMet()) { return [1, 0, 0, 1]; @@ -1616,7 +1624,8 @@ suite('WebGPU p5.Shader', function () { test('simple vector multiplication in filter shader', async () => { await myp5.createCanvas(50, 50, myp5.WEBGPU); - const testShader = myp5.baseFilterShader().modify( + // Compiling the shader without throwing is what this test checks. + myp5.baseFilterShader().modify( () => { myp5.getColor((inputs, canvasContent) => { // Test simple scalar * vector operation @@ -1879,9 +1888,12 @@ suite('WebGPU p5.Shader', function () { () => { const buf = myp5.uniformStorage(); const id = myp5.index.x; - if (id == 0) { + if (id === 0) { buf[0] = 1.0; return; + // The statement after the early return is the subject of this + // test: p5.strands must not emit it. + /* oxlint-disable-next-line no-unreachable */ buf[0] = 2.0; // Should not execute } }, @@ -2065,6 +2077,8 @@ suite('WebGPU p5.Shader', function () { expect(() => { myp5.baseMaterialShader().modify( () => { + // The shared variable is consumed by the p5.strands transpiler, not by JS. + /* oxlint-disable-next-line no-unused-vars */ let worldPosX = myp5.sharedVec3(); myp5.getWorldInputs(inputs => { worldPosX = inputs.position.x; // scalar → vec3, valid broadcast @@ -2082,6 +2096,8 @@ suite('WebGPU p5.Shader', function () { expect(() => { myp5.baseMaterialShader().modify( () => { + // The shared variable is consumed by the p5.strands transpiler, not by JS. + /* oxlint-disable-next-line no-unused-vars */ let myVec = myp5.sharedVec3(); myp5.getWorldInputs(inputs => { myVec = inputs.position.xy; // vec2 → vec3 mismatch @@ -2116,6 +2132,8 @@ suite('WebGPU p5.Shader', function () { expect(() => { myp5.baseMaterialShader().modify( () => { + // The shared variable is consumed by the p5.strands transpiler, not by JS. + /* oxlint-disable-next-line no-unused-vars */ let myVec = myp5.sharedVec3(); myp5.getWorldInputs(inputs => { myVec = inputs.position; // vec3 → vec3, OK diff --git a/utils/contributors-png.js b/utils/contributors-png.js index 2686f1685f..40d8b02997 100644 --- a/utils/contributors-png.js +++ b/utils/contributors-png.js @@ -23,7 +23,7 @@ async function loadAvatar(url) { const buffer = Buffer.from(await res.arrayBuffer()); return await loadImage(buffer); - } catch (err) { + } catch { return null; } } diff --git a/utils/contributors-png.mjs b/utils/contributors-png.mjs index ec13c50c8f..1258021d8a 100644 --- a/utils/contributors-png.mjs +++ b/utils/contributors-png.mjs @@ -22,7 +22,7 @@ async function loadAvatar(url) { if (!res.ok) throw new Error(`HTTP ${res.status}`); const buffer = Buffer.from(await res.arrayBuffer()); return await loadImage(buffer); - } catch (err) { + } catch { return null; } }