backbone-nested-attributes 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NWQ0Y2NjZDgwNmFjNjk0NjBmMjc2Y2Q5MTQ3ZTZiMzM0NzFmMTBhOA==
4
+ MWQwMDQ2NGVlMDExZGViYTQ0YmNkOTFlZDgzODM2OTdhNDM5YmEzMg==
5
5
  data.tar.gz: !binary |-
6
- ZjVlYzIxOTJmOTk4YjgxMmJkM2EwNGZlODFhYzQxMDRkMzZiNTdkOA==
7
- SHA512:
6
+ NjBlNjdhYTFiZTliZDY3YjhkYmIwM2I2Mzk3OGY5YjdjZDIyZTA0YQ==
7
+ !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ODRhMmI2ZmNmNjk5NWY4M2U0MDMxMGFmNjA1ZjU4ZmZhM2NmNzg0MTE1NDM4
10
- ZjJkMjNmYTljYWJkZjUyMjY3OTljYjhjMDI4OGI5YTFmNjI4ZjA1MDQ1YjNi
11
- YjdjYjQ0NTJiOTFmY2EwY2Y0MDU5NzU4MDUxZTM4YjhlNzljYTc=
9
+ NGI0NGVkNDU1ZThmMmMyZTM4ODdhNjFlZmFhMTg2MGQ1M2Y5MTMwMGU1MTU5
10
+ NmU4ZjQzMjI3OWY5ZTJmYTliNmRmYzAwZDY0ZDAyNDhjZDlhMzRkOTkzYzk4
11
+ YzU3ZTlhMTEzNTY0YTFiNWU4MzRhMWY3N2Y0OWU3ZGNhNjRlMjM=
12
12
  data.tar.gz: !binary |-
13
- ZDdlNzQ4M2ExMjQwNTI0MWJjMmQ5NGFmYjFkMWYxNjIzZGRjNDE3YTg1ZDRl
14
- NGNhZDI4M2ZlZWIzZDRiNzhkODI1NThjYzNhNThlMjM1OTI3NDljYzYwMTlh
15
- ZmYwYTcxNzM4OTFlY2ZiODJmYzJjZjhkOTRmMWVkZGVmMDU1N2U=
13
+ NDUzODI3ODJjMzM1YzQ4MjYxOGRlMTBjNzQ4M2IwZWQ5ZTU5NjllMTIwNzcw
14
+ ZmE2ZTU2YTY3Y2FhNjUyNWM5NGE4NzA5OGNjOWJkYWUzOTM4MDg0ZDhhNzJj
15
+ MDE1MDZkMDViMTM2ZWIyM2M1OGJhMmUzYjg1YzcxZWZkZmEwOWU=
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- backbone-nested-attributes (0.4.0)
4
+ backbone-nested-attributes (0.4.1)
5
5
  rails (>= 3.2.8)
6
6
 
7
7
  GEM
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Vicente Mundim
1
+ Copyright (c) 2014 Vicente Mundim
2
2
 
3
3
  MIT License
4
4
 
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
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.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -10,12 +10,24 @@ load 'rails/tasks/engine.rake'
10
10
 
11
11
  Bundler::GemHelper.install_tasks
12
12
 
13
+ task :build_js do
14
+ require 'sprockets'
15
+
16
+ Sprockets::Environment.new do |environment|
17
+ environment.append_path "app/assets/javascripts"
18
+
19
+ environment['backbone-nested-attributes/all'].write_to "dist/js/backbone-nested-attributes.js"
20
+ end
21
+ end
22
+
13
23
  task :travis do
14
24
  puts "Starting to run app:jasmine:ci..."
15
25
  system("export DISPLAY=:99.0 && bundle exec rake app:jasmine:ci")
16
26
  raise "#{cmd} failed!" unless $?.exitstatus == 0
17
27
  end
18
28
 
29
+ task :release => :build_js
30
+
19
31
  task :jasmine => 'app:jasmine'
20
32
 
21
33
  task :default => :travis
