joosy 1.1.2 → 1.2.0.alpha.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -7
  3. data/Gemfile +1 -11
  4. data/Gruntfile.coffee +138 -0
  5. data/README.md +65 -24
  6. data/bin/joosy +21 -0
  7. data/bower.json +23 -0
  8. data/joosy.gemspec +6 -12
  9. data/lib/joosy.js +3754 -0
  10. data/lib/joosy.rb +8 -9
  11. data/package.json +37 -0
  12. data/spec/{javascripts/helpers/spec_helper.js.coffee → helpers/helper.coffee} +0 -0
  13. data/spec/{javascripts/joosy/core/application_spec.js.coffee → joosy/core/application_spec.coffee} +0 -0
  14. data/spec/{javascripts/joosy/core/form_spec.js.coffee → joosy/core/form_spec.coffee} +30 -30
  15. data/spec/{javascripts/joosy/core/helpers/forms_spec.js.coffee → joosy/core/helpers/forms_spec.coffee} +0 -0
  16. data/spec/{javascripts/joosy/core/helpers/view_spec.js.coffee → joosy/core/helpers/view_spec.coffee} +0 -0
  17. data/spec/{javascripts/joosy/core/helpers/widgets_spec.js.coffee → joosy/core/helpers/widgets_spec.coffee} +0 -0
  18. data/spec/{javascripts/joosy/core/joosy_spec.js.coffee → joosy/core/joosy_spec.coffee} +0 -0
  19. data/spec/{javascripts/joosy/core/layout_spec.js.coffee → joosy/core/layout_spec.coffee} +0 -0
  20. data/spec/{javascripts/joosy/core/modules/container_spec.js.coffee → joosy/core/modules/container_spec.coffee} +1 -1
  21. data/spec/{javascripts/joosy/core/modules/events_spec.js.coffee → joosy/core/modules/events_spec.coffee} +0 -0
  22. data/spec/{javascripts/joosy/core/modules/filters_spec.js.coffee → joosy/core/modules/filters_spec.coffee} +0 -0
  23. data/spec/{javascripts/joosy/core/modules/log_spec.js.coffee → joosy/core/modules/log_spec.coffee} +0 -0
  24. data/spec/{javascripts/joosy/core/modules/module_spec.js.coffee → joosy/core/modules/module_spec.coffee} +0 -0
  25. data/spec/{javascripts/joosy/core/modules/renderer_spec.js.coffee → joosy/core/modules/renderer_spec.coffee} +35 -0
  26. data/spec/{javascripts/joosy/core/modules/time_manager_spec.js.coffee → joosy/core/modules/time_manager_spec.coffee} +0 -0
  27. data/spec/{javascripts/joosy/core/modules/widget_manager_spec.js.coffee → joosy/core/modules/widget_manager_spec.coffee} +0 -0
  28. data/spec/{javascripts/joosy/core/page_spec.js.coffee → joosy/core/page_spec.coffee} +0 -0
  29. data/spec/{javascripts/joosy/core/resource/collection_spec.js.coffee → joosy/core/resource/collection_spec.coffee} +0 -0
  30. data/spec/{javascripts/joosy/core/resource/generic_spec.js.coffee → joosy/core/resource/generic_spec.coffee} +0 -0
  31. data/spec/{javascripts/joosy/core/resource/rest_collection_spec.js.coffee → joosy/core/resource/rest_collection_spec.coffee} +0 -0
  32. data/spec/{javascripts/joosy/core/resource/rest_spec.js.coffee → joosy/core/resource/rest_spec.coffee} +0 -8
  33. data/spec/{javascripts/joosy/core/router_spec.js.coffee → joosy/core/router_spec.coffee} +19 -22
  34. data/spec/{javascripts/joosy/core/templaters/rails_jst_spec.js.coffee → joosy/core/templaters/rails_jst_spec.coffee} +0 -0
  35. data/spec/{javascripts/joosy/core/widget_spec.js.coffee → joosy/core/widget_spec.coffee} +0 -0
  36. data/spec/{javascripts/joosy/preloaders/caching_spec.js.coffee → joosy/preloaders/caching_spec.coffee} +2 -2
  37. data/spec/{javascripts/joosy/preloaders/inline_spec.js.coffee → joosy/preloaders/inline_spec.coffee} +1 -1
  38. data/spec/support/test.js +1 -0
  39. data/{app/assets/javascripts/joosy/core/application.js.coffee → src/joosy/core/application.coffee} +0 -0
  40. data/{app/assets/javascripts/joosy/core/form.js.coffee → src/joosy/core/form.coffee} +5 -5
  41. data/{app/assets/javascripts/joosy/core/helpers/form.js.coffee → src/joosy/core/helpers/form.coffee} +0 -0
  42. data/{app/assets/javascripts/joosy/core/helpers/view.js.coffee → src/joosy/core/helpers/view.coffee} +0 -0
  43. data/{app/assets/javascripts/joosy/core/helpers/widgets.js.coffee → src/joosy/core/helpers/widgets.coffee} +0 -0
  44. data/{app/assets/javascripts/joosy/core/joosy.js.coffee → src/joosy/core/joosy.coffee} +1 -1
  45. data/{app/assets/javascripts/joosy/core/layout.js.coffee → src/joosy/core/layout.coffee} +0 -0
  46. data/{app/assets/javascripts/joosy/core/modules/container.js.coffee → src/joosy/core/modules/container.coffee} +1 -1
  47. data/{app/assets/javascripts/joosy/core/modules/events.js.coffee → src/joosy/core/modules/events.coffee} +4 -6
  48. data/{app/assets/javascripts/joosy/core/modules/filters.js.coffee → src/joosy/core/modules/filters.coffee} +0 -0
  49. data/{app/assets/javascripts/joosy/core/modules/log.js.coffee → src/joosy/core/modules/log.coffee} +0 -0
  50. data/{app/assets/javascripts/joosy/core/modules/module.js.coffee → src/joosy/core/modules/module.coffee} +0 -0
  51. data/{app/assets/javascripts/joosy/core/modules/renderer.js.coffee → src/joosy/core/modules/renderer.coffee} +1 -1
  52. data/{app/assets/javascripts/joosy/core/modules/time_manager.js.coffee → src/joosy/core/modules/time_manager.coffee} +0 -0
  53. data/{app/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee → src/joosy/core/modules/widgets_manager.coffee} +0 -0
  54. data/{app/assets/javascripts/joosy/core/page.js.coffee → src/joosy/core/page.coffee} +0 -1
  55. data/{app/assets/javascripts/joosy/core/preloader.js.coffee → src/joosy/core/preloader.coffee} +0 -0
  56. data/{app/assets/javascripts/joosy/core/resource/collection.js.coffee → src/joosy/core/resource/collection.coffee} +0 -0
  57. data/{app/assets/javascripts/joosy/core/resource/generic.js.coffee → src/joosy/core/resource/generic.coffee} +5 -5
  58. data/{app/assets/javascripts/joosy/core/resource/rest.js.coffee → src/joosy/core/resource/rest.coffee} +5 -5
  59. data/{app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee → src/joosy/core/resource/rest_collection.coffee} +0 -0
  60. data/src/joosy/core/resource/watcher.coffee +50 -0
  61. data/{app/assets/javascripts/joosy/core/router.js.coffee → src/joosy/core/router.coffee} +28 -30
  62. data/{app/assets/javascripts/joosy/core/templaters/rails_jst.js.coffee → src/joosy/core/templaters/rails_jst.coffee} +12 -2
  63. data/{app/assets/javascripts/joosy/core/widget.js.coffee → src/joosy/core/widget.coffee} +0 -0
  64. data/src/joosy/generators/command.coffee +49 -0
  65. data/src/joosy/generators/generator.coffee +93 -0
  66. data/src/joosy/generators/layout.coffee +20 -0
  67. data/src/joosy/generators/page.coffee +20 -0
  68. data/src/joosy/generators/project/base.coffee +28 -0
  69. data/src/joosy/generators/project/standalone.coffee +25 -0
  70. data/src/joosy/generators/project.coffee +16 -0
  71. data/src/joosy/generators/widget.coffee +20 -0
  72. data/{app/assets/javascripts/joosy/preloaders/caching.js.coffee → src/joosy/preloaders/caching.coffee} +0 -0
  73. data/{app/assets/javascripts/joosy/preloaders/inline.js.coffee → src/joosy/preloaders/inline.coffee} +0 -0
  74. data/src/joosy.coffee +2 -0
  75. data/src/vendor/metamorph.coffee +410 -0
  76. data/tasks/joosy.coffee +63 -0
  77. data/templates/application/base/application.coffee +11 -0
  78. data/{lib/rails/generators/joosy/templates/app/helpers/application.js.coffee → templates/application/base/helpers/application.coffee} +0 -0
  79. data/{lib/rails/generators/joosy/templates/app/layouts/application.js.coffee → templates/application/base/layouts/application.coffee} +0 -0
  80. data/{lib/rails/generators/joosy/templates/app/pages/application.js.coffee → templates/application/base/pages/application.coffee} +0 -0
  81. data/{lib/rails/generators/joosy/templates/app/pages/welcome/index.js.coffee → templates/application/base/pages/welcome/index.coffee} +3 -3
  82. data/templates/application/base/routes.coffee +3 -0
  83. data/{lib/rails/generators/joosy/templates/app → templates/application/base}/templates/layouts/application.jst.hamlc +0 -0
  84. data/{lib/rails/generators/joosy/templates/app → templates/application/base}/templates/pages/welcome/index.jst.hamlc +1 -2
  85. data/templates/application/standalone/.gitignore +5 -0
  86. data/templates/application/standalone/Gruntfile.coffee +40 -0
  87. data/templates/application/standalone/Procfile +1 -0
  88. data/templates/application/standalone/bower.json +7 -0
  89. data/templates/application/standalone/package.json +24 -0
  90. data/templates/application/standalone/source/index.haml +7 -0
  91. data/templates/application/standalone/stylesheets/application.styl +2 -0
  92. data/templates/layout/basic.coffee +2 -0
  93. data/templates/layout/namespaced.coffee +4 -0
  94. data/templates/page/basic.coffee +3 -0
  95. data/templates/page/namespaced.coffee +5 -0
  96. data/templates/widget/basic.coffee +2 -0
  97. data/templates/widget/namespaced.coffee +4 -0
  98. metadata +98 -179
  99. data/.codoopts +0 -5
  100. data/Gemfile.lock +0 -157
  101. data/Guardfile +0 -32
  102. data/LICENSE +0 -22
  103. data/MIT-LICENSE +0 -21
  104. data/Rakefile +0 -14
  105. data/app/assets/javascripts/joosy.js.coffee +0 -5
  106. data/app/helpers/joosy/sprockets_helper.rb +0 -41
  107. data/app/views/layouts/json_wrapper.json.erb +0 -1
  108. data/lib/joosy/rails/engine.rb +0 -24
  109. data/lib/joosy/version.rb +0 -3
  110. data/lib/rails/generators/joosy/application_generator.rb +0 -43
  111. data/lib/rails/generators/joosy/joosy_base.rb +0 -30
  112. data/lib/rails/generators/joosy/layout_generator.rb +0 -30
  113. data/lib/rails/generators/joosy/page_generator.rb +0 -42
  114. data/lib/rails/generators/joosy/preloader_generator.rb +0 -30
  115. data/lib/rails/generators/joosy/resource_generator.rb +0 -40
  116. data/lib/rails/generators/joosy/templates/app/layouts/template.js.coffee +0 -2
  117. data/lib/rails/generators/joosy/templates/app/pages/template.js.coffee +0 -5
  118. data/lib/rails/generators/joosy/templates/app/resources/template.js.coffee +0 -2
  119. data/lib/rails/generators/joosy/templates/app/resources/template_with_namespace.js.coffee +0 -4
  120. data/lib/rails/generators/joosy/templates/app/routes.js.coffee +0 -8
  121. data/lib/rails/generators/joosy/templates/app/widgets/template.js.coffee +0 -2
  122. data/lib/rails/generators/joosy/templates/app.js.coffee +0 -11
  123. data/lib/rails/generators/joosy/templates/app_controller.rb +0 -9
  124. data/lib/rails/generators/joosy/templates/app_preloader.js.coffee.erb +0 -13
  125. data/lib/rails/generators/joosy/templates/app_railties.js.coffee.erb +0 -11
  126. data/lib/rails/generators/joosy/templates/preload.html.erb +0 -26
  127. data/lib/rails/generators/joosy/templates/preload.html.haml +0 -19
  128. data/lib/rails/generators/joosy/templates/preload.html.slim +0 -19
  129. data/lib/rails/generators/joosy/widget_generator.rb +0 -30
  130. data/lib/rails/resources_with_joosy.rb +0 -11
  131. data/spec/javascripts/support/assets/coolface.jpg +0 -0
  132. data/spec/javascripts/support/assets/okay.jpg +0 -0
  133. data/spec/javascripts/support/assets/test.js +0 -1
  134. data/spec/javascripts/support/jasmine.yml +0 -74
  135. data/spec/javascripts/support/jasmine_config.rb +0 -23
  136. data/spec/javascripts/support/jasmine_runner.rb +0 -32
  137. data/spec/javascripts/support/sinon-1.3.1.js +0 -3469
  138. data/spec/javascripts/support/sinon-ie-1.3.1.js.skip +0 -82
  139. data/vendor/assets/javascripts/jquery.form.js +0 -1190
  140. data/vendor/assets/javascripts/jquery.hashchange.js +0 -390
  141. data/vendor/assets/javascripts/metamorph.js +0 -409
  142. data/vendor/assets/javascripts/sugar.js +0 -8637
