joosy 0.1.0.RC2 → 0.1.0.RC3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/.codoopts +5 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile.lock +4 -2
  4. data/README.md +10 -4
  5. data/app/assets/javascripts/joosy/core/application.js.coffee +3 -1
  6. data/app/assets/javascripts/joosy/core/form.js.coffee +69 -42
  7. data/app/assets/javascripts/joosy/core/helpers/view.js.coffee +30 -0
  8. data/app/assets/javascripts/joosy/core/joosy.js.coffee +125 -66
  9. data/app/assets/javascripts/joosy/core/layout.js.coffee +106 -1
  10. data/app/assets/javascripts/joosy/core/modules/container.js.coffee +41 -0
  11. data/app/assets/javascripts/joosy/core/modules/events.js.coffee +88 -1
  12. data/app/assets/javascripts/joosy/core/modules/filters.js.coffee +24 -0
  13. data/app/assets/javascripts/joosy/core/modules/log.js.coffee +18 -0
  14. data/app/assets/javascripts/joosy/core/modules/module.js.coffee +53 -1
  15. data/app/assets/javascripts/joosy/core/modules/renderer.js.coffee +22 -6
  16. data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +21 -0
  17. data/app/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +26 -0
  18. data/app/assets/javascripts/joosy/core/page.js.coffee +225 -16
  19. data/app/assets/javascripts/joosy/core/preloader.js.coffee +8 -0
  20. data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +52 -15
  21. data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +78 -50
  22. data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +39 -41
  23. data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +36 -27
  24. data/app/assets/javascripts/joosy/core/router.js.coffee +95 -19
  25. data/app/assets/javascripts/joosy/core/widget.js.coffee +42 -1
  26. data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +39 -24
  27. data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +9 -7
  28. data/app/helpers/joosy/sprockets_helper.rb +4 -1
  29. data/lib/joosy/rails/version.rb +1 -1
  30. data/spec/javascripts/joosy/core/application_spec.js.coffee +3 -3
  31. data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +0 -2
  32. data/spec/javascripts/joosy/core/router_spec.js.coffee +24 -24
  33. data/vendor/assets/javascripts/jquery.form.js +978 -963
  34. data/vendor/assets/javascripts/sugar.js +1 -1
  35. metadata +20 -20
  36. data/app/assets/javascripts/joosy/core/helpers.js.coffee +0 -16
  37. data/vendor/assets/javascripts/base64.js +0 -135
@@ -8,6 +8,14 @@
8
8
  #= require joosy/core/modules/widgets_manager
9
9
  #= require joosy/core/modules/filters
10
10
 
11
+ #
12
+ # Base class for all of your Joosy Pages.
13
+ # @see http://guides.joosy.ws/guides/layouts-pages-and-routing.html
14
+ #
15
+ # @example Sample application page
16
+ # class @RumbaPage extends Joosy.Layout
17
+ # @view 'rumba'
18
+ #
11
19
  class Joosy.Page extends Joosy.Module
12
20
  @include Joosy.Modules.Log
13
21
  @include Joosy.Modules.Events
@@ -17,32 +25,173 @@ class Joosy.Page extends Joosy.Module
17
25
  @include Joosy.Modules.WidgetsManager
18
26
  @include Joosy.Modules.Filters
19
27
 
28
+ #
29
+ # Default layout is no layout.
30
+ #
20
31
  layout: false
32
+
33
+ #
34
+ # Previous page.
35
+ #
21
36
  previous: false
37
+
38
+ #
39
+ # Route params.
40
+ #
22
41
  params: false
42
+
43
+ #
44
+ # Prefetched page data.
45
+ #
23
46
  data: false
24
47
 
25
- @fetch: (callback) ->
26
- @::__fetch = callback
27
-
28
- @scroll: (element, options={}) ->
29
- @::__scrollElement = element
30
- @::__scrollSpeed = options.speed || 500
31
- @::__scrollMargin = options.margin || 0
32
-
48
+ #
49
+ # Sets layout for current page
50
+ #
51
+ # @param [Class] layoutClass Layout to use
52
+ #
33
53
  @layout: (layoutClass) ->
