joosy 1.2.0.alpha.41 → 1.2.0.alpha.51

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gruntfile.coffee +27 -7
  4. data/bin/joosy +1 -1
  5. data/bower.json +3 -2
  6. data/build/joosy/extensions/preloaders.js +189 -0
  7. data/build/joosy/extensions/resources-form.js +588 -0
  8. data/build/joosy/extensions/resources.js +673 -0
  9. data/build/joosy.js +2395 -0
  10. data/{src/joosy/generators → generators}/base.coffee +2 -2
  11. data/{src/joosy/generators → generators/command}/command.coffee +16 -3
  12. data/generators/command/help.coffee +38 -0
  13. data/{src/joosy/generators → generators}/layout.coffee +0 -0
  14. data/{src/joosy/generators → generators}/page.coffee +0 -0
  15. data/{src/joosy/generators → generators}/project/base.coffee +2 -4
  16. data/{src/joosy/generators → generators}/project/standalone.coffee +4 -3
  17. data/{src/joosy/generators → generators}/project.coffee +0 -0
  18. data/generators/templates/application/base/application.coffee +13 -0
  19. data/{templates → generators/templates}/application/base/helpers/application.coffee +0 -0
  20. data/{templates → generators/templates}/application/base/layouts/application.coffee +0 -0
  21. data/{templates → generators/templates}/application/base/pages/application.coffee +0 -0
  22. data/{templates → generators/templates}/application/base/pages/welcome/index.coffee +0 -0
  23. data/{templates → generators/templates}/application/base/routes.coffee +0 -0
  24. data/{templates → generators/templates}/application/base/templates/layouts/application.jst.hamlc +0 -0
  25. data/{templates → generators/templates}/application/base/templates/pages/welcome/index.jst.hamlc +0 -0
  26. data/{templates → generators/templates}/application/standalone/Gruntfile.coffee +1 -0
  27. data/{templates → generators/templates}/application/standalone/Procfile +0 -0
  28. data/{templates → generators/templates}/application/standalone/_gitignore +0 -0
  29. data/generators/templates/application/standalone/bower.json +17 -0
  30. data/{templates → generators/templates}/application/standalone/package.json +0 -0
  31. data/{templates → generators/templates}/application/standalone/source/haml/index.haml +0 -0
  32. data/{templates → generators/templates}/application/standalone/source/stylesheets/application.styl +0 -0
  33. data/{templates → generators/templates}/layout/basic.coffee +0 -0
  34. data/{templates → generators/templates}/layout/namespaced.coffee +0 -0
  35. data/{templates → generators/templates}/page/basic.coffee +0 -0
  36. data/{templates → generators/templates}/page/namespaced.coffee +0 -0
  37. data/{templates → generators/templates}/widget/basic.coffee +0 -0
  38. data/{templates → generators/templates}/widget/namespaced.coffee +0 -0
  39. data/{src/joosy/generators → generators}/widget.coffee +0 -0
  40. data/lib/joosy.rb +3 -3
  41. data/package.json +2 -3
  42. data/source/joosy/application.coffee +95 -0
  43. data/source/joosy/events/namespace.coffee +24 -0
  44. data/{src → source}/joosy/extensions/preloaders/caching.coffee +0 -0
  45. data/{src → source}/joosy/extensions/preloaders/index.coffee +0 -0
  46. data/{src → source}/joosy/extensions/preloaders/inline.coffee +0 -0
  47. data/{src → source}/joosy/extensions/resources/base.coffee +16 -8
  48. data/{src → source}/joosy/extensions/resources/collection.coffee +0 -0
  49. data/{src → source}/joosy/extensions/resources/index.coffee +0 -0
  50. data/{src → source}/joosy/extensions/resources/rest.coffee +0 -0
  51. data/{src → source}/joosy/extensions/resources/rest_collection.coffee +0 -0
  52. data/{src → source}/joosy/extensions/resources-form/form.coffee +18 -18
  53. data/{src → source}/joosy/extensions/resources-form/helpers/form.coffee +6 -6
  54. data/{src → source}/joosy/extensions/resources-form/index.coffee +0 -0
  55. data/source/joosy/helpers/routes.coffee +10 -0
  56. data/source/joosy/helpers/view.coffee +115 -0
  57. data/{src/joosy/core → source/joosy}/helpers/widgets.coffee +1 -1
  58. data/{src/joosy/core → source/joosy}/joosy.coffee +59 -19
  59. data/source/joosy/layout.coffee +73 -0
  60. data/{src/joosy/core → source/joosy}/module.coffee +7 -2
  61. data/{src/joosy/core/modules/container.coffee → source/joosy/modules/dom.coffee} +24 -17
  62. data/source/joosy/modules/events.coffee +156 -0
  63. data/source/joosy/modules/filters.coffee +67 -0
  64. data/{src/joosy/core → source/joosy}/modules/log.coffee +7 -3
  65. data/source/joosy/modules/page/scrolling.coffee +51 -0
  66. data/source/joosy/modules/page/title.coffee +18 -0
  67. data/{src/joosy/core → source/joosy}/modules/renderer.coffee +12 -13
  68. data/{src/joosy/core → source/joosy}/modules/time_manager.coffee +5 -1
  69. data/{src/joosy/core → source/joosy}/modules/widgets_manager.coffee +9 -5
  70. data/source/joosy/page.coffee +68 -0
  71. data/{src/joosy/core → source/joosy}/resources/watcher.coffee +5 -1
  72. data/source/joosy/router.coffee +305 -0
  73. data/{src/joosy/core → source/joosy}/templaters/jst.coffee +10 -7
  74. data/source/joosy/widget.coffee +385 -0
  75. data/source/joosy.coffee +1 -0
  76. data/{src/vendor → source}/metamorph.coffee +0 -0
  77. data/spec/helpers/matchers.coffee +8 -1
  78. data/spec/joosy/core/application_spec.coffee +121 -20
  79. data/spec/joosy/core/helpers/view_spec.coffee +3 -3
  80. data/spec/joosy/core/helpers/widgets_spec.coffee +3 -6
  81. data/spec/joosy/core/joosy_spec.coffee +0 -5
  82. data/spec/joosy/core/layout_spec.coffee +2 -28
  83. data/spec/joosy/core/modules/dom_spec.coffee +133 -0
  84. data/spec/joosy/core/modules/events_spec.coffee +16 -9
  85. data/spec/joosy/core/modules/filters_spec.coffee +232 -89
  86. data/spec/joosy/core/modules/log_spec.coffee +2 -2
  87. data/spec/joosy/core/modules/renderer_spec.coffee +8 -4
  88. data/spec/joosy/core/page_spec.coffee +2 -201
  89. data/spec/joosy/core/router_spec.coffee +295 -233
  90. data/spec/joosy/core/templaters/jst_spec.coffee +1 -1
  91. data/spec/joosy/core/widget_spec.coffee +373 -34
  92. data/spec/joosy/environments/amd_spec.coffee +38 -0
  93. data/spec/joosy/environments/global_spec.coffee +21 -0
  94. data/spec/joosy/extensions/form/form_spec.coffee +18 -18
  95. data/spec/joosy/extensions/form/helpers/forms_spec.coffee +1 -1
  96. data/spec/joosy/extensions/resources/base_spec.coffee +23 -11
  97. data/tasks/joosy.coffee +6 -9
  98. metadata +75 -69
  99. data/lib/extensions/preloaders.js +0 -193
  100. data/lib/extensions/resources-form.js +0 -592
  101. data/lib/extensions/resources.js +0 -675
  102. data/lib/joosy.js +0 -2199
  103. data/spec/joosy/core/modules/container_spec.coffee +0 -153
  104. data/spec/joosy/core/modules/widget_manager_spec.coffee +0 -96
  105. data/src/joosy/core/application.coffee +0 -59
  106. data/src/joosy/core/helpers/view.coffee +0 -52
  107. data/src/joosy/core/layout.coffee +0 -174
  108. data/src/joosy/core/modules/events.coffee +0 -188
  109. data/src/joosy/core/modules/filters.coffee +0 -42
  110. data/src/joosy/core/page.coffee +0 -383
  111. data/src/joosy/core/router.coffee +0 -313
  112. data/src/joosy/core/widget.coffee +0 -88
  113. data/src/joosy.coffee +0 -1
  114. data/templates/application/base/application.coffee +0 -9
  115. data/templates/application/standalone/bower.json +0 -7