@@ -0,0 +1,410 @@
1
+ # ==========================================================================
2
+ # Project: metamorph
3
+ # Copyright: ©2013 Tilde, Inc. All rights reserved.
4
+ # ==========================================================================
5
+ ((window) ->
6
+ K = ->
7
+
8
+ guid = 0
9
+ document = window.document
10
+
11
+ # Feature-detect the W3C range API, the extended check is for IE9 which only partially supports ranges
12
+ supportsRange = document and ("createRange" of document) and (typeof Range isnt "undefined") and Range::createContextualFragment
13
+
14
+ # Internet Explorer prior to 9 does not allow setting innerHTML if the first element
15
+ # is a "zero-scope" element. This problem can be worked around by making
16
+ # the first node an invisible text node. We, like Modernizr, use ­
17
+ needsShy = document and (->
18
+ testEl = document.createElement("div")
19
+ testEl.innerHTML = "<div></div>"
20
+ testEl.firstChild.innerHTML = "<script></script>"
21
+ testEl.firstChild.innerHTML is ""
22
+ )()
23
+
24
+ # IE 8 (and likely earlier) likes to move whitespace preceeding
25
+ # a script tag to appear after it. This means that we can
26
+ # accidentally remove whitespace when updating a morph.
27
+ movesWhitespace = document and (->
28
+ testEl = document.createElement("div")
29
+ testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value"
30
+ testEl.childNodes[0].nodeValue is "Test:" and testEl.childNodes[2].nodeValue is " Value"
31
+ )()
32
+
33
+ # Constructor that supports either Metamorph('foo') or new
34
+ # Metamorph('foo');
35
+ #
36
+ # Takes a string of HTML as the argument.
37
+ Metamorph = (html) ->
38
+ self = undefined
39
+ if this instanceof Metamorph
40
+ self = this
41
+ else
42
+ self = new K()
43
+ self.innerHTML = html
44
+ myGuid = "metamorph-" + (guid++)
45
+ self.start = myGuid + "-start"
46
+ self.end = myGuid + "-end"
47
+ self
48
+
49
+ K:: = Metamorph::
50
+ rangeFor = undefined
51
+ htmlFunc = undefined
52
+ removeFunc = undefined
53
+ outerHTMLFunc = undefined
54
+ appendToFunc = undefined
55
+ afterFunc = undefined
56
+ prependFunc = undefined
57
+ startTagFunc = undefined
58
+ endTagFunc = undefined
59
+ outerHTMLFunc = ->
60
+ @startTag() + @innerHTML + @endTag()
61
+
62
+ startTagFunc = ->
63
+
64
+ #
65
+ # * We replace chevron by its hex code in order to prevent escaping problems.
66
+ # * Check this thread for more explaination:
67
+ # * http://stackoverflow.com/questions/8231048/why-use-x3c-instead-of-when-generating-html-from-javascript
68
+ #
69
+ "<script id='" + @start + "' type='text/x-placeholder'></script>"
70
+
71
+ endTagFunc = ->
72
+
73
+ #
74
+ # * We replace chevron by its hex code in order to prevent escaping problems.
75
+ # * Check this thread for more explaination:
76
+ # * http://stackoverflow.com/questions/8231048/why-use-x3c-instead-of-when-generating-html-from-javascript
77
+ #
78
+ "<script id='" + @end + "' type='text/x-placeholder'></script>"
79
+
80
+
81
+ # If we have the W3C range API, this process is relatively straight forward.
82
+ if supportsRange
83
+
84
+ # Get a range for the current morph. Optionally include the starting and
85
+ # ending placeholders.
86
+ rangeFor = (morph, outerToo) ->
87
+ range = document.createRange()
88
+ before = document.getElementById(morph.start)
89
+ after = document.getElementById(morph.end)
90
+ if outerToo
91
+ range.setStartBefore before
92
+ range.setEndAfter after
93
+ else
94
+ range.setStartAfter before
95
+ range.setEndBefore after
96
+ range
97
+
98
+ htmlFunc = (html, outerToo) ->
99
+
100
+ # get a range for the current metamorph object
101
+ range = rangeFor(this, outerToo)
102
+
103
+ # delete the contents of the range, which will be the
104
+ # nodes between the starting and ending placeholder.
105
+ range.deleteContents()
106
+
107
+ # create a new document fragment for the HTML
108
+ fragment = range.createContextualFragment(html)
109
+
110
+ # insert the fragment into the range
111
+ range.insertNode fragment
112
+
113
+ removeFunc = ->
114
+
115
+ # get a range for the current metamorph object including
116
+ # the starting and ending placeholders.
117
+ range = rangeFor(this, true)
118
+
119
+ # delete the entire range.
120
+ range.deleteContents()
121
+
122
+ appendToFunc = (node) ->
123
+ range = document.createRange()
124
+ range.setStart node
125
+ range.collapse false
126
+ frag = range.createContextualFragment(@outerHTML())
127
+ node.appendChild frag
128
+
129
+ afterFunc = (html) ->
130
+ range = document.createRange()
131
+ after = document.getElementById(@end)
132
+ range.setStartAfter after
133
+ range.setEndAfter after
134
+ fragment = range.createContextualFragment(html)
135
+ range.insertNode fragment
136
+
137
+ prependFunc = (html) ->
138
+ range = document.createRange()
139
+ start = document.getElementById(@start)
140
+ range.setStartAfter start
141
+ range.setEndAfter start
142
+ fragment = range.createContextualFragment(html)
143
+ range.insertNode fragment
144
+ else
145
+
146
+ ###
147
+ This code is mostly taken from jQuery, with one exception. In jQuery's case, we
148
+ have some HTML and we need to figure out how to convert it into some nodes.
149
+
150
+ In this case, jQuery needs to scan the HTML looking for an opening tag and use
151
+ that as the key for the wrap map. In our case, we know the parent node, and
152
+ can use its type as the key for the wrap map.
153
+ ###
154
+ wrapMap =
155
+ select: [1, "<select multiple='multiple'>", "</select>"]
156
+ fieldset: [1, "<fieldset>", "</fieldset>"]
157
+ table: [1, "<table>", "</table>"]
158
+ tbody: [2, "<table><tbody>", "</tbody></table>"]
159
+ tr: [3, "<table><tbody><tr>", "</tr></tbody></table>"]
160
+ colgroup: [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"]
161
+ map: [1, "<map>", "</map>"]
162
+ _default: [0, "", ""]
163
+
164
+ findChildById = (element, id) ->
165
+ return element if element.getAttribute("id") is id
166
+ len = element.childNodes.length
167
+ idx = undefined
168
+ node = undefined
169
+ found = undefined
170
+ idx = 0
171
+ while idx < len
172
+ node = element.childNodes[idx]
173
+ found = node.nodeType is 1 and findChildById(node, id)
174
+ return found if found
175
+ idx++
176
+
177
+ setInnerHTML = (element, html) ->
178
+ matches = []
179
+ if movesWhitespace
180
+
181
+ # Right now we only check for script tags with ids with the
182
+ # goal of targeting morphs.
183
+ html = html.replace(/(\s+)(<script id='([^']+)')/g, (match, spaces, tag, id) ->
184
+ matches.push [id, spaces]
185
+ tag
186
+ )
187
+ element.innerHTML = html
188
+
189
+ # If we have to do any whitespace adjustments do them now
190
+ if matches.length > 0
191
+ len = matches.length
192
+ idx = undefined
193
+ idx = 0
194
+ while idx < len
195
+ script = findChildById(element, matches[idx][0])
196
+ node = document.createTextNode(matches[idx][1])
197
+ script.parentNode.insertBefore node, script
198
+ idx++
199
+
200
+
201
+ ###
202
+ Given a parent node and some HTML, generate a set of nodes. Return the first
203
+ node, which will allow us to traverse the rest using nextSibling.
204
+
205
+ We need to do this because innerHTML in IE does not really parse the nodes.
206
+ ###
207
+ firstNodeFor = (parentNode, html) ->
208
+ arr = wrapMap[parentNode.tagName.toLowerCase()] or wrapMap._default
209
+ depth = arr[0]
210
+ start = arr[1]
211
+ end = arr[2]
212
+ html = "&shy;" + html if needsShy
213
+ element = document.createElement("div")
214
+ setInnerHTML element, start + html + end
215
+ i = 0
216
+
217
+ while i <= depth
218
+ element = element.firstChild
219
+ i++
220
+
221
+ # Look for &shy; to remove it.
222
+ if needsShy
223
+ shyElement = element
224
+
225
+ # Sometimes we get nameless elements with the shy inside
226
+ shyElement = shyElement.firstChild while shyElement.nodeType is 1 and not shyElement.nodeName
227
+
228
+ # At this point it's the actual unicode character.
229
+ shyElement.nodeValue = shyElement.nodeValue.slice(1) if shyElement.nodeType is 3 and shyElement.nodeValue.charAt(0) is "­"
230
+ element
231
+
232
+
233
+ ###
234
+ In some cases, Internet Explorer can create an anonymous node in
235
+ the hierarchy with no tagName. You can create this scenario via:
236
+
237
+ div = document.createElement("div");
238
+ div.innerHTML = "<table>&shy<script></script><tr><td>hi</td></tr></table>";
239
+ div.firstChild.firstChild.tagName //=> ""
240
+
241
+ If our script markers are inside such a node, we need to find that
242
+ node and use *it* as the marker.
243
+ ###
244
+ realNode = (start) ->
245
+ start = start.parentNode while start.parentNode.tagName is ""
246
+ start
247
+
248
+
249
+ ###
250
+ When automatically adding a tbody, Internet Explorer inserts the
251
+ tbody immediately before the first <tr>. Other browsers create it
252
+ before the first node, no matter what.
253
+
254
+ This means the the following code:
255
+
256
+ div = document.createElement("div");
257
+ div.innerHTML = "<table><script id='first'></script><tr><td>hi</td></tr><script id='last'></script></table>
258
+
259
+ Generates the following DOM in IE:
260
+
261
+ + div
262
+ + table
263
+ - script id='first'
264
+ + tbody
265
+ + tr
266
+ + td
267
+ - "hi"
268
+ - script id='last'
269
+
270
+ Which means that the two script tags, even though they were
271
+ inserted at the same point in the hierarchy in the original
272
+ HTML, now have different parents.
273
+
274
+ This code reparents the first script tag by making it the tbody's
275
+ first child.
276
+ ###
277
+ fixParentage = (start, end) ->
278
+ end.parentNode.insertBefore start, end.parentNode.firstChild if start.parentNode isnt end.parentNode
279
+
280
+ htmlFunc = (html, outerToo) ->
281
+
282
+ # get the real starting node. see realNode for details.
283
+ start = realNode(document.getElementById(@start))
284
+ end = document.getElementById(@end)
285
+ parentNode = end.parentNode
286
+ node = undefined
287
+ nextSibling = undefined
288
+ last = undefined
289
+
290
+ # make sure that the start and end nodes share the same
291
+ # parent. If not, fix it.
292
+ fixParentage start, end
293
+
294
+ # remove all of the nodes after the starting placeholder and
295
+ # before the ending placeholder.
296
+ node = start.nextSibling
297
+ while node
298
+ nextSibling = node.nextSibling
299
+ last = node is end
300
+
301
+ # if this is the last node, and we want to remove it as well,
302
+ # set the `end` node to the next sibling. This is because
303
+ # for the rest of the function, we insert the new nodes
304
+ # before the end (note that insertBefore(node, null) is
305
+ # the same as appendChild(node)).
306
+ #
307
+ # if we do not want to remove it, just break.
308
+ if last
309
+ if outerToo
310
+ end = node.nextSibling
311
+ else
312
+ break
313
+ node.parentNode.removeChild node
314
+
315
+ # if this is the last node and we didn't break before
316
+ # (because we wanted to remove the outer nodes), break
317
+ # now.
318
+ break if last
319
+ node = nextSibling
320
+
321
+ # get the first node for the HTML string, even in cases like
322
+ # tables and lists where a simple innerHTML on a div would
323
+ # swallow some of the content.
324
+ node = firstNodeFor(start.parentNode, html)
325
+
326
+ # copy the nodes for the HTML between the starting and ending
327
+ # placeholder.
328
+ while node
329
+ nextSibling = node.nextSibling
330
+ parentNode.insertBefore node, end
331
+ node = nextSibling
332
+
333
+
334
+ # remove the nodes in the DOM representing this metamorph.
335
+ #
336
+ # this includes the starting and ending placeholders.
337
+ removeFunc = ->
338
+ start = realNode(document.getElementById(@start))
339
+ end = document.getElementById(@end)
340
+ @html ""
341
+ start.parentNode.removeChild start
342
+ end.parentNode.removeChild end
343
+
344
+ appendToFunc = (parentNode) ->
345
+ node = firstNodeFor(parentNode, @outerHTML())
346
+ nextSibling = undefined
347
+ while node
348
+ nextSibling = node.nextSibling
349
+ parentNode.appendChild node
350
+ node = nextSibling
351
+
352
+ afterFunc = (html) ->
353
+
354
+ # get the real starting node. see realNode for details.
355
+ end = document.getElementById(@end)
356
+ insertBefore = end.nextSibling
357
+ parentNode = end.parentNode
358
+ nextSibling = undefined
359
+ node = undefined
360
+
361
+ # get the first node for the HTML string, even in cases like
362
+ # tables and lists where a simple innerHTML on a div would
363
+ # swallow some of the content.
364
+ node = firstNodeFor(parentNode, html)
365
+
366
+ # copy the nodes for the HTML between the starting and ending
367
+ # placeholder.
368
+ while node
369
+ nextSibling = node.nextSibling
370
+ parentNode.insertBefore node, insertBefore
371
+ node = nextSibling
372
+
373
+ prependFunc = (html) ->
374
+ start = document.getElementById(@start)
375
+ parentNode = start.parentNode
376
+ nextSibling = undefined
377
+ node = undefined
378
+ node = firstNodeFor(parentNode, html)
379
+ insertBefore = start.nextSibling
380
+ while node
381
+ nextSibling = node.nextSibling
382
+ parentNode.insertBefore node, insertBefore
383
+ node = nextSibling
384
+ Metamorph::html = (html) ->
385
+ @checkRemoved()
386
+ return @innerHTML if html is `undefined`
387
+ htmlFunc.call this, html
388
+ @innerHTML = html
389
+
390
+ Metamorph::replaceWith = (html) ->
391
+ @checkRemoved()
392
+ htmlFunc.call this, html, true
393
+
394
+ Metamorph::remove = removeFunc
395
+ Metamorph::outerHTML = outerHTMLFunc
396
+ Metamorph::appendTo = appendToFunc
397
+ Metamorph::after = afterFunc
398
+ Metamorph::prepend = prependFunc
399
+ Metamorph::startTag = startTagFunc
400
+ Metamorph::endTag = endTagFunc
401
+ Metamorph::isRemoved = ->
402
+ before = document.getElementById(@start)
403
+ after = document.getElementById(@end)
404
+ not before or not after
405
+
406
+ Metamorph::checkRemoved = ->
407
+ throw new Error("Cannot perform operations on a Metamorph that is not in the DOM.") if @isRemoved()
408
+
409
+ window.Metamorph = Metamorph
410
+ ) this
@@ -0,0 +1,63 @@
1
+ module.exports = (grunt) ->
2
+
3
+ Path = require('path')
4
+
5
+ grunt.loadNpmTasks 'grunt-mincer'
6
+ grunt.loadNpmTasks 'grunt-contrib-connect'
7
+ grunt.loadNpmTasks 'grunt-contrib-uglify'
8
+ grunt.loadNpmTasks 'grunt-contrib-stylus'
9
+ grunt.loadNpmTasks 'grunt-contrib-cssmin'
10
+ grunt.loadNpmTasks 'grunt-bower-task'
11
+
12
+ grunt.registerTask 'joosy:compile', ['joosy:compile:code', 'joosy:compile:styles', 'joosy:compile:playground']
13
+ grunt.registerTask 'joosy:compile:code', ['mince:application', 'uglify:application']
14
+ grunt.registerTask 'joosy:compile:styles', ['stylus:application', 'cssmin:application']
15
+
16
+ grunt.registerTask 'joosy:compile:playground', ->
17
+ hamlc = require 'haml-coffee'
18
+ grunt.file.write 'public/index.html', hamlc.compile(grunt.file.read 'source/index.haml')()
19
+
20
+ grunt.registerTask 'joosy:server', ->
21
+ @async()
22
+ connect = require('connect')
23
+ mincer = require('mincer')
24
+ hamlc = require('haml-coffee')
25
+
26
+ mincer.StylusEngine.registerConfigurator (stylus) ->
27
+ stylus.options.paths.push Path.join(process.cwd(), 'public')
28
+ stylus.use require('nib')()
29
+
30
+ server = connect()
31
+ assets = new mincer.Environment(process.cwd())
32
+ assets.appendPath 'source',
33
+ assets.appendPath 'stylesheets',
34
+ assets.appendPath 'components'
35
+ assets.appendPath 'vendor'
36
+ assets.appendPath 'node_modules/joosy/lib'
37
+
38
+ server.use '/assets', mincer.createServer(assets)
39
+
40
+ server.use '/', (req, res, next) ->
41
+ if req.url == '/'
42
+ res.end hamlc.compile(grunt.file.read 'source/index.haml')()
43
+ else
44
+ next()
45
+
46
+ server.use connect.static('public')
47
+ server.listen 4000
48
+
49
+ grunt.registerTask 'joosy:server:production', ->
50
+ @async()
51
+ connect = require('connect')
52
+ server = connect()
53
+ server.use require('gzippo').staticGzip('public')
54
+ server.listen process.env['PORT'] ? 4000
55
+
56
+ grunt.registerTask 'joosy:postinstall', ->
57
+ @async
58
+
59
+ if grunt.file.exists('bower.json')
60
+ grunt.task.run 'bower:install'
61
+
62
+ if process.env['NODE_ENV'] == 'production'
63
+ grunt.task.run 'joosy:compile'
@@ -0,0 +1,11 @@
1
+ #= require jquery/jquery.js
2
+ #= require jquery-form/jquery.form.js
3
+ #= require sugar/release/sugar-full.min.js
4
+ #
5
+ #= require joosy
6
+ #
7
+ #= require_tree ./
8
+ #= require_self
9
+
10
+ $ ->
11
+ Joosy.Application.initialize '<%= application %>', 'body'
@@ -6,8 +6,8 @@ Joosy.namespace 'Welcome', ->
6
6
 
