spine-rails 0.0.9 → 0.1.0
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.
- data/Gemfile +3 -3
- data/README.md +21 -21
- data/app/assets/javascripts/spine.js +279 -222
- data/app/assets/javascripts/spine/ajax.js +152 -94
- data/app/assets/javascripts/spine/list.js +29 -21
- data/app/assets/javascripts/spine/local.js +5 -3
- data/app/assets/javascripts/spine/manager.js +62 -38
- data/app/assets/javascripts/spine/relation.js +102 -85
- data/app/assets/javascripts/spine/route.js +73 -60
- data/app/assets/javascripts/spine/tabs.js +31 -23
- data/app/assets/javascripts/spine/tmpl.js +6 -1
- data/lib/generators/spine/scaffold/templates/controller.coffee.erb +2 -2
- data/lib/generators/spine/scaffold/templates/new.jst.erb +1 -1
- data/lib/spine/rails/version.rb +2 -2
- metadata +34 -65
@@ -1,18 +1,16 @@
|
|
1
1
|
(function() {
|
2
|
-
var $, Ajax, Base, Collection, Extend, Include, Model, Singleton
|
3
|
-
|
4
|
-
|
5
|
-
function ctor() { this.constructor = child; }
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
};
|
11
|
-
if (typeof Spine === "undefined" || Spine === null) {
|
12
|
-
Spine = require('spine');
|
13
|
-
}
|
2
|
+
var $, Ajax, Base, Collection, Extend, Include, Model, Singleton,
|
3
|
+
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
4
|
+
__hasProp = Object.prototype.hasOwnProperty,
|
5
|
+
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; },
|
6
|
+
__slice = Array.prototype.slice;
|
7
|
+
|
8
|
+
if (typeof Spine === "undefined" || Spine === null) Spine = require('spine');
|
9
|
+
|
14
10
|
$ = Spine.$;
|
11
|
+
|
15
12
|
Model = Spine.Model;
|
13
|
+
|
16
14
|
Ajax = {
|
17
15
|
getURL: function(object) {
|
18
16
|
return object && (typeof object.url === "function" ? object.url() : void 0) || object.url;
|
@@ -21,9 +19,13 @@
|
|
21
19
|
pending: false,
|
22
20
|
requests: [],
|
23
21
|
disable: function(callback) {
|
24
|
-
this.enabled
|
25
|
-
|
26
|
-
|
22
|
+
if (this.enabled) {
|
23
|
+
this.enabled = false;
|
24
|
+
callback();
|
25
|
+
return this.enabled = true;
|
26
|
+
} else {
|
27
|
+
return callback();
|
28
|
+
}
|
27
29
|
},
|
28
30
|
requestNext: function() {
|
29
31
|
var next;
|
@@ -35,14 +37,13 @@
|
|
35
37
|
}
|
36
38
|
},
|
37
39
|
request: function(callback) {
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
var _this = this;
|
41
|
+
return (callback()).complete(function() {
|
42
|
+
return _this.requestNext();
|
43
|
+
});
|
41
44
|
},
|
42
45
|
queue: function(callback) {
|
43
|
-
if (!this.enabled)
|
44
|
-
return;
|
45
|
-
}
|
46
|
+
if (!this.enabled) return;
|
46
47
|
if (this.pending) {
|
47
48
|
this.requests.push(callback);
|
48
49
|
} else {
|
@@ -52,8 +53,11 @@
|
|
52
53
|
return callback;
|
53
54
|
}
|
54
55
|
};
|
56
|
+
|
55
57
|
Base = (function() {
|
58
|
+
|
56
59
|
function Base() {}
|
60
|
+
|
57
61
|
Base.prototype.defaults = {
|
58
62
|
contentType: 'application/json',
|
59
63
|
dataType: 'json',
|
@@ -62,21 +66,29 @@
|
|
62
66
|
'X-Requested-With': 'XMLHttpRequest'
|
63
67
|
}
|
64
68
|
};
|
69
|
+
|
65
70
|
Base.prototype.ajax = function(params, defaults) {
|
66
71
|
return $.ajax($.extend({}, this.defaults, defaults, params));
|
67
72
|
};
|
73
|
+
|
68
74
|
Base.prototype.queue = function(callback) {
|
69
75
|
return Ajax.queue(callback);
|
70
76
|
};
|
77
|
+
|
71
78
|
return Base;
|
79
|
+
|
72
80
|
})();
|
73
|
-
|
74
|
-
|
81
|
+
|
82
|
+
Collection = (function(_super) {
|
83
|
+
|
84
|
+
__extends(Collection, _super);
|
85
|
+
|
75
86
|
function Collection(model) {
|
76
87
|
this.model = model;
|
77
88
|
this.errorResponse = __bind(this.errorResponse, this);
|
78
89
|
this.recordsResponse = __bind(this.recordsResponse, this);
|
79
90
|
}
|
91
|
+
|
80
92
|
Collection.prototype.find = function(id, params) {
|
81
93
|
var record;
|
82
94
|
record = new this.model({
|
@@ -87,123 +99,163 @@
|
|
87
99
|
url: Ajax.getURL(record)
|
88
100
|
}).success(this.recordsResponse).error(this.errorResponse);
|
89
101
|
};
|
102
|
+
|
90
103
|
Collection.prototype.all = function(params) {
|
91
104
|
return this.ajax(params, {
|
92
105
|
type: 'GET',
|
93
106
|
url: Ajax.getURL(this.model)
|
94
107
|
}).success(this.recordsResponse).error(this.errorResponse);
|
95
108
|
};
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
}
|
109
|
+
|
110
|
+
Collection.prototype.fetch = function(params, options) {
|
111
|
+
var id,
|
112
|
+
_this = this;
|
113
|
+
if (params == null) params = {};
|
114
|
+
if (options == null) options = {};
|
101
115
|
if (id = params.id) {
|
102
116
|
delete params.id;
|
103
|
-
return this.find(id, params).success(
|
104
|
-
return
|
105
|
-
}
|
117
|
+
return this.find(id, params).success(function(record) {
|
118
|
+
return _this.model.refresh(record, options);
|
119
|
+
});
|
106
120
|
} else {
|
107
|
-
return this.all(params).success(
|
108
|
-
return
|
109
|
-
}
|
121
|
+
return this.all(params).success(function(records) {
|
122
|
+
return _this.model.refresh(records, options);
|
123
|
+
});
|
110
124
|
}
|
111
125
|
};
|
126
|
+
|
112
127
|
Collection.prototype.recordsResponse = function(data, status, xhr) {
|
113
128
|
return this.model.trigger('ajaxSuccess', null, status, xhr);
|
114
129
|
};
|
130
|
+
|
115
131
|
Collection.prototype.errorResponse = function(xhr, statusText, error) {
|
116
132
|
return this.model.trigger('ajaxError', null, xhr, statusText, error);
|
117
133
|
};
|
134
|
+
|
118
135
|
return Collection;
|
119
|
-
|
120
|
-
|
121
|
-
|
136
|
+
|
137
|
+
})(Base);
|
138
|
+
|
139
|
+
Singleton = (function(_super) {
|
140
|
+
|
141
|
+
__extends(Singleton, _super);
|
142
|
+
|
122
143
|
function Singleton(record) {
|
123
144
|
this.record = record;
|
124
145
|
this.errorResponse = __bind(this.errorResponse, this);
|
125
|
-
this.blankResponse = __bind(this.blankResponse, this);
|
126
146
|
this.recordResponse = __bind(this.recordResponse, this);
|
127
147
|
this.model = this.record.constructor;
|
128
148
|
}
|
129
|
-
|
130
|
-
|
131
|
-
|
149
|
+
|
150
|
+
Singleton.prototype.reload = function(params, options) {
|
151
|
+
var _this = this;
|
152
|
+
return this.queue(function() {
|
153
|
+
return _this.ajax(params, {
|
132
154
|
type: 'GET',
|
133
|
-
url: Ajax.getURL(
|
134
|
-
}).success(
|
135
|
-
}
|
155
|
+
url: Ajax.getURL(_this.record)
|
156
|
+
}).success(_this.recordResponse(options)).error(_this.errorResponse(options));
|
157
|
+
});
|
136
158
|
};
|
137
|
-
|
138
|
-
|
139
|
-
|
159
|
+
|
160
|
+
Singleton.prototype.create = function(params, options) {
|
161
|
+
var _this = this;
|
162
|
+
return this.queue(function() {
|
163
|
+
return _this.ajax(params, {
|
140
164
|
type: 'POST',
|
141
|
-
data: JSON.stringify(
|
142
|
-
url: Ajax.getURL(
|
143
|
-
}).success(
|
144
|
-
}
|
165
|
+
data: JSON.stringify(_this.record),
|
166
|
+
url: Ajax.getURL(_this.model)
|
167
|
+
}).success(_this.recordResponse(options)).error(_this.errorResponse(options));
|
168
|
+
});
|
145
169
|
};
|
146
|
-
|
147
|
-
|
148
|
-
|
170
|
+
|
171
|
+
Singleton.prototype.update = function(params, options) {
|
172
|
+
var _this = this;
|
173
|
+
return this.queue(function() {
|
174
|
+
return _this.ajax(params, {
|
149
175
|
type: 'PUT',
|
150
|
-
data: JSON.stringify(
|
151
|
-
url: Ajax.getURL(
|
152
|
-
}).success(
|
153
|
-
}
|
176
|
+
data: JSON.stringify(_this.record),
|
177
|
+
url: Ajax.getURL(_this.record)
|
178
|
+
}).success(_this.recordResponse(options)).error(_this.errorResponse(options));
|
179
|
+
});
|
154
180
|
};
|
155
|
-
|
156
|
-
|
157
|
-
|
181
|
+
|
182
|
+
Singleton.prototype.destroy = function(params, options) {
|
183
|
+
var _this = this;
|
184
|
+
return this.queue(function() {
|
185
|
+
return _this.ajax(params, {
|
158
186
|
type: 'DELETE',
|
159
|
-
url: Ajax.getURL(
|
160
|
-
}).success(
|
161
|
-
}
|
187
|
+
url: Ajax.getURL(_this.record)
|
188
|
+
}).success(_this.recordResponse(options)).error(_this.errorResponse(options));
|
189
|
+
});
|
162
190
|
};
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
191
|
+
|
192
|
+
Singleton.prototype.recordResponse = function(options) {
|
193
|
+
var _this = this;
|
194
|
+
if (options == null) options = {};
|
195
|
+
return function(data, status, xhr) {
|
196
|
+
var _ref;
|
197
|
+
if (Spine.isBlank(data)) {
|
198
|
+
data = false;
|
199
|
+
} else {
|
200
|
+
data = _this.model.fromJSON(data);
|
172
201
|
}
|
173
|
-
|
174
|
-
|
202
|
+
Ajax.disable(function() {
|
203
|
+
if (data) {
|
204
|
+
if (data.id && _this.record.id !== data.id) {
|
205
|
+
_this.record.changeID(data.id);
|
206
|
+
}
|
207
|
+
return _this.record.updateAttributes(data.attributes());
|
208
|
+
}
|
209
|
+
});
|
210
|
+
_this.record.trigger('ajaxSuccess', data, status, xhr);
|
211
|
+
return (_ref = options.success) != null ? _ref.apply(_this.record) : void 0;
|
212
|
+
};
|
175
213
|
};
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
return
|
214
|
+
|
215
|
+
Singleton.prototype.errorResponse = function(options) {
|
216
|
+
var _this = this;
|
217
|
+
if (options == null) options = {};
|
218
|
+
return function(xhr, statusText, error) {
|
219
|
+
var _ref;
|
220
|
+
_this.record.trigger('ajaxError', xhr, statusText, error);
|
221
|
+
return (_ref = options.error) != null ? _ref.apply(_this.record) : void 0;
|
222
|
+
};
|
181
223
|
};
|
224
|
+
|
182
225
|
return Singleton;
|
183
|
-
|
226
|
+
|
227
|
+
})(Base);
|
228
|
+
|
184
229
|
Model.host = '';
|
230
|
+
|
185
231
|
Include = {
|
186
232
|
ajax: function() {
|
187
233
|
return new Singleton(this);
|
188
234
|
},
|
189
235
|
url: function() {
|
190
|
-
var
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
return
|
236
|
+
var args, url;
|
237
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
238
|
+
url = Ajax.getURL(this.constructor);
|
239
|
+
if (url.charAt(url.length - 1) !== '/') url += '/';
|
240
|
+
url += encodeURIComponent(this.id);
|
241
|
+
args.unshift(url);
|
242
|
+
return args.join('/');
|
197
243
|
}
|
198
244
|
};
|
245
|
+
|
199
246
|
Extend = {
|
200
247
|
ajax: function() {
|
201
248
|
return new Collection(this);
|
202
249
|
},
|
203
250
|
url: function() {
|
204
|
-
|
251
|
+
var args;
|
252
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
253
|
+
args.unshift(this.className.toLowerCase() + 's');
|
254
|
+
args.unshift(Model.host);
|
255
|
+
return args.join('/');
|
205
256
|
}
|
206
257
|
};
|
258
|
+
|
207
259
|
Model.Ajax = {
|
208
260
|
extended: function() {
|
209
261
|
this.fetch(this.ajaxFetch);
|
@@ -215,18 +267,24 @@
|
|
215
267
|
var _ref;
|
216
268
|
return (_ref = this.ajax()).fetch.apply(_ref, arguments);
|
217
269
|
},
|
218
|
-
ajaxChange: function(record, type) {
|
219
|
-
|
270
|
+
ajaxChange: function(record, type, options) {
|
271
|
+
if (options == null) options = {};
|
272
|
+
if (options.ajax === false) return;
|
273
|
+
return record.ajax()[type](options.ajax, options);
|
220
274
|
}
|
221
275
|
};
|
276
|
+
|
222
277
|
Model.Ajax.Methods = {
|
223
278
|
extended: function() {
|
224
279
|
this.extend(Extend);
|
225
280
|
return this.include(Include);
|
226
281
|
}
|
227
282
|
};
|
283
|
+
|
284
|
+
Ajax.defaults = Base.prototype.defaults;
|
285
|
+
|
228
286
|
Spine.Ajax = Ajax;
|
229
|
-
|
230
|
-
|
231
|
-
|
287
|
+
|
288
|
+
if (typeof module !== "undefined" && module !== null) module.exports = Ajax;
|
289
|
+
|
232
290
|
}).call(this);
|
@@ -1,42 +1,44 @@
|
|
1
1
|
(function() {
|
2
|
-
var
|
3
|
-
|
4
|
-
|
5
|
-
function ctor() { this.constructor = child; }
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
return child;
|
10
|
-
};
|
11
|
-
if (typeof Spine === "undefined" || Spine === null) {
|
12
|
-
Spine = require('spine');
|
13
|
-
}
|
2
|
+
var $,
|
3
|
+
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
4
|
+
__hasProp = Object.prototype.hasOwnProperty,
|
5
|
+
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
|
6
|
+
|
7
|
+
if (typeof Spine === "undefined" || Spine === null) Spine = require('spine');
|
8
|
+
|
14
9
|
$ = Spine.$;
|
15
|
-
|
16
|
-
|
10
|
+
|
11
|
+
Spine.List = (function(_super) {
|
12
|
+
|
13
|
+
__extends(List, _super);
|
14
|
+
|
17
15
|
List.prototype.events = {
|
18
16
|
'click .item': 'click'
|
19
17
|
};
|
18
|
+
|
20
19
|
List.prototype.selectFirst = false;
|
20
|
+
|
21
21
|
function List() {
|
22
22
|
this.change = __bind(this.change, this); List.__super__.constructor.apply(this, arguments);
|
23
23
|
this.bind('change', this.change);
|
24
24
|
}
|
25
|
+
|
25
26
|
List.prototype.template = function() {
|
26
27
|
return arguments[0];
|
27
28
|
};
|
29
|
+
|
28
30
|
List.prototype.change = function(item) {
|
29
|
-
|
31
|
+
this.current = item;
|
32
|
+
if (!this.current) {
|
33
|
+
this.children().removeClass('active');
|
30
34
|
return;
|
31
35
|
}
|
32
|
-
this.current = item;
|
33
36
|
this.children().removeClass('active');
|
34
37
|
return this.children().forItem(this.current).addClass('active');
|
35
38
|
};
|
39
|
+
|
36
40
|
List.prototype.render = function(items) {
|
37
|
-
if (items)
|
38
|
-
this.items = items;
|
39
|
-
}
|
41
|
+
if (items) this.items = items;
|
40
42
|
this.html(this.template(this.items));
|
41
43
|
this.change(this.current);
|
42
44
|
if (this.selectFirst) {
|
@@ -45,18 +47,24 @@
|
|
45
47
|
}
|
46
48
|
}
|
47
49
|
};
|
50
|
+
|
48
51
|
List.prototype.children = function(sel) {
|
49
52
|
return this.el.children(sel);
|
50
53
|
};
|
54
|
+
|
51
55
|
List.prototype.click = function(e) {
|
52
56
|
var item;
|
53
57
|
item = $(e.currentTarget).item();
|
54
58
|
this.trigger('change', item);
|
55
|
-
return
|
59
|
+
return true;
|
56
60
|
};
|
61
|
+
|
57
62
|
return List;
|
58
|
-
|
63
|
+
|
64
|
+
})(Spine.Controller);
|
65
|
+
|
59
66
|
if (typeof module !== "undefined" && module !== null) {
|
60
67
|
module.exports = Spine.List;
|
61
68
|
}
|
69
|
+
|
62
70
|
}).call(this);
|