@@ -0,0 +1,115 @@
1
+ #= require joosy/joosy
2
+
3
+ #
4
+ # Rendering and string representation helpers
5
+ #
6
+ Joosy.helpers 'Application', ->
7
+
8
+ # Little helpers for HTML escaping
9
+ DOMtext = document.createTextNode("test")
10
+ DOMnative = document.createElement("span")
11
+ DOMnative.appendChild(DOMtext)
12
+
13
+ #
14
+ # Escapes HTML string
15
+ #
16
+ # @param [String] html String to escape
17
+ # @return [String] Escaped string
18
+ #
19
+ @escapeOnce = (html) ->
20
+ DOMtext.nodeValue = html
21
+ DOMnative.innerHTML
22
+
23
+ #
24
+ # Generates HTML string
25
+ #
26
+ # @param [String] name Tag name
27
+ # @param [Object] options Tag attributes
28
+ # @param [Boolean] open Marks whether standalone tags (like <br>) should be kept open
29
+ # @param [Boolean] escape Marks whether atribute values should be escaped
30
+ # @return [String] Tag HTML string
31
+ #
32
+ @tag = (name, options={}, open=false, escape=true) ->
33
+ element = document.createElement name
34
+ temp = document.createElement 'div'
35
+
36
+ for name, value of options
37
+ value = @escapeOnce(value) if escape
38
+ element.setAttribute name, value
39
+
40
+ temp.appendChild element
41
+ tag = temp.innerHTML
42
+
43
+ tag = tag.replace('/>', '>') if open
44
+ tag
45
+
46
+ #
47
+ # Generates HTML tag string with given content
48
+ #
49
+ # @param [String] name Tag name
50
+ # @param [Object] contentOrOptions Tag attributes
51
+ # @param [String] contentOrOptions String content
52
+ # @param [Object] options Tag attributes
53
+ # @param [Boolean] escape Marks whether attribute values should be escaped
54
+ # @return [String] Tag HTML string
55
+ #
56
+ # Possible arguments variations:
57
+ # 1. @contentTag 'name', 'content'
58
+ # 2. @contentTag 'name', {}, ->
59
+ # 3. @contentTag 'name', {}, false, ->
60
+ # 4. @contentTag 'name', ->
61
+ #
62
+ # Example
63
+ # != @contentTag 'div', {class: 'foo'}, =>
64
+ # != @contentTag 'hr'
65
+ #
66
+ @contentTag = (name, contentOrOptions=null, options=null, escape=true) ->
67
+ # This is a bit painfull but this is
68
+ # how we emulate Ruby block with lambda :(
69
+ if Object.isString(contentOrOptions)
70
+ options ||= {}
71
+ content = contentOrOptions
72
+ else if Object.isObject(contentOrOptions)
73
+ if Object.isFunction(options)
74
+ escape = true
75
+ content = options()
76
+ else
77
+ escape = options
78
+ content = escape()
79
+ options = contentOrOptions
80
+ else
81
+ options = {}
82
+ content = contentOrOptions()
83
+
84
+ element = document.createElement name
85
+ temp = document.createElement 'div'
86
+
87
+ for name, value of options
88
+ value = @escapeOnce(value) if escape
89
+ element.setAttribute name, value
90
+
91
+ try
92
+ element.innerHTML = content
93
+ catch e
94
+ # setting innerHTML fails in the IE for elements, which cann't have children (INPUT, for ex.)
95
+ # suppress this error unless content looks valuable
96
+ throw e if content
97
+
98
+ temp.appendChild element
99
+ temp.innerHTML
100
+
101
+ #
102
+ # Wraps the inline block into given template
103
+ # Request template will receive the inline block as @yield parameter
104
+ #
105
+ # Example
106
+ # -# foo/baz template
107
+ # != @renderWrapped 'foo/bar', ->
108
+ # %b This string will be passed to 'foo/bar'
109
+ #
110
+ # -# foo/bar template
111
+ # %h1 I'm the wrapper here!
112
+ # != @yield
113
+ #
114
+ @renderWrapped = (template, lambda) ->
115
+ @render template, Joosy.Module.merge(this, yield: lambda())
@@ -1,4 +1,4 @@
1
- #= require joosy/core/joosy
1
+ #= require joosy/joosy
2
2
 
