Skip to content

Commit 849a05b

Browse files
committed
added jsonp to resources
1 parent b5bbfae commit 849a05b

9 files changed

Lines changed: 125 additions & 21 deletions

File tree

example/buzz/buzz.css

Whitespace-only changes.

example/buzz/buzz.html

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2+
<html xmlns:ng="http://angularjs.org">
3+
<head>
4+
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
5+
<script type="text/javascript" src="../../src/angular-bootstrap.js#autobind"></script>
6+
<script type="text/javascript" src="buzz.js"></script>
7+
<link rel="stylesheet" type="text/css" href="style.css"/>
8+
</head>
9+
<body ng:init="$window.$root = this" ng:controller="BuzzController">
10+
<div class="bar">
11+
<input type="text" name="userId"/>
12+
<button ng:click="$location.hashPath = userId">fetch</button>
13+
</div>
14+
<ul>
15+
<li ng:repeat="item in activities.data.items">
16+
<img src="{{item.actor.thumbnailUrl}}"/>
17+
<a href="{{item.actor.profileUrl}}">{{item.actor.name}}</a>
18+
{{item.object.content | html}}
19+
<a href="">Replies: {{item.links.replies[0].count}}</a>
20+
<ul>
21+
<li ng:repeat="reply in item.replies.items">
22+
<img src="{{reply.actor.thumbnailUrl}}"/>
23+
<a href="{{reply.actor.profileUrl}}">{{reply.actor.name}}</a>
24+
{{reply.content | html}}
25+
</li>
26+
</ul>
27+
</li>
28+
</ul>
29+
</body>
30+
</html>

example/buzz/buzz.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
angular.service('myApplication', function($resource){
2+
this.Activity = $resource(
3+
'https://www.googleapis.com/buzz/v1/activities/:userId/:visibility/:activityId/:comments',
4+
{alt:'json', callback:'JSON_CALLBACK'},
5+
{
6+
get: {method:'JSON', params:{visibility:'@self'}},
7+
replies: {method:'JSON', params:{visibility:'@self', comments:'@comments'}}
8+
});
9+
}, {inject:['$resource']});
10+
11+
function BuzzController(){
12+
this.$watch('$location.hashPath', this.userChange);
13+
}
14+
BuzzController.prototype = {
15+
userChange: function(){
16+
this.userId = this.$location.hashPath;
17+
this.activities = this.Activity.get({userId:this.userId});
18+
}
19+
};

