import { Canvas } from './Canvas'; import { Rect } from '../shapes/Rect'; import { IText } from '../shapes/IText/IText'; import '../shapes/ActiveSelection'; describe('Canvas', () => { it('implements toCanvasElement method that clears the contextTop', () => { const canvas = new Canvas(); const mockSetCtx = jest.fn(); class UpperMock { declare el: any; set ctx(value: any) { mockSetCtx(value); } get ctx() { return undefined; } constructor() { this.el = { getContext: jest.fn(), }; } } canvas.elements.upper = new UpperMock(); canvas.toCanvasElement(); expect(mockSetCtx).toHaveBeenCalledWith(undefined); expect(mockSetCtx).toHaveBeenCalledTimes(2); }); describe('touchStart', () => { test('will prevent default to not allow dom scrolling on canvas touch drag', () => { const canvas = new Canvas(undefined, { allowTouchScrolling: false, }); const touch = { clientX: 10, clientY: 0, identifier: 1, target: canvas.upperCanvasEl, }; const evt = new TouchEvent('touchstart', { touches: [touch], changedTouches: [touch], }); evt.preventDefault = jest.fn(); canvas._onTouchStart(evt); expect(evt.preventDefault).toHaveBeenCalled(); }); test('will not prevent default when allowTouchScrolling is true and there is no action', () => { const canvas = new Canvas(undefined, { allowTouchScrolling: true, }); const touch = { clientX: 10, clientY: 0, identifier: 1, target: canvas.upperCanvasEl, }; const evt = new TouchEvent('touchstart', { touches: [touch], changedTouches: [touch], }); evt.preventDefault = jest.fn(); canvas._onTouchStart(evt); expect(evt.preventDefault).not.toHaveBeenCalled(); }); test('will prevent default when allowTouchScrolling is true but we are drawing', () => { const canvas = new Canvas(undefined, { allowTouchScrolling: true, isDrawingMode: true, }); const touch = { clientX: 10, clientY: 0, identifier: 1, target: canvas.upperCanvasEl, }; const evt = new TouchEvent('touchstart', { touches: [touch], changedTouches: [touch], }); evt.preventDefault = jest.fn(); canvas._onTouchStart(evt); expect(evt.preventDefault).toHaveBeenCalled(); }); test('will prevent default when allowTouchScrolling is true and we are dragging an object', () => { const canvas = new Canvas(undefined, { allowTouchScrolling: true, }); const rect = new Rect({ width: 2000, height: 2000, left: -500, top: -500, }); canvas.add(rect); canvas.setActiveObject(rect); const touch = { clientX: 10, clientY: 0, identifier: 1, target: canvas.upperCanvasEl, }; const evt = new TouchEvent('touchstart', { touches: [touch], changedTouches: [touch], }); evt.preventDefault = jest.fn(); canvas._onTouchStart(evt); expect(evt.preventDefault).toHaveBeenCalled(); }); test('will NOT prevent default when allowTouchScrolling is true and we just lost selection', () => { const canvas = new Canvas(undefined, { allowTouchScrolling: true, }); const rect = new Rect({ width: 200, height: 200, left: 1000, top: 1000, }); canvas.add(rect); canvas.setActiveObject(rect); const touch = { clientX: 10, clientY: 0, identifier: 1, target: canvas.upperCanvasEl, }; const evt = new TouchEvent('touchstart', { touches: [touch], changedTouches: [touch], }); evt.preventDefault = jest.fn(); canvas._onTouchStart(evt); expect(evt.preventDefault).not.toHaveBeenCalled(); }); test('dispose after _onTouchStart', () => { jest.spyOn(global, 'clearTimeout'); const canvas = new Canvas(undefined, { allowTouchScrolling: true, isDrawingMode: true, }); const touch = { clientX: 10, clientY: 0, identifier: 1, target: canvas.upperCanvasEl, }; const evtStart = new TouchEvent('touchstart', { touches: [touch], changedTouches: [touch], }); canvas._onTouchStart(evtStart); const evtEnd = new TouchEvent('touchend', { touches: [], changedTouches: [touch], }); canvas._onTouchEnd(evtEnd); expect(canvas._willAddMouseDown).toBeGreaterThan(0); canvas.dispose(); expect(global.clearTimeout).toHaveBeenCalledWith( canvas._willAddMouseDown, ); }); }); describe('handleMultiSelection', () => { const canvas = new Canvas(); const rect = new Rect({ left: 100, width: 100, height: 100 }); const iText = new IText('itext'); canvas.add(rect, iText); test('Selecting shapes containing text does not trigger the exit event', () => { const exitMock = jest.fn(); iText.on('editing:exited', exitMock); const firstClick = new MouseEvent('click', { clientX: 0, clientY: 0, }); canvas._onMouseDown(firstClick); canvas._onMouseUp(firstClick); const secondClick = new MouseEvent('click', { shiftKey: true, clientX: 100, clientY: 0, }); canvas._onMouseDown(secondClick); canvas._onMouseUp(secondClick); expect(exitMock).toHaveBeenCalledTimes(0); }); }); });