railsy_backbone 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
1
+ ( function($){
2
+
3
+ // Backbone.sync
4
+ // -------------
5
+
6
+ // Need to define the methodMap since it's called from within Backbone.sync
7
+ //
8
+ var methodMap = {
9
+ 'create': 'POST',
10
+ 'update': 'PUT',
11
+ 'patch': 'PATCH',
12
+ 'delete': 'DELETE',
13
+ 'read': 'GET'
14
+ };
15
+
16
+ var urlError = function() {
17
+ throw new Error("A 'url' property or function must be specified");
18
+ };
19
+
20
+ // Overriding Backbone.sync to nest model attributes in within the paramRoot
21
+ // key-value JSON hashmap.
22
+ //
23
+ // For example, when saving a new Model,
24
+ //
25
+ // var Book = Backbone.Model.extend({
26
+ // url: '/books',
27
+ // paramRoot: 'book'
28
+ // });
29
+ //
30
+ // var book_instance = new Book({
31
+ // title: 'the illiad',
32
+ // author: 'homer'
33
+ // });
34
+ //
35
+ // book_instance.sync();
36
+ //
37
+ // This will cause the HTTP POST to look like this,
38
+ //
39
+ // Started POST "/books" for 127.0.0.1 at 2013-08-03 18:08:56 -0600
40
+ // Processing by BooksController#create as JSON
41
+ // Parameters: { "book" => { "title" => "the illiad", "author" => "homer" }}
42
+ //
43
+ //
44
+ // Everything that is not explicitly called out as **railys_backbone** code, is
45
+ // unmodified Backbone code.
46
+ //
47
+ Backbone.sync = function(method, model, options) {
48
+ var type = methodMap[method];
49
+
50
+ // Default options, unless specified.
51
+ _.defaults(options || (options = {}), {
52
+ emulateHTTP: Backbone.emulateHTTP,
53
+ emulateJSON: Backbone.emulateJSON
54
+ });
55
+
56
+ // Default JSON-request options.
57
+ var params = {type: type, dataType: 'json'};
58
+
59
+ // Ensure that we have a URL.
60
+ if (!options.url) {
61
+ params.url = _.result(model, 'url') || urlError();
62
+ }
63
+
64
+ // =========================================================================
65
+ // railsy_backbone
66
+ // -------------------------------------------------------------------------
67
+ // include the Rails CSRF token on HTTP PUTs/POSTs
68
+ //
69
+ if(!options.noCSRF){
70
+ var beforeSend = options.beforeSend;
71
+
72
+ // Set X-CSRF-Token HTTP header
73
+ options.beforeSend = function(xhr) {
74
+ var token = $('meta[name="csrf-token"]').attr('content');
75
+ if (token) xhr.setRequestHeader('X-CSRF-Token', token);
76
+ if (beforeSend) return beforeSend.apply(this, arguments);
77
+ };
78
+ }
79
+ // =========================================================================
80
+
81
+ // Ensure that we have the appropriate request data.
82
+ if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
83
+ params.contentType = 'application/json';
84
+
85
+ // =======================================================================
86
+ // railsy_backbone
87
+ // -----------------------------------------------------------------------
88
+ // If model defines **paramRoot**, store model attributes within it. IE
89
+ //
90
+ // HTTP POST Parameters: { "book" => { "title" => "the illiad", "author" => "home" }}
91
+ //
92
+
93
+ if(model.paramRoot) {
94
+ var model_attributes = {}
95
+ model_attributes[model.paramRoot] = model.toJSON(options);
96
+ params.data = JSON.stringify(options.attrs || model_attributes );
97
+ } else {
98
+ params.data = JSON.stringify(options.attrs || model.toJSON(options) );
99
+ }
100
+
101
+ // -------------------------------------------------------------------------
102
+ // original Backbone code
103
+ //
104
+ // params.data = JSON.stringify(options.attrs || model.toJSON(options) );
105
+ //
106
+ // =========================================================================
107
+ }
108
+
109
+ // For older servers, emulate JSON by encoding the request into an HTML-form.
110
+ if (options.emulateJSON) {
111
+ params.contentType = 'application/x-www-form-urlencoded';
112
+ params.data = params.data ? {model: params.data} : {};
113
+ }
114
+
115
+ // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
116
+ // And an `X-HTTP-Method-Override` header.
117
+ if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
118
+ params.type = 'POST';
119
+ if (options.emulateJSON) params.data._method = type;
120
+ var beforeSend = options.beforeSend;
121
+ options.beforeSend = function(xhr) {
122
+ xhr.setRequestHeader('X-HTTP-Method-Override', type);
123
+ if (beforeSend) return beforeSend.apply(this, arguments);
124
+ };
125
+ }
126
+
127
+ // Don't process data on a non-GET request.
128
+ if (params.type !== 'GET' && !options.emulateJSON) {
129
+ params.processData = false;
130
+ }
131
+
132
+ // If we're sending a `PATCH` request, and we're in an old Internet Explorer
133
+ // that still has ActiveX enabled by default, override jQuery to use that
134
+ // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
135
+ if (params.type === 'PATCH' && window.ActiveXObject &&
136
+ !(window.external && window.external.msActiveXFilteringEnabled)) {
137
+ params.xhr = function() {
138
+ return new ActiveXObject("Microsoft.XMLHTTP");
139
+ };
140
+ }
141
+
142
+ // Make the request, allowing the user to override any Ajax options.
143
+ var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
144
+ model.trigger('request', model, xhr, options);
145
+ return xhr;
146
+ };
147
+
148
+ })(jQuery);