railsy_backbone 0.0.1

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,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);