3
3
  #
4
4
  # Widgets manipulation
@@ -1,5 +1,5 @@
1
1
  #= require_self
2
- #= require joosy/core/module
2
+ #= require joosy/module
3
3
 
4
4
  #
5
5
  # All the tiny core stuff
@@ -22,6 +22,40 @@
22
22
  #
23
23
  Templaters: {}
24
24
 
25
+ #
26
+ # Helpers container
27
+ #
28
+ Helpers: {}
29
+
30
+ #
31
+ # Events namespace
32
+ #
33
+ Events: {}
34
+
35
+
36
+ ### Global settings ###
37
+
38
+ #
39
+ # Debug mode
40
+ #
41
+ debug: (value) ->
42
+ if value?
43
+ @__debug = value
44
+ else
45
+ !!@__debug
46
+
47
+ #
48
+ # Templating engine
49
+ #
50
+ templater: (value) ->
51
+ if value?
52
+ @__templater = value
53
+ else
54
+ throw new Error "No templater registered" unless @__templater
55
+ @__templater
56
+
57
+ ### Global helpers ###
58
+
25
59
  #
26
60
  # Registeres anything inside specified namespace (objects chain starting from `window`)
27
61
  #
@@ -54,7 +88,27 @@
54
88
  # @param [Boolean] generator Helpers content
