diff --git a/src/lib/annotations/Annotator.js b/src/lib/annotations/Annotator.js index 7418b63cb..c3a27284a 100644 --- a/src/lib/annotations/Annotator.js +++ b/src/lib/annotations/Annotator.js @@ -545,14 +545,23 @@ class Annotator extends EventEmitter { */ bindPointModeListeners() { const pointFunc = this.pointClickHandler.bind(this.annotatedElement); - const handler = { - type: 'click', - func: pointFunc, - eventObj: this.annotatedElement - }; - - handler.eventObj.addEventListener(handler.type, handler.func); - this.annotationModeHandlers.push(handler); + const handlers = [ + { + type: 'mousedown', + func: pointFunc, + eventObj: this.annotatedElement + }, + { + type: 'touchstart', + func: pointFunc, + eventObj: this.annotatedElement + } + ]; + + handlers.forEach((handler) => { + handler.eventObj.addEventListener(handler.type, handler.func); + this.annotationModeHandlers.push(handler); + }); } /** @@ -565,6 +574,7 @@ class Annotator extends EventEmitter { */ pointClickHandler(event) { event.stopPropagation(); + event.preventDefault(); // Determine if a point annotation dialog is already open and close the // current open dialog diff --git a/src/lib/annotations/__tests__/Annotator-test.js b/src/lib/annotations/__tests__/Annotator-test.js index 4fa3bea00..cef6b0d3d 100644 --- a/src/lib/annotations/__tests__/Annotator-test.js +++ b/src/lib/annotations/__tests__/Annotator-test.js @@ -151,7 +151,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('setupAnnotations', () => { + describe('setupAnnotations()', () => { it('should initialize thread map and bind DOM listeners', () => { sandbox.stub(annotator, 'bindDOMListeners'); sandbox.stub(annotator, 'bindCustomListenersOnService'); @@ -341,7 +341,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('fetchAnnotations', () => { + describe('fetchAnnotations()', () => { beforeEach(() => { annotator.annotationService = { getThreadMap: () => {} @@ -380,7 +380,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('bindCustomListenersOnService', () => { + describe('bindCustomListenersOnService()', () => { it('should do nothing if the service does not exist', () => { annotator.annotationService = { addListener: sandbox.stub() @@ -438,7 +438,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('unbindCustomListenersOnService', () => { + describe('unbindCustomListenersOnService()', () => { it('should do nothing if the service does not exist', () => { annotator.annotationService = { removeListener: sandbox.stub() @@ -463,7 +463,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('bindCustomListenersOnThread', () => { + describe('bindCustomListenersOnThread()', () => { it('should bind custom listeners on the thread', () => { stubs.threadMock.expects('addListener').withArgs('threaddeleted', sinon.match.func); stubs.threadMock.expects('addListener').withArgs('threadcleanup', sinon.match.func); @@ -471,7 +471,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('unbindCustomListenersOnThread', () => { + describe('unbindCustomListenersOnThread()', () => { it('should unbind custom listeners from the thread', () => { stubs.threadMock.expects('removeAllListeners').withArgs('threaddeleted'); stubs.threadMock.expects('removeAllListeners').withArgs('threadcleanup'); @@ -479,7 +479,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('bindPointModeListeners', () => { + describe('bindPointModeListeners()', () => { it('should bind point mode click handler', () => { sandbox.stub(annotator.annotatedElement, 'addEventListener'); sandbox.stub(annotator.annotatedElement, 'removeEventListener'); @@ -488,7 +488,11 @@ describe('lib/annotations/Annotator', () => { annotator.bindPointModeListeners(); expect(annotator.pointClickHandler.bind).to.be.called; expect(annotator.annotatedElement.addEventListener).to.be.calledWith( - 'click', + 'mousedown', + annotator.pointClickHandler + ); + expect(annotator.annotatedElement.addEventListener).to.be.calledWith( + 'touchstart', annotator.pointClickHandler ); }); @@ -503,7 +507,11 @@ describe('lib/annotations/Annotator', () => { annotator.unbindModeListeners(); expect(annotator.pointClickHandler.bind).to.be.called; expect(annotator.annotatedElement.removeEventListener).to.be.calledWith( - 'click', + 'mousedown', + annotator.pointClickHandler + ); + expect(annotator.annotatedElement.removeEventListener).to.be.calledWith( + 'touchstart', annotator.pointClickHandler ); }); @@ -542,7 +550,8 @@ describe('lib/annotations/Annotator', () => { describe('pointClickHandler()', () => { const event = { - stopPropagation: () => {} + stopPropagation: () => {}, + preventDefault: () => {} }; beforeEach(() => { @@ -603,7 +612,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('bindDrawModeListeners', () => { + describe('bindDrawModeListeners()', () => { it('should do nothing if neither a thread nor a post button is not provided', () => { const drawingThread = { handleStart: () => {}, @@ -661,7 +670,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('addToThreadMap', () => { + describe('addToThreadMap()', () => { it('should add valid threads to the thread map', () => { stubs.thread.location = { page: 2 }; stubs.thread2.location = { page: 3 }; @@ -684,7 +693,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('isInPointMode', () => { + describe('isInPointMode()', () => { it('should return whether the annotator is in point mode or not', () => { annotator.annotatedElement.classList.add(CLASS_ANNOTATION_POINT_MODE); expect(annotator.isInPointMode()).to.be.true; @@ -694,7 +703,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('isInDrawMode', () => { + describe('isInDrawMode()', () => { it('should return whether the annotator is in draw mode or not', () => { annotator.annotatedElement.classList.add(CLASS_ANNOTATION_DRAW_MODE); expect(annotator.isInDrawMode()).to.be.true; @@ -704,7 +713,7 @@ describe('lib/annotations/Annotator', () => { }); }); - describe('destroyPendingThreads', () => { + describe('destroyPendingThreads()', () => { beforeEach(() => { stubs.thread = { location: { page: 2 }, diff --git a/src/lib/annotations/doc/DocAnnotator.js b/src/lib/annotations/doc/DocAnnotator.js index c8f10ab51..bb4495947 100644 --- a/src/lib/annotations/doc/DocAnnotator.js +++ b/src/lib/annotations/doc/DocAnnotator.js @@ -174,16 +174,24 @@ class DocAnnotator extends Annotator { let location = null; const zoomScale = annotatorUtil.getScale(this.annotatedElement); - if (annotationType === TYPES.point) { - // If there is a selection, ignore - if (docAnnotatorUtil.isSelectionPresent()) { + let clientEvent = event; + if (this.isMobile) { + if (!event.targetTouches || event.targetTouches.length === 0) { return location; } + clientEvent = event.targetTouches[0]; + } - // If click isn't on a page, ignore - const eventTarget = event.target; - const { pageEl, page } = annotatorUtil.getPageInfo(eventTarget); - if (!pageEl) { + // If click isn't on a page, ignore + const eventTarget = clientEvent.target; + const { pageEl, page } = annotatorUtil.getPageInfo(eventTarget); + if (!pageEl) { + return location; + } + + if (annotationType === TYPES.point) { + // If there is a selection, ignore + if (docAnnotatorUtil.isSelectionPresent()) { return location; } @@ -198,15 +206,23 @@ class DocAnnotator extends Annotator { const pageWidth = pageDimensions.width; const pageHeight = pageDimensions.height - PAGE_PADDING_TOP - PAGE_PADDING_BOTTOM; const browserCoordinates = [ - event.clientX - pageDimensions.left, - event.clientY - pageDimensions.top - PAGE_PADDING_TOP + clientEvent.clientX - pageDimensions.left, + clientEvent.clientY - pageDimensions.top - PAGE_PADDING_TOP ]; + let [x, y] = browserCoordinates; + + // Do not create annotation if event doesn't have coordinates + if (isNaN(x) || isNaN(y)) { + this.emit('annotationerror', __('annotations_create_error')); + return location; + } + const pdfCoordinates = docAnnotatorUtil.convertDOMSpaceToPDFSpace( browserCoordinates, pageHeight, zoomScale ); - const [x, y] = pdfCoordinates; + [x, y] = pdfCoordinates; // We save the dimensions of the annotated element scaled to 100% // so we can compare to the annotated element during render time @@ -222,9 +238,6 @@ class DocAnnotator extends Annotator { return location; } - // Get correct page - const { pageEl, page } = annotatorUtil.getPageInfo(event.target); - // Use highlight module to calculate quad points const { highlightEls } = docAnnotatorUtil.getHighlightAndHighlightEls(this.highlighter, pageEl); diff --git a/src/lib/annotations/doc/__tests__/DocAnnotator-test.js b/src/lib/annotations/doc/__tests__/DocAnnotator-test.js index d3633e807..933df78e0 100644 --- a/src/lib/annotations/doc/__tests__/DocAnnotator-test.js +++ b/src/lib/annotations/doc/__tests__/DocAnnotator-test.js @@ -69,13 +69,23 @@ describe('lib/annotations/doc/DocAnnotator', () => { let page = 3; beforeEach(() => { + stubs.event = { + clientX: x, + clientY: y, + target: annotator.annotatedEl + }; + annotator.isMobile = false; + stubs.selection = sandbox.stub(docAnnotatorUtil, 'isSelectionPresent').returns(true); stubs.pageEl = { getBoundingClientRect: sandbox.stub().returns({ width: dimensions.x, - height: dimensions.y + 30 // 15px padding top and bottom + height: dimensions.y + 30, // 15px padding top and bottom, + top: 0, + left: 0 }) }; + stubs.getPageInfo.returns({ pageEl: stubs.pageEl, page }); stubs.getHighlights = sandbox.stub(docAnnotatorUtil, 'getHighlightAndHighlightEls').returns({ highlight: {}, @@ -93,15 +103,45 @@ describe('lib/annotations/doc/DocAnnotator', () => { stubs.restoreSel = sandbox.stub(rangy, 'restoreSelection'); }); + it('should not return a location if no touch event is available and user is on a mobile device', () => { + annotator.isMobile = true; + expect(annotator.getLocationFromEvent({ targetTouches: [] }, TYPES.point)).to.be.null; + }); + + it('should replace event with mobile touch event if user is on a mobile device', () => { + annotator.isMobile = true; + stubs.event = { + targetTouches: [{ + clientX: x, + clientY: y, + target: annotator.annotatedEl + }] + }; + annotator.getLocationFromEvent(stubs.event, TYPES.point); + }); + + it('should not return a location if there are no touch event and the user is on a mobile device', () => { + annotator.isMobile = true; + expect(annotator.getLocationFromEvent(stubs.event, TYPES.point)).to.be.null; + + stubs.event = { + targetTouches: [{ + target: annotator.annotatedEl + }] + }; + annotator + expect(annotator.getLocationFromEvent(stubs.event, TYPES.point)).to.be.null; + }); + + it('should not return a location if click isn\'t on page', () => { + stubs.selection.returns(false); + stubs.getPageInfo.returns({ pageEl: null, page: -1 }); + expect(annotator.getLocationFromEvent(stubs.event, TYPES.point)).to.be.null; + }); + describe(TYPES.point, () => { it('should not return a location if there is a selection present', () => { - expect(annotator.getLocationFromEvent({}, TYPES.point)).to.be.null; - }); - - it('should not return a location if click isn\'t on page', () => { - stubs.selection.returns(false); - stubs.getPageInfo.returns({ pageEl: null, page: -1 }); - expect(annotator.getLocationFromEvent({}, TYPES.point)).to.be.null; + expect(annotator.getLocationFromEvent(stubs.event, TYPES.point)).to.be.null; }); it('should not return a location if click is on dialog', () => { @@ -110,18 +150,24 @@ describe('lib/annotations/doc/DocAnnotator', () => { pageEl: document.querySelector('.annotated-element'), page: 1 }); + expect(annotator.getLocationFromEvent(stubs.event, TYPES.point)).to.be.null; + }); + + it('should not return a location if click event does not have coordinates', () => { + stubs.selection.returns(false); + stubs.findClosest.returns('not-a-dialog'); + sandbox.stub(docAnnotatorUtil, 'convertDOMSpaceToPDFSpace'); + expect(annotator.getLocationFromEvent({}, TYPES.point)).to.be.null; + expect(docAnnotatorUtil.convertDOMSpaceToPDFSpace).to.not.be.called; }); it('should return a valid point location if click is valid', () => { - page = 2; - stubs.selection.returns(false); - stubs.getPageInfo.returns({ pageEl: stubs.pageEl, page }); stubs.findClosest.returns('not-a-dialog'); sandbox.stub(docAnnotatorUtil, 'convertDOMSpaceToPDFSpace').returns([x, y]); - const location = annotator.getLocationFromEvent({}, TYPES.point); + const location = annotator.getLocationFromEvent(stubs.event, TYPES.point); expect(location).to.deep.equal({ x, y, page, dimensions }); }); }); @@ -133,31 +179,29 @@ describe('lib/annotations/doc/DocAnnotator', () => { }); it('should not return a location if there is no selection present', () => { - expect(annotator.getLocationFromEvent({}, TYPES.highlight)).to.be.null; + expect(annotator.getLocationFromEvent(stubs.event, TYPES.highlight)).to.be.null; }); it('should infer page from selection if it cannot be inferred from event', () => { annotator.highlighter.highlights = [{}, {}]; stubs.getPageInfo.returns({ pageEl: null, page: -1 }); - annotator.getLocationFromEvent({}, TYPES.highlight); + annotator.getLocationFromEvent(stubs.event, TYPES.highlight); expect(stubs.getPageInfo).to.be.called; }); it('should not return a valid highlight location if no highlights exist', () => { - stubs.getPageInfo.returns({ pageEl: stubs.pageEl, page }); - expect(annotator.getLocationFromEvent({}, TYPES.highlight)).to.deep.equal(null); + expect(annotator.getLocationFromEvent(stubs.event, TYPES.highlight)).to.deep.equal(null); }); it('should return a valid highlight location if selection is valid', () => { annotator.highlighter.highlights = [{}]; - stubs.getPageInfo.returns({ pageEl: stubs.pageEl, page }); stubs.points.onFirstCall().returns(quadPoints[0]); stubs.points.onSecondCall().returns(quadPoints[1]); stubs.getHighlights.returns({ highlight: {}, highlightEls: [{}, {}] }); - const location = annotator.getLocationFromEvent({}, TYPES.highlight); + const location = annotator.getLocationFromEvent(stubs.event, TYPES.highlight); expect(location).to.deep.equal({ page, quadPoints, dimensions }); }); }); @@ -169,31 +213,29 @@ describe('lib/annotations/doc/DocAnnotator', () => { }); it('should not return a location if there is no selection present', () => { - expect(annotator.getLocationFromEvent({}, TYPES.highlight_comment)).to.be.null; + expect(annotator.getLocationFromEvent(stubs.event, TYPES.highlight_comment)).to.be.null; }); it('should infer page from selection if it cannot be inferred from event', () => { annotator.highlighter.highlights = [{}, {}]; stubs.getPageInfo.returns({ pageEl: null, page: -1 }); - annotator.getLocationFromEvent({}, TYPES.highlight_comment); + annotator.getLocationFromEvent(stubs.event, TYPES.highlight_comment); expect(stubs.getPageInfo).to.be.called; }); it('should not return a valid highlight location if no highlights exist', () => { annotator.highlighter.highlights = [{}]; - stubs.getPageInfo.returns({ pageEl: stubs.pageEl, page }); - expect(annotator.getLocationFromEvent({}, TYPES.highlight_comment)).to.deep.equal(null); + expect(annotator.getLocationFromEvent(stubs.event, TYPES.highlight_comment)).to.deep.equal(null); }); it('should return a valid highlight location if selection is valid', () => { annotator.highlighter.highlights = [{}]; - stubs.getPageInfo.returns({ pageEl: stubs.pageEl, page }); stubs.points.onFirstCall().returns(quadPoints[0]); stubs.points.onSecondCall().returns(quadPoints[1]); stubs.getHighlights.returns({ highlight: {}, highlightEls: [{}, {}] }); - const location = annotator.getLocationFromEvent({}, TYPES.highlight_comment); + const location = annotator.getLocationFromEvent(stubs.event, TYPES.highlight_comment); expect(location).to.deep.equal({ page, quadPoints, dimensions }); }); }); diff --git a/src/lib/annotations/image/ImageAnnotator.js b/src/lib/annotations/image/ImageAnnotator.js index 2668b454c..e2904004e 100644 --- a/src/lib/annotations/image/ImageAnnotator.js +++ b/src/lib/annotations/image/ImageAnnotator.js @@ -38,8 +38,16 @@ class ImageAnnotator extends Annotator { getLocationFromEvent(event) { let location = null; + let clientEvent = event; + if (this.isMobile) { + if (!event.targetTouches || event.targetTouches.length === 0) { + return location; + } + clientEvent = event.targetTouches[0]; + } + // Get image tag inside viewer - const imageEl = event.target; + const imageEl = clientEvent.target; if (imageEl.nodeName.toLowerCase() !== IMAGE_NODE_NAME) { return location; } @@ -49,7 +57,13 @@ class ImageAnnotator extends Annotator { // Location based only on image position const imageDimensions = imageEl.getBoundingClientRect(); - let [x, y] = [event.clientX - imageDimensions.left, event.clientY - imageDimensions.top]; + let [x, y] = [clientEvent.clientX - imageDimensions.left, clientEvent.clientY - imageDimensions.top]; + + // Do not create annotation if event doesn't have coordinates + if (isNaN(x) || isNaN(y)) { + this.emit('annotationerror', __('annotations_create_error')); + return location; + } // Scale location coordinates according to natural image size const scale = annotatorUtil.getScale(this.annotatedElement); diff --git a/src/lib/annotations/image/__tests__/ImageAnnotator-test.js b/src/lib/annotations/image/__tests__/ImageAnnotator-test.js index 43835c322..5323bbd4f 100644 --- a/src/lib/annotations/image/__tests__/ImageAnnotator-test.js +++ b/src/lib/annotations/image/__tests__/ImageAnnotator-test.js @@ -44,6 +44,27 @@ describe('lib/annotations/image/ImageAnnotator', () => { }); describe('getLocationFromEvent()', () => { + let event = {}; + let imageEl = {}; + const x = 100; + const y = 200; + const dimensions = { + x: 100, + y: 200 + }; + + beforeEach(() => { + annotator.isMobile = false; + imageEl = annotator.annotatedElement.querySelector('img'); + event = { + targetTouches: [{ + clientX: x, + clientY: y, + target: imageEl + }] + }; + }); + it('should not return a location if image isn\'t inside viewer', () => { annotator.annotatedElement = document.createElement('div'); const location = annotator.getLocationFromEvent({ @@ -54,18 +75,45 @@ describe('lib/annotations/image/ImageAnnotator', () => { expect(location).to.be.null; }); - it('should return a valid point location if click is valid', () => { - const x = 100; - const y = 200; - const dimensions = { - x: 100, - y: 200 + it('should not return a location if no touch event is available and user is on a mobile device', () => { + annotator.isMobile = true; + expect(annotator.getLocationFromEvent({ targetTouches: [] })).to.be.null; + }); + + it('should replace event with mobile touch event if user is on a mobile device', () => { + annotator.isMobile = true; + annotator.getLocationFromEvent(event); + }); + + it('should not return a location if there are no touch event and the user is on a mobile device', () => { + annotator.isMobile = true; + const location = annotator.getLocationFromEvent({ + target: { + nodeName: 'not-annotated' + } + }); + expect(location).to.be.null; + + event = { + targetTouches: [{ + target: imageEl + }] }; - const imageEl = annotator.annotatedElement.querySelector('img'); + expect(annotator.getLocationFromEvent(event)).to.be.null; + }); + + it('should not return a location if click event does not have coordinates', () => { + event = { target: imageEl }; + expect(annotator.getLocationFromEvent(event)).to.be.null; + }); + + it('should return a valid point location if click is valid', () => { sandbox.stub(annotatorUtil, 'getScale').returns(1); sandbox.stub(imageAnnotatorUtil, 'getLocationWithoutRotation').returns([x, y]); const location = annotator.getLocationFromEvent({ + clientX: x, + clientY: y, target: imageEl }); expect(location).to.deep.equal({ diff --git a/src/lib/viewers/doc/__tests__/PresentationViewer-test.js b/src/lib/viewers/doc/__tests__/PresentationViewer-test.js index 9c0207d4d..e90ad2e7f 100644 --- a/src/lib/viewers/doc/__tests__/PresentationViewer-test.js +++ b/src/lib/viewers/doc/__tests__/PresentationViewer-test.js @@ -439,9 +439,6 @@ describe('lib/viewers/doc/PresentationViewer', () => { stubs.nextPage = sandbox.stub(presentation, 'nextPage'); stubs.previousPage = sandbox.stub(presentation, 'previousPage'); stubs.checkOverflow = sandbox.stub(presentation, 'checkOverflow').returns(false); - presentation.annotator = { - isInDialogOnPage: sandbox.stub().returns(false) - }; presentation.event = { deltaY: 5, deltaX: -0 diff --git a/src/lib/viewers/image/ImageBaseViewer.js b/src/lib/viewers/image/ImageBaseViewer.js index d0d9fa609..bd411cd3f 100644 --- a/src/lib/viewers/image/ImageBaseViewer.js +++ b/src/lib/viewers/image/ImageBaseViewer.js @@ -285,11 +285,6 @@ class ImageBaseViewer extends BaseViewer { * @return {void} */ handleMouseUp(event) { - // Ignore zoom/pan mouse events if in annotation mode - if (this.annotator && this.annotator.isInPointMode()) { - return; - } - const { button, ctrlKey, metaKey } = event; // If this is not a left click, then ignore @@ -344,22 +339,6 @@ class ImageBaseViewer extends BaseViewer { } } - /** - * @inheritdoc - */ - getAnnotationModeClickHandler(mode) { - if (!mode || !this.isAnnotatable(mode)) { - return null; - } - - const eventName = `toggle${mode}annotationmode`; - return () => { - this.imageEl.classList.remove(CSS_CLASS_ZOOMABLE); - this.imageEl.classList.remove(CSS_CLASS_PANNABLE); - this.emit(eventName); - }; - } - //-------------------------------------------------------------------------- // Abstract //-------------------------------------------------------------------------- diff --git a/src/lib/viewers/image/ImageViewer.js b/src/lib/viewers/image/ImageViewer.js index 1d3f510fc..43a091d16 100644 --- a/src/lib/viewers/image/ImageViewer.js +++ b/src/lib/viewers/image/ImageViewer.js @@ -77,7 +77,7 @@ class ImageViewer extends ImageBaseViewer { * @return {void} */ updatePannability() { - if (!this.imageEl || (this.annotator && this.annotator.isInPointMode())) { + if (!this.imageEl) { return; } diff --git a/src/lib/viewers/image/__tests__/ImageBaseViewer-test.js b/src/lib/viewers/image/__tests__/ImageBaseViewer-test.js index ce04b7272..e0954091e 100644 --- a/src/lib/viewers/image/__tests__/ImageBaseViewer-test.js +++ b/src/lib/viewers/image/__tests__/ImageBaseViewer-test.js @@ -475,38 +475,6 @@ describe('lib/viewers/image/ImageBaseViewer', () => { }); }); - describe('getAnnotationModeClickHandler()', () => { - beforeEach(() => { - stubs.isAnnotatable = sandbox.stub(imageBase, 'isAnnotatable').returns(false); - }); - - it('should return null if you cannot annotate', () => { - const handler = imageBase.getAnnotationModeClickHandler('point'); - expect(stubs.isAnnotatable).to.be.called; - expect(handler).to.equal(null); - }); - - it('should return the toggle point mode handler', () => { - stubs.isAnnotatable.returns(true); - stubs.emitter = sandbox.stub(imageBase, 'emit'); - imageBase.annotator = { - togglePointAnnotationHandler: () => {} - }; - imageBase.imageEl.classList.add(CSS_CLASS_PANNABLE); - imageBase.imageEl.classList.add(CSS_CLASS_ZOOMABLE); - - const handler = imageBase.getAnnotationModeClickHandler('point'); - expect(stubs.isAnnotatable).to.be.called; - expect(handler).to.be.a('function'); - - handler(event); - - expect(imageBase.imageEl).to.not.have.class(CSS_CLASS_PANNABLE); - expect(imageBase.imageEl).to.not.have.class(CSS_CLASS_ZOOMABLE); - expect(imageBase.emit).to.have.been.calledWith('togglepointannotationmode'); - }); - }); - describe('finishLoading()', () => { beforeEach(() => { imageBase.loaded = false; diff --git a/src/lib/viewers/image/__tests__/ImageViewer-test.js b/src/lib/viewers/image/__tests__/ImageViewer-test.js index c34e9fa78..c415733c7 100644 --- a/src/lib/viewers/image/__tests__/ImageViewer-test.js +++ b/src/lib/viewers/image/__tests__/ImageViewer-test.js @@ -32,9 +32,6 @@ describe('lib/viewers/image/ImageViewer', () => { id: '1', file_version: { id: '1' - }, - permissions: { - can_annotate: true } }, viewer: { @@ -139,22 +136,7 @@ describe('lib/viewers/image/ImageViewer', () => { image.imageEl = stubs.imageEl; }); - it('should ignore if in point annotation mode', () => { - image.annotator = { - isInPointMode: sandbox.stub().returns(true) - }; - - image.updatePannability(); - - expect(image.annotator.isInPointMode).to.be.called; - expect(image.didPan).to.have.been.true; - expect(stubs.cursor).to.not.be.called; - }); - it('should set pannability to true if rotated image is pannable', () => { - image.annotator = { - isInPointMode: sandbox.stub().returns(false) - }; sandbox.stub(image, 'isRotated').returns(true); image.imageEl.style.height = '50px'; @@ -163,15 +145,11 @@ describe('lib/viewers/image/ImageViewer', () => { image.wrapperEl.style.width = '50px'; image.updatePannability(); - expect(image.annotator.isInPointMode).to.be.called; expect(image.didPan).to.have.been.false; expect(stubs.cursor).to.be.called; }); it('should set pannability to false if rotated image is not pannable', () => { - image.annotator = { - isInPointMode: sandbox.stub().returns(false) - }; sandbox.stub(image, 'isRotated').returns(true); image.imageEl.style.height = '10px'; @@ -181,15 +159,11 @@ describe('lib/viewers/image/ImageViewer', () => { image.updatePannability(); - expect(image.annotator.isInPointMode).to.be.called; expect(image.didPan).to.have.been.false; expect(stubs.cursor).to.be.called; }); it('should set pannability to true if non-rotated image is pannable', () => { - image.annotator = { - isInPointMode: sandbox.stub().returns(false) - }; sandbox.stub(image, 'isRotated').returns(false); image.imageEl.style.height = '50px'; @@ -199,15 +173,11 @@ describe('lib/viewers/image/ImageViewer', () => { image.updatePannability(); - expect(image.annotator.isInPointMode).to.be.called; expect(image.didPan).to.have.been.false; expect(stubs.cursor).to.be.called; }); it('should set pannability to false if non-rotated image is not pannable', () => { - image.annotator = { - isInPointMode: sandbox.stub().returns(false) - }; sandbox.stub(image, 'isRotated').returns(false); image.imageEl.style.height = '10px'; @@ -217,7 +187,6 @@ describe('lib/viewers/image/ImageViewer', () => { image.updatePannability(); - expect(image.annotator.isInPointMode).to.be.called; expect(image.didPan).to.have.been.false; expect(stubs.cursor).to.be.called; }); @@ -227,7 +196,6 @@ describe('lib/viewers/image/ImageViewer', () => { beforeEach(() => { stubs.emit = sandbox.stub(image, 'emit'); stubs.orientChange = sandbox.stub(image, 'handleOrientationChange'); - image.annotator = {}; stubs.scale = sandbox.stub(image, 'setScale'); image.currentRotationAngle = 0; }); @@ -241,12 +209,6 @@ describe('lib/viewers/image/ImageViewer', () => { expect(stubs.emit).to.be.calledWith('rotate'); expect(stubs.orientChange).to.be.called; }); - - it('should re-render annotations if annotator is initialized', () => { - image.rotateLeft(); - - expect(stubs.scale).to.be.called; - }); }); describe('zoom()', () => { @@ -324,16 +286,6 @@ describe('lib/viewers/image/ImageViewer', () => { expect(stubs.adjustZoom).to.be.called; }); - it('should scale annotations if annotator exists', () => { - image.annotator = {}; - sandbox.stub(image, 'setScale'); - - image.load(imageUrl).catch(() => {}); - - image.zoomIn(); - expect(image.setScale).to.be.called; - }); - it('should reset dimensions and adjust padding when called with reset', () => { image.imageEl.style.width = '10px'; image.imageEl.style.height = '20px'; @@ -364,14 +316,10 @@ describe('lib/viewers/image/ImageViewer', () => { describe('loadUI()', () => { it('should load UI & controls for zoom', () => { - image.boxAnnotationsLoaded = false; - image.annotator = null; - image.loadUI(); expect(image.controls).to.not.be.undefined; expect(image.controls.buttonRefs.length).to.equal(5); - expect(image.boxAnnotationsLoaded).to.be.false; }); }); @@ -493,20 +441,10 @@ describe('lib/viewers/image/ImageViewer', () => { describe('handleMouseUp()', () => { beforeEach(() => { stubs.pan = sandbox.stub(image, 'stopPanning'); - image.annotator = { - isInPointMode: sandbox.stub().returns(false) - }; - stubs.point = image.annotator.isInPointMode; stubs.zoom = sandbox.stub(image, 'zoom'); image.isPanning = false; }); - it('should do nothing if in point annotation mode', () => { - stubs.point.returns(true); - image.handleMouseUp(); - expect(stubs.zoom).to.not.be.called; - }); - it('should do nothing if incorrect click type', () => { const event = { button: 3, @@ -583,31 +521,4 @@ describe('lib/viewers/image/ImageViewer', () => { }); }); }); - - describe('getPointModeClickHandler()', () => { - it('should do nothing if not annotatable', () => { - sandbox.stub(image, 'isAnnotatable').returns(false); - const handler = image.getAnnotationModeClickHandler('point'); - expect(handler).to.be.null; - }); - - it('should return event listener', () => { - const event = {}; - image.annotator = { - togglePointAnnotationHandler: () => {} - }; - sandbox.stub(image, 'emit'); - image.imageEl.classList.add(CSS_CLASS_ZOOMABLE); - image.imageEl.classList.add(CSS_CLASS_PANNABLE); - sandbox.stub(image, 'isAnnotatable').returns(true); - - const handler = image.getAnnotationModeClickHandler('point'); - expect(handler).to.be.a('function'); - - handler(event); - expect(image.imageEl).to.not.have.class(CSS_CLASS_ZOOMABLE); - expect(image.imageEl).to.not.have.class(CSS_CLASS_PANNABLE); - expect(image.emit).to.have.been.calledWith('togglepointannotationmode'); - }); - }); });