backbone-relational-hal-rails 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/LICENSE.txt +20 -0
- data/README.md +8 -0
- data/VERSION +1 -0
- data/lib/backbone-relational-hal-rails/engine.rb +6 -0
- data/lib/backbone-relational-hal-rails/version.rb +6 -0
- data/lib/backbone-relational-hal-rails.rb +6 -0
- data/vendor/assets/javascripts/backbone-relational-hal/backbone-relational-hal.js +222 -0
- data/vendor/assets/javascripts/backbone-relational-hal/backbone-relational.js +2043 -0
- data/vendor/assets/javascripts/backbone-relational-hal/backbone.js +1608 -0
- data/vendor/assets/javascripts/backbone-relational-hal/index.js +1 -0
- data/vendor/assets/javascripts/backbone-relational-hal/jquery.js +9111 -0
- data/vendor/assets/javascripts/backbone-relational-hal/underscore.js +1344 -0
- data/vendor/assets/javascripts/backbone-relational-hal/uri-templates.js +398 -0
- metadata +71 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YTg0NWU1NDg4N2RiYTk1MTdmNDU0NjM4YTI2NmE3ODY0NTJiNjMwNA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTQ1Y2Q5MWI4ZTFjYzY1ZGFmNTQyNmYxZDExZGI0Yjc0ZWQzMDliYw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NzMxODExOTg2ZmNhM2VhNjU4NTIzMjU0Njc1ZTI4YWViMjIzMTM1YzgwOWY1
|
10
|
+
MTkwNjQxMjg4NWIyMGVmN2ExYTRhNjRjMGU4MWZiNGJlNzM4ZjY3NjI4Y2Iw
|
11
|
+
ODVjMTgxM2VjNzhmOTU3NmE4Mzc2Mzk4YjIzMzNmNWZiZGRhM2M=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZDU5ZWE5N2ViOTQxZTMyY2U2NDhhZTM2NzEzMjhkYjhlNTdiM2NhZTIxOWRh
|
14
|
+
ZDBhNDkzZTYwMjI0MTMwMTMxZWE4NjA0MzI5ODlmZjcyZWM0YjIyNGNlZDg2
|
15
|
+
MjllN2M1YzYyYzg3MTUwNGY2MzJhNTQ2YjI0ZTY0ODkxODQyNzg=
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 Simon Oulevay (Alpha Hydrae)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# backbone-relational-hal for Ruby on Rails
|
2
|
+
|
3
|
+
Javascript assets for the latest [backbone-relational-hal](https://github.com/AlphaHydrae/backbone-relational-hal) release.
|
4
|
+
|
5
|
+
## Meta
|
6
|
+
|
7
|
+
* **Author:** Simon Oulevay a.k.a. Alpha Hydrae
|
8
|
+
* **License:** MIT (see [LICENSE.txt](https://github.com/AlphaHydrae/backbone-relational-hal-rails/blob/master/LICENSE.txt))
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
@@ -0,0 +1,222 @@
|
|
1
|
+
/*!
|
2
|
+
* backbone-relational-hal v0.1.1
|
3
|
+
* Copyright (c) 2014 Simon Oulevay
|
4
|
+
* Distributed under MIT license
|
5
|
+
* https://github.com/AlphaHydrae/backbone-relational-hal
|
6
|
+
*/
|
7
|
+
(function(Backbone, _, UriTemplate, $) {
|
8
|
+
|
9
|
+
var Collection = Backbone.Collection,
|
10
|
+
RelationalModel = Backbone.RelationalModel;
|
11
|
+
|
12
|
+
var HalLink = RelationalModel.extend({
|
13
|
+
|
14
|
+
href: function(options) {
|
15
|
+
options = _.extend({}, options);
|
16
|
+
|
17
|
+
var href = this.get('href');
|
18
|
+
|
19
|
+
if (this.get('templated')) {
|
20
|
+
href = new UriTemplate(href);
|
21
|
+
href = href.fillFromObject(options.template || {});
|
22
|
+
}
|
23
|
+
|
24
|
+
return href;
|
25
|
+
},
|
26
|
+
|
27
|
+
model: function(options) {
|
28
|
+
options = _.extend({}, options);
|
29
|
+
|
30
|
+
var model = options.model || (options.type ? new options.type() : new (Backbone.RelationalHalResource.extend({}))());
|
31
|
+
|
32
|
+
return model;
|
33
|
+
},
|
34
|
+
|
35
|
+
fetchResource: function(options) {
|
36
|
+
options = _.extend({}, options);
|
37
|
+
|
38
|
+
var fetchOptions = _.extend({}, options.fetch, { url: this.href(options.href) });
|
39
|
+
|
40
|
+
return this.model(options).fetch(fetchOptions);
|
41
|
+
}
|
42
|
+
});
|
43
|
+
|
44
|
+
var HalLinkCollection = Collection.extend({
|
45
|
+
model: HalLink
|
46
|
+
});
|
47
|
+
|
48
|
+
var HalResourceLinks = RelationalModel.extend({
|
49
|
+
|
50
|
+
parse: function(response) {
|
51
|
+
return _.reduce(response, function(memo, data, name) {
|
52
|
+
memo[name] = _.isArray(data) ? new HalLinkCollection(data) : new HalLink(data);
|
53
|
+
return memo;
|
54
|
+
}, {});
|
55
|
+
},
|
56
|
+
|
57
|
+
link: function(rel, options) {
|
58
|
+
options = _.extend({}, options);
|
59
|
+
|
60
|
+
var data = this.get(rel);
|
61
|
+
if (!data) {
|
62
|
+
return options.all ? new HalLinkCollection() : null;
|
63
|
+
} else if (data instanceof HalLinkCollection) {
|
64
|
+
return options.all ? data : data.at(0);
|
65
|
+
} else {
|
66
|
+
return options.all ? new HalLinkCollection([ data ]) : data;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
});
|
70
|
+
|
71
|
+
var HalModelEmbedded = RelationalModel.extend({
|
72
|
+
|
73
|
+
embedded: function(rel) {
|
74
|
+
return this.get(rel);
|
75
|
+
}
|
76
|
+
});
|
77
|
+
|
78
|
+
var HalResource = Backbone.RelationalHalResource = RelationalModel.extend({
|
79
|
+
|
80
|
+
url: function() {
|
81
|
+
|
82
|
+
if (this.hasLink('self')) {
|
83
|
+
return this.link('self').href();
|
84
|
+
} else if (this._cachedHalUrl) {
|
85
|
+
return this._cachedHalUrl;
|
86
|
+
}
|
87
|
+
|
88
|
+
var halUrl = _.result(this, 'halUrl');
|
89
|
+
if (halUrl) {
|
90
|
+
$.when(halUrl).then(_.bind(function(url) {
|
91
|
+
this._cachedHalUrl = url;
|
92
|
+
}, this));
|
93
|
+
}
|
94
|
+
|
95
|
+
return halUrl || null;
|
96
|
+
},
|
97
|
+
|
98
|
+
link: function(rel) {
|
99
|
+
var links = this.get('_links');
|
100
|
+
return links ? links.link.apply(links, Array.prototype.slice.call(arguments)) : null;
|
101
|
+
},
|
102
|
+
|
103
|
+
hasLink: function(rel) {
|
104
|
+
return this.has('_links') && this.get('_links').has(rel);
|
105
|
+
},
|
106
|
+
|
107
|
+
fetchHalUrl: function(rels) {
|
108
|
+
return this._fetchResource(rels.slice(), $.Deferred(), 'url', this);
|
109
|
+
},
|
110
|
+
|
111
|
+
fetchResource: function(rels) {
|
112
|
+
return this._fetchResource(rels.slice(), $.Deferred(), 'resource', this);
|
113
|
+
},
|
114
|
+
|
115
|
+
_fetchResource: function(rels, deferred, fetchType, resource, response, options) {
|
116
|
+
if (!rels.length) {
|
117
|
+
return deferred.resolve(resource, response, options);
|
118
|
+
}
|
119
|
+
|
120
|
+
var relName = rels.shift(),
|
121
|
+
rel = _.isObject(relName) ? relName : { name: relName },
|
122
|
+
link = resource.link(rel.name);
|
123
|
+
|
124
|
+
if (fetchType == 'url' && !rels.length) {
|
125
|
+
return deferred.resolve(link.href(_.omit(rel, 'name')), resource, response, options);
|
126
|
+
}
|
127
|
+
|
128
|
+
link.fetchResource({
|
129
|
+
model: rel.model || (rel.name == 'self' ? this : null),
|
130
|
+
type: rel.type,
|
131
|
+
fetch: {
|
132
|
+
error: _.bind(deferred.reject, deferred),
|
133
|
+
success: _.bind(this._fetchResource, this, rels, deferred, fetchType)
|
134
|
+
}
|
135
|
+
});
|
136
|
+
|
137
|
+
return deferred;
|
138
|
+
},
|
139
|
+
|
140
|
+
embedded: function(rel) {
|
141
|
+
var embedded = this.get('_embedded');
|
142
|
+
return embedded ? embedded.embedded.apply(embedded, Array.prototype.slice.call(arguments)) : null;
|
143
|
+
},
|
144
|
+
|
145
|
+
hasEmbedded: function(rel) {
|
146
|
+
return this.has('_embedded') && this.get('_embedded').has(rel);
|
147
|
+
},
|
148
|
+
|
149
|
+
hasSameUri: function(other) {
|
150
|
+
if (!other) {
|
151
|
+
return false;
|
152
|
+
}
|
153
|
+
|
154
|
+
return this.link('self').href() == other.link('self').href();
|
155
|
+
},
|
156
|
+
|
157
|
+
isNew: function() {
|
158
|
+
return !this.hasLink('self');
|
159
|
+
}
|
160
|
+
});
|
161
|
+
|
162
|
+
var relationalHalResourceExtend = HalResource.extend;
|
163
|
+
|
164
|
+
HalResource.extend = function(options) {
|
165
|
+
|
166
|
+
options = _.defaults({}, options, {
|
167
|
+
relations: [],
|
168
|
+
halEmbedded: []
|
169
|
+
});
|
170
|
+
|
171
|
+
var embedded = HalModelEmbedded.extend({
|
172
|
+
|
173
|
+
relations: _.map(options.halEmbedded, function(halEmbedded) {
|
174
|
+
return _.clone(halEmbedded);
|
175
|
+
})
|
176
|
+
});
|
177
|
+
|
178
|
+
options.relations.push({
|
179
|
+
type: Backbone.HasOne,
|
180
|
+
key: '_links',
|
181
|
+
relatedModel: HalResourceLinks,
|
182
|
+
includeInJSON: false,
|
183
|
+
parse: true
|
184
|
+
});
|
185
|
+
|
186
|
+
options.relations.push({
|
187
|
+
type: Backbone.HasOne,
|
188
|
+
key: '_embedded',
|
189
|
+
relatedModel: embedded,
|
190
|
+
includeInJSON: false
|
191
|
+
});
|
192
|
+
|
193
|
+
return relationalHalResourceExtend.call(HalResource, options);
|
194
|
+
};
|
195
|
+
|
196
|
+
Backbone.originalSync = Backbone.sync;
|
197
|
+
|
198
|
+
Backbone.sync = function(method, model, options) {
|
199
|
+
options = _.clone(options) || {};
|
200
|
+
|
201
|
+
var deferred = $.Deferred(),
|
202
|
+
failureHandler = _.bind(deferred.reject, deferred);
|
203
|
+
|
204
|
+
// WTF: fix for weird backbone behavior.
|
205
|
+
// For some reason, when creating a model, backbone resets empty attributes
|
206
|
+
// right after starting to sync with the server. Since the actual sync happens
|
207
|
+
// later (after the HAL URL has been fetched), we need to make sure the
|
208
|
+
// attributes are passed in the options instead.
|
209
|
+
if (!options.attrs) {
|
210
|
+
options.attrs = model.toJSON(options);
|
211
|
+
}
|
212
|
+
|
213
|
+
var url = options.url || _.result(model, 'url');
|
214
|
+
$.when(url).fail(failureHandler).done(function(actualUrl) {
|
215
|
+
options.url = actualUrl;
|
216
|
+
Backbone.originalSync.call(Backbone, method, model, options).fail(failureHandler).done(_.bind(deferred.resolve, deferred));
|
217
|
+
});
|
218
|
+
|
219
|
+
return deferred;
|
220
|
+
};
|
221
|
+
|
222
|
+
})(Backbone, _, UriTemplate, $);
|