async-debug 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/async/debug/application.rb +21 -0
  4. data/lib/async/debug/reactor_view.rb +7 -24
  5. data/lib/async/debug/version.rb +3 -20
  6. data/lib/async/debug.rb +15 -71
  7. data/license.md +21 -0
  8. data/readme.md +27 -0
  9. data.tar.gz.sig +0 -0
  10. metadata +45 -182
  11. metadata.gz.sig +0 -0
  12. data/pages/_heading.xnode +0 -2
  13. data/pages/_page.xnode +0 -42
  14. data/pages/controller.rb +0 -19
  15. data/pages/errors/exception.xnode +0 -5
  16. data/pages/errors/file-not-found.xnode +0 -5
  17. data/pages/index.xnode +0 -3
  18. data/pages/links.yaml +0 -4
  19. data/public/_components/@socketry/live/live.js +0 -157
  20. data/public/_components/@socketry/live/live.min.js +0 -1
  21. data/public/_components/jquery/jquery.js +0 -10872
  22. data/public/_components/jquery/jquery.min.js +0 -2
  23. data/public/_components/jquery/jquery.min.map +0 -1
  24. data/public/_components/jquery/jquery.slim.js +0 -8777
  25. data/public/_components/jquery/jquery.slim.min.js +0 -2
  26. data/public/_components/jquery/jquery.slim.min.map +0 -1
  27. data/public/_components/jquery-syntax/base/jquery.syntax.brush.apache.css +0 -12
  28. data/public/_components/jquery-syntax/base/jquery.syntax.brush.applescript.css +0 -5
  29. data/public/_components/jquery-syntax/base/jquery.syntax.brush.assembly.css +0 -8
  30. data/public/_components/jquery-syntax/base/jquery.syntax.brush.bash-script.css +0 -4
  31. data/public/_components/jquery-syntax/base/jquery.syntax.brush.bash.css +0 -2
  32. data/public/_components/jquery-syntax/base/jquery.syntax.brush.clang.css +0 -6
  33. data/public/_components/jquery-syntax/base/jquery.syntax.brush.css.css +0 -14
  34. data/public/_components/jquery-syntax/base/jquery.syntax.brush.diff.css +0 -16
  35. data/public/_components/jquery-syntax/base/jquery.syntax.brush.html.css +0 -5
  36. data/public/_components/jquery-syntax/base/jquery.syntax.brush.ocaml.css +0 -3
  37. data/public/_components/jquery-syntax/base/jquery.syntax.brush.protobuf.css +0 -2
  38. data/public/_components/jquery-syntax/base/jquery.syntax.brush.python.css +0 -6
  39. data/public/_components/jquery-syntax/base/jquery.syntax.brush.ruby.css +0 -2
  40. data/public/_components/jquery-syntax/base/jquery.syntax.brush.xml.css +0 -35
  41. data/public/_components/jquery-syntax/base/jquery.syntax.core.css +0 -58
  42. data/public/_components/jquery-syntax/base/jquery.syntax.editor.css +0 -6
  43. data/public/_components/jquery-syntax/base/theme.js +0 -1
  44. data/public/_components/jquery-syntax/bright/jquery.syntax.core.css +0 -27
  45. data/public/_components/jquery-syntax/bright/theme.js +0 -1
  46. data/public/_components/jquery-syntax/jquery.syntax.brush.apache.js +0 -3
  47. data/public/_components/jquery-syntax/jquery.syntax.brush.applescript.js +0 -5
  48. data/public/_components/jquery-syntax/jquery.syntax.brush.assembly.js +0 -3
  49. data/public/_components/jquery-syntax/jquery.syntax.brush.bash-script.js +0 -4
  50. data/public/_components/jquery-syntax/jquery.syntax.brush.bash.js +0 -2
  51. data/public/_components/jquery-syntax/jquery.syntax.brush.basic.js +0 -5
  52. data/public/_components/jquery-syntax/jquery.syntax.brush.clang.js +0 -5
  53. data/public/_components/jquery-syntax/jquery.syntax.brush.csharp.js +0 -4
  54. data/public/_components/jquery-syntax/jquery.syntax.brush.css.js +0 -5
  55. data/public/_components/jquery-syntax/jquery.syntax.brush.diff.js +0 -2
  56. data/public/_components/jquery-syntax/jquery.syntax.brush.go.js +0 -3
  57. data/public/_components/jquery-syntax/jquery.syntax.brush.haskell.js +0 -3
  58. data/public/_components/jquery-syntax/jquery.syntax.brush.html.js +0 -4
  59. data/public/_components/jquery-syntax/jquery.syntax.brush.io.js +0 -3
  60. data/public/_components/jquery-syntax/jquery.syntax.brush.java.js +0 -4
  61. data/public/_components/jquery-syntax/jquery.syntax.brush.javascript.js +0 -3
  62. data/public/_components/jquery-syntax/jquery.syntax.brush.kai.js +0 -2
  63. data/public/_components/jquery-syntax/jquery.syntax.brush.lisp.js +0 -2
  64. data/public/_components/jquery-syntax/jquery.syntax.brush.lua.js +0 -3
  65. data/public/_components/jquery-syntax/jquery.syntax.brush.nginx.js +0 -2
  66. data/public/_components/jquery-syntax/jquery.syntax.brush.ocaml.js +0 -4
  67. data/public/_components/jquery-syntax/jquery.syntax.brush.ooc.js +0 -4
  68. data/public/_components/jquery-syntax/jquery.syntax.brush.pascal.js +0 -4
  69. data/public/_components/jquery-syntax/jquery.syntax.brush.perl5.js +0 -3
  70. data/public/_components/jquery-syntax/jquery.syntax.brush.php-script.js +0 -4
  71. data/public/_components/jquery-syntax/jquery.syntax.brush.php.js +0 -2
  72. data/public/_components/jquery-syntax/jquery.syntax.brush.plain.js +0 -2
  73. data/public/_components/jquery-syntax/jquery.syntax.brush.protobuf.js +0 -3
  74. data/public/_components/jquery-syntax/jquery.syntax.brush.python.js +0 -5
  75. data/public/_components/jquery-syntax/jquery.syntax.brush.ruby.js +0 -5
  76. data/public/_components/jquery-syntax/jquery.syntax.brush.scala.js +0 -4
  77. data/public/_components/jquery-syntax/jquery.syntax.brush.smalltalk.js +0 -2
  78. data/public/_components/jquery-syntax/jquery.syntax.brush.sql.js +0 -4
  79. data/public/_components/jquery-syntax/jquery.syntax.brush.super-collider.js +0 -3
  80. data/public/_components/jquery-syntax/jquery.syntax.brush.swift.js +0 -3
  81. data/public/_components/jquery-syntax/jquery.syntax.brush.trenni.js +0 -2
  82. data/public/_components/jquery-syntax/jquery.syntax.brush.xml.js +0 -4
  83. data/public/_components/jquery-syntax/jquery.syntax.brush.yaml.js +0 -2
  84. data/public/_components/jquery-syntax/jquery.syntax.cache.js +0 -7
  85. data/public/_components/jquery-syntax/jquery.syntax.core.js +0 -34
  86. data/public/_components/jquery-syntax/jquery.syntax.editor.js +0 -11
  87. data/public/_components/jquery-syntax/jquery.syntax.js +0 -8
  88. data/public/_components/jquery-syntax/jquery.syntax.min.js +0 -13
  89. data/public/_components/jquery-syntax/paper/jquery.syntax.core.css +0 -31
  90. data/public/_components/jquery-syntax/paper/theme.js +0 -1
  91. data/public/_components/morphdom/morphdom-esm.js +0 -755
  92. data/public/_components/morphdom/morphdom-factory.js +0 -691
  93. data/public/_components/morphdom/morphdom-umd.js +0 -763
  94. data/public/_components/morphdom/morphdom-umd.min.js +0 -1
  95. data/public/_components/morphdom/morphdom.js +0 -757
  96. data/public/_static/icon.png +0 -0
  97. data/public/_static/links.js +0 -21
  98. /data/public/_static/{site.css → index.css} +0 -0
