Skip to content

Commit

Permalink
fix(activator): cancel remove .activated timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
manucorporat committed Nov 20, 2016
1 parent bb80033 commit 9510a2b
Show file tree
Hide file tree
Showing 6 changed files with 290 additions and 61 deletions.
36 changes: 36 additions & 0 deletions src/components/tap-click/activator-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { PointerCoordinates } from '../../util/dom';

export abstract class ActivatorBase {

abstract clickAction(ev, activatableEle: HTMLElement, startCoord: PointerCoordinates);

abstract downAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates);

abstract upAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates);

abstract clearState();
}

export function isActivatedDisabled(ev: any, activatableEle: any): boolean {
if (!activatableEle || !activatableEle.parentNode) {
return true;
}
if (!ev) {
return false;
}
if (ev.defaultPrevented) {
return true;
}

let targetEle = ev.target;
for (let i = 0; i < 4; i++) {
if (!targetEle) {
break;
}
if (targetEle.hasAttribute('disable-activated')) {
return true;
}
targetEle = targetEle.parentElement;
}
return false;
}
74 changes: 36 additions & 38 deletions src/components/tap-click/activator.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import { App } from '../app/app';
import { Config } from '../../config/config';
import { PointerCoordinates, nativeTimeout, rafFrames } from '../../util/dom';
import { ActivatorBase, isActivatedDisabled } from './activator-base';


