Skip to content

Commit

Permalink
Fix: Unregister drawing on mode cancel (#288)
Browse files Browse the repository at this point in the history
- Unregister drawing on mode cancel
- Save drawing on done w/ undoStack isn't empty
  • Loading branch information
pramodsum authored Nov 15, 2018
1 parent e972a72 commit 12d5f6d
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 13 deletions.
17 changes: 13 additions & 4 deletions src/controllers/AnnotationModeController.js
Original file line number Diff line number Diff line change
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) {
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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

0 comments on commit 12d5f6d

Please sign in to comment.