build: move zone.js to angular repo (#30962)

PR Close #30962
This commit is contained in:
JiaLiPassion
2019-06-01 00:56:07 +09:00
committed by Kara Erickson
parent 7b3bcc23af
commit 5eb7426216
271 changed files with 30890 additions and 19 deletions

View File

@ -0,0 +1,59 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Zone.js Basic Demo</title>
<link rel="stylesheet" href="css/style.css">
<script src="../dist/zone.js"></script>
<script src="../dist/long-stack-trace-zone.js"></script>
</head>
<body>
<h1>Basic Example</h1>
<button id="b1">Bind Error</button>
<button id="b2">Cause Error</button>
<script>
/*
* This is a simple example of async stack traces with zones
*/
function main () {
b1.addEventListener('click', bindSecondButton);
}
/*
* What if your stack trace could tell you what
* order the user pushed the buttons from the stack trace?
*
* What if you could log this back to the server?
*
* Think of how much more productive your debugging could be!
*/
function bindSecondButton () {
b2.addEventListener('click', throwError);
}
function throwError () {
throw new Error('aw shucks');
}
/*
* Bootstrap the app
*/
//main();
Zone.current.fork(
{
onHandleError: function (parentZoneDelegate, currentZone, targetZone, error) {
console.log(error.stack);
}
}
).fork(Zone.longStackTraceZoneSpec).run(main);
</script>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Zone.js addEventListenerBenchmark</title>
<link rel="stylesheet" href="../css/style.css">
<script src="../../dist/zone.js"></script>
</head>
<body>
<h1>addEventListener Benchmark</h1>
<h2>No Zone</h2>
<button id="b1">Add/Remove same callback</button>
<button id="b2">Add/Remove different callback</button>
<h2>With Zone</h2>
<button id="b3">Add/Remove same callback</button>
<button id="b4">Add/Remove different callback</button>
<div id="rootDiv"></div>
<script>
b1.addEventListener('click', function () { addRemoveCallback(true, false); });
b2.addEventListener('click', function () { addRemoveCallback(false, false); });
b3.addEventListener('click', function () { addRemoveCallback(true, true); });
b4.addEventListener('click', function () { addRemoveCallback(false, true); });
var divs = [];
var callbacks = [];
var size = 100000;
for(var i = 0; i < size; i++) {
var div = document.createElement("div");
var callback = (function(i) { return function() { console.log(i); }; })(i);
rootDiv.appendChild(div);
divs[i] = div;
callbacks[i] = callback;
}
function addRemoveCallback(reuse, useZone) {
var start = performance.now();
var callback = callbacks[0];
for(var i = 0; i < size; i++) {
var div = divs[i];
if (!reuse) callback = callbacks[i];
if (useZone)
div.addEventListener('click', callback);
else
div.__zone_symbol__addEventListener('click', callback);
}
for(var i = 0; i < size; i++) {
var div = divs[i];
if (!reuse) callback = callbacks[i];
if (useZone)
div.removeEventListener('click', callback);
else
div.__zone_symbol__removeEventListener('click', callback);
}
var end = performance.now();
console.log(useZone ? 'use zone': 'native', reuse ? 'reuse' : 'new', end - start, 'ms');
}
</script>
</body>
</html>

View File

@ -0,0 +1,50 @@
/**
* @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
*/
const events = require('events');
const EventEmitter = events.EventEmitter;
require('../../dist/zone-node');
const emitters = [];
const callbacks = [];
const size = 100000;
for (let i = 0; i < size; i++) {
const emitter = new EventEmitter();
const callback = (function(i) { return function() { console.log(i); }; })(i);
emitters[i] = emitter;
callbacks[i] = callback;
}
function addRemoveCallback(reuse, useZone) {
const start = new Date();
let callback = callbacks[0];
for (let i = 0; i < size; i++) {
const emitter = emitters[i];
if (!reuse) callback = callbacks[i];
if (useZone)
emitter.on('msg', callback);
else
emitter.__zone_symbol__addListener('msg', callback);
}
for (let i = 0; i < size; i++) {
const emitter = emitters[i];
if (!reuse) callback = callbacks[i];
if (useZone)
emitter.removeListener('msg', callback);
else
emitter.__zone_symbol__removeListener('msg', callback);
}
const end = new Date();
console.log(useZone ? 'use zone' : 'native', reuse ? 'reuse' : 'new');
console.log('Execution time: %dms', end - start);
}
addRemoveCallback(false, false);
addRemoveCallback(false, true);
addRemoveCallback(true, false);
addRemoveCallback(true, true);

View File

@ -0,0 +1,95 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Counting Pending Tasks</title>
<link rel="stylesheet" href="css/style.css">
<script src="../dist/zone.js"></script>
<script src="js/counting-zone.js"></script>
</head>
<body>
<h1>Counting Pending Tasks</h1>
<p>We want to know about just the events from a single mouse click
while a bunch of other stuff is happening on the page</p>
<p>This is useful in E2E testing. Because you know when there are
no async tasks, you avoid adding timeouts that wait for tasks that
run for an indeterminable amount of time.</p>
<button id="b1">Start</button>
<p id="output"></p>
<script>
/*
* Zone that counts pending async tasks
*/
const outputElem = document.getElementById('output');
const countingZoneSpec = Zone['countingZoneSpec'];
const myCountingZone = Zone.current.fork(countingZoneSpec).fork({
onScheduleTask(parent, current, target, task) {
parent.scheduleTask(target, task);
console.log('Scheduled ' + task.source + ' => ' + task.data.handleId);
outputElem.innerText = countingZoneSpec.counter();
},
onInvokeTask(parent, current, target, task) {
console.log('Invoking ' + task.source + ' => ' + task.data.handleId);
parent.invokeTask(target, task);
outputElem.innerText = countingZoneSpec.counter();
},
onHasTask(parent, current, target, hasTask) {
if (hasTask.macroTask) {
console.log("There are outstanding MacroTasks.");
} else {
console.log("All MacroTasks have been completed.");
}
}
});
/*
* We want to profile just the actions that are a result of this button, so with
* a single line of code, we can run `main` in the countingZone
*/
b1.addEventListener('click', function () {
myCountingZone.run(main);
});
/*
* Spawns a bunch of setTimeouts which in turn spawn more setTimeouts!
* This is a boring way to simulate HTTP requests and other async actions.
*/
function main () {
for (var i = 0; i < 10; i++) {
recur(i, 800);
}
}
function recur (x, t) {
if (x > 0) {
setTimeout(function () {
for (var i = x; i < 8; i++) {
recur(x - 1, Math.random()*t);
}
}, t);
}
}
/*
* There may be other async actions going on in the background.
* Because this is not in the zone, our profiling ignores it.
* Nice.
*/
function noop () {
setTimeout(noop, 10*Math.random());
}
noop();
</script>
</body>
</html>

View File

@ -0,0 +1,8 @@
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}

