backbone-stickit-rails 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce28e2d9b7f84a8ab32ac88627c31c81b4ca3c6a
4
+ data.tar.gz: 33fcc80f659cedff12c6838e7221b5383cba7c7a
5
+ SHA512:
6
+ metadata.gz: 27acf5e40c9a5474f4b07056954259898a85b295b686463301adf126f4cac0c0a1c8a61b07feabdacf50866bd318984a2351b6407d2dbf07b781c813b7f44789
7
+ data.tar.gz: 36f1502fdc633b8ba3f9f8653f88de01708aa2bb450a28ebdb4682a07c797a9b5206a12e89a701163846822546624644c03ef21823bc6b4765aec5cbfa3908c8
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Sean Griffin
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # Backbone.Stickit Rails
2
+
3
+ A simple wrapper for backbone.stickit for use with the Rails asset pipeline
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'backbone-stickit-rails'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install backbone-stickit-rails
18
+
19
+ ## Usage
20
+
21
+ Add the following line to application.js
22
+
23
+ ```javascript
24
+ //= require backbone.stickit
25
+ ```
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create new Pull Request
@@ -0,0 +1,10 @@
1
+ require "backbone/stickit/rails/version"
2
+
3
+ module Backbone
4
+ module Stickit
5
+ module Rails
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ module Backbone
2
+ module Stickit
3
+ module Rails
4
+ VERSION = "0.6.3"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,468 @@
1
+ //
2
+ // backbone.stickit - v0.6.3
3
+ // The MIT License
4
+ // Copyright (c) 2012 The New York Times, CMS Group, Matthew DeLambo <delambo@gmail.com>
5
+ //
6
+ (function($) {
7
+
8
+ // Backbone.Stickit Namespace
9
+ // --------------------------
10
+
11
+ Backbone.Stickit = {
12
+
13
+ _handlers: [],
14
+
15
+ addHandler: function(handlers) {
16
+ // Fill-in default values.
17
+ handlers = _.map(_.flatten([handlers]), function(handler) {
18
+ return _.extend({
19
+ updateModel: true,
20
+ updateView: true,
21
+ updateMethod: 'text'
22
+ }, handler);
23
+ });
24
+ this._handlers = this._handlers.concat(handlers);
25
+ }
26
+ };
27
+
28
+ // Backbone.View Mixins
29
+ // --------------------
30
+
31
+ _.extend(Backbone.View.prototype, {
32
+
33
+ // Collection of model event bindings.
34
+ // [{model,event,fn}, ...]
35
+ _modelBindings: null,
36
+
37
+ // Unbind the model and event bindings from `this._modelBindings` and
38
+ // `this.$el`. If the optional `model` parameter is defined, then only
39
+ // delete bindings for the given `model` and its corresponding view events.
40
+ unstickit: function(model) {
41
+ _.each(this._modelBindings, _.bind(function(binding, i) {
42
+ if (model && binding.model !== model) return false;
43
+ binding.model.off(binding.event, binding.fn);
44
+ delete this._modelBindings[i];
45
+ }, this));
46
+ this._modelBindings = _.compact(this._modelBindings);
47
+
48
+ this.$el.off('.stickit' + (model ? '.' + model.cid : ''));
49
+ },
50
+
51
+ // Using `this.bindings` configuration or the `optionalBindingsConfig`, binds `this.model`
52
+ // or the `optionalModel` to elements in the view.
53
+ stickit: function(optionalModel, optionalBindingsConfig) {
54
+ var self = this,
55
+ model = optionalModel || this.model,
56
+ namespace = '.stickit.' + model.cid,
57
+ bindings = optionalBindingsConfig || this.bindings || {};
58
+
59
+ this._modelBindings || (this._modelBindings = []);
60
+ this.unstickit(model);
61
+
62
+ // Iterate through the selectors in the bindings configuration and configure
63
+ // the various options for each field.
64
+ _.each(_.keys(bindings), function(selector) {
65
+ var $el, options, modelAttr, config,
66
+ binding = bindings[selector] || {},
67
+ bindKey = _.uniqueId();
68
+
69
+ // Support ':el' selector - special case selector for the view managed delegate.
70
+ if (selector != ':el') $el = self.$(selector);
71
+ else {
72
+ $el = self.$el;
73
+ selector = '';
74
+ }
75
+
76
+ // Fail fast if the selector didn't match an element.
77
+ if (!$el.length) return;
78
+
79
+ // Allow shorthand setting of model attributes - `'selector':'observe'`.
80
+ if (_.isString(binding)) binding = {observe:binding};
81
+
82
+ config = getConfiguration($el, binding);
83
+
84
+ modelAttr = config.observe;
85
+
86
+ // Create the model set options with a unique `bindKey` so that we
87
+ // can avoid double-binding in the `change:attribute` event handler.
88
+ options = _.extend({bindKey:bindKey}, config.setOptions || {});
89
+
90
+ initializeAttributes(self, $el, config, model, modelAttr);
91
+
92
+ initializeVisible(self, $el, config, model, modelAttr);
93
+
94
+ if (modelAttr) {
95
+ // Setup one-way, form element to model, bindings.
96
+ _.each(config.events || [], function(type) {
97
+ var event = type + namespace;
98
+ var method = function(event) {
99
+ var val = config.getVal.call(self, $el, event, config);
100
+ // Don't update the model if false is returned from the `updateModel` configuration.
101
+ if (evaluateBoolean(self, config.updateModel, val, config))
102
+ setAttr(model, modelAttr, val, options, self, config);
103
+ };
104
+ if (selector === '') self.$el.on(event, method);
105
+ else self.$el.on(event, selector, method);
106
+ });
107
+
108
+ // Setup a `change:modelAttr` observer to keep the view element in sync.
109
+ // `modelAttr` may be an array of attributes or a single string value.
110
+ _.each(_.flatten([modelAttr]), function(attr) {
111
+ observeModelEvent(model, self, 'change:'+attr, function(model, val, options) {
112
+ if (options == null || options.bindKey != bindKey)
113
+ updateViewBindEl(self, $el, config, getAttr(model, modelAttr, config, self), model);
114
+ });
115
+ });
116
+
117
+ updateViewBindEl(self, $el, config, getAttr(model, modelAttr, config, self), model, true);
118
+ }
119
+
120
+ // After each binding is setup, call the `initialize` callback.
121
+ applyViewFn(self, config.initialize, $el, model, config);
122
+ });
123
+
124
+ // Wrap `view.remove` to unbind stickit model and dom events.
125
+ this.remove = _.wrap(this.remove, function(oldRemove) {
126
+ self.unstickit();
127
+ if (oldRemove) oldRemove.call(self);
128
+ });
129
+ }
130
+ });
131
+
132
+ // Helpers
133
+ // -------
134
+
135
+ // Evaluates the given `path` (in object/dot-notation) relative to the given
136
+ // `obj`. If the path is null/undefined, then the given `obj` is returned.
137
+ var evaluatePath = function(obj, path) {
138
+ var parts = (path || '').split('.');
139
+ var result = _.reduce(parts, function(memo, i) { return memo[i]; }, obj);
140
+ return result == null ? obj : result;
141
+ };
142
+
143
+ // If the given `fn` is a string, then view[fn] is called, otherwise it is
144
+ // a function that should be executed.
145
+ var applyViewFn = function(view, fn) {
146
+ if (fn) return (_.isString(fn) ? view[fn] : fn).apply(view, _.toArray(arguments).slice(2));
147
+ };
148
+
149
+ var getSelectedOption = function($select) { return $select.find('option').not(function(){ return !this.selected; }); };
150
+
151
+ // Given a function, string (view function reference), or a boolean
152
+ // value, returns the truthy result. Any other types evaluate as false.
153
+ var evaluateBoolean = function(view, reference) {
154
+ if (_.isBoolean(reference)) return reference;
155
+ else if (_.isFunction(reference) || _.isString(reference))
156
+ return applyViewFn.apply(this, _.toArray(arguments));
157
+ return false;
158
+ };
159
+
160
+ // Setup a model event binding with the given function, and track the event
161
+ // in the view's _modelBindings.
162
+ var observeModelEvent = function(model, view, event, fn) {
163
+ model.on(event, fn, view);
164
+ view._modelBindings.push({model:model, event:event, fn:fn});
165
+ };
166
+
167
+ // Prepares the given `val`ue and sets it into the `model`.
168
+ var setAttr = function(model, attr, val, options, context, config) {
169
+ if (config.onSet) val = applyViewFn(context, config.onSet, val, config);
170
+ model.set(attr, val, options);
171
+ };
172
+
173
+ // Returns the given `attr`'s value from the `model`, escaping and
174
+ // formatting if necessary. If `attr` is an array, then an array of
175
+ // respective values will be returned.
176
+ var getAttr = function(model, attr, config, context) {
177
+ var val, retrieveVal = function(field) {
178
+ var retrieved = config.escape ? model.escape(field) : model.get(field);
179
+ return _.isUndefined(retrieved) ? '' : retrieved;
180
+ };
181
+ val = _.isArray(attr) ? _.map(attr, retrieveVal) : retrieveVal(attr);
182
+ return config.onGet ? applyViewFn(context, config.onGet, val, config) : val;
183
+ };
184
+
185
+ // Find handlers in `Backbone.Stickit._handlers` with selectors that match
186
+ // `$el` and generate a configuration by mixing them in the order that they
187
+ // were found with the with the givne `binding`.
188
+ var getConfiguration = function($el, binding) {
189
+ var handlers = [{
190
+ updateModel: false,
191
+ updateView: true,
192
+ updateMethod: 'text',
193
+ update: function($el, val, m, opts) { $el[opts.updateMethod](val); },
194
+ getVal: function($el, e, opts) { return $el[opts.updateMethod](); }
195
+ }];
196
+ _.each(Backbone.Stickit._handlers, function(handler) {
197
+ if ($el.is(handler.selector)) handlers.push(handler);
198
+ });
199
+ handlers.push(binding);
200
+ var config = _.extend.apply(_, handlers);
201
+ delete config.selector;
202
+ return config;
203
+ };
204
+
205
+ // Setup the attributes configuration - a list that maps an attribute or
206
+ // property `name`, to an `observe`d model attribute, using an optional
207
+ // `onGet` formatter.
208
+ //
209
+ // attributes: [{
210
+ // name: 'attributeOrPropertyName',
211
+ // observe: 'modelAttrName'
212
+ // onGet: function(modelAttrVal, modelAttrName) { ... }
213
+ // }, ...]
214
+ //
215
+ var initializeAttributes = function(view, $el, config, model, modelAttr) {
216
+ var props = ['autofocus', 'autoplay', 'async', 'checked', 'controls', 'defer', 'disabled', 'hidden', 'loop', 'multiple', 'open', 'readonly', 'required', 'scoped', 'selected'];
217
+
218
+ _.each(config.attributes || [], function(attrConfig) {
219
+ var lastClass = '',
220
+ observed = attrConfig.observe || (attrConfig.observe = modelAttr),
221
+ updateAttr = function() {
222
+ var updateType = _.indexOf(props, attrConfig.name, true) > -1 ? 'prop' : 'attr',
223
+ val = getAttr(model, observed, attrConfig, view);
224
+ // If it is a class then we need to remove the last value and add the new.
225
+ if (attrConfig.name == 'class') {
226
+ $el.removeClass(lastClass).addClass(val);
227
+ lastClass = val;
228
+ }
229
+ else $el[updateType](attrConfig.name, val);
230
+ };
231
+ _.each(_.flatten([observed]), function(attr) {
232
+ observeModelEvent(model, view, 'change:' + attr, updateAttr);
233
+ });
234
+ updateAttr();
235
+ });
236
+ };
237
+
238
+ // If `visible` is configured, then the view element will be shown/hidden
239
+ // based on the truthiness of the modelattr's value or the result of the
240
+ // given callback. If a `visibleFn` is also supplied, then that callback
241
+ // will be executed to manually handle showing/hiding the view element.
242
+ //
243
+ // observe: 'isRight',
244
+ // visible: true, // or function(val, options) {}
245
+ // visibleFn: function($el, isVisible, options) {} // optional handler
246
+ //
247
+ var initializeVisible = function(view, $el, config, model, modelAttr) {
248
+ if (config.visible == null) return;
249
+ var visibleCb = function() {
250
+ var visible = config.visible,
251
+ visibleFn = config.visibleFn,
252
+ val = getAttr(model, modelAttr, config, view),
253
+ isVisible = !!val;
254
+ // If `visible` is a function then it should return a boolean result to show/hide.
255
+ if (_.isFunction(visible) || _.isString(visible)) isVisible = applyViewFn(view, visible, val, config);
256
+ // Either use the custom `visibleFn`, if provided, or execute the standard show/hide.
257
+ if (visibleFn) applyViewFn(view, visibleFn, $el, isVisible, config);
258
+ else {
259
+ if (isVisible) $el.show();
260
+ else $el.hide();
261
+ }
262
+ };
263
+ _.each(_.flatten([modelAttr]), function(attr) {
264
+ observeModelEvent(model, view, 'change:' + attr, visibleCb);
265
+ });
266
+ visibleCb();
267
+ };
268
+
269
+ // Update the value of `$el` using the given configuration and trigger the
270
+ // `afterUpdate` callback. This action may be blocked by `config.updateView`.
271
+ //
272
+ // update: function($el, val, model, options) {}, // handler for updating
273
+ // updateView: true, // defaults to true
274
+ // afterUpdate: function($el, val, options) {} // optional callback
275
+ //
276
+ var updateViewBindEl = function(view, $el, config, val, model, isInitializing) {
277
+ if (!evaluateBoolean(view, config.updateView, val, config)) return;
278
+ config.update.call(view, $el, val, model, config);
279
+ if (!isInitializing) applyViewFn(view, config.afterUpdate, $el, val, config);
280
+ };
281
+
282
+ // Default Handlers
283
+ // ----------------
284
+
285
+ Backbone.Stickit.addHandler([{
286
+ selector: '[contenteditable="true"]',
287
+ updateMethod: 'html',
288
+ events: ['keyup', 'change', 'paste', 'cut']
289
+ }, {
290
+ selector: 'input',
291
+ events: ['keyup', 'change', 'paste', 'cut'],
292
+ update: function($el, val) { $el.val(val); },
293
+ getVal: function($el) {
294
+ var val = $el.val();
295
+ if ($el.is('[type="number"]')) return val == null ? val : Number(val);
296
+ else return val;
297
+ }
298
+ }, {
299
+ selector: 'textarea',
300
+ events: ['keyup', 'change', 'paste', 'cut'],
301
+ update: function($el, val) { $el.val(val); },
302
+ getVal: function($el) { return $el.val(); }
303
+ }, {
304
+ selector: 'input[type="radio"]',
305
+ events: ['change'],
306
+ update: function($el, val) {
307
+ $el.filter('[value="'+val+'"]').prop('checked', true);
308
+ },
309
+ getVal: function($el) {
310
+ return $el.filter(':checked').val();
311
+ }
312
+ }, {
313
+ selector: 'input[type="checkbox"]',
314
+ events: ['change'],
315
+ update: function($el, val, model, options) {
316
+ if ($el.length > 1) {
317
+ // There are multiple checkboxes so we need to go through them and check
318
+ // any that have value attributes that match what's in the array of `val`s.
319
+ val || (val = []);
320
+ _.each($el, function(el) {
321
+ if (_.indexOf(val, $(el).val()) > -1) $(el).prop('checked', true);
322
+ else $(el).prop('checked', false);
323
+ });
324
+ } else {
325
+ if (_.isBoolean(val)) $el.prop('checked', val);
326
+ else $el.prop('checked', val == $el.val());
327
+ }
328
+ },
329
+ getVal: function($el) {
330
+ var val;
331
+ if ($el.length > 1) {
332
+ val = _.reduce($el, function(memo, el) {
333
+ if ($(el).prop('checked')) memo.push($(el).val());
334
+ return memo;
335
+ }, []);
336
+ } else {
337
+ val = $el.prop('checked');
338
+ // If the checkbox has a value attribute defined, then
339
+ // use that value. Most browsers use "on" as a default.
340
+ var boxval = $el.val();
341
+ if (boxval != 'on' && boxval != null) {
342
+ if (val) val = $el.val();
343
+ else val = null;
344
+ }
345
+ }
346
+ return val;
347
+ }
348
+ }, {
349
+ selector: 'select',
350
+ events: ['change'],
351
+ update: function($el, val, model, options) {
352
+ var optList,
353
+ selectConfig = options.selectOptions,
354
+ list = selectConfig && selectConfig.collection || undefined,
355
+ isMultiple = $el.prop('multiple');
356
+
357
+ // If there are no `selectOptions` then we assume that the `<select>`
358
+ // is pre-rendered and that we need to generate the collection.
359
+ if (!selectConfig) {
360
+ selectConfig = {};
361
+ var getList = function($el) {
362
+ return $el.find('option').map(function() {
363
+ return {value:this.value, label:this.text};
364
+ }).get();
365
+ };
366
+ if ($el.find('optgroup').length) {
367
+ list = {opt_labels:[]};
368
+ _.each($el.find('optgroup'), function(el) {
369
+ var label = $(el).attr('label');
370
+ list.opt_labels.push(label);
371
+ list[label] = getList($(el));
372
+ });
373
+ } else {
374
+ list = getList($el);
375
+ }
376
+ }
377
+
378
+ // Fill in default label and path values.
379
+ selectConfig.valuePath = selectConfig.valuePath || 'value';
380
+ selectConfig.labelPath = selectConfig.labelPath || 'label';
381
+
382
+ var addSelectOptions = function(optList, $el, fieldVal) {
383
+ // Add a flag for default option at the beginning of the list.
384
+ if (selectConfig.defaultOption) {
385
+ optList = _.clone(optList);
386
+ optList.unshift('__default__');
387
+ }
388
+ _.each(optList, function(obj) {
389
+ var option = $('<option/>'), optionVal = obj;
390
+
391
+ var fillOption = function(text, val) {
392
+ option.text(text);
393
+ optionVal = val;
394
+ // Save the option value as data so that we can reference it later.
395
+ option.data('stickit_bind_val', optionVal);
396
+ if (!_.isArray(optionVal) && !_.isObject(optionVal)) option.val(optionVal);
397
+ };
398
+
399
+ if (obj === '__default__')
400
+ fillOption(selectConfig.defaultOption.label, selectConfig.defaultOption.value);
401
+ else
402
+ fillOption(evaluatePath(obj, selectConfig.labelPath), evaluatePath(obj, selectConfig.valuePath));
403
+
404
+ // Determine if this option is selected.
405
+ if (!isMultiple && optionVal != null && fieldVal != null && optionVal == fieldVal || (_.isObject(fieldVal) && _.isEqual(optionVal, fieldVal)))
406
+ option.prop('selected', true);
407
+ else if (isMultiple && _.isArray(fieldVal)) {
408
+ _.each(fieldVal, function(val) {
409
+ if (_.isObject(val)) val = evaluatePath(val, selectConfig.valuePath);
410
+ if (val == optionVal || (_.isObject(val) && _.isEqual(optionVal, val)))
411
+ option.prop('selected', true);
412
+ });
413
+ }
414
+
415
+ $el.append(option);
416
+ });
417
+ };
418
+
419
+ $el.html('');
420
+
421
+ // The `list` configuration is a function that returns the options list or a string
422
+ // which represents the path to the list relative to `window` or the view/`this`.
423
+ var evaluate = function(view, list) {
424
+ var context = window;
425
+ if (list.indexOf('this.') === 0) context = view;
426
+ list = list.replace(/^[a-z]*\.(.+)$/, '$1');
427
+ return evaluatePath(context, list);
428
+ };
429
+ if (_.isString(list)) optList = evaluate(this, list);
430
+ else if (_.isFunction(list)) optList = applyViewFn(this, list, $el, options);
431
+ else optList = list;
432
+
433
+ // Support Backbone.Collection and deserialize.
434
+ if (optList instanceof Backbone.Collection) optList = optList.toJSON();
435
+
436
+ if (_.isArray(optList)) {
437
+ addSelectOptions(optList, $el, val);
438
+ } else {
439
+ // If the optList is an object, then it should be used to define an optgroup. An
440
+ // optgroup object configuration looks like the following:
441
+ //
442
+ // {
443
+ // 'opt_labels': ['Looney Tunes', 'Three Stooges'],
444
+ // 'Looney Tunes': [{id: 1, name: 'Bugs Bunny'}, {id: 2, name: 'Donald Duck'}],
445
+ // 'Three Stooges': [{id: 3, name : 'moe'}, {id: 4, name : 'larry'}, {id: 5, name : 'curly'}]
446
+ // }
447
+ //
448
+ _.each(optList.opt_labels, function(label) {
449
+ var $group = $('<optgroup/>').attr('label', label);
450
+ addSelectOptions(optList[label], $group, val);
451
+ $el.append($group);
452
+ });
453
+ }
454
+ },
455
+ getVal: function($el) {
456
+ var val;
457
+ if ($el.prop('multiple')) {
458
+ val = $(getSelectedOption($el).map(function() {
459
+ return $(this).data('stickit_bind_val');
460
+ })).get();
461
+ } else {
462
+ val = getSelectedOption($el).data('stickit_bind_val');
463
+ }
464
+ return val;
465
+ }
466
+ }]);
467
+
468
+ })(window.jQuery || window.Zepto);
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: backbone-stickit-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.3
5
+ platform: ruby
6
+ authors:
7
+ - Sean Griffin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: railties
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '3.1'
48
+ - - <=
49
+ - !ruby/object:Gem::Version
50
+ version: '4.0'
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '3.1'
58
+ - - <=
59
+ - !ruby/object:Gem::Version
60
+ version: '4.0'
61
+ description: A wrapper around backbone.stickit for use with the rails asset pipeline
62
+ email:
63
+ - sean@thoughtbot.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - lib/backbone/stickit/rails/version.rb
69
+ - lib/backbone/stickit/rails.rb
70
+ - vendor/assets/javascripts/backbone.stickit.js
71
+ - LICENSE.txt
72
+ - README.md
73
+ homepage: ''
74
+ licenses:
75
+ - MIT
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.0.2
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: A wrapper around backbone.stickit for use with the rails asset pipeline
97
+ test_files: []