7
7
  @afterLoad ->
8
8
  @startHeartbeat()
9
- @content.css
10
- 'padding-top': "#{$(window).height() / 2 - 160}px"
9
+ @$content.css
10
+ 'padding-top': "#{$(window).height() / 2 - 80}px"
11
11
 
12
12
  elements:
13
13
  content: '#content'
@@ -19,4 +19,4 @@ Joosy.namespace 'Welcome', ->
19
19
 
20
20
  startHeartbeat: ->
21
21
  @heartbeat = @setInterval 1500, =>
22
- @joosy.animate({opacity: 0.8}, 300).animate({opacity: 1}, 300)
22
+ @$joosy.animate({opacity: 0.8}, 300).animate({opacity: 1}, 300)
@@ -0,0 +1,3 @@
1
+ Joosy.Router.map
2
+ 404 : (path) -> alert "Page '#{path}' was not found :("
3
+ '/' : Welcome.IndexPage
@@ -1,7 +1,6 @@
1
1
  #wrapper
2
2
  #content
3
3
  %h1 Welcome aboard
4
- %h2{:style => 'margin-bottom: 30px'} You’re still riding Ruby on Rails.
5
4
  .joosy{:style => 'background: #F71; border-radius: 10px; width: 250px; display: inline-block'}
6
5
  %div{:style => 'color: #FFF; padding: 10px;'}
