Socket
Socket
Sign inDemoInstall

zone.js

Package Overview
Dependencies
Maintainers
1
Versions
124
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zone.js - npm Package Compare versions

Comparing version 0.2.1 to 0.2.2

test/patch/element.spec.js

34

counting-zone.js
/*
* See example/counting.html
*/
Zone.countingZone = {
'-onZoneCreated': function () {
Zone.countingZone.counter += 1;
// setTimeout
'+enqueueTask': function () {
this.data.count += 1;
},
// fires when...
// - clearTimeout
// - setTimeout finishes
'-dequeueTask': function () {
this.data.count -= 1;
},
'+afterTask': function () {
Zone.countingZone.counter -= 1;
if (Zone.countingZone.counter <= 0) {
Zone.countingZone.counter = 0;
this.onFlush();
if (this.data.count === 0 && !this.data.flushed) {
this.data.flushed = true;
this.run(this.onFlush);
}
},
'-run': function () {
Zone.countingZone.counter = 0;
},
counter: function () {
return Zone.countingZone.counter;
return this.data.count;
},
data: {
count: 0,
flushed: false
},
onFlush: function () {}
};

@@ -9,3 +9,3 @@ // Karma configuration

'*-zone.js',
'test/*.spec.js'
'test/**/*.spec.js'
],

@@ -12,0 +12,0 @@

@@ -11,9 +11,7 @@ /*

Zone.Stacktrace.prototype.get = function () {
var frames = this._e.stack.split('\n');
var markerIndex;
for (var markerIndex = frames.length - 1; markerIndex >= 0; markerIndex -= 1) {
if (frames[markerIndex].indexOf('marker@') === 0) {
return frames.slice(markerIndex+1).join('\n');
}
if (zone.stackFramesFilter) {
return this._e.stack.
split('\n').
filter(zone.stackFramesFilter).
join('\n');
}

@@ -50,4 +48,11 @@ return this._e.stack;

getLongStacktrace: function (exception) {
var trace = [exception.stack];
var trace = [];
var zone = this;
if (zone.stackFramesFilter) {
trace.push(exception.stack.split('\n').
filter(zone.stackFramesFilter).
join('\n'));
} else {
trace.push(exception.stack);
}
var now = Date.now();

@@ -64,2 +69,6 @@ while (zone && zone.constructedAtException) {

stackFramesFilter: function (line) {
return line.indexOf('zone.js') === -1;
},
onError: function (exception) {

@@ -66,0 +75,0 @@ var reporter = this.reporter || console.log.bind(console);

{
"name": "zone.js",
"version": "0.2.1",
"version": "0.2.2",
"description": "Zones for JavaScript",

@@ -18,3 +18,3 @@ "main": "zone.js",

"author": "Brian Ford",
"license": "MIT",
"license": "Apache 2.0",
"bugs": {

@@ -21,0 +21,0 @@ "url": "https://github.com/btford/zone.js/issues"

@@ -63,2 +63,9 @@ # Zone.js

## Usage
To start using Zones, you need to include the `zone.js` script in this package onto
your page. This script should appear in the `<head>` of your HTML file before any other
scripts, including shims/polyfills.
## Examples

@@ -225,2 +232,12 @@

### `zone.enqueueTask`
This hook is called when a function is registered with the VM.
For instance `setTimeout` and `addEventListener`.
### `zone.dequeueTask`
This hook is called when a function is unregistered with the VM.
For instance `clearTimeout` and `removeEventListener`.
### `zone.setTimeout`, `zone.setInterval`, `zone.alert`, `zone.prompt`

@@ -227,0 +244,0 @@

'use strict';
describe('Zone.countingZone', function () {
var flushSpy = jasmine.createSpy('flush'),
countingZone = zone.fork(Zone.countingZone).fork({
onFlush: flushSpy
});
var flushSpy, countingZone;
beforeEach(function () {
jasmine.Clock.useMock();
flushSpy.reset();
flushSpy = jasmine.createSpy('flush');
countingZone = zone.fork(Zone.longStackTraceZone).
fork(Zone.countingZone).
fork({
onFlush: flushSpy
});
});
it('should flush at the end of a run', function () {
countingZone.run(function () {});
expect(flushSpy).toHaveBeenCalled();
countingZone.run(function () {
expect(countingZone.counter()).toBe(0);
});
expect(countingZone.counter()).toBe(0);
expect(flushSpy.calls.length).toBe(1);
});
it('should work', function () {
it('should work with setTimeout', function () {
var latch;
runs(function () {
countingZone.run(function () {
setTimeout(function () {
latch = true;
}, 0);
expect(countingZone.counter()).toBe(1);
});
});
waitsFor(function () {
return latch;
});
runs(function () {
expect(countingZone.counter()).toBe(0);
})
});
it('should work with clearTimeout', function () {
var latch = false;
countingZone.run(function () {
var id = setTimeout(function () {
latch = true;
}, 0);
expect(countingZone.counter()).toBe(1);
clearTimeout(id);
expect(countingZone.counter()).toBe(0);
});
});
setTimeout(function () {}, 0);
it('should work with setInterval', function () {
var latch = 0, id;
runs(function () {
countingZone.run(function () {
id = setInterval(function () {
latch += 1;
}, 0);
expect(countingZone.counter()).toBe(1);
});
});
waitsFor(function () {
return latch === 2;
}, 100, 'latch to increment');
runs(function () {
expect(countingZone.counter()).toBe(1);
clearInterval(id);
});
});
//jasmine.Clock.tick(0);
it('should work with clearInterval', function () {
var id;
countingZone.run(function () {
id = setInterval(function () {
latch += 1;
}, 0);
expect(countingZone.counter()).toBe(1);
clearInterval(id);
expect(countingZone.counter()).toBe(0);
});
});
//expect(countingZone.counter()).toBe(0);
it('should work with addEventListener', function () {
var elt = document.createElement('button');
var clicked = false;
runs(function () {
countingZone.run(main);
});
//jasmine.Clock.tick(0);
function main () {
expect(countingZone.counter()).toBe(0);
elt.addEventListener('click', onClick);
expect(countingZone.counter()).toBe(1);
elt.click();
function onClick () {
expect(countingZone.counter()).toBe(1);
elt.removeEventListener('click', onClick);
expect(countingZone.counter()).toBe(0);
clicked = true;
}
expect(countingZone.counter()).toBe(0);
}
waitsFor(function () {
return clicked;
}, 10, 'the thing');
runs(function () {
expect(flushSpy.calls.length).toBe(1);
});
});
});
'use strict';
describe('Zone.patch', function () {
describe('longStackTraceZone', function () {
var log;

@@ -32,2 +31,20 @@

});
it('should filter based on stackFramesFilter', function () {
lstz.fork({
stackFramesFilter: function (line) {
return line.indexOf('jasmine.js') === -1;
}
}).run(function () {
setTimeout(function () {
setTimeout(function () {
throw new Error('hello');
}, 0);
}, 0);
});
jasmine.Clock.tick(0);
expect(log[1]).not.toContain('jasmine.js');
});
});
'use strict';
describe('Zone', function () {
describe('Zone.patch', function () {
beforeEach(function () {

@@ -10,447 +9,2 @@ zone.mark = 'root';

describe('setTimeout', function () {
beforeEach(function () {
jasmine.Clock.useMock();
});
it('should work with setTimeout', function () {
var childZone = window.zone.fork({
mark: 'child'
});
expect(zone.mark).toEqual('root');
childZone.run(function() {
expect(zone.mark).toEqual('child');
expect(zone).toEqual(childZone);
window.setTimeout(function() {
// creates implied zone in all callbacks.
expect(zone).not.toEqual(childZone);
expect(zone.parent).toEqual(childZone);
expect(zone.mark).toEqual('child'); // proto inherited
}, 0);
expect(zone.mark).toEqual('child');
});
expect(zone.mark).toEqual('root');
});
it('should allow canceling of fns registered with setTimeout', function () {
var spy = jasmine.createSpy();
var cancelId = window.setTimeout(spy, 0);
window.clearTimeout(cancelId);
jasmine.Clock.tick(1);
expect(spy).not.toHaveBeenCalled();
});
});
describe('setInterval', function () {
beforeEach(function () {
jasmine.Clock.useMock();
});
it('should work with setInterval', function () {
var childZone = window.zone.fork({
mark: 'child'
});
expect(zone.mark).toEqual('root');
childZone.run(function() {
expect(zone.mark).toEqual('child');
expect(zone).toEqual(childZone);
var cancelId = window.setInterval(function() {
// creates implied zone in all callbacks.
expect(zone).not.toEqual(childZone);
expect(zone.parent).toEqual(childZone);
expect(zone.mark).toEqual('child'); // proto inherited
}, 10);
jasmine.Clock.tick(11);
expect(zone.mark).toEqual('child');
clearInterval(cancelId);
});
expect(zone.mark).toEqual('root');
});
});
describe('requestAnimationFrame', function () {
var flag, hasParent, skip = false;
it('should work', function (done) {
if (!window.requestAnimationFrame) {
console.log('WARNING: skipping requestAnimationFrame test (missing this API)');
return;
}
// Some browsers (especially Safari) do not fire requestAnimationFrame
// if they are offscreen. We can disable this test for those browsers and
// assume the patch works if setTimeout works, since they are mechanically
// the same
runs(function() {
flag = false;
window.requestAnimationFrame(function () {
flag = true;
});
setTimeout(function () {
skip = true;
flag = true;
console.log('WARNING: skipping requestAnimationFrame test (not firing rAF)');
}, 50);
});
waitsFor(function() {
return flag;
}, "requestAnimationFrame to run", 100);
runs(function() {
flag = false;
hasParent = false;
window.requestAnimationFrame(function () {
hasParent = !!window.zone.parent;
flag = true;
});
});
waitsFor(function() {
return flag || skip;
}, "requestAnimationFrame to run", 100);
runs(function() {
expect(hasParent || skip).toBe(true);
});
});
});
describe('webkitRequestAnimationFrame', function () {
var flag, hasParent, skip = false;
it('should work', function (done) {
if (!window.webkitRequestAnimationFrame) {
console.log('WARNING: skipping webkitRequestAnimationFrame test (missing this API)');
return;
}
// Some browsers (especially Safari) do not fire webkitRequestAnimationFrame
// if they are offscreen. We can disable this test for those browsers and
// assume the patch works if setTimeout works, since they are mechanically
// the same
runs(function() {
flag = false;
window.webkitRequestAnimationFrame(function () {
flag = true;
});
setTimeout(function () {
skip = true;
flag = true;
console.log('WARNING: skipping webkitRequestAnimationFrame test (not firing rAF)');
}, 50);
});
waitsFor(function() {
return flag;
}, 'webkitRequestAnimationFrame to run', 100);
runs(function() {
flag = false;
hasParent = false;
window.webkitRequestAnimationFrame(function () {
hasParent = !!window.zone.parent;
flag = true;
});
});
waitsFor(function() {
return flag || skip;
}, 'webkitRequestAnimationFrame to run', 100);
runs(function() {
expect(hasParent || skip).toBe(true);
});
});
});
describe('Promise', function () {
var flag, hasParent;
beforeEach(function () {
jasmine.Clock.useMock();
flag = false;
hasParent = false;
});
it('should work with .then', function () {
if (!window.Promise) {
console.log('WARNING: skipping Promise test (missing this API)');
return;
}
runs(function () {
new Promise(function (resolve) {
setTimeout(resolve, 0);
}).then(function () {
hasParent = !!window.zone.parent;
flag = true;
});
jasmine.Clock.tick(1);
});
waitsFor(function() {
return flag;
}, 'promise to resolve', 100);
runs(function() {
expect(hasParent).toBe(true);
});
});
it('should work with .catch', function () {
if (!window.Promise) {
return;
}
runs(function() {
new Promise(function (resolve, reject) {
setTimeout(reject, 0);
}).catch(function () {
hasParent = !!window.zone.parent;
flag = true;
});
jasmine.Clock.tick(1);
});
waitsFor(function() {
return flag;
}, "promise to reject", 100);
runs(function() {
expect(hasParent).toBe(true);
});
});
});
describe('element', function () {
var button;
beforeEach(function () {
button = document.createElement('button');
document.body.appendChild(button);
});
afterEach(function () {
document.body.removeChild(button);
button.remove();
});
it('should work with addEventListener', function () {
var zoneHasParent;
button.addEventListener('click', function () {
zoneHasParent = !!window.zone.parent;
});
button.click();
expect(zoneHasParent).toEqual(true);
});
it('should respect removeEventListener', function () {
var log = '';
var logOnClick = function logOnClick () {
log += 'a';
};
button.addEventListener('click', logOnClick);
button.click();
expect(log).toEqual('a');
button.removeEventListener('click', logOnClick);
button.click();
expect(log).toEqual('a');
});
it('should work with onclick', function () {
var zoneHasParent;
button.onclick = function () {
zoneHasParent = !!window.zone.parent;
};
button.click();
expect(zoneHasParent).toEqual(true);
});
it('should only allow one onclick handler', function () {
var log = '';
button.onclick = function () {
log += 'a';
};
button.onclick = function () {
log += 'b';
};
button.click();
expect(log).toEqual('b');
});
it('should handle removing onclick', function () {
var log = '';
button.onclick = function () {
log += 'a';
};
button.onclick = null;
button.click();
expect(log).toEqual('');
});
});
describe('MutationObserver', function () {
it('should work', function () {
if (!window.MutationObserver) {
console.log('WARNING: skipping MutationObserver test (missing this API)');
return;
}
var flag = false,
elt = document.createElement('div'),
hasParent;
runs(function () {
var ob = new MutationObserver(function () {
hasParent = !!window.zone.parent;
flag = true;
});
ob.observe(elt, {
childList: true
});
elt.innerHTML = '<p>hey</p>';
});
waitsFor(function() {
return flag;
}, 'mutation observer to fire', 100);
runs(function() {
expect(hasParent).toBe(true);
});
});
});
describe('WebKitMutationObserver', function () {
it('should work', function () {
if (!window.WebKitMutationObserver) {
console.log('WARNING: skipping WebKitMutationObserver test (missing this API)');
return;
}
var flag = false,
elt = document.createElement('div'),
hasParent;
runs(function () {
var ob = new WebKitMutationObserver(function () {
hasParent = !!window.zone.parent;
flag = true;
});
ob.observe(elt, {
childList: true
});
elt.innerHTML = '<p>hey</p>';
});
waitsFor(function() {
return flag;
}, 'mutation observer to fire', 100);
runs(function() {
expect(hasParent).toBe(true);
});
});
});
describe('XMLHttpRequest', function () {
it('should work with onreadystatechange', function () {
var flag = false,
hasParent;
runs(function () {
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
hasParent = !!window.zone.parent;
flag = true;
};
req.open('get', '/', true);
req.send();
});
waitsFor(function() {
return flag;
}, 'HTTP request to resolve', 100);
runs(function() {
expect(hasParent).toBe(true);
});
});
it('should work with onprogress', function () {
var flag = false,
hasParent;
runs(function () {
var req = new XMLHttpRequest();
req.onprogress = function () {
hasParent = !!window.zone.parent;
flag = true;
};
req.open('get', '/', true);
req.send();
});
waitsFor(function() {
return flag;
}, 'HTTP request to resolve', 100);
runs(function() {
expect(hasParent).toBe(true);
});
});
it('should preserve other setters', function () {
var req = new XMLHttpRequest();
req.open('get', '/', true);
req.send();
req.responseType = 'document';
expect(req.responseType).toBe('document');
});
});
describe('hooks', function () {

@@ -578,2 +132,13 @@

describe('fork', function () {
it('should fork deep copy', function () {
var protoZone = { too: { deep: true } },
a = zone.fork(protoZone),
b = zone.fork(protoZone);
expect(a.too).not.toBe(b.too);
expect(a.too).toEqual(b.too);
});
});
});

@@ -580,0 +145,0 @@

@@ -42,3 +42,5 @@ 'use strict';

} else {
zone[property] = data[property];
zone[property] = (typeof data[property] === 'object') ?
JSON.parse(JSON.stringify(data[property])) :
data[property];
}

@@ -59,3 +61,4 @@ });

bind: function (fn) {
bind: function (fn, skipEnqueue) {
skipEnqueue || this.enqueueTask(fn);
var zone = this.fork();

@@ -67,2 +70,10 @@ return function zoneBoundFn() {

bindOnce: function (fn) {
return this.bind(function () {
var result = fn.apply(this, arguments);
zone.dequeueTask(fn);
return result;
});
},
run: function run (fn, applyTo, applyWith) {

@@ -94,14 +105,83 @@ applyWith = applyWith || [];

onZoneCreated: function () {},
afterTask: function () {}
afterTask: function () {},
enqueueTask: function () {},
dequeueTask: function () {}
};
Zone.patchFn = function (obj, fnNames) {
Zone.patchSetClearFn = function (obj, fnNames) {
fnNames.map(function (name) {
return name[0].toUpperCase() + name.substr(1);
}).
forEach(function (name) {
var setName = 'set' + name;
var clearName = 'clear' + name;
var delegate = obj[setName];
if (delegate) {
var ids = {};
if (setName === 'setInterval') {
zone[setName] = function (fn) {
var id;
arguments[0] = function () {
delete ids[id];
return fn.apply(this, arguments);
};
var args = Zone.bindArguments(arguments);
id = delegate.apply(obj, args);
ids[id] = true;
return id;
};
} else {
zone[setName] = function (fn) {
var id;
arguments[0] = function () {
delete ids[id];
return fn.apply(this, arguments);
};
var args = Zone.bindArgumentsOnce(arguments);
id = delegate.apply(obj, args);
ids[id] = true;
return id;
};
}
obj[setName] = function () {
return zone[setName].apply(this, arguments);
};
var clearDelegate = obj[clearName];
zone[clearName] = function (id) {
if (ids[id]) {
delete ids[id];
zone.dequeueTask();
}
return clearDelegate.apply(this, arguments);
};
obj[clearName] = function () {
return zone[clearName].apply(this, arguments);
};
}
});
};
Zone.patchSetFn = function (obj, fnNames) {
fnNames.forEach(function (name) {
var delegate = obj[name];
if (delegate) {
zone[name] = function () {
return delegate.apply(obj, Zone.bindArguments(arguments));
zone[name] = function (fn) {
arguments[0] = function () {
return fn.apply(this, arguments);
};
var args = Zone.bindArgumentsOnce(arguments);
return delegate.apply(obj, args);
};
obj[name] = function marker () {
obj[name] = function () {
return zone[name].apply(this, arguments);

@@ -133,2 +213,12 @@ };

Zone.bindArgumentsOnce = function (args) {
for (var i = args.length - 1; i >= 0; i--) {
if (typeof args[i] === 'function') {
args[i] = zone.bindOnce(args[i]);
}
}
return args;
};
Zone.patchableFn = function (obj, fnNames) {

@@ -212,3 +302,5 @@ fnNames.forEach(function (name) {

arguments[1] = arguments[1]._bound || arguments[1];
return removeDelegate.apply(this, arguments);
var result = removeDelegate.apply(this, arguments);
zone.dequeueTask(fn);
return result;
};

@@ -218,8 +310,13 @@ };

Zone.patch = function patch () {
Zone.patchFn(window, [
'setTimeout',
'setInterval',
Zone.patchSetClearFn(window, [
'timeout',
'interval',
'immediate'
]);
Zone.patchSetFn(window, [
'requestAnimationFrame',
'webkitRequestAnimationFrame'
]);
Zone.patchableFn(window, ['alert', 'prompt']);

@@ -277,4 +374,5 @@

}
Zone.patchClass('MutationObserver');
Zone.patchClass('WebKitMutationObserver');
Zone.patchMutationObserverClass('MutationObserver');
Zone.patchMutationObserverClass('WebKitMutationObserver');
Zone.patchRegisterElement();
};

@@ -299,5 +397,3 @@

Zone.patchViaPropertyDescriptor = function () {
Zone.patchProperties(HTMLElement.prototype, Zone.eventNames.map(function (property) {
return 'on' + property;
}));
Zone.patchProperties(HTMLElement.prototype, Zone.onEventNames);
Zone.patchProperties(XMLHttpRequest.prototype);

@@ -326,3 +422,3 @@ };

// TODO: wrap some native API
// wrap some native API on `window`
Zone.patchClass = function (className) {

@@ -372,3 +468,83 @@ var OriginalClass = window[className];

// wrap some native API on `window`
Zone.patchMutationObserverClass = function (className) {
var OriginalClass = window[className];
if (!OriginalClass) {
return;
}
window[className] = function (fn) {
this._o = new OriginalClass(zone.bind(fn, true));
};
var instance = new OriginalClass(function () {});
window[className].prototype.disconnect = function () {
var result = this._o.disconnect.apply(this._o, arguments);
this._active && zone.dequeueTask();
this._active = false;
return result;
};
window[className].prototype.observe = function () {
if (!this._active) {
zone.enqueueTask();
}
dump(this._active)
this._active = true;
return this._o.observe.apply(this._o, arguments);
};
var prop;
for (prop in instance) {
(function (prop) {
if (typeof window[className].prototype !== undefined) {
return;
}
if (typeof instance[prop] === 'function') {
window[className].prototype[prop] = function () {
return this._o[prop].apply(this._o, arguments);
};
} else {
Object.defineProperty(window[className].prototype, prop, {
set: function (fn) {
if (typeof fn === 'function') {
this._o[prop] = zone.bind(fn);
} else {
this._o[prop] = fn;
}
},
get: function () {
return this._o[prop];
}
});
}
}(prop));
}
};
Zone.patchRegisterElement = function () {
if (!('registerElement' in document)) {
return;
}
var _registerElement = document.registerElement;
var callbacks = [
'createdCallback',
'attachedCallback',
'detachedCallback',
'attributeChangedCallback'
];
document.registerElement = function (name, opts) {
callbacks.forEach(function (callback) {
if (opts.prototype[callback]) {
opts.prototype[callback] = zone.bind(opts.prototype[callback]);
}
});
return _registerElement.apply(document, [name, opts]);
};
}
Zone.eventNames = 'copy cut paste abort blur focus canplay canplaythrough change click contextmenu dblclick drag dragend dragenter dragleave dragover dragstart drop durationchange emptied ended input invalid keydown keypress keyup load loadeddata loadedmetadata loadstart mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup pause play playing progress ratechange reset scroll seeked seeking select show stalled submit suspend timeupdate volumechange waiting mozfullscreenchange mozfullscreenerror mozpointerlockchange mozpointerlockerror error'.split(' ');
Zone.onEventNames = Zone.eventNames.map(function (property) {
return 'on' + property;
});

@@ -375,0 +551,0 @@ Zone.init = function init () {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc