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,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()