@@ -1,757 +0,0 @@
1
- 'use strict';
2
-
3
- var DOCUMENT_FRAGMENT_NODE = 11;
4
-
5
- function morphAttrs(fromNode, toNode) {
6
- var toNodeAttrs = toNode.attributes;
7
- var attr;
8
- var attrName;
9
- var attrNamespaceURI;
10
- var attrValue;
11
- var fromValue;
12
-
13
- // document-fragments dont have attributes so lets not do anything
14
- if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE || fromNode.nodeType === DOCUMENT_FRAGMENT_NODE) {
15
- return;
16
- }
17
-
18
- // update attributes on original DOM element
19
- for (var i = toNodeAttrs.length - 1; i >= 0; i--) {
20
- attr = toNodeAttrs[i];
21
- attrName = attr.name;
22
- attrNamespaceURI = attr.namespaceURI;
23
- attrValue = attr.value;
24
-
25
- if (attrNamespaceURI) {
26
- attrName = attr.localName || attrName;
27
- fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName);
28
-
29
- if (fromValue !== attrValue) {
30
- if (attr.prefix === 'xmlns'){
31
- attrName = attr.name; // It's not allowed to set an attribute with the XMLNS namespace without specifying the `xmlns` prefix
32
- }
33
- fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);
34
- }
35
- } else {
36
- fromValue = fromNode.getAttribute(attrName);
37
-
38
- if (fromValue !== attrValue) {
39
- fromNode.setAttribute(attrName, attrValue);
40
- }
41
- }
42
- }
43
-
44
- // Remove any extra attributes found on the original DOM element that
45
- // weren't found on the target element.
46
- var fromNodeAttrs = fromNode.attributes;
47
-
48
- for (var d = fromNodeAttrs.length - 1; d >= 0; d--) {
49
- attr = fromNodeAttrs[d];
50
- attrName = attr.name;
51
- attrNamespaceURI = attr.namespaceURI;
52
-
53
- if (attrNamespaceURI) {
54
- attrName = attr.localName || attrName;
55
-
56
- if (!toNode.hasAttributeNS(attrNamespaceURI, attrName)) {
57
- fromNode.removeAttributeNS(attrNamespaceURI, attrName);
58
- }
59
- } else {
60
- if (!toNode.hasAttribute(attrName)) {
61
- fromNode.removeAttribute(attrName);
62
- }
63
- }
64
- }
65
- }
66
-
67
- var range; // Create a range object for efficently rendering strings to elements.
68
- var NS_XHTML = 'http://www.w3.org/1999/xhtml';
69
-
70
- var doc = typeof document === 'undefined' ? undefined : document;
71
- var HAS_TEMPLATE_SUPPORT = !!doc && 'content' in doc.createElement('template');
72
- var HAS_RANGE_SUPPORT = !!doc && doc.createRange && 'createContextualFragment' in doc.createRange();
73
-
74
- function createFragmentFromTemplate(str) {
75
- var template = doc.createElement('template');
76
- template.innerHTML = str;
77
- return template.content.childNodes[0];
78
- }
79
-
80
- function createFragmentFromRange(str) {
81
- if (!range) {
82
- range = doc.createRange();
83
- range.selectNode(doc.body);
84
- }
85
-
86
- var fragment = range.createContextualFragment(str);
87
- return fragment.childNodes[0];
88
- }
89
-
90
- function createFragmentFromWrap(str) {
91
- var fragment = doc.createElement('body');
92
- fragment.innerHTML = str;
93
- return fragment.childNodes[0];
94
- }
95
-
96
- /**
97
- * This is about the same
98
- * var html = new DOMParser().parseFromString(str, 'text/html');
99
- * return html.body.firstChild;
100
- *
101
- * @method toElement
102
- * @param {String} str
103
- */
104
- function toElement(str) {
105
- str = str.trim();
106
- if (HAS_TEMPLATE_SUPPORT) {
107
- // avoid restrictions on content for things like `<tr><th>Hi</th></tr>` which
108
- // createContextualFragment doesn't support
109
- // <template> support not available in IE
110
- return createFragmentFromTemplate(str);
111
- } else if (HAS_RANGE_SUPPORT) {
112
- return createFragmentFromRange(str);
113
- }
114
-
115
- return createFragmentFromWrap(str);
116
- }
117
-
118
- /**
119
- * Returns true if two node's names are the same.
120
- *
121
- * NOTE: We don't bother checking `namespaceURI` because you will never find two HTML elements with the same
122
- * nodeName and different namespace URIs.
123
- *
124
- * @param {Element} a
125
- * @param {Element} b The target element
126
- * @return {boolean}
127
- */
128
- function compareNodeNames(fromEl, toEl) {
129
- var fromNodeName = fromEl.nodeName;
130
- var toNodeName = toEl.nodeName;
131
- var fromCodeStart, toCodeStart;
132
-
133
- if (fromNodeName === toNodeName) {
134
- return true;
135
- }
136
-
137
- fromCodeStart = fromNodeName.charCodeAt(0);
138
- toCodeStart = toNodeName.charCodeAt(0);
139
-
140
- // If the target element is a virtual DOM node or SVG node then we may
141
- // need to normalize the tag name before comparing. Normal HTML elements that are
142
- // in the "http://www.w3.org/1999/xhtml"
143
- // are converted to upper case
144
- if (fromCodeStart <= 90 && toCodeStart >= 97) { // from is upper and to is lower
145
- return fromNodeName === toNodeName.toUpperCase();
146
- } else if (toCodeStart <= 90 && fromCodeStart >= 97) { // to is upper and from is lower
147
- return toNodeName === fromNodeName.toUpperCase();
148
- } else {
149
- return false;
150
- }
151
- }
152
-
153
- /**
154
- * Create an element, optionally with a known namespace URI.
155
- *
156
- * @param {string} name the element name, e.g. 'div' or 'svg'
157
- * @param {string} [namespaceURI] the element's namespace URI, i.e. the value of
158
- * its `xmlns` attribute or its inferred namespace.
159
- *
160
- * @return {Element}
161
- */
162
- function createElementNS(name, namespaceURI) {
163
- return !namespaceURI || namespaceURI === NS_XHTML ?
164
- doc.createElement(name) :
165
- doc.createElementNS(namespaceURI, name);
166
- }
167
-
168
- /**
169
- * Copies the children of one DOM element to another DOM element
170
- */
171
- function moveChildren(fromEl, toEl) {
172
- var curChild = fromEl.firstChild;
173
- while (curChild) {
174
- var nextChild = curChild.nextSibling;
175
- toEl.appendChild(curChild);
176
- curChild = nextChild;
177
- }
178
- return toEl;
179
- }
180
-
181
- function syncBooleanAttrProp(fromEl, toEl, name) {
182
- if (fromEl[name] !== toEl[name]) {
183
- fromEl[name] = toEl[name];
184
- if (fromEl[name]) {
185
- fromEl.setAttribute(name, '');
186
- } else {
187
- fromEl.removeAttribute(name);
188
- }
189
- }
190
- }
191
-
192
- var specialElHandlers = {
193
- OPTION: function(fromEl, toEl) {
194
- var parentNode = fromEl.parentNode;
195
- if (parentNode) {
196
- var parentName = parentNode.nodeName.toUpperCase();
197
- if (parentName === 'OPTGROUP') {
198
- parentNode = parentNode.parentNode;
199
- parentName = parentNode && parentNode.nodeName.toUpperCase();
200
- }
201
- if (parentName === 'SELECT' && !parentNode.hasAttribute('multiple')) {
202
- if (fromEl.hasAttribute('selected') && !toEl.selected) {
203
- // Workaround for MS Edge bug where the 'selected' attribute can only be
204
- // removed if set to a non-empty value:
205
- // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12087679/
206
- fromEl.setAttribute('selected', 'selected');
207
- fromEl.removeAttribute('selected');
208
- }
209
- // We have to reset select element's selectedIndex to -1, otherwise setting
210
- // fromEl.selected using the syncBooleanAttrProp below has no effect.
211
- // The correct selectedIndex will be set in the SELECT special handler below.
212
- parentNode.selectedIndex = -1;
213
- }
214
- }
215
- syncBooleanAttrProp(fromEl, toEl, 'selected');
216
- },
217
- /**
218
- * The "value" attribute is special for the <input> element since it sets
219
- * the initial value. Changing the "value" attribute without changing the
220
- * "value" property will have no effect since it is only used to the set the
221
- * initial value. Similar for the "checked" attribute, and "disabled".
222
- */
223
- INPUT: function(fromEl, toEl) {
224
- syncBooleanAttrProp(fromEl, toEl, 'checked');
225
- syncBooleanAttrProp(fromEl, toEl, 'disabled');
226
-
227
- if (fromEl.value !== toEl.value) {
228
- fromEl.value = toEl.value;
229
- }
230
-
231
- if (!toEl.hasAttribute('value')) {
232
- fromEl.removeAttribute('value');
233
- }
234
- },
235
-
236
- TEXTAREA: function(fromEl, toEl) {
237
- var newValue = toEl.value;
238
- if (fromEl.value !== newValue) {
239
- fromEl.value = newValue;
240
- }
241
-
242
- var firstChild = fromEl.firstChild;
243
- if (firstChild) {
244
- // Needed for IE. Apparently IE sets the placeholder as the
245
- // node value and vise versa. This ignores an empty update.
246
- var oldValue = firstChild.nodeValue;
247
-
248
- if (oldValue == newValue || (!newValue && oldValue == fromEl.placeholder)) {
249
- return;
250
- }
251
-
252
- firstChild.nodeValue = newValue;
253
- }
254
- },
255
- SELECT: function(fromEl, toEl) {
256
- if (!toEl.hasAttribute('multiple')) {
257
- var selectedIndex = -1;
258
- var i = 0;
259
- // We have to loop through children of fromEl, not toEl since nodes can be moved
260
- // from toEl to fromEl directly when morphing.
261
- // At the time this special handler is invoked, all children have already been morphed
262
- // and appended to / removed from fromEl, so using fromEl here is safe and correct.
263
- var curChild = fromEl.firstChild;
264
- var optgroup;
265
- var nodeName;
266
- while(curChild) {
267
- nodeName = curChild.nodeName && curChild.nodeName.toUpperCase();
268
- if (nodeName === 'OPTGROUP') {
269
- optgroup = curChild;
270
- curChild = optgroup.firstChild;
271
- } else {
272
- if (nodeName === 'OPTION') {
273
- if (curChild.hasAttribute('selected')) {
274
- selectedIndex = i;
275
- break;
276
- }
277
- i++;
278
- }
279
- curChild = curChild.nextSibling;
280
- if (!curChild && optgroup) {
281
- curChild = optgroup.nextSibling;
282
- optgroup = null;
283
- }
284
- }
285
- }
286
-
287
- fromEl.selectedIndex = selectedIndex;
288
- }
289
- }
290
- };
291
-
292
- var ELEMENT_NODE = 1;
293
- var DOCUMENT_FRAGMENT_NODE$1 = 11;
294
- var TEXT_NODE = 3;
295
- var COMMENT_NODE = 8;
296
-
297
- function noop() {}
298
-
299
- function defaultGetNodeKey(node) {
300
- if (node) {
301
- return (node.getAttribute && node.getAttribute('id')) || node.id;
302
- }
303
- }
304
-
305
- function morphdomFactory(morphAttrs) {
306
-
307
- return function morphdom(fromNode, toNode, options) {
308
- if (!options) {
309
- options = {};
310
- }
311
-
312
- if (typeof toNode === 'string') {
313
- if (fromNode.nodeName === '#document' || fromNode.nodeName === 'HTML' || fromNode.nodeName === 'BODY') {
314
- var toNodeHtml = toNode;
315
- toNode = doc.createElement('html');
316
- toNode.innerHTML = toNodeHtml;
317
- } else {
318
- toNode = toElement(toNode);
319
- }
320
- }
321
-
322
- var getNodeKey = options.getNodeKey || defaultGetNodeKey;
323
- var onBeforeNodeAdded = options.onBeforeNodeAdded || noop;
324
- var onNodeAdded = options.onNodeAdded || noop;
325
- var onBeforeElUpdated = options.onBeforeElUpdated || noop;
326
- var onElUpdated = options.onElUpdated || noop;
327
- var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop;
328
- var onNodeDiscarded = options.onNodeDiscarded || noop;
329
- var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop;
330
- var childrenOnly = options.childrenOnly === true;
331
-
332
- // This object is used as a lookup to quickly find all keyed elements in the original DOM tree.
333
- var fromNodesLookup = Object.create(null);
334
- var keyedRemovalList = [];
335
-
336
- function addKeyedRemoval(key) {
337
- keyedRemovalList.push(key);
338
- }
339
-
340
- function walkDiscardedChildNodes(node, skipKeyedNodes) {
341
- if (node.nodeType === ELEMENT_NODE) {
342
- var curChild = node.firstChild;
343
- while (curChild) {
344
-
345
- var key = undefined;
346
-
347
- if (skipKeyedNodes && (key = getNodeKey(curChild))) {
348
- // If we are skipping keyed nodes then we add the key
349
- // to a list so that it can be handled at the very end.
350
- addKeyedRemoval(key);
351
- } else {
352
- // Only report the node as discarded if it is not keyed. We do this because
353
- // at the end we loop through all keyed elements that were unmatched
354
- // and then discard them in one final pass.
355
- onNodeDiscarded(curChild);
356
- if (curChild.firstChild) {
357
- walkDiscardedChildNodes(curChild, skipKeyedNodes);
358
- }
359
- }
360
-
361
- curChild = curChild.nextSibling;
362
- }
363
- }
364
- }
365
-
366
- /**
367
- * Removes a DOM node out of the original DOM
368
- *
369
- * @param {Node} node The node to remove
370
- * @param {Node} parentNode The nodes parent
371
- * @param {Boolean} skipKeyedNodes If true then elements with keys will be skipped and not discarded.
372
- * @return {undefined}
373
- */
374
- function removeNode(node, parentNode, skipKeyedNodes) {
375
- if (onBeforeNodeDiscarded(node) === false) {
376
- return;
377
- }
378
-
379
- if (parentNode) {
380
- parentNode.removeChild(node);
381
- }
382
-
383
- onNodeDiscarded(node);
384
- walkDiscardedChildNodes(node, skipKeyedNodes);
385
- }
386
-
387
- // // TreeWalker implementation is no faster, but keeping this around in case this changes in the future
388
- // function indexTree(root) {
389
- // var treeWalker = document.createTreeWalker(
390
- // root,
391
- // NodeFilter.SHOW_ELEMENT);
392
- //
393
- // var el;
394
- // while((el = treeWalker.nextNode())) {
395
- // var key = getNodeKey(el);
396
- // if (key) {
397
- // fromNodesLookup[key] = el;
398
- // }
399
- // }
400
- // }
401
-
402
- // // NodeIterator implementation is no faster, but keeping this around in case this changes in the future
403
- //
404
- // function indexTree(node) {
405
- // var nodeIterator = document.createNodeIterator(node, NodeFilter.SHOW_ELEMENT);
406
- // var el;
407
- // while((el = nodeIterator.nextNode())) {
408
- // var key = getNodeKey(el);
409
- // if (key) {
410
- // fromNodesLookup[key] = el;
411
- // }
412
- // }
413
- // }
414
-
415
- function indexTree(node) {
416
- if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) {
417
- var curChild = node.firstChild;
418
- while (curChild) {
419
- var key = getNodeKey(curChild);
420
- if (key) {
421
- fromNodesLookup[key] = curChild;
422
- }
423
-
424
- // Walk recursively
425
- indexTree(curChild);
426
-
427
- curChild = curChild.nextSibling;
428
- }
429
- }
430
- }
431
-
432
- indexTree(fromNode);
433
-
434
- function handleNodeAdded(el) {
435
- onNodeAdded(el);
436
-
437
- var curChild = el.firstChild;
438
- while (curChild) {
439
- var nextSibling = curChild.nextSibling;
440
-
441
- var key = getNodeKey(curChild);
442
- if (key) {
443
- var unmatchedFromEl = fromNodesLookup[key];
444
- // if we find a duplicate #id node in cache, replace `el` with cache value
445
- // and morph it to the child node.
446
- if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) {
447
- curChild.parentNode.replaceChild(unmatchedFromEl, curChild);
448
- morphEl(unmatchedFromEl, curChild);
449
- } else {
450
- handleNodeAdded(curChild);
451
- }
452
- } else {
453
- // recursively call for curChild and it's children to see if we find something in
454
- // fromNodesLookup
455
- handleNodeAdded(curChild);
456
- }
457
-
458
- curChild = nextSibling;
459
- }
460
- }
461
-
462
- function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) {
463
- // We have processed all of the "to nodes". If curFromNodeChild is
464
- // non-null then we still have some from nodes left over that need
465
- // to be removed
466
- while (curFromNodeChild) {
467
- var fromNextSibling = curFromNodeChild.nextSibling;
468
- if ((curFromNodeKey = getNodeKey(curFromNodeChild))) {
469
- // Since the node is keyed it might be matched up later so we defer
470
- // the actual removal to later
471
- addKeyedRemoval(curFromNodeKey);
472
- } else {
473
- // NOTE: we skip nested keyed nodes from being removed since there is
474
- // still a chance they will be matched up later
475
- removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */);
476
- }
477
- curFromNodeChild = fromNextSibling;
478
- }
479
- }
480
-
481
- function morphEl(fromEl, toEl, childrenOnly) {
482
- var toElKey = getNodeKey(toEl);
483
-
484
- if (toElKey) {
485
- // If an element with an ID is being morphed then it will be in the final
486
- // DOM so clear it out of the saved elements collection
487
- delete fromNodesLookup[toElKey];
488
- }
489
-
490
- if (!childrenOnly) {
491
- // optional
492
- if (onBeforeElUpdated(fromEl, toEl) === false) {
493
- return;
494
- }
495
-
496
- // update attributes on original DOM element first
497
- morphAttrs(fromEl, toEl);
498
- // optional
499
- onElUpdated(fromEl);
500
-
501
- if (onBeforeElChildrenUpdated(fromEl, toEl) === false) {
502
- return;
503
- }
504
- }
505
-
506
- if (fromEl.nodeName !== 'TEXTAREA') {
507
- morphChildren(fromEl, toEl);
508
- } else {
509
- specialElHandlers.TEXTAREA(fromEl, toEl);
510
- }
511
- }
512
-
513
- function morphChildren(fromEl, toEl) {
514
- var curToNodeChild = toEl.firstChild;
515
- var curFromNodeChild = fromEl.firstChild;
516
- var curToNodeKey;
517
- var curFromNodeKey;
518
-
519
- var fromNextSibling;
520
- var toNextSibling;
521
- var matchingFromEl;
522
-
523
- // walk the children
524
- outer: while (curToNodeChild) {
525
- toNextSibling = curToNodeChild.nextSibling;
526
- curToNodeKey = getNodeKey(curToNodeChild);
527
-
528
- // walk the fromNode children all the way through
529
- while (curFromNodeChild) {
530
- fromNextSibling = curFromNodeChild.nextSibling;
531
-
532
- if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) {
533
- curToNodeChild = toNextSibling;
534
- curFromNodeChild = fromNextSibling;
535
- continue outer;
536
- }
537
-
538
- curFromNodeKey = getNodeKey(curFromNodeChild);
539
-
540
- var curFromNodeType = curFromNodeChild.nodeType;
541
-
542
- // this means if the curFromNodeChild doesnt have a match with the curToNodeChild
543
- var isCompatible = undefined;
544
-
545
- if (curFromNodeType === curToNodeChild.nodeType) {
546
- if (curFromNodeType === ELEMENT_NODE) {
547
- // Both nodes being compared are Element nodes
548
-
549
- if (curToNodeKey) {
550
- // The target node has a key so we want to match it up with the correct element
551
- // in the original DOM tree
552
- if (curToNodeKey !== curFromNodeKey) {
553
- // The current element in the original DOM tree does not have a matching key so
554
- // let's check our lookup to see if there is a matching element in the original
555
- // DOM tree
556
- if ((matchingFromEl = fromNodesLookup[curToNodeKey])) {
557
- if (fromNextSibling === matchingFromEl) {
558
- // Special case for single element removals. To avoid removing the original
559
- // DOM node out of the tree (since that can break CSS transitions, etc.),
560
- // we will instead discard the current node and wait until the next
561
- // iteration to properly match up the keyed target element with its matching
562
- // element in the original tree
563
- isCompatible = false;
564
- } else {
565
- // We found a matching keyed element somewhere in the original DOM tree.
566
- // Let's move the original DOM node into the current position and morph
567
- // it.
568
-
569
- // NOTE: We use insertBefore instead of replaceChild because we want to go through
570
- // the `removeNode()` function for the node that is being discarded so that
571
- // all lifecycle hooks are correctly invoked
572
- fromEl.insertBefore(matchingFromEl, curFromNodeChild);
573
-
574
- // fromNextSibling = curFromNodeChild.nextSibling;
575
-
576
- if (curFromNodeKey) {
577
- // Since the node is keyed it might be matched up later so we defer
578
- // the actual removal to later
579
- addKeyedRemoval(curFromNodeKey);
580
- } else {
581
- // NOTE: we skip nested keyed nodes from being removed since there is
582
- // still a chance they will be matched up later
583
- removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */);
584
- }
585
-
586
- curFromNodeChild = matchingFromEl;
587
- }
588
- } else {
589
- // The nodes are not compatible since the "to" node has a key and there
590
- // is no matching keyed node in the source tree
591
- isCompatible = false;
592
- }
593
- }
594
- } else if (curFromNodeKey) {
595
- // The original has a key
596
- isCompatible = false;
597
- }
598
-
599
- isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild);
600
- if (isCompatible) {
601
- // We found compatible DOM elements so transform
602
- // the current "from" node to match the current
603
- // target DOM node.
604
- // MORPH
605
- morphEl(curFromNodeChild, curToNodeChild);
606
- }
607
-
608
- } else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) {
609
- // Both nodes being compared are Text or Comment nodes
610
- isCompatible = true;
611
- // Simply update nodeValue on the original node to
612
- // change the text value
613
- if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) {
614
- curFromNodeChild.nodeValue = curToNodeChild.nodeValue;
615
- }
616
-
617
- }
618
- }
619
-
620
- if (isCompatible) {
621
- // Advance both the "to" child and the "from" child since we found a match
622
- // Nothing else to do as we already recursively called morphChildren above
623
- curToNodeChild = toNextSibling;
624
- curFromNodeChild = fromNextSibling;
625
- continue outer;
626
- }
627
-
628
- // No compatible match so remove the old node from the DOM and continue trying to find a
629
- // match in the original DOM. However, we only do this if the from node is not keyed
630
- // since it is possible that a keyed node might match up with a node somewhere else in the
631
- // target tree and we don't want to discard it just yet since it still might find a
632
- // home in the final DOM tree. After everything is done we will remove any keyed nodes
633
- // that didn't find a home
634
- if (curFromNodeKey) {
635
- // Since the node is keyed it might be matched up later so we defer
636
- // the actual removal to later
637
- addKeyedRemoval(curFromNodeKey);
638
- } else {
639
- // NOTE: we skip nested keyed nodes from being removed since there is
640
- // still a chance they will be matched up later
641
- removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */);
642
- }
643
-
644
- curFromNodeChild = fromNextSibling;
645
- } // END: while(curFromNodeChild) {}
646
-
647
- // If we got this far then we did not find a candidate match for
648
- // our "to node" and we exhausted all of the children "from"
649
- // nodes. Therefore, we will just append the current "to" node
650
- // to the end
651
- if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) {
652
- fromEl.appendChild(matchingFromEl);
653
- // MORPH
654
- morphEl(matchingFromEl, curToNodeChild);
655
- } else {
656
- var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild);
657
- if (onBeforeNodeAddedResult !== false) {
658
- if (onBeforeNodeAddedResult) {
659
- curToNodeChild = onBeforeNodeAddedResult;
660
- }
661
-
662
- if (curToNodeChild.actualize) {
663
- curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc);
664
- }
665
- fromEl.appendChild(curToNodeChild);
666
- handleNodeAdded(curToNodeChild);
667
- }
668
- }
669
-
670
- curToNodeChild = toNextSibling;
671
- curFromNodeChild = fromNextSibling;
672
- }
673
-
674
- cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey);
675
-
676
- var specialElHandler = specialElHandlers[fromEl.nodeName];
677
- if (specialElHandler) {
678
- specialElHandler(fromEl, toEl);
679
- }
680
- } // END: morphChildren(...)
681
-
682
- var morphedNode = fromNode;
683
- var morphedNodeType = morphedNode.nodeType;
684
- var toNodeType = toNode.nodeType;
685
-
686
- if (!childrenOnly) {
687
- // Handle the case where we are given two DOM nodes that are not
688
- // compatible (e.g. <div> --> <span> or <div> --> TEXT)
689
- if (morphedNodeType === ELEMENT_NODE) {
690
- if (toNodeType === ELEMENT_NODE) {
691
- if (!compareNodeNames(fromNode, toNode)) {
692
- onNodeDiscarded(fromNode);
693
- morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));
694
- }
695
- } else {
696
- // Going from an element node to a text node
697
- morphedNode = toNode;
698
- }
699
- } else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) { // Text or comment node
700
- if (toNodeType === morphedNodeType) {
701
- if (morphedNode.nodeValue !== toNode.nodeValue) {
702
- morphedNode.nodeValue = toNode.nodeValue;
703
- }
704
-
705
- return morphedNode;
706
- } else {
707
- // Text node to something else
708
- morphedNode = toNode;
709
- }
710
- }
711
- }
712
-
713
- if (morphedNode === toNode) {
714
- // The "to node" was not compatible with the "from node" so we had to
715
- // toss out the "from node" and use the "to node"
716
- onNodeDiscarded(fromNode);
717
- } else {
718
- if (toNode.isSameNode && toNode.isSameNode(morphedNode)) {
719
- return;
720
- }
721
-
722
- morphEl(morphedNode, toNode, childrenOnly);
723
-
724
- // We now need to loop over any keyed nodes that might need to be
725
- // removed. We only do the removal if we know that the keyed node
726
- // never found a match. When a keyed node is matched up we remove
727
- // it out of fromNodesLookup and we use fromNodesLookup to determine
728
- // if a keyed node has been matched up or not
729
- if (keyedRemovalList) {
730
- for (var i=0, len=keyedRemovalList.length; i<len; i++) {
731
- var elToRemove = fromNodesLookup[keyedRemovalList[i]];
732
- if (elToRemove) {
733
- removeNode(elToRemove, elToRemove.parentNode, false);
734
- }
735
- }
736
- }
737
- }
738
-
739
- if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) {
740
- if (morphedNode.actualize) {
741
- morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc);
742
- }
743
- // If we had to swap out the from node with a new node because the old
744
- // node was not compatible with the target node then we need to
745
- // replace the old DOM node in the original DOM tree. This is only
746
- // possible if the original DOM node was part of a DOM tree which
747
- // we know is the case if it has a parent node.
748
- fromNode.parentNode.replaceChild(morphedNode, fromNode);
749
- }
750
-
751
- return morphedNode;
752
- };
753
- }
754
-
755
- var morphdom = morphdomFactory(morphAttrs);
756
-
757
- module.exports = morphdom;