spine-rails 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,194 @@
1
+ (function() {
2
+ var $, Ajax, Base, Collection, Include, Model, Singleton;
3
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
4
+ for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
5
+ function ctor() { this.constructor = child; }
6
+ ctor.prototype = parent.prototype;
7
+ child.prototype = new ctor;
8
+ child.__super__ = parent.prototype;
9
+ return child;
10
+ };
11
+ if (typeof Spine === "undefined" || Spine === null) {
12
+ Spine = require("spine");
13
+ }
14
+ $ = Spine.$;
15
+ Model = Spine.Model;
16
+ Ajax = {
17
+ getURL: function(object) {
18
+ return object && (typeof object.url === "function" ? object.url() : void 0) || object.url;
19
+ },
20
+ enabled: true,
21
+ pending: false,
22
+ requests: [],
23
+ disable: function(callback) {
24
+ this.enabled = false;
25
+ callback();
26
+ return this.enabled = true;
27
+ },
28
+ requestNext: function() {
29
+ var next;
30
+ next = this.requests.shift();
31
+ if (next) {
32
+ return this.request(next);
33
+ } else {
34
+ return this.pending = false;
35
+ }
36
+ },
37
+ request: function(callback) {
38
+ return (callback()).complete(__bind(function() {
39
+ return this.requestNext();
40
+ }, this));
41
+ },
42
+ queue: function(callback) {
43
+ if (!this.enabled) {
44
+ return;
45
+ }
46
+ if (this.pending) {
47
+ return this.requests.push(callback);
48
+ } else {
49
+ this.pending = true;
50
+ return this.request(callback);
51
+ }
52
+ }
53
+ };
54
+ Base = (function() {
55
+ function Base() {}
56
+ Base.prototype.defaults = {
57
+ contentType: "application/json",
58
+ dataType: "json",
59
+ processData: false
60
+ };
61
+ Base.prototype.ajax = function(params, defaults) {
62
+ return $.ajax($.extend({}, this.defaults, defaults, params));
63
+ };
64
+ Base.prototype.queue = function(callback) {
65
+ return Ajax.queue(callback);
66
+ };
67
+ return Base;
68
+ })();
69
+ Collection = (function() {
70
+ __extends(Collection, Base);
71
+ function Collection(model) {
72
+ this.model = model;
73
+ this.errorResponse = __bind(this.errorResponse, this);
74
+ this.recordsResponse = __bind(this.recordsResponse, this);
75
+ }
76
+ Collection.prototype.findAll = function(params) {
77
+ return this.ajax(params, {
78
+ type: "GET",
79
+ url: Ajax.getURL(this.model)
80
+ }).success(this.recordsResponse).error(this.errorResponse);
81
+ };
82
+ Collection.prototype.fetch = function() {
83
+ return this.findAll().success(__bind(function(records) {
84
+ return this.model.refresh(records);
85
+ }, this));
86
+ };
87
+ Collection.prototype.recordsResponse = function(data, status, xhr) {
88
+ return this.model.trigger("ajaxSuccess", null, status, xhr);
89
+ };
90
+ Collection.prototype.errorResponse = function(xhr, statusText, error) {
91
+ return this.model.trigger("ajaxError", null, xhr, statusText, error);
92
+ };
93
+ return Collection;
94
+ })();
95
+ Singleton = (function() {
96
+ __extends(Singleton, Base);
97
+ function Singleton(record) {
98
+ this.record = record;
99
+ this.errorResponse = __bind(this.errorResponse, this);
100
+ this.blankResponse = __bind(this.blankResponse, this);
101
+ this.recordResponse = __bind(this.recordResponse, this);
102
+ this.model = this.record.constructor;
103
+ }
104
+ Singleton.prototype.find = function(params) {
105
+ return this.ajax(params, {
106
+ type: "GET",
107
+ url: this.url
108
+ });
109
+ };
110
+ Singleton.prototype.create = function(params) {
111
+ return this.queue(__bind(function() {
112
+ return this.ajax(params, {
113
+ type: "POST",
114
+ data: JSON.stringify(this.record),
115
+ url: Ajax.getURL(this.model)
116
+ }).success(this.recordResponse).error(this.errorResponse);
117
+ }, this));
118
+ };
119
+ Singleton.prototype.update = function(params) {
120
+ return this.queue(__bind(function() {
121
+ return this.ajax(params, {
122
+ type: "PUT",
123
+ data: JSON.stringify(this.record),
124
+ url: Ajax.getURL(this.record)
125
+ }).success(this.recordResponse).error(this.errorResponse);
126
+ }, this));
127
+ };
128
+ Singleton.prototype.destroy = function(params) {
129
+ return this.queue(__bind(function() {
130
+ return this.ajax(params, {
131
+ type: "DELETE",
132
+ url: Ajax.getURL(this.record)
133
+ }).success(this.recordResponse).error(this.errorResponse);
134
+ }, this));
135
+ };
136
+ Singleton.prototype.recordResponse = function(data, status, xhr) {
137
+ this.record.trigger("ajaxSuccess", this.record, status, xhr);
138
+ if (Spine.isBlank(data)) {
139
+ return;
140
+ }
141
+ data = this.model.fromJSON(data);
142
+ return Ajax.disable(__bind(function() {
143
+ if (data.id && this.record.id !== data.id) {
144
+ this.record.changeID(data.id);
145
+ }
146
+ return this.record.updateAttributes(data.attributes());
147
+ }, this));
148
+ };
149
+ Singleton.prototype.blankResponse = function(data, status, xhr) {
150
+ return this.record.trigger("ajaxSuccess", this.record, status, xhr);
151
+ };
152
+ Singleton.prototype.errorResponse = function(xhr, statusText, error) {
153
+ return this.record.trigger("ajaxError", this.record, xhr, statusText, error);
154
+ };
155
+ return Singleton;
156
+ })();
157
+ Model.host = "";
158
+ Include = {
159
+ ajax: function() {
160
+ return new Singleton(this);
161
+ },
162
+ url: function() {
163
+ var base;
164
+ base = Ajax.getURL(this.constructor);
165
+ if (base.charAt(base.length - 1) !== "/") {
166
+ base += "/";
167
+ }
168
+ base += encodeURIComponent(this.id);
169
+ return base;
170
+ }
171
+ };
172
+ Model.Ajax = {
173
+ ajax: function() {
174
+ return new Collection(this);
175
+ },
176
+ extended: function() {
177
+ this.change(function(record, type) {
178
+ return record.ajax()[type]();
179
+ });
180
+ this.fetch(function() {
181
+ var _ref;
182
+ return (_ref = this.ajax()).fetch.apply(_ref, arguments);
183
+ });
184
+ return this.include(Include);
185
+ },
186
+ url: function() {
187
+ return "" + Model.host + "/" + (this.className.toLowerCase()) + "s";
188
+ }
189
+ };
190
+ Spine.Ajax = Ajax;
191
+ if (typeof module !== "undefined" && module !== null) {
192
+ module.exports = Ajax;
193
+ }
194
+ }).call(this);
@@ -0,0 +1,61 @@
1
+ (function() {
2
+ var $;
3
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
4
+ for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
5
+ function ctor() { this.constructor = child; }
6
+ ctor.prototype = parent.prototype;
7
+ child.prototype = new ctor;
8
+ child.__super__ = parent.prototype;
9
+ return child;
10
+ };
11
+ if (typeof Spine === "undefined" || Spine === null) {
12
+ Spine = require("spine");
13
+ }
14
+ $ = Spine.$;
15
+ Spine.List = (function() {
16
+ __extends(List, Spine.Controller);
17
+ List.prototype.events = {
18
+ "click .item": "click"
19
+ };
20
+ List.prototype.selectFirst = false;
21
+ function List() {
22
+ this.change = __bind(this.change, this); List.__super__.constructor.apply(this, arguments);
23
+ this.bind("change", this.change);
24
+ }
25
+ List.prototype.template = function() {
26
+ return arguments[0];
27
+ };
28
+ List.prototype.change = function(item) {
29
+ if (!item) {
30
+ return;
31
+ }
32
+ this.current = item;
33
+ this.children().removeClass("active");
34
+ return this.children().forItem(this.current).addClass("active");
35
+ };
36
+ List.prototype.render = function(items) {
37
+ if (items) {
38
+ this.items = items;
39
+ }
40
+ this.html(this.template(this.items));
41
+ this.change(this.current);
42
+ if (this.selectFirst) {
43
+ if (!this.children(".active").length) {
44
+ return this.children(":first").click();
45
+ }
46
+ }
47
+ };
48
+ List.prototype.children = function(sel) {
49
+ return this.el.children(sel);
50
+ };
51
+ List.prototype.click = function(e) {
52
+ var item;
53
+ item = $(e.target).item();
54
+ return this.trigger("change", item);
55
+ };
56
+ return List;
57
+ })();
58
+ if (typeof module !== "undefined" && module !== null) {
59
+ module.exports = Spine.List;
60
+ }
61
+ }).call(this);
@@ -0,0 +1,26 @@
1
+ (function() {
2
+ if (typeof Spine === "undefined" || Spine === null) {
3
+ Spine = require("spine");
4
+ }
5
+ Spine.Model.Local = {
6
+ extended: function() {
7
+ this.change(this.saveLocal);
8
+ return this.fetch(this.loadLocal);
9
+ },
10
+ saveLocal: function() {
11
+ var result;
12
+ result = JSON.stringify(this);
13
+ return localStorage[this.className] = result;
14
+ },
15
+ loadLocal: function() {
16
+ var result;
17
+ result = localStorage[this.className];
18
+ return this.refresh(result || [], {
19
+ clear: true
20
+ });
21
+ }
22
+ };
23
+ if (typeof module !== "undefined" && module !== null) {
24
+ module.exports = Spine.Model.Local;
25
+ }
26
+ }).call(this);
@@ -0,0 +1,86 @@
1
+ (function() {
2
+ var $;
3
+ var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
4
+ for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
5
+ function ctor() { this.constructor = child; }
6
+ ctor.prototype = parent.prototype;
7
+ child.prototype = new ctor;
8
+ child.__super__ = parent.prototype;
9
+ return child;
10
+ }, __slice = Array.prototype.slice, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
11
+ if (typeof Spine === "undefined" || Spine === null) {
12
+ Spine = require('spine');
13
+ }
14
+ $ = Spine.$;
15
+ Spine.Manager = (function() {
16
+ __extends(Manager, Spine.Module);
17
+ Manager.include(Spine.Events);
18
+ function Manager() {
19
+ this.controllers = [];
20
+ this.add.apply(this, arguments);
21
+ this.bind('change', this.change);
22
+ }
23
+ Manager.prototype.add = function() {
24
+ var cont, controllers, _i, _len, _results;
25
+ controllers = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
26
+ _results = [];
27
+ for (_i = 0, _len = controllers.length; _i < _len; _i++) {
28
+ cont = controllers[_i];
29
+ _results.push(this.addOne(cont));
30
+ }
31
+ return _results;
32
+ };
33
+ Manager.prototype.addOne = function(controller) {
34
+ controller.bind('active', __bind(function() {
35
+ var args;
36
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
37
+ return this.trigger('change', controller, args);
38
+ }, this));
39
+ controller.bind('destroy', __bind(function() {
40
+ return this.controllers.splice(this.controllers.indexOf(controller), 1);
41
+ }, this));
42
+ return this.controllers.push(controller);
43
+ };
44
+ Manager.prototype.deactivate = function() {
45
+ return this.trigger('change', false, arguments);
46
+ };
47
+ Manager.prototype.change = function(current, args) {
48
+ var cont, _i, _len, _ref, _results;
49
+ _ref = this.controllers;
50
+ _results = [];
51
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
52
+ cont = _ref[_i];
53
+ _results.push(cont === current ? cont.activate.apply(cont, args) : cont.deactivate.apply(cont, args));
54
+ }
55
+ return _results;
56
+ };
57
+ return Manager;
58
+ })();
59
+ Spine.Controller.include({
60
+ active: function() {
61
+ var args;
62
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
63
+ if (typeof args[0] === 'function') {
64
+ this.bind('active', args[0]);
65
+ } else {
66
+ args.unshift('active');
67
+ this.trigger.apply(this, args);
68
+ }
69
+ return this;
70
+ },
71
+ isActive: function() {
72
+ return this.el.hasClass('active');
73
+ },
74
+ activate: function() {
75
+ this.el.addClass('active');
76
+ return this;
77
+ },
78
+ deactivate: function() {
79
+ this.el.removeClass('active');
80
+ return this;
81
+ }
82
+ });
83
+ if (typeof module !== "undefined" && module !== null) {
84
+ module.exports = Spine.Manager;
85
+ }
86
+ }).call(this);
@@ -0,0 +1,145 @@
1
+ (function() {
2
+ var Collection, Instance, singularize, underscore;
3
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
4
+ if (typeof Spine === "undefined" || Spine === null) {
5
+ Spine = require("spine");
6
+ }
7
+ Collection = (function() {
8
+ function Collection(options) {
9
+ var key, value;
10
+ if (options == null) {
11
+ options = {};
12
+ }
13
+ for (key in options) {
14
+ value = options[key];
15
+ this[key] = value;
16
+ }
17
+ }
18
+ Collection.prototype.all = function() {
19
+ return this.model.select(__bind(function(rec) {
20
+ return this.associated(rec);
21
+ }, this));
22
+ };
23
+ Collection.prototype.first = function() {
24
+ return this.all()[0];
25
+ };
26
+ Collection.prototype.last = function() {
27
+ var values;
28
+ values = this.all();
29
+ return values[values.length - 1];
30
+ };
31
+ Collection.prototype.find = function(id) {
32
+ var records;
33
+ records = this.model.select(__bind(function(rec) {
34
+ return this.associated(rec) && rec.id === id;
35
+ }, this));
36
+ if (!records[0]) {
37
+ throw "Unknown record";
38
+ }
39
+ return records[0];
40
+ };
41
+ Collection.prototype.select = function(cb) {
42
+ return this.model.select(__bind(function(rec) {
43
+ return this.associated(rec) && cb(rec);
44
+ }, this));
45
+ };
46
+ Collection.prototype.refresh = function(values) {
47
+ var record, records, value, _i, _j, _len, _len2;
48
+ records = this.all();
49
+ for (_i = 0, _len = records.length; _i < _len; _i++) {
50
+ record = records[_i];
51
+ delete this.model.records[record.id];
52
+ }
53
+ values = this.model.fromJSON(values);
54
+ for (_j = 0, _len2 = values.length; _j < _len2; _j++) {
55
+ value = values[_j];
56
+ value.newRecord = false;
57
+ value[this.fkey] = this.record.id;
58
+ this.model.records[value.id] = value;
59
+ }
60
+ return this.model.trigger("refresh");
61
+ };
62
+ Collection.prototype.create = function(record) {
63
+ record[this.fkey] = this.record.id;
64
+ return this.model.create(record);
65
+ };
66
+ Collection.prototype.associated = function(record) {
67
+ return record[this.fkey] === this.record.id;
68
+ };
69
+ return Collection;
70
+ })();
71
+ Instance = (function() {
72
+ function Instance(options) {
73
+ var key, value;
74
+ if (options == null) {
75
+ options = {};
76
+ }
77
+ for (key in options) {
78
+ value = options[key];
79
+ this[key] = value;
80
+ }
81
+ }
82
+ Instance.prototype.find = function() {
83
+ return this.record[this.fkey] && this.model.find(this.record[this.fkey]);
84
+ };
85
+ Instance.prototype.update = function(value) {
86
+ return this.record[this.fkey] = value && value.id;
87
+ };
88
+ return Instance;
89
+ })();
90
+ singularize = function(str) {
91
+ return str.replace(/s$/, '');
92
+ };
93
+ underscore = function(str) {
94
+ return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/-/g, '_').toLowerCase();
95
+ };
96
+ Spine.Model.extend({
97
+ many: function(name, model, fkey) {
98
+ var association;
99
+ if (fkey == null) {
100
+ fkey = "" + (underscore(this.className)) + "_id";
101
+ }
102
+ association = function(record) {
103
+ if (typeof model === "string") {
104
+ model = require(model);
105
+ }
106
+ return new Collection({
107
+ name: name,
108
+ model: model,
109
+ record: record,
110
+ fkey: fkey
111
+ });
112
+ };
113
+ this.prototype.__defineGetter__(name, function() {
114
+ return association(this);
115
+ });
116
+ return this.prototype.__defineSetter__(name, function(value) {
117
+ return association(this).refresh(value);
118
+ });
119
+ },
120
+ belongs: function(name, model, fkey) {
121
+ var association;
122
+ if (fkey == null) {
123
+ fkey = "" + (singularize(name)) + "_id";
124
+ }
125
+ association = function(record) {
126
+ if (typeof model === "string") {
127
+ model = require(model);
128
+ }
129
+ return new Instance({
130
+ name: name,
131
+ model: model,
132
+ record: record,
133
+ fkey: fkey
134
+ });
135
+ };
136
+ this.prototype.__defineGetter__(name, function() {
137
+ return association(this).find();
138
+ });
139
+ this.prototype.__defineSetter__(name, function(value) {
140
+ return association(this).update(value);
141
+ });
142
+ return this.attributes.push(fkey);
143
+ }
144
+ });
145
+ }).call(this);