@@ -1,2 +1,30 @@
1
+ /**
2
+ * Copyright (c) 2013-2014 Vicente Mundim
3
+ *
4
+ * MIT License
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining
7
+ * a copy of this software and associated documentation files (the
8
+ * "Software"), to deal in the Software without restriction, including
9
+ * without limitation the rights to use, copy, modify, merge, publish,
10
+ * distribute, sublicense, and/or sell copies of the Software, and to
11
+ * permit persons to whom the Software is furnished to do so, subject to
12
+ * the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ //= require_self
1
27
  //= require backbone-nested-attributes/model
2
28
  //= require backbone-nested-attributes/undoable
29
+
30
+
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "backbone-nested-attributes",
3
+ "version": "0.4.1",
4
+ "main": "dist/js/backbone-nested-attributes.js",
5
+ "description": "Add Rails-like nested attributes support for Backbone.Model.",
6
+ "license": "MIT",
7
+ "ignore": [
8
+ ".ruby-gemset",
9
+ ".ruby-version",
10
+ ".travis.yml",
11
+ "*.gemspec",
12
+ "Rakefile",
13
+ "app/**/*",
14
+ "lib/**/*",
15
+ "pkg/**/*",
16
+ "spec/**/*"
17
+ ],
18
+ "dependencies": {
19
+ "backbone": ">=1.0.0"
20
+ }
21
+ }
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Copyright (c) 2013-2014 Vicente Mundim
3
+ *
4
+ * MIT License
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining
7
+ * a copy of this software and associated documentation files (the
8
+ * "Software"), to deal in the Software without restriction, including
9
+ * without limitation the rights to use, copy, modify, merge, publish,
10
+ * distribute, sublicense, and/or sell copies of the Software, and to
11
+ * permit persons to whom the Software is furnished to do so, subject to
12
+ * the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+
27
+
28
+
29
+
30
+
31
+ ;
32
+ (function(Backbone, _) {
33
+ var BackboneModelPrototype = Backbone.Model.prototype
34
+
35
+ function setNestedAttributes(model, key, value, options) {
36
+ var attributes = attributesFor(key, value, options)
37
+
38
+ if (attributes) {
39
+ _(model.relations).each(function (relation) {
40
+ if (relation.type == 'one') {
41
+ setHasOneNestedAttributeFor(model, relation, attributes)
42
+ } else {
43
+ setNestedAttributeFor(model, relation, attributes)
44
+ }
45
+ })
46
+ }
47
+
48
+ configureNestedAttributesEvents(model)
49
+
50
+ return attributes
51
+ }
52
+
53
+ function setHasOneNestedAttributeFor(model, relation, attributes) {
54
+ var key = relation.key,
55
+ value = attributes[key],
56
+ ModelClass = _(relation).result('relatedModel')
57
+
58
+ if (value) {
59
+ value = value instanceof Backbone.Model ? value : new ModelClass(value)
60
+
61
+ configureEventBubbling(model, value, relation)
62
+ attributes[key] = value
63
+ }
64
+ }
65
+
66
+ function setNestedAttributeFor(model, relation, attributes) {
67
+ var key = relation.key,
68
+ value = attributes[key],
69
+ deletedValue = attributes['deleted_' + key],
70
+ currentValue = model.get(key),
71
+ nested = currentValue || createNestedAttributeCollection(relation)
72
+
73
+ value = valueOrSliceCollection(value)
74
+
75
+ configureEventBubbling(model, nested, relation)
76
+
77
+ if (value) {
78
+ nested.set(value)
79
+ }
80
+
81
+ if (deletedValue) {
82
+ delete attributes['deleted_' + key]
83
+
84
+ deletedValue = valueOrSliceCollection(deletedValue)
85
+ nested.deletedModels.set(deletedValue)
86
+ }
87
+
88
+ attributes[key] = nested
89
+
90
+ return attributes
91
+ }
92
+
93
+ function valueOrSliceCollection(value) {
94
+ return value instanceof Backbone.Collection ? value.slice() : value
95
+ }
96
+
97
+ function clearDeletedModelsFor(model) {
98
+ _(model.relations).each(function (relation) {
99
+ var collectionOrModel = model.get(relation.key)
100
+
101
+ if (collectionOrModel && collectionOrModel.each) {
102
+ collectionOrModel.each(function (nestedModel) {
103
+ clearDeletedModelsFor(nestedModel)
104
+ })
105
+
106
+ if (collectionOrModel.deletedModels) {
107
+ collectionOrModel.deletedModels.reset()
108
+ }
109
+ }
110
+ })
111
+ }
112
+
113
+ function configureNestedAttributesEvents(model) {
114
+ if (!model._hasNestedAttributesEventsConfigured) {
115
+ model.on('sync', clearDeletedModelsFor)
116
+ model._hasNestedAttributesEventsConfigured = true
117
+ }
118
+ }
119
+
120
+ function configureEventBubbling(model, nested, relation) {
121
+ if (!nested._hasEventBubblingConfigured) {
122
+ model.listenTo(nested, 'add change nested:change remove', function (nestedModel, options) {
123
+ model.trigger('nested:change change:' + relation.key, nestedModel, options)
124
+ })
125
+
126
+ nested._hasEventBubblingConfigured = true
127
+ }
128
+ }
129
+
130
+ function clearNestedEvents(model) {
131
+ _(model.relations).each(function (relation) {
132
+ var nested = model.get(relation.key)
133
+
134
+ model.stopListening(nested)
135
+ nested.off('remove', nestedModelRemoved, nested)
136
+
137
+ if (nested.deletedModels) {
138
+ nested.deletedModels.reset()
139
+ }
140
+ }, model)
141
+ }
142
+
143
+ function nestedToJson(json, relations, options) {
144
+ _(relations).each(function (relation) {
145
+ var key = relation.key,
146
+ value = json[key],
147
+ deleted = [],
148
+ jsonValue
149
+
150
+ if (value) {
151
+ if (options) {
152
+ if (options.withDeleted) {
153
+ if (value.deletedModels) {
154
+ json['deleted_' + key] = value.deletedModels.toJSON(options)
155
+ }
156
+ }
157
+
158
+ if (options.nested) {
159
+ if (value.deletedModels) {
160
+ deleted = value.deletedModels.toJSON(options)
161
+ }
162
+
163
+ delete json[key]
164
+ key = key + '_attributes'
165
+ }
166
+ }
167
+
168
+ jsonValue = value.toJSON(options)
169
+
170
+ if (_(jsonValue).isArray()) {
171
+ json[key] = jsonValue.concat(deleted)
172
+ } else {
173
+ json[key] = jsonValue
174
+ }
175
+ }
176
+ })
177
+
178
+ return json
179
+ }
180
+
181
+ function createNestedAttributeCollection(relation) {
182
+ var CollectionType = _(relation).result('collectionType') || Backbone.Collection,
183
+ collection = new CollectionType
184
+
185
+ collection.model = _(relation).result('relatedModel') || collection.model
186
+
187
+ collection.deletedModels = new Backbone.Collection
188
+ collection.deletedModels.model = collection.model
189
+ collection.on('remove', nestedModelRemoved)
190
+
191
+ return collection
192
+ }
193
+
194
+ function nestedModelRemoved(model, collection) {
195
+ if (!model.isNew()) {
196
+ model.set({ _destroy: true })
197
+ collection.deletedModels.add(model)
198
+ }
199
+ }
200
+
201
+ function attributesFor(key, value, options) {
202
+ var attributes
203
+
204
+ // Duplicate backbone's behavior to allow separate key/value parameters,
205
+ // instead of a single 'attributes' object.
206
+ if (_.isObject(key) || key == null) {
207
+ attributes = key
208
+ options = value
209
+ } else {
210
+ attributes = {}
211
+ attributes[key] = value
212
+ }
213
+
214
+ return attributes
215
+ }
216
+
217
+ Backbone.NestedAttributesModel = Backbone.Model.extend({
218
+ set: function (key, value, options) {
219
+ var attributes = setNestedAttributes(this, key, value, options)
220
+ return BackboneModelPrototype.set.call(this, attributes, options)
221
+ },
222
+
223
+ toJSON: function (options) {
224
+ return nestedToJson(BackboneModelPrototype.toJSON.apply(this, arguments), this.relations, options)
225
+ },
226
+
227
+ clone: function() {
228
+ return new this.constructor(this.toJSON());
229
+ },
230
+
231
+ clear: function (options) {
232
+ clearNestedEvents(this)
233
+ return BackboneModelPrototype.clear.apply(this, arguments)
234
+ }
235
+ })
236
+ })(Backbone, _);
237
+ (function(Backbone, _) {
238
+ var NestedAttributesModel = Backbone.NestedAttributesModel,
239
+ NestedAttributesModelProto = NestedAttributesModel.prototype
240
+
241
+ function UndoableState(model) {
242
+ this.model = model
243
+
244
+ model.on('nested:change', this.change, this)
245
+ model.on('change', this.change, this)
246
+ model.on('sync', this.save, this)
247
+ }
248
+
249
+ _.extend(UndoableState.prototype, Backbone.Events, {
250
+ change: function () {
251
+ this.changed = true
252
+ },
253
+
254
+ save: function () {
255
+ this.updateAttributes()
256
+
257
+ this.model.trigger('state:store')
258
+ },
259
+
260
+ undo: function () {
261
+ this.attributesToUnset().each(function (attribute) {
262
+ this.model.unset(attribute)
263
+ }, this)
264
+
265
+ this.model.set(this.attributes)
266
+
267
+ this.updateAttributes()
268
+
269
+ this.model.trigger('state:restore')
270
+ },
271
+
272
+ attributesToUnset: function () {
273
+ var previousAttributes = _(this.attributes || {}).keys()
274
+
275
+ return _(this.model.attributes).chain().keys().select(function (attribute) {
276
+ return !_(previousAttributes).include(attribute)
277
+ })
278
+ },
279
+
280
+ updateAttributes: function () {
281
+ this.attributes = this.model.toJSON({ withDeleted: true })
282
+ this.changed = false
283
+ }
284
+ })
285
+
286
+ Backbone.UndoableModel = NestedAttributesModel.extend({
287
+ initialize: function () {
288
+ NestedAttributesModelProto.initialize.apply(this, arguments)
289
+
290
+ this.undoable()
291
+ },
292
+
293
+ undoable: function () {
294
+ this.saveState()
295
+ },
296
+
297
+ undo: function () {
298
+ this.undoableState().undo()
299
+ },
300
+
301
+ hasChangedSinceSync: function () {
302
+ return this.undoableState().changed === true
303
+ },
304
+
305
+ saveState: function () {
306
+ this.undoableState().save()
307
+ },
308
+
309
+ undoableState: function () {
310
+ return this._undoableState = this._undoableState || new UndoableState(this)
311
+ }
312
+ })
313
+ })(Backbone, _);
@@ -1,5 +1,5 @@
1
1
  module Backbone