View File

@ -0,0 +1,21 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Zone.js Examples</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>Examples</h1>
<ol>
<li><a href="basic.html">Tracing user actions with long stack traces</a></li>
<li><a href="counting.html">Counting Tasks</a></li>
<li><a href="profiling.html">Profiling Across Tasks</a></li>
<li><a href="throttle.html">Throttle</a></li>
<li><a href="web-socket.html">WebSocket</a></li>
</ol>
</body>
</html>

View File

@ -0,0 +1,33 @@
/*
* See example/counting.html
*/
Zone['countingZoneSpec'] = {
name: 'counterZone',
// setTimeout
onScheduleTask: function(delegate, current, target, task) {
this.data.count += 1;
delegate.scheduleTask(target, task);
},
// fires when...
// - clearTimeout
// - setTimeout finishes
onInvokeTask: function(delegate, current, target, task, applyThis, applyArgs) {
delegate.invokeTask(target, task, applyThis, applyArgs);
this.data.count -= 1;
},
onHasTask: function(delegate, current, target, hasTask) {
if (this.data.count === 0 && !this.data.flushed) {
this.data.flushed = true;
target.run(this.onFlush);
}
},
counter: function() { return this.data.count; },
data: {count: 0, flushed: false},
onFlush: function() {}
};

View File

