diff options
| -rw-r--r-- | src/ng/httpBackend.js | 59 | ||||
| -rw-r--r-- | test/ng/httpBackendSpec.js | 71 | 
2 files changed, 35 insertions, 95 deletions
| diff --git a/src/ng/httpBackend.js b/src/ng/httpBackend.js index 28107966..9b2d7361 100644 --- a/src/ng/httpBackend.js +++ b/src/ng/httpBackend.js @@ -49,16 +49,13 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc        var callbackId = '_' + (callbacks.counter++).toString(36);        callbacks[callbackId] = function(data) {          callbacks[callbackId].data = data; +        callbacks[callbackId].called = true;        };        var jsonpDone = jsonpReq(url.replace('JSON_CALLBACK', 'angular.callbacks.' + callbackId), -          function() { -        if (callbacks[callbackId].data) { -          completeRequest(callback, 200, callbacks[callbackId].data); -        } else { -          completeRequest(callback, status || -2); -        } -        callbacks[callbackId] = angular.noop; +          callbackId, function(status, text) { +        completeRequest(callback, status, callbacks[callbackId].data, "", text); +        callbacks[callbackId] = noop;        });      } else { @@ -158,33 +155,39 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc      }    }; -  function jsonpReq(url, done) { +  function jsonpReq(url, callbackId, done) {      // we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.:      // - fetches local scripts via XHR and evals them      // - adds and immediately removes script elements from the document -    var script = rawDocument.createElement('script'), -        doneWrapper = function() { -          script.onreadystatechange = script.onload = script.onerror = null; -          rawDocument.body.removeChild(script); -          if (done) done(); -        }; - -    script.type = 'text/javascript'; +    var script = rawDocument.createElement('script'), callback = null; +    script.type = "text/javascript";      script.src = url; - -    if (msie && msie <= 8) { -      script.onreadystatechange = function() { -        if (/loaded|complete/.test(script.readyState)) { -          doneWrapper(); +    script.async = true; + +    callback = function(event) { +      removeEventListenerFn(script, "load", callback); +      removeEventListenerFn(script, "error", callback); +      rawDocument.body.removeChild(script); +      script = null; +      var status = -1; +      var text = "unknown"; + +      if (event) { +        if (event.type === "load" && !callbacks[callbackId].called) { +          event = { type: "error" };          } -      }; -    } else { -      script.onload = script.onerror = function() { -        doneWrapper(); -      }; -    } +        text = event.type; +        status = event.type === "error" ? 404 : 200; +      } + +      if (done) { +        done(status, text); +      } +    }; +    addEventListenerFn(script, "load", callback); +    addEventListenerFn(script, "error", callback);      rawDocument.body.appendChild(script); -    return doneWrapper; +    return callback;    }  } diff --git a/test/ng/httpBackendSpec.js b/test/ng/httpBackendSpec.js index 5c9cbf58..837fbab9 100644 --- a/test/ng/httpBackendSpec.js +++ b/test/ng/httpBackendSpec.js @@ -39,7 +39,8 @@ describe('$httpBackend', function() {      fakeDocument = {        $$scripts: [],        createElement: jasmine.createSpy('createElement').andCallFake(function() { -        return {}; +        // Return a proper script element... +        return document.createElement(arguments[0]);        }),        body: {          appendChild: jasmine.createSpy('body.appendChild').andCallFake(function(script) { @@ -325,13 +326,7 @@ describe('$httpBackend', function() {        expect(url[1]).toBe('http://example.org/path');        callbacks[url[2]]('some-data'); - -      if (script.onreadystatechange) { -        script.readyState = 'complete'; -        script.onreadystatechange(); -      } else { -        script.onload(); -      } +      browserTrigger(script, "load");        expect(callback).toHaveBeenCalledOnce();      }); @@ -346,71 +341,13 @@ describe('$httpBackend', function() {            callbackId = script.src.match(SCRIPT_URL)[2];        callbacks[callbackId]('some-data'); - -      if (script.onreadystatechange) { -        script.readyState = 'complete'; -        script.onreadystatechange(); -      } else { -        script.onload(); -      } +      browserTrigger(script, "load");        expect(callbacks[callbackId]).toBe(angular.noop);        expect(fakeDocument.body.removeChild).toHaveBeenCalledOnceWith(script);      }); -    if(msie<=8) { - -      it('should attach onreadystatechange handler to the script object', function() { -        $backend('JSONP', 'http://example.org/path?cb=JSON_CALLBACK', null, noop); - -        expect(fakeDocument.$$scripts[0].onreadystatechange).toEqual(jasmine.any(Function)); - -        var script = fakeDocument.$$scripts[0]; - -        script.readyState = 'complete'; -        script.onreadystatechange(); - -        expect(script.onreadystatechange).toBe(null); -      }); - -    } else { - -      it('should attach onload and onerror handlers to the script object', function() { -        $backend('JSONP', 'http://example.org/path?cb=JSON_CALLBACK', null, noop); - -        expect(fakeDocument.$$scripts[0].onload).toEqual(jasmine.any(Function)); -        expect(fakeDocument.$$scripts[0].onerror).toEqual(jasmine.any(Function)); - -        var script = fakeDocument.$$scripts[0]; -        script.onload(); - -        expect(script.onload).toBe(null); -        expect(script.onerror).toBe(null); -      }); - -    } - -    it('should call callback with status -2 when script fails to load', function() { -      callback.andCallFake(function(status, response) { -        expect(status).toBe(-2); -        expect(response).toBeUndefined(); -      }); - -      $backend('JSONP', 'http://example.org/path?cb=JSON_CALLBACK', null, callback); -      expect(fakeDocument.$$scripts.length).toBe(1); - -      var script = fakeDocument.$$scripts.shift(); -      if (script.onreadystatechange) { -        script.readyState = 'complete'; -        script.onreadystatechange(); -      } else { -        script.onload(); -      } -      expect(callback).toHaveBeenCalledOnce(); -    }); - -      it('should set url to current location if not specified or empty string', function() {        $backend('JSONP', undefined, null, callback);        expect(fakeDocument.$$scripts[0].src).toBe($browser.url()); | 
