From 02c863b1a9d94c902fe0d81887a31094d2431b77 Mon Sep 17 00:00:00 2001 From: "Manu Mtz.-Almeida" Date: Mon, 20 Jun 2016 20:31:34 +0200 Subject: [PATCH 1/2] refactor(picker): uses new UIEventManager --- src/components/picker/picker.ts | 54 ++++++++++----------------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/src/components/picker/picker.ts b/src/components/picker/picker.ts index c0ca56235f..1408bb54c3 100644 --- a/src/components/picker/picker.ts +++ b/src/components/picker/picker.ts @@ -9,6 +9,7 @@ import {Key} from '../../util/key'; import {NavParams} from '../nav/nav-params'; import {ViewController} from '../nav/view-controller'; import {raf, cancelRaf, CSS, pointerCoord} from '../../util/dom'; +import {UIEventManager} from '../../util/ui-event-manager'; /** @@ -99,12 +100,6 @@ export class Picker extends ViewController { '[style.min-width]': 'col.columnWidth', '[class.picker-opts-left]': 'col.align=="left"', '[class.picker-opts-right]': 'col.align=="right"', - '(touchstart)': 'pointerStart($event)', - '(touchmove)': 'pointerMove($event)', - '(touchend)': 'pointerEnd($event)', - '(mousedown)': 'pointerStart($event)', - '(mousemove)': 'pointerMove($event)', - '(body:mouseup)': 'pointerEnd($event)' } }) class PickerColumnCmp { @@ -115,7 +110,6 @@ class PickerColumnCmp { optHeight: number; velocity: number; pos: number[] = []; - msPrv: number = 0; startY: number = null; rafId: number; bounceFrom: number; @@ -124,10 +118,11 @@ class PickerColumnCmp { rotateFactor: number; lastIndex: number; receivingEvents: boolean = false; + events: UIEventManager = new UIEventManager(); @Output() ionChange: EventEmitter = new EventEmitter(); - constructor(config: Config, private _sanitizer: DomSanitizationService) { + constructor(config: Config, private elementRef: ElementRef, private _sanitizer: DomSanitizationService) { this.rotateFactor = config.getNumber('pickerRotateFactor', 0); } @@ -142,16 +137,22 @@ class PickerColumnCmp { // set the scroll position for the selected option this.setSelected(this.col.selectedIndex, 0); + + // Listening for pointer events + this.events.pointerEventsRef(this.elementRef, + (ev: any) => this.pointerStart(ev), + (ev: any) => this.pointerMove(ev), + (ev: any) => this.pointerEnd(ev) + ); + } + + ngOnDestroy() { + this.events.unlistenAll(); } - pointerStart(ev: UIEvent) { + pointerStart(ev: UIEvent): boolean { console.debug('picker, pointerStart', ev.type, this.startY); - if (this.isPrevented(ev)) { - // do not both with mouse events if a touch event already fired - return; - } - // cancel any previous raf's that haven't fired yet cancelRaf(this.rafId); @@ -176,6 +177,7 @@ class PickerColumnCmp { this.minY = (minY * this.optHeight * -1); this.maxY = (maxY * this.optHeight * -1); + return true; } pointerMove(ev: UIEvent) { @@ -186,10 +188,6 @@ class PickerColumnCmp { return; } - if (this.isPrevented(ev)) { - return; - } - var currentY = pointerCoord(ev).y; this.pos.push(currentY, Date.now()); @@ -214,10 +212,6 @@ class PickerColumnCmp { } pointerEnd(ev: UIEvent) { - if (this.isPrevented(ev)) { - return; - } - if (!this.receivingEvents) { return; } @@ -411,22 +405,6 @@ class PickerColumnCmp { } } - isPrevented(ev: UIEvent): boolean { - let now = Date.now(); - if (ev.type.indexOf('touch') > -1) { - // this is a touch event, so prevent mouse events for a while - this.msPrv = now + 2000; - - } else if (this.msPrv > now && ev.type.indexOf('mouse') > -1) { - // this is a mouse event, and a touch event already happend recently - // prevent the calling method from continuing - ev.preventDefault(); - ev.stopPropagation(); - return true; - } - return false; - } - } From 1cef5a7084d71500d500091dd3c5e80363fdc6fd Mon Sep 17 00:00:00 2001 From: "Manu Mtz.-Almeida" Date: Mon, 20 Jun 2016 20:31:56 +0200 Subject: [PATCH 2/2] refactor(range): uses new UIEventManager --- src/components/range/range.ts | 56 +++++++---------------------------- 1 file changed, 11 insertions(+), 45 deletions(-) diff --git a/src/components/range/range.ts b/src/components/range/range.ts index 554819bfb7..d9b78f1fd4 100644 --- a/src/components/range/range.ts +++ b/src/components/range/range.ts @@ -4,6 +4,7 @@ import {NG_VALUE_ACCESSOR} from '@angular/common'; import {Form} from '../../util/form'; import {isTrueProperty, isNumber, isString, isPresent, clamp} from '../../util/util'; import {Item} from '../item/item'; +import {UIEventManager} from '../../util/ui-event-manager'; import {pointerCoord, Coordinates, raf} from '../../util/dom'; import {Debouncer} from '../../util/debouncer'; @@ -213,10 +214,9 @@ export class Range { private _max: number = 100; private _step: number = 1; private _snaps: boolean = false; - private _removes: Function[] = []; - private _mouseRemove: Function; - private _debouncer: Debouncer = new Debouncer(0); + private _debouncer: Debouncer = new Debouncer(0); + private _events: UIEventManager = new UIEventManager(); /** * @private */ @@ -359,8 +359,10 @@ export class Range { this._renderer.setElementStyle(this._bar.nativeElement, 'right', barR); // add touchstart/mousedown listeners - this._renderer.listen(this._slider.nativeElement, 'touchstart', this.pointerDown.bind(this)); - this._mouseRemove = this._renderer.listen(this._slider.nativeElement, 'mousedown', this.pointerDown.bind(this)); + this._events.pointerEventsRef(this._slider, + this.pointerDown.bind(this), + this.pointerMove.bind(this), + this.pointerUp.bind(this)); this.createTicks(); } @@ -368,12 +370,12 @@ export class Range { /** * @private */ - pointerDown(ev: UIEvent) { + pointerDown(ev: UIEvent): boolean { // TODO: we could stop listening for events instead of checking this._disabled. // since there are a lot of events involved, this solution is // enough for the moment if (this._disabled) { - return; + return false; } console.debug(`range, ${ev.type}`); @@ -381,11 +383,6 @@ export class Range { ev.preventDefault(); ev.stopPropagation(); - if (ev.type === 'touchstart') { - // if this was a touchstart, then let's remove the mousedown - this._mouseRemove && this._mouseRemove(); - } - // get the start coordinates this._start = pointerCoord(ev); @@ -411,25 +408,11 @@ export class Range { // update the ratio for the active knob this.updateKnob(this._start, rect); - // ensure past listeners have been removed - this.clearListeners(); - // update the active knob's position this._active.position(); this._pressed = this._active.pressed = true; - // add a move listener depending on touch/mouse - let renderer = this._renderer; - let removes = this._removes; - - if (ev.type === 'touchstart') { - removes.push(renderer.listen(this._slider.nativeElement, 'touchmove', this.pointerMove.bind(this))); - removes.push(renderer.listen(this._slider.nativeElement, 'touchend', this.pointerUp.bind(this))); - - } else { - removes.push(renderer.listenGlobal('body', 'mousemove', this.pointerMove.bind(this))); - removes.push(renderer.listenGlobal('window', 'mouseup', this.pointerUp.bind(this))); - } + return true; } /** @@ -453,9 +436,6 @@ export class Range { this._active.position(); this._pressed = this._active.pressed = true; - } else { - // ensure listeners have been removed - this.clearListeners(); } } @@ -477,21 +457,7 @@ export class Range { // clear the start coordinates and active knob this._start = this._active = null; - - // ensure listeners have been removed - this.clearListeners(); - } - - /** - * @private - */ - clearListeners() { this._pressed = this._knobs.first.pressed = this._knobs.last.pressed = false; - - for (var i = 0; i < this._removes.length; i++) { - this._removes[i](); - } - this._removes.length = 0; } /** @@ -709,7 +675,7 @@ export class Range { */ ngOnDestroy() { this._form.deregister(this); - this.clearListeners(); + this._events.unlistenAll(); } }