joosy 1.2.0.alpha.73 → 1.2.0.beta.1

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/Gruntfile.coffee +56 -18
  3. data/bower.json +1 -1
  4. data/build/joosy/form.js +1 -0
  5. data/build/joosy/resources.js +1 -0
  6. data/build/joosy.js +2 -2774
  7. data/package.json +5 -4
  8. data/source/joosy/application.coffee +9 -7
  9. data/source/joosy/{extensions/resources-form/form.coffee → form.coffee} +58 -51
  10. data/source/joosy/helpers/form.coffee +241 -0
  11. data/source/joosy/helpers/index.coffee +3 -0
  12. data/source/joosy/helpers/routes.coffee +3 -1
  13. data/source/joosy/helpers/view.coffee +9 -9
  14. data/source/joosy/joosy.coffee +3 -5
  15. data/source/joosy/module.coffee +9 -4
  16. data/source/joosy/modules/dom.coffee +33 -31
  17. data/source/joosy/modules/events.coffee +24 -20
  18. data/source/joosy/modules/filters.coffee +38 -35
  19. data/source/joosy/modules/page/title.coffee +3 -3
  20. data/source/joosy/modules/renderer.coffee +23 -18
  21. data/source/joosy/modules/resources/identity_map.coffee +45 -0
  22. data/source/joosy/modules/resources/model.coffee +146 -0
  23. data/source/joosy/modules/widgets_manager.coffee +8 -8
  24. data/source/joosy/resources/array.coffee +0 -5
  25. data/source/joosy/resources/hash.coffee +8 -13
  26. data/source/joosy/resources/index.coffee +2 -0
  27. data/source/joosy/{extensions/resources → resources}/rest.coffee +48 -19
  28. data/source/joosy/resources/scalar.coffee +8 -10
  29. data/source/joosy/router.coffee +13 -12
  30. data/source/joosy/templaters/jst.coffee +3 -2
  31. data/source/joosy/widget.coffee +17 -15
  32. data/source/joosy.coffee +2 -0
  33. data/source/vendor/es5-shim.js +1316 -0
  34. data/source/vendor/inflections.js +598 -0
  35. data/source/vendor/metamorph.js +457 -0
  36. data/spec/helpers/matchers.coffee +4 -4
  37. data/spec/joosy/core/application_spec.coffee +1 -1
  38. data/spec/joosy/core/helpers/view_spec.coffee +2 -2
  39. data/spec/joosy/core/joosy_spec.coffee +8 -4
  40. data/spec/joosy/core/modules/dom_spec.coffee +7 -7
  41. data/spec/joosy/core/modules/events_spec.coffee +2 -2
  42. data/spec/joosy/core/modules/filters_spec.coffee +7 -8
  43. data/spec/joosy/core/modules/module_spec.coffee +5 -5
  44. data/spec/joosy/core/router_spec.coffee +3 -3
  45. data/spec/joosy/core/widget_spec.coffee +6 -6
  46. data/spec/joosy/environments/amd_spec.coffee +4 -2
  47. data/spec/joosy/environments/global_spec.coffee +1 -1
  48. data/spec/joosy/{extensions/form → form}/form_spec.coffee +9 -16
  49. data/spec/joosy/{extensions/form → form}/helpers/forms_spec.coffee +5 -5
  50. data/spec/joosy/{core/resources → resources}/array_spec.coffee +2 -2
  51. data/spec/joosy/{core/resources → resources}/hash_spec.coffee +0 -8
  52. data/spec/joosy/{core/modules/resources → resources/modules}/cacher_spec.coffee +0 -0
  53. data/spec/joosy/resources/modules/identity_map_spec.coffee +47 -0
  54. data/spec/joosy/{extensions/resources/base_spec.coffee → resources/modules/model_spec.coffee} +28 -48
  55. data/spec/joosy/{extensions/resources → resources}/rest_spec.coffee +29 -22
  56. data/spec/joosy/{core/resources → resources}/scalar_spec.coffee +8 -8
  57. data/templates/application/application.coffee.tt +0 -2
  58. data/templates/environment/app/haml/index.haml +2 -2
  59. data/templates/environment/package.json +1 -1
  60. metadata +23 -19
  61. data/build/joosy/extensions/resources-form.js +0 -590
  62. data/build/joosy/extensions/resources.js +0 -561
  63. data/source/joosy/extensions/resources/base.coffee +0 -282
  64. data/source/joosy/extensions/resources/index.coffee +0 -1
  65. data/source/joosy/extensions/resources-form/helpers/form.coffee +0 -104
  66. data/source/joosy/extensions/resources-form/index.coffee +0 -1
  67. data/source/metamorph.coffee +0 -410