7
- But it's so joosy this time!
6
+ It's Joosy time!
@@ -0,0 +1,5 @@
1
+ components
2
+ node_modules
3
+ .DS_Store
4
+ public/assets
5
+ public/index.html
@@ -0,0 +1,40 @@
1
+ module.exports = (grunt) ->
2
+
3
+ grunt.loadNpmTasks 'joosy'
4
+
5
+ grunt.initConfig
6
+ bower:
7
+ install:
8
+ options:
9
+ copy: false
10
+ verbose: true
11
+
12
+ connect:
13
+ server:
14
+ options:
15
+ port: 4000
16
+ base: 'public'
17
+
18
+ mince:
19
+ application:
20
+ include: ['source', 'components', 'vendor', 'node_modules/joosy/src']
21
+ src: 'application.coffee'
22
+ dest: 'public/assets/application.js'
23
+
24
+ stylus:
25
+ application:
26
+ options:
27
+ paths: ['stylesheets', 'public']
28
+ files: 'public/assets/application.css': 'stylesheets/application.styl'
29
+
30
+ uglify:
31
+ application:
32
+ options:
33
+ sourceMap: 'public/assets/application.js.map'
34
+ files:
35
+ 'public/assets/application.js': 'public/assets/application.js'
36
+
37
+ cssmin:
38
+ application:
39
+ files:
40
+ 'public/assets/application.css': 'public/assets/application.css'
@@ -0,0 +1 @@
1
+ web: node_modules/.bin/grunt joosy:server:production
@@ -0,0 +1,7 @@
1
+ {
2
+ "dependencies": {
3
+ "jquery": "~2.0.2",
4
+ "sugar": "~1.3.9",
5
+ "jquery-form": "~3.32.0-2013.04.09"
6
+ }
7
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "dependencies": {
3
+ "joosy": "~<%= joosy_version %>",
4
+ "connect": "~2.7.11",
5
+ "gzippo": "~0.2.0",
6
+ "mincer": "~0.4.6",
7
+ "coffee-script": "~1.6.3",
8
+ "stylus": "~0.32.1",
9
+ "nib": "~0.9.1",
10
+ "haml-coffee": "~1.11.1",
11
+ "grunt": "~0.4.1",
12
+ "grunt-mincer": "~0.3.1",
13
+ "grunt-contrib-connect": "~0.3.0",
14
+ "grunt-contrib-uglify": "~0.2.2",
15
+ "grunt-contrib-watch": "~0.4.4",
16
+ "grunt-contrib-stylus": "~0.5.0",
17
+ "grunt-contrib-cssmin": "~0.6.1",
18
+ "grunt-bower-task": "~0.2.3",
19
+ "grunt-cli": "~0.1.9"
20
+ },
21
+ "scripts": {
22
+ "postinstall": "node_modules/.bin/grunt joosy:postinstall"
23
+ }
24
+ }
@@ -0,0 +1,7 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %title
5
+ %link{:href => "assets/application.css", :media => "screen", :rel => "stylesheet", :type => "text/css"}/
6
+ %script{:src => "assets/application.js", :type => "text/javascript"}
7
+ %body
@@ -0,0 +1,2 @@
1
+ body
2
+ font-family arial,sans-serif
@@ -0,0 +1,2 @@
1
+ class @<%= class_name %>Layout extends ApplicationLayout
2
+ @view '<%= view_name %>'
@@ -0,0 +1,4 @@
1
+ Joosy.namespace '<%= namespace_name %>', ->
2
+
3
+ class @<%= class_name %>Layout extends ApplicationLayout
4
+ @view '<%= view_name %>'
@@ -0,0 +1,3 @@
1
+ class @<%= class_name %>Page extends ApplicationPage
2
+ @layout ApplicationLayout
3
+ @view '<%= view_name %>'
@@ -0,0 +1,5 @@
1
+ Joosy.namespace '<%= namespace_name %>', ->
2
+
3
+ class @<%= class_name %>Page extends ApplicationPage
4
+ @layout ApplicationLayout
5
+ @view '<%= view_name %>'
@@ -0,0 +1,2 @@
1
+ class @<%= class_name %>Widget extends Joosy.Widget
2
+ @view '<%= view_name %>'
@@ -0,0 +1,4 @@
1
+ Joosy.namespace '<%= namespace_name %>', ->
2
+
3
+ class @<%= class_name %>Widget extends Joosy.Widget
4
+ @view '<%= view_name %>'