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

Sign up to get free protection for your applications and to get access to all the features.
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