src/AngularPublic.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
var browserSingleton;
22
angularService('$browser', function browserFactory(){
33
if (!browserSingleton) {
4-
browserSingleton = new Browser(window.location, window.document);
4+
browserSingleton = new Browser(
5+
window.location,
6+
jqLite(window.document),
7+
jqLite(window.document.getElementsByTagName('head')[0]));
58
browserSingleton.startUrlWatcher();
69
browserSingleton.bind();
710
}

src/Browser.js

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Browser
33
//////////////////////////////
44

5-
function Browser(location, document) {
5+
function Browser(location, document, head) {
66
this.delay = 50;
77
this.expectedUrl = location.href;
88
this.urlListeners = [];
@@ -21,8 +21,9 @@ function Browser(location, document) {
2121
};
2222

2323
this.location = location;
24-
this.document = jqLite(document);
25-
this.body = jqLite(document.body);
24+
this.document = document;
25+
this.head = head;
26+
this.idCounter = 0;
2627
}
2728

2829
Browser.prototype = {
@@ -58,21 +59,34 @@ Browser.prototype = {
5859
callback = post;
5960
post = null;
6061
}
61-
var xhr = new this.XHR(),
62-
self = this;
63-
xhr.open(method, url, true);
64-
this.outstandingRequests.count ++;
65-
xhr.onreadystatechange = function() {
66-
if (xhr.readyState == 4) {
67-
try {
68-
callback(xhr.status || 200, xhr.responseText);
69-
} finally {
70-
self.outstandingRequests.count--;
71-
self.processRequestCallbacks();
62+
if (lowercase(method) == 'json') {
63+
var callbackId = "angular_" + Math.random() + '_' + (this.idCounter++);
64+
callbackId = callbackId.replace(/\d\./, '');
65+
var script = this.document[0].createElement('script');
66+
script.type = 'text/javascript';
67+
script.src = url.replace('JSON_CALLBACK', callbackId);
68+
this.head.append(script);
69+
window[callbackId] = function(data){
70+
delete window[callbackId];
71+
callback(200, data);
72+
};
73+
} else {
74+
var xhr = new this.XHR(),
75+
self = this;
76+
xhr.open(method, url, true);
77+
this.outstandingRequests.count ++;
78+
xhr.onreadystatechange = function() {
79+
if (xhr.readyState == 4) {
80+
try {
81+
callback(xhr.status || 200, xhr.responseText);
82+
} finally {
83+
self.outstandingRequests.count--;
84+
self.processRequestCallbacks();
85+
}
7286
}
73-
}
74-
};
75-
xhr.send(post || '');
87+
};
88+
xhr.send(post || '');
89+
}
7690
},
7791

7892
processRequestCallbacks: function(){

src/Resource.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Route.prototype = {
2828
query.push(encodeURI(key) + '=' + encodeURI(value));
2929
}
3030
});
31+
url = url.replace(/\/*$/, '');
3132
return url + (query.length ? '?' + query.join('&') : '');
3233
}
3334
};
@@ -88,7 +89,7 @@ ResourceFactory.prototype = {
8889
throw "Expected between 0-3 arguments [params, data, callback], got " + arguments.length + " arguments.";
8990
}
9091

91-
var value = action.isArray ? [] : new Resource(data)
92+
var value = action.isArray ? [] : new Resource(data);
9293
self.xhr(
9394
action.method,
9495
route.url(extend({}, action.params || {}, extractParams(data), params)),

test/BrowserSpecs.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
describe('browser', function(){
22

3-
var browser, location;
3+
var browser, location, head;
44

55
beforeEach(function(){
66
location = {href:"http://server", hash:""};
7-
browser = new Browser(location, {});
7+
document = jqLite(window.document);
8+
head = {
9+
scripts: [],
10+
append: function(node){head.scripts.push(node);}
11+
};
12+
browser = new Browser(location, jqLite(window.document), head);
813
browser.setTimeout = noop;
914
});
1015

@@ -45,4 +50,23 @@ describe('browser', function(){
4550
});
4651
});
4752

53+
describe('xhr', function(){
54+
describe('JSON', function(){
55+
it('should add script tag for request', function() {
56+
var log = "";
57+
browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', function(code, data){
58+
log += code + ':' + data + ';';
59+
});
60+
expect(head.scripts.length).toEqual(1);
61+
var url = head.scripts[0].src.split('?cb=');
62+
expect(url[0]).toEqual('http://example.org/path');
63+
expect(typeof window[url[1]]).toEqual('function');
64+
window[url[1]]('data');
65+
expect(log).toEqual('200:data;');
66+
expect(typeof window[url[1]]).toEqual('undefined');
67+
68+
});
69+
});
70+
});
71+
4872
});

test/ResourceSpec.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ describe("resource", function() {
2828
resource.route('URL').query();
2929
});
3030

31+
it('should ignore slashes of undefinend parameters', function(){
32+
var R = resource.route('/Path/:a/:b/:c');
33+
xhr.expectGET('/Path').respond({});
34+
xhr.expectGET('/Path/1').respond({});
35+
xhr.expectGET('/Path/2/3').respond({});
36+
xhr.expectGET('/Path/4/5/6').respond({});
37+
R.get({});
38+
R.get({a:1});
39+
R.get({a:2, b:3});
40+
R.get({a:4, b:5, c:6});
41+
});
42+
3143
it("should build resource with default param", function(){
3244
xhr.expectGET('/Order/123/Line/456.visa?minimum=0.05').respond({id:'abc'});
3345
var LineItem = resource.route('/Order/:orderId/Line/:id:verb', {orderId: '123', id: '@id.key', verb:'.visa', minimum:0.05});

test/angular-mocks.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ function MockBrowser() {
6666
self.xhr.expectPOST = angular.bind(self, self.xhr.expect, 'POST');
6767
self.xhr.expectDELETE = angular.bind(self, self.xhr.expect, 'DELETE');
6868
self.xhr.expectPUT = angular.bind(self, self.xhr.expect, 'PUT');
69+
self.xhr.expectJSON = angular.bind(self, self.xhr.expect, 'JSON');
6970
self.xhr.flush = function() {
7071
while(requests.length) {
7172
requests.pop()();

0 commit comments

Comments
 (0)