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

Sign up to get free protection for your applications and to get access to all the features.
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