34
54
  @::__layoutClass = layoutClass
35
55
 
56
+ #
57
+ # Sets the method which will controll the painting preparation proccess.
58
+ #
59
+ # This method will be called right ater previous page {Joosy.Page.erase} and in parallel with
60
+ # page data fetching so you can use it to initiate preloader.
61
+ #
62
+ # @note Given method will be called with `complete` function as parameter. As soon as your
63
+ # preparations are done you should call that function.
64
+ #
65
+ # @example Sample before painter
66
+ # @beforePaint (complete) ->
67
+ # if !@data # checks if parallel fetching finished
68
+ # $('preloader').slideDown -> complete()
69
+ #
70
+ #
36
71
  @beforePaint: (callback) ->
37
72
  @::__beforePaint = callback
73
+
74
+ #
75
+ # Sets the method which will controll the painting proccess.
76
+ #
77
+ # This method will be called after fetching, erasing and beforePaint is complete.
78
+ # It should be used to setup appearance effects of page.
79
+ #
80
+ # @note Given method will be called with `complete` function as parameter. As soon as your
81
+ # preparations are done you should call that function.
82
+ #
83
+ # @example Sample painter
84
+ # @paint (complete) ->
85
+ # @container.fadeIn -> complete()
86
+ #
38
87
  @paint: (callback) ->
39
88
  @::__paint = callback
89
+
90
+ #
91
+ # @todo Does anybody have idea why we could need this method?
92
+ # Looks like something should be removed from here and bootstrap proccess.
93
+ #
40
94
  @afterPaint: (callback) ->
41
95
  @::__afterPaint = callback
96
+
97
+ #
98
+ # Sets the method which will controll the erasing proccess.
99
+ #
100
+ # Use this method to setup hiding effect.
101
+ #
102
+ # @note Given method will be called with `complete` function as parameter. As soon as your
103
+ # preparations are done you should call that function.
104
+ #
105
+ # @note This method will be caled _before_ unload routines so in theory you can
106
+ # access page data from that. Think twice if you are doing it right though.
107
+ #
108
+ # @example Sample eraser
109
+ # @erase (complete) ->
110
+ # @container.fadeOut -> complete()
111
+ #
42
112
  @erase: (callback) ->
43
113
  @::__erase = callback
44
114
 
115
+ #
116
+ # Sets the method which will controll the data fetching proccess.
117
+ #
118
+ # @note Given method will be called with `complete` function as parameter. As soon as your
119
+ # preparations are done you should call that function.
120
+ #
121
+ # @example Basic usage
122
+ # @fetch (complete) ->
123
+ # $.get '/rumbas', (@data) => complete()
124
+ #
125
+ @fetch: (callback) ->
126
+ @::__fetch = callback
127
+
128
+ #
129
+ # Sets the several separate methods that will fetch data in parallel.
130
+ #
131
+ # @note This will work through {Joosy.Modules.Events#synchronize}
132
+ #
133
+ # @example Basic usage
134
+ # @fetchSynchronized (context) ->
135
+ # context.do (done) ->
136
+ # $.get '/rumbas', (data) =>
137
+ # @data.rumbas = data
138
+ # done()
139
+ #
140
+ # context.do (done) ->
141
+ # $.get '/kutuzkas', (data) =>
142
+ # @data.kutuzkas = data
143
+ # done()
144
+ #
145
+ @fetchSynchronized: (callback) ->
146
+ @::__fetch = (complete) ->
147
+ @synchronize (context) ->
148
+ context.after -> complete()
149
+ callback.call(this, context)
150
+
151
+ #
152
+ # Sets the position where page will be scrolled to after load.
153
+ #
154
+ # @note If you use animated scroll joosy will atempt to temporarily fix the
155
+ # height of your document while scrolling to prevent jump effect.
156
+ #
157
+ # @param [jQuery] element Element to scroll to
158
+ # @param [Hash] options
159
+ #
160
+ # @option options [Integer] speed Sets the animation duration (500 is default)
161
+ # @option options [Integer] margin Defines the margin from element position.
162
+ # Can be negative.
163
+ #
164
+ @scroll: (element, options={}) ->
165
+ @::__scrollElement = element
166
+ @::__scrollSpeed = options.speed || 500
167
+ @::__scrollMargin = options.margin || 0
168
+
169
+ #
170
+ # Sets the page HTML title.
171
+ #
172
+ # @note Title will be reverted on unload.
173
+ #
174
+ # @param [String] title Title to set.
175
+ #
176
+ @title: (title, separator=' / ') ->
177
+ @afterLoad ->
178
+ titleStr = if Object.isFunction(title) then title.apply(this) else title
179
+ titleStr = titleStr.join(separator) if Object.isArray(titleStr)
180
+ @__previousTitle = document.title
181
+ document.title = titleStr
182
+
183
+ @afterUnload ->
184
+ document.title = @__previousTitle
185
+
186
+ #
187
+ # Constructor is very destructive (c), it calls bootstrap directly so use with caution.
188
+ #
189
+ # @params [Hash] params Route params
190
+ # @params [Joosy.Page] previous Previous page to unload
191
+ #
45
192
  constructor: (@params, @previous) ->
