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.
- data/.codoopts +5 -0
- data/.gitignore +2 -0
- data/Gemfile +15 -2
- data/Gemfile.lock +102 -81
- data/Guardfile +16 -16
- data/LICENSE +22 -0
- data/MIT-LICENSE +2 -2
- data/README.md +118 -0
- data/app/assets/javascripts/joosy/core/application.js.coffee +53 -0
- data/app/assets/javascripts/joosy/core/form.js.coffee +338 -0
- data/app/assets/javascripts/joosy/core/helpers/form.js.coffee +72 -0
- data/app/assets/javascripts/joosy/core/helpers/view.js.coffee +42 -0
- data/app/assets/javascripts/joosy/core/helpers/widgets.js.coffee +14 -0
- data/app/assets/javascripts/joosy/core/joosy.js.coffee +184 -0
- data/app/assets/javascripts/joosy/core/layout.js.coffee +168 -0
- data/app/assets/javascripts/joosy/core/modules/container.js.coffee +124 -0
- data/app/assets/javascripts/joosy/core/modules/events.js.coffee +122 -0
- data/app/assets/javascripts/joosy/core/modules/filters.js.coffee +39 -0
- data/app/assets/javascripts/joosy/core/modules/log.js.coffee +36 -0
- data/app/assets/javascripts/joosy/core/modules/module.js.coffee +117 -0
- data/app/assets/javascripts/joosy/core/modules/renderer.js.coffee +200 -0
- data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +46 -0
- data/app/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +87 -0
- data/app/assets/javascripts/joosy/core/page.js.coffee +387 -0
- data/app/assets/javascripts/joosy/core/preloader.js.coffee +13 -0
- data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +175 -0
- data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +303 -0
- data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +244 -0
- data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +24 -0
- data/app/assets/javascripts/joosy/core/router.js.coffee +201 -0
- data/app/assets/javascripts/joosy/core/templaters/rails_jst.js.coffee +37 -0
- data/app/assets/javascripts/joosy/core/widget.js.coffee +85 -0
- data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +169 -0
- data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +56 -0
- data/{vendor → app}/assets/javascripts/joosy.js.coffee +0 -1
- data/app/helpers/joosy/sprockets_helper.rb +39 -12
- data/joosy.gemspec +4 -3
- data/lib/joosy/rails/engine.rb +12 -1
- data/lib/joosy/rails/version.rb +2 -2
- data/lib/joosy.rb +9 -0
- data/lib/rails/generators/joosy/application_generator.rb +15 -3
- data/lib/rails/generators/joosy/joosy_base.rb +2 -2
- data/lib/rails/generators/joosy/layout_generator.rb +8 -1
- data/lib/rails/generators/joosy/page_generator.rb +21 -6
- data/lib/rails/generators/joosy/preloader_generator.rb +14 -7
- data/lib/rails/generators/joosy/resource_generator.rb +29 -0
- data/lib/rails/generators/joosy/templates/app/helpers/application.js.coffee +4 -0
- data/lib/rails/generators/joosy/templates/app/layouts/application.js.coffee +1 -0
- data/lib/rails/generators/joosy/templates/app/layouts/template.js.coffee +1 -1
- data/lib/rails/generators/joosy/templates/app/pages/application.js.coffee +1 -1
- data/lib/rails/generators/joosy/templates/app/pages/template.js.coffee +3 -3
- data/lib/rails/generators/joosy/templates/app/pages/welcome/index.js.coffee +22 -0
- data/lib/rails/generators/joosy/templates/app/resources/template.js.coffee +2 -0
- data/lib/rails/generators/joosy/templates/app/routes.js.coffee +7 -1
- data/lib/rails/generators/joosy/templates/app/templates/layouts/application.jst.hamlc +2 -0
- data/lib/rails/generators/joosy/templates/app/templates/pages/welcome/index.jst.hamlc +7 -0
- data/lib/rails/generators/joosy/templates/app/widgets/template.js.coffee +2 -2
- data/lib/rails/generators/joosy/templates/app.js.coffee +4 -0
- data/lib/rails/generators/joosy/templates/app_preloader.js.coffee.erb +9 -12
- data/lib/rails/generators/joosy/templates/app_resources_predefiner.js.coffee.erb +11 -0
- data/lib/rails/generators/joosy/templates/preload.html.erb +5 -6
- data/lib/rails/generators/joosy/templates/preload.html.haml +3 -5
- data/lib/rails/generators/joosy/widget_generator.rb +8 -1
- data/lib/rails/resources_with_joosy.rb +11 -0
- data/spec/javascripts/helpers/spec_helper.js.coffee +25 -0
- data/spec/javascripts/joosy/core/application_spec.js.coffee +40 -0
- data/spec/javascripts/joosy/core/form_spec.js.coffee +200 -0
- data/spec/javascripts/joosy/core/helpers/forms_spec.js.coffee +103 -0
- data/spec/javascripts/joosy/core/helpers/view_spec.js.coffee +10 -0
- data/spec/javascripts/joosy/core/joosy_spec.js.coffee +97 -0
- data/spec/javascripts/joosy/core/layout_spec.js.coffee +50 -0
- data/spec/javascripts/joosy/core/modules/container_spec.js.coffee +32 -27
- data/spec/javascripts/joosy/core/modules/events_spec.js.coffee +55 -18
- data/spec/javascripts/joosy/core/modules/filters_spec.js.coffee +28 -27
- data/spec/javascripts/joosy/core/modules/log_spec.js.coffee +3 -3
- data/spec/javascripts/joosy/core/modules/module_spec.js.coffee +6 -15
- data/spec/javascripts/joosy/core/modules/renderer_spec.js.coffee +203 -0
- data/spec/javascripts/joosy/core/modules/time_manager_spec.js.coffee +12 -7
- data/spec/javascripts/joosy/core/modules/widget_manager_spec.js.coffee +31 -17
- data/spec/javascripts/joosy/core/page_spec.js.coffee +178 -0
- data/spec/javascripts/joosy/core/resource/collection_spec.js.coffee +84 -0
- data/spec/javascripts/joosy/core/resource/generic_spec.js.coffee +149 -0
- data/spec/javascripts/joosy/core/resource/rest_collection_spec.js.coffee +31 -0
- data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +171 -0
- data/spec/javascripts/joosy/core/router_spec.js.coffee +143 -0
- data/spec/javascripts/joosy/core/templaters/rails_jst_spec.js.coffee +25 -0
- data/spec/javascripts/joosy/core/widget_spec.js.coffee +40 -0
- data/spec/javascripts/joosy/preloaders/caching_spec.js.coffee +36 -0
- data/spec/javascripts/joosy/preloaders/inline_spec.js.coffee +16 -0
- data/spec/javascripts/support/assets/coolface.jpg +0 -0
- data/spec/javascripts/support/assets/okay.jpg +0 -0
- data/spec/javascripts/support/assets/test.js +1 -0
- data/spec/javascripts/support/sinon-ie-1.3.1.js +82 -0
- data/vendor/assets/javascripts/jquery.form.js +978 -963
- data/vendor/assets/javascripts/metamorph.js +409 -0
- data/vendor/assets/javascripts/sugar.js +1057 -366
- metadata +95 -50
- data/README.rdoc +0 -3
- data/lib/joosy/forms.rb +0 -47
- data/lib/joosy-rails.rb +0 -5
- data/lib/rails/generators/joosy/templates/preload.html.slim +0 -21
- data/tmp/javascripts/.gitignore +0 -1
- data/tmp/spec/javascripts/helpers/.gitignore +0 -1
- data/vendor/assets/javascripts/base64.js +0 -135
- data/vendor/assets/javascripts/inflection.js +0 -656
- data/vendor/assets/javascripts/joosy/core/application.js.coffee +0 -26
- data/vendor/assets/javascripts/joosy/core/form.js.coffee +0 -87
- data/vendor/assets/javascripts/joosy/core/joosy.js.coffee +0 -62
- data/vendor/assets/javascripts/joosy/core/layout.js.coffee +0 -38
- data/vendor/assets/javascripts/joosy/core/modules/container.js.coffee +0 -51
- data/vendor/assets/javascripts/joosy/core/modules/events.js.coffee +0 -17
- data/vendor/assets/javascripts/joosy/core/modules/filters.js.coffee +0 -39
- data/vendor/assets/javascripts/joosy/core/modules/log.js.coffee +0 -12
- data/vendor/assets/javascripts/joosy/core/modules/module.js.coffee +0 -28
- data/vendor/assets/javascripts/joosy/core/modules/time_manager.js.coffee +0 -23
- data/vendor/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +0 -45
- data/vendor/assets/javascripts/joosy/core/page.js.coffee +0 -136
- data/vendor/assets/javascripts/joosy/core/resource/rest.js.coffee +0 -69
- data/vendor/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +0 -42
- data/vendor/assets/javascripts/joosy/core/router.js.coffee +0 -75
- data/vendor/assets/javascripts/joosy/core/widget.js.coffee +0 -35
- data/vendor/assets/javascripts/joosy/preloader/development.js.coffee +0 -27
- data/vendor/assets/javascripts/joosy/preloader/production.js.coffee +0 -84
@@ -0,0 +1,244 @@
|
|
1
|
+
#
|
2
|
+
# Resource with REST/JSON backend
|
3
|
+
#
|
4
|
+
class Joosy.Resource.REST extends Joosy.Resource.Generic
|
5
|
+
|
6
|
+
#
|
7
|
+
# Implements `@collection` default behavior.
|
8
|
+
# Changes the default fallback to Joosy.Resource.RESTCollection.
|
9
|
+
#
|
10
|
+
__collection: ->
|
11
|
+
named = @__entityName.camelize().pluralize() + 'Collection'
|
12
|
+
if window[named] then window[named] else Joosy.Resource.RESTCollection
|
13
|
+
|
14
|
+
#
|
15
|
+
# Builds member path based on the given id.
|
16
|
+
#
|
17
|
+
# @param [String] id ID of entity to build member path for
|
18
|
+
# @param [Hash] options See {Joosy.Resource.REST.find} for possible options
|
19
|
+
#
|
20
|
+
# @example Basic usage
|
21
|
+
# Resource.memberPath(1, from: 'foo') # /resources/1/foo
|
22
|
+
#
|
23
|
+
@memberPath: (id, options={}) ->
|
24
|
+
path = ("/" + @::__entityName.pluralize())
|
25
|
+
path = @__source if @__source? && !options.parent?
|
26
|
+
path += "/#{id}"
|
27
|
+
|
28
|
+
if options.parent instanceof Joosy.Resource.Generic
|
29
|
+
path = options.parent.memberPath() + path
|
30
|
+
else if options.parent?
|
31
|
+
path = options.parent + path
|
32
|
+
|
33
|
+
path += "/#{options.from}" if options.from?
|
34
|
+
path
|
35
|
+
|
36
|
+
#
|
37
|
+
# Builds member path
|
38
|
+
#
|
39
|
+
# @param [Hash] options See {Joosy.Resource.REST.find} for possible options
|
40
|
+
#
|
41
|
+
# @example Basic usage
|
42
|
+
# resource.memberPath(from: 'foo') # /resources/1/foo
|
43
|
+
#
|
44
|
+
memberPath: (options={}) ->
|
45
|
+
@constructor.memberPath @id(), options
|
46
|
+
|
47
|
+
#
|
48
|
+
# Builds collection path
|
49
|
+
#
|
50
|
+
# @param [Hash] options See {Joosy.Resource.REST.find} for possible options
|
51
|
+
#
|
52
|
+
# @example Basic usage
|
53
|
+
# Resource.collectionPath() # /resources/
|
54
|
+
#
|
55
|
+
@collectionPath: (options={}) ->
|
56
|
+
path = ("/" + @::__entityName.pluralize())
|
57
|
+
path = @__source if @__source? && !options.parent?
|
58
|
+
|
59
|
+
if options.parent instanceof Joosy.Resource.Generic
|
60
|
+
path = options.parent.memberPath() + path
|
61
|
+
else if options.parent?
|
62
|
+
path = options.parent + path
|
63
|
+
|
64
|
+
path += "/#{options.from}" if options.from?
|
65
|
+
path
|
66
|
+
|
67
|
+
#
|
68
|
+
# Builds collection path
|
69
|
+
#
|
70
|
+
# @see Joosy.Resource.REST.collectionPath
|
71
|
+
#
|
72
|
+
collectionPath: ->
|
73
|
+
@constructor.collectionPath()
|
74
|
+
|
75
|
+
#
|
76
|
+
# Sends the GET query using collectionPath.
|
77
|
+
# Callback will get parsed JSON object as a parameter.
|
78
|
+
#
|
79
|
+
# @param [Hash] options Options to proxy to collectionPath
|
80
|
+
# @param [Function] callback Resulting callback
|
81
|
+
#
|
82
|
+
@get: (options, callback) ->
|
83
|
+
if Object.isFunction(options)
|
84
|
+
callback = options
|
85
|
+
options = {}
|
86
|
+
@__query @collectionPath(options), 'GET', options.params, callback
|
87
|
+
|
88
|
+
#
|
89
|
+
# Sends the POST query using collectionPath.
|
90
|
+
# Callback will get parsed JSON object as a parameter.
|
91
|
+
#
|
92
|
+
# @param [Hash] options Options to proxy to collectionPath
|
93
|
+
# @param [Function] callback Resulting callback
|
94
|
+
#
|
95
|
+
@post: (options, callback) ->
|
96
|
+
if Object.isFunction(options)
|
97
|
+
callback = options
|
98
|
+
options = {}
|
99
|
+
@__query @collectionPath(options), 'POST', options.params, callback
|
100
|
+
|
101
|
+
#
|
102
|
+
# Sends the PUT query using collectionPath.
|
103
|
+
# Callback will get parsed JSON object as a parameter.
|
104
|
+
#
|
105
|
+
# @param [Hash] options Options to proxy to collectionPath
|
106
|
+
# @param [Function] callback Resulting callback
|
107
|
+
#
|
108
|
+
@put: (options, callback) ->
|
109
|
+
if Object.isFunction(options)
|
110
|
+
callback = options
|
111
|
+
options = {}
|
112
|
+
@__query @collectionPath(options), 'PUT', options.params, callback
|
113
|
+
|
114
|
+
#
|
115
|
+
# Sends the DELETE query using collectionPath.
|
116
|
+
# Callback will get parsed JSON object as a parameter.
|
117
|
+
#
|
118
|
+
# @param [Hash] options Options to proxy to collectionPath
|
119
|
+
# @param [Function] callback Resulting callback
|
120
|
+
#
|
121
|
+
@delete: (options, callback) ->
|
122
|
+
if Object.isFunction(options)
|
123
|
+
callback = options
|
124
|
+
options = {}
|
125
|
+
@__query @collectionPath(options), 'DELETE', options.params, callback
|
126
|
+
|
127
|
+
#
|
128
|
+
# Sends the GET query using memberPath.
|
129
|
+
# Callback will get parsed JSON object as a parameter.
|
130
|
+
#
|
131
|
+
# @param [Hash] options Options to proxy to memberPath
|
132
|
+
# @param [Function] callback Resulting callback
|
133
|
+
#
|
134
|
+
get: (options, callback) ->
|
135
|
+
if Object.isFunction(options)
|
136
|
+
callback = options
|
137
|
+
options = {}
|
138
|
+
@constructor.__query @memberPath(options), 'GET', options.params, callback
|
139
|
+
|
140
|
+
#
|
141
|
+
# Sends the POST query using memberPath.
|
142
|
+
# Callback will get parsed JSON object as a parameter.
|
143
|
+
#
|
144
|
+
# @param [Hash] options Options to proxy to memberPath
|
145
|
+
# @param [Function] callback Resulting callback
|
146
|
+
#
|
147
|
+
post: (options, callback) ->
|
148
|
+
if Object.isFunction(options)
|
149
|
+
callback = options
|
150
|
+
options = {}
|
151
|
+
@constructor.__query @memberPath(options), 'POST', options.params, callback
|
152
|
+
|
153
|
+
#
|
154
|
+
# Sends the PUT query using memberPath.
|
155
|
+
# Callback will get parsed JSON object as a parameter.
|
156
|
+
#
|
157
|
+
# @param [Hash] options Options to proxy to memberPath
|
158
|
+
# @param [Function] callback Resulting callback
|
159
|
+
#
|
160
|
+
put: (options, callback) ->
|
161
|
+
if Object.isFunction(options)
|
162
|
+
callback = options
|
163
|
+
options = {}
|
164
|
+
@constructor.__query @memberPath(options), 'PUT', options.params, callback
|
165
|
+
|
166
|
+
#
|
167
|
+
# Sends the DELETE query using memberPath.
|
168
|
+
# Callback will get parsed JSON object as a parameter.
|
169
|
+
#
|
170
|
+
# @param [Hash] options Options to proxy to memberPath
|
171
|
+
# @param [Function] callback Resulting callback
|
172
|
+
#
|
173
|
+
delete: (options, callback) ->
|
174
|
+
if Object.isFunction(options)
|
175
|
+
callback = options
|
176
|
+
options = {}
|
177
|
+
@constructor.__query @memberPath(options), 'DELETE', options.params, callback
|
178
|
+
|
179
|
+
#
|
180
|
+
# Requests the required resources from backend
|
181
|
+
#
|
182
|
+
# @param [String] where Possible values: 'all', id.
|
183
|
+
# 'all' will query for collection from collectionPath.
|
184
|
+
# Everything else will be considered as an id string and will make resource
|
185
|
+
# query for single instance from memberPath.
|
186
|
+
# @param [Hash] options Path modification options
|
187
|
+
# @param [Function] callback Resulting callback
|
188
|
+
# (will receive retrieved Collection/Resource)
|
189
|
+
#
|
190
|
+
# @option options [Joosy.Resource.REST] parent Sets the given resource as a base path
|
191
|
+
# i.e. /parents/1/resources
|
192
|
+
# @option options [String] parent Sets the given staring as a base path
|
193
|
+
# i.e. /trololo/resources
|
194
|
+
# @option options [String] from Adds the given string as a last path element
|
195
|
+
# i.e. /resources/trololo
|
196
|
+
# @option options [Hash] params Passes the given params to the query
|
197
|
+
#
|
198
|
+
@find: (where, options={}, callback=false) ->
|
199
|
+
if Object.isFunction(options)
|
200
|
+
callback = options
|
201
|
+
options = {}
|
202
|
+
|
203
|
+
if where == 'all'
|
204
|
+
result = new (@::__collection()) this, options
|
205
|
+
|
206
|
+
@__query @collectionPath(options), 'GET', options.params, (data) =>
|
207
|
+
result.load data
|
208
|
+
callback?(result)
|
209
|
+
else
|
210
|
+
result = @build where
|
211
|
+
@__query @memberPath(where, options), 'GET', options.params, (data) =>
|
212
|
+
result.load data
|
213
|
+
callback?(result)
|
214
|
+
|
215
|
+
result
|
216
|
+
|
217
|
+
@__query: (path, method, params, callback) ->
|
218
|
+
options =
|
219
|
+
data: params
|
220
|
+
type: method
|
221
|
+
cache: false
|
222
|
+
dataType: 'json'
|
223
|
+
|
224
|
+
if Object.isFunction(callback)
|
225
|
+
options.success = callback
|
226
|
+
else
|
227
|
+
Joosy.Module.merge options, callback
|
228
|
+
|
229
|
+
$.ajax path, options
|
230
|
+
|
231
|
+
#
|
232
|
+
# Refetches the data from backend and triggers `changed`
|
233
|
+
#
|
234
|
+
# @param [Hash] options See {Joosy.Resource.REST.find} for possible options
|
235
|
+
# @param [Function] callback Resulting callback
|
236
|
+
#
|
237
|
+
reload: (options={}, callback=false) ->
|
238
|
+
if Object.isFunction(options)
|
239
|
+
callback = options
|
240
|
+
options = {}
|
241
|
+
|
242
|
+
@constructor.__query @memberPath(options), 'GET', options.params, (data) =>
|
243
|
+
@load data
|
244
|
+
callback? this
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#
|
2
|
+
# Collection of REST Resources
|
3
|
+
#
|
4
|
+
# @include Joosy.Modules.Log
|
5
|
+
# @include Joosy.Modules.Events
|
6
|
+
#
|
7
|
+
class Joosy.Resource.RESTCollection extends Joosy.Resource.Collection
|
8
|
+
@include Joosy.Modules.Log
|
9
|
+
@include Joosy.Modules.Events
|
10
|
+
|
11
|
+
#
|
12
|
+
# Refetches the data from backend and triggers `changed`
|
13
|
+
#
|
14
|
+
# @param [Hash] options See {Joosy.Resource.REST.find} for possible options
|
15
|
+
# @param [Function] callback Resulting callback
|
16
|
+
#
|
17
|
+
reload: (options={}, callback=false) ->
|
18
|
+
if Object.isFunction(options)
|
19
|
+
callback = options
|
20
|
+
options = {}
|
21
|
+
|
22
|
+
@model.__query @model.collectionPath(options), 'GET', options.params, (data) =>
|
23
|
+
@load data
|
24
|
+
callback?(data)
|
@@ -0,0 +1,201 @@
|
|
1
|
+
#= require joosy/core/joosy
|
2
|
+
|
3
|
+
#
|
4
|
+
# Router. Reacts on a hash change event and loads proper pages
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
# Joosy.Router.map
|
8
|
+
# 404 : (path) -> alert "Page '#{path}' was not found :("
|
9
|
+
# '/' : Welcome.IndexPage
|
10
|
+
# '/resources' :
|
11
|
+
# '/' : Resource.IndexPage
|
12
|
+
# '/:id' : Resource.ShowPage
|
13
|
+
# '/:id/edit' : Resource.EditPage
|
14
|
+
# '/new' : Resource.EditPage
|
15
|
+
#
|
16
|
+
# @mixin
|
17
|
+
#
|
18
|
+
Joosy.Router =
|
19
|
+
#
|
20
|
+
# The Object containing route parts in keys and pages/lambdas in values
|
21
|
+
#
|
22
|
+
rawRoutes: Object.extended()
|
23
|
+
|
24
|
+
#
|
25
|
+
# Flattern routes mapped to regexps (to check if current route is what we
|
26
|
+
# need) and actual executors
|
27
|
+
#
|
28
|
+
routes: Object.extended()
|
29
|
+
|
30
|
+
#
|
31
|
+
# The regexp to restrict the next loading url. By default set to false and
|
32
|
+
# therefore no restrictions apply.
|
33
|
+
#
|
34
|
+
restrictPattern: false
|
35
|
+
|
36
|
+
#
|
37
|
+
# Set the restriction pattern. If the requested url does not match this it
|
38
|
+
# will not load. Set `false` to avoid check.
|
39
|
+
#
|
40
|
+
restrict: (@restrictPattern) ->
|
41
|
+
|
42
|
+
#
|
43
|
+
# Clears the routes
|
44
|
+
#
|
45
|
+
reset: ->
|
46
|
+
@rawRoutes = Object.extended()
|
47
|
+
@routes = Object.extended()
|
48
|
+
|
49
|
+
#
|
50
|
+
# Registers the set of raw routes
|
51
|
+
# This method will only store routes and will not make them act immediately
|
52
|
+
# Routes get registered only once at system initialization during #__setupRoutes call
|
53
|
+
#
|
54
|
+
# @param [Object] routes Set of routes in inner format (see class description)
|
55
|
+
#
|
56
|
+
map: (routes) ->
|
57
|
+
Joosy.Module.merge @rawRoutes, routes
|
58
|
+
|
59
|
+
#
|
60
|
+
# Changes current hash with shebang (#!) and therefore triggers new route loading
|
61
|
+
# to be loaded
|
62
|
+
#
|
63
|
+
# @param [String] to Route to navigate to
|
64
|
+
#
|
65
|
+
# @option options [Boolean] respond If false just changes hash without responding
|
66
|
+
# @option options [Boolean] replaceState If true uses replaces history entry instead of adding. Works only in browsers supporting history.pushState
|
67
|
+
#
|
68
|
+
navigate: (to, options={}) ->
|
69
|
+
path = to.replace /^\#?\!?/, '!'
|
70
|
+
if options.respond != false
|
71
|
+
location.hash = path
|
72
|
+
else
|
73
|
+
if !history.pushState
|
74
|
+
@__ignoreRequest = to
|
75
|
+
location.hash = path
|
76
|
+
setTimeout =>
|
77
|
+
@__ignoreRequest = false
|
78
|
+
, 2 # jQuery.hashchange checks hash changing every 1ms
|
79
|
+
else
|
80
|
+
history[if options.replaceState then 'replaceState' else 'pushState'] {}, '', '#'+path
|
81
|
+
|
82
|
+
#
|
83
|
+
# Inits the routing system and loads the current route
|
84
|
+
# Binds the window hashchange event and therefore should only be called once
|
85
|
+
# during system startup
|
86
|
+
#
|
87
|
+
__setupRoutes: ->
|
88
|
+
@__prepareRoutes @rawRoutes
|
89
|
+
@__respondRoute location.hash
|
90
|
+
$(window).hashchange =>
|
91
|
+
@__respondRoute location.hash unless @__ignoreRequest && location.hash.match(@__ignoreRequest)
|
92
|
+
|
93
|
+
#
|
94
|
+
# Compiles routes to map object
|
95
|
+
# Object will contain regexp string as key and lambda/Page to load as value
|
96
|
+
#
|
97
|
+
# @param [Object] routes Raw routes to prepare
|
98
|
+
# @param [String] namespace Inner cursor for recursion
|
99
|
+
#
|
100
|
+
__prepareRoutes: (routes, namespace='') ->
|
101
|
+
if !namespace && routes[404]
|
102
|
+
@wildcardAction = routes[404]
|
103
|
+
delete routes[404]
|
104
|
+
|
105
|
+
Object.each routes, (path, response) =>
|
106
|
+
path = (namespace + path).replace /\/{2,}/, '/'
|
107
|
+
if response && (Object.isFunction(response) || response.prototype?)
|
108
|
+
Joosy.Module.merge @routes, @__prepareRoute(path, response)
|
109
|
+
else
|
110
|
+
@__prepareRoutes response, path
|
111
|
+
|
112
|
+
#
|
113
|
+
# Compiles one single route
|
114
|
+
#
|
115
|
+
# @param [String] path Full path from raw route
|
116
|
+
# @param [Joosy.Page] response Page that should be loaded at this route
|
117
|
+
# @param [Function] response Lambda to call at this route
|
118
|
+
#
|
119
|
+
__prepareRoute: (path, response) ->
|
120
|
+
matchPath = path.replace(/\/:([^\/]+)/g, '/([^/]+)').replace(/^\/?/, '^/?').replace(/\/?$/, '/?$')
|
121
|
+
result = Object.extended()
|
122
|
+
|
123
|
+
result[matchPath] =
|
124
|
+
capture: (path.match(/\/:[^\/]+/g) || []).map (str) ->
|
125
|
+
str.substr 2
|
126
|
+
action: response
|
127
|
+
result
|
128
|
+
|
129
|
+
#
|
130
|
+
# Searches the corresponding route through compiled routes
|
131
|
+
#
|
132
|
+
# @param [String] hash Hash value to search route for
|
133
|
+
#
|
134
|
+
__respondRoute: (hash) ->
|
135
|
+
Joosy.Modules.Log.debug "Router> Answering '#{hash}'"
|
136
|
+
fullPath = hash.replace /^#!?/, ''
|
137
|
+
|
138
|
+
if (@restrictPattern && fullPath.match(@restrictPattern) == null)
|
139
|
+
@trigger 'restricted', fullPath
|
140
|
+
return
|
141
|
+
else
|
142
|
+
@trigger 'responded', fullPath
|
143
|
+
|
144
|
+
@currentPath = fullPath
|
145
|
+
found = false
|
146
|
+
queryArray = fullPath.split '&'
|
147
|
+
path = queryArray.shift()
|
148
|
+
urlParams = @__paramsFromQueryArray queryArray
|
149
|
+
|
150
|
+
for regex, route of @routes when @routes.hasOwnProperty regex
|
151
|
+
if vals = path.match new RegExp(regex)
|
152
|
+
params = @__paramsFromRouteMatch(vals, route).merge urlParams
|
153
|
+
|
154
|
+
if Joosy.Module.hasAncestor route.action, Joosy.Page
|
155
|
+
Joosy.Application.setCurrentPage route.action, params
|
156
|
+
else
|
157
|
+
route.action.call this, params
|
158
|
+
|
159
|
+
found = true
|
160
|
+
break
|
161
|
+
|
162
|
+
if !found && @wildcardAction?
|
163
|
+
if Joosy.Module.hasAncestor @wildcardAction, Joosy.Page
|
164
|
+
Joosy.Application.setCurrentPage @wildcardAction, urlParams
|
165
|
+
else
|
166
|
+
@wildcardAction path, urlParams
|
167
|
+
|
168
|
+
#
|
169
|
+
# Collects params from route placeholders (/foo/:placeholder)
|
170
|
+
#
|
171
|
+
# @param [Array] vals Array of value gathered by regexp
|
172
|
+
# @param [Object] route Compiled route
|
173
|
+
# @returns [Object] Hash of params
|
174
|
+
#
|
175
|
+
__paramsFromRouteMatch: (vals, route) ->
|
176
|
+
params = Object.extended()
|
177
|
+
|
178
|
+
vals.shift()
|
179
|
+
for param in route.capture
|
180
|
+
params[param] = vals.shift()
|
181
|
+
|
182
|
+
params
|
183
|
+
|
184
|
+
#
|
185
|
+
# Collects params from query routes (/foo/&a=b)
|
186
|
+
#
|
187
|
+
# @param [Array] queryArray Array of query string split by '&' sign
|
188
|
+
# @returns [Object] Hash of params
|
189
|
+
#
|
190
|
+
__paramsFromQueryArray: (queryArray) ->
|
191
|
+
params = Object.extended()
|
192
|
+
|
193
|
+
if queryArray
|
194
|
+
$.each queryArray, ->
|
195
|
+
unless @isBlank()
|
196
|
+
pair = @split '='
|
197
|
+
params[pair[0]] = pair[1]
|
198
|
+
|
199
|
+
params
|
200
|
+
|
201
|
+
Joosy.Module.merge Joosy.Router, Joosy.Modules.Events
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#= require joosy/core/joosy
|
2
|
+
|
3
|
+
#
|
4
|
+
# Rails JST template precompilation binding
|
5
|
+
#
|
6
|
+
class Joosy.Templaters.RailsJST
|
7
|
+
constructor: (@applicationName) ->
|
8
|
+
|
9
|
+
#
|
10
|
+
# Gets template lambda by its full name
|
11
|
+
#
|
12
|
+
# @param [String] name Template name 'foo/bar'
|
13
|
+
#
|
14
|
+
buildView: (name) ->
|
15
|
+
unless template = JST[location = "#{@applicationName}/templates/#{name}-#{I18n?.locale}"]
|
16
|
+
template = JST[location = "#{@applicationName}/templates/#{name}"]
|
17
|
+
|
18
|
+
unless template
|
19
|
+
throw new Error "Template '#{name}' not found. Checked at: #{location}"
|
20
|
+
|
21
|
+
template
|
22
|
+
|
23
|
+
#
|
24
|
+
# Gets full name of template by several params
|
25
|
+
#
|
26
|
+
# @param [String] section Section of templates like pages/layouts/...
|
27
|
+
# @param [String] template Internal template path
|
28
|
+
# @param [String] entity Entity to lookup template path by its namespace
|
29
|
+
#
|
30
|
+
resolveTemplate: (section, template, entity) ->
|
31
|
+
if template.startsWith '/'
|
32
|
+
return template.substr 1
|
33
|
+
|
34
|
+
path = entity.constructor?.__namespace__?.map('underscore') || []
|
35
|
+
path.unshift section
|
36
|
+
|
37
|
+
"#{path.join '/'}/#{template}"
|
@@ -0,0 +1,85 @@
|
|
1
|
+
#= require joosy/core/joosy
|
2
|
+
#= require joosy/core/modules/module
|
3
|
+
#= require joosy/core/modules/log
|
4
|
+
#= require joosy/core/modules/events
|
5
|
+
#= require joosy/core/modules/container
|
6
|
+
#= require joosy/core/modules/renderer
|
7
|
+
#= require joosy/core/modules/filters
|
8
|
+
|
9
|
+
#
|
10
|
+
# Base class for all of your Joosy Layouts.
|
11
|
+
#
|
12
|
+
# @todo Add link to the 5th chapter of guides here.
|
13
|
+
#
|
14
|
+
# @example Sample widget
|
15
|
+
# class @FooWidget extends Joosy.Widget
|
16
|
+
# @view 'foo'
|
17
|
+
#
|
18
|
+
# @include Joosy.Modules.Log
|
19
|
+
# @include Joosy.Modules.Events
|
20
|
+
# @include Joosy.Modules.Container
|
21
|
+
# @include Joosy.Modules.Renderer
|
22
|
+
# @include Joosy.Modules.Filters
|
23
|
+
# @include Joosy.Modules.TimeManager
|
24
|
+
#
|
25
|
+
class Joosy.Widget extends Joosy.Module
|
26
|
+
@include Joosy.Modules.Log
|
27
|
+
@include Joosy.Modules.Events
|
28
|
+
@include Joosy.Modules.Container
|
29
|
+
@include Joosy.Modules.Renderer
|
30
|
+
@include Joosy.Modules.Filters
|
31
|
+
@include Joosy.Modules.TimeManager
|
32
|
+
|
33
|
+
#
|
34
|
+
# By default widget will not render on load
|
35
|
+
#
|
36
|
+
__renderer: false
|
37
|
+
|
38
|
+
#
|
39
|
+
# Initial data that will be passed to view on load
|
40
|
+
# False (and not {}) by default to have a chance to check if data was loaded
|
41
|
+
#
|
42
|
+
data: false
|
43
|
+
|
44
|
+
#
|
45
|
+
# Proxy to Joosy.Router.navigate
|
46
|
+
#
|
47
|
+
navigate: (args...) ->
|
48
|
+
Joosy.Router.navigate args...
|
49
|
+
|
50
|
+
#
|
51
|
+
# This is required by {Joosy.Modules.Renderer}
|
52
|
+
# Sets the base template dir to app_name/templates/widgets
|
53
|
+
#
|
54
|
+
__renderSection: ->
|
55
|
+
'widgets'
|
56
|
+
|
57
|
+
#
|
58
|
+
# Widget bootstrap proccess
|
59
|
+
#
|
60
|
+
# * Rendering (if required)
|
61
|
+
# * {Joosy.Modules.Container.refreshElements}
|
62
|
+
# * {Joosy.Modules.Container.__delegateEvents}
|
63
|
+
#
|
64
|
+
# @param [Joosy.Page, Joosy.Layout] Page or Layout to attach to
|
65
|
+
# @param [jQuery] container Container to attach to
|
66
|
+
#
|
67
|
+
__load: (@parent, @container, render=true) ->
|
68
|
+
if render && @__renderer
|
69
|
+
@swapContainer @container, @__renderer(@data || {})
|
70
|
+
@refreshElements()
|
71
|
+
@__delegateEvents()
|
72
|
+
@__runAfterLoads()
|
73
|
+
|
74
|
+
this
|
75
|
+
|
76
|
+
#
|
77
|
+
# Layout destruction proccess.
|
78
|
+
#
|
79
|
+
# * {Joosy.Modules.TimeManager.__clearTime}
|
80
|
+
# * {Joosy.Modules.Renderer.__removeMetamorphs}
|
81
|
+
#
|
82
|
+
__unload: ->
|
83
|
+
@__clearTime()
|
84
|
+
@__removeMetamorphs()
|
85
|
+
@__runAfterUnloads()
|