@ -0,0 +1,126 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Zones Profiling</title>
<link rel="stylesheet" href="css/style.css">
<script>
__Zone_disable_Error = true;
__Zone_disable_on_property = true;
__Zone_disable_geolocation = true;
__Zone_disable_toString = true;
__Zone_disable_blocking = true;
__Zone_disable_PromiseRejectionEvent = true;
</script>
<script src="../dist/zone.js"></script>
<script src="../dist/long-stack-trace-zone.js"></script>
</head>
<body>
<h1>Profiling with Zones</h1>
<button id="b1">Start Profiling</button>
<script>
/*
* Let's say we want to know the CPU cost from some action
* that includes async tasks. We can do this with zones!
*/
/*
* For this demo, we're going to sort an array using an async
* algorithm when a button is pressed.
*/
function sortAndPrintArray (unsortedArray) {
profilingZoneSpec.reset();
asyncBogosort(unsortedArray, function (sortedArray) {
console.log(sortedArray);
console.log('sorting took ' + profilingZoneSpec.time() + ' of CPU time');
});
}
/*
* This is a really efficient algorithm.
*
* First, check if the array is sorted.
* - If it is, call the wrapCallback
* - If it isn't, randomize the array and recur
*
* This implementation is async because JavaScript
*/
function asyncBogosort (arr, cb) {
setTimeout(function () {
if (isSorted(arr)) {
cb(arr);
} else {
var newArr = arr.slice(0);
newArr.sort(function () {
return Math.random() - 0.5;
});
asyncBogosort(newArr, cb);
}
}, 0);
}
function isSorted (things) {
for (var i = 1; i < things.length; i += 1) {
if (things[i] < things[i - 1]) {
return false;
}
}
return true;
}
/*
* Bind button
*/
function main () {
var unsortedArray = [3,4,1,2,7];
b1.addEventListener('click', function () {
sortAndPrintArray(unsortedArray);
});
}
/*
* This zone starts a timer at the start of each taskEnv,
* and stops it at the end. It accumulates the total run
* time internally, exposing it via `zone.time()`
*
* Note that this is the time the CPU is spending doing
* bogosort, as opposed to the time from the start
* of the algorithm until it's completion.
*/
var profilingZoneSpec = (function () {
var time = 0,
// use the high-res timer if available
timer = performance ?
performance.now.bind(performance) :
Date.now.bind(Date);
return {
onInvokeTask: function (delegate, current, target, task, applyThis, applyArgs) {
this.start = timer();
delegate.invokeTask(target, task, applyThis, applyArgs);
time += timer() - this.start;
},
time: function () {
return Math.floor(time*100) / 100 + 'ms';
},
reset: function () {
time = 0;
}
};
}());
/*
* Bootstrap the app
*/
Zone.current.fork(profilingZoneSpec).run(main);
</script>
</body>
</html>

View File

@ -0,0 +1,91 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Zones throttle</title>
<link rel="stylesheet" href="css/style.css">
<script src="../dist/zone.js"></script>
<script src="../dist/long-stack-trace-zone.js"></script>
</head>
<body>
<h1>Throttle Example</h1>
<button id="b2">Error</button>
<script>
/*
* In this example, we have a button that makes some request
* to our server. We want to only make the request once per
* 1s, so we use a `throttle` helper. If the request fails,
* it's difficult to see where the failure originated from.
*
* Thankfully, we can use zones to preserve the stack even
* across async tasks to get a better picture of the control
* flow of the app.
*/
var throttleMakeRequest;
/*
* Start the app
* Bind listeners
*/
function bootstrap () {
b2.addEventListener('click', throttleMakeRequest);
}
/*
* Makes a request to the server
* Will only make the request once every 1000ms
*/
throttleMakeRequest = throttle(function () {
makeRequestToServer(handleServerResponse);
}, 1000);
/*
* Pretend this makes a request to a server
*/
function makeRequestToServer (cb) {
setTimeout(cb, 100);
}
function handleServerResponse (err, data) {
throw new Error('Oops');
}
/*
* Returns a fn that can only be called once
* per `time` milliseconds
*/
function throttle (fn, time) {
var id = null;
if (typeof time !== 'number') {
time = 0;
}
return function () {
if (!id) {
id = setTimeout(function () {
id = null;
fn();
}, time);
}
};
}
/*
* Start the application
*
* If we start the application with `zone.run`, we
* get long stack traces in the console!
*/
//bootstrap();
Zone.current.fork(Zone.longStackTraceZoneSpec).run(bootstrap);
</script>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebSockets with Zones</title>
<link rel="stylesheet" href="css/style.css">
<script src="../dist/zone.js"></script>
</head>
<body>
<p>
Ensure that you started <code>node test/ws-server.js</code> before loading
this page. Then check console output.
</p>
<script>
var ws = new WebSocket('ws://localhost:8001');
ws.onopen = function() {
Zone.current.fork({properties: {secretPayload: 'bah!'}, name: 'secrete-zone'}).run(function() {
ws.onmessage = function(eventListener) {
if (Zone.current.get('secretPayload') === 'bah!') {
console.log("The current zone (id: %s) has secretPayload. Zones are working!",
Zone.current.name);
} else {
console.error('Secret payload not found where expected! Zones are not working! :-(', Zone.current.name);
}
};
console.log('Setting secret payload in the current zone (id: %s)', Zone.current.name);
});
ws.send('hello!');
};
</script>
</body>
</html>