55
89
  #
56
90
  helpers: (name, generator) ->
57
- Joosy.namespace "Joosy.Helpers.#{name}", generator
91
+ Joosy.Helpers[name] ||= {}
92
+ generator.apply Joosy.Helpers[name]
93
+
94
+ #
95
+ # Generates ID unique within current run
96
+ #
97
+ uid: ->
98
+ @__uid ||= 0
99
+ "__joosy#{@__uid++}"
100
+
101
+ #
102
+ # Generates UUID
103
+ #
104
+ uuid: ->
105
+ 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace /[xy]/g, (c) ->
106
+ r = Math.random() * 16 | 0
107
+ v = if c is 'x' then r else r & 3 | 8
108
+ v.toString 16
109
+ .toUpperCase()
110
+
111
+ ### Shortcuts ###
58
112
 
59
113
  #
60
114
  # Runs set of callbacks finializing with result callback
@@ -74,23 +128,6 @@
74
128
  else
75
129
  Joosy.Modules.Events.synchronize arguments...
76
130
 
77
- #
78
- # Generates ID unique within current run
79
- #
80
- uid: ->
81
- @__uid ||= 0
82
- "__joosy#{@__uid++}"
83
-
84
- #
85
- # Generates UUID
86
- #
87
- uuid: ->
88
- 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace /[xy]/g, (c) ->
89
- r = Math.random() * 16 | 0
90
- v = if c is 'x' then r else r & 3 | 8
91
- v.toString 16
92
- .toUpperCase()
93
-
94
131
  #
95
132
  # Basic URI builder. Joins base path with params hash
96
133
  #
@@ -116,3 +153,6 @@
116
153
  paramsString = '&' + paramsString
117
154
 
118
155
  url + paramsString + hash
