diff --git a/test/zone.spec.js b/test/zone.spec.js index 48dbd1fa5..b29362cd4 100644 --- a/test/zone.spec.js +++ b/test/zone.spec.js @@ -324,6 +324,56 @@ describe('Zone.patch', function () { }); + 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); + }); + }); + }); + + describe('hooks', function () { beforeEach(function () { diff --git a/zone.js b/zone.js index 9b1b2421d..7f1cc4f40 100644 --- a/zone.js +++ b/zone.js @@ -250,6 +250,7 @@ Zone.patch = function patch () { Zone.patchViaPropertyDescriptor(); } else { Zone.patchViaCapturingAllTheEvents(); + Zone.patchClass('XMLHttpRequest'); } // patch promises @@ -304,6 +305,38 @@ Zone.patchViaCapturingAllTheEvents = function () { }); }; +// TODO: wrap some native API +Zone.patchClass = function (className) { + var OriginalClass = window[className]; + window[className] = function () { + this._o = new OriginalClass(); + }; + + var instance = (new OriginalClass()); + + var prop; + for (prop in instance) { + (function (prop) { + 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); + } + }, + get: function () { + return this._o[prop]; + } + }); + } + }(prop)); + }; +}; + 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.init = function init () {