js_stack 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 393d1a96109e84e9d653ee620aec8514276f293c
4
- data.tar.gz: e09d9e2565dd19abccd3e8481e82e20d6f20071b
3
+ metadata.gz: 5dba30cdf10a542fc2075be0e211dc211082f1f4
4
+ data.tar.gz: 672fe6206d90b5f212b986b0b768016046a89960
5
5
  SHA512:
6
- metadata.gz: 6d9142008b1b9a8f73ce7bb947b3cd34f9fef57aeaf58a87b6446a69683507765f92670dea7dd625b625f3aebe3e42c236b0bc096a6531ac2abe643a2ac1185d
7
- data.tar.gz: 0cde1e7d3fff8c8b5c9bea7f5d125d97d1400e2b002e4c6fc1de8002af3500380c2ee2f9e4dec6dd4d2f4b1550e7c62d36aa26e927139f7b59c6bcb4b08cae14
6
+ metadata.gz: b9fd43d12fa92b7d590a572d9d9d2ec13bd4d27f6f3d1577e1fc299ed3a9c6e4432791e32d5d50bfca63cae6749c84d25825fcdd4c5a62ece74973afd927682e
7
+ data.tar.gz: fd9ca35a353a30a01aa33fbfcab7323ee7e4255d98169613b3769a0196b9592678daca64aa0ce74203972ab48303fe47e5376cb329f2b0f1215f4727d416e51d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## libs
4
+ * underscore - [changelog](http://underscorejs.org/#changelog)
5
+ * backbone - [changelog](http://backbonejs.org/#changelog)
6
+ * marionette - [changelog](https://github.com/marionettejs/backbone.marionette/blob/master/changelog.md)
7
+ * backbone.stickit - [changelog](http://nytimes.github.io/backbone.stickit/#change-log)
8
+ * backbone.validation - [changelog](https://github.com/thedersen/backbone.validation#release-notes)
9
+ * backbone-associations - [changelog](https://github.com/dhruvaray/backbone-associations/blob/master/CHANGELOG.md)
10
+ * backbone-pageable - [changelog](https://github.com/backbone-paginator/backbone-pageable#change-log)
11
+ * backbone.deepmodel - [changelog](https://github.com/powmedia/backbone-deep-model#changelog)
12
+ * backbone-virtualcollection - [changelog](https://github.com/p3drosola/Backbone.VirtualCollection#changelog)
13
+
14
+ ## v0.2.0
15
+
16
+ * updated *backbone-stickit* 0.6.3 -> 0.7.0 [@gvl]
17
+ * updated marionette 1.4.0 -> 1.4.1 [@gvl]
18
+ * updated backbone-pageable 1.4.1 -> 1.4.3 [@gvl]
19
+
20
+ ### Breaking Changes
21
+ * see http://nytimes.github.io/backbone.stickit/#change-log for breaking changes in backbone-stickit
22
+
3
23
  ## v0.1.0
4
24
 
5
25
  * updated *backbone* 1.0.0 -> 1.1.0 - http://backbonejs.org/#changelog [@gvl]
data/README.md CHANGED
@@ -42,7 +42,7 @@ http://backbonejs.org/
42
42
  #= require js_stack/backbone
43
43
  ```
44
44
 
45
- ### marionette.js 1.4.0
45
+ ### marionette.js 1.4.1
46
46
 
47
47
  https://github.com/marionettejs/backbone.marionette/tree/master/docs
48
48
 
@@ -50,7 +50,7 @@ https://github.com/marionettejs/backbone.marionette/tree/master/docs
50
50
  #= require js_stack/marionette
51
51
  ```
52
52
 
53
- ### backbone.stickit 0.6.3
53
+ ### backbone.stickit 0.7.0
54
54
 
55
55
  http://nytimes.github.io/backbone.stickit/
56
56
 
@@ -75,7 +75,7 @@ http://dhruvaray.github.io/backbone-associations/
75
75
  #= require js_stack/backbone.associations
76
76
  ```
77
77
 
78
- ### backbone-pageable 1.4.1
78
+ ### backbone-pageable 1.4.3
79
79
 
80
80
  https://github.com/wyuenho/backbone-pageable
81
81
 
@@ -1,3 +1,3 @@
1
1
  module JsStack
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,5 +1,5 @@
1
1
  /*
2
- backbone-pageable 1.4.1
2
+ backbone-pageable 1.4.3
3
3
  http://github.com/wyuenho/backbone-pageable
4
4
 
5
5
  Copyright (c) 2013 Jimmy Yuen Ho Wong
@@ -425,7 +425,11 @@
425
425
  fullIndex;
426
426
  }
427
427
 
428
- ++state.totalRecords;
428
+ if (!options.onRemove) {
429
+ ++state.totalRecords;
430
+ delete options.onRemove;
431
+ }
432
+
429
433
  pageCol.state = pageCol._checkState(state);
430
434
 
431
435
  if (colToAdd) {
@@ -436,9 +440,8 @@
436
440
  pageCol.at(pageSize) :
437
441
  null;
438
442
  if (modelToRemove) {
439
- var popOptions = {onAdd: true};
440
443
  runOnceAtLastHandler(collection, event, function () {
441
- pageCol.remove(modelToRemove, popOptions);
444
+ pageCol.remove(modelToRemove, {onAdd: true});
442
445
  });
443
446
  }
444
447
  }
@@ -463,16 +466,18 @@
463
466
  if (collection == pageCol) {
464
467
  if (nextModel = fullCol.at(pageEnd)) {
465
468
  runOnceAtLastHandler(pageCol, event, function () {
466
- pageCol.push(nextModel);
469
+ pageCol.push(nextModel, {onRemove: true});
467
470
  });
468
471
  }
469
472
  fullCol.remove(model);
470
473
  }
471
474
  else if (removedIndex >= pageStart && removedIndex < pageEnd) {
475
+ if (nextModel = fullCol.at(pageEnd - 1)) {
476
+ runOnceAtLastHandler(pageCol, event, function() {
477
+ pageCol.push(nextModel, {onRemove: true});
478
+ });
479
+ }
472
480
  pageCol.remove(model);
473
- var at = removedIndex + 1
474
- nextModel = fullCol.at(at) || fullCol.last();
475
- if (nextModel) pageCol.add(nextModel, {at: at});
476
481
  }
477
482
  }
478
483
  else delete options.onAdd;
@@ -578,8 +583,6 @@
578
583
  else if (currentPage < firstPage ||
579
584
  (totalPages > 0 &&
580
585
  (firstPage ? currentPage > totalPages : currentPage >= totalPages))) {
581
- var op = firstPage ? ">=" : ">";
582
-
583
586
  throw new RangeError("`currentPage` must be firstPage <= currentPage " +
584
587
  (firstPage ? ">" : ">=") +
585
588
  " totalPages if " + firstPage + "-based. Got " +
@@ -1132,7 +1135,7 @@
1132
1135
  then reset.
1133
1136
 
1134
1137
  The query string is constructed by translating the current pagination
1135
- state to your server API query parameter using #queryParams. The current
1138
+ state to your server API query parameter using #queryParams. The current
1136
1139
  page will reset after fetch.
1137
1140
 
1138
1141
  @param {Object} [options] Accepts all
@@ -1209,13 +1212,16 @@
1209
1212
 
1210
1213
  var models = col.models;
1211
1214
  if (mode == "client") fullCol.reset(models, opts);
1212
- else fullCol.add(models, _extend({at: fullCol.length}, opts));
1215
+ else {
1216
+ fullCol.add(models, _extend({at: fullCol.length}, opts));
1217
+ self.trigger("reset", self, opts);
1218
+ }
1213
1219
 
1214
1220
  if (success) success(col, resp, opts);
1215
1221
  };
1216
1222
 
1217
1223
  // silent the first reset from backbone
1218
- return BBColProto.fetch.call(self, _extend({}, options, {silent: true}));
1224
+ return BBColProto.fetch.call(this, _extend({}, options, {silent: true}));
1219
1225
  }
1220
1226
 
1221
1227
  return BBColProto.fetch.call(this, options);
@@ -1 +1 @@
1
- //= require js_stack/backbone.pageable/backbone.pageable-1.4.1
1
+ //= require js_stack/backbone.pageable/backbone.pageable-1.4.3
@@ -0,0 +1,537 @@
1
+ //
2
+ // backbone.stickit - v0.7.0
3
+ // The MIT License
4
+ // Copyright (c) 2012 The New York Times, CMS Group, Matthew DeLambo <delambo@gmail.com>
5
+ //
6
+ (function (factory) {
7
+
8
+ // Set up Stickit appropriately for the environment. Start with AMD.
9
+ if (typeof define === 'function' && define.amd)
10
+ define(['underscore', 'backbone'], factory);
11
+
12
+ // Next for Node.js or CommonJS.
13
+ else if (typeof exports === 'object')
14
+ factory(require('underscore'), require('backbone'));
15
+
16
+ // Finally, as a browser global.
17
+ else
18
+ factory(_, Backbone);
19
+
20
+ }(function (_, Backbone) {
21
+
22
+ // Backbone.Stickit Namespace
23
+ // --------------------------
24
+
25
+ Backbone.Stickit = {
26
+
27
+ _handlers: [],
28
+
29
+ addHandler: function(handlers) {
30
+ // Fill-in default values.
31
+ handlers = _.map(_.flatten([handlers]), function(handler) {
32
+ return _.extend({
33
+ updateModel: true,
34
+ updateView: true,
35
+ updateMethod: 'text'
36
+ }, handler);
37
+ });
38
+ this._handlers = this._handlers.concat(handlers);
39
+ }
40
+ };
41
+
42
+ // Backbone.View Mixins
43
+ // --------------------
44
+
45
+ _.extend(Backbone.View.prototype, {
46
+
47
+ // Collection of model event bindings.
48
+ // [{model,event,fn}, ...]
49
+ _modelBindings: null,
50
+
51
+ // Unbind the model and event bindings from `this._modelBindings` and
52
+ // `this.$el`. If the optional `model` parameter is defined, then only
53
+ // delete bindings for the given `model` and its corresponding view events.
54
+ unstickit: function(model) {
55
+ var models = [];
56
+ _.each(this._modelBindings, function(binding, i) {
57
+ if (model && binding.model !== model) return false;
58
+ binding.model.off(binding.event, binding.fn);
59
+ models.push(binding.model);
60
+ delete this._modelBindings[i];
61
+ }, this);
62
+
63
+ // Trigger an event for each model that was unbound.
64
+ _.invoke(_.uniq(models), 'trigger', 'stickit:unstuck', this.cid);
65
+ // Cleanup the null values.
66
+ this._modelBindings = _.compact(this._modelBindings);
67
+
68
+ this.$el.off('.stickit' + (model ? '.' + model.cid : ''));
69
+ },
70
+
71
+ // Using `this.bindings` configuration or the `optionalBindingsConfig`, binds `this.model`
72
+ // or the `optionalModel` to elements in the view.
73
+ stickit: function(optionalModel, optionalBindingsConfig) {
74
+ var model = optionalModel || this.model,
75
+ namespace = '.stickit.' + model.cid,
76
+ bindings = optionalBindingsConfig || _.result(this, "bindings") || {};
77
+
78
+ this._modelBindings || (this._modelBindings = []);
79
+ this.unstickit(model);
80
+
81
+ // Iterate through the selectors in the bindings configuration and configure
82
+ // the various options for each field.
83
+ _.each(bindings, function(v, selector) {
84
+ var $el, options, modelAttr, config,
85
+ binding = bindings[selector] || {},
86
+ bindId = _.uniqueId();
87
+
88
+ // Support ':el' selector - special case selector for the view managed delegate.
89
+ $el = selector === ':el' ? this.$el : this.$(selector);
90
+
91
+ // Fail fast if the selector didn't match an element.
92
+ if (!$el.length) return;
93
+
94
+ // Allow shorthand setting of model attributes - `'selector':'observe'`.
95
+ if (_.isString(binding)) binding = {observe:binding};
96
+
97
+ // Handle case where `observe` is in the form of a function.
98
+ if (_.isFunction(binding.observe)) binding.observe = binding.observe.call(this);
99
+
100
+ config = getConfiguration($el, binding);
101
+
102
+ modelAttr = config.observe;
103
+
104
+ // Create the model set options with a unique `bindId` so that we
105
+ // can avoid double-binding in the `change:attribute` event handler.
106
+ config.bindId = bindId;
107
+ // Add a reference to the view for handlers of stickitChange events
108
+ config.view = this;
109
+ options = _.extend({stickitChange:config}, config.setOptions);
110
+
111
+ initializeAttributes(this, $el, config, model, modelAttr);
112
+
113
+ initializeVisible(this, $el, config, model, modelAttr);
114
+
115
+ if (modelAttr) {
116
+ // Setup one-way, form element to model, bindings.
117
+ _.each(config.events, function(type) {
118
+ var event = type + namespace;
119
+ var method = function(event) {
120
+ var val = config.getVal.call(this, $el, event, config, _.rest(arguments));
121
+ // Don't update the model if false is returned from the `updateModel` configuration.
122
+ if (evaluateBoolean(this, config.updateModel, val, event, config))
123
+ setAttr(model, modelAttr, val, options, this, config);
124
+ };
125
+ method = _.bind(method, this);
126
+ if (selector === ':el') this.$el.on(event, method);
127
+ else this.$el.on(event, selector, method);
128
+ }, this);
129
+
130
+ // Setup a `change:modelAttr` observer to keep the view element in sync.
131
+ // `modelAttr` may be an array of attributes or a single string value.
132
+ _.each(_.flatten([modelAttr]), function(attr) {
133
+ observeModelEvent(model, this, 'change:'+attr, function(model, val, options) {
134
+ var changeId = options && options.stickitChange && options.stickitChange.bindId || null;
135
+ if (changeId !== bindId)
136
+ updateViewBindEl(this, $el, config, getAttr(model, modelAttr, config, this), model);
137
+ });
138
+ }, this);
139
+
140
+ updateViewBindEl(this, $el, config, getAttr(model, modelAttr, config, this), model, true);
141
+ }
142
+
143
+ model.once('stickit:unstuck', function(cid) {
144
+ if (cid === this.cid) applyViewFn(this, config.destroy, $el, model, config);
145
+ }, this);
146
+
147
+ // After each binding is setup, call the `initialize` callback.
148
+ applyViewFn(this, config.initialize, $el, model, config);
149
+ }, this);
150
+
151
+ // Wrap `view.remove` to unbind stickit model and dom events.
152
+ var remove = this.remove;
153
+ this.remove = function() {
154
+ var ret = this;
155
+ this.unstickit();
156
+ if (remove) ret = remove.apply(this, _.rest(arguments));
157
+ return ret;
158
+ };
159
+ }
160
+ });
161
+
162
+ // Helpers
163
+ // -------
164
+
165
+ // Evaluates the given `path` (in object/dot-notation) relative to the given
166
+ // `obj`. If the path is null/undefined, then the given `obj` is returned.
167
+ var evaluatePath = function(obj, path) {
168
+ var parts = (path || '').split('.');
169
+ var result = _.reduce(parts, function(memo, i) { return memo[i]; }, obj);
170
+ return result == null ? obj : result;
171
+ };
172
+
173
+ // If the given `fn` is a string, then view[fn] is called, otherwise it is
174
+ // a function that should be executed.
175
+ var applyViewFn = function(view, fn) {
176
+ if (fn) return (_.isString(fn) ? evaluatePath(view,fn) : fn).apply(view, _.rest(arguments, 2));
177
+ };
178
+
179
+ var getSelectedOption = function($select) { return $select.find('option').not(function(){ return !this.selected; }); };
180
+
181
+ // Given a function, string (view function reference), or a boolean
182
+ // value, returns the truthy result. Any other types evaluate as false.
183
+ var evaluateBoolean = function(view, reference) {
184
+ if (_.isBoolean(reference)) return reference;
185
+ else if (_.isFunction(reference) || _.isString(reference))
186
+ return applyViewFn.apply(this, arguments);
187
+ return false;
188
+ };
189
+
190
+ // Setup a model event binding with the given function, and track the event
191
+ // in the view's _modelBindings.
192
+ var observeModelEvent = function(model, view, event, fn) {
193
+ model.on(event, fn, view);
194
+ view._modelBindings.push({model:model, event:event, fn:fn});
195
+ };
196
+
197
+ // Prepares the given `val`ue and sets it into the `model`.
198
+ var setAttr = function(model, attr, val, options, context, config) {
199
+ var value = {};
200
+ if (config.onSet)
201
+ val = applyViewFn(context, config.onSet, val, config);
202
+
203
+ if (config.set)
204
+ applyViewFn(context, config.set, attr, val, options, config);
205
+ else {
206
+ value[attr] = val;
207
+ // If `observe` is defined as an array and `onSet` returned
208
+ // an array, then map attributes to their values.
209
+ if (_.isArray(attr) && _.isArray(val)) {
210
+ value = _.reduce(attr, function(memo, attribute, index) {
211
+ memo[attribute] = _.has(val, index) ? val[index] : null;
212
+ return memo;
213
+ }, {});
214
+ }
215
+ model.set(value, options);
216
+ }
217
+ };
218
+
219
+ // Returns the given `attr`'s value from the `model`, escaping and
220
+ // formatting if necessary. If `attr` is an array, then an array of
221
+ // respective values will be returned.
222
+ var getAttr = function(model, attr, config, context) {
223
+ var val,
224
+ retrieveVal = function(field) {
225
+ return model[config.escape ? 'escape' : 'get'](field);
226
+ },
227
+ sanitizeVal = function(val) {
228
+ return val == null ? '' : val;
229
+ };
230
+ val = _.isArray(attr) ? _.map(attr, retrieveVal) : retrieveVal(attr);
231
+ if (config.onGet) val = applyViewFn(context, config.onGet, val, config);
232
+ return _.isArray(val) ? _.map(val, sanitizeVal) : sanitizeVal(val);
233
+ };
234
+
235
+ // Find handlers in `Backbone.Stickit._handlers` with selectors that match
236
+ // `$el` and generate a configuration by mixing them in the order that they
237
+ // were found with the given `binding`.
238
+ var getConfiguration = Backbone.Stickit.getConfiguration = function($el, binding) {
239
+ var handlers = [{
240
+ updateModel: false,
241
+ updateMethod: 'text',
242
+ update: function($el, val, m, opts) { if ($el[opts.updateMethod]) $el[opts.updateMethod](val); },
243
+ getVal: function($el, e, opts) { return $el[opts.updateMethod](); }
244
+ }];
245
+ handlers = handlers.concat(_.filter(Backbone.Stickit._handlers, function(handler) {
246
+ return $el.is(handler.selector);
247
+ }));
248
+ handlers.push(binding);
249
+ var config = _.extend.apply(_, handlers);
250
+ // `updateView` is defaulted to false for configutrations with
251
+ // `visible`; otherwise, `updateView` is defaulted to true.
252
+ if (config.visible && !_.has(config, 'updateView')) config.updateView = false;
253
+ else if (!_.has(config, 'updateView')) config.updateView = true;
254
+ delete config.selector;
255
+ return config;
256
+ };
257
+
258
+ // Setup the attributes configuration - a list that maps an attribute or
259
+ // property `name`, to an `observe`d model attribute, using an optional
260
+ // `onGet` formatter.
261
+ //
262
+ // attributes: [{
263
+ // name: 'attributeOrPropertyName',
264
+ // observe: 'modelAttrName'
265
+ // onGet: function(modelAttrVal, modelAttrName) { ... }
266
+ // }, ...]
267
+ //
268
+ var initializeAttributes = function(view, $el, config, model, modelAttr) {
269
+ var props = ['autofocus', 'autoplay', 'async', 'checked', 'controls', 'defer', 'disabled', 'hidden', 'indeterminate', 'loop', 'multiple', 'open', 'readonly', 'required', 'scoped', 'selected'];
270
+
271
+ _.each(config.attributes || [], function(attrConfig) {
272
+ var lastClass = '', observed, updateAttr;
273
+ attrConfig = _.clone(attrConfig);
274
+ observed = attrConfig.observe || (attrConfig.observe = modelAttr),
275
+ updateAttr = function() {
276
+ var updateType = _.indexOf(props, attrConfig.name, true) > -1 ? 'prop' : 'attr',
277
+ val = getAttr(model, observed, attrConfig, view);
278
+ // If it is a class then we need to remove the last value and add the new.
279
+ if (attrConfig.name === 'class') {
280
+ $el.removeClass(lastClass).addClass(val);
281
+ lastClass = val;
282
+ }
283
+ else $el[updateType](attrConfig.name, val);
284
+ };
285
+ _.each(_.flatten([observed]), function(attr) {
286
+ observeModelEvent(model, view, 'change:' + attr, updateAttr);
287
+ });
288
+ updateAttr();
289
+ });
290
+ };
291
+
292
+ // If `visible` is configured, then the view element will be shown/hidden
293
+ // based on the truthiness of the modelattr's value or the result of the
294
+ // given callback. If a `visibleFn` is also supplied, then that callback
295
+ // will be executed to manually handle showing/hiding the view element.
296
+ //
297
+ // observe: 'isRight',
298
+ // visible: true, // or function(val, options) {}
299
+ // visibleFn: function($el, isVisible, options) {} // optional handler
300
+ //
301
+ var initializeVisible = function(view, $el, config, model, modelAttr) {
302
+ if (config.visible == null) return;
303
+ var visibleCb = function() {
304
+ var visible = config.visible,
305
+ visibleFn = config.visibleFn,
306
+ val = getAttr(model, modelAttr, config, view),
307
+ isVisible = !!val;
308
+ // If `visible` is a function then it should return a boolean result to show/hide.
309
+ if (_.isFunction(visible) || _.isString(visible)) isVisible = !!applyViewFn(view, visible, val, config);
310
+ // Either use the custom `visibleFn`, if provided, or execute the standard show/hide.
311
+ if (visibleFn) applyViewFn(view, visibleFn, $el, isVisible, config);
312
+ else {
313
+ $el.toggle(isVisible);
314
+ }
315
+ };
316
+ _.each(_.flatten([modelAttr]), function(attr) {
317
+ observeModelEvent(model, view, 'change:' + attr, visibleCb);
318
+ });
319
+ visibleCb();
320
+ };
321
+
322
+ // Update the value of `$el` using the given configuration and trigger the
323
+ // `afterUpdate` callback. This action may be blocked by `config.updateView`.
324
+ //
325
+ // update: function($el, val, model, options) {}, // handler for updating
326
+ // updateView: true, // defaults to true
327
+ // afterUpdate: function($el, val, options) {} // optional callback
328
+ //
329
+ var updateViewBindEl = function(view, $el, config, val, model, isInitializing) {
330
+ if (!evaluateBoolean(view, config.updateView, val, config)) return;
331
+ applyViewFn(view, config.update, $el, val, model, config);
332
+ if (!isInitializing) applyViewFn(view, config.afterUpdate, $el, val, config);
333
+ };
334
+
335
+ // Default Handlers
336
+ // ----------------
337
+
338
+ Backbone.Stickit.addHandler([{
339
+ selector: '[contenteditable="true"]',
340
+ updateMethod: 'html',
341
+ events: ['input', 'change']
342
+ }, {
343
+ selector: 'input',
344
+ events: ['propertychange', 'input', 'change'],
345
+ update: function($el, val) { $el.val(val); },
346
+ getVal: function($el) {
347
+ return $el.val();
348
+ }
349
+ }, {
350
+ selector: 'textarea',
351
+ events: ['propertychange', 'input', 'change'],
352
+ update: function($el, val) { $el.val(val); },
353
+ getVal: function($el) { return $el.val(); }
354
+ }, {
355
+ selector: 'input[type="radio"]',
356
+ events: ['change'],
357
+ update: function($el, val) {
358
+ $el.filter('[value="'+val+'"]').prop('checked', true);
359
+ },
360
+ getVal: function($el) {
361
+ return $el.filter(':checked').val();
362
+ }
363
+ }, {
364
+ selector: 'input[type="checkbox"]',
365
+ events: ['change'],
366
+ update: function($el, val, model, options) {
367
+ if ($el.length > 1) {
368
+ // There are multiple checkboxes so we need to go through them and check
369
+ // any that have value attributes that match what's in the array of `val`s.
370
+ val || (val = []);
371
+ $el.each(function(i, el) {
372
+ var checkbox = Backbone.$(el);
373
+ var checked = _.indexOf(val, checkbox.val()) > -1;
374
+ checkbox.prop('checked', checked);
375
+ });
376
+ } else {
377
+ var checked = _.isBoolean(val) ? val : val === $el.val();
378
+ $el.prop('checked', checked);
379
+ }
380
+ },
381
+ getVal: function($el) {
382
+ var val;
383
+ if ($el.length > 1) {
384
+ val = _.reduce($el, function(memo, el) {
385
+ var checkbox = Backbone.$(el);
386
+ if (checkbox.prop('checked')) memo.push(checkbox.val());
387
+ return memo;
388
+ }, []);
389
+ } else {
390
+ val = $el.prop('checked');
391
+ // If the checkbox has a value attribute defined, then
392
+ // use that value. Most browsers use "on" as a default.
393
+ var boxval = $el.val();
394
+ if (boxval !== 'on' && boxval != null) {
395
+ val = val ? $el.val() : null;
396
+ }
397
+ }
398
+ return val;
399
+ }
400
+ }, {
401
+ selector: 'select',
402
+ events: ['change'],
403
+ update: function($el, val, model, options) {
404
+ var optList,
405
+ selectConfig = options.selectOptions,
406
+ list = selectConfig && selectConfig.collection || undefined,
407
+ isMultiple = $el.prop('multiple');
408
+
409
+ // If there are no `selectOptions` then we assume that the `<select>`
410
+ // is pre-rendered and that we need to generate the collection.
411
+ if (!selectConfig) {
412
+ selectConfig = {};
413
+ var getList = function($el) {
414
+ return $el.map(function() {
415
+ return {value:this.value, label:this.text};
416
+ }).get();
417
+ };
418
+ if ($el.find('optgroup').length) {
419
+ list = {opt_labels:[]};
420
+ // Search for options without optgroup
421
+ if ($el.find('> option').length) {
422
+ list.opt_labels.push(undefined);
423
+ _.each($el.find('> option'), function(el) {
424
+ list[undefined] = getList(Backbone.$(el));
425
+ });
426
+ }
427
+ _.each($el.find('optgroup'), function(el) {
428
+ var label = Backbone.$(el).attr('label');
429
+ list.opt_labels.push(label);
430
+ list[label] = getList(Backbone.$(el).find('option'));
431
+ });
432
+ } else {
433
+ list = getList($el.find('option'));
434
+ }
435
+ }
436
+
437
+ // Fill in default label and path values.
438
+ selectConfig.valuePath = selectConfig.valuePath || 'value';
439
+ selectConfig.labelPath = selectConfig.labelPath || 'label';
440
+
441
+ var addSelectOptions = function(optList, $el, fieldVal) {
442
+ _.each(optList, function(obj) {
443
+ var option = Backbone.$('<option/>'), optionVal = obj;
444
+
445
+ var fillOption = function(text, val) {
446
+ option.text(text);
447
+ optionVal = val;
448
+ // Save the option value as data so that we can reference it later.
449
+ option.data('stickit_bind_val', optionVal);
450
+ if (!_.isArray(optionVal) && !_.isObject(optionVal)) option.val(optionVal);
451
+ };
452
+
453
+ if (obj === '__default__')
454
+ fillOption(selectConfig.defaultOption.label, selectConfig.defaultOption.value);
455
+ else
456
+ fillOption(evaluatePath(obj, selectConfig.labelPath), evaluatePath(obj, selectConfig.valuePath));
457
+
458
+ // Determine if this option is selected.
459
+ if (!isMultiple && optionVal != null && fieldVal != null && optionVal === fieldVal || (_.isObject(fieldVal) && _.isEqual(optionVal, fieldVal)))
460
+ option.prop('selected', true);
461
+ else if (isMultiple && _.isArray(fieldVal)) {
462
+ _.each(fieldVal, function(val) {
463
+ if (_.isObject(val)) val = evaluatePath(val, selectConfig.valuePath);
464
+ if (val === optionVal || (_.isObject(val) && _.isEqual(optionVal, val)))
465
+ option.prop('selected', true);
466
+ });
467
+ }
468
+
469
+ $el.append(option);
470
+ });
471
+ };
472
+
473
+ $el.html('');
474
+
475
+ // The `list` configuration is a function that returns the options list or a string
476
+ // which represents the path to the list relative to `window` or the view/`this`.
477
+ var evaluate = function(view, list) {
478
+ var context = window;
479
+ if (list.indexOf('this.') === 0) context = view;
480
+ list = list.replace(/^[a-z]*\.(.+)$/, '$1');
481
+ return evaluatePath(context, list);
482
+ };
483
+ if (_.isString(list)) optList = evaluate(this, list);
484
+ else if (_.isFunction(list)) optList = applyViewFn(this, list, $el, options);
485
+ else optList = list;
486
+
487
+ // Support Backbone.Collection and deserialize.
488
+ if (optList instanceof Backbone.Collection) optList = optList.toJSON();
489
+
490
+ if (selectConfig.defaultOption) {
491
+ addSelectOptions(["__default__"], $el);
492
+ }
493
+
494
+ if (_.isArray(optList)) {
495
+ addSelectOptions(optList, $el, val);
496
+ } else if (optList.opt_labels) {
497
+ // To define a select with optgroups, format selectOptions.collection as an object
498
+ // with an 'opt_labels' property, as in the following:
499
+ //
500
+ // {
501
+ // 'opt_labels': ['Looney Tunes', 'Three Stooges'],
502
+ // 'Looney Tunes': [{id: 1, name: 'Bugs Bunny'}, {id: 2, name: 'Donald Duck'}],
503
+ // 'Three Stooges': [{id: 3, name : 'moe'}, {id: 4, name : 'larry'}, {id: 5, name : 'curly'}]
504
+ // }
505
+ //
506
+ _.each(optList.opt_labels, function(label) {
507
+ var $group = Backbone.$('<optgroup/>').attr('label', label);
508
+ addSelectOptions(optList[label], $group, val);
509
+ $el.append($group);
510
+ });
511
+ // With no 'opt_labels' parameter, the object is assumed to be a simple value-label map.
512
+ // Pass a selectOptions.comparator to override the default order of alphabetical by label.
513
+ } else {
514
+ var opts = [], opt;
515
+ for (var i in optList) {
516
+ opt = {};
517
+ opt[selectConfig.valuePath] = i;
518
+ opt[selectConfig.labelPath] = optList[i];
519
+ opts.push(opt);
520
+ }
521
+ addSelectOptions(_.sortBy(opts, selectConfig.comparator || selectConfig.labelPath), $el, val);
522
+ }
523
+ },
524
+ getVal: function($el) {
525
+ var val;
526
+ if ($el.prop('multiple')) {
527
+ val = Backbone.$(getSelectedOption($el).map(function() {
528
+ return Backbone.$(this).data('stickit_bind_val');
529
+ })).get();
530
+ } else {
531
+ val = getSelectedOption($el).data('stickit_bind_val');
532
+ }
533
+ return val;
534
+ }
535
+ }]);
536
+
537
+ }));
@@ -1 +1 @@
1
- //= require js_stack/backbone.stickit/backbone.stickit-0.6.3
1
+ //= require js_stack/backbone.stickit/backbone.stickit-0.7.0
@@ -1,6 +1,6 @@
1
1
  // MarionetteJS (Backbone.Marionette)
2
2
  // ----------------------------------
3
- // v1.4.0
3
+ // v1.4.1
4
4
  //
5
5
  // Copyright (c)2013 Derick Bailey, Muted Solutions, LLC.
6
6
  // Distributed under MIT license
@@ -1211,7 +1211,7 @@ Marionette.View = Backbone.View.extend({
1211
1211
  // this is a backfill since backbone removed the assignment
1212
1212
  // of this.options
1213
1213
  // at some point however this may be removed
1214
- this.options = options || {};
1214
+ this.options = _.extend({}, this.options, options);
1215
1215
 
1216
1216
  // parses out the @ui DSL for events
1217
1217
  this.events = this.normalizeUIKeys(_.result(this, 'events'));
@@ -1 +1 @@
1
- //= require js_stack/marionette/marionette-1.4.0
1
+ //= require js_stack/marionette/marionette-1.4.1
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: js_stack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Pewiński
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-29 00:00:00.000000000 Z
11
+ date: 2014-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: haml_coffee_assets
@@ -106,9 +106,10 @@ files:
106
106
  - vendor/assets/javascripts/js_stack/backbone.js
107
107
  - vendor/assets/javascripts/js_stack/backbone.pageable.js
108
108
  - vendor/assets/javascripts/js_stack/backbone.pageable/backbone.pageable-1.3.2.js
109
- - vendor/assets/javascripts/js_stack/backbone.pageable/backbone.pageable-1.4.1.js
109
+ - vendor/assets/javascripts/js_stack/backbone.pageable/backbone.pageable-1.4.3.js
110
110
  - vendor/assets/javascripts/js_stack/backbone.stickit.js
111
111
  - vendor/assets/javascripts/js_stack/backbone.stickit/backbone.stickit-0.6.3.js
112
+ - vendor/assets/javascripts/js_stack/backbone.stickit/backbone.stickit-0.7.0.js
112
113
  - vendor/assets/javascripts/js_stack/backbone.validation.js
113
114
  - vendor/assets/javascripts/js_stack/backbone.validation/backbone.validation-0.8.1.js
114
115
  - vendor/assets/javascripts/js_stack/backbone.validation/backbone.validation-0.9.0.js
@@ -121,7 +122,7 @@ files:
121
122
  - vendor/assets/javascripts/js_stack/jsroutes.js
122
123
  - vendor/assets/javascripts/js_stack/marionette.js
123
124
  - vendor/assets/javascripts/js_stack/marionette/marionette-1.1.0.js
124
- - vendor/assets/javascripts/js_stack/marionette/marionette-1.4.0.js
125
+ - vendor/assets/javascripts/js_stack/marionette/marionette-1.4.1.js
125
126
  - vendor/assets/javascripts/js_stack/moment.js
126
127
  - vendor/assets/javascripts/js_stack/underscore.js
127
128
  homepage: https://github.com/netguru/js_stack