Skip to content

Commit

Permalink
fix: prevent accidental accessing of ref
Browse files Browse the repository at this point in the history
  • Loading branch information
trezy committed Jun 15, 2024
1 parent 5ba3bcc commit 815cb8f
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 27 deletions.
3 changes: 3 additions & 0 deletions src/constants/PixiReactIgnoredProps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const PixiReactIgnoredProps = Object.freeze([
'draw',
]);
5 changes: 5 additions & 0 deletions src/constants/ReactIgnoredProps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const ReactIgnoredProps = Object.freeze([
'children',
'key',
'ref',
]);
13 changes: 2 additions & 11 deletions src/helpers/createInstance.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { applyProps } from './applyProps.js';
import { catalogue } from './catalogue.js';
import { convertStringToPascalCase } from './convertStringToPascalCase.js';
import { gentleCloneProps } from './gentleCloneProps.js';
import { log } from './log.js';
import { prepareInstance } from './prepareInstance.js';

Expand Down Expand Up @@ -29,17 +30,7 @@ export function createInstance(type, props, root)
throw new Error(`${name} is not part of the PIXI namespace! Did you forget to extend?`);
}

const {
// react props
children,
key,
ref,

// @pixi/react props
draw,

...pixiProps
} = props;
const pixiProps = gentleCloneProps(props);

const instance = prepareInstance(new PixiComponent(pixiProps), {
root,
Expand Down
15 changes: 3 additions & 12 deletions src/helpers/diffProps.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isEqual } from './compare.js';
import { gentleCloneProps } from './gentleCloneProps.js';

/** @typedef {import('../typedefs/Change.js').Change} Change */
/** @typedef {import('../typedefs/DiffSet.js').DiffSet} DiffSet */
Expand All @@ -19,18 +20,8 @@ export function diffProps(
remove = false,
)
{
const {
children: newChildren,
key: newKey,
ref: newRef,
...newPropsRest
} = newProps;
const {
children: oldChildren,
key: oldKey,
ref: oldRef,
...oldPropsRest
} = oldProps;
const newPropsRest = gentleCloneProps(newProps);
const oldPropsRest = gentleCloneProps(oldProps);

const entries = Object.entries(newPropsRest);

Expand Down
22 changes: 22 additions & 0 deletions src/helpers/gentleClone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Clones an object without any of the ignored keys.
*
* @param {Record<string, any>} object The object to clone.
* @param {string[]} [ignoredKeys] An array of keys to ignore when cloning the object.
* @returns {Record<string, any>} The cloned object.
*/
export function gentleClone(object, ignoredKeys = [])
{
/** @type {Record<string, any>} */
const cloneBase = {};

return Object.entries(object).reduce((accumulator, [key, value]) =>
{
if (!ignoredKeys.includes(key))
{
accumulator[key] = value;
}

return accumulator;
}, cloneBase);
}
16 changes: 16 additions & 0 deletions src/helpers/gentleCloneProps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { PixiReactIgnoredProps } from '../constants/PixiReactIgnoredProps.js';
import { ReactIgnoredProps } from '../constants/ReactIgnoredProps.js';
import { gentleClone } from './gentleClone.js';

const IGNORED_PROPS = ReactIgnoredProps.concat(PixiReactIgnoredProps);

/**
* Clones a props object, excluding keys that are special to React and Pixi React.
*
* @param {Record<string, any>} props The props object to clone.
* @returns {Record<string, any>} The cloned props.
*/
export function gentleCloneProps(props)
{
return gentleClone(props, IGNORED_PROPS);
}
2 changes: 1 addition & 1 deletion src/typedefs/Instance.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @typedef {import('pixi.js').Graphics} Graphics */

/** @typedef {import('./ContainerElement.js').ContainerElement} ContainerElement */
/** @typedef {import('./EventHandlers.js').EventHandlers} EventHandlers */
/** @typedef {import('./InstanceProps.js').InstanceProps} InstanceProps */
/** @typedef {import('./InstanceState.js').InstanceState} InstanceState */

/**
Expand Down
12 changes: 9 additions & 3 deletions src/typedefs/InstanceProps.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
/** @typedef {import('./Instance.js').Instance} Instance */
/** @typedef {import('pixi.js').Graphics} Graphics */

/** @typedef {import('./ContainerElement.js').ContainerElement} ContainerElement */
/** @typedef {import('./InstanceState.js').InstanceState} InstanceState */

/**
* @typedef {object} BaseInstanceProps
* @property {any} [children]
* @property {(...args: any[]) => any} [draw]
* @property {InstanceState} [__pixireact]
* @property {boolean} [autoRemovedBeforeAppend]
* @property {ContainerElement | ContainerElement[]} [children]
* @property {(graphics: Graphics) => void} [draw]
*/

/** @typedef {{ [key: string]: unknown } & BaseInstanceProps} InstanceProps */
Expand Down

0 comments on commit 815cb8f

Please sign in to comment.