diff --git a/src/highlight/HighlightCanvas.tsx b/src/highlight/HighlightCanvas.tsx index 9e6ba4dea..dcdaf35a7 100644 --- a/src/highlight/HighlightCanvas.tsx +++ b/src/highlight/HighlightCanvas.tsx @@ -67,6 +67,12 @@ export default class HighlightCanvas extends React.PureComponent { shapesArray.forEach(rect => { const { height, isActive, isHover, width, x, y } = rect; + + // Ignore empty rects with a width or height of 0 + if (width === 0 || height === 0) { + return; + } + const rectHeight = (height / 100) * canvasHeight; const rectWidth = (width / 100) * canvasWidth; const x1 = (x / 100) * canvasWidth; diff --git a/src/highlight/__mocks__/data.ts b/src/highlight/__mocks__/data.ts index 96068240e..1c123bd57 100644 --- a/src/highlight/__mocks__/data.ts +++ b/src/highlight/__mocks__/data.ts @@ -8,6 +8,22 @@ export const rect: Rect = { y: 5, }; +export const noWidthRect: Rect = { + type: 'rect' as const, + height: 10, + width: 0, + x: 5, + y: 5, +}; + +export const noHeightRect: Rect = { + type: 'rect' as const, + height: 0, + width: 20, + x: 5, + y: 5, +}; + export const target: TargetHighlight = { location: { type: 'page' as const, @@ -55,3 +71,10 @@ export const selection = { }, ], }; + +export const canvasContext = { + fillRect: jest.fn(), + restore: jest.fn(), + save: jest.fn(), + strokeRect: jest.fn(), +}; diff --git a/src/highlight/__tests__/HighlightCanvas-test.tsx b/src/highlight/__tests__/HighlightCanvas-test.tsx index cf050834c..201cd8372 100644 --- a/src/highlight/__tests__/HighlightCanvas-test.tsx +++ b/src/highlight/__tests__/HighlightCanvas-test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; import HighlightCanvas, { Props } from '../HighlightCanvas'; -import { rect as mockRect } from '../__mocks__/data'; +import { canvasContext, rect as mockRect, noWidthRect, noHeightRect } from '../__mocks__/data'; describe('HighlightCanvas', () => { const defaults: Props = { @@ -56,5 +56,23 @@ describe('HighlightCanvas', () => { const wrapper = getWrapper(); expect(wrapper.find('canvas').hasClass('ba-HighlightCanvas')).toBe(true); }); + + test('should render, excluding 0 width and height values', () => { + const wrapper = getWrapper({ shapes: [mockRect, noWidthRect, noHeightRect] }); + const instance = wrapper.instance() as HighlightCanvas; + + instance.canvasRef = { + current: { + // eslint-disable-next-line @typescript-eslint/ban-ts-ignore + // @ts-ignore + getContext: () => canvasContext, + }, + }; + + instance.renderRects(); + + expect(canvasContext.fillRect).toHaveBeenCalledTimes(1); + expect(canvasContext.strokeRect).toHaveBeenCalledTimes(1); + }); }); }); diff --git a/src/highlight/__tests__/highlightUtil-test.ts b/src/highlight/__tests__/highlightUtil-test.ts index 575065514..ce3bd1f46 100644 --- a/src/highlight/__tests__/highlightUtil-test.ts +++ b/src/highlight/__tests__/highlightUtil-test.ts @@ -166,6 +166,46 @@ describe('highlightUtil', () => { expect(result[1]).toEqual(rects[3]); expect(result[2]).toEqual(rects[4]); }); + + test('should combine rects by row, excluding 0 width and height values', () => { + const validRect1 = { + height: 20, + width: 100, + x: 100, + y: 200, + }; + + const validRect2 = { + height: 21, + width: 100, + x: 500, + y: 200, + }; + + const noHeightRect = { + height: 0, + width: 100, + x: 200, + y: 200, + }; + + const noWidthRect = { + height: 23, + width: 0, + x: 400, + y: 300, + }; + + const result = combineRects([validRect1, noHeightRect, validRect2, noWidthRect]); + expect(result).toHaveLength(2); + expect(result[0]).toEqual({ + height: 20, + width: 100, + x: 100, + y: 200, + }); + expect(result[1]).toEqual(validRect2); + }); }); describe('getShapeRelativeToContainer', () => { diff --git a/src/highlight/highlightUtil.ts b/src/highlight/highlightUtil.ts index 11f92aea2..6fbc13a41 100644 --- a/src/highlight/highlightUtil.ts +++ b/src/highlight/highlightUtil.ts @@ -103,6 +103,12 @@ export const combineRects = (rects: Shape[]): Shape[] => { dedupeRects(rects).forEach(rect => { const { height, width, x, y } = rect; + + // Ignore empty rects with a width or height of 0 + if (width === 0 || height === 0) { + return; + } + const lastRect = result.pop(); if (!lastRect) {