diff options
| -rw-r--r-- | example/buzz/buzz.css | 0 | ||||
| -rw-r--r-- | example/buzz/buzz.html | 30 | ||||
| -rw-r--r-- | example/buzz/buzz.js | 19 | ||||
| -rw-r--r-- | src/AngularPublic.js | 5 | ||||
| -rw-r--r-- | src/Browser.js | 48 | ||||
| -rw-r--r-- | src/Resource.js | 3 | ||||
| -rw-r--r-- | test/BrowserSpecs.js | 28 | ||||
| -rw-r--r-- | test/ResourceSpec.js | 12 | ||||
| -rw-r--r-- | test/angular-mocks.js | 1 | 
9 files changed, 125 insertions, 21 deletions
| diff --git a/example/buzz/buzz.css b/example/buzz/buzz.css new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/example/buzz/buzz.css diff --git a/example/buzz/buzz.html b/example/buzz/buzz.html new file mode 100644 index 00000000..ee2b2bb9 --- /dev/null +++ b/example/buzz/buzz.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html xmlns:ng="http://angularjs.org"> +  <head> +    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script> +    <script type="text/javascript" src="../../src/angular-bootstrap.js#autobind"></script> +    <script type="text/javascript" src="buzz.js"></script> +    <link rel="stylesheet" type="text/css" href="style.css"/> +  </head> +  <body ng:init="$window.$root = this" ng:controller="BuzzController"> +  <div class="bar"> +    <input type="text" name="userId"/> +    <button ng:click="$location.hashPath = userId">fetch</button> +  </div> +  <ul> +    <li ng:repeat="item in activities.data.items"> +      <img src="{{item.actor.thumbnailUrl}}"/> +      <a href="{{item.actor.profileUrl}}">{{item.actor.name}}</a> +      {{item.object.content | html}} +      <a href="">Replies: {{item.links.replies[0].count}}</a> +      <ul> +        <li ng:repeat="reply in item.replies.items"> +          <img src="{{reply.actor.thumbnailUrl}}"/> +          <a href="{{reply.actor.profileUrl}}">{{reply.actor.name}}</a> +          {{reply.content | html}} +        </li> +      </ul> +    </li> +  </ul> +  </body> +</html> diff --git a/example/buzz/buzz.js b/example/buzz/buzz.js new file mode 100644 index 00000000..871982d7 --- /dev/null +++ b/example/buzz/buzz.js @@ -0,0 +1,19 @@ +angular.service('myApplication', function($resource){ +  this.Activity = $resource( +      'https://www.googleapis.com/buzz/v1/activities/:userId/:visibility/:activityId/:comments', +      {alt:'json', callback:'JSON_CALLBACK'}, +      { +        get:     {method:'JSON', params:{visibility:'@self'}}, +        replies: {method:'JSON', params:{visibility:'@self', comments:'@comments'}} +      }); +}, {inject:['$resource']}); + +function BuzzController(){ +  this.$watch('$location.hashPath', this.userChange); +} +BuzzController.prototype = { +  userChange: function(){ +    this.userId = this.$location.hashPath; +    this.activities = this.Activity.get({userId:this.userId}); +  } +}; diff --git a/src/AngularPublic.js b/src/AngularPublic.js index e2e576fd..7b093f88 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -1,7 +1,10 @@  var browserSingleton;  angularService('$browser', function browserFactory(){    if (!browserSingleton) { -    browserSingleton = new Browser(window.location, window.document); +    browserSingleton = new Browser( +        window.location, +        jqLite(window.document), +        jqLite(window.document.getElementsByTagName('head')[0]));      browserSingleton.startUrlWatcher();      browserSingleton.bind();    } diff --git a/src/Browser.js b/src/Browser.js index 0552b3ae..3299540c 100644 --- a/src/Browser.js +++ b/src/Browser.js @@ -2,7 +2,7 @@  // Browser  ////////////////////////////// -function Browser(location, document) { +function Browser(location, document, head) {    this.delay = 50;    this.expectedUrl = location.href;    this.urlListeners = []; @@ -21,8 +21,9 @@ function Browser(location, document) {    };    this.location = location; -  this.document = jqLite(document); -  this.body = jqLite(document.body); +  this.document = document; +  this.head = head; +  this.idCounter = 0;  }  Browser.prototype = { @@ -58,21 +59,34 @@ Browser.prototype = {        callback = post;        post = null;      } -    var xhr = new this.XHR(), -        self = this; -    xhr.open(method, url, true); -    this.outstandingRequests.count ++; -    xhr.onreadystatechange = function() { -      if (xhr.readyState == 4) { -        try { -          callback(xhr.status || 200, xhr.responseText); -        } finally { -          self.outstandingRequests.count--; -          self.processRequestCallbacks(); +    if (lowercase(method) == 'json') { +      var callbackId = "angular_" + Math.random() + '_' + (this.idCounter++); +      callbackId = callbackId.replace(/\d\./, ''); +      var script = this.document[0].createElement('script'); +      script.type = 'text/javascript'; +      script.src = url.replace('JSON_CALLBACK', callbackId); +      this.head.append(script); +      window[callbackId] = function(data){ +        delete window[callbackId]; +        callback(200, data); +      }; +    } else { +      var xhr = new this.XHR(), +      self = this; +      xhr.open(method, url, true); +      this.outstandingRequests.count ++; +      xhr.onreadystatechange = function() { +        if (xhr.readyState == 4) { +          try { +            callback(xhr.status || 200, xhr.responseText); +          } finally { +            self.outstandingRequests.count--; +            self.processRequestCallbacks(); +          }          } -      } -    }; -    xhr.send(post || ''); +      }; +      xhr.send(post || ''); +    }    },    processRequestCallbacks: function(){ diff --git a/src/Resource.js b/src/Resource.js index 1279dc54..f4f26ebd 100644 --- a/src/Resource.js +++ b/src/Resource.js @@ -28,6 +28,7 @@ Route.prototype = {          query.push(encodeURI(key) + '=' + encodeURI(value));        }      }); +    url = url.replace(/\/*$/, '');      return url + (query.length ? '?' + query.join('&') : '');    }  }; @@ -88,7 +89,7 @@ ResourceFactory.prototype = {            throw "Expected between 0-3 arguments [params, data, callback], got " + arguments.length + " arguments.";          } -        var value = action.isArray ? [] : new Resource(data) +        var value = action.isArray ? [] : new Resource(data);          self.xhr(            action.method,            route.url(extend({}, action.params || {}, extractParams(data), params)), diff --git a/test/BrowserSpecs.js b/test/BrowserSpecs.js index 3ce158b4..a9f61a6b 100644 --- a/test/BrowserSpecs.js +++ b/test/BrowserSpecs.js @@ -1,10 +1,15 @@  describe('browser', function(){ -  var browser, location; +  var browser, location, head;    beforeEach(function(){      location = {href:"http://server", hash:""}; -    browser = new Browser(location, {}); +    document = jqLite(window.document); +    head = { +        scripts: [], +        append: function(node){head.scripts.push(node);} +    }; +    browser = new Browser(location, jqLite(window.document), head);      browser.setTimeout = noop;    }); @@ -45,4 +50,23 @@ describe('browser', function(){      });    }); +  describe('xhr', function(){ +    describe('JSON', function(){ +      it('should add script tag for request', function() { +        var log = ""; +        browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', function(code, data){ +          log += code + ':' + data + ';'; +        }); +        expect(head.scripts.length).toEqual(1); +        var url = head.scripts[0].src.split('?cb='); +        expect(url[0]).toEqual('http://example.org/path'); +        expect(typeof window[url[1]]).toEqual('function'); +        window[url[1]]('data'); +        expect(log).toEqual('200:data;'); +        expect(typeof window[url[1]]).toEqual('undefined'); + +      }); +    }); +  }); +  }); diff --git a/test/ResourceSpec.js b/test/ResourceSpec.js index 4882e70e..6e32ce18 100644 --- a/test/ResourceSpec.js +++ b/test/ResourceSpec.js @@ -28,6 +28,18 @@ describe("resource", function() {      resource.route('URL').query();    }); +  it('should ignore slashes of undefinend parameters', function(){ +    var R = resource.route('/Path/:a/:b/:c'); +    xhr.expectGET('/Path').respond({}); +    xhr.expectGET('/Path/1').respond({}); +    xhr.expectGET('/Path/2/3').respond({}); +    xhr.expectGET('/Path/4/5/6').respond({}); +    R.get({}); +    R.get({a:1}); +    R.get({a:2, b:3}); +    R.get({a:4, b:5, c:6}); +  }); +    it("should build resource with default param", function(){      xhr.expectGET('/Order/123/Line/456.visa?minimum=0.05').respond({id:'abc'});      var LineItem = resource.route('/Order/:orderId/Line/:id:verb', {orderId: '123', id: '@id.key', verb:'.visa', minimum:0.05}); diff --git a/test/angular-mocks.js b/test/angular-mocks.js index 8838b2cd..bac2e800 100644 --- a/test/angular-mocks.js +++ b/test/angular-mocks.js @@ -66,6 +66,7 @@ function MockBrowser() {    self.xhr.expectPOST   = angular.bind(self, self.xhr.expect, 'POST');    self.xhr.expectDELETE = angular.bind(self, self.xhr.expect, 'DELETE');    self.xhr.expectPUT    = angular.bind(self, self.xhr.expect, 'PUT'); +  self.xhr.expectJSON   = angular.bind(self, self.xhr.expect, 'JSON');    self.xhr.flush = function() {      while(requests.length) {        requests.pop()(); | 