@@ -1,5 +1,3 @@
1
- #= require joosy/modules/resources/cacher
2
-
3
1
  class Joosy.Resources.Hash extends Joosy.Function
4
2
 
5
3
  @include Joosy.Modules.Events
@@ -11,7 +9,11 @@ class Joosy.Resources.Hash extends Joosy.Function
11
9
  return super ->
12
10
  @__fillData data, false
13
11
 
14
- get: (path) ->
12
+ load: (data) ->
13
+ @__fillData data
14
+ @
15
+
16
+ __get: (path) ->
15
17
  [instance, property] = @__callTarget path, true
16
18
 
17
19
  return undefined unless instance
@@ -21,7 +23,7 @@ class Joosy.Resources.Hash extends Joosy.Function
21
23
  else
22
24
  instance[property]
23
25
 
24
- set: (path, value) ->
26
+ __set: (path, value) ->
25
27
  [instance, property] = @__callTarget path
26
28
 
27
29
  if instance instanceof Joosy.Resources.Hash
@@ -32,18 +34,11 @@ class Joosy.Resources.Hash extends Joosy.Function
32
34
  @trigger 'changed'
33
35
  value
34
36
 
35
- load: (data) ->
36
- @__fillData data
37
- @
38
-
39
- clone: (callback) ->
40
- new @constructor Object.clone(@data, true)
41
-
42
37
  __call: (path, value) ->
43
38
  if arguments.length > 1
44
- @set path, value
39
+ @__set path, value
45
40
  else
46
- @get path
41
+ @__get path
47
42
 
48
43
  #
49
44
  # Locates the actual instance of attribute path `foo.bar` from get/set
@@ -0,0 +1,2 @@
1
+ #= require_tree ./
2
+ #= require_tree ../modules/resources
@@ -1,9 +1,22 @@
1
- #= require ./base
1
+ #= require ./hash
2
+ #= require joosy/modules/resources/model
2
3
 
3
4
  #
4
5
  # Resource with REST/JSON backend
5
6
  #
6
- class Joosy.Resources.REST extends Joosy.Resources.Base
7
+ class Joosy.Resources.REST extends Joosy.Resources.Hash
8
+
9
+ @include Joosy.Modules.Resources.Model
10
+
11
+ @registerPlainFilters 'beforeSave'
12
+
13
+ @beforeLoad (data) ->
14
+ if data.constructor == Object && Object.keys(data).length == 1 && @__entityName
15
+ name = inflection.camelize(@__entityName, true)
16
+ data = data[name] if data[name]
17
+
18
+ data
19
+
7
20
 
8
21
  @requestOptions: (options) ->
9
22
  @::__requestOptions = options
@@ -23,7 +36,7 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
23
36
  # Makes needed changes with clone/wrapper for @at method to extend its' path
24
37
  #
25
38
  @__atWrapper: (definer, args...) ->
26
- if args.length == 1 && Object.isArray(args[0])
39
+ if args.length == 1 && args[0] instanceof Array
27
40
  @__atWrapper(definer, args[0]...)
28
41
  else
29
42
  definer (clone) =>
@@ -33,7 +46,7 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
33
46
  else
34
47
  arg.replace(/^\/?/, '/')
35
48
  , ''
36
- clone.__source += '/' + @::__entityName.pluralize()
49
+ clone.__source += '/' + inflection.pluralize(@::__entityName)
37
50
 
38
51
  #
39
52
  # Creates the proxy of current resource binded as a child of given entity
@@ -45,11 +58,11 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
45
58
  #
46
59
  # @note accepts both array notation (Comment.at(['admin', @blog, @post])) and args notation (Comment.at('admin', @blog, @post))
47
60
  #
48
- @at: (args...) ->
61
+ @at: ->
49
62
  @__atWrapper (callback) =>
50
63
  class Clone extends @
51
64
  callback(@)
52
- , args...
65
+ , arguments...
53
66
 
54
67
 
55
68
  #
@@ -69,7 +82,7 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
69
82
  # Interpolates path with masks by given array of params
70
83
  #
