fix(zone): ensure rAFs are firing outside of zone

This commit is contained in:
Adam Bradley
2015-11-30 22:46:43 -06:00
parent 85d6d6f89e
commit b01301b3b2
6 changed files with 36 additions and 24 deletions

View File

@ -1,5 +1,7 @@
import {Title} from 'angular2/angular2'; import {Injectable, NgZone, Title} from 'angular2/angular2';
import {Config} from '../../config/config';
import {ClickBlock} from '../../util/click-block';
import {rafFrames} from '../../util/dom'; import {rafFrames} from '../../util/dom';
import {ScrollTo} from '../../animations/scroll-to'; import {ScrollTo} from '../../animations/scroll-to';
@ -8,10 +10,12 @@ import {ScrollTo} from '../../animations/scroll-to';
* Component registry service. For more information on registering * Component registry service. For more information on registering
* components see the [IdRef API reference](../id/IdRef/). * components see the [IdRef API reference](../id/IdRef/).
*/ */
@Injectable()
export class IonicApp { export class IonicApp {
constructor(config, clickBlock) { constructor(config: Config, clickBlock: ClickBlock, zone: NgZone) {
this._config = config; this._config = config;
this._zone = zone;
this._titleSrv = new Title(); this._titleSrv = new Title();
this._title = ''; this._title = '';
this._disTime = 0; this._disTime = 0;
@ -29,10 +33,12 @@ export class IonicApp {
let self = this; let self = this;
if (val !== self._title) { if (val !== self._title) {
self._title = val; self._title = val;
function setAppTitle() { this._zone.runOutsideAngular(() => {
self._titleSrv.setTitle(self._title); function setAppTitle() {
} self._titleSrv.setTitle(self._title);
rafFrames(4, setAppTitle); }
rafFrames(4, setAppTitle);
});
} }
} }

View File

@ -3,8 +3,9 @@ import {raf, rafFrames} from '../../util/dom';
export class Activator { export class Activator {
constructor(app, config) { constructor(app, config, zone) {
this.app = app; this.app = app;
this.zone = zone;
this.queue = []; this.queue = [];
this.active = []; this.active = [];
this.clearStateDefers = 5; this.clearStateDefers = 5;
@ -39,7 +40,9 @@ export class Activator {
self.queue = []; self.queue = [];
} }
rafFrames(2, activateCss); this.zone.runOutsideAngular(() => {
rafFrames(2, activateCss);
});
return true; return true;
} }
@ -50,7 +53,9 @@ export class Activator {
function activateUp() { function activateUp() {
self.clearState(); self.clearState();
} }
rafFrames(self.clearStateDefers, activateUp); this.zone.runOutsideAngular(() => {
rafFrames(self.clearStateDefers, activateUp);
});
} }
clearState() { clearState() {

View File

@ -18,11 +18,13 @@ export class RippleActivator extends Activator {
// create a new ripple element // create a new ripple element
this.expandSpeed = EXPAND_DOWN_PLAYBACK_RATE; this.expandSpeed = EXPAND_DOWN_PLAYBACK_RATE;
raf(() => { this.zone.runOutsideAngular(() => {
let clientRect = activatableEle.getBoundingClientRect();
raf(() => { raf(() => {
this.createRipple(activatableEle, pointerX, pointerY, clientRect); let clientRect = activatableEle.getBoundingClientRect();
raf(() => {
this.createRipple(activatableEle, pointerX, pointerY, clientRect);
});
}); });
}); });
} }
@ -83,8 +85,10 @@ export class RippleActivator extends Activator {
this.expandSpeed = 1; this.expandSpeed = 1;
rafFrames(4, () => { this.zone.runOutsideAngular(() => {
this.next(); rafFrames(4, () => {
this.next();
});
}); });
} }

View File

@ -21,10 +21,10 @@ export class TapClick {
this.lastActivated = 0; this.lastActivated = 0;
if (config.get('activator') == 'ripple') { if (config.get('activator') == 'ripple') {
this.activator = new RippleActivator(app, config); this.activator = new RippleActivator(app, config, zone);
} else if (config.get('activator') == 'highlight') { } else if (config.get('activator') == 'highlight') {
this.activator = new Activator(app, config); this.activator = new Activator(app, config, zone);
} }
this.usePolyfill = (config.get('tapPolyfill') === true); this.usePolyfill = (config.get('tapPolyfill') === true);

View File

@ -39,8 +39,6 @@ export function ionicProviders(args={}) {
let clickBlock = new ClickBlock(config.get('clickBlock')); let clickBlock = new ClickBlock(config.get('clickBlock'));
let app = new IonicApp(config, clickBlock);
let events = new Events(); let events = new Events();
let featureDetect = new FeatureDetect(); let featureDetect = new FeatureDetect();
@ -51,7 +49,8 @@ export function ionicProviders(args={}) {
platform.prepareReady(config); platform.prepareReady(config);
return [ return [
provide(IonicApp, {useValue: app}), IonicApp,
provide(ClickBlock, {useValue: clickBlock}),
provide(Config, {useValue: config}), provide(Config, {useValue: config}),
provide(Platform, {useValue: platform}), provide(Platform, {useValue: platform}),
provide(FeatureDetect, {useValue: featureDetect}), provide(FeatureDetect, {useValue: featureDetect}),

View File

@ -1,3 +1,4 @@
const nativeRaf = window.requestAnimationFrame || const nativeRaf = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame || window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame; window.mozRequestAnimationFrame;
@ -8,6 +9,7 @@ const nativeCancelRaf = window.cancelAnimationFrame ||
export function raf(callback) { export function raf(callback) {
//console.log('raf', callback.toString().replace(/\s/g, '').replace('function', '').substring(0, 50)); //console.log('raf', callback.toString().replace(/\s/g, '').replace('function', '').substring(0, 50));
//console.log('raf, isRootZone()', zone.isRootZone(), '$id', zone.$id);
_raf(callback); _raf(callback);
} }
@ -27,10 +29,6 @@ export const rafCancel = nativeRaf ? nativeCancelRaf : function(id) {
return window.cancelTimeout(id); return window.cancelTimeout(id);
} }
export function rafPromise() {
return new Promise(resolve => raf(resolve));
}
export function rafFrames(framesToWait, callback) { export function rafFrames(framesToWait, callback) {
framesToWait = Math.ceil(framesToWait); framesToWait = Math.ceil(framesToWait);