156
+
157
+ if define?.amd?
158
+ define 'joosy', -> Joosy
@@ -0,0 +1,73 @@
1
+ #= require joosy/joosy
2
+ #= require joosy/widget
3
+ #= require joosy/helpers/view
4
+
5
+ #
6
+ # Base class for all Joosy Layouts.
7
+ #
8
+ # @example Sample application layout
9
+ # class @ApplicationLayout extends Joosy.Layout
10
+ # @view 'application'
11
+ #
12
+ class Joosy.Layout extends Joosy.Widget
13
+ @helper 'page'
14
+
15
+ #
16
+ # @param [Hash] params Route params
17
+ # @param [Joosy.Layout] previous Layout to replace on load
18
+ #
19
+ constructor: (@params, @previous) ->
20
+ @uid = Joosy.uid()
21
+
22
+ #
23
+ # Helper that outputs container tag for the page
24
+ #
25
+ # @param [String] name Tag name
26
+ # @param [Object] options Tag attributes
27
+ #
28
+ page: (tag, options={}) ->
29
+ options.id = @uid
30
+ Joosy.Helpers.Application.tag tag, options
31
+
32
+ #
33
+ # Gets DOM element that should be used as container for nested Page
34
+ #
35
+ # @return [jQuery]
36
+ #
37
+ content: ->
38
+ $("##{@uid}")
39
+
40
+ ######
41
+ ###### Widget extensions
42
+ ######
43
+
44
+ #
45
+ # This is required by {Joosy.Modules.Renderer}
46
+ # Sets the base template dir to app_name/templates/layouts
47
+ #
48
+ __renderSection: ->
49
+ 'layouts'
50
+
51
+ #
52
+ # Extends list of registered nested widgets with page
53
+ #
54
+ __nestingMap: (page) ->
55
+ map = super()
56
+ map["##{@uid}"] =
57
+ instance: page
58
+ nested: page.__nestingMap()
59
+
60
+ map
61
+
62
+ #
63
+ # Adds page as first argument to default bootstrap
64
+ #
65
+ # @param [Joosy.Page] page Page to inject
66
+ # @param [jQuery] applicationContainer The base container for the application to paint at
67
+ #
68
+ __bootstrapDefault: (page, applicationContainer) ->
69
+ @__bootstrap @__nestingMap(page), applicationContainer
70
+
71
+ # AMD wrapper
72
+ if define?.amd?
73
+ define 'joosy/layout', -> Joosy.Layout
@@ -2,7 +2,7 @@
2
2
  # Base Joosy class extending Coffee class with module-like injections
3
3
  # and other tiny stuff.
4
4
  #
5
- class @Joosy.Module
5
+ class Joosy.Module
6
6
  #
7
7
  # Sets the default namespace for all Joosy descendants.
8
8
  # This is used in {Joosy.namespace} magic.
@@ -43,7 +43,8 @@ class @Joosy.Module
43
43
  unless what? && klass?
44
44
  return false
45
45
 
46
- [what, klass] = [what.prototype, klass.prototype]
46
+ what = what.prototype
47
+ klass = klass.prototype
47
48
 
48
49
  while what
49
50
  if what == klass
@@ -133,3 +134,7 @@ class @Joosy.Module
133
134
 
134
135
  object.extended?.apply this
135
136
  null
137
+
138
+ # AMD wrapper
139
+ if define?.amd?
140
+ define 'joosy/module', -> Joosy.Module
@@ -1,13 +1,13 @@
1
- #= require joosy/core/joosy
1
+ #= require joosy/joosy
2
2
 
3
3
  #
4
4
  # DOM container handling, DOM elements and DOM events bindings
5
5
  #
6
- # @note Requires implementor to contain DOM node at @container propert
6
+ # @note Requires implementor to contain DOM node at @$container propert
7
7
  #
8
8
  # @mixin
9
9
  #
10
- Joosy.Modules.Container =
10
+ Joosy.Modules.DOM =
11
11
  eventSplitter: /^(\S+)\s*(.*)$/
12
12
 
13
13
  included: ->
@@ -41,18 +41,7 @@ Joosy.Modules.Container =
41
41
  Object.merge @::__events, map
42
42
 
43
43
  $: (selector) ->
44
- $(selector, @container)
45
-
46
- #
47
- # Fills container with given data removing all events
48
- #
49
- # @param [jQuery] container jQuery entity of container to update
50
- # @param [String] data HTML to inject
51
- #
52
- swapContainer: (container, data) ->
53
- container.unbind().off()
54
- container.html data
55
- container
44
+ $(selector, @$container)
56
45
 
