aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2010-07-22 11:18:32 -0700
committerMisko Hevery2010-07-22 11:18:32 -0700
commit849a05b5a578f19ddc3d24dc9fbd304e0e07612a (patch)
tree3e32e2ab7b8c1ed3f53e5b568990070b5edab4fa
parentb5bbfaeb80c3f89c65d14c72cff6f0e1c8aa497a (diff)
downloadangular.js-849a05b5a578f19ddc3d24dc9fbd304e0e07612a.tar.bz2
added jsonp to resources
-rw-r--r--example/buzz/buzz.css0
-rw-r--r--example/buzz/buzz.html30
-rw-r--r--example/buzz/buzz.js19
-rw-r--r--src/AngularPublic.js5
-rw-r--r--src/Browser.js48
-rw-r--r--src/Resource.js3
-rw-r--r--test/BrowserSpecs.js28
-rw-r--r--test/ResourceSpec.js12
-rw-r--r--test/angular-mocks.js1
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()();