71
84
  __interpolatePath: (source, ids) ->
72
- ids = [ids] unless Object.isArray(ids)
85
+ ids = [ids] unless ids instanceof Array
73
86
  ids.reduce (path, id) ->
74
87
  id = id.id() if id instanceof Joosy.Resources.REST
75
88
  path.replace /:[^\/]+/, id
@@ -98,7 +111,8 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
98
111
  # Resource.collectionPath(['admin', Resource.build 1]) # /admin/resources/1/resources
99
112
  #
100
113
  collectionPath: (ids=[], options={}) ->
101
- if Object.isObject(ids)
114
+ # (options) ->
115
+ if ids.constructor == Object
102
116
  options = ids
103
117
  ids = []
104
118
 
@@ -111,7 +125,7 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
111
125
  else
112
126
  path = '/'
113
127
  path += @constructor.__namespace__.map(String::underscore).join('/') + '/' if @constructor.__namespace__.length > 0
114
- path += @__entityName.pluralize()
128
+ path += inflection.pluralize(@__entityName)
115
129
 
116
130
  path += "/#{options.action}" if options.action
117
131
  path
@@ -140,19 +154,19 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
140
154
  # Resource.memberPath(['admin', Resource.build 1]) # /admin/resources/1/resources/2
141
155
  #
142
156
  memberPath: (ids=[], options={}) ->
143
- if Object.isObject(ids)
157
+ if ids.constructor == Object
144
158
  options = ids
145
159
  ids = []
146
160
 
147
161
  return options.url if options.url
148
162
 
149
- ids = [ids] unless Object.isArray(ids)
163
+ ids = [ids] unless ids instanceof Array
150
164
  id = @id() || ids.pop()
151
165
 
152
166
  action = options.action
153
167
 
154
168
  ids.push @id()
155
- path = @collectionPath(ids, Object.merge(options, action: undefined)) + "/#{id}"
169
+ path = @collectionPath(ids, Joosy.Module.merge(options, action: undefined)) + "/#{id}"
156
170
  path += "/#{action}" if action?
157
171
  path
158
172
 
@@ -281,12 +295,13 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
281
295
  @find: (where, options={}, callback=false) ->
282
296
  [options, callback] = @::__extractOptionsAndCallback(options, callback)
283
297
 
284
- id = if where instanceof Array
298
+ result = {}
299
+ result[@::__primaryKey] = if where instanceof Array
285
300
  where[where.length-1]
286
301
  else
287
302
  where
288
303
 
289
- result = @build id
304
+ result = @build result
290
305
 
291
306
  # Substitute interpolation mask with actual path
292
307
  if where instanceof Array && where.length > 1
@@ -312,17 +327,17 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
312
327
  # @option options [Hash] params Passes the given params to the query
313
328
  #
314
329
  @all: (where, options={}, callback=false) ->
315
- if Object.isFunction(where) || Object.isObject(where)
330
+ if typeof(where) == 'function' || where.constructor == Object
316
331
  [options, callback] = @::__extractOptionsAndCallback(where, options)
317
332
  where = []
318
333
  else
319
334
  [options, callback] = @::__extractOptionsAndCallback(options, callback)
320
335
 
321
- result = new Joosy.Resources.Array
336
+ result = new @::__collection
322
337
 
323
338
  @__query @collectionPath(where, options), 'GET', options.params, (error, rawData, xhr) =>
324
339
  if (data = rawData)?
325
- if Object.isObject(data) && !(data = data[@::__entityName.pluralize()])
340
+ if data.constructor == Object && !(data = data[inflection.pluralize(@::__entityName)])
326
341
  throw new Error "Invalid data for `all` received: #{JSON.stringify(data)}"
327
342
 
328
343
  data = data.map (x) =>
@@ -337,6 +352,16 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
337
352
 
338
353
  result
339
354
 
355
+ save: (callback) ->
356
+ if @id()
357
+ @put {params: @__applyBeforeSaves(@data)}, (error, data) =>
358
+ @load data unless error
359
+ callback? error, @
360
+ else
361
+ @constructor.post {params: @__applyBeforeSaves(@data)}, (error, data) =>
362
+ @load data unless error
363
+ callback? error, @
364
+
340
365
  #
341
366
  # Wrapper for AJAX request
342
367
  #
@@ -348,7 +373,7 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
348
373
  cache: false
349
374
  dataType: 'json'
