Skip to content

Commit

Permalink
perf(draggable): lazily create the mouse move listener
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Lewis committed Mar 4, 2017
1 parent 1c62985 commit bebd925
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
34 changes: 25 additions & 9 deletions src/draggable.directive.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import {Directive, HostListener, OnInit, ElementRef, Renderer, Output, EventEmitter, Input, OnDestroy} from '@angular/core';
import {
Directive,
HostListener,
OnInit,
ElementRef,
Renderer,
Output,
EventEmitter,
Input,
OnDestroy
} from '@angular/core';
import {Subject} from 'rxjs/Subject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/merge';
Expand Down Expand Up @@ -57,6 +67,8 @@ export class Draggable implements OnInit, OnDestroy {
*/
mouseUp: Subject<any> = new Subject();

private mouseMoveEventListenerUnsubscribe: Function;

/**
* @hidden
*/
Expand Down Expand Up @@ -158,6 +170,9 @@ export class Draggable implements OnInit, OnDestroy {
}

ngOnDestroy(): void {
if (this.mouseMoveEventListenerUnsubscribe) {
this.mouseMoveEventListenerUnsubscribe();
}
this.mouseDown.complete();
this.mouseMove.complete();
this.mouseUp.complete();
Expand All @@ -168,22 +183,23 @@ export class Draggable implements OnInit, OnDestroy {
*/
@HostListener('mousedown', ['$event'])
onMouseDown(event: MouseEvent): void {
if (!this.mouseMoveEventListenerUnsubscribe) {
this.mouseMoveEventListenerUnsubscribe = this.renderer.listenGlobal('document', 'mousemove', (event: MouseEvent) => {
this.mouseMove.next(event);
});
}
this.mouseDown.next(event);
}

/**
* @hidden
*/
@HostListener('document:mousemove', ['$event'])
onMouseMove(event: MouseEvent): void {
this.mouseMove.next(event);
}

/**
* @hidden
*/
@HostListener('document:mouseup', ['$event'])
onMouseUp(event: MouseEvent): void {
if (this.mouseMoveEventListenerUnsubscribe) {
this.mouseMoveEventListenerUnsubscribe();
this.mouseMoveEventListenerUnsubscribe = null;
}
this.mouseUp.next(event);
}

Expand Down
14 changes: 14 additions & 0 deletions test/draggable.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,18 @@ describe('draggable directive', () => {
expect(fixture.componentInstance.dragEnd).to.have.been.calledOnce;
});

it('should only unregister the mouse move listener if it exists', () => {
const draggableElement: HTMLElement = fixture.componentInstance.draggable.element.nativeElement;
triggerDomEvent('mouseup', draggableElement, {clientX: 7, clientY: 8});
expect(fixture.componentInstance.draggable['mouseMoveEventListenerUnsubscribe']).not.to.be.ok;
});

it('should not register multiple mouse move listeners', () => {
const draggableElement: HTMLElement = fixture.componentInstance.draggable.element.nativeElement;
triggerDomEvent('mousedown', draggableElement, {clientX: 7, clientY: 8});
const mouseMoveUnsubscribe: Function = fixture.componentInstance.draggable['mouseMoveEventListenerUnsubscribe'];
triggerDomEvent('mousedown', draggableElement, {clientX: 7, clientY: 8});
expect(fixture.componentInstance.draggable['mouseMoveEventListenerUnsubscribe']).to.equal(mouseMoveUnsubscribe);
});

});

0 comments on commit bebd925

Please sign in to comment.