diff --git a/src/canvas/SelectableCanvas.ts b/src/canvas/SelectableCanvas.ts index ad498c65ba6..5710781e84e 100644 --- a/src/canvas/SelectableCanvas.ts +++ b/src/canvas/SelectableCanvas.ts @@ -1104,7 +1104,9 @@ export class SelectableCanvas return false; } this._activeObject = object; - if (object instanceof ActiveSelection) { + + if (object instanceof ActiveSelection && this._activeSelection !== object) { + this._activeSelection.dispose(); this._activeSelection = object; this._activeSelection.set('canvas', this); this._activeSelection.setCoords(); diff --git a/src/shapes/ActiveSelection.spec.ts b/src/shapes/ActiveSelection.spec.ts index ee5a9588fba..d6f74bea367 100644 --- a/src/shapes/ActiveSelection.spec.ts +++ b/src/shapes/ActiveSelection.spec.ts @@ -88,18 +88,27 @@ describe('ActiveSelection', () => { expect(canvas.getActiveSelection().aCoords).toMatchSnapshot(); }); - it('`setActiveObject` should update the active selection ref on canvas', () => { + it('`setActiveObject` should update the active selection ref on canvas if it changed', () => { const canvas = new Canvas(null); const obj1 = new FabricObject(); const obj2 = new FabricObject(); canvas.add(obj1, obj2); + const existingActiveSelection = canvas.getActiveSelection(); + const disposeSpy = jest.spyOn(existingActiveSelection, 'dispose'); const activeSelection = new ActiveSelection([obj1, obj2]); const spy = jest.spyOn(activeSelection, 'setCoords'); canvas.setActiveObject(activeSelection); expect(canvas.getActiveSelection()).toBe(activeSelection); expect(canvas.getActiveObjects()).toEqual([obj1, obj2]); + expect(disposeSpy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled(); expect(activeSelection.canvas).toBe(canvas); + + spy.mockClear(); + const disposeSpy2 = jest.spyOn(activeSelection, 'dispose'); + canvas.setActiveObject(activeSelection); + expect(disposeSpy2).not.toHaveBeenCalled(); + expect(spy).not.toHaveBeenCalled(); }); it('transferring an object between active selections keeps its owning group', () => {