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.
- checksums.yaml +4 -4
- data/Gruntfile.coffee +56 -18
- data/bower.json +1 -1
- data/build/joosy/form.js +1 -0
- data/build/joosy/resources.js +1 -0
- data/build/joosy.js +2 -2774
- data/package.json +5 -4
- data/source/joosy/application.coffee +9 -7
- data/source/joosy/{extensions/resources-form/form.coffee → form.coffee} +58 -51
- data/source/joosy/helpers/form.coffee +241 -0
- data/source/joosy/helpers/index.coffee +3 -0
- data/source/joosy/helpers/routes.coffee +3 -1
- data/source/joosy/helpers/view.coffee +9 -9
- data/source/joosy/joosy.coffee +3 -5
- data/source/joosy/module.coffee +9 -4
- data/source/joosy/modules/dom.coffee +33 -31
- data/source/joosy/modules/events.coffee +24 -20
- data/source/joosy/modules/filters.coffee +38 -35
- data/source/joosy/modules/page/title.coffee +3 -3
- data/source/joosy/modules/renderer.coffee +23 -18
- data/source/joosy/modules/resources/identity_map.coffee +45 -0
- data/source/joosy/modules/resources/model.coffee +146 -0
- data/source/joosy/modules/widgets_manager.coffee +8 -8
- data/source/joosy/resources/array.coffee +0 -5
- data/source/joosy/resources/hash.coffee +8 -13
- data/source/joosy/resources/index.coffee +2 -0
- data/source/joosy/{extensions/resources → resources}/rest.coffee +48 -19
- data/source/joosy/resources/scalar.coffee +8 -10
- data/source/joosy/router.coffee +13 -12
- data/source/joosy/templaters/jst.coffee +3 -2
- data/source/joosy/widget.coffee +17 -15
- data/source/joosy.coffee +2 -0
- data/source/vendor/es5-shim.js +1316 -0
- data/source/vendor/inflections.js +598 -0
- data/source/vendor/metamorph.js +457 -0
- data/spec/helpers/matchers.coffee +4 -4
- data/spec/joosy/core/application_spec.coffee +1 -1
- data/spec/joosy/core/helpers/view_spec.coffee +2 -2
- data/spec/joosy/core/joosy_spec.coffee +8 -4
- data/spec/joosy/core/modules/dom_spec.coffee +7 -7
- data/spec/joosy/core/modules/events_spec.coffee +2 -2
- data/spec/joosy/core/modules/filters_spec.coffee +7 -8
- data/spec/joosy/core/modules/module_spec.coffee +5 -5
- data/spec/joosy/core/router_spec.coffee +3 -3
- data/spec/joosy/core/widget_spec.coffee +6 -6
- data/spec/joosy/environments/amd_spec.coffee +4 -2
- data/spec/joosy/environments/global_spec.coffee +1 -1
- data/spec/joosy/{extensions/form → form}/form_spec.coffee +9 -16
- data/spec/joosy/{extensions/form → form}/helpers/forms_spec.coffee +5 -5
- data/spec/joosy/{core/resources → resources}/array_spec.coffee +2 -2
- data/spec/joosy/{core/resources → resources}/hash_spec.coffee +0 -8
- data/spec/joosy/{core/modules/resources → resources/modules}/cacher_spec.coffee +0 -0
- data/spec/joosy/resources/modules/identity_map_spec.coffee +47 -0
- data/spec/joosy/{extensions/resources/base_spec.coffee → resources/modules/model_spec.coffee} +28 -48
- data/spec/joosy/{extensions/resources → resources}/rest_spec.coffee +29 -22
- data/spec/joosy/{core/resources → resources}/scalar_spec.coffee +8 -8
- data/templates/application/application.coffee.tt +0 -2
- data/templates/environment/app/haml/index.haml +2 -2
- data/templates/environment/package.json +1 -1
- metadata +23 -19
- data/build/joosy/extensions/resources-form.js +0 -590
- data/build/joosy/extensions/resources.js +0 -561
- data/source/joosy/extensions/resources/base.coffee +0 -282
- data/source/joosy/extensions/resources/index.coffee +0 -1
- data/source/joosy/extensions/resources-form/helpers/form.coffee +0 -104
- data/source/joosy/extensions/resources-form/index.coffee +0 -1
- 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
|
-
|
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
|
-
|
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
|
-
@
|
39
|
+
@__set path, value
|
45
40
|
else
|
46
|
-
@
|
41
|
+
@__get path
|
47
42
|
|
48
43
|
#
|
49
44
|
# Locates the actual instance of attribute path `foo.bar` from get/set
|
@@ -1,9 +1,22 @@
|
|
1
|
-
#= require ./
|
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.
|
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 &&
|
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 += '/' +
|
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:
|
61
|
+
@at: ->
|
49
62
|
@__atWrapper (callback) =>
|
50
63
|
class Clone extends @
|
51
64
|
callback(@)
|
52
|
-
,
|
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
|
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
|
-
|
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 +=
|
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
|
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
|
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,
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
@
|
22
|
+
@__set arguments[0]
|
31
23
|
else
|
32
|
-
@
|
24
|
+
@__get()
|
25
|
+
|
26
|
+
__get: ->
|
27
|
+
@value
|
28
|
+
|
29
|
+
__set: (@value) ->
|
30
|
+
@trigger 'changed'
|
33
31
|
|
34
32
|
valueOf: ->
|
35
33
|
@value.valueOf()
|
data/source/joosy/router.coffee
CHANGED
@@ -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
|
-
|
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
|
-
|
110
|
+
for path, to of routes
|
110
111
|
path = namespace + '/' + path if namespace?
|
111
|
-
if
|
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)
|
280
|
-
|
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
|
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
|
307
|
-
|
308
|
-
|
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
|
42
|
+
if template[0] == '/'
|
43
43
|
return template.substr 1
|
44
44
|
|
45
|
-
path = entity.constructor?.__namespace__?.map(
|
45
|
+
path = entity.constructor?.__namespace__?.map (x) -> inflection.underscore(x)
|
46
|
+
path ||= []
|
46
47
|
path.unshift section
|
47
48
|
|
48
49
|
"#{path.join '/'}/#{template}"
|
data/source/joosy/widget.coffee
CHANGED
@@ -130,8 +130,8 @@ class Joosy.Widget extends Joosy.Module
|
|
130
130
|
#
|
131
131
|
@mapWidgets: (map) ->
|
132
132
|
unless @::hasOwnProperty "__widgets"
|
133
|
-
@::__widgets =
|
134
|
-
|
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
|
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
|
-
|
255
|
-
|
254
|
+
for selector, section of nestingMap
|
255
|
+
do (selector, section) ->
|
256
|
+
section.instance.__fetch(section.nested)
|
256
257
|
|
257
|
-
|
258
|
-
|
259
|
-
|
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
|
-
|
291
|
-
|
291
|
+
for selector, section of nestingMap
|
292
|
+
do (selector, section) =>
|
293
|
+
$container = @__normalizeSelector(selector)
|
292
294
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
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
|
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