2
2
  module NestedAttributes
3
- VERSION = "0.4.0"
3
+ VERSION = "0.4.1"
4
4
  end
5
5
  end
@@ -0,0 +1,17 @@
1
+ {
2
+ "name" : "backbone-nested-attributes",
3
+ "description" : "Add Rails-like nested attributes support for Backbone.Model.",
4
+ "url" : "http://github.com/dtmtec/backbone-nested-attributes",
5
+ "keywords" : ["model", "backbone", "nested attributes"],
6
+ "author" : "Vicente Mundim <vicente.mundim@gmail.com>",
7
+ "dependencies" : {
8
+ "backbone" : ">=1.0.0"
9
+ },
10
+ "main" : "dist/js/backbone-nested-attributes.js",
11
+ "version" : "0.4.1",
12
+ "license" : "MIT",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/dtmtec/backbone-nested-attributes.git"
16
+ }
17
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backbone-nested-attributes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vicente Mundim
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-23 00:00:00.000000000 Z
11
+ date: 2014-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -44,9 +44,12 @@ files:
44
44
  - app/assets/javascripts/backbone-nested-attributes/model.js
45
45
  - app/assets/javascripts/backbone-nested-attributes/undoable.js
46
46
  - backbone-nested-attributes.gemspec
47
+ - bower.json
48
+ - dist/js/backbone-nested-attributes.js
47
49
  - lib/backbone-nested-attributes.rb
48
50
  - lib/backbone-nested-attributes/engine.rb
49
51
  - lib/backbone-nested-attributes/version.rb
52
+ - package.json
50
53
  - spec/dummy/README.rdoc
51
54
  - spec/dummy/Rakefile
52
55
  - spec/dummy/app/assets/javascripts/application.js
@@ -104,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
107
  version: '0'
105
108
  requirements: []
106
109
  rubyforge_project:
107
- rubygems_version: 2.1.11
110
+ rubygems_version: 2.0.6
108
111
  signing_key:
109
112
  specification_version: 4
110
113
  summary: Add nested attributes to your Backbone models