pullentity-backbone 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,229 @@
|
|
1
|
+
// Backbone.CrossDomainModel 0.1.0
|
2
|
+
//
|
3
|
+
// (c) 2013 Victor Quinn
|
4
|
+
// Licensed under the MIT license.
|
5
|
+
|
6
|
+
(function (root, factory) {
|
7
|
+
if (typeof define === "function" && define.amd) {
|
8
|
+
// AMD. Register as an anonymous module.
|
9
|
+
define(["underscore","backbone"], function(_, Backbone) {
|
10
|
+
// Use global variables if the locals are undefined.
|
11
|
+
return factory(_ || root._, Backbone || root.Backbone);
|
12
|
+
});
|
13
|
+
} else {
|
14
|
+
// RequireJS isn't being used. Assume underscore and backbone are loaded in <script> tags
|
15
|
+
factory(_, Backbone);
|
16
|
+
}
|
17
|
+
}(this, function(_, Backbone) {
|
18
|
+
|
19
|
+
// Helper function to determine the request url given model and options objects
|
20
|
+
function requestUrl(model, options) {
|
21
|
+
var requestUrl = null;
|
22
|
+
// First try the options object
|
23
|
+
try {
|
24
|
+
requestUrl = options.url;
|
25
|
+
} catch(x) {}
|
26
|
+
|
27
|
+
// Then try the model's url
|
28
|
+
if (!requestUrl) {
|
29
|
+
try {
|
30
|
+
requestUrl = _.result(model, 'url');
|
31
|
+
} catch(x) {}
|
32
|
+
}
|
33
|
+
|
34
|
+
return requestUrl;
|
35
|
+
}
|
36
|
+
|
37
|
+
// Helper function to determine whether protocols differ.
|
38
|
+
function protocolsDiffer(thisProtocol, requestProtocol) {
|
39
|
+
if (thisProtocol === ':' || requestProtocol === ":") {
|
40
|
+
return false;
|
41
|
+
}
|
42
|
+
|
43
|
+
else if (thisProtocol === requestProtocol) {
|
44
|
+
return false;
|
45
|
+
}
|
46
|
+
|
47
|
+
return true;
|
48
|
+
}
|
49
|
+
|
50
|
+
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
|
51
|
+
|
52
|
+
var methodMap = {
|
53
|
+
'create': 'POST',
|
54
|
+
'update': 'PUT',
|
55
|
+
'patch': 'PATCH',
|
56
|
+
'delete': 'DELETE',
|
57
|
+
'read': 'GET'
|
58
|
+
};
|
59
|
+
|
60
|
+
Backbone.vanillaSync = Backbone.sync;
|
61
|
+
|
62
|
+
// Override 'Backbone.sync' to default to CrossDomainModel sync.
|
63
|
+
// the original 'Backbone.sync' is still available in 'Backbone.vanillaSync'
|
64
|
+
Backbone.sync = function(method, model, options) {
|
65
|
+
|
66
|
+
// See if we need to use the XDomainRequest object for IE. If the request is on the
|
67
|
+
// same domain, we can fall back on the normal Backbone.ajax handling.
|
68
|
+
var useXDomainRequest = false;
|
69
|
+
|
70
|
+
// See https://gist.github.com/jlong/2428561
|
71
|
+
var thisDomainParser = document.createElement('a');
|
72
|
+
thisDomainParser.href = document.URL;
|
73
|
+
|
74
|
+
var requestDomainParser = document.createElement('a');
|
75
|
+
requestDomainParser.href = requestUrl(model, options);
|
76
|
+
|
77
|
+
if (requestDomainParser.host !== "" && (thisDomainParser.host !== requestDomainParser.host)) {
|
78
|
+
useXDomainRequest = true;
|
79
|
+
}
|
80
|
+
|
81
|
+
// Only use this if browser doesn't support CORS natively. This should
|
82
|
+
// catch IE7/8/9 but keep IE10 using the built in XMLHttpRequest which
|
83
|
+
// IE10 finally supports for CORS.
|
84
|
+
if (useXDomainRequest && !Backbone.$.support.cors) {
|
85
|
+
|
86
|
+
// See this article for more details on all the silly nuances: http://vq.io/14DJ1Tv
|
87
|
+
|
88
|
+
// Basically Backbone.sync rewritten to use XDomainRequest object
|
89
|
+
var type = methodMap[method];
|
90
|
+
|
91
|
+
// Default options, unless specified.
|
92
|
+
_.defaults(options || (options = {}), {
|
93
|
+
emulateHTTP: Backbone.emulateHTTP,
|
94
|
+
emulateJSON: Backbone.emulateJSON
|
95
|
+
});
|
96
|
+
|
97
|
+
// XDomainRequest only works with POST. So DELETE/PUT/PATCH can't work here.
|
98
|
+
|
99
|
+
// Note: Conscious decision to throw error rather than try to munge the request and
|
100
|
+
// do something like force "options.emulateHTTP = true" because we want developers
|
101
|
+
// to notice they're trying to do something illegal with this request and it may
|
102
|
+
// require server-side changes for compatibility.
|
103
|
+
if (!options.emulateHTTP && (method === 'update' || method === 'patch' || method === 'delete')) {
|
104
|
+
throw new Error('Backbone.CrossDomain cannot use PUT, PATCH, DELETE with XDomainRequest (IE) and emulateHTTP=false');
|
105
|
+
}
|
106
|
+
|
107
|
+
// Default JSON-request options.
|
108
|
+
var params = {type: type, dataType: 'json'};
|
109
|
+
|
110
|
+
// Ensure that we have a URL.
|
111
|
+
if (!options.url) {
|
112
|
+
params.url = _.result(model, 'url') || urlError();
|
113
|
+
}
|
114
|
+
|
115
|
+
// Check if protocols differ, if so try the request with the current domain protocol
|
116
|
+
if (protocolsDiffer(thisDomainParser.protocol, requestDomainParser.protocol)) {
|
117
|
+
params.url = params.url.replace(new RegExp(requestDomainParser.protocol), thisDomainParser.protocol);
|
118
|
+
}
|
119
|
+
|
120
|
+
// TODO: XDomainRequest only accepts text/plain Content-Type header
|
121
|
+
|
122
|
+
// TODO: XDomainRequest doesn't like other headers
|
123
|
+
|
124
|
+
// Ensure that we have the appropriate request data.
|
125
|
+
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
|
126
|
+
params.data = JSON.stringify(options.attrs || model.toJSON(options));
|
127
|
+
}
|
128
|
+
|
129
|
+
// For older servers, emulate JSON by encoding the request into an HTML-form.
|
130
|
+
if (options.emulateJSON) {
|
131
|
+
params.data = params.data ? {model: params.data} : {};
|
132
|
+
}
|
133
|
+
|
134
|
+
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
|
135
|
+
// And an `X-HTTP-Method-Override` header.
|
136
|
+
|
137
|
+
if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
|
138
|
+
params.type = 'POST';
|
139
|
+
if (options.emulateJSON) params.data._method = type;
|
140
|
+
var beforeSend = options.beforeSend;
|
141
|
+
options.beforeSend = function(xhr) {
|
142
|
+
xhr.setRequestHeader('X-HTTP-Method-Override', type);
|
143
|
+
if (beforeSend) return beforeSend.apply(this, arguments);
|
144
|
+
};
|
145
|
+
}
|
146
|
+
|
147
|
+
// Don't process data on a non-GET request.
|
148
|
+
if (params.type !== 'GET' && !options.emulateJSON) {
|
149
|
+
params.processData = false;
|
150
|
+
}
|
151
|
+
|
152
|
+
// Need to send this along as key/value pairs, can't send JSON blob
|
153
|
+
if (params.type === 'POST') {
|
154
|
+
params.data = Backbone.$.param(Backbone.$.parseJSON(params.data));
|
155
|
+
}
|
156
|
+
|
157
|
+
var xdr = options.xhr = new XDomainRequest(),
|
158
|
+
success = options.success,
|
159
|
+
error = options.error;
|
160
|
+
|
161
|
+
// Attach deferreds, but only if $ is jQuery (if we don't do this check,
|
162
|
+
// we'll break support for Zepto or other libraries without promise support
|
163
|
+
if (Backbone.$.fn.jquery) {
|
164
|
+
var deferred = Backbone.$.Deferred(),
|
165
|
+
completeDeferred = Backbone.$.Callbacks("once memory");
|
166
|
+
|
167
|
+
// Attach deferreds
|
168
|
+
deferred.promise(xdr).complete = completeDeferred.add;
|
169
|
+
|
170
|
+
xdr.onload = function () {
|
171
|
+
var obj = {};
|
172
|
+
if (xdr.responseText) {
|
173
|
+
obj = Backbone.$.parseJSON(xdr.responseText);
|
174
|
+
}
|
175
|
+
if (obj) {
|
176
|
+
deferred.resolveWith(this, [success, 'success', xdr]);
|
177
|
+
success(obj);
|
178
|
+
} else {
|
179
|
+
deferred.resolveWith(this, [success, 'success', xdr]);
|
180
|
+
success(obj);
|
181
|
+
}
|
182
|
+
};
|
183
|
+
xdr.onerror = function () {
|
184
|
+
if (error) {
|
185
|
+
error(model, xdr, options);
|
186
|
+
deferred.resolveWith(this, [xdr, 'error', error]);
|
187
|
+
}
|
188
|
+
model.trigger('error', model, xdr, options);
|
189
|
+
};
|
190
|
+
|
191
|
+
xdr.done(xdr.onload);
|
192
|
+
xdr.fail(xdr.onerror);
|
193
|
+
|
194
|
+
} else {
|
195
|
+
xdr.onload = function (resp) {
|
196
|
+
var obj = {};
|
197
|
+
if (xdr.responseText) {
|
198
|
+
obj = Backbone.$.parseJSON(xdr.responseText);
|
199
|
+
}
|
200
|
+
if (obj) success(obj);
|
201
|
+
};
|
202
|
+
|
203
|
+
xdr.onerror = function (xdr) {
|
204
|
+
if (error) error(model, xdr, options);
|
205
|
+
model.trigger('error', model, xdr, options);
|
206
|
+
};
|
207
|
+
}
|
208
|
+
|
209
|
+
// Make the request using XDomainRequest
|
210
|
+
xdr.open(params.type, params.url);
|
211
|
+
|
212
|
+
// Must declare these even if empty or IE will abort randomly: http://vq.io/12bnhye
|
213
|
+
xdr.onprogress = function () {};
|
214
|
+
xdr.ontimeout = function () {};
|
215
|
+
|
216
|
+
setTimeout(function () {
|
217
|
+
xdr.send(params.data);
|
218
|
+
}, 0);
|
219
|
+
|
220
|
+
model.trigger('request', model, xdr, options);
|
221
|
+
return xdr;
|
222
|
+
}
|
223
|
+
else {
|
224
|
+
return Backbone.vanillaSync.apply(this, arguments);
|
225
|
+
}
|
226
|
+
};
|
227
|
+
|
228
|
+
return Backbone;
|
229
|
+
}));
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pullentity-backbone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- vendor/assets/.DS_Store
|
63
63
|
- vendor/assets/javascripts/.DS_Store
|
64
64
|
- vendor/assets/javascripts/backbone/.DS_Store
|
65
|
+
- vendor/assets/javascripts/backbone/backbone.CrossDomain.js
|
65
66
|
- vendor/assets/javascripts/backbone/backbone.js
|
66
67
|
- vendor/assets/javascripts/backbone/underscore.js
|
67
68
|
- vendor/assets/javascripts/handlebars.js
|
@@ -91,18 +92,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
92
|
- - ! '>='
|
92
93
|
- !ruby/object:Gem::Version
|
93
94
|
version: '0'
|
94
|
-
segments:
|
95
|
-
- 0
|
96
|
-
hash: -4361046666830992680
|
97
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
96
|
none: false
|
99
97
|
requirements:
|
100
98
|
- - ! '>='
|
101
99
|
- !ruby/object:Gem::Version
|
102
100
|
version: '0'
|
103
|
-
segments:
|
104
|
-
- 0
|
105
|
-
hash: -4361046666830992680
|
106
101
|
requirements: []
|
107
102
|
rubyforge_project:
|
108
103
|
rubygems_version: 1.8.25
|