joosy 0.1.0.RC2 → 0.1.0.RC3

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.
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