refactor: improve tree shaking abilities

Internal refactor completed in order to improve tree shaking and dead
code removal. The public API, with an exception to ion-slides, has
stayed the same. However, internally many changes were required so
bundlers could better exclude modules which should not be bundled.
Ultimately most changes resorted to removing references to `window` or
`document`, or a module that referenced one of those.

BREAKING CHANGES

ion-slides was refactored to remove the external dependencies, and
rewritten in TypeScript/ES6 modules to again improve tree shaking
abilities.
This commit is contained in:
Adam Bradley
2017-01-09 09:51:39 -06:00
parent 13cf6a6cb7
commit 7000b1b173
191 changed files with 9401 additions and 13664 deletions

View File

@ -0,0 +1,155 @@
/**
* Adopted from FastDom
* https://github.com/wilsonpage/fastdom
* MIT License
*/
import { Injectable } from '@angular/core';
import { Platform } from './platform';
import { removeArrayItem } from '../util/util';
/**
* @private
*/
export class DomDebouncer {
private writeTask: Function = null;
private readTask: Function = null;
constructor(private dom: DomController) { }
read(fn: DomCallback): Function {
if (this.readTask) {
return;
}
return this.readTask = this.dom.read((t) => {
this.readTask = null;
fn(t);
});
}
write(fn: DomCallback, ctx?: any): Function {
if (this.writeTask) {
return;
}
return this.writeTask = this.dom.write((t) => {
this.writeTask = null;
fn(t);
});
}
cancel() {
const writeTask = this.writeTask;
writeTask && this.dom.cancel(writeTask);
const readTask = this.readTask;
readTask && this.dom.cancel(readTask);
this.readTask = this.writeTask = null;
}
}
/**
* @private
*/
@Injectable()
export class DomController {
private r: Function[] = [];
private w: Function[] = [];
private q: boolean;
constructor(public plt: Platform) {}
debouncer(): DomDebouncer {
return new DomDebouncer(this);
}
read(fn: DomCallback, timeout?: number): any {
if (timeout) {
(<any>fn).timeoutId = this.plt.timeout(() => {
this.r.push(fn);
this._queue();
}, timeout);
} else {
this.r.push(fn);
this._queue();
}
return fn;
}
write(fn: DomCallback, timeout?: number): any {
if (timeout) {
(<any>fn).timeoutId = this.plt.timeout(() => {
this.w.push(fn);
this._queue();
}, timeout);
} else {
this.w.push(fn);
this._queue();
}
return fn;
}
cancel(fn: any): void {
if (fn) {
if (fn.timeoutId) {
this.plt.cancelTimeout(fn.timeoutId);
}
removeArrayItem(this.r, fn) || removeArrayItem(this.w, fn);
}
}
private _queue() {
const self = this;
if (!self.q) {
self.q = true;
self.plt.raf(function rafCallback(timeStamp) {
self._flush(timeStamp);
});
}
}
private _flush(timeStamp: number) {
let err: any;
try {
dispatch(timeStamp, this.r, this.w);
} catch (e) {
err = e;
}
this.q = false;
if (this.r.length || this.w.length) {
this._queue();
}
if (err) {
throw err;
}
}
}
function dispatch(timeStamp: number, r: Function[], w: Function[]) {
let fn: Function;
// ******** DOM READS ****************
while (fn = r.shift()) {
fn(timeStamp);
}
// ******** DOM WRITES ****************
while (fn = w.shift()) {
fn(timeStamp);
}
}
/**
* @private
*/
export type DomCallback = { (timeStamp?: number): void };