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: Unregister drawing on mode cancel #288

Merged
merged 6 commits into from Nov 15, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/controllers/AnnotationModeController.js
Expand Up @@ -599,6 +599,17 @@ class AnnotationModeController extends EventEmitter {
Object.keys(this.annotations).forEach((pageNum) => this.renderPage(pageNum));
}

/**
* Unregisters and destroys the specified thread
*
* @param {AnnotationThread} thread thread to destroy
* @return {void}
*/
destroyThread(thread: AnnotationThread) {
pramodsum marked this conversation as resolved.
Show resolved Hide resolved
this.unregisterThread(thread);
thread.destroy();
}

/**
* Renders annotations from memory for a specified page.
*
Expand All @@ -614,8 +625,7 @@ class AnnotationModeController extends EventEmitter {
pageThreads.forEach((thread, index) => {
// Destroy any pending threads that may exist on re-render
if (thread.state === STATES.pending || thread.id === this.pendingThreadID) {
this.unregisterThread(thread);
thread.destroy();
this.destroyThread(thread);
return;
}

Expand Down Expand Up @@ -645,10 +655,9 @@ class AnnotationModeController extends EventEmitter {
const pageThreads = this.annotations[pageNum].all() || [];
pageThreads.forEach((thread) => {
if (thread.state === STATES.pending || thread.id === this.pendingThreadID) {
this.unregisterThread(thread);
this.destroyThread(thread);
hadPendingThreads = true;
this.pendingThreadID = null;
thread.destroy();
}
});
});
Expand Down
8 changes: 4 additions & 4 deletions src/controllers/DrawingModeController.js
Expand Up @@ -93,7 +93,7 @@ class DrawingModeController extends AnnotationModeController {
*/
cancelDrawing(): void {
if (this.currentThread) {
this.currentThread.destroy();
this.destroyThread(this.currentThread);
}

this.exit();
Expand All @@ -108,7 +108,8 @@ class DrawingModeController extends AnnotationModeController {
if (
this.currentThread &&
this.currentThread.state === STATES.pending &&
this.currentThread.pathContainer.length > 0
this.currentThread.pathContainer &&
this.currentThread.pathContainer.undoStack.length > 0
) {
this.currentThread.save(TYPES.draw);
}
Expand Down Expand Up @@ -305,8 +306,7 @@ class DrawingModeController extends AnnotationModeController {
this.unbindListeners();
this.bindListeners();
} else {
this.unregisterThread(thread);
thread.destroy();
this.destroyThread(thread);
this.renderPage(thread.location.page);
}

Expand Down
3 changes: 1 addition & 2 deletions src/controllers/PointModeController.js
Expand Up @@ -65,8 +65,7 @@ class PointModeController extends AnnotationModeController {

const thread = this.getThreadByID(this.pendingThreadID);
if (thread) {
this.unregisterThread(thread);
thread.destroy();
this.destroyThread(thread);
}

this.pendingThreadID = null;
Expand Down
49 changes: 49 additions & 0 deletions src/controllers/__tests__/DrawingModeController-test.js
Expand Up @@ -87,6 +87,55 @@ describe('controllers/DrawingModeController', () => {
});
});

describe('cancelDrawing()', () => {
it('should exit drawing mode', () => {
controller.exit = jest.fn();
controller.destroyThread = jest.fn();
controller.currentThread = thread;

controller.cancelDrawing();
expect(controller.exit).toBeCalled();
expect(controller.destroyThread).toBeCalled();
});
});

describe('postDrawing()', () => {
beforeEach(() => {
controller.exit = jest.fn();
thread.state = STATES.pending;
});

it('should exit drawing mode', () => {
controller.postDrawing();
expect(controller.exit).toBeCalled();
expect(thread.save).not.toBeCalled();
});

it('should not save non-pending threads', () => {
thread.state = STATES.inactive;
controller.currentThread = thread;
controller.postDrawing();
expect(controller.exit).toBeCalled();
expect(thread.save).not.toBeCalled();
});

it('should not save pending threads without paths', () => {
thread.pathContainer = { undoStack: [] };
controller.currentThread = thread;
controller.postDrawing();
expect(controller.exit).toBeCalled();
expect(thread.save).not.toBeCalled();
});

it('should save the current pending thread', () => {
thread.pathContainer = { undoStack: [{}] };
controller.currentThread = thread;
controller.postDrawing();
expect(controller.exit).toBeCalled();
expect(thread.save).toBeCalled();
});
});

describe('setupHandlers()', () => {
it('should successfully contain draw mode handlers if undo and redo buttons exist', () => {
controller.annotatedElement = {};
Expand Down
7 changes: 4 additions & 3 deletions src/controllers/__tests__/PointModeController-test.js
Expand Up @@ -91,22 +91,23 @@ describe('controllers/PointModeController', () => {
});

describe('resetMode()', () => {
beforeEach(() => {
it('should reset annotation mode', () => {
// Set up annotation mode
controller.annotatedElement = document.createElement('div');
controller.annotatedElement.classList.add(CLASS_ANNOTATION_MODE);
controller.headerElement = document.createElement('div');

controller.buttonEl = document.createElement('button');
controller.buttonEl.classList.add(CLASS_ACTIVE);
});
controller.getThreadByID = jest.fn().mockReturnValue(thread);
controller.destroyThread = jest.fn();

it('should reset annotation mode', () => {
controller.buttonEl = document.createElement('button');
controller.buttonEl.classList.add(CLASS_ACTIVE);
controller.resetMode();
expect(controller.buttonEl.classList).not.toContain(CLASS_ACTIVE);
expect(controller.hadPendingThreads).toBeFalsy();
expect(controller.destroyThread).toBeCalledWith(thread);
});
});

Expand Down