spine-rails 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +12 -3
- data/build/update.sh +9 -0
- data/lib/generators/spine/model/model_generator.rb +1 -1
- data/lib/generators/spine/new/new_generator.rb +14 -14
- data/lib/generators/spine/scaffold/scaffold_generator.rb +5 -5
- data/lib/generators/spine/scaffold/templates/controller.coffee.erb +1 -1
- data/lib/spine/generators.rb +5 -5
- data/lib/spine/rails/version.rb +2 -2
- data/spine-rails.gemspec +2 -1
- data/vendor/assets/javascripts/spine.coffee +640 -0
- data/vendor/assets/javascripts/spine/ajax.coffee +237 -0
- data/vendor/assets/javascripts/spine/list.coffee +43 -0
- data/vendor/assets/javascripts/spine/local.coffee +16 -0
- data/vendor/assets/javascripts/spine/manager.coffee +84 -0
- data/vendor/assets/javascripts/spine/relation.coffee +136 -0
- data/vendor/assets/javascripts/spine/route.coffee +148 -0
- metadata +41 -17
- data/app/assets/javascripts/json2.js +0 -485
- data/app/assets/javascripts/spine.js +0 -808
- data/app/assets/javascripts/spine/ajax.js +0 -290
- data/app/assets/javascripts/spine/list.js +0 -70
- data/app/assets/javascripts/spine/local.js +0 -28
- data/app/assets/javascripts/spine/manager.js +0 -154
- data/app/assets/javascripts/spine/relation.js +0 -222
- data/app/assets/javascripts/spine/route.js +0 -197
- data/app/assets/javascripts/spine/tabs.js +0 -66
- data/app/assets/javascripts/spine/tmpl.js +0 -22
@@ -1,222 +0,0 @@
|
|
1
|
-
(function() {
|
2
|
-
var Collection, Instance, Singleton, isArray, singularize, underscore,
|
3
|
-
__hasProp = Object.prototype.hasOwnProperty,
|
4
|
-
__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; };
|
5
|
-
|
6
|
-
if (typeof Spine === "undefined" || Spine === null) Spine = require('spine');
|
7
|
-
|
8
|
-
isArray = Spine.isArray;
|
9
|
-
|
10
|
-
if (typeof require === "undefined" || require === null) {
|
11
|
-
require = (function(value) {
|
12
|
-
return eval(value);
|
13
|
-
});
|
14
|
-
}
|
15
|
-
|
16
|
-
Collection = (function(_super) {
|
17
|
-
|
18
|
-
__extends(Collection, _super);
|
19
|
-
|
20
|
-
function Collection(options) {
|
21
|
-
var key, value;
|
22
|
-
if (options == null) options = {};
|
23
|
-
for (key in options) {
|
24
|
-
value = options[key];
|
25
|
-
this[key] = value;
|
26
|
-
}
|
27
|
-
}
|
28
|
-
|
29
|
-
Collection.prototype.all = function() {
|
30
|
-
var _this = this;
|
31
|
-
return this.model.select(function(rec) {
|
32
|
-
return _this.associated(rec);
|
33
|
-
});
|
34
|
-
};
|
35
|
-
|
36
|
-
Collection.prototype.first = function() {
|
37
|
-
return this.all()[0];
|
38
|
-
};
|
39
|
-
|
40
|
-
Collection.prototype.last = function() {
|
41
|
-
var values;
|
42
|
-
values = this.all();
|
43
|
-
return values[values.length - 1];
|
44
|
-
};
|
45
|
-
|
46
|
-
Collection.prototype.find = function(id) {
|
47
|
-
var records,
|
48
|
-
_this = this;
|
49
|
-
records = this.select(function(rec) {
|
50
|
-
return rec.id + '' === id + '';
|
51
|
-
});
|
52
|
-
if (!records[0]) throw 'Unknown record';
|
53
|
-
return records[0];
|
54
|
-
};
|
55
|
-
|
56
|
-
Collection.prototype.findAllByAttribute = function(name, value) {
|
57
|
-
var _this = this;
|
58
|
-
return this.model.select(function(rec) {
|
59
|
-
return rec[name] === value;
|
60
|
-
});
|
61
|
-
};
|
62
|
-
|
63
|
-
Collection.prototype.findByAttribute = function(name, value) {
|
64
|
-
return this.findAllByAttribute(name, value)[0];
|
65
|
-
};
|
66
|
-
|
67
|
-
Collection.prototype.select = function(cb) {
|
68
|
-
var _this = this;
|
69
|
-
return this.model.select(function(rec) {
|
70
|
-
return _this.associated(rec) && cb(rec);
|
71
|
-
});
|
72
|
-
};
|
73
|
-
|
74
|
-
Collection.prototype.refresh = function(values) {
|
75
|
-
var record, records, _i, _j, _len, _len2, _ref;
|
76
|
-
_ref = this.all();
|
77
|
-
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
78
|
-
record = _ref[_i];
|
79
|
-
delete this.model.records[record.id];
|
80
|
-
}
|
81
|
-
records = this.model.fromJSON(values);
|
82
|
-
if (!isArray(records)) records = [records];
|
83
|
-
for (_j = 0, _len2 = records.length; _j < _len2; _j++) {
|
84
|
-
record = records[_j];
|
85
|
-
record.newRecord = false;
|
86
|
-
record[this.fkey] = this.record.id;
|
87
|
-
this.model.records[record.id] = record;
|
88
|
-
}
|
89
|
-
return this.model.trigger('refresh', records);
|
90
|
-
};
|
91
|
-
|
92
|
-
Collection.prototype.create = function(record) {
|
93
|
-
record[this.fkey] = this.record.id;
|
94
|
-
return this.model.create(record);
|
95
|
-
};
|
96
|
-
|
97
|
-
Collection.prototype.associated = function(record) {
|
98
|
-
return record[this.fkey] === this.record.id;
|
99
|
-
};
|
100
|
-
|
101
|
-
return Collection;
|
102
|
-
|
103
|
-
})(Spine.Module);
|
104
|
-
|
105
|
-
Instance = (function(_super) {
|
106
|
-
|
107
|
-
__extends(Instance, _super);
|
108
|
-
|
109
|
-
function Instance(options) {
|
110
|
-
var key, value;
|
111
|
-
if (options == null) options = {};
|
112
|
-
for (key in options) {
|
113
|
-
value = options[key];
|
114
|
-
this[key] = value;
|
115
|
-
}
|
116
|
-
}
|
117
|
-
|
118
|
-
Instance.prototype.exists = function() {
|
119
|
-
return this.record[this.fkey] && this.model.exists(this.record[this.fkey]);
|
120
|
-
};
|
121
|
-
|
122
|
-
Instance.prototype.update = function(value) {
|
123
|
-
if (!(value instanceof this.model)) value = new this.model(value);
|
124
|
-
if (value.isNew()) value.save();
|
125
|
-
return this.record[this.fkey] = value && value.id;
|
126
|
-
};
|
127
|
-
|
128
|
-
return Instance;
|
129
|
-
|
130
|
-
})(Spine.Module);
|
131
|
-
|
132
|
-
Singleton = (function(_super) {
|
133
|
-
|
134
|
-
__extends(Singleton, _super);
|
135
|
-
|
136
|
-
function Singleton(options) {
|
137
|
-
var key, value;
|
138
|
-
if (options == null) options = {};
|
139
|
-
for (key in options) {
|
140
|
-
value = options[key];
|
141
|
-
this[key] = value;
|
142
|
-
}
|
143
|
-
}
|
144
|
-
|
145
|
-
Singleton.prototype.find = function() {
|
146
|
-
return this.record.id && this.model.findByAttribute(this.fkey, this.record.id);
|
147
|
-
};
|
148
|
-
|
149
|
-
Singleton.prototype.update = function(value) {
|
150
|
-
if (!(value instanceof this.model)) value = this.model.fromJSON(value);
|
151
|
-
value[this.fkey] = this.record.id;
|
152
|
-
return value.save();
|
153
|
-
};
|
154
|
-
|
155
|
-
return Singleton;
|
156
|
-
|
157
|
-
})(Spine.Module);
|
158
|
-
|
159
|
-
singularize = function(str) {
|
160
|
-
return str.replace(/s$/, '');
|
161
|
-
};
|
162
|
-
|
163
|
-
underscore = function(str) {
|
164
|
-
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();
|
165
|
-
};
|
166
|
-
|
167
|
-
Spine.Model.extend({
|
168
|
-
hasMany: function(name, model, fkey) {
|
169
|
-
var association;
|
170
|
-
if (fkey == null) fkey = "" + (underscore(this.className)) + "_id";
|
171
|
-
association = function(record) {
|
172
|
-
if (typeof model === 'string') model = require(model);
|
173
|
-
return new Collection({
|
174
|
-
name: name,
|
175
|
-
model: model,
|
176
|
-
record: record,
|
177
|
-
fkey: fkey
|
178
|
-
});
|
179
|
-
};
|
180
|
-
return this.prototype[name] = function(value) {
|
181
|
-
if (value != null) association(this).refresh(value);
|
182
|
-
return association(this);
|
183
|
-
};
|
184
|
-
},
|
185
|
-
belongsTo: function(name, model, fkey) {
|
186
|
-
var association;
|
187
|
-
if (fkey == null) fkey = "" + (singularize(name)) + "_id";
|
188
|
-
association = function(record) {
|
189
|
-
if (typeof model === 'string') model = require(model);
|
190
|
-
return new Instance({
|
191
|
-
name: name,
|
192
|
-
model: model,
|
193
|
-
record: record,
|
194
|
-
fkey: fkey
|
195
|
-
});
|
196
|
-
};
|
197
|
-
this.prototype[name] = function(value) {
|
198
|
-
if (value != null) association(this).update(value);
|
199
|
-
return association(this).exists();
|
200
|
-
};
|
201
|
-
return this.attributes.push(fkey);
|
202
|
-
},
|
203
|
-
hasOne: function(name, model, fkey) {
|
204
|
-
var association;
|
205
|
-
if (fkey == null) fkey = "" + (underscore(this.className)) + "_id";
|
206
|
-
association = function(record) {
|
207
|
-
if (typeof model === 'string') model = require(model);
|
208
|
-
return new Singleton({
|
209
|
-
name: name,
|
210
|
-
model: model,
|
211
|
-
record: record,
|
212
|
-
fkey: fkey
|
213
|
-
});
|
214
|
-
};
|
215
|
-
return this.prototype[name] = function(value) {
|
216
|
-
if (value != null) association(this).update(value);
|
217
|
-
return association(this).find();
|
218
|
-
};
|
219
|
-
}
|
220
|
-
});
|
221
|
-
|
222
|
-
}).call(this);
|
@@ -1,197 +0,0 @@
|
|
1
|
-
(function() {
|
2
|
-
var $, escapeRegExp, hashStrip, namedParam, splatParam,
|
3
|
-
__hasProp = Object.prototype.hasOwnProperty,
|
4
|
-
__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; },
|
5
|
-
__slice = Array.prototype.slice;
|
6
|
-
|
7
|
-
if (typeof Spine === "undefined" || Spine === null) Spine = require('spine');
|
8
|
-
|
9
|
-
$ = Spine.$;
|
10
|
-
|
11
|
-
hashStrip = /^#*/;
|
12
|
-
|
13
|
-
namedParam = /:([\w\d]+)/g;
|
14
|
-
|
15
|
-
splatParam = /\*([\w\d]+)/g;
|
16
|
-
|
17
|
-
escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;
|
18
|
-
|
19
|
-
Spine.Route = (function(_super) {
|
20
|
-
var _ref;
|
21
|
-
|
22
|
-
__extends(Route, _super);
|
23
|
-
|
24
|
-
Route.extend(Spine.Events);
|
25
|
-
|
26
|
-
Route.historySupport = ((_ref = window.history) != null ? _ref.pushState : void 0) != null;
|
27
|
-
|
28
|
-
Route.routes = [];
|
29
|
-
|
30
|
-
Route.options = {
|
31
|
-
trigger: true,
|
32
|
-
history: false,
|
33
|
-
shim: false
|
34
|
-
};
|
35
|
-
|
36
|
-
Route.add = function(path, callback) {
|
37
|
-
var key, value, _results;
|
38
|
-
if (typeof path === 'object' && !(path instanceof RegExp)) {
|
39
|
-
_results = [];
|
40
|
-
for (key in path) {
|
41
|
-
value = path[key];
|
42
|
-
_results.push(this.add(key, value));
|
43
|
-
}
|
44
|
-
return _results;
|
45
|
-
} else {
|
46
|
-
return this.routes.push(new this(path, callback));
|
47
|
-
}
|
48
|
-
};
|
49
|
-
|
50
|
-
Route.setup = function(options) {
|
51
|
-
if (options == null) options = {};
|
52
|
-
this.options = $.extend({}, this.options, options);
|
53
|
-
if (this.options.history) {
|
54
|
-
this.history = this.historySupport && this.options.history;
|
55
|
-
}
|
56
|
-
if (this.options.shim) return;
|
57
|
-
if (this.history) {
|
58
|
-
$(window).bind('popstate', this.change);
|
59
|
-
} else {
|
60
|
-
$(window).bind('hashchange', this.change);
|
61
|
-
}
|
62
|
-
return this.change();
|
63
|
-
};
|
64
|
-
|
65
|
-
Route.unbind = function() {
|
66
|
-
if (this.history) {
|
67
|
-
return $(window).unbind('popstate', this.change);
|
68
|
-
} else {
|
69
|
-
return $(window).unbind('hashchange', this.change);
|
70
|
-
}
|
71
|
-
};
|
72
|
-
|
73
|
-
Route.navigate = function() {
|
74
|
-
var args, lastArg, options, path;
|
75
|
-
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
76
|
-
options = {};
|
77
|
-
lastArg = args[args.length - 1];
|
78
|
-
if (typeof lastArg === 'object') {
|
79
|
-
options = args.pop();
|
80
|
-
} else if (typeof lastArg === 'boolean') {
|
81
|
-
options.trigger = args.pop();
|
82
|
-
}
|
83
|
-
options = $.extend({}, this.options, options);
|
84
|
-
path = args.join('/');
|
85
|
-
if (this.path === path) return;
|
86
|
-
this.path = path;
|
87
|
-
this.trigger('navigate', this.path);
|
88
|
-
if (options.trigger) this.matchRoute(this.path, options);
|
89
|
-
if (options.shim) return;
|
90
|
-
if (this.history) {
|
91
|
-
return history.pushState({}, document.title, this.path);
|
92
|
-
} else {
|
93
|
-
return window.location.hash = this.path;
|
94
|
-
}
|
95
|
-
};
|
96
|
-
|
97
|
-
Route.getPath = function() {
|
98
|
-
var path;
|
99
|
-
path = window.location.pathname;
|
100
|
-
if (path.substr(0, 1) !== '/') path = '/' + path;
|
101
|
-
return path;
|
102
|
-
};
|
103
|
-
|
104
|
-
Route.getHash = function() {
|
105
|
-
return window.location.hash;
|
106
|
-
};
|
107
|
-
|
108
|
-
Route.getFragment = function() {
|
109
|
-
return this.getHash().replace(hashStrip, '');
|
110
|
-
};
|
111
|
-
|
112
|
-
Route.getHost = function() {
|
113
|
-
return (document.location + '').replace(this.getPath() + this.getHash(), '');
|
114
|
-
};
|
115
|
-
|
116
|
-
Route.change = function() {
|
117
|
-
var path;
|
118
|
-
path = this.getFragment() !== '' ? this.getFragment() : this.getPath();
|
119
|
-
if (path === this.path) return;
|
120
|
-
this.path = path;
|
121
|
-
return this.matchRoute(this.path);
|
122
|
-
};
|
123
|
-
|
124
|
-
Route.matchRoute = function(path, options) {
|
125
|
-
var route, _i, _len, _ref2;
|
126
|
-
_ref2 = this.routes;
|
127
|
-
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
128
|
-
route = _ref2[_i];
|
129
|
-
if (route.match(path, options)) {
|
130
|
-
this.trigger('change', route, path);
|
131
|
-
return route;
|
132
|
-
}
|
133
|
-
}
|
134
|
-
};
|
135
|
-
|
136
|
-
function Route(path, callback) {
|
137
|
-
var match;
|
138
|
-
this.path = path;
|
139
|
-
this.callback = callback;
|
140
|
-
this.names = [];
|
141
|
-
if (typeof path === 'string') {
|
142
|
-
namedParam.lastIndex = 0;
|
143
|
-
while ((match = namedParam.exec(path)) !== null) {
|
144
|
-
this.names.push(match[1]);
|
145
|
-
}
|
146
|
-
path = path.replace(escapeRegExp, '\\$&').replace(namedParam, '([^\/]*)').replace(splatParam, '(.*?)');
|
147
|
-
this.route = new RegExp('^' + path + '$');
|
148
|
-
} else {
|
149
|
-
this.route = path;
|
150
|
-
}
|
151
|
-
}
|
152
|
-
|
153
|
-
Route.prototype.match = function(path, options) {
|
154
|
-
var i, match, param, params, _len;
|
155
|
-
if (options == null) options = {};
|
156
|
-
match = this.route.exec(path);
|
157
|
-
if (!match) return false;
|
158
|
-
options.match = match;
|
159
|
-
params = match.slice(1);
|
160
|
-
if (this.names.length) {
|
161
|
-
for (i = 0, _len = params.length; i < _len; i++) {
|
162
|
-
param = params[i];
|
163
|
-
options[this.names[i]] = param;
|
164
|
-
}
|
165
|
-
}
|
166
|
-
return this.callback.call(null, options) !== false;
|
167
|
-
};
|
168
|
-
|
169
|
-
return Route;
|
170
|
-
|
171
|
-
})(Spine.Module);
|
172
|
-
|
173
|
-
Spine.Route.change = Spine.Route.proxy(Spine.Route.change);
|
174
|
-
|
175
|
-
Spine.Controller.include({
|
176
|
-
route: function(path, callback) {
|
177
|
-
return Spine.Route.add(path, this.proxy(callback));
|
178
|
-
},
|
179
|
-
routes: function(routes) {
|
180
|
-
var key, value, _results;
|
181
|
-
_results = [];
|
182
|
-
for (key in routes) {
|
183
|
-
value = routes[key];
|
184
|
-
_results.push(this.route(key, value));
|
185
|
-
}
|
186
|
-
return _results;
|
187
|
-
},
|
188
|
-
navigate: function() {
|
189
|
-
return Spine.Route.navigate.apply(Spine.Route, arguments);
|
190
|
-
}
|
191
|
-
});
|
192
|
-
|
193
|
-
if (typeof module !== "undefined" && module !== null) {
|
194
|
-
module.exports = Spine.Route;
|
195
|
-
}
|
196
|
-
|
197
|
-
}).call(this);
|
@@ -1,66 +0,0 @@
|
|
1
|
-
(function() {
|
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
|
-
|
9
|
-
$ = Spine.$;
|
10
|
-
|
11
|
-
Spine.Tabs = (function(_super) {
|
12
|
-
|
13
|
-
__extends(Tabs, _super);
|
14
|
-
|
15
|
-
Tabs.prototype.events = {
|
16
|
-
'click [data-name]': 'click'
|
17
|
-
};
|
18
|
-
|
19
|
-
function Tabs() {
|
20
|
-
this.change = __bind(this.change, this); Tabs.__super__.constructor.apply(this, arguments);
|
21
|
-
this.bind('change', this.change);
|
22
|
-
}
|
23
|
-
|
24
|
-
Tabs.prototype.change = function(name) {
|
25
|
-
if (!name) return;
|
26
|
-
this.current = name;
|
27
|
-
this.children().removeClass('active');
|
28
|
-
return this.children("[data-name=" + this.current + "]").addClass('active');
|
29
|
-
};
|
30
|
-
|
31
|
-
Tabs.prototype.render = function() {
|
32
|
-
this.change(this.current);
|
33
|
-
if (!(this.children('.active').length || this.current)) {
|
34
|
-
return this.children(':first').click();
|
35
|
-
}
|
36
|
-
};
|
37
|
-
|
38
|
-
Tabs.prototype.children = function(sel) {
|
39
|
-
return this.el.children(sel);
|
40
|
-
};
|
41
|
-
|
42
|
-
Tabs.prototype.click = function(e) {
|
43
|
-
var name;
|
44
|
-
name = $(e.currentTarget).attr('data-name');
|
45
|
-
return this.trigger('change', name);
|
46
|
-
};
|
47
|
-
|
48
|
-
Tabs.prototype.connect = function(tabName, controller) {
|
49
|
-
var _this = this;
|
50
|
-
this.bind('change', function(name) {
|
51
|
-
if (name === tabName) return controller.active();
|
52
|
-
});
|
53
|
-
return controller.bind('active', function() {
|
54
|
-
return _this.change(tabName);
|
55
|
-
});
|
56
|
-
};
|
57
|
-
|
58
|
-
return Tabs;
|
59
|
-
|
60
|
-
})(Spine.Controller);
|
61
|
-
|
62
|
-
if (typeof module !== "undefined" && module !== null) {
|
63
|
-
module.exports = Spine.Tabs;
|
64
|
-
}
|
65
|
-
|
66
|
-
}).call(this);
|