clearwater 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,108 @@
1
+ require 'browser'
2
+ require 'clearwater/virtual_dom/js/virtual_dom.js'
3
+
4
+ module StringUtils
5
+ def self.camelize string
6
+ string.gsub(/_(\w)/) { |match| match.gsub(/_/, '').upcase }
7
+ end
8
+ end
9
+
10
+ module HashUtils
11
+ def self.camelize_keys(hash)
12
+ return nil if hash.nil?
13
+
14
+ Hash[hash.map { |k,v|
15
+ key = StringUtils.camelize(k)
16
+ value = if Hash === v
17
+ camelize_keys(v)
18
+ else
19
+ v
20
+ end
21
+
22
+ [key, value]
23
+ }]
24
+ end
25
+ end
26
+
27
+ module VirtualDOM
28
+ def self.node(tag_name, attributes, content)
29
+ content = Array(content).map { |node|
30
+ case node
31
+ when Node
32
+ node.node
33
+ else
34
+ node
35
+ end
36
+ }
37
+ attributes = HashUtils.camelize_keys(attributes).to_n
38
+ Node.new(`virtualDom.h(tag_name, attributes, content)`)
39
+ end
40
+
41
+ def self.create_element node
42
+ `virtualDom.create(node)`
43
+ end
44
+
45
+ class Document
46
+ def initialize(root=$document.create_element('div'))
47
+ @root = root
48
+ @rendered_nodes = {}
49
+ end
50
+
51
+ def render node
52
+ if rendered?
53
+ diff = @node.diff(node)
54
+ @tree = Element.new(@tree.patch(diff))
55
+ @node = node
56
+ else
57
+ @node = node
58
+ @tree = node.to_element
59
+ @root.inner_dom = @tree.to_n
60
+ @rendered = true
61
+ end
62
+ end
63
+
64
+ def rendered?
65
+ @rendered
66
+ end
67
+ end
68
+
69
+ class Node
70
+ attr_reader :node
71
+
72
+ def initialize(node)
73
+ @node = node
74
+ end
75
+
76
+ def method_missing *args, &block
77
+ node.send *args, &block
78
+ end
79
+
80
+ def to_element
81
+ Element.new(VirtualDOM.create_element(node))
82
+ end
83
+
84
+ def diff other
85
+ `virtualDom.diff(self.node, other.node)`
86
+ end
87
+
88
+ def patch diff
89
+ `virtualDom.patch(#{to_element.to_n}, diff)`
90
+ end
91
+ end
92
+
93
+ class Element
94
+ attr_reader :element
95
+
96
+ def initialize(element)
97
+ @element = element
98
+ end
99
+
100
+ def patch(diff)
101
+ `virtualDom.patch(#{element}, diff)`
102
+ end
103
+
104
+ def to_n
105
+ @element
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,1663 @@
1
+ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.virtualDom = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
+ var createElement = require("./vdom/create-element.js")
3
+
4
+ module.exports = createElement
5
+
6
+ },{"./vdom/create-element.js":14}],2:[function(require,module,exports){
7
+ var diff = require("./vtree/diff.js")
8
+
9
+ module.exports = diff
10
+
11
+ },{"./vtree/diff.js":34}],3:[function(require,module,exports){
12
+ var h = require("./virtual-hyperscript/index.js")
13
+
14
+ module.exports = h
15
+
16
+ },{"./virtual-hyperscript/index.js":21}],4:[function(require,module,exports){
17
+ var diff = require("./diff.js")
18
+ var patch = require("./patch.js")
19
+ var h = require("./h.js")
20
+ var create = require("./create-element.js")
21
+ var VNode = require('./vnode/vnode.js')
22
+ var VText = require('./vnode/vtext.js')
23
+
24
+ module.exports = {
25
+ diff: diff,
26
+ patch: patch,
27
+ h: h,
28
+ create: create,
29
+ VNode: VNode,
30
+ VText: VText
31
+ }
32
+
33
+ },{"./create-element.js":1,"./diff.js":2,"./h.js":3,"./patch.js":12,"./vnode/vnode.js":30,"./vnode/vtext.js":32}],5:[function(require,module,exports){
34
+ /*!
35
+ * Cross-Browser Split 1.1.1
36
+ * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
37
+ * Available under the MIT License
38
+ * ECMAScript compliant, uniform cross-browser split method
39
+ */
40
+
41
+ /**
42
+ * Splits a string into an array of strings using a regex or string separator. Matches of the
43
+ * separator are not included in the result array. However, if `separator` is a regex that contains
44
+ * capturing groups, backreferences are spliced into the result each time `separator` is matched.
45
+ * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably
46
+ * cross-browser.
47
+ * @param {String} str String to split.
48
+ * @param {RegExp|String} separator Regex or string to use for separating the string.
49
+ * @param {Number} [limit] Maximum number of items to include in the result array.
50
+ * @returns {Array} Array of substrings.
51
+ * @example
52
+ *
53
+ * // Basic use
54
+ * split('a b c d', ' ');
55
+ * // -> ['a', 'b', 'c', 'd']
56
+ *
57
+ * // With limit
58
+ * split('a b c d', ' ', 2);
59
+ * // -> ['a', 'b']
60
+ *
61
+ * // Backreferences in result array
62
+ * split('..word1 word2..', /([a-z]+)(\d+)/i);
63
+ * // -> ['..', 'word', '1', ' ', 'word', '2', '..']
64
+ */
65
+ module.exports = (function split(undef) {
66
+
67
+ var nativeSplit = String.prototype.split,
68
+ compliantExecNpcg = /()??/.exec("")[1] === undef,
69
+ // NPCG: nonparticipating capturing group
70
+ self;
71
+
72
+ self = function(str, separator, limit) {
73
+ // If `separator` is not a regex, use `nativeSplit`
74
+ if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
75
+ return nativeSplit.call(str, separator, limit);
76
+ }
77
+ var output = [],
78
+ flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.extended ? "x" : "") + // Proposed for ES6
79
+ (separator.sticky ? "y" : ""),
80
+ // Firefox 3+
81
+ lastLastIndex = 0,
82
+ // Make `global` and avoid `lastIndex` issues by working with a copy
83
+ separator = new RegExp(separator.source, flags + "g"),
84
+ separator2, match, lastIndex, lastLength;
85
+ str += ""; // Type-convert
86
+ if (!compliantExecNpcg) {
87
+ // Doesn't need flags gy, but they don't hurt
88
+ separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
89
+ }
90
+ /* Values for `limit`, per the spec:
91
+ * If undefined: 4294967295 // Math.pow(2, 32) - 1
92
+ * If 0, Infinity, or NaN: 0
93
+ * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
94
+ * If negative number: 4294967296 - Math.floor(Math.abs(limit))
95
+ * If other: Type-convert, then use the above rules
96
+ */
97
+ limit = limit === undef ? -1 >>> 0 : // Math.pow(2, 32) - 1
98
+ limit >>> 0; // ToUint32(limit)
99
+ while (match = separator.exec(str)) {
100
+ // `separator.lastIndex` is not reliable cross-browser
101
+ lastIndex = match.index + match[0].length;
102
+ if (lastIndex > lastLastIndex) {
103
+ output.push(str.slice(lastLastIndex, match.index));
104
+ // Fix browsers whose `exec` methods don't consistently return `undefined` for
105
+ // nonparticipating capturing groups
106
+ if (!compliantExecNpcg && match.length > 1) {
107
+ match[0].replace(separator2, function() {
108
+ for (var i = 1; i < arguments.length - 2; i++) {
109
+ if (arguments[i] === undef) {
110
+ match[i] = undef;
111
+ }
112
+ }
113
+ });
114
+ }
115
+ if (match.length > 1 && match.index < str.length) {
116
+ Array.prototype.push.apply(output, match.slice(1));
117
+ }
118
+ lastLength = match[0].length;
119
+ lastLastIndex = lastIndex;
120
+ if (output.length >= limit) {
121
+ break;
122
+ }
123
+ }
124
+ if (separator.lastIndex === match.index) {
125
+ separator.lastIndex++; // Avoid an infinite loop
126
+ }
127
+ }
128
+ if (lastLastIndex === str.length) {
129
+ if (lastLength || !separator.test("")) {
130
+ output.push("");
131
+ }
132
+ } else {
133
+ output.push(str.slice(lastLastIndex));
134
+ }
135
+ return output.length > limit ? output.slice(0, limit) : output;
136
+ };
137
+
138
+ return self;
139
+ })();
140
+
141
+ },{}],6:[function(require,module,exports){
142
+ 'use strict';
143
+
144
+ var OneVersionConstraint = require('individual/one-version');
145
+
146
+ var MY_VERSION = '7';
147
+ OneVersionConstraint('ev-store', MY_VERSION);
148
+
149
+ var hashKey = '__EV_STORE_KEY@' + MY_VERSION;
150
+
151
+ module.exports = EvStore;
152
+
153
+ function EvStore(elem) {
154
+ var hash = elem[hashKey];
155
+
156
+ if (!hash) {
157
+ hash = elem[hashKey] = {};
158
+ }
159
+
160
+ return hash;
161
+ }
162
+
163
+ },{"individual/one-version":8}],7:[function(require,module,exports){
164
+ (function (global){
165
+ 'use strict';
166
+
167
+ /*global window, global*/
168
+
169
+ var root = typeof window !== 'undefined' ?
170
+ window : typeof global !== 'undefined' ?
171
+ global : {};
172
+
173
+ module.exports = Individual;
174
+
175
+ function Individual(key, value) {
176
+ if (key in root) {
177
+ return root[key];
178
+ }
179
+
180
+ root[key] = value;
181
+
182
+ return value;
183
+ }
184
+
185
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
186
+ },{}],8:[function(require,module,exports){
187
+ 'use strict';
188
+
189
+ var Individual = require('./index.js');
190
+
191
+ module.exports = OneVersion;
192
+
193
+ function OneVersion(moduleName, version, defaultValue) {
194
+ var key = '__INDIVIDUAL_ONE_VERSION_' + moduleName;
195
+ var enforceKey = key + '_ENFORCE_SINGLETON';
196
+
197
+ var versionValue = Individual(enforceKey, version);
198
+
199
+ if (versionValue !== version) {
200
+ throw new Error('Can only have one copy of ' +
201
+ moduleName + '.\n' +
202
+ 'You already have version ' + versionValue +
203
+ ' installed.\n' +
204
+ 'This means you cannot install version ' + version);
205
+ }
206
+
207
+ return Individual(key, defaultValue);
208
+ }
209
+
210
+ },{"./index.js":7}],9:[function(require,module,exports){
211
+ (function (global){
212
+ var topLevel = typeof global !== 'undefined' ? global :
213
+ typeof window !== 'undefined' ? window : {}
214
+ var minDoc = require('min-document');
215
+
216
+ if (typeof document !== 'undefined') {
217
+ module.exports = document;
218
+ } else {
219
+ var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
220
+
221
+ if (!doccy) {
222
+ doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
223
+ }
224
+
225
+ module.exports = doccy;
226
+ }
227
+
228
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
229
+ },{"min-document":35}],10:[function(require,module,exports){
230
+ "use strict";
231
+
232
+ module.exports = function isObject(x) {
233
+ return typeof x === "object" && x !== null;
234
+ };
235
+
236
+ },{}],11:[function(require,module,exports){
237
+ var nativeIsArray = Array.isArray
238
+ var toString = Object.prototype.toString
239
+
240
+ module.exports = nativeIsArray || isArray
241
+
242
+ function isArray(obj) {
243
+ return toString.call(obj) === "[object Array]"
244
+ }
245
+
246
+ },{}],12:[function(require,module,exports){
247
+ var patch = require("./vdom/patch.js")
248
+
249
+ module.exports = patch
250
+
251
+ },{"./vdom/patch.js":17}],13:[function(require,module,exports){
252
+ var isObject = require("is-object")
253
+ var isHook = require("../vnode/is-vhook.js")
254
+
255
+ module.exports = applyProperties
256
+
257
+ function applyProperties(node, props, previous) {
258
+ for (var propName in props) {
259
+ var propValue = props[propName]
260
+
261
+ if (propValue === undefined) {
262
+ removeProperty(node, propName, propValue, previous);
263
+ } else if (isHook(propValue)) {
264
+ removeProperty(node, propName, propValue, previous)
265
+ if (propValue.hook) {
266
+ propValue.hook(node,
267
+ propName,
268
+ previous ? previous[propName] : undefined)
269
+ }
270
+ } else {
271
+ if (isObject(propValue)) {
272
+ patchObject(node, props, previous, propName, propValue);
273
+ } else {
274
+ node[propName] = propValue
275
+ }
276
+ }
277
+ }
278
+ }
279
+
280
+ function removeProperty(node, propName, propValue, previous) {
281
+ if (previous) {
282
+ var previousValue = previous[propName]
283
+
284
+ if (!isHook(previousValue)) {
285
+ if (propName === "attributes") {
286
+ for (var attrName in previousValue) {
287
+ node.removeAttribute(attrName)
288
+ }
289
+ } else if (propName === "style") {
290
+ for (var i in previousValue) {
291
+ node.style[i] = ""
292
+ }
293
+ } else if (typeof previousValue === "string") {
294
+ node[propName] = ""
295
+ } else {
296
+ node[propName] = null
297
+ }
298
+ } else if (previousValue.unhook) {
299
+ previousValue.unhook(node, propName, propValue)
300
+ }
301
+ }
302
+ }
303
+
304
+ function patchObject(node, props, previous, propName, propValue) {
305
+ var previousValue = previous ? previous[propName] : undefined
306
+
307
+ // Set attributes
308
+ if (propName === "attributes") {
309
+ for (var attrName in propValue) {
310
+ var attrValue = propValue[attrName]
311
+
312
+ if (attrValue === undefined) {
313
+ node.removeAttribute(attrName)
314
+ } else {
315
+ node.setAttribute(attrName, attrValue)
316
+ }
317
+ }
318
+
319
+ return
320
+ }
321
+
322
+ if(previousValue && isObject(previousValue) &&
323
+ getPrototype(previousValue) !== getPrototype(propValue)) {
324
+ node[propName] = propValue
325
+ return
326
+ }
327
+
328
+ if (!isObject(node[propName])) {
329
+ node[propName] = {}
330
+ }
331
+
332
+ var replacer = propName === "style" ? "" : undefined
333
+
334
+ for (var k in propValue) {
335
+ var value = propValue[k]
336
+ node[propName][k] = (value === undefined) ? replacer : value
337
+ }
338
+ }
339
+
340
+ function getPrototype(value) {
341
+ if (Object.getPrototypeOf) {
342
+ return Object.getPrototypeOf(value)
343
+ } else if (value.__proto__) {
344
+ return value.__proto__
345
+ } else if (value.constructor) {
346
+ return value.constructor.prototype
347
+ }
348
+ }
349
+
350
+ },{"../vnode/is-vhook.js":25,"is-object":10}],14:[function(require,module,exports){
351
+ var document = require("global/document")
352
+
353
+ var applyProperties = require("./apply-properties")
354
+
355
+ var isVNode = require("../vnode/is-vnode.js")
356
+ var isVText = require("../vnode/is-vtext.js")
357
+ var isWidget = require("../vnode/is-widget.js")
358
+ var handleThunk = require("../vnode/handle-thunk.js")
359
+
360
+ module.exports = createElement
361
+
362
+ function createElement(vnode, opts) {
363
+ var doc = opts ? opts.document || document : document
364
+ var warn = opts ? opts.warn : null
365
+
366
+ vnode = handleThunk(vnode).a
367
+
368
+ if (isWidget(vnode)) {
369
+ return vnode.init()
370
+ } else if (isVText(vnode)) {
371
+ return doc.createTextNode(vnode.text)
372
+ } else if (!isVNode(vnode)) {
373
+ if (warn) {
374
+ warn("Item is not a valid virtual dom node", vnode)
375
+ }
376
+ return null
377
+ }
378
+
379
+ var node = (vnode.namespace === null) ?
380
+ doc.createElement(vnode.tagName) :
381
+ doc.createElementNS(vnode.namespace, vnode.tagName)
382
+
383
+ var props = vnode.properties
384
+ applyProperties(node, props)
385
+
386
+ var children = vnode.children
387
+
388
+ for (var i = 0; i < children.length; i++) {
389
+ var childNode = createElement(children[i], opts)
390
+ if (childNode) {
391
+ node.appendChild(childNode)
392
+ }
393
+ }
394
+
395
+ return node
396
+ }
397
+
398
+ },{"../vnode/handle-thunk.js":23,"../vnode/is-vnode.js":26,"../vnode/is-vtext.js":27,"../vnode/is-widget.js":28,"./apply-properties":13,"global/document":9}],15:[function(require,module,exports){
399
+ // Maps a virtual DOM tree onto a real DOM tree in an efficient manner.
400
+ // We don't want to read all of the DOM nodes in the tree so we use
401
+ // the in-order tree indexing to eliminate recursion down certain branches.
402
+ // We only recurse into a DOM node if we know that it contains a child of
403
+ // interest.
404
+
405
+ var noChild = {}
406
+
407
+ module.exports = domIndex
408
+
409
+ function domIndex(rootNode, tree, indices, nodes) {
410
+ if (!indices || indices.length === 0) {
411
+ return {}
412
+ } else {
413
+ indices.sort(ascending)
414
+ return recurse(rootNode, tree, indices, nodes, 0)
415
+ }
416
+ }
417
+
418
+ function recurse(rootNode, tree, indices, nodes, rootIndex) {
419
+ nodes = nodes || {}
420
+
421
+
422
+ if (rootNode) {
423
+ if (indexInRange(indices, rootIndex, rootIndex)) {
424
+ nodes[rootIndex] = rootNode
425
+ }
426
+
427
+ var vChildren = tree.children
428
+
429
+ if (vChildren) {
430
+
431
+ var childNodes = rootNode.childNodes
432
+
433
+ for (var i = 0; i < tree.children.length; i++) {
434
+ rootIndex += 1
435
+
436
+ var vChild = vChildren[i] || noChild
437
+ var nextIndex = rootIndex + (vChild.count || 0)
438
+
439
+ // skip recursion down the tree if there are no nodes down here
440
+ if (indexInRange(indices, rootIndex, nextIndex)) {
441
+ recurse(childNodes[i], vChild, indices, nodes, rootIndex)
442
+ }
443
+
444
+ rootIndex = nextIndex
445
+ }
446
+ }
447
+ }
448
+
449
+ return nodes
450
+ }
451
+
452
+ // Binary search for an index in the interval [left, right]
453
+ function indexInRange(indices, left, right) {
454
+ if (indices.length === 0) {
455
+ return false
456
+ }
457
+
458
+ var minIndex = 0
459
+ var maxIndex = indices.length - 1
460
+ var currentIndex
461
+ var currentItem
462
+
463
+ while (minIndex <= maxIndex) {
464
+ currentIndex = ((maxIndex + minIndex) / 2) >> 0
465
+ currentItem = indices[currentIndex]
466
+
467
+ if (minIndex === maxIndex) {
468
+ return currentItem >= left && currentItem <= right
469
+ } else if (currentItem < left) {
470
+ minIndex = currentIndex + 1
471
+ } else if (currentItem > right) {
472
+ maxIndex = currentIndex - 1
473
+ } else {
474
+ return true
475
+ }
476
+ }
477
+
478
+ return false;
479
+ }
480
+
481
+ function ascending(a, b) {
482
+ return a > b ? 1 : -1
483
+ }
484
+
485
+ },{}],16:[function(require,module,exports){
486
+ var applyProperties = require("./apply-properties")
487
+
488
+ var isWidget = require("../vnode/is-widget.js")
489
+ var VPatch = require("../vnode/vpatch.js")
490
+
491
+ var render = require("./create-element")
492
+ var updateWidget = require("./update-widget")
493
+
494
+ module.exports = applyPatch
495
+
496
+ function applyPatch(vpatch, domNode, renderOptions) {
497
+ var type = vpatch.type
498
+ var vNode = vpatch.vNode
499
+ var patch = vpatch.patch
500
+
501
+ switch (type) {
502
+ case VPatch.REMOVE:
503
+ return removeNode(domNode, vNode)
504
+ case VPatch.INSERT:
505
+ return insertNode(domNode, patch, renderOptions)
506
+ case VPatch.VTEXT:
507
+ return stringPatch(domNode, vNode, patch, renderOptions)
508
+ case VPatch.WIDGET:
509
+ return widgetPatch(domNode, vNode, patch, renderOptions)
510
+ case VPatch.VNODE:
511
+ return vNodePatch(domNode, vNode, patch, renderOptions)
512
+ case VPatch.ORDER:
513
+ reorderChildren(domNode, patch)
514
+ return domNode
515
+ case VPatch.PROPS:
516
+ applyProperties(domNode, patch, vNode.properties)
517
+ return domNode
518
+ case VPatch.THUNK:
519
+ return replaceRoot(domNode,
520
+ renderOptions.patch(domNode, patch, renderOptions))
521
+ default:
522
+ return domNode
523
+ }
524
+ }
525
+
526
+ function removeNode(domNode, vNode) {
527
+ var parentNode = domNode.parentNode
528
+
529
+ if (parentNode) {
530
+ parentNode.removeChild(domNode)
531
+ }
532
+
533
+ destroyWidget(domNode, vNode);
534
+
535
+ return null
536
+ }
537
+
538
+ function insertNode(parentNode, vNode, renderOptions) {
539
+ var newNode = render(vNode, renderOptions)
540
+
541
+ if (parentNode) {
542
+ parentNode.appendChild(newNode)
543
+ }
544
+
545
+ return parentNode
546
+ }
547
+
548
+ function stringPatch(domNode, leftVNode, vText, renderOptions) {
549
+ var newNode
550
+
551
+ if (domNode.nodeType === 3) {
552
+ domNode.replaceData(0, domNode.length, vText.text)
553
+ newNode = domNode
554
+ } else {
555
+ var parentNode = domNode.parentNode
556
+ newNode = render(vText, renderOptions)
557
+
558
+ if (parentNode && newNode !== domNode) {
559
+ parentNode.replaceChild(newNode, domNode)
560
+ }
561
+ }
562
+
563
+ return newNode
564
+ }
565
+
566
+ function widgetPatch(domNode, leftVNode, widget, renderOptions) {
567
+ var updating = updateWidget(leftVNode, widget)
568
+ var newNode
569
+
570
+ if (updating) {
571
+ newNode = widget.update(leftVNode, domNode) || domNode
572
+ } else {
573
+ newNode = render(widget, renderOptions)
574
+ }
575
+
576
+ var parentNode = domNode.parentNode
577
+
578
+ if (parentNode && newNode !== domNode) {
579
+ parentNode.replaceChild(newNode, domNode)
580
+ }
581
+
582
+ if (!updating) {
583
+ destroyWidget(domNode, leftVNode)
584
+ }
585
+
586
+ return newNode
587
+ }
588
+
589
+ function vNodePatch(domNode, leftVNode, vNode, renderOptions) {
590
+ var parentNode = domNode.parentNode
591
+ var newNode = render(vNode, renderOptions)
592
+
593
+ if (parentNode && newNode !== domNode) {
594
+ parentNode.replaceChild(newNode, domNode)
595
+ }
596
+
597
+ return newNode
598
+ }
599
+
600
+ function destroyWidget(domNode, w) {
601
+ if (typeof w.destroy === "function" && isWidget(w)) {
602
+ w.destroy(domNode)
603
+ }
604
+ }
605
+
606
+ function reorderChildren(domNode, moves) {
607
+ var childNodes = domNode.childNodes
608
+ var keyMap = {}
609
+ var node
610
+ var remove
611
+ var insert
612
+
613
+ for (var i = 0; i < moves.removes.length; i++) {
614
+ remove = moves.removes[i]
615
+ node = childNodes[remove.from]
616
+ if (remove.key) {
617
+ keyMap[remove.key] = node
618
+ }
619
+ domNode.removeChild(node)
620
+ }
621
+
622
+ var length = childNodes.length
623
+ for (var j = 0; j < moves.inserts.length; j++) {
624
+ insert = moves.inserts[j]
625
+ node = keyMap[insert.key]
626
+ // this is the weirdest bug i've ever seen in webkit
627
+ domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to])
628
+ }
629
+ }
630
+
631
+ function replaceRoot(oldRoot, newRoot) {
632
+ if (oldRoot && newRoot && oldRoot !== newRoot && oldRoot.parentNode) {
633
+ oldRoot.parentNode.replaceChild(newRoot, oldRoot)
634
+ }
635
+
636
+ return newRoot;
637
+ }
638
+
639
+ },{"../vnode/is-widget.js":28,"../vnode/vpatch.js":31,"./apply-properties":13,"./create-element":14,"./update-widget":18}],17:[function(require,module,exports){
640
+ var document = require("global/document")
641
+ var isArray = require("x-is-array")
642
+
643
+ var domIndex = require("./dom-index")
644
+ var patchOp = require("./patch-op")
645
+ module.exports = patch
646
+
647
+ function patch(rootNode, patches) {
648
+ return patchRecursive(rootNode, patches)
649
+ }
650
+
651
+ function patchRecursive(rootNode, patches, renderOptions) {
652
+ var indices = patchIndices(patches)
653
+
654
+ if (indices.length === 0) {
655
+ return rootNode
656
+ }
657
+
658
+ var index = domIndex(rootNode, patches.a, indices)
659
+ var ownerDocument = rootNode.ownerDocument
660
+
661
+ if (!renderOptions) {
662
+ renderOptions = { patch: patchRecursive }
663
+ if (ownerDocument !== document) {
664
+ renderOptions.document = ownerDocument
665
+ }
666
+ }
667
+
668
+ for (var i = 0; i < indices.length; i++) {
669
+ var nodeIndex = indices[i]
670
+ rootNode = applyPatch(rootNode,
671
+ index[nodeIndex],
672
+ patches[nodeIndex],
673
+ renderOptions)
674
+ }
675
+
676
+ return rootNode
677
+ }
678
+
679
+ function applyPatch(rootNode, domNode, patchList, renderOptions) {
680
+ if (!domNode) {
681
+ return rootNode
682
+ }
683
+
684
+ var newNode
685
+
686
+ if (isArray(patchList)) {
687
+ for (var i = 0; i < patchList.length; i++) {
688
+ newNode = patchOp(patchList[i], domNode, renderOptions)
689
+
690
+ if (domNode === rootNode) {
691
+ rootNode = newNode
692
+ }
693
+ }
694
+ } else {
695
+ newNode = patchOp(patchList, domNode, renderOptions)
696
+
697
+ if (domNode === rootNode) {
698
+ rootNode = newNode
699
+ }
700
+ }
701
+
702
+ return rootNode
703
+ }
704
+
705
+ function patchIndices(patches) {
706
+ var indices = []
707
+
708
+ for (var key in patches) {
709
+ if (key !== "a") {
710
+ indices.push(Number(key))
711
+ }
712
+ }
713
+
714
+ return indices
715
+ }
716
+
717
+ },{"./dom-index":15,"./patch-op":16,"global/document":9,"x-is-array":11}],18:[function(require,module,exports){
718
+ var isWidget = require("../vnode/is-widget.js")
719
+
720
+ module.exports = updateWidget
721
+
722
+ function updateWidget(a, b) {
723
+ if (isWidget(a) && isWidget(b)) {
724
+ if ("name" in a && "name" in b) {
725
+ return a.id === b.id
726
+ } else {
727
+ return a.init === b.init
728
+ }
729
+ }
730
+
731
+ return false
732
+ }
733
+
734
+ },{"../vnode/is-widget.js":28}],19:[function(require,module,exports){
735
+ 'use strict';
736
+
737
+ var EvStore = require('ev-store');
738
+
739
+ module.exports = EvHook;
740
+
741
+ function EvHook(value) {
742
+ if (!(this instanceof EvHook)) {
743
+ return new EvHook(value);
744
+ }
745
+
746
+ this.value = value;
747
+ }
748
+
749
+ EvHook.prototype.hook = function (node, propertyName) {
750
+ var es = EvStore(node);
751
+ var propName = propertyName.substr(3);
752
+
753
+ es[propName] = this.value;
754
+ };
755
+
756
+ EvHook.prototype.unhook = function(node, propertyName) {
757
+ var es = EvStore(node);
758
+ var propName = propertyName.substr(3);
759
+
760
+ es[propName] = undefined;
761
+ };
762
+
763
+ },{"ev-store":6}],20:[function(require,module,exports){
764
+ 'use strict';
765
+
766
+ module.exports = SoftSetHook;
767
+
768
+ function SoftSetHook(value) {
769
+ if (!(this instanceof SoftSetHook)) {
770
+ return new SoftSetHook(value);
771
+ }
772
+
773
+ this.value = value;
774
+ }
775
+
776
+ SoftSetHook.prototype.hook = function (node, propertyName) {
777
+ if (node[propertyName] !== this.value) {
778
+ node[propertyName] = this.value;
779
+ }
780
+ };
781
+
782
+ },{}],21:[function(require,module,exports){
783
+ 'use strict';
784
+
785
+ var isArray = require('x-is-array');
786
+
787
+ var VNode = require('../vnode/vnode.js');
788
+ var VText = require('../vnode/vtext.js');
789
+ var isVNode = require('../vnode/is-vnode');
790
+ var isVText = require('../vnode/is-vtext');
791
+ var isWidget = require('../vnode/is-widget');
792
+ var isHook = require('../vnode/is-vhook');
793
+ var isVThunk = require('../vnode/is-thunk');
794
+
795
+ var parseTag = require('./parse-tag.js');
796
+ var softSetHook = require('./hooks/soft-set-hook.js');
797
+ var evHook = require('./hooks/ev-hook.js');
798
+
799
+ module.exports = h;
800
+
801
+ function h(tagName, properties, children) {
802
+ var childNodes = [];
803
+ var tag, props, key, namespace;
804
+
805
+ if (!children && isChildren(properties)) {
806
+ children = properties;
807
+ props = {};
808
+ }
809
+
810
+ props = props || properties || {};
811
+ tag = parseTag(tagName, props);
812
+
813
+ // support keys
814
+ if (props.hasOwnProperty('key')) {
815
+ key = props.key;
816
+ props.key = undefined;
817
+ }
818
+
819
+ // support namespace
820
+ if (props.hasOwnProperty('namespace')) {
821
+ namespace = props.namespace;
822
+ props.namespace = undefined;
823
+ }
824
+
825
+ // fix cursor bug
826
+ if (tag === 'INPUT' &&
827
+ !namespace &&
828
+ props.hasOwnProperty('value') &&
829
+ props.value !== undefined &&
830
+ !isHook(props.value)
831
+ ) {
832
+ props.value = softSetHook(props.value);
833
+ }
834
+
835
+ transformProperties(props);
836
+
837
+ if (children !== undefined && children !== null) {
838
+ addChild(children, childNodes, tag, props);
839
+ }
840
+
841
+
842
+ return new VNode(tag, props, childNodes, key, namespace);
843
+ }
844
+
845
+ function addChild(c, childNodes, tag, props) {
846
+ if (typeof c === 'string') {
847
+ childNodes.push(new VText(c));
848
+ } else if (isChild(c)) {
849
+ childNodes.push(c);
850
+ } else if (isArray(c)) {
851
+ for (var i = 0; i < c.length; i++) {
852
+ addChild(c[i], childNodes, tag, props);
853
+ }
854
+ } else if (c === null || c === undefined) {
855
+ return;
856
+ } else {
857
+ throw UnexpectedVirtualElement({
858
+ foreignObject: c,
859
+ parentVnode: {
860
+ tagName: tag,
861
+ properties: props
862
+ }
863
+ });
864
+ }
865
+ }
866
+
867
+ function transformProperties(props) {
868
+ for (var propName in props) {
869
+ if (props.hasOwnProperty(propName)) {
870
+ var value = props[propName];
871
+
872
+ if (isHook(value)) {
873
+ continue;
874
+ }
875
+
876
+ if (propName.substr(0, 3) === 'ev-') {
877
+ // add ev-foo support
878
+ props[propName] = evHook(value);
879
+ }
880
+ }
881
+ }
882
+ }
883
+
884
+ function isChild(x) {
885
+ return isVNode(x) || isVText(x) || isWidget(x) || isVThunk(x);
886
+ }
887
+
888
+ function isChildren(x) {
889
+ return typeof x === 'string' || isArray(x) || isChild(x);
890
+ }
891
+
892
+ function UnexpectedVirtualElement(data) {
893
+ var err = new Error();
894
+
895
+ err.type = 'virtual-hyperscript.unexpected.virtual-element';
896
+ err.message = 'Unexpected virtual child passed to h().\n' +
897
+ 'Expected a VNode / Vthunk / VWidget / string but:\n' +
898
+ 'got:\n' +
899
+ errorString(data.foreignObject) +
900
+ '.\n' +
901
+ 'The parent vnode is:\n' +
902
+ errorString(data.parentVnode)
903
+ '\n' +
904
+ 'Suggested fix: change your `h(..., [ ... ])` callsite.';
905
+ err.foreignObject = data.foreignObject;
906
+ err.parentVnode = data.parentVnode;
907
+
908
+ return err;
909
+ }
910
+
911
+ function errorString(obj) {
912
+ try {
913
+ return JSON.stringify(obj, null, ' ');
914
+ } catch (e) {
915
+ return String(obj);
916
+ }
917
+ }
918
+
919
+ },{"../vnode/is-thunk":24,"../vnode/is-vhook":25,"../vnode/is-vnode":26,"../vnode/is-vtext":27,"../vnode/is-widget":28,"../vnode/vnode.js":30,"../vnode/vtext.js":32,"./hooks/ev-hook.js":19,"./hooks/soft-set-hook.js":20,"./parse-tag.js":22,"x-is-array":11}],22:[function(require,module,exports){
920
+ 'use strict';
921
+
922
+ var split = require('browser-split');
923
+
924
+ var classIdSplit = /([\.#]?[a-zA-Z0-9_:-]+)/;
925
+ var notClassId = /^\.|#/;
926
+
927
+ module.exports = parseTag;
928
+
929
+ function parseTag(tag, props) {
930
+ if (!tag) {
931
+ return 'DIV';
932
+ }
933
+
934
+ var noId = !(props.hasOwnProperty('id'));
935
+
936
+ var tagParts = split(tag, classIdSplit);
937
+ var tagName = null;
938
+
939
+ if (notClassId.test(tagParts[1])) {
940
+ tagName = 'DIV';
941
+ }
942
+
943
+ var classes, part, type, i;
944
+
945
+ for (i = 0; i < tagParts.length; i++) {
946
+ part = tagParts[i];
947
+
948
+ if (!part) {
949
+ continue;
950
+ }
951
+
952
+ type = part.charAt(0);
953
+
954
+ if (!tagName) {
955
+ tagName = part;
956
+ } else if (type === '.') {
957
+ classes = classes || [];
958
+ classes.push(part.substring(1, part.length));
959
+ } else if (type === '#' && noId) {
960
+ props.id = part.substring(1, part.length);
961
+ }
962
+ }
963
+
964
+ if (classes) {
965
+ if (props.className) {
966
+ classes.push(props.className);
967
+ }
968
+
969
+ props.className = classes.join(' ');
970
+ }
971
+
972
+ return props.namespace ? tagName : tagName.toUpperCase();
973
+ }
974
+
975
+ },{"browser-split":5}],23:[function(require,module,exports){
976
+ var isVNode = require("./is-vnode")
977
+ var isVText = require("./is-vtext")
978
+ var isWidget = require("./is-widget")
979
+ var isThunk = require("./is-thunk")
980
+
981
+ module.exports = handleThunk
982
+
983
+ function handleThunk(a, b) {
984
+ var renderedA = a
985
+ var renderedB = b
986
+
987
+ if (isThunk(b)) {
988
+ renderedB = renderThunk(b, a)
989
+ }
990
+
991
+ if (isThunk(a)) {
992
+ renderedA = renderThunk(a, null)
993
+ }
994
+
995
+ return {
996
+ a: renderedA,
997
+ b: renderedB
998
+ }
999
+ }
1000
+
1001
+ function renderThunk(thunk, previous) {
1002
+ var renderedThunk = thunk.vnode
1003
+
1004
+ if (!renderedThunk) {
1005
+ renderedThunk = thunk.vnode = thunk.render(previous)
1006
+ }
1007
+
1008
+ if (!(isVNode(renderedThunk) ||
1009
+ isVText(renderedThunk) ||
1010
+ isWidget(renderedThunk))) {
1011
+ throw new Error("thunk did not return a valid node");
1012
+ }
1013
+
1014
+ return renderedThunk
1015
+ }
1016
+
1017
+ },{"./is-thunk":24,"./is-vnode":26,"./is-vtext":27,"./is-widget":28}],24:[function(require,module,exports){
1018
+ module.exports = isThunk
1019
+
1020
+ function isThunk(t) {
1021
+ return t && t.type === "Thunk"
1022
+ }
1023
+
1024
+ },{}],25:[function(require,module,exports){
1025
+ module.exports = isHook
1026
+
1027
+ function isHook(hook) {
1028
+ return hook &&
1029
+ (typeof hook.hook === "function" && !hook.hasOwnProperty("hook") ||
1030
+ typeof hook.unhook === "function" && !hook.hasOwnProperty("unhook"))
1031
+ }
1032
+
1033
+ },{}],26:[function(require,module,exports){
1034
+ var version = require("./version")
1035
+
1036
+ module.exports = isVirtualNode
1037
+
1038
+ function isVirtualNode(x) {
1039
+ return x && x.type === "VirtualNode" && x.version === version
1040
+ }
1041
+
1042
+ },{"./version":29}],27:[function(require,module,exports){
1043
+ var version = require("./version")
1044
+
1045
+ module.exports = isVirtualText
1046
+
1047
+ function isVirtualText(x) {
1048
+ return x && x.type === "VirtualText" && x.version === version
1049
+ }
1050
+
1051
+ },{"./version":29}],28:[function(require,module,exports){
1052
+ module.exports = isWidget
1053
+
1054
+ function isWidget(w) {
1055
+ return w && w.type === "Widget"
1056
+ }
1057
+
1058
+ },{}],29:[function(require,module,exports){
1059
+ module.exports = "2"
1060
+
1061
+ },{}],30:[function(require,module,exports){
1062
+ var version = require("./version")
1063
+ var isVNode = require("./is-vnode")
1064
+ var isWidget = require("./is-widget")
1065
+ var isThunk = require("./is-thunk")
1066
+ var isVHook = require("./is-vhook")
1067
+
1068
+ module.exports = VirtualNode
1069
+
1070
+ var noProperties = {}
1071
+ var noChildren = []
1072
+
1073
+ function VirtualNode(tagName, properties, children, key, namespace) {
1074
+ this.tagName = tagName
1075
+ this.properties = properties || noProperties
1076
+ this.children = children || noChildren
1077
+ this.key = key != null ? String(key) : undefined
1078
+ this.namespace = (typeof namespace === "string") ? namespace : null
1079
+
1080
+ var count = (children && children.length) || 0
1081
+ var descendants = 0
1082
+ var hasWidgets = false
1083
+ var hasThunks = false
1084
+ var descendantHooks = false
1085
+ var hooks
1086
+
1087
+ for (var propName in properties) {
1088
+ if (properties.hasOwnProperty(propName)) {
1089
+ var property = properties[propName]
1090
+ if (isVHook(property) && property.unhook) {
1091
+ if (!hooks) {
1092
+ hooks = {}
1093
+ }
1094
+
1095
+ hooks[propName] = property
1096
+ }
1097
+ }
1098
+ }
1099
+
1100
+ for (var i = 0; i < count; i++) {
1101
+ var child = children[i]
1102
+ if (isVNode(child)) {
1103
+ descendants += child.count || 0
1104
+
1105
+ if (!hasWidgets && child.hasWidgets) {
1106
+ hasWidgets = true
1107
+ }
1108
+
1109
+ if (!hasThunks && child.hasThunks) {
1110
+ hasThunks = true
1111
+ }
1112
+
1113
+ if (!descendantHooks && (child.hooks || child.descendantHooks)) {
1114
+ descendantHooks = true
1115
+ }
1116
+ } else if (!hasWidgets && isWidget(child)) {
1117
+ if (typeof child.destroy === "function") {
1118
+ hasWidgets = true
1119
+ }
1120
+ } else if (!hasThunks && isThunk(child)) {
1121
+ hasThunks = true;
1122
+ }
1123
+ }
1124
+
1125
+ this.count = count + descendants
1126
+ this.hasWidgets = hasWidgets
1127
+ this.hasThunks = hasThunks
1128
+ this.hooks = hooks
1129
+ this.descendantHooks = descendantHooks
1130
+ }
1131
+
1132
+ VirtualNode.prototype.version = version
1133
+ VirtualNode.prototype.type = "VirtualNode"
1134
+
1135
+ },{"./is-thunk":24,"./is-vhook":25,"./is-vnode":26,"./is-widget":28,"./version":29}],31:[function(require,module,exports){
1136
+ var version = require("./version")
1137
+
1138
+ VirtualPatch.NONE = 0
1139
+ VirtualPatch.VTEXT = 1
1140
+ VirtualPatch.VNODE = 2
1141
+ VirtualPatch.WIDGET = 3
1142
+ VirtualPatch.PROPS = 4
1143
+ VirtualPatch.ORDER = 5
1144
+ VirtualPatch.INSERT = 6
1145
+ VirtualPatch.REMOVE = 7
1146
+ VirtualPatch.THUNK = 8
1147
+
1148
+ module.exports = VirtualPatch
1149
+
1150
+ function VirtualPatch(type, vNode, patch) {
1151
+ this.type = Number(type)
1152
+ this.vNode = vNode
1153
+ this.patch = patch
1154
+ }
1155
+
1156
+ VirtualPatch.prototype.version = version
1157
+ VirtualPatch.prototype.type = "VirtualPatch"
1158
+
1159
+ },{"./version":29}],32:[function(require,module,exports){
1160
+ var version = require("./version")
1161
+
1162
+ module.exports = VirtualText
1163
+
1164
+ function VirtualText(text) {
1165
+ this.text = String(text)
1166
+ }
1167
+
1168
+ VirtualText.prototype.version = version
1169
+ VirtualText.prototype.type = "VirtualText"
1170
+
1171
+ },{"./version":29}],33:[function(require,module,exports){
1172
+ var isObject = require("is-object")
1173
+ var isHook = require("../vnode/is-vhook")
1174
+
1175
+ module.exports = diffProps
1176
+
1177
+ function diffProps(a, b) {
1178
+ var diff
1179
+
1180
+ for (var aKey in a) {
1181
+ if (!(aKey in b)) {
1182
+ diff = diff || {}
1183
+ diff[aKey] = undefined
1184
+ }
1185
+
1186
+ var aValue = a[aKey]
1187
+ var bValue = b[aKey]
1188
+
1189
+ if (aValue === bValue) {
1190
+ continue
1191
+ } else if (isObject(aValue) && isObject(bValue)) {
1192
+ if (getPrototype(bValue) !== getPrototype(aValue)) {
1193
+ diff = diff || {}
1194
+ diff[aKey] = bValue
1195
+ } else if (isHook(bValue)) {
1196
+ diff = diff || {}
1197
+ diff[aKey] = bValue
1198
+ } else {
1199
+ var objectDiff = diffProps(aValue, bValue)
1200
+ if (objectDiff) {
1201
+ diff = diff || {}
1202
+ diff[aKey] = objectDiff
1203
+ }
1204
+ }
1205
+ } else {
1206
+ diff = diff || {}
1207
+ diff[aKey] = bValue
1208
+ }
1209
+ }
1210
+
1211
+ for (var bKey in b) {
1212
+ if (!(bKey in a)) {
1213
+ diff = diff || {}
1214
+ diff[bKey] = b[bKey]
1215
+ }
1216
+ }
1217
+
1218
+ return diff
1219
+ }
1220
+
1221
+ function getPrototype(value) {
1222
+ if (Object.getPrototypeOf) {
1223
+ return Object.getPrototypeOf(value)
1224
+ } else if (value.__proto__) {
1225
+ return value.__proto__
1226
+ } else if (value.constructor) {
1227
+ return value.constructor.prototype
1228
+ }
1229
+ }
1230
+
1231
+ },{"../vnode/is-vhook":25,"is-object":10}],34:[function(require,module,exports){
1232
+ var isArray = require("x-is-array")
1233
+
1234
+ var VPatch = require("../vnode/vpatch")
1235
+ var isVNode = require("../vnode/is-vnode")
1236
+ var isVText = require("../vnode/is-vtext")
1237
+ var isWidget = require("../vnode/is-widget")
1238
+ var isThunk = require("../vnode/is-thunk")
1239
+ var handleThunk = require("../vnode/handle-thunk")
1240
+
1241
+ var diffProps = require("./diff-props")
1242
+
1243
+ module.exports = diff
1244
+
1245
+ function diff(a, b) {
1246
+ var patch = { a: a }
1247
+ walk(a, b, patch, 0)
1248
+ return patch
1249
+ }
1250
+
1251
+ function walk(a, b, patch, index) {
1252
+ if (a === b) {
1253
+ return
1254
+ }
1255
+
1256
+ var apply = patch[index]
1257
+ var applyClear = false
1258
+
1259
+ if (isThunk(a) || isThunk(b)) {
1260
+ thunks(a, b, patch, index)
1261
+ } else if (b == null) {
1262
+
1263
+ // If a is a widget we will add a remove patch for it
1264
+ // Otherwise any child widgets/hooks must be destroyed.
1265
+ // This prevents adding two remove patches for a widget.
1266
+ if (!isWidget(a)) {
1267
+ clearState(a, patch, index)
1268
+ apply = patch[index]
1269
+ }
1270
+
1271
+ apply = appendPatch(apply, new VPatch(VPatch.REMOVE, a, b))
1272
+ } else if (isVNode(b)) {
1273
+ if (isVNode(a)) {
1274
+ if (a.tagName === b.tagName &&
1275
+ a.namespace === b.namespace &&
1276
+ a.key === b.key) {
1277
+ var propsPatch = diffProps(a.properties, b.properties)
1278
+ if (propsPatch) {
1279
+ apply = appendPatch(apply,
1280
+ new VPatch(VPatch.PROPS, a, propsPatch))
1281
+ }
1282
+ apply = diffChildren(a, b, patch, apply, index)
1283
+ } else {
1284
+ apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b))
1285
+ applyClear = true
1286
+ }
1287
+ } else {
1288
+ apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b))
1289
+ applyClear = true
1290
+ }
1291
+ } else if (isVText(b)) {
1292
+ if (!isVText(a)) {
1293
+ apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b))
1294
+ applyClear = true
1295
+ } else if (a.text !== b.text) {
1296
+ apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b))
1297
+ }
1298
+ } else if (isWidget(b)) {
1299
+ if (!isWidget(a)) {
1300
+ applyClear = true
1301
+ }
1302
+
1303
+ apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b))
1304
+ }
1305
+
1306
+ if (apply) {
1307
+ patch[index] = apply
1308
+ }
1309
+
1310
+ if (applyClear) {
1311
+ clearState(a, patch, index)
1312
+ }
1313
+ }
1314
+
1315
+ function diffChildren(a, b, patch, apply, index) {
1316
+ var aChildren = a.children
1317
+ var orderedSet = reorder(aChildren, b.children)
1318
+ var bChildren = orderedSet.children
1319
+
1320
+ var aLen = aChildren.length
1321
+ var bLen = bChildren.length
1322
+ var len = aLen > bLen ? aLen : bLen
1323
+
1324
+ for (var i = 0; i < len; i++) {
1325
+ var leftNode = aChildren[i]
1326
+ var rightNode = bChildren[i]
1327
+ index += 1
1328
+
1329
+ if (!leftNode) {
1330
+ if (rightNode) {
1331
+ // Excess nodes in b need to be added
1332
+ apply = appendPatch(apply,
1333
+ new VPatch(VPatch.INSERT, null, rightNode))
1334
+ }
1335
+ } else {
1336
+ walk(leftNode, rightNode, patch, index)
1337
+ }
1338
+
1339
+ if (isVNode(leftNode) && leftNode.count) {
1340
+ index += leftNode.count
1341
+ }
1342
+ }
1343
+
1344
+ if (orderedSet.moves) {
1345
+ // Reorder nodes last
1346
+ apply = appendPatch(apply, new VPatch(
1347
+ VPatch.ORDER,
1348
+ a,
1349
+ orderedSet.moves
1350
+ ))
1351
+ }
1352
+
1353
+ return apply
1354
+ }
1355
+
1356
+ function clearState(vNode, patch, index) {
1357
+ // TODO: Make this a single walk, not two
1358
+ unhook(vNode, patch, index)
1359
+ destroyWidgets(vNode, patch, index)
1360
+ }
1361
+
1362
+ // Patch records for all destroyed widgets must be added because we need
1363
+ // a DOM node reference for the destroy function
1364
+ function destroyWidgets(vNode, patch, index) {
1365
+ if (isWidget(vNode)) {
1366
+ if (typeof vNode.destroy === "function") {
1367
+ patch[index] = appendPatch(
1368
+ patch[index],
1369
+ new VPatch(VPatch.REMOVE, vNode, null)
1370
+ )
1371
+ }
1372
+ } else if (isVNode(vNode) && (vNode.hasWidgets || vNode.hasThunks)) {
1373
+ var children = vNode.children
1374
+ var len = children.length
1375
+ for (var i = 0; i < len; i++) {
1376
+ var child = children[i]
1377
+ index += 1
1378
+
1379
+ destroyWidgets(child, patch, index)
1380
+
1381
+ if (isVNode(child) && child.count) {
1382
+ index += child.count
1383
+ }
1384
+ }
1385
+ } else if (isThunk(vNode)) {
1386
+ thunks(vNode, null, patch, index)
1387
+ }
1388
+ }
1389
+
1390
+ // Create a sub-patch for thunks
1391
+ function thunks(a, b, patch, index) {
1392
+ var nodes = handleThunk(a, b)
1393
+ var thunkPatch = diff(nodes.a, nodes.b)
1394
+ if (hasPatches(thunkPatch)) {
1395
+ patch[index] = new VPatch(VPatch.THUNK, null, thunkPatch)
1396
+ }
1397
+ }
1398
+
1399
+ function hasPatches(patch) {
1400
+ for (var index in patch) {
1401
+ if (index !== "a") {
1402
+ return true
1403
+ }
1404
+ }
1405
+
1406
+ return false
1407
+ }
1408
+
1409
+ // Execute hooks when two nodes are identical
1410
+ function unhook(vNode, patch, index) {
1411
+ if (isVNode(vNode)) {
1412
+ if (vNode.hooks) {
1413
+ patch[index] = appendPatch(
1414
+ patch[index],
1415
+ new VPatch(
1416
+ VPatch.PROPS,
1417
+ vNode,
1418
+ undefinedKeys(vNode.hooks)
1419
+ )
1420
+ )
1421
+ }
1422
+
1423
+ if (vNode.descendantHooks || vNode.hasThunks) {
1424
+ var children = vNode.children
1425
+ var len = children.length
1426
+ for (var i = 0; i < len; i++) {
1427
+ var child = children[i]
1428
+ index += 1
1429
+
1430
+ unhook(child, patch, index)
1431
+
1432
+ if (isVNode(child) && child.count) {
1433
+ index += child.count
1434
+ }
1435
+ }
1436
+ }
1437
+ } else if (isThunk(vNode)) {
1438
+ thunks(vNode, null, patch, index)
1439
+ }
1440
+ }
1441
+
1442
+ function undefinedKeys(obj) {
1443
+ var result = {}
1444
+
1445
+ for (var key in obj) {
1446
+ result[key] = undefined
1447
+ }
1448
+
1449
+ return result
1450
+ }
1451
+
1452
+ // List diff, naive left to right reordering
1453
+ function reorder(aChildren, bChildren) {
1454
+ // O(M) time, O(M) memory
1455
+ var bChildIndex = keyIndex(bChildren)
1456
+ var bKeys = bChildIndex.keys
1457
+ var bFree = bChildIndex.free
1458
+
1459
+ if (bFree.length === bChildren.length) {
1460
+ return {
1461
+ children: bChildren,
1462
+ moves: null
1463
+ }
1464
+ }
1465
+
1466
+ // O(N) time, O(N) memory
1467
+ var aChildIndex = keyIndex(aChildren)
1468
+ var aKeys = aChildIndex.keys
1469
+ var aFree = aChildIndex.free
1470
+
1471
+ if (aFree.length === aChildren.length) {
1472
+ return {
1473
+ children: bChildren,
1474
+ moves: null
1475
+ }
1476
+ }
1477
+
1478
+ // O(MAX(N, M)) memory
1479
+ var newChildren = []
1480
+
1481
+ var freeIndex = 0
1482
+ var freeCount = bFree.length
1483
+ var deletedItems = 0
1484
+
1485
+ // Iterate through a and match a node in b
1486
+ // O(N) time,
1487
+ for (var i = 0 ; i < aChildren.length; i++) {
1488
+ var aItem = aChildren[i]
1489
+ var itemIndex
1490
+
1491
+ if (aItem.key) {
1492
+ if (bKeys.hasOwnProperty(aItem.key)) {
1493
+ // Match up the old keys
1494
+ itemIndex = bKeys[aItem.key]
1495
+ newChildren.push(bChildren[itemIndex])
1496
+
1497
+ } else {
1498
+ // Remove old keyed items
1499
+ itemIndex = i - deletedItems++
1500
+ newChildren.push(null)
1501
+ }
1502
+ } else {
1503
+ // Match the item in a with the next free item in b
1504
+ if (freeIndex < freeCount) {
1505
+ itemIndex = bFree[freeIndex++]
1506
+ newChildren.push(bChildren[itemIndex])
1507
+ } else {
1508
+ // There are no free items in b to match with
1509
+ // the free items in a, so the extra free nodes
1510
+ // are deleted.
1511
+ itemIndex = i - deletedItems++
1512
+ newChildren.push(null)
1513
+ }
1514
+ }
1515
+ }
1516
+
1517
+ var lastFreeIndex = freeIndex >= bFree.length ?
1518
+ bChildren.length :
1519
+ bFree[freeIndex]
1520
+
1521
+ // Iterate through b and append any new keys
1522
+ // O(M) time
1523
+ for (var j = 0; j < bChildren.length; j++) {
1524
+ var newItem = bChildren[j]
1525
+
1526
+ if (newItem.key) {
1527
+ if (!aKeys.hasOwnProperty(newItem.key)) {
1528
+ // Add any new keyed items
1529
+ // We are adding new items to the end and then sorting them
1530
+ // in place. In future we should insert new items in place.
1531
+ newChildren.push(newItem)
1532
+ }
1533
+ } else if (j >= lastFreeIndex) {
1534
+ // Add any leftover non-keyed items
1535
+ newChildren.push(newItem)
1536
+ }
1537
+ }
1538
+
1539
+ var simulate = newChildren.slice()
1540
+ var simulateIndex = 0
1541
+ var removes = []
1542
+ var inserts = []
1543
+ var simulateItem
1544
+
1545
+ for (var k = 0; k < bChildren.length;) {
1546
+ var wantedItem = bChildren[k]
1547
+ simulateItem = simulate[simulateIndex]
1548
+
1549
+ // remove items
1550
+ while (simulateItem === null && simulate.length) {
1551
+ removes.push(remove(simulate, simulateIndex, null))
1552
+ simulateItem = simulate[simulateIndex]
1553
+ }
1554
+
1555
+ if (!simulateItem || simulateItem.key !== wantedItem.key) {
1556
+ // if we need a key in this position...
1557
+ if (wantedItem.key) {
1558
+ if (simulateItem && simulateItem.key) {
1559
+ // if an insert doesn't put this key in place, it needs to move
1560
+ if (bKeys[simulateItem.key] !== k + 1) {
1561
+ removes.push(remove(simulate, simulateIndex, simulateItem.key))
1562
+ simulateItem = simulate[simulateIndex]
1563
+ // if the remove didn't put the wanted item in place, we need to insert it
1564
+ if (!simulateItem || simulateItem.key !== wantedItem.key) {
1565
+ inserts.push({key: wantedItem.key, to: k})
1566
+ }
1567
+ // items are matching, so skip ahead
1568
+ else {
1569
+ simulateIndex++
1570
+ }
1571
+ }
1572
+ else {
1573
+ inserts.push({key: wantedItem.key, to: k})
1574
+ }
1575
+ }
1576
+ else {
1577
+ inserts.push({key: wantedItem.key, to: k})
1578
+ }
1579
+ k++
1580
+ }
1581
+ // a key in simulate has no matching wanted key, remove it
1582
+ else if (simulateItem && simulateItem.key) {
1583
+ removes.push(remove(simulate, simulateIndex, simulateItem.key))
1584
+ }
1585
+ }
1586
+ else {
1587
+ simulateIndex++
1588
+ k++
1589
+ }
1590
+ }
1591
+
1592
+ // remove all the remaining nodes from simulate
1593
+ while(simulateIndex < simulate.length) {
1594
+ simulateItem = simulate[simulateIndex]
1595
+ removes.push(remove(simulate, simulateIndex, simulateItem && simulateItem.key))
1596
+ }
1597
+
1598
+ // If the only moves we have are deletes then we can just
1599
+ // let the delete patch remove these items.
1600
+ if (removes.length === deletedItems && !inserts.length) {
1601
+ return {
1602
+ children: newChildren,
1603
+ moves: null
1604
+ }
1605
+ }
1606
+
1607
+ return {
1608
+ children: newChildren,
1609
+ moves: {
1610
+ removes: removes,
1611
+ inserts: inserts
1612
+ }
1613
+ }
1614
+ }
1615
+
1616
+ function remove(arr, index, key) {
1617
+ arr.splice(index, 1)
1618
+
1619
+ return {
1620
+ from: index,
1621
+ key: key
1622
+ }
1623
+ }
1624
+
1625
+ function keyIndex(children) {
1626
+ var keys = {}
1627
+ var free = []
1628
+ var length = children.length
1629
+
1630
+ for (var i = 0; i < length; i++) {
1631
+ var child = children[i]
1632
+
1633
+ if (child.key) {
1634
+ keys[child.key] = i
1635
+ } else {
1636
+ free.push(i)
1637
+ }
1638
+ }
1639
+
1640
+ return {
1641
+ keys: keys, // A hash of key name to index
1642
+ free: free // An array of unkeyed item indices
1643
+ }
1644
+ }
1645
+
1646
+ function appendPatch(apply, patch) {
1647
+ if (apply) {
1648
+ if (isArray(apply)) {
1649
+ apply.push(patch)
1650
+ } else {
1651
+ apply = [apply, patch]
1652
+ }
1653
+
1654
+ return apply
1655
+ } else {
1656
+ return patch
1657
+ }
1658
+ }
1659
+
1660
+ },{"../vnode/handle-thunk":23,"../vnode/is-thunk":24,"../vnode/is-vnode":26,"../vnode/is-vtext":27,"../vnode/is-widget":28,"../vnode/vpatch":31,"./diff-props":33,"x-is-array":11}],35:[function(require,module,exports){
1661
+
1662
+ },{}]},{},[4])(4)
1663
+ });