Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Fixes issues with adding annotations on tablets #186

Merged
merged 2 commits into from
Jun 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions src/lib/annotations/doc/DocHighlightDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ const PAGE_PADDING_TOP = 15;
}

// Reposition dialog
this.position();
if (!this.isMobile) {
this.position();
}
}

//--------------------------------------------------------------------------
Expand Down Expand Up @@ -255,10 +257,12 @@ const PAGE_PADDING_TOP = 15;
*/
bindDOMListeners() {
this.element.addEventListener('mousedown', this.mousedownHandler);
this.element.addEventListener('mouseup', this.mouseupHandler);
this.element.addEventListener('keydown', this.keydownHandler);
this.element.addEventListener('mouseenter', this.mouseenterHandler);
this.element.addEventListener('mouseleave', this.mouseleaveHandler);

if (!this.isMobile) {
this.element.addEventListener('mouseenter', this.mouseenterHandler);
this.element.addEventListener('mouseleave', this.mouseleaveHandler);
}
}

/**
Expand All @@ -270,10 +274,12 @@ const PAGE_PADDING_TOP = 15;
*/
unbindDOMListeners() {
this.element.removeEventListener('mousedown', this.mousedownHandler);
this.element.removeEventListener('mouseup', this.mouseupHandler);
this.element.removeEventListener('keydown', this.keydownHandler);
this.element.removeEventListener('mouseenter', this.mouseenterHandler);
this.element.removeEventListener('mouseleave', this.mouseleaveHandler);

if (!this.isMobile) {
this.element.removeEventListener('mouseenter', this.mouseenterHandler);
this.element.removeEventListener('mouseleave', this.mouseleaveHandler);
}
}

/**
Expand Down
10 changes: 5 additions & 5 deletions src/lib/annotations/doc/DocHighlightThread.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,11 +360,11 @@ const HOVER_TIMEOUT_MS = 75;
* @return {void}
*/
unbindCustomListenersOnDialog() {
this.removeAllListeners('annotationdraw');
this.removeAllListeners('annotationcommentpending');
this.removeAllListeners('annotationcreate');
this.removeAllListeners('annotationcancel');
this.removeAllListeners('annotationdelete');
this.dialog.removeAllListeners('annotationdraw');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

this.dialog.removeAllListeners('annotationcommentpending');
this.dialog.removeAllListeners('annotationcreate');
this.dialog.removeAllListeners('annotationcancel');
this.dialog.removeAllListeners('annotationdelete');
}

//--------------------------------------------------------------------------
Expand Down
126 changes: 126 additions & 0 deletions src/lib/annotations/doc/__tests__/DocHighlightDialog-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import AnnotationDialog from '../../AnnotationDialog';
import * as annotatorUtil from '../../annotatorUtil';
import * as docAnnotatorUtil from '../docAnnotatorUtil';
import { CLASS_HIDDEN } from '../../../constants';
import * as util from '../../../util';
import * as constants from '../../annotationConstants';

let dialog;
Expand Down Expand Up @@ -190,6 +191,19 @@ describe('lib/annotations/doc/DocHighlightDialog', () => {
expect(commentTextEl.classList.contains(CLASS_HIDDEN)).to.be.true;
expect(replyTextEl.classList.contains(CLASS_HIDDEN)).to.be.false;
});

it('should reposition the dialog if using a desktop browser', () => {
sandbox.stub(dialog, 'position');
dialog.toggleHighlightCommentsReply();
expect(dialog.position).to.be.called;
});

it('should not reposition the dialog on a mobile device', () => {
sandbox.stub(dialog, 'position');
dialog.isMobile = true;
dialog.toggleHighlightCommentsReply();
expect(dialog.position).to.not.be.called;
});
});

describe('setup()', () => {
Expand Down Expand Up @@ -297,6 +311,110 @@ describe('lib/annotations/doc/DocHighlightDialog', () => {
});
});

describe('bindDOMListeners()', () => {
it('should bind DOM listeners', () => {
stubs.add = sandbox.stub(dialog.element, 'addEventListener');

dialog.bindDOMListeners();
expect(stubs.add).to.be.calledWith('mousedown', sinon.match.func);
expect(stubs.add).to.be.calledWith('keydown', sinon.match.func);
expect(stubs.add).to.be.calledWith('mouseleave', sinon.match.func);
expect(stubs.add).to.be.calledWith('mouseenter', sinon.match.func);
});

it('should not bind mouseenter/leave events for mobile browsers', () => {
stubs.add = sandbox.stub(dialog.element, 'addEventListener');
dialog.isMobile = true;

dialog.bindDOMListeners();
expect(stubs.add).to.be.calledWith('mousedown', sinon.match.func);
expect(stubs.add).to.be.calledWith('keydown', sinon.match.func);
expect(stubs.add).to.not.be.calledWith('mouseenter', sinon.match.func);
expect(stubs.add).to.not.be.calledWith('mouseleave', sinon.match.func);
});
});

