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.
- checksums.yaml +4 -4
- data/Gruntfile.coffee +56 -18
- data/bower.json +1 -1
- data/build/joosy/form.js +1 -0
- data/build/joosy/resources.js +1 -0
- data/build/joosy.js +2 -2774
- data/package.json +5 -4
- data/source/joosy/application.coffee +9 -7
- data/source/joosy/{extensions/resources-form/form.coffee → form.coffee} +58 -51
- data/source/joosy/helpers/form.coffee +241 -0
- data/source/joosy/helpers/index.coffee +3 -0
- data/source/joosy/helpers/routes.coffee +3 -1
- data/source/joosy/helpers/view.coffee +9 -9
- data/source/joosy/joosy.coffee +3 -5
- data/source/joosy/module.coffee +9 -4
- data/source/joosy/modules/dom.coffee +33 -31
- data/source/joosy/modules/events.coffee +24 -20
- data/source/joosy/modules/filters.coffee +38 -35
- data/source/joosy/modules/page/title.coffee +3 -3
- data/source/joosy/modules/renderer.coffee +23 -18
- data/source/joosy/modules/resources/identity_map.coffee +45 -0
- data/source/joosy/modules/resources/model.coffee +146 -0
- data/source/joosy/modules/widgets_manager.coffee +8 -8
- data/source/joosy/resources/array.coffee +0 -5
- data/source/joosy/resources/hash.coffee +8 -13
- data/source/joosy/resources/index.coffee +2 -0
- data/source/joosy/{extensions/resources → resources}/rest.coffee +48 -19
- data/source/joosy/resources/scalar.coffee +8 -10
- data/source/joosy/router.coffee +13 -12
- data/source/joosy/templaters/jst.coffee +3 -2
- data/source/joosy/widget.coffee +17 -15
- data/source/joosy.coffee +2 -0
- data/source/vendor/es5-shim.js +1316 -0
- data/source/vendor/inflections.js +598 -0
- data/source/vendor/metamorph.js +457 -0
- data/spec/helpers/matchers.coffee +4 -4
- data/spec/joosy/core/application_spec.coffee +1 -1
- data/spec/joosy/core/helpers/view_spec.coffee +2 -2
- data/spec/joosy/core/joosy_spec.coffee +8 -4
- data/spec/joosy/core/modules/dom_spec.coffee +7 -7
- data/spec/joosy/core/modules/events_spec.coffee +2 -2
- data/spec/joosy/core/modules/filters_spec.coffee +7 -8
- data/spec/joosy/core/modules/module_spec.coffee +5 -5
- data/spec/joosy/core/router_spec.coffee +3 -3
- data/spec/joosy/core/widget_spec.coffee +6 -6
- data/spec/joosy/environments/amd_spec.coffee +4 -2
- data/spec/joosy/environments/global_spec.coffee +1 -1
- data/spec/joosy/{extensions/form → form}/form_spec.coffee +9 -16
- data/spec/joosy/{extensions/form → form}/helpers/forms_spec.coffee +5 -5
- data/spec/joosy/{core/resources → resources}/array_spec.coffee +2 -2
- data/spec/joosy/{core/resources → resources}/hash_spec.coffee +0 -8
- data/spec/joosy/{core/modules/resources → resources/modules}/cacher_spec.coffee +0 -0
- data/spec/joosy/resources/modules/identity_map_spec.coffee +47 -0
- data/spec/joosy/{extensions/resources/base_spec.coffee → resources/modules/model_spec.coffee} +28 -48
- data/spec/joosy/{extensions/resources → resources}/rest_spec.coffee +29 -22
- data/spec/joosy/{core/resources → resources}/scalar_spec.coffee +8 -8
- data/templates/application/application.coffee.tt +0 -2
- data/templates/environment/app/haml/index.haml +2 -2
- data/templates/environment/package.json +1 -1
- metadata +23 -19
- data/build/joosy/extensions/resources-form.js +0 -590
- data/build/joosy/extensions/resources.js +0 -561
- data/source/joosy/extensions/resources/base.coffee +0 -282
- data/source/joosy/extensions/resources/index.coffee +0 -1
- data/source/joosy/extensions/resources-form/helpers/form.coffee +0 -104
- data/source/joosy/extensions/resources-form/index.coffee +0 -1
- data/source/metamorph.coffee +0 -410
data/source/metamorph.coffee
DELETED
@@ -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 = "­" + 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 ­ 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>­<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
|