opal-virtual-dom 0.2.3 → 0.3.0

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