export class Activator {
protected _css: string;
export class Activator implements ActivatorBase {
protected _queue: HTMLElement[] = [];
protected _active: HTMLElement[] = [];
protected _activeRafDefer: Function;
protected _clearRafDefer: Function;
_css: string;
activatedDelay = ADD_ACTIVATED_DEFERS;
clearDelay = CLEAR_STATE_DEFERS;

constructor(protected app: App, config: Config) {
this._css = config.get('activatedClass') || 'activated';
}

clickAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
// a click happened, so immediately deactive all activated elements
this._clearDeferred();
this._scheduleClear();

this._queue.length = 0;

for (var i = 0; i < this._active.length; i++) {
Expand All @@ -32,21 +37,22 @@ export class Activator {

downAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
// the user just pressed down
if (this.disableActivated(ev)) {
if (isActivatedDisabled(ev, activatableEle)) {
return;
}

this.unscheduleClear();
this.deactivate();

// queue to have this element activated
this._queue.push(activatableEle);

this._activeRafDefer = rafFrames(6, () => {
this._activeRafDefer = rafFrames(this.activatedDelay, () => {
let activatableEle: HTMLElement;
for (let i = 0; i < this._queue.length; i++) {
activatableEle = this._queue[i];
if (activatableEle && activatableEle.parentNode) {
this._active.push(activatableEle);
activatableEle.classList.add(this._css);
}
this._active.push(activatableEle);
activatableEle.classList.add(this._css);
}
this._queue.length = 0;
this._clearDeferred();
Expand All @@ -55,16 +61,28 @@ export class Activator {

// the user was pressing down, then just let up
upAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
this._clearDeferred();
this._scheduleClear();
}

rafFrames(CLEAR_STATE_DEFERS, () => {
_scheduleClear() {
if (this._clearRafDefer) {
return;
}
this._clearRafDefer = rafFrames(this.clearDelay, () => {
this.clearState();
this._clearRafDefer = null;
});
}

unscheduleClear() {
if (this._clearRafDefer) {
this._clearRafDefer();
this._clearRafDefer = null;
}
}

// all states should return to normal
clearState() {

if (!this.app.isEnabled()) {
// the app is actively disabled, so don't bother deactivating anything.
// this makes it easier on the GPU so it doesn't have to redraw any
Expand All @@ -85,12 +103,10 @@ export class Activator {

this._queue.length = 0;

rafFrames(2, () => {
for (var i = 0; i < this._active.length; i++) {
this._active[i].classList.remove(this._css);
}
this._active.length = 0;
});
for (var i = 0; i < this._active.length; i++) {
this._active[i].classList.remove(this._css);
}
this._active.length = 0;
}

_clearDeferred() {
Expand All @@ -100,25 +116,7 @@ export class Activator {
this._activeRafDefer = null;
}
}

disableActivated(ev: any) {
if (ev.defaultPrevented) {
return true;
}

let targetEle = ev.target;
for (let i = 0; i < 4; i++) {
if (!targetEle) {
break;
}
if (targetEle.hasAttribute('disable-activated')) {
return true;
}
targetEle = targetEle.parentElement;
}
return false;
}

}

const CLEAR_STATE_DEFERS = 5;
const ADD_ACTIVATED_DEFERS = 6;
const CLEAR_STATE_DEFERS = 6;
58 changes: 38 additions & 20 deletions src/components/tap-click/ripple.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ActivatorBase, isActivatedDisabled } from './activator-base';
import { Activator } from './activator';
import { App } from '../app/app';
import { PointerCoordinates, CSS, hasPointerMoved, pointerCoord, rafFrames } from '../../util/dom';
Expand All @@ -7,19 +8,47 @@ import { Config } from '../../config/config';
/**
* @private
*/
export class RippleActivator extends Activator {
export class RippleActivator implements ActivatorBase {
protected _queue: HTMLElement[] = [];
protected _active: HTMLElement[] = [];
protected highlight: Activator;

constructor(app: App, config: Config) {
super(app, config);
this.highlight = new Activator(app, config);
this.highlight.activatedDelay = 0;
}

clickAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
this.downAction(ev, activatableEle, startCoord);
this.upAction(ev, activatableEle, startCoord);
// Highlight
this.highlight && this.highlight.clickAction(ev, activatableEle, startCoord);

// Ripple
this._clickAction(ev, activatableEle, startCoord);
}

downAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
if (this.disableActivated(ev) || !activatableEle || !activatableEle.parentNode) {
// Highlight
this.highlight && this.highlight.downAction(ev, activatableEle, startCoord);

// Ripple
this._downAction(ev, activatableEle, startCoord);
}

upAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
// Highlight
this.highlight && this.highlight.upAction(ev, activatableEle, startCoord);

// Ripple
this._upAction(ev, activatableEle, startCoord);
}

clearState() {
// Highlight
this.highlight && this.highlight.clearState();
}

_downAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
if (isActivatedDisabled(ev, activatableEle)) {
return;
}

Expand All @@ -38,12 +67,9 @@ export class RippleActivator extends Activator {
break;
}
}

// DOM WRITE
activatableEle.classList.add(this._css);
}

upAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
_upAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
if (!hasPointerMoved(6, startCoord, pointerCoord(ev))) {
let i = activatableEle.childElementCount;
while (i--) {
Expand All @@ -55,8 +81,10 @@ export class RippleActivator extends Activator {
}
}
}
}

super.upAction(ev, activatableEle, startCoord);
_clickAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
// NOTHING
}

startRippleEffect(rippleEle: any, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
Expand Down Expand Up @@ -107,16 +135,6 @@ export class RippleActivator extends Activator {
});
}

deactivate() {
rafFrames(2, () => {
for (var i = 0; i < this._active.length; i++) {
// DOM WRITE
this._active[i].classList.remove(this._css);
}
this._active.length = 0;
});
}

}

const TOUCH_DOWN_ACCEL = 300;
Expand Down
3 changes: 2 additions & 1 deletion src/components/tap-click/tap-click.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Injectable, NgZone } from '@angular/core';

import { ActivatorBase } from './activator-base';
import { Activator } from './activator';
import { App } from '../app/app';
import { Config } from '../../config/config';
Expand All @@ -15,7 +16,7 @@ import { UIEventManager, PointerEvents, PointerEventType } from '../../util/ui-e
export class TapClick {
private disableClick: number = 0;
private usePolyfill: boolean;
private activator: Activator;
private activator: ActivatorBase;
private startCoord: any;
private events: UIEventManager = new UIEventManager(false);
private pointerEvents: PointerEvents;
Expand Down
Loading

0 comments on commit 9510a2b

Please sign in to comment.