diff --git a/src/api/tile/__tests__/denormalizeDupes.test.ts b/src/api/tile/__tests__/denormalizeDupes.test.ts new file mode 100644 index 0000000..3f45f5d --- /dev/null +++ b/src/api/tile/__tests__/denormalizeDupes.test.ts @@ -0,0 +1,17 @@ +import { BLACK24 } from '../../palette/colors'; +import { getTestCanvas } from '../../../testUtil'; +import { denormalizeDupes } from '../denormalizeDupes'; + +describe('denormalizeDupes', function () { + it('should maintain the original Canvas ref', function () { + const tile = { + cromIndex: 0, + canvasSource: getTestCanvas(BLACK24), + }; + + const deduped = denormalizeDupes([[[tile]]], 'cromIndex'); + + expect(tile).not.toBe(deduped[0][0][0]); + expect(tile.canvasSource).toBe(deduped[0][0][0].canvasSource); + }); +}); diff --git a/src/api/tile/denormalizeDupes.ts b/src/api/tile/denormalizeDupes.ts index f79fc78..a93bcee 100644 --- a/src/api/tile/denormalizeDupes.ts +++ b/src/api/tile/denormalizeDupes.ts @@ -1,4 +1,5 @@ import cloneDeep from 'lodash/cloneDeep'; +import { Canvas } from 'canvas'; /** * If a tile is a dupe, it won't have a c/sromIndex but instead @@ -11,16 +12,46 @@ import cloneDeep from 'lodash/cloneDeep'; type DupableTile = { duplicateOf?: DupableTile; + canvasSource?: Canvas; }; type MatrixRow = T[]; type Matrix = MatrixRow[]; +/** + * A Canvas cannot be cloned. So this method clones but copies the original Canvas + * ref, if any, back onto the clone + */ +function cloneDeepExceptCanvasSource( + tiles: Matrix[] +): Matrix[] { + const cloned = cloneDeep(tiles); + + cloned.forEach((image, i) => { + image.forEach((row, r) => { + row.forEach((clonedTile, t) => { + if (clonedTile) { + const originalTile = tiles[i][r][t]; + + if ( + originalTile && + typeof originalTile.canvasSource !== 'undefined' + ) { + clonedTile.canvasSource = originalTile.canvasSource; + } + } + }); + }); + }); + + return cloned; +} + export function denormalizeDupes( tiles: Matrix[], indexProp: keyof T ): Matrix[] { - const cloned = cloneDeep(tiles); + const cloned = cloneDeepExceptCanvasSource(tiles); cloned.forEach((image) => { image.forEach((row) => {