350
375
 
351
- if Object.isFunction(callback)
376
+ if typeof(callback) == 'function'
352
377
  options.success = (data, _, xhr) -> callback(false, data, xhr)
353
378
  options.error = (xhr) -> callback(xhr)
354
379
  else
@@ -365,7 +390,11 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
365
390
  # utility function for better API support for unrequired first options parameter
366
391
  #
367
392
  __extractOptionsAndCallback: (options, callback) ->
368
- if Object.isFunction(options)
393
+ if typeof(options) == 'function'
369
394
  callback = options
370
395
  options = {}
371
396
  [options, callback]
397
+
398
+ # AMD wrapper
399
+ if define?.amd?
400
+ define 'joosy/resources/rest', -> Joosy.Resources.REST
@@ -1,5 +1,3 @@
1
- #= require joosy/modules/resources/cacher
2
-
3
1
  class Joosy.Resources.Scalar extends Joosy.Function
4
2
 
5
3
  @include Joosy.Modules.Events
@@ -11,12 +9,6 @@ class Joosy.Resources.Scalar extends Joosy.Function
11
9
  return super ->
12
10
  @load value
13
11
 
14
- get: ->
15
- @value
16
-
17
- set: (@value) ->
18
- @trigger 'changed'
19
-
20
12
  load: (value) ->
21
13
  @value = @__applyBeforeLoads(value)
22
14
  @trigger 'changed'
@@ -27,9 +19,15 @@ class Joosy.Resources.Scalar extends Joosy.Function
27
19
 
28
20
  __call: ->
29
21
  if arguments.length > 0
30
- @set arguments[0]
22
+ @__set arguments[0]
31
23
  else
32
- @get()
24
+ @__get()
25
+
26
+ __get: ->
27
+ @value
28
+
29
+ __set: (@value) ->
30
+ @trigger 'changed'
33
31
 
34
32
  valueOf: ->
35
33
  @value.valueOf()
@@ -93,7 +93,8 @@ class Joosy.Router extends Joosy.Module
93
93
  # @option [Hash] options "as", prefixes all other "as" commands
94
94
  # @param [Function] block callback for child commands
95
95
  namespace: (name, options={}, block) ->
96
- if Object.isFunction(options)
96
+ # (name, block) ->
97
+ if arguments.length == 2
97
98
  block = options
98
99
  options = {}
99
100
 
@@ -106,9 +107,9 @@ class Joosy.Router extends Joosy.Module
106
107
  # @param [Object] routes Set of routes in inner format (see class description)
107
108
  #
108
109
  @map: (routes, namespace) ->
109
- Object.each routes, (path, to) =>
110
+ for path, to of routes
110
111
  path = namespace + '/' + path if namespace?
111
- if Object.isFunction(to) || to.prototype
112
+ if typeof(to) == 'function' || to.prototype
112
113
  @compileRoute path, to
113
114
  else
114
115
  @map to, path
@@ -118,7 +119,7 @@ class Joosy.Router extends Joosy.Module
118
119
  #
119
120
  # @param [Function] block callback for child commands
120
121
  #
121
- @draw: (block)->
122
+ @draw: (block) ->
122
123
  Drawer.run block
123
124
 
124
125
  #
@@ -276,8 +277,9 @@ class Joosy.Router extends Joosy.Module
276
277
  helper = (options) ->
277
278
  result = path
278
279
 
279
- path.match(/\/:[^\/]+/g)?.each? (param) ->
280
- result = result.replace(param.substr(1), options[param.substr(2)])
280
+ if match = path.match(/\/:[^\/]+/g)
281
+ for param in match
282
+ result = result.replace(param.substr(1), options[param.substr(2)])
281
283
 
282
284
  if Joosy.Router.config.html5
283
285
  "#{Joosy.Router.config.prefix}#{result}"
@@ -299,14 +301,13 @@ class Joosy.Router extends Joosy.Module
299
301
  # Collect parameters from route placeholers
300
302
  match.shift() # First entry is full route regexp match that should be just skipped
301
303
 
302
- route?.capture?.each (key) ->
303
- params[key] = decodeURIComponent match.shift()
304
+ if captures = route?.capture
305
+ params[key] = decodeURIComponent match.shift() for key in captures
304
306
 
305
307
  # Collect parameters from URL query section
