joosy 1.2.0.alpha.73 → 1.2.0.beta.1

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/Gruntfile.coffee +56 -18
  3. data/bower.json +1 -1
  4. data/build/joosy/form.js +1 -0
  5. data/build/joosy/resources.js +1 -0
  6. data/build/joosy.js +2 -2774
  7. data/package.json +5 -4
  8. data/source/joosy/application.coffee +9 -7
  9. data/source/joosy/{extensions/resources-form/form.coffee → form.coffee} +58 -51
  10. data/source/joosy/helpers/form.coffee +241 -0
  11. data/source/joosy/helpers/index.coffee +3 -0
  12. data/source/joosy/helpers/routes.coffee +3 -1
  13. data/source/joosy/helpers/view.coffee +9 -9
  14. data/source/joosy/joosy.coffee +3 -5
  15. data/source/joosy/module.coffee +9 -4
  16. data/source/joosy/modules/dom.coffee +33 -31
  17. data/source/joosy/modules/events.coffee +24 -20
  18. data/source/joosy/modules/filters.coffee +38 -35
  19. data/source/joosy/modules/page/title.coffee +3 -3
  20. data/source/joosy/modules/renderer.coffee +23 -18
  21. data/source/joosy/modules/resources/identity_map.coffee +45 -0
  22. data/source/joosy/modules/resources/model.coffee +146 -0
  23. data/source/joosy/modules/widgets_manager.coffee +8 -8
  24. data/source/joosy/resources/array.coffee +0 -5
  25. data/source/joosy/resources/hash.coffee +8 -13
  26. data/source/joosy/resources/index.coffee +2 -0
  27. data/source/joosy/{extensions/resources → resources}/rest.coffee +48 -19
  28. data/source/joosy/resources/scalar.coffee +8 -10
  29. data/source/joosy/router.coffee +13 -12
  30. data/source/joosy/templaters/jst.coffee +3 -2
  31. data/source/joosy/widget.coffee +17 -15
  32. data/source/joosy.coffee +2 -0
  33. data/source/vendor/es5-shim.js +1316 -0
  34. data/source/vendor/inflections.js +598 -0
  35. data/source/vendor/metamorph.js +457 -0
  36. data/spec/helpers/matchers.coffee +4 -4
  37. data/spec/joosy/core/application_spec.coffee +1 -1
  38. data/spec/joosy/core/helpers/view_spec.coffee +2 -2
  39. data/spec/joosy/core/joosy_spec.coffee +8 -4
  40. data/spec/joosy/core/modules/dom_spec.coffee +7 -7
  41. data/spec/joosy/core/modules/events_spec.coffee +2 -2
  42. data/spec/joosy/core/modules/filters_spec.coffee +7 -8
  43. data/spec/joosy/core/modules/module_spec.coffee +5 -5
  44. data/spec/joosy/core/router_spec.coffee +3 -3
  45. data/spec/joosy/core/widget_spec.coffee +6 -6
  46. data/spec/joosy/environments/amd_spec.coffee +4 -2
  47. data/spec/joosy/environments/global_spec.coffee +1 -1
  48. data/spec/joosy/{extensions/form → form}/form_spec.coffee +9 -16
  49. data/spec/joosy/{extensions/form → form}/helpers/forms_spec.coffee +5 -5
  50. data/spec/joosy/{core/resources → resources}/array_spec.coffee +2 -2
  51. data/spec/joosy/{core/resources → resources}/hash_spec.coffee +0 -8
  52. data/spec/joosy/{core/modules/resources → resources/modules}/cacher_spec.coffee +0 -0
  53. data/spec/joosy/resources/modules/identity_map_spec.coffee +47 -0
  54. data/spec/joosy/{extensions/resources/base_spec.coffee → resources/modules/model_spec.coffee} +28 -48
  55. data/spec/joosy/{extensions/resources → resources}/rest_spec.coffee +29 -22
  56. data/spec/joosy/{core/resources → resources}/scalar_spec.coffee +8 -8
  57. data/templates/application/application.coffee.tt +0 -2
  58. data/templates/environment/app/haml/index.haml +2 -2
  59. data/templates/environment/package.json +1 -1
  60. metadata +23 -19
  61. data/build/joosy/extensions/resources-form.js +0 -590
  62. data/build/joosy/extensions/resources.js +0 -561
  63. data/source/joosy/extensions/resources/base.coffee +0 -282
  64. data/source/joosy/extensions/resources/index.coffee +0 -1
  65. data/source/joosy/extensions/resources-form/helpers/form.coffee +0 -104
  66. data/source/joosy/extensions/resources-form/index.coffee +0 -1
  67. data/source/metamorph.coffee +0 -410
@@ -1,410 +0,0 @@
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