57
46
  #
58
47
  # Converts '$...' notation to selector from 'elements'
@@ -127,10 +116,28 @@ Joosy.Modules.Container =
127
116
  selector = @__extractSelector match[2]
128
117
 
129
118
  if selector == ""
130
- @container.bind eventName, callback
119
+ @$container.bind eventName, callback
131
120
  Joosy.Modules.Log.debugAs @, "#{eventName} binded on container"
132
121
  else if selector == undefined
133
122
  throw new Error "Unknown element #{match[2]} in #{Joosy.Module.__className @constructor} (maybe typo?)"
134
123
  else
135
- @container.on eventName, selector, callback
124
+ @$container.on eventName, selector, callback
136
125
  Joosy.Modules.Log.debugAs @, "#{eventName} binded on #{selector}"
126
+
127
+ __clearContainer: ->
128
+ @$container?.unbind().off()
129
+ @$container = $()
130
+
131
+
132
+ # This is not clearly related for container management
133
+ # But it will be later common for all containers
134
+ # See https://github.com/joosy/joosy/issues/102
135
+ __loadData: (done) ->
136
+ @data = {}
137
+ @__runFetchs [], =>
138
+ @dataFetched = true
139
+ done()
140
+
141
+ # AMD wrapper
142
+ if define?.amd?
143
+ define 'joosy/modules/dom', -> Joosy.Modules.DOM
@@ -0,0 +1,156 @@
1
+ #= require joosy/joosy
2
+ #= require_tree ../events
3
+
4
+ class SynchronizationContext
5
+ constructor: -> @actions = []
6
+ do: (action) -> @actions.push action
7
+ after: (@after) ->
8
+
9
+ #
10
+ # Basic events implementation
11
+ #
12
+ # @mixin
13
+ #
14
+ Joosy.Modules.Events =
15
+
16
+ #
17
+ # Waits for the list of given events to happen at least once. Then runs callback.
18
+ #
19
+ # @param [String|Array] events List of events to wait for separated by space
20
+ # @param [Function] callback Action to run when all events were triggered at least once
21
+ # @param [Hash] options Options
22
+ #
23
+ wait: (name, events, callback) ->
24
+ @__oneShotEvents = {} unless @hasOwnProperty('__oneShotEvents')
25
+
26
+ # unnamed binding
27
+ if Object.isFunction(events)
28
+ callback = events
29
+ events = name
30
+ name = Object.keys(@__oneShotEvents).length.toString()
31
+
32
+ events = @__splitEvents(events)
33
+
34
+ if events.length > 0
35
+ @__oneShotEvents[name] = [events, callback]
36
+ else
37
+ callback()
38
+
39
+ name
40
+
41
+ #
42
+ # Removes waiter action
43
+ #
44
+ # @param [Function] target Name of waiter to unbind
45
+ #
46
+ unwait: (target) ->
47
+ delete @__oneShotEvents[target] if @hasOwnProperty '__oneShotEvents'
48
+
49
+ #
50
+ # Binds action to run each time any of given event was triggered
51
+ #
52
+ # @param [String|Array] events List of events separated by space
53
+ # @param [Function] callback Action to run on trigger
54
+ # @param [Hash] options Options
55
+ #
56
+ bind: (name, events, callback) ->
57
+ @__boundEvents = {} unless @hasOwnProperty '__boundEvents'
58
+
59
+ # unnamed binding
60
+ if Object.isFunction(events)
61
+ callback = events
62
+ events = name
63
+ name = Object.keys(@__boundEvents).length.toString()
64
+
65
+ events = @__splitEvents(events)
66
+
67
+ if events.length > 0
68
+ @__boundEvents[name] = [events, callback]
69
+ else
70
+ callback()
71
+
72
+ name
73
+
74
+ #
75
+ # Unbinds action from runing on trigger
76
+ #
77
+ # @param [Function] target Name of bind to unbind
78
+ #
79
+ unbind: (target) ->
80
+ delete @__boundEvents[target] if @hasOwnProperty '__boundEvents'
81
+
82
+ #
83
+ # Triggers event for {bind} and {wait}
84
+ #
85
+ # @param [String] Name of event to trigger
86
+ #
87
+ trigger: (event, data...) ->
88
+ Joosy.Modules.Log.debugAs @, "Event #{event} triggered"
89
+
90
+ if Object.isObject event
91
+ remember = event.remember
92
+ event = event.name
93
+ else
94
+ remember = false
95
+
96
+ if @hasOwnProperty '__oneShotEvents'
97
+ fire = []
98
+ for name, [events, callback] of @__oneShotEvents
99
+ events.remove event
100
+ if events.length == 0
101
+ fire.push name
102
+ fire.each (name) =>
103
+ callback = @__oneShotEvents[name][1]
104
+ delete @__oneShotEvents[name]
105
+ callback data...
106
+
107
+ if @hasOwnProperty '__boundEvents'
108
+ for name, [events, callback] of @__boundEvents
109
+ if events.any event
110
+ callback data...
111
+
112
+ if remember
113
+ @__triggeredEvents = {} unless @hasOwnProperty '__triggeredEvents'
114
+ @__triggeredEvents[event] = true
115
+
116
+ #
117
+ # Runs set of callbacks finializing with result callback
118
+ #
119
+ # @example Basic usage
120
+ # @synchronize (context) ->
121
+ # context.do (done) -> done()
122
+ # context.do (done) -> done()
123
+ # context.after ->
124
+ # console.log 'Success!'
125
+ #
126
+ # @param [Function] block Configuration block (see example)
127
+ #
128
+ synchronize: (block) ->
129
+ context = new SynchronizationContext
130
+ counter = 0
131
+
132
+ block(context)
133
+
134
+ if context.actions.length == 0
135
+ context.after.call(@)
136
+ else
137
+ context.actions.each (action) =>
138
+ action.call @, ->
139
+ if ++counter >= context.actions.length
140
+ context.after.call(@)
141
+
142
+ __splitEvents: (events) ->
143
+ if Object.isString events
144
+ if events.isBlank()
145
+ events = []
146
+ else
147
+ events = events.trim().split /\s+/
148
+
149
+ if @hasOwnProperty '__triggeredEvents'
150
+ events = events.findAll (e) => !@__triggeredEvents[e]
151
+
152
+ events
153
+
154
+ # AMD wrapper
155
+ if define?.amd?
156
+ define 'joosy/modules/events', -> Joosy.Modules.Events
@@ -0,0 +1,67 @@
1
+ #= require joosy/joosy
2
+
3
+ #
4
+ # Filters registration routines
5
+ #
6
+ # @mixin
7
+ #
8
+ Joosy.Modules.Filters =
9
+
10
+ #
11
+ # Defines static registration routines
12
+ #
13
+ # @example Set of methods
14
+ # class Test
15
+ # @beforeLoad -> # supposed to run before load and control loading queue
16
+ # @afterLoad -> # supposed to run after load to finalize loading
17
+ # @afterUnload -> # supposed to run after unload to collect garbage
18
+ #
19
+ # # private
20
+ #
21
+ # @__runBeforeLoads() # Runs filters registered as beforeLoad
22
+ # @__runAfterLoads() # Runs filters registered as afterLoad
23
+ # @__runAfterUnloads() # Runs filters registered as afterUnload
24
+ #
25
+ included: ->
26
+ @__registerFilterCollector = (filter) =>
27
+ @[filter] = (callback) ->
28
+ unless @::hasOwnProperty "__#{filter}s"
29
+ @::["__#{filter}s"] = [].concat @.__super__["__#{filter}s"] || []
30
+ @::["__#{filter}s"].push callback
31
+
32
+ filter.charAt(0).toUpperCase() + filter.slice(1)
33
+
34
+ @registerPlainFilters = (filters...) =>
35
+ filters.each (filter) =>
36
+ camelized = @__registerFilterCollector filter
37
+
38
+ @::["__run#{camelized}s"] = (params...) ->
39
+ return true unless @["__#{filter}s"]
40
+
41
+ @["__#{filter}s"].reduce (flag, callback) =>
42
+ callback = @[callback] unless Object.isFunction callback
43
+ flag && callback.apply(@, params) != false
44
+ , true
45
+
46
+ @registerSequencedFilters = (filters...) =>
47
+ filters.each (filter) =>
48
+ camelized = @__registerFilterCollector filter
49
+
50
+ @::["__run#{camelized}s"] = (params, callback) ->
51
+ return callback() unless @["__#{filter}s"]
52
+
53
+ runners = @["__#{filter}s"]
54
+ filterer = @
55
+
56
+ if runners.length == 1
57
+ return runners[0].apply @, params.include(callback)
58
+
59
+ Joosy.synchronize (context) ->
60
+ runners.each (runner) ->
61
+ context.do (done) ->
62
+ runner.apply filterer, params.include(done)
63
+ context.after callback
64
+
65
+ # AMD wrapper
66
+ if define?.amd?
67
+ define 'joosy/modules/filters', -> Joosy.Modules.Filters
@@ -1,4 +1,4 @@
1
- #= require joosy/core/joosy
1
+ #= require joosy/joosy
2
2
 
