fix(core): benchmarks - enable ng1 benchmark again
Also make it match the ng2 benchmark.
This commit is contained in:
parent
2f442062d2
commit
bccfaa46ec
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {$} from 'protractor';
|
||||||
|
|
||||||
|
export const CreateBtn = '#createDom';
|
||||||
|
export const DestroyBtn = '#destroyDom';
|
||||||
|
export const DetectChangesBtn = '#detectChanges';
|
||||||
|
export const RootEl = '#root';
|
||||||
|
export const NumberOfChecksEl = '#numberOfChecks';
|
||||||
|
|
||||||
|
export interface Benchmark {
|
||||||
|
id: string;
|
||||||
|
url: string;
|
||||||
|
buttons: string[];
|
||||||
|
ignoreBrowserSynchronization?: boolean;
|
||||||
|
extraParams?: {name: string, value: any}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const CreateDestroyButtons: string[] = [CreateBtn, DestroyBtn];
|
||||||
|
const CreateDestroyDetectChangesButtons: string[] = [...CreateDestroyButtons, DetectChangesBtn];
|
||||||
|
|
||||||
|
export const Benchmarks: Benchmark[] = [
|
||||||
|
{
|
||||||
|
id: `deepTree.ng2`,
|
||||||
|
url: 'all/benchmarks/src/tree/ng2/index.html',
|
||||||
|
buttons: CreateDestroyDetectChangesButtons,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `deepTree.ng2.next`,
|
||||||
|
url: 'all/benchmarks/src/tree/ng2_next/index.html',
|
||||||
|
buttons: CreateDestroyDetectChangesButtons,
|
||||||
|
ignoreBrowserSynchronization: true,
|
||||||
|
// Can't use bundles as we use non exported code
|
||||||
|
extraParams: [{name: 'bundles', value: false}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `deepTree.ng2.static`,
|
||||||
|
url: 'all/benchmarks/src/tree/ng2_static/index.html',
|
||||||
|
buttons: CreateDestroyButtons,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `deepTree.ng2_switch`,
|
||||||
|
url: 'all/benchmarks/src/tree/ng2_switch/index.html',
|
||||||
|
buttons: CreateDestroyButtons,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `deepTree.baseline`,
|
||||||
|
url: 'all/benchmarks/src/tree/baseline/index.html',
|
||||||
|
buttons: CreateDestroyButtons,
|
||||||
|
ignoreBrowserSynchronization: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `deepTree.incremental_dom`,
|
||||||
|
url: 'all/benchmarks/src/tree/incremental_dom/index.html',
|
||||||
|
buttons: CreateDestroyButtons,
|
||||||
|
ignoreBrowserSynchronization: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `deepTree.polymer`,
|
||||||
|
url: 'all/benchmarks/src/tree/polymer/index.html',
|
||||||
|
buttons: CreateDestroyButtons,
|
||||||
|
ignoreBrowserSynchronization: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `deepTree.polymer_leaves`,
|
||||||
|
url: 'all/benchmarks/src/tree/polymer_leaves/index.html',
|
||||||
|
buttons: CreateDestroyButtons,
|
||||||
|
ignoreBrowserSynchronization: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `deepTree.ng1`,
|
||||||
|
url: 'all/benchmarks/src/tree/ng1/index.html',
|
||||||
|
buttons: CreateDestroyDetectChangesButtons,
|
||||||
|
}
|
||||||
|
];
|
|
@ -7,162 +7,77 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {runBenchmark, verifyNoBrowserErrors} from 'e2e_util/perf_util';
|
import {runBenchmark, verifyNoBrowserErrors} from 'e2e_util/perf_util';
|
||||||
import {$} from 'protractor';
|
import {$, browser} from 'protractor';
|
||||||
|
|
||||||
interface Worker {
|
import {Benchmark, Benchmarks, CreateBtn, DestroyBtn, DetectChangesBtn, RootEl} from './tree_data';
|
||||||
id: string;
|
|
||||||
prepare?(): void;
|
|
||||||
work(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CreateOnlyWorker: Worker = {
|
|
||||||
id: 'createOnly',
|
|
||||||
prepare: () => $('#destroyDom').click(),
|
|
||||||
work: () => $('#createDom').click()
|
|
||||||
};
|
|
||||||
|
|
||||||
const CreateAndDestroyWorker: Worker = {
|
|
||||||
id: 'createDestroy',
|
|
||||||
work: () => {
|
|
||||||
$('#createDom').click();
|
|
||||||
$('#destroyDom').click();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const UpdateWorker: Worker = {
|
|
||||||
id: 'update',
|
|
||||||
work: () => $('#createDom').click()
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('tree benchmark perf', () => {
|
describe('tree benchmark perf', () => {
|
||||||
|
|
||||||
afterEach(verifyNoBrowserErrors);
|
let _oldRootEl: any;
|
||||||
|
beforeEach(() => _oldRootEl = browser.rootEl);
|
||||||
|
|
||||||
[CreateOnlyWorker, CreateAndDestroyWorker, UpdateWorker].forEach((worker) => {
|
afterEach(() => {
|
||||||
describe(worker.id, () => {
|
browser.rootEl = _oldRootEl;
|
||||||
|
verifyNoBrowserErrors();
|
||||||
|
});
|
||||||
|
|
||||||
it('should run for ng2', (done) => {
|
Benchmarks.forEach(benchmark => {
|
||||||
|
describe(benchmark.id, () => {
|
||||||
|
it('should work for createOnly', (done) => {
|
||||||
runTreeBenchmark({
|
runTreeBenchmark({
|
||||||
id: `deepTree.ng2.${worker.id}`,
|
id: 'createOnly',
|
||||||
url: 'all/benchmarks/src/tree/ng2/index.html',
|
benchmark,
|
||||||
work: worker.work,
|
prepare: () => $(CreateBtn).click(),
|
||||||
prepare: worker.prepare,
|
work: () => $(DestroyBtn).click()
|
||||||
}).then(done, done.fail);
|
}).then(done, done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should run for ng2 next', (done) => {
|
it('should work for createDestroy', (done) => {
|
||||||
runTreeBenchmark({
|
runTreeBenchmark({
|
||||||
id: `deepTree.ng2.next.${worker.id}`,
|
id: 'createDestroy',
|
||||||
url: 'all/benchmarks/src/tree/ng2_next/index.html',
|
benchmark,
|
||||||
ignoreBrowserSynchronization: true,
|
work: () => {
|
||||||
work: worker.work,
|
$(DestroyBtn).click();
|
||||||
prepare: worker.prepare,
|
$(CreateBtn).click();
|
||||||
// Can't use bundles as we use non exported code
|
}
|
||||||
extraParams: [{name: 'bundles', value: false}]
|
|
||||||
}).then(done, done.fail);
|
}).then(done, done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should run for ng2 static', (done) => {
|
it('should work for update', (done) => {
|
||||||
runTreeBenchmark({
|
runTreeBenchmark({id: 'update', benchmark, work: () => $(CreateBtn).click()})
|
||||||
id: `deepTree.ng2.static.${worker.id}`,
|
.then(done, done.fail);
|
||||||
url: 'all/benchmarks/src/tree/ng2_static/index.html',
|
|
||||||
work: worker.work,
|
|
||||||
prepare: worker.prepare,
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should run for ng2 switch', (done) => {
|
if (benchmark.buttons.indexOf(DetectChangesBtn) !== -1) {
|
||||||
runTreeBenchmark({
|
it('should work for detectChanges', (done) => {
|
||||||
id: `deepTree.ng2_switch.${worker.id}`,
|
runTreeBenchmark({
|
||||||
url: 'all/benchmarks/src/tree/ng2_switch/index.html',
|
id: 'detectChanges',
|
||||||
work: worker.work,
|
benchmark,
|
||||||
prepare: worker.prepare,
|
work: () => $(DetectChangesBtn).click(),
|
||||||
}).then(done, done.fail);
|
setup: () => $(DestroyBtn).click()
|
||||||
});
|
}).then(done, done.fail);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
it('should run for the baseline', (done) => {
|
|
||||||
runTreeBenchmark({
|
|
||||||
id: `deepTree.baseline.${worker.id}`,
|
|
||||||
url: 'all/benchmarks/src/tree/baseline/index.html',
|
|
||||||
ignoreBrowserSynchronization: true,
|
|
||||||
work: worker.work,
|
|
||||||
prepare: worker.prepare,
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should run for incremental-dom', (done) => {
|
|
||||||
runTreeBenchmark({
|
|
||||||
id: `deepTree.incremental_dom.${worker.id}`,
|
|
||||||
url: 'all/benchmarks/src/tree/incremental_dom/index.html',
|
|
||||||
ignoreBrowserSynchronization: true,
|
|
||||||
work: worker.work,
|
|
||||||
prepare: worker.prepare,
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should run for polymer binary tree', (done) => {
|
|
||||||
runTreeBenchmark({
|
|
||||||
id: `deepTree.polymer.${worker.id}`,
|
|
||||||
url: 'all/benchmarks/src/tree/polymer/index.html',
|
|
||||||
ignoreBrowserSynchronization: true,
|
|
||||||
work: worker.work,
|
|
||||||
prepare: worker.prepare,
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should run for polymer leaves', (done) => {
|
|
||||||
runTreeBenchmark({
|
|
||||||
id: `deepTree.polymer_leaves.${worker.id}`,
|
|
||||||
url: 'all/benchmarks/src/tree/polymer_leaves/index.html',
|
|
||||||
ignoreBrowserSynchronization: true,
|
|
||||||
work: worker.work,
|
|
||||||
prepare: worker.prepare,
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should run ng2 changedetection', (done) => {
|
|
||||||
runTreeBenchmark({
|
|
||||||
id: `deepTree.ng2.changedetection`,
|
|
||||||
url: 'all/benchmarks/src/tree/ng2/index.html',
|
|
||||||
work: () => $('#detectChanges').click(),
|
|
||||||
setup: () => $('#createDom').click(),
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should run ng2 next changedetection', (done) => {
|
|
||||||
runTreeBenchmark({
|
|
||||||
id: `deepTree.ng2.next.changedetection`,
|
|
||||||
url: 'all/benchmarks/src/tree/ng2_next/index.html',
|
|
||||||
work: () => $('#detectChanges').click(),
|
|
||||||
setup: () => $('#createDom').click(),
|
|
||||||
ignoreBrowserSynchronization: true,
|
|
||||||
// Can't use bundles as we use non exported code
|
|
||||||
extraParams: [{name: 'bundles', value: false}]
|
|
||||||
}).then(done, done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
function runTreeBenchmark(config: {
|
|
||||||
id: string,
|
|
||||||
url: string, ignoreBrowserSynchronization?: boolean,
|
|
||||||
work: () => any,
|
|
||||||
prepare?: () => any,
|
|
||||||
extraParams?: {name: string, value: any}[],
|
|
||||||
setup?: () => any
|
|
||||||
}) {
|
|
||||||
let params = [{name: 'depth', value: 11}];
|
|
||||||
if (config.extraParams) {
|
|
||||||
params = params.concat(config.extraParams);
|
|
||||||
}
|
|
||||||
return runBenchmark({
|
|
||||||
id: config.id,
|
|
||||||
url: config.url,
|
|
||||||
ignoreBrowserSynchronization: config.ignoreBrowserSynchronization,
|
|
||||||
params: params,
|
|
||||||
work: config.work,
|
|
||||||
prepare: config.prepare,
|
|
||||||
setup: config.setup
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function runTreeBenchmark({id, benchmark, prepare, setup, work}: {
|
||||||
|
id: string; benchmark: Benchmark, prepare ? () : void; setup ? () : void; work(): void;
|
||||||
|
}) {
|
||||||
|
let params = [{name: 'depth', value: 11}];
|
||||||
|
if (benchmark.extraParams) {
|
||||||
|
params = params.concat(benchmark.extraParams);
|
||||||
|
}
|
||||||
|
browser.rootEl = RootEl;
|
||||||
|
return runBenchmark({
|
||||||
|
id: `${benchmark.id}.${id}`,
|
||||||
|
url: benchmark.url,
|
||||||
|
ignoreBrowserSynchronization: benchmark.ignoreBrowserSynchronization,
|
||||||
|
params: params,
|
||||||
|
work: work,
|
||||||
|
prepare: prepare,
|
||||||
|
setup: setup
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -7,107 +7,57 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {openBrowser, verifyNoBrowserErrors} from 'e2e_util/e2e_util';
|
import {openBrowser, verifyNoBrowserErrors} from 'e2e_util/e2e_util';
|
||||||
import {$} from 'protractor';
|
import {$, browser} from 'protractor';
|
||||||
|
|
||||||
|
import {Benchmark, Benchmarks, CreateBtn, DestroyBtn, DetectChangesBtn, NumberOfChecksEl, RootEl} from './tree_data';
|
||||||
|
|
||||||
describe('tree benchmark spec', () => {
|
describe('tree benchmark spec', () => {
|
||||||
|
|
||||||
afterEach(verifyNoBrowserErrors);
|
let _oldRootEl: any;
|
||||||
|
beforeEach(() => _oldRootEl = browser.rootEl);
|
||||||
|
|
||||||
it('should work for ng2', () => {
|
afterEach(() => {
|
||||||
testTreeBenchmark({
|
browser.rootEl = _oldRootEl;
|
||||||
url: 'all/benchmarks/src/tree/ng2/index.html',
|
verifyNoBrowserErrors();
|
||||||
|
});
|
||||||
|
|
||||||
|
Benchmarks.forEach(benchmark => {
|
||||||
|
describe(benchmark.id, () => {
|
||||||
|
it('should work for createDestroy', () => {
|
||||||
|
openTreeBenchmark(benchmark);
|
||||||
|
$(CreateBtn).click();
|
||||||
|
expect($(RootEl).getText()).toContain('0');
|
||||||
|
$(DestroyBtn).click();
|
||||||
|
expect($(RootEl).getText()).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work for update', () => {
|
||||||
|
openTreeBenchmark(benchmark);
|
||||||
|
$(CreateBtn).click();
|
||||||
|
$(CreateBtn).click();
|
||||||
|
expect($(RootEl).getText()).toContain('A');
|
||||||
|
});
|
||||||
|
|
||||||
|
if (benchmark.buttons.indexOf(DetectChangesBtn) !== -1) {
|
||||||
|
it('should work for detectChanges', () => {
|
||||||
|
openTreeBenchmark(benchmark);
|
||||||
|
$(DetectChangesBtn).click();
|
||||||
|
expect($(NumberOfChecksEl).getText()).toContain('10');
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work for ng2 detect changes', () => {
|
function openTreeBenchmark(benchmark: Benchmark) {
|
||||||
let params = [{name: 'depth', value: 4}];
|
let params = [{name: 'depth', value: 4}];
|
||||||
openBrowser({url: 'all/benchmarks/src/tree/ng2/index.html', params});
|
if (benchmark.extraParams) {
|
||||||
$('#detectChanges').click();
|
params = params.concat(benchmark.extraParams);
|
||||||
expect($('#numberOfChecks').getText()).toContain('10');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work for ng2 next', () => {
|
|
||||||
testTreeBenchmark({
|
|
||||||
url: 'all/benchmarks/src/tree/ng2_next/index.html',
|
|
||||||
ignoreBrowserSynchronization: true,
|
|
||||||
// Can't use bundles as we use non exported code
|
|
||||||
extraParams: [{name: 'bundles', value: false}]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work for ng2 next detect changes', () => {
|
|
||||||
let params = [
|
|
||||||
{name: 'depth', value: 4},
|
|
||||||
// Can't use bundles as we use non exported code
|
|
||||||
{name: 'bundles', value: false}
|
|
||||||
];
|
|
||||||
openBrowser({
|
|
||||||
url: 'all/benchmarks/src/tree/ng2_next/index.html',
|
|
||||||
ignoreBrowserSynchronization: true, params
|
|
||||||
});
|
|
||||||
$('#detectChanges').click();
|
|
||||||
expect($('#numberOfChecks').getText()).toContain('10');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work for ng2 static', () => {
|
|
||||||
testTreeBenchmark({
|
|
||||||
url: 'all/benchmarks/src/tree/ng2_static/index.html',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work for ng2 switch', () => {
|
|
||||||
testTreeBenchmark({
|
|
||||||
url: 'all/benchmarks/src/tree/ng2_switch/index.html',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work for the baseline', () => {
|
|
||||||
testTreeBenchmark({
|
|
||||||
url: 'all/benchmarks/src/tree/baseline/index.html',
|
|
||||||
ignoreBrowserSynchronization: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work for incremental dom', () => {
|
|
||||||
testTreeBenchmark({
|
|
||||||
url: 'all/benchmarks/src/tree/incremental_dom/index.html',
|
|
||||||
ignoreBrowserSynchronization: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work for polymer binary tree', () => {
|
|
||||||
testTreeBenchmark({
|
|
||||||
url: 'all/benchmarks/src/tree/polymer/index.html',
|
|
||||||
ignoreBrowserSynchronization: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work for polymer leaves', () => {
|
|
||||||
testTreeBenchmark({
|
|
||||||
url: 'all/benchmarks/src/tree/polymer_leaves/index.html',
|
|
||||||
ignoreBrowserSynchronization: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function testTreeBenchmark(openConfig: {
|
|
||||||
url: string,
|
|
||||||
ignoreBrowserSynchronization?: boolean,
|
|
||||||
extraParams?: {name: string, value: any}[]
|
|
||||||
}) {
|
|
||||||
let params = [{name: 'depth', value: 4}];
|
|
||||||
if (openConfig.extraParams) {
|
|
||||||
params = params.concat(openConfig.extraParams);
|
|
||||||
}
|
}
|
||||||
|
browser.rootEl = RootEl;
|
||||||
openBrowser({
|
openBrowser({
|
||||||
url: openConfig.url,
|
url: benchmark.url,
|
||||||
ignoreBrowserSynchronization: openConfig.ignoreBrowserSynchronization,
|
ignoreBrowserSynchronization: benchmark.ignoreBrowserSynchronization,
|
||||||
params: params,
|
params: params,
|
||||||
});
|
});
|
||||||
$('#createDom').click();
|
|
||||||
expect($('#root').getText()).toContain('0');
|
|
||||||
$('#createDom').click();
|
|
||||||
expect($('#root').getText()).toContain('A');
|
|
||||||
$('#destroyDom').click();
|
|
||||||
expect($('#root').getText()).toEqual('');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h2>Params</h2>
|
||||||
|
<form>
|
||||||
|
Depth:
|
||||||
|
<input type="number" name="depth" placeholder="depth" value="9">
|
||||||
|
<br>
|
||||||
|
<button>Apply</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h2>Ng1 Tree Benchmark</h2>
|
||||||
|
<p>
|
||||||
|
<button id="destroyDom">destroyDom</button>
|
||||||
|
<button id="createDom">createDom</button>
|
||||||
|
<button id="detectChanges">detectChanges</button>
|
||||||
|
<button id="updateDomProfile">profile updateDom</button>
|
||||||
|
<button id="createDomProfile">profile createDom</button>
|
||||||
|
<button id="detectChangesProfile">profile detectChanges</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Change detection runs:<span id="numberOfChecks"></span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<tree id="root" data="initData">Loading...</tree>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var mainUrls = [
|
||||||
|
'/all/benchmarks/vendor/angular.js',
|
||||||
|
'../../bootstrap_plain.js'
|
||||||
|
];
|
||||||
|
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1];
|
||||||
|
if (mainUrl) {
|
||||||
|
mainUrls = [mainUrl];
|
||||||
|
}
|
||||||
|
mainUrls.forEach(function(mainUrl) {
|
||||||
|
document.write('<script src="' + mainUrl + '">\u003c/script>');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {bindAction, profile} from '../../util';
|
||||||
|
import {buildTree, emptyTree} from '../util';
|
||||||
|
|
||||||
|
import {addTreeToModule} from './tree';
|
||||||
|
|
||||||
|
declare var angular: any;
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
let detectChangesRuns = 0;
|
||||||
|
const numberOfChecksEl = document.getElementById('numberOfChecks') !;
|
||||||
|
|
||||||
|
addTreeToModule(angular.module('app', [])).run([
|
||||||
|
'$rootScope',
|
||||||
|
($rootScope: any) => {
|
||||||
|
function detectChanges() {
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
$rootScope.$digest();
|
||||||
|
}
|
||||||
|
detectChangesRuns += 10;
|
||||||
|
numberOfChecksEl.textContent = `${detectChangesRuns}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function noop() {}
|
||||||
|
|
||||||
|
function destroyDom() {
|
||||||
|
$rootScope.$apply(() => { $rootScope.initData = emptyTree; });
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDom() {
|
||||||
|
$rootScope.$apply(() => { $rootScope.initData = buildTree(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
bindAction('#destroyDom', destroyDom);
|
||||||
|
bindAction('#createDom', createDom);
|
||||||
|
bindAction('#detectChanges', detectChanges);
|
||||||
|
bindAction('#detectChangesProfile', profile(detectChanges, noop, 'detectChanges'));
|
||||||
|
bindAction('#updateDomProfile', profile(createDom, noop, 'update'));
|
||||||
|
bindAction('#createDomProfile', profile(createDom, destroyDom, 'create'));
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
angular.bootstrap(document.querySelector('tree'), ['app']);
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
import {TreeNode} from '../util';
|
||||||
|
|
||||||
|
declare var angular: any;
|
||||||
|
|
||||||
|
export function addTreeToModule(mod: any): any {
|
||||||
|
return mod
|
||||||
|
.directive(
|
||||||
|
'tree',
|
||||||
|
function() {
|
||||||
|
return {
|
||||||
|
scope: {data: '='},
|
||||||
|
template:
|
||||||
|
`<span ng-style="{'background-color': data.depth % 2 ? '' : 'grey'}"> {{data.value}} </span><tree-if data='data.right'></tree-if><tree-if data='data.left'></tree-if>`
|
||||||
|
};
|
||||||
|
})
|
||||||
|
// special directive for "if" as angular 1.3 does not support
|
||||||
|
// recursive components.
|
||||||
|
// Cloned from real ngIf directive, but using a lazily created transclude function.
|
||||||
|
.directive(
|
||||||
|
'treeIf',
|
||||||
|
[
|
||||||
|
'$compile', '$animate',
|
||||||
|
function($compile: any, $animate: any) {
|
||||||
|
let transcludeFn: any;
|
||||||
|
return {
|
||||||
|
transclude: 'element',
|
||||||
|
priority: 600,
|
||||||
|
terminal: true,
|
||||||
|
$$tlb: true,
|
||||||
|
link: function($scope: any, $element: any, $attr: any, ctrl: any) {
|
||||||
|
if (!transcludeFn) {
|
||||||
|
const template = '<tree data="' + $attr.data + '"></tree>';
|
||||||
|
transcludeFn = $compile(template);
|
||||||
|
}
|
||||||
|
let childElement: any, childScope: any;
|
||||||
|
$scope.$watch($attr.data, function ngIfWatchAction(value: any) {
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
if (!childScope) {
|
||||||
|
childScope = $scope.$new();
|
||||||
|
transcludeFn(childScope, function(clone: any) {
|
||||||
|
childElement = clone;
|
||||||
|
$animate.enter(clone, $element.parent(), $element);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (childScope) {
|
||||||
|
childScope.$destroy();
|
||||||
|
childScope = null;
|
||||||
|
}
|
||||||
|
if (childElement) {
|
||||||
|
$animate.leave(childElement);
|
||||||
|
childElement = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.config([
|
||||||
|
'$compileProvider',
|
||||||
|
function($compileProvider: any) { $compileProvider.debugInfoEnabled(false); }
|
||||||
|
]);
|
||||||
|
}
|
Loading…
Reference in New Issue