306
- query.each (entry) ->
307
- unless entry.isBlank()
308
- [key, value] = entry.split '='
309
- params[key] = value
308
+ for entry in query when entry.length > 0
309
+ [key, value] = entry.split '='
310
+ params[key] = value
310
311
 
311
312
  params
312
313
 
@@ -39,10 +39,11 @@ class Joosy.Templaters.JST
39
39
  # @param [String] entity Entity to lookup template path by its namespace
40
40
  #
41
41
  resolveTemplate: (section, template, entity) ->
42
- if template.startsWith '/'
42
+ if template[0] == '/'
43
43
  return template.substr 1
44
44
 
45
- path = entity.constructor?.__namespace__?.map('underscore') || []
45
+ path = entity.constructor?.__namespace__?.map (x) -> inflection.underscore(x)
46
+ path ||= []
46
47
  path.unshift section
47
48
 
48
49
  "#{path.join '/'}/#{template}"
@@ -130,8 +130,8 @@ class Joosy.Widget extends Joosy.Module
130
130
  #
131
131
  @mapWidgets: (map) ->
132
132
  unless @::hasOwnProperty "__widgets"
133
- @::__widgets = Object.clone(@.__super__.__widgets) || {}
134
- Object.merge @::__widgets, map
133
+ @::__widgets = Joosy.Module.merge {}, @.__super__.__widgets
134
+ Joosy.Module.merge @::__widgets, map
135
135
 
136
136
  #
137
137
  # Declares widget as indepent changing the way it behaves during the bootstrap
@@ -156,7 +156,7 @@ class Joosy.Widget extends Joosy.Module
156
156
  # @param [Joosy.Widget] widget Class or object of Joosy.Widget to register
157
157
  #
158
158
  registerWidget: ($container, widget) ->
159
- if Object.isString $container
159
+ if typeof($container) == 'string'
160
160
  $container = @__normalizeSelector($container)
161
161
 
162
162
  widget = @__normalizeWidget(widget)
@@ -251,12 +251,13 @@ class Joosy.Widget extends Joosy.Module
251
251
  @data = {}
252
252
 
253
253
  @synchronize (context) =>
254
- Object.each nestingMap, (selector, section) ->
255
- section.instance.__fetch(section.nested)
254
+ for selector, section of nestingMap
255
+ do (selector, section) ->
256
+ section.instance.__fetch(section.nested)
256
257
 
257
- if !section.instance.__independent
258
- context.do (done) ->
259
- section.instance.wait 'section:fetched', done
258
+ if !section.instance.__independent
259
+ context.do (done) ->
260
+ section.instance.wait 'section:fetched', done
260
261
 
261
262
  context.do (done) =>
262
263
  @__runFetchs [], done
@@ -287,13 +288,14 @@ class Joosy.Widget extends Joosy.Module
287
288
 
288
289
  @__load()
289
290
 
290
- Object.each nestingMap, (selector, section) =>
291
- $container = @__normalizeSelector(selector)
291
+ for selector, section of nestingMap
292
+ do (selector, section) =>
293
+ $container = @__normalizeSelector(selector)
292
294
 
293
- if !section.instance.__independent || section.instance.__triggeredEvents?['section:fetched']
294
- section.instance.__paint @, section.nested, $container
295
- else
296
- section.instance.__bootstrap @, section.nested, $container, false
295
+ if !section.instance.__independent || section.instance.__triggeredEvents?['section:fetched']
296
+ section.instance.__paint @, section.nested, $container
297
+ else
298
+ section.instance.__bootstrap @, section.nested, $container, false
297
299
 
298
300
  #
299
301
  # Initializes section that was injected into DOM
@@ -347,7 +349,7 @@ class Joosy.Widget extends Joosy.Module
347
349
  # Besides already being instance it cann be either class or lambda
348
350
  #
349
351
  __normalizeWidget: (widget) ->
350
- if Object.isFunction(widget) && !Joosy.Module.hasAncestor(widget, Joosy.Widget)
352
+ if typeof(widget) == 'function' && !Joosy.Module.hasAncestor(widget, Joosy.Widget)
351
353
  widget = widget.call(@)
352
354
 
353
355
  if Joosy.Module.hasAncestor widget, Joosy.Widget
data/source/joosy.coffee CHANGED
@@ -1 +1,3 @@
1
+ #= require vendor/es5-shim
2
+ #= require vendor/inflections
1
3
  #= require joosy/application