joosy 0.1.0.alpha → 1.0.0.RC1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/.codoopts +5 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +15 -2
  4. data/Gemfile.lock +102 -81
  5. data/Guardfile +16 -16
  6. data/LICENSE +22 -0
  7. data/MIT-LICENSE +2 -2
  8. data/README.md +118 -0
  9. data/app/assets/javascripts/joosy/core/application.js.coffee +53 -0
  10. data/app/assets/javascripts/joosy/core/form.js.coffee +338 -0
  11. data/app/assets/javascripts/joosy/core/helpers/form.js.coffee +72 -0
  12. data/app/assets/javascripts/joosy/core/helpers/view.js.coffee +42 -0
  13. data/app/assets/javascripts/joosy/core/helpers/widgets.js.coffee +14 -0
  14. data/app/assets/javascripts/joosy/core/joosy.js.coffee +184 -0
  15. data/app/assets/javascripts/joosy/core/layout.js.coffee +168 -0
  16. data/app/assets/javascripts/joosy/core/modules/container.js.coffee +124 -0
  17. data/app/assets/javascripts/joosy/core/modules/events.js.coffee +122 -0
  18. data/app/assets/javascripts/joosy/core/modules/filters.js.coffee +39 -0
  19. data/app/assets/javascripts/joosy/core/modules/log.js.coffee +36 -0
  20. data/app/assets/javascripts/joosy/core/modules/module.js.coffee +117 -0
  21. data/app/assets/javascripts/joosy/core/modules/renderer.js.coffee +200 -0
  22. data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +46 -0
  23. data/app/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +87 -0
  24. data/app/assets/javascripts/joosy/core/page.js.coffee +387 -0
  25. data/app/assets/javascripts/joosy/core/preloader.js.coffee +13 -0
  26. data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +175 -0
  27. data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +303 -0
  28. data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +244 -0
  29. data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +24 -0
  30. data/app/assets/javascripts/joosy/core/router.js.coffee +201 -0
  31. data/app/assets/javascripts/joosy/core/templaters/rails_jst.js.coffee +37 -0
  32. data/app/assets/javascripts/joosy/core/widget.js.coffee +85 -0
  33. data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +169 -0
  34. data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +56 -0
  35. data/{vendor → app}/assets/javascripts/joosy.js.coffee +0 -1
  36. data/app/helpers/joosy/sprockets_helper.rb +39 -12
  37. data/joosy.gemspec +4 -3
  38. data/lib/joosy/rails/engine.rb +12 -1
  39. data/lib/joosy/rails/version.rb +2 -2
  40. data/lib/joosy.rb +9 -0
  41. data/lib/rails/generators/joosy/application_generator.rb +15 -3
  42. data/lib/rails/generators/joosy/joosy_base.rb +2 -2
  43. data/lib/rails/generators/joosy/layout_generator.rb +8 -1
  44. data/lib/rails/generators/joosy/page_generator.rb +21 -6
  45. data/lib/rails/generators/joosy/preloader_generator.rb +14 -7
  46. data/lib/rails/generators/joosy/resource_generator.rb +29 -0
  47. data/lib/rails/generators/joosy/templates/app/helpers/application.js.coffee +4 -0
  48. data/lib/rails/generators/joosy/templates/app/layouts/application.js.coffee +1 -0
  49. data/lib/rails/generators/joosy/templates/app/layouts/template.js.coffee +1 -1
  50. data/lib/rails/generators/joosy/templates/app/pages/application.js.coffee +1 -1
  51. data/lib/rails/generators/joosy/templates/app/pages/template.js.coffee +3 -3
  52. data/lib/rails/generators/joosy/templates/app/pages/welcome/index.js.coffee +22 -0
  53. data/lib/rails/generators/joosy/templates/app/resources/template.js.coffee +2 -0
  54. data/lib/rails/generators/joosy/templates/app/routes.js.coffee +7 -1
  55. data/lib/rails/generators/joosy/templates/app/templates/layouts/application.jst.hamlc +2 -0
  56. data/lib/rails/generators/joosy/templates/app/templates/pages/welcome/index.jst.hamlc +7 -0
  57. data/lib/rails/generators/joosy/templates/app/widgets/template.js.coffee +2 -2
  58. data/lib/rails/generators/joosy/templates/app.js.coffee +4 -0
  59. data/lib/rails/generators/joosy/templates/app_preloader.js.coffee.erb +9 -12
  60. data/lib/rails/generators/joosy/templates/app_resources_predefiner.js.coffee.erb +11 -0
  61. data/lib/rails/generators/joosy/templates/preload.html.erb +5 -6
  62. data/lib/rails/generators/joosy/templates/preload.html.haml +3 -5
  63. data/lib/rails/generators/joosy/widget_generator.rb +8 -1
  64. data/lib/rails/resources_with_joosy.rb +11 -0
  65. data/spec/javascripts/helpers/spec_helper.js.coffee +25 -0
  66. data/spec/javascripts/joosy/core/application_spec.js.coffee +40 -0
  67. data/spec/javascripts/joosy/core/form_spec.js.coffee +200 -0
  68. data/spec/javascripts/joosy/core/helpers/forms_spec.js.coffee +103 -0
  69. data/spec/javascripts/joosy/core/helpers/view_spec.js.coffee +10 -0
  70. data/spec/javascripts/joosy/core/joosy_spec.js.coffee +97 -0
  71. data/spec/javascripts/joosy/core/layout_spec.js.coffee +50 -0
  72. data/spec/javascripts/joosy/core/modules/container_spec.js.coffee +32 -27
  73. data/spec/javascripts/joosy/core/modules/events_spec.js.coffee +55 -18
  74. data/spec/javascripts/joosy/core/modules/filters_spec.js.coffee +28 -27
  75. data/spec/javascripts/joosy/core/modules/log_spec.js.coffee +3 -3
  76. data/spec/javascripts/joosy/core/modules/module_spec.js.coffee +6 -15
  77. data/spec/javascripts/joosy/core/modules/renderer_spec.js.coffee +203 -0
  78. data/spec/javascripts/joosy/core/modules/time_manager_spec.js.coffee +12 -7
  79. data/spec/javascripts/joosy/core/modules/widget_manager_spec.js.coffee +31 -17
  80. data/spec/javascripts/joosy/core/page_spec.js.coffee +178 -0
  81. data/spec/javascripts/joosy/core/resource/collection_spec.js.coffee +84 -0
  82. data/spec/javascripts/joosy/core/resource/generic_spec.js.coffee +149 -0
  83. data/spec/javascripts/joosy/core/resource/rest_collection_spec.js.coffee +31 -0
  84. data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +171 -0
  85. data/spec/javascripts/joosy/core/router_spec.js.coffee +143 -0
  86. data/spec/javascripts/joosy/core/templaters/rails_jst_spec.js.coffee +25 -0
  87. data/spec/javascripts/joosy/core/widget_spec.js.coffee +40 -0
  88. data/spec/javascripts/joosy/preloaders/caching_spec.js.coffee +36 -0
  89. data/spec/javascripts/joosy/preloaders/inline_spec.js.coffee +16 -0
  90. data/spec/javascripts/support/assets/coolface.jpg +0 -0
  91. data/spec/javascripts/support/assets/okay.jpg +0 -0
  92. data/spec/javascripts/support/assets/test.js +1 -0
  93. data/spec/javascripts/support/sinon-ie-1.3.1.js +82 -0
  94. data/vendor/assets/javascripts/jquery.form.js +978 -963
  95. data/vendor/assets/javascripts/metamorph.js +409 -0
  96. data/vendor/assets/javascripts/sugar.js +1057 -366
  97. metadata +95 -50
  98. data/README.rdoc +0 -3
  99. data/lib/joosy/forms.rb +0 -47
  100. data/lib/joosy-rails.rb +0 -5
  101. data/lib/rails/generators/joosy/templates/preload.html.slim +0 -21
  102. data/tmp/javascripts/.gitignore +0 -1
  103. data/tmp/spec/javascripts/helpers/.gitignore +0 -1
  104. data/vendor/assets/javascripts/base64.js +0 -135
  105. data/vendor/assets/javascripts/inflection.js +0 -656
  106. data/vendor/assets/javascripts/joosy/core/application.js.coffee +0 -26
  107. data/vendor/assets/javascripts/joosy/core/form.js.coffee +0 -87
  108. data/vendor/assets/javascripts/joosy/core/joosy.js.coffee +0 -62
  109. data/vendor/assets/javascripts/joosy/core/layout.js.coffee +0 -38
  110. data/vendor/assets/javascripts/joosy/core/modules/container.js.coffee +0 -51
  111. data/vendor/assets/javascripts/joosy/core/modules/events.js.coffee +0 -17
  112. data/vendor/assets/javascripts/joosy/core/modules/filters.js.coffee +0 -39
  113. data/vendor/assets/javascripts/joosy/core/modules/log.js.coffee +0 -12
  114. data/vendor/assets/javascripts/joosy/core/modules/module.js.coffee +0 -28
  115. data/vendor/assets/javascripts/joosy/core/modules/time_manager.js.coffee +0 -23
  116. data/vendor/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +0 -45
  117. data/vendor/assets/javascripts/joosy/core/page.js.coffee +0 -136
  118. data/vendor/assets/javascripts/joosy/core/resource/rest.js.coffee +0 -69
  119. data/vendor/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +0 -42
  120. data/vendor/assets/javascripts/joosy/core/router.js.coffee +0 -75
  121. data/vendor/assets/javascripts/joosy/core/widget.js.coffee +0 -35
  122. data/vendor/assets/javascripts/joosy/preloader/development.js.coffee +0 -27
  123. data/vendor/assets/javascripts/joosy/preloader/production.js.coffee +0 -84