193
+ Joosy.Application.loading = true
194
+
46
195
  @__layoutClass ||= ApplicationLayout
47
196
 
48
197
  if @__runBeforeLoads @params, @previous
@@ -51,18 +200,42 @@ class Joosy.Page extends Joosy.Module
51
200
  else
52
201
  @__bootstrap()
53
202
 
203
+ #
204
+ # @see Joosy.Router#navigate
205
+ #
54
206
  navigate: (args...) ->
55
207
  Joosy.Router.navigate(args...)
56
208
 
209
+ #
210
+ # This is required by {Joosy.Modules.Renderer}
211
+ # Sets the base template dir to app_name/templates/pages
212
+ #
57
213
  __renderSection: ->
58
214
  'pages'
59
215
 
216
+ #
217
+ # Freezes the page height through $(html).
218
+ #
219
+ # Required to implement better {Joosy.Page.scroll} behavior.
220
+ #
60
221
  __fixHeight: ->
61
222
  $('html').css 'min-height', $(document).height()
62
-
223
+
224
+ #
225
+ # Undo {#__fixHeight}
226
+ #
63
227
  __releaseHeight: ->
64
228
  $('html').css 'min-height', ''
65
229
 
230
+ #
231
+ # Page bootstrap proccess
232
+ #
233
+ # * {Joosy.Modules.Container#refreshElements}
234
+ # * {Joosy.Modules.Container#__delegateEvents}
235
+ # * {Joosy.Modules.WidgetsManager#__setupWidgets}
236
+ # * {Joosy.Modules.Filters#__runAfterLoads}
237
+ # * Scrolling
238
+ #
66
239
  __load: ->
67
240
  @refreshElements()
68
241
  @__delegateEvents()
@@ -74,9 +247,19 @@ class Joosy.Page extends Joosy.Module
74
247
  $('html, body').animate {scrollTop: scroll}, @__scrollSpeed, =>
75
248
  if @__scrollSpeed != 0
76
249
  @__releaseHeight()
250
+ Joosy.Application.loading = false
251
+ @trigger 'loaded'
77
252
 
78
253
  Joosy.Modules.Log.debugAs @, "Page loaded"
79
254
 
255
+ #
256
+ # Page destruction proccess.
257
+ #
258
+ # * {Joosy.Modules.TimeManager#__clearTime}
259
+ # * {Joosy.Modules.WidgetsManager#__unloadWidgets}
260
+ # * {Joosy.Modules.Renderer#__removeMetamorphs}
261
+ # * {Joosy.Modules.Filters#__runAfterUnloads}
262
+ #
80
263
  __unload: ->
81
264
  @__clearTime()
82
265
  @__unloadWidgets()
@@ -84,19 +267,35 @@ class Joosy.Page extends Joosy.Module
84
267
  @__runAfterUnloads @params, @previous