describe('unbindDOMListeners()', () => {
it('should unbind DOM listeners', () => {
stubs.remove = sandbox.stub(dialog.element, 'removeEventListener');

dialog.unbindDOMListeners();
expect(stubs.remove).to.be.calledWith('mousedown', sinon.match.func);
expect(stubs.remove).to.be.calledWith('keydown', sinon.match.func);
expect(stubs.remove).to.be.calledWith('mouseleave', sinon.match.func);
expect(stubs.remove).to.be.calledWith('mouseenter', sinon.match.func);
});

it('should not unbind mouseenter/leave events for mobile browsers', () => {
stubs.remove = sandbox.stub(dialog.element, 'removeEventListener');
dialog.isMobile = true;

dialog.unbindDOMListeners();
expect(stubs.remove).to.be.calledWith('mousedown', sinon.match.func);
expect(stubs.remove).to.be.calledWith('keydown', sinon.match.func);
expect(stubs.remove).to.not.be.calledWith('mouseenter', sinon.match.func);
expect(stubs.remove).to.not.be.calledWith('mouseleave', sinon.match.func);
});
});

describe('keydownHandler()', () => {
const event = {
stopPropagation: sandbox.stub()
};

it('should call mousedownHandler if \'Enter\' is pressed', () => {
sandbox.stub(util, 'decodeKeydown').returns('Enter');
sandbox.stub(dialog, 'mousedownHandler');
dialog.keydownHandler(event);
expect(dialog.mousedownHandler).to.be.called;
});

it('should not call mousedownHandler if a key other than \'Enter\' is pressed', () => {
sandbox.stub(util, 'decodeKeydown').returns('Delete');
sandbox.stub(dialog, 'mousedownHandler');
dialog.keydownHandler(event);
expect(dialog.mousedownHandler).to.not.be.called;
});
});

describe('mousedownHandler()', () => {
const event = {
stopPropagation: sandbox.stub(),
preventDefault: sandbox.stub()
};

beforeEach(() => {
stubs.dataType = sandbox.stub(annotatorUtil, 'findClosestDataType');
sandbox.stub(dialog, 'toggleHighlight');
sandbox.stub(dialog, 'toggleHighlightCommentsReply');
sandbox.stub(dialog, 'toggleHighlightDialogs');
sandbox.stub(dialog, 'focusAnnotationsTextArea');
});

it('should create/remove a highlight when the \'highlight-btn\' is pressed', () => {
stubs.dataType.returns('highlight-btn');
dialog.mousedownHandler(event);
expect(stubs.emit).to.be.calledWith('annotationdraw');
expect(dialog.toggleHighlight).to.be.called;
});

it('should create highlight when the \'add-highlight-comment-btn\' is pressed', () => {
stubs.dataType.returns('add-highlight-comment-btn');
dialog.mousedownHandler(event);
expect(stubs.emit).to.be.calledWith('annotationdraw');
expect(dialog.toggleHighlightCommentsReply).to.be.called;
expect(dialog.toggleHighlightDialogs).to.be.called;
expect(event.preventDefault).to.be.called;
expect(dialog.focusAnnotationsTextArea).to.be.called;
});

it('should not create a highlight when any other button is pressed', () => {
stubs.dataType.returns('anything-else');
dialog.mousedownHandler(event);
expect(stubs.emit).to.not.be.calledWith('annotationdraw');
});
});

describe('toggleHighlightIcon()', () => {
it('should display active highlight icon when highlight is active', () => {
const addHighlightBtn = dialog.element.querySelector('.bp-add-highlight-btn');
Expand Down Expand Up @@ -399,4 +517,12 @@ describe('lib/annotations/doc/DocHighlightDialog', () => {
expect(highlight.dataset.annotationId).to.equal('1');
});
});

describe('generateHighlightDialogEl()', () => {
it('should return a highlight annotation dialog DOM element', () => {
const highlightEl = dialog.generateHighlightDialogEl();
const highlightBtnEl = highlightEl.querySelector('.bp-annotations-highlight-btns');
expect(highlightBtnEl).to.not.be.null;
});
});
});
29 changes: 29 additions & 0 deletions src/lib/annotations/doc/__tests__/DocHighlightThread-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,17 @@ describe('lib/annotations/doc/DocHighlightThread', () => {
expect(highlightThread.showDialog).to.be.called;
expect(highlightThread.draw).to.be.calledWith(constants.HIGHLIGHT_ACTIVE_FILL_STYLE);
});

it('should do nothing if state is invalid', () => {
sandbox.stub(highlightThread, 'showDialog');
sandbox.stub(highlightThread, 'draw');

highlightThread.state = 'invalid';
highlightThread.show();

expect(highlightThread.showDialog).to.not.be.called;
expect(highlightThread.draw).to.not.be.called;
});
});

describe('createDialog()', () => {
Expand Down Expand Up @@ -463,6 +474,24 @@ describe('lib/annotations/doc/DocHighlightThread', () => {
});
});

describe('unbindCustomListenersOnDialog()', () => {
it('should unbind custom listeners on dialog', () => {
highlightThread.dialog = {
removeAllListeners: () => {}
};

const removeAllListenersStub = sandbox.stub(highlightThread.dialog, 'removeAllListeners');

highlightThread.unbindCustomListenersOnDialog();

expect(removeAllListenersStub).to.be.calledWith('annotationdraw');
expect(removeAllListenersStub).to.be.calledWith('annotationcommentpending');
expect(removeAllListenersStub).to.be.calledWith('annotationcreate');
expect(removeAllListenersStub).to.be.calledWith('annotationcancel');
expect(removeAllListenersStub).to.be.calledWith('annotationdelete');
});
});

describe('draw()', () => {
it('should not draw if no context exists', () => {
sandbox.stub(highlightThread, 'getPageEl');
Expand Down