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

@ -9,7 +9,7 @@ export class E2EPage {
items: any[] = [];
webview: string = '';
constructor(platform: Platform, public navCtrl: NavController) {
constructor(plt: Platform, public navCtrl: NavController) {
for (var i = 0; i < 200; i++) {
this.items.push({
value: i,
@ -19,8 +19,8 @@ export class E2EPage {
});
}
if (platform.is('ios')) {
if (platform.testUserAgent('Safari')) {
if (plt.is('ios')) {
if (plt.testUserAgent('Safari')) {
this.webview = ': iOS Safari';
} else if (!!window['webkit']) {

View File

@ -0,0 +1,81 @@
import { Component, NgModule } from '@angular/core';
import { IonicApp, IonicModule, Platform } from '../../../..';
@Component({
templateUrl: 'main.html'
})
export class E2EPage {
items: any[] = [];
webview: string = '';
type: string = 'range';
testCheck: boolean;
constructor(plt: Platform) {
for (var i = 0; i < 200; i++) {
if (i % 2 === 0) {
this.changeType();
}
this.items.push({
value: i,
type: this.type,
class: `item-${i}`
});
}
if (plt.is('ios')) {
if (plt.testUserAgent('Safari')) {
this.webview = ': iOS Safari';
} else if (!!window['webkit']) {
this.webview = ': iOS WKWebView';
} else {
this.webview = ': iOS UIWebView';
}
}
}
changeType() {
if (this.type === 'range') {
this.type = 'checkbox';
} else if (this.type === 'checkbox') {
this.type = 'toggle';
} else if (this.type === 'toggle') {
this.type = 'radio';
} else {
this.type = 'range';
}
}
reload() {
window.location.reload(true);
}
}
@Component({
template: '<ion-nav [root]="root"></ion-nav>'
})
export class E2EApp {
root = E2EPage;
}
@NgModule({
declarations: [
E2EApp,
E2EPage
],
imports: [
IonicModule.forRoot(E2EApp)
],
bootstrap: [IonicApp],
entryComponents: [
E2EApp,
E2EPage
]
})
export class AppModule {}

View File

@ -0,0 +1,6 @@
it('should check the first checkbox, toggle, and radio', function() {
element(by.css('.item-0 .checkbox')).click();
element(by.css('.item-2 .toggle')).click();
element(by.css('.item-4 .radio')).click();
});

View File

@ -0,0 +1,23 @@
<ion-header>
<ion-navbar>
<ion-title>Virtual Scroll{{webview}}</ion-title>
<ion-buttons end>
<button ion-button (click)="reload()">
Reload
</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list radio-group [virtualScroll]="items">
<ion-item *virtualItem="let item" [ngClass]="item.class">
<ion-label>{{item.type}}-{{item.value}}</ion-label>
<ion-checkbox *ngIf="item.type === 'checkbox'" item-left></ion-checkbox>
<ion-toggle *ngIf="item.type === 'toggle'" item-left></ion-toggle>
<ion-radio *ngIf="item.type === 'radio'" item-left></ion-radio>
<ion-range *ngIf="item.type === 'range'"></ion-range>
</ion-item>
</ion-list>
</ion-content>

View File

@ -11,7 +11,7 @@ export class E2EPage {
@ViewChild('content') content: ElementRef;
constructor(platform: Platform) {
constructor(plt: Platform) {
for (var i = 0; i < 200; i++) {
this.items.push({
value: i,
@ -21,7 +21,7 @@ export class E2EPage {
});
}
if (platform.is('ios')) {
if (plt.is('ios')) {
if (window.indexedDB) {
this.webview = ': WKWebView';

View File

@ -1,5 +1,6 @@
import { VirtualCell, VirtualData, VirtualNode } from '../virtual-util';
import { processRecords, populateNodeData, initReadNodes, getVirtualHeight, adjustRendered, estimateHeight } from '../virtual-util';
import { mockPlatform } from '../../../util/mock-providers';
describe('VirtualScroll', () => {
@ -324,7 +325,7 @@ describe('VirtualScroll', () => {
{row: 0, tmpl: TEMPLATE_FOOTER, reads: 0},
];
initReadNodes(nodes, cells, data);
initReadNodes(mockPlatform(), nodes, cells, data);
expect(cells[0].top).toBe(firstTop);
expect(cells[0].left).toBe(0);
@ -374,7 +375,7 @@ describe('VirtualScroll', () => {
{row: 4, tmpl: TEMPLATE_FOOTER, reads: 0},
];
initReadNodes(nodes, cells, data);
initReadNodes(mockPlatform(), nodes, cells, data);
expect(cells[0].top).toBe(0);
expect(cells[0].height).toBe(HEIGHT_HEADER);

View File

@ -1,9 +1,9 @@
import { AfterContentInit, ChangeDetectorRef, ContentChild, Directive, DoCheck, ElementRef, Input, IterableDiffers, IterableDiffer, NgZone, OnDestroy, Optional, Renderer, TrackByFn } from '@angular/core';
import { AfterContentInit, ChangeDetectorRef, ContentChild, Directive, DoCheck, ElementRef, Input, IterableDiffers, IterableDiffer, NgZone, OnDestroy, Renderer, TrackByFn } from '@angular/core';
import { adjustRendered, calcDimensions, estimateHeight, initReadNodes, processRecords, populateNodeData, updateDimensions, updateNodeContext, writeToNodes } from './virtual-util';
import { Config } from '../../config/config';
import { Content, ScrollEvent } from '../content/content';
import { DomController } from '../../util/dom-controller';
import { DomController } from '../../platform/dom-controller';
import { isBlank, isFunction, isPresent } from '../../util/util';
import { Platform } from '../../platform/platform';
import { ViewController } from '../../navigation/view-controller';
@ -343,7 +343,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
*/
@Input() set headerFn(val: Function) {
if (isFunction(val)) {
this._hdrFn = val.bind((this._ctrl && this._ctrl._cmp) || this);
this._hdrFn = val.bind((this._ctrl._cmp) || this);
}
}
@ -356,7 +356,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
*/
@Input() set footerFn(val: Function) {
if (isFunction(val)) {
this._ftrFn = val.bind((this._ctrl && this._ctrl._cmp) || this);
this._ftrFn = val.bind((this._ctrl._cmp) || this);
}
}
@ -373,8 +373,8 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
private _zone: NgZone,
private _cd: ChangeDetectorRef,
private _content: Content,
private _platform: Platform,
@Optional() private _ctrl: ViewController,
private _plt: Platform,
private _ctrl: ViewController,
private _config: Config,
private _dom: DomController) {
@ -384,14 +384,14 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
this._renderer.setElementClass(_elementRef.nativeElement, 'virtual-loading', true);
// wait for the content to be rendered and has readable dimensions
_content.readReady.subscribe(() => {
_ctrl.readReady.subscribe(() => {
this._init = true;
if (this._hasChanges()) {
this.readUpdate();
// wait for the content to be writable
var subscription = _content.writeReady.subscribe(() => {
var subscription = _ctrl.writeReady.subscribe(() => {
subscription.unsubscribe();
this.writeUpdate();
});
@ -478,7 +478,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
// wait a frame before trying to read and calculate the dimensions
this._dom.read(() => {
// ******** DOM READ ****************
initReadNodes(nodes, cells, data);
initReadNodes(this._plt, nodes, cells, data);
});
this._dom.write(() => {
@ -509,7 +509,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
renderer.setElementClass(ele, 'virtual-loading', false);
// ******** DOM WRITE ****************
writeToNodes(nodes, cells, recordsLength);
writeToNodes(this._plt, nodes, cells, recordsLength);
// ******** DOM WRITE ****************
this._setHeight(
@ -541,7 +541,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
const recordsLength = this._records.length;
// ******** DOM WRITE ****************
writeToNodes(nodes, cells, recordsLength);
writeToNodes(this._plt, nodes, cells, recordsLength);
// ******** DOM WRITE ****************
this._setHeight(
@ -587,7 +587,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
}
// ******** DOM READ ****************
updateDimensions(nodes, cells, data, false);
updateDimensions(this._plt, nodes, cells, data, false);
adjustRendered(cells, data);
@ -621,7 +621,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
const data = this._data;
// ******** DOM READ ****************
updateDimensions(nodes, cells, data, false);
updateDimensions(this._plt, nodes, cells, data, false);
adjustRendered(cells, data);
@ -639,7 +639,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
}
// ******** DOM WRITE ****************
writeToNodes(nodes, cells, recordsLength);
writeToNodes(this._plt, nodes, cells, recordsLength);
// ******** DOM WRITE ****************
this._setHeight(

View File

@ -1,7 +1,6 @@
import { ViewContainerRef, TemplateRef, EmbeddedViewRef, } from '@angular/core';
import { CSS } from '../../util/dom';
import { ViewContainerRef, TemplateRef, EmbeddedViewRef } from '@angular/core';
import { Platform } from '../../platform/platform';
/**
* NO DOM
@ -248,7 +247,7 @@ export function populateNodeData(startCellIndex: number, endCellIndex: number, v
/**
* DOM READ
*/
export function initReadNodes(nodes: VirtualNode[], cells: VirtualCell[], data: VirtualData) {
export function initReadNodes(plt: Platform, nodes: VirtualNode[], cells: VirtualCell[], data: VirtualData) {
if (nodes.length && cells.length) {
// first node
// ******** DOM READ ****************
@ -259,7 +258,7 @@ export function initReadNodes(nodes: VirtualNode[], cells: VirtualCell[], data:
firstCell.row = 0;
// ******** DOM READ ****************
updateDimensions(nodes, cells, data, true);
updateDimensions(plt, nodes, cells, data, true);
}
}
@ -267,7 +266,7 @@ export function initReadNodes(nodes: VirtualNode[], cells: VirtualCell[], data:
/**
* DOM READ
*/
export function updateDimensions(nodes: VirtualNode[], cells: VirtualCell[], data: VirtualData, initialUpdate: boolean) {
export function updateDimensions(plt: Platform, nodes: VirtualNode[], cells: VirtualCell[], data: VirtualData, initialUpdate: boolean) {
let node: VirtualNode;
let element: VirtualHtmlElement;
let cell: VirtualCell;
@ -283,7 +282,7 @@ export function updateDimensions(nodes: VirtualNode[], cells: VirtualCell[], dat
element = getElement(node);
// ******** DOM READ ****************
readElements(cell, element);
readElements(plt, cell, element);
if (initialUpdate) {
// update estimated dimensions with more accurate dimensions
@ -376,9 +375,9 @@ export function updateNodeContext(nodes: VirtualNode[], cells: VirtualCell[], da
/**
* DOM READ
*/
function readElements(cell: VirtualCell, element: VirtualHtmlElement) {
function readElements(plt: Platform, cell: VirtualCell, element: VirtualHtmlElement) {
// ******** DOM READ ****************
const styles = window.getComputedStyle(<any>element);
const styles = plt.getElementComputedStyle(<any>element);
// ******** DOM READ ****************
cell.left = (element.clientLeft - parseFloat(styles.marginLeft));
@ -394,7 +393,7 @@ function readElements(cell: VirtualCell, element: VirtualHtmlElement) {
/**
* DOM WRITE
*/
export function writeToNodes(nodes: VirtualNode[], cells: VirtualCell[], totalRecords: number) {
export function writeToNodes(plt: Platform, nodes: VirtualNode[], cells: VirtualCell[], totalRecords: number) {
let node: VirtualNode;
let element: VirtualHtmlElement;
let cell: VirtualCell;
@ -412,7 +411,7 @@ export function writeToNodes(nodes: VirtualNode[], cells: VirtualCell[], totalRe
if (element) {
// ******** DOM WRITE ****************
element.style[CSS.transform] = node.lastTransform = transform;
element.style[plt.Css.transform] = node.lastTransform = transform;
// ******** DOM WRITE ****************
element.classList.add('virtual-position');