85
268
  delete @previous
86
269
 
270
+ #
271
+ # Proxies callback through possible async wrapper.
272
+ #
273
+ # If wrapper is defined, it will be called with given callback as one of parameters.
274
+ # If wrapper is not defined callback will be called directly.
275
+ #
276
+ # @note Magic People Voodoo People
277
+ #
278
+ # @param [Object] entity Object possibly containing wrapper method
279
+ # @param [String] receiver String name of wrapper method inside entity
280
+ # @param [Hash] params Params to send to wrapper, callback will be
281
+ # attached as the last of them.
282
+ # @param [Function] callback Callback to run
283
+ #
87
284
  __callSyncedThrough: (entity, receiver, params, callback) ->
88
285
  if entity?[receiver]?
89
286
  entity[receiver].apply entity, params.clone().add(callback)
90
287
  else
91
288
  callback()
92
-
93
- # Boot Sequence:
289
+
290
+ #
291
+ # The single page (without layout reloading) bootstrap logic
94
292
  #
95
- # previous::erase \
96
- # previous::unload \
97
- # beforePaint \
98
- # > paint
99
- # fetch /
293
+ # @example Hacky boot sequence description
294
+ # previous::erase \
295
+ # previous::unload \
296
+ # beforePaint \
297
+ # > paint
298
+ # fetch /
100
299
  #
101
300
  __bootstrap: ->
102
301
  Joosy.Modules.Log.debugAs @, "Boostraping page"
@@ -127,6 +326,16 @@ class Joosy.Page extends Joosy.Module
127
326
  Joosy.Modules.Log.debugAs @, "Fetch complete"
128
327
  @trigger 'dataReceived'
129
328
 
329
+ #
330
+ # The page+layout bootstrap logic
331
+ #
332
+ # @example Hacky boot sequence description
333
+ # previous::erase \
334
+ # previous::unload \
335
+ # beforePaint \
336
+ # > paint
337
+ # fetch /
338
+ #
130
339
  __bootstrapLayout: ->
131
340
  Joosy.Modules.Log.debugAs @, "Boostraping page with layout"
132
341
  @layout = new @__layoutClass(@params)
@@ -1,5 +1,13 @@
1
+ #
1
2
  # Preloader stub
3
+ #
4
+ # @module
5
+ #
2
6
  @Preloader =
7
+
8
+ #
9
+ # Mocks loader to do nothing if Joosy is already here
10
+ #
3
11
  load: (libraries, options) ->
4
12
  @[key] = val for key, val of options
5
13
  @complete?.call window
@@ -1,17 +1,17 @@
1
1
  #
2
- # Basic collection of Resources
3
- # Turns JSON array into array of Resources and manages them
2
+ # Basic collection of Resources.
3
+ # Turns JSON array into array of Resources and manages them.
4
4
  #
5
- # Generally you should not use Collection directly. It will be
6
- # automatically created by things like Joosy.Resource.Generic#map
7
- # or Joosy.Resource.REST#find.
5
+ # @note You should not use Collection directly. It will be
6
+ # automatically created by things like {Joosy.Resource.Generic.map}
7
+ # or {Joosy.Resource.REST.find}.
8
8
  #
9
- # Example:
9
+ # @example Basic sample
10
10
  # class R extends Joosy.Resource.Generic
11
11
  # @entity 'r'
12
- #
12
+ #
13
13
  # collection = new Joosy.Resource.Collection(R)
14
- #
14
+ #
15
15
  # collection.reset [{foo: 'bar'}, {foo: 'baz'}]
16
16
  # collection.each (resource) ->
17
17
  # resource('foo')
@@ -22,25 +22,46 @@ class Joosy.Resource.Collection extends Joosy.Module
22
22
  #
23
23
  # Allows to modify data before it gets stored
24
24
  #
25
+ # @note Supposed to be used in descendants
26
+ #
25
27
  # @param [Function] action `(Object) -> Object` to call
26
28
  #
27
29
  @beforeLoad: (action) -> @::__beforeLoad = action