3
3
  #
4
4
  # Wrappers for console.log
@@ -23,7 +23,7 @@ Joosy.Modules.Log =
23
23
  # Runs `log` if debug is active
24
24
  #
25
25
  debug: (args...) ->
26
- return unless Joosy.Application.config.debug
26
+ return unless Joosy.debug()
27
27
  @log args...
28
28
 
29
29
  #
@@ -33,6 +33,10 @@ Joosy.Modules.Log =
33
33
  # @param [String] string Message to log
34
34
  #
35
35
  debugAs: (context, string, args...) ->
36
- return unless Joosy.Application.config.debug
36
+ return unless Joosy.debug()
37
37
  context = Joosy.Module.__className(context) || 'unknown context'
38
38
  @debug "#{context}> #{string}", args...
39
+
40
+ # AMD wrapper
41
+ if define?.amd?
42
+ define 'joosy/modules/log', -> Joosy.Modules.Log
@@ -0,0 +1,51 @@
1
+ Joosy.Modules.Page_Scrolling =
2
+
3
+ included: ->
4
+ #
5
+ # Sets the position where page will be scrolled to after load.
6
+ #
7
+ # @note If you use animated scroll joosy will atempt to temporarily fix the
8
+ # height of your document while scrolling to prevent jump effect.
9
+ #
10
+ # @param [jQuery] element Element to scroll to
11
+ # @param [Hash] options
12
+ #
13
+ # @option options [Integer] speed Sets the animation duration (500 is default)
14
+ # @option options [Integer] margin Defines the margin from element position.
15
+ # Can be negative.
16
+ #
17
+ @scroll = (element, options={}) ->
18
+ @::__scrollElement = element
19
+ @::__scrollSpeed = options.speed || 500
20
+ @::__scrollMargin = options.margin || 0
21
+
22
+ @paint (complete) ->
23
+ @__fixHeight() if @__scrollElement && @__scrollSpeed != 0
24
+ complete()
25
+
26
+ @afterLoad ->
27
+ @__performScrolling() if @__scrollElement
28
+
29
+ #
30
+ # Scrolls page to stored positions
31
+ #
32
+ __performScrolling: ->
33
+ scroll = $(@__extractSelector @__scrollElement).offset()?.top + @__scrollMargin
34
+ Joosy.Modules.Log.debugAs @, "Scrolling to #{@__extractSelector @__scrollElement}"
35
+ $('html, body').animate {scrollTop: scroll}, @__scrollSpeed, =>
36
+ if @__scrollSpeed != 0
37
+ @__releaseHeight()
38
+
39
+ #
40
+ # Freezes the page height through $(html).
41
+ #
42
+ # Required to implement better {Joosy.Page.scroll} behavior.
43
+ #
44
+ __fixHeight: ->
45
+ $('html').css 'min-height', $(document).height()
46
+
47
+ #
48
+ # Undo {#__fixHeight}
49
+ #
50
+ __releaseHeight: ->
51
+ $('html').css 'min-height', ''