@@ -0,0 +1,13 @@
1
+ #
2
+ # Preloader stub
3
+ #
4
+ # @mixin
5
+ #
6
+ @Preloader =
7
+
8
+ #
9
+ # Mocks loader to do nothing if Joosy is already here
10
+ #
11
+ load: (libraries, options) ->
12
+ @[key] = val for key, val of options
13
+ @complete?.call window
@@ -0,0 +1,175 @@
1
+ #
2
+ # Basic collection of Resources.
3
+ # Turns JSON array into array of Resources and manages them.
4
+ #
5
+ # @note You should not use Collection directly. It will be
6
+ # automatically created by things like {Joosy.Resource.Generic.map}
7
+ # or {Joosy.Resource.REST.find}.
8
+ #
9
+ # @example Basic sample
10
+ # class R extends Joosy.Resource.Generic
11
+ # @entity 'r'
12
+ #
13
+ # collection = new Joosy.Resource.Collection(R)
14
+ #
15
+ # collection.load [{foo: 'bar'}, {foo: 'baz'}]
16
+ # collection.each (resource) ->
17
+ # resource('foo')
18
+ #
19
+ # @include Joosy.Modules.Events
20
+ #
21
+ class Joosy.Resource.Collection extends Joosy.Module
22
+ @include Joosy.Modules.Events
23
+
24
+ #
25
+ # Allows to modify data before it gets stored
26
+ #
27
+ # @note Supposed to be used in descendants
28
+ #
29
+ # @param [Function] action `(Object) -> Object` to call
30
+ #
31
+ @beforeLoad: (action) -> @::__beforeLoad = action
32
+
33
+ #
34
+ # Sets the default model for collection
35
+ #
36
+ # @note Supposed to be used in descendants
37
+ #
38
+ # @param [Class] model Model class
39
+ #
40
+ @model: (model) -> @::model = model
41
+
42
+ #
43
+ # Modelized data storage
44
+ #
45
+ data: []
46
+
47
+ #
48
+ # If model param was empty it will fallback to `@model`
49
+ # If both param and `@model` were empty it will throw an exception.
50
+ #
51
+ # @param [Class] model Resource class which this collection will handle
52
+ #
53
+ constructor: (model=false) ->
54
+ @model = model if model
55
+
56
+ if !@model
57
+ throw new Error "#{Joosy.Module.__className @}> model can't be empty"
58
+
59
+ #
60
+ # Clears the storage and attempts to import given array
61
+ #
62
+ # @param [Array, Hash] entities Array of entities to import.
63
+ # If hash was given will seek for moodel name camelized and pluralized.
64
+ # @param [Boolean] notify Indicates whether to trigger 'changed' event
65
+ #
66
+ # @return [Joosy.Resource.Collection] Returns self.
67
+ #
68
+ load: (entities, notify=true) ->
69
+ if @__beforeLoad?
70
+ entities = @__beforeLoad entities
71
+
72
+ @data = @modelize entities
73
+
74
+ @trigger 'changed' if notify
75
+ this
76
+
77
+ #
78
+ # Turns Objects array into array of Resources
79
+ #
80
+ # @param [Array] collection Array of Objects
81
+ #
82
+ modelize: (collection) ->
83
+ root = @model::__entityName.pluralize()
84
+
85
+ if collection not instanceof Array
86
+ collection = collection?[root.camelize(false)]
87
+
88
+ if collection not instanceof Array
89
+ throw new Error "Can not read incoming JSON"
90
+
91
+ collection.map (x) =>
92
+ @model.build x
93
+
94
+ #
95
+ # Calls callback for each Resource inside Collection
96
+ #
97
+ # @param [Function] callback `(mixed) -> mixed` to call for each Resource in collection
98
+ #
99
+ each: (callback) ->
100
+ @data.each callback
101
+
102
+ #
103
+ # Returns number of Resources inside Collection
104
+ #
105
+ size: ->
106
+ @data.length
107
+
108
+ #
109
+ # Gets first resource matching description (see Sugar.js Array#find)
110
+ #
111
+ # @param [Function] description Callback matcher
112
+ #
113
+ # @return [Joosy.Resource.Generic]
114
+ #
115
+ find: (description) ->
116
+ @data.find description
117
+
118
+ #
119
+ # Gets resource by id
120
+ #
121
+ # @param [Integer] id Id to find
122
+ #
123
+ # @return [Joosy.Resource.Generic]
124
+ #
125
+ findById: (id) ->
126
+ @data.find (x) -> x.id().toString() == id.toString()
127
+
128
+ #
129
+ # Gets resource by its index inside collection
130
+ #
131
+ # @param [Integer] i Index
132
+ #
133
+ # @return [Joosy.Resource.Generic]
134
+ #
135
+ at: (i) ->
136
+ @data[i]
137
+
138
+ #
139
+ # Removes resource from collection by its index or by === comparison
140
+ #
141
+ # @param [Integer] target Index
142
+ # @param [Resource] target Resource by itself
143
+ # @param [Boolean] notify Indicates whether to trigger 'changed' event
144
+ #
145
+ # @return [Joosy.Resource.Generic] Removed element
146
+ #
147
+ remove: (target, notify=true) ->
148
+ if Object.isNumber target
149
+ index = target
150
+ else
151
+ index = @data.indexOf target
152
+ if index >= 0
153
+ result = @data.splice(index, 1)[0]
154
+ if notify
155
+ @trigger 'changed'
156
+ result
157
+
158
+ #
159
+ # Adds resource to collection to given index or to the end
160
+ #
161
+ # @param [Resource] element Resource to add
162
+ # @param [Integer] index Index to add to. If omited will be pushed to the end
163
+ # @param [Boolean] notify Indicates whether to trigger 'changed' event
164
+ #
165
+ # @return [Joosy.Resource.Generic] Added element
166
+ #
167
+ add: (element, index=false, notify=true) ->
168
+ if index
169
+ @data.splice index, 0, element
170
+ else
171
+ @data.push element
172
+
173
+ if notify
174
+ @trigger 'changed'
175
+ element
@@ -0,0 +1,303 @@
1
+ #
2
+ # Basic data wrapper with triggering and entity name binding
3
+ #
4
+ # @example Basic usage
5
+ # class R extends Joosy.Resource.Generic
6
+ # @entity 'r'
7
+ #
8
+ # @beforeLoad (data) ->
9
+ # data.real = true
10
+ #
11
+ # r = R.build {r: {foo: {bar: 'baz'}}}
12
+ #
13
+ # r('foo') # {baz: 'baz'}
14
+ # r('real') # true
15
+ # r('foo.bar') # baz
16
+ # r('foo.bar', 'fluffy') # triggers 'changed'
17
+ #
18
+ # @include Joosy.Modules.Log
19
+ # @include Joosy.Modules.Events
20
+ #
21
+ class Joosy.Resource.Generic extends Joosy.Module
22
+ @include Joosy.Modules.Log
23
+ @include Joosy.Modules.Events
24
+
25
+ #
26
+ # Default primary key field 'id'
27
+ #
28
+ __primaryKey: 'id'
29
+
30
+ __source: false
31
+
32
+ @resetIdentity: ->
33
+ Joosy.Resource.Generic.identity = {}
34
+
35
+ #
36
+ # Allows to modify data before it gets stored.
37
+ # You can define several beforeLoad filters that will be chained.
38
+ #
39
+ # @param [Function] action `(Object) -> Object` to call
40
+ #
41
+ @beforeLoad: (action) ->
42
+ unless @::hasOwnProperty '__beforeLoads'
43
+ @::__beforeLoads = [].concat @.__super__.__beforeLoads || []
44
+ @::__beforeLoads.push action
45
+
46
+ #
47
+ # Sets the field containing primary key.
48
+ #
49
+ # @note It has no direct use inside the REST resource itself and can be omited.
50
+ # But it usually should not since we have plans on adding some kind of Identity Map to Joosy.
51
+ #
52
+ # @param [String] primary Name of the field
53
+ #
54
+ @primaryKey: (primaryKey) -> @::__primaryKey = primaryKey
55
+
56
+ @source: (location) ->
57
+ @__source = location
58
+
59
+ #
60
+ # Creates the proxy of current resource binded as a child of given entity
61
+ #
62
+ @at: (entity) ->
63
+ #
64
+ # Class inheritance used to create proxy
65
+ #
66
+ # @private
67
+ #
68
+ class clone extends this
69
+
70
+ if entity instanceof Joosy.Resource.Generic
71
+ clone.__source = entity.memberPath()
72
+ else
73
+ clone.__source = entity
74
+
75
+ clone
76
+
77
+ #
78
+ # Sets the entity text name:
79
+ # required to do some magic like skipping the root node.
80
+ #
81
+ # @param [String] name Singular name of resource
82
+ #
83
+ @entity: (name) -> @::__entityName = name
84
+
85
+ #
86
+ # Sets the collection to use
87
+ #
88
+ # @note By default will try to seek for `EntityNamesCollection`.
89
+ # Will fallback to {Joosy.Resource.Collection}
90
+ #
91
+ # @param [Class] klass Class to assign as collection
92
+ #
93
+ @collection: (klass) -> @::__collection = -> klass
94
+
95
+ #
96
+ # Implements {Joosy.Resource.Generic.collection} default behavior.
97
+ #
98
+ __collection: ->
99
+ named = @__entityName.camelize().pluralize() + 'Collection'
100
+ if window[named] then window[named] else Joosy.Resource.Collection
101
+
102
+ #
103
+ # Dynamically creates collection of inline resources.
104
+ #
105
+ # Inline resources share the instance with direct data and therefore can be used
106
+ # to handle inline changes with triggers and all that resources stuff
107
+ #
108
+ # @example Basic usage
109
+ # class Zombie extends Joosy.Resource.Generic
110
+ # @entity 'zombie'
111
+ # class Puppy extends Joosy.Resource.Generic
112
+ # @entity 'puppy'
113
+ # @map 'zombies'
114
+ #
115
+ # p = Puppy.build {zombies: [{foo: 'bar'}]}
116
+ #
117
+ # p('zombies') # Direct access: [{foo: 'bar'}]
118
+ # p.zombies # Wrapped Collection of Zombie instances
119
+ # p.zombies.at(0)('foo') # bar
120
+ #
121
+ # @param [String] name Pluralized name of property to define
122
+ # @param [Class] klass Resource class to instantiate
123
+ #
124
+ @map: (name, klass=false) ->
125
+ unless klass
126
+ klass = window[name.singularize().camelize()]
127
+
128
+ if !klass
129
+ throw new Error "#{Joosy.Module.__className @}> class can not be detected for '#{name}' mapping"
130
+
131
+ @beforeLoad (data) ->
132
+ @__map(data, name, klass)
133
+
134
+ #
135
+ # Wraps instance of resource inside shim-function allowing to track
136
+ # data changes. See class example
137
+ #
138
+ # @return [Joosy.Resource.Generic]
139
+ #
140
+ @build: (data={}) ->
141
+ klass = @::__entityName
142
+
143
+ Joosy.Resource.Generic.identity ||= {}
144
+ Joosy.Resource.Generic.identity[klass] ||= {}
145
+
146
+ shim = ->
147
+ shim.__call.apply shim, arguments
148
+
149
+ if shim.__proto__
150
+ shim.__proto__ = @prototype
151
+ else
152
+ for key, value of @prototype
153
+ shim[key] = value
154
+
155
+ shim.constructor = @
156
+
157
+ if Object.isNumber(data) || Object.isString(data)
158
+ id = data
159
+ data = {}
160
+ data[shim.__primaryKey] = id
161
+
162
+ if Joosy.Application.identity
163
+ id = data[shim.__primaryKey]
164
+
165
+ if id? && Joosy.Resource.Generic.identity[klass][id]
166
+ shim = Joosy.Resource.Generic.identity[klass][id]
167
+ shim.load data
168
+ else
169
+ @apply shim, [data]
170
+ Joosy.Resource.Generic.identity[klass][id] = shim
171
+ else
172
+ @apply shim, [data]
173
+
174
+ shim
175
+
176
+ #
177
+ # Should NOT be called directly, use {::build} instead
178
+ #
179
+ # @private
180
+ # @param [Object] data Data to store
181
+ #
182
+ constructor: (data={}) ->
183
+ @__fillData data, false
184
+
185
+ id: ->
186
+ @data[@__primaryKey]
187
+
188
+ knownAttributes: ->
189
+ @data.keys()
190
+
191
+ #
192
+ # Set the resource data manually
193
+ #
194
+ # @param [Object] data Data to store
195
+ #
196
+ # @return [Joosy.Resource.Generic] Returns self
197
+ #
198
+ load: (data) ->
199
+ @__fillData data
200
+ return this
201
+
202
+ #
203
+ # Getter for wrapped data
204
+ #
205
+ # @param [String] path Attribute name to get. Can contain dots to get inline Objects values
206
+ # @return [mixed]
207
+ #
208
+ __get: (path) ->
209
+ target = @__callTarget path
210
+
211
+ if target[0] instanceof Joosy.Resource.Generic
212
+ return target[0](target[1])
213
+ else
214
+ return target[0][target[1]]
215
+
216
+ #
217
+ # Setter for wrapped data, triggers `changed` event.
218
+ #
219
+ # @param [String] path Attribute name to set. Can contain dots to get inline Objects values
220
+ # @param [mixed] value Value to set
221
+ #
222
+ __set: (path, value) ->
223
+ target = @__callTarget path
224
+
225
+ if target[0] instanceof Joosy.Resource.Generic
226
+ target[0](target[1], value)
227
+ else
228
+ target[0][target[1]] = value
229
+
230
+ @trigger 'changed'
231
+ null
232
+
233
+ #
234
+ # Locates the actual instance of attribute path `foo.bar` from get/set
235
+ #
236
+ # @param [String] path Path to the attribute (`foo.bar`)
237
+ # @return [Array] Instance of object containing last step of path and keyword for required field
238
+ #
239
+ __callTarget: (path) ->
240
+ if path.has(/\./) && !@data[path]?
241
+ path = path.split '.'
242
+ keyword = path.pop()
243
+ target = @data
244
+
245
+ for part in path
246
+ target[part] ||= {}
247
+ if target instanceof Joosy.Resource.Generic
248
+ target = target(part)
249
+ else
250
+ target = target[part]
251
+
252
+ [target, keyword]
253
+ else
254
+ [@data, path]
255
+
256
+ #
257
+ # Wrapper for {Joosy.Resource.Generic.build} magic
258
+ #
259
+ __call: (path, value) ->
260
+ if arguments.length > 1
261
+ @__set path, value
262
+ else
263
+ @__get path
264
+
265
+ #
266
+ # Defines how exactly prepared data should be saved
267
+ #
268
+ # @param [Object] data Raw data to store
269
+ #
270
+ __fillData: (data, notify=true) ->
271
+ @raw = data
272
+ @data = {} unless @hasOwnProperty 'data'
273
+
274
+ Joosy.Module.merge @data, @__prepareData(data)
275
+
276
+ @trigger 'changed' if notify
277
+
278
+ null
279
+
280
+ #
281
+ # Prepares raw data: cuts the root node if it exists, runs before filters
282
+ #
283
+ # @param [Hash] data Raw data to prepare
284
+ # @return [Hash]
285
+ #
286
+ __prepareData: (data) ->
287
+ if Object.isObject(data) && Object.keys(data).length == 1 && @__entityName
288
+ name = @__entityName.camelize(false)
289
+ data = data[name] if data[name]
290
+
291
+ if @__beforeLoads?
292
+ data = bl.call(this, data) for bl in @__beforeLoads
293
+
294
+ data
295
+
296
+ __map: (data, name, klass) ->
297
+ if Object.isArray data[name]
298
+ entry = new (klass::__collection()) klass
299
+ entry.load data[name]
300
+ data[name] = entry
301
+ else if Object.isObject data[name]
302
+ data[name] = klass.build data[name]
303
+ data