28
30
 
31
+ #
32
+ # Sets the default model for collection
33
+ #
34
+ # @note Supposed to be used in descendants
35
+ #
36
+ # @param [Class] model Model class
37
+ #
38
+ @model: (model) -> @::model = model
39
+
29
40
  #
30
41
  # Modelized data storage
31
42
  #
32
43
  data: []
33
44
 
34
45
  #
35
- # @param [Class] model Resource class this collection will handle
46
+ # If model param was empty it will fallback to `@model`
47
+ # If both param and `@model` were empty it will throw an exception.
48
+ #
49
+ # @param [Class] model Resource class which this collection will handle
36
50
  #
37
- constructor: (@model) ->
51
+ constructor: (model=false) ->
52
+ @model = model if model
53
+
54
+ if !@model
55
+ throw new Error "#{Joosy.Module.__className @}> model can't be empty"
38
56
 
39
57
  #
40
- # Clears the storage and attempts to import given JSON
58
+ # Clears the storage and attempts to import given array
41
59
  #
42
- # @param [Object] entities Entities to import
43
- # @param [Boolean] notify Indicates whether to trigger 'changed' event
60
+ # @param [Array, Hash] entities Array of entities to import.
61
+ # If hash was given will seek for moodel name camelized and pluralized.
62
+ # @param [Boolean] notify Indicates whether to trigger 'changed' event
63
+ #
64
+ # @return [Joosy.Resource.Collection] Returns self.
44
65
  #
45
66
  reset: (entities, notify=true) ->
46
67
  if @__beforeLoad?
@@ -72,16 +93,24 @@ class Joosy.Resource.Collection extends Joosy.Module
72
93
  #
73
94
  # Calls callback for each Resource inside Collection
74
95
  #
75
- # @param [Function] callback
96
+ # @param [Function] callback `(mixed) -> mixed` to call for each Resource in collection
76
97
  #
77
98
  each: (callback) ->
78
99
  @data.each callback
79
-
100
+
101
+ #
102
+ # Returns number of Resources inside Collection
103
+ #
104
+ size: ->
105
+ @data.length
106
+
80
107
  #
81
108
  # Gets first resource matching description (see Sugar.js Array#find)
82
109
  #
83
110
  # @param [Function] description Callback matcher
84
111
  #
112
+ # @return [Joosy.Resource.Generic]
113
+ #
85
114
  find: (description) ->
86
115
  @data.find description
87
116
 
@@ -90,6 +119,8 @@ class Joosy.Resource.Collection extends Joosy.Module
90
119
  #
91
120
  # @param [Integer] id Id to find
92
121
  #
122
+ # @return [Joosy.Resource.Generic]
123
+ #
93
124
  findById: (id) ->
94
125
  @data.find (x) -> x('id').toString() == id.toString()
95
126
 
@@ -98,6 +129,8 @@ class Joosy.Resource.Collection extends Joosy.Module
98
129
  #
99
130
  # @param [Integer] i Index
100
131
  #
132
+ # @return [Joosy.Resource.Generic]
133
+ #
101
134
  at: (i) ->
102
135
  @data[i]
103
136
 
@@ -108,6 +141,8 @@ class Joosy.Resource.Collection extends Joosy.Module
108
141
  # @param [Resource] target Resource by itself
109
142
  # @param [Boolean] notify Indicates whether to trigger 'changed' event
110
143
  #
144
+ # @return [Joosy.Resource.Generic] Removed element
145
+ #
111
146
  remove: (target, notify=true) ->
112
147
  if Object.isNumber target
113
148
  index = target
@@ -126,6 +161,8 @@ class Joosy.Resource.Collection extends Joosy.Module
126
161
  # @param [Integer] index Index to add to. If omited will be pushed to the end
127
162
  # @param [Boolean] notify Indicates whether to trigger 'changed' event
128
163
  #
164
+ # @return [Joosy.Resource.Generic] Added element
165
+ #
129
166
  add: (element, index=false, notify=true) ->
130
167
  if index
131
168
  @data.splice index, 0, element