UNPKG

nervjs

Version:

A react-like framework based on virtual-dom

1,986 lines (1,801 loc) 64.5 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.Nerv = global.Nerv || {}))); }(this, (function (exports) { 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }; var possibleConstructorReturn = function (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }; var Events = function () { function Events(opts) { classCallCheck(this, Events); if (typeof opts !== 'undefined' && opts.callbacks) { this.callbacks = opts.callbacks; } else { this.callbacks = {}; } } Events.prototype.on = function on(events, callback, context) { var calls = void 0, event = void 0, node = void 0, tail = void 0, list = void 0; if (!callback) { return this; } events = events.split(Events.eventSplitter); calls = this.callbacks; while (event = events.shift()) { list = calls[event]; node = list ? list.tail : {}; node.next = tail = {}; node.context = context; node.callback = callback; calls[event] = { tail: tail, next: list ? list.next : node }; } return this; }; Events.prototype.off = function off(events, callback, context) { var event = void 0, calls = void 0, node = void 0, tail = void 0, cb = void 0, ctx = void 0; if (!(calls = this.callbacks)) { return this; } if (!(events || callback || context)) { delete this.callbacks; return this; } events = events ? events.split(Events.eventSplitter) : Object.keys(calls); while (event = events.shift()) { node = calls[event]; delete calls[event]; if (!node || !(callback || context)) { continue; } tail = node.tail; while ((node = node.next) !== tail) { cb = node.callback; ctx = node.context; if (callback && cb !== callback || context && ctx !== context) { this.on(event, cb, ctx); } } } return this; }; Events.prototype.trigger = function trigger(events) { var event = void 0, node = void 0, calls = void 0, tail = void 0, rest = void 0; if (!(calls = this.callbacks)) { return this; } events = events.split(Events.eventSplitter); rest = [].slice.call(arguments, 1); while (event = events.shift()) { if (node = calls[event]) { tail = node.tail; while ((node = node.next) !== tail) { node.callback.apply(node.context || this, rest); } } } return this; }; return Events; }(); Events.eventSplitter = /\s+/; function type(arg) { var class2type = {}; var toString = class2type.toString; var types = 'Boolean Number String Function Array Date RegExp Object Error'.split(' '); for (var i = 0; i < types.length; i++) { var typeItem = types[i]; class2type['[object ' + typeItem + ']'] = typeItem.toLowerCase(); } if (arg === null) { return arg + ''; } return (typeof arg === 'undefined' ? 'undefined' : _typeof(arg)) === 'object' || typeof arg === 'function' ? class2type[toString.call(arg)] || 'object' : typeof arg === 'undefined' ? 'undefined' : _typeof(arg); } function isBoolean(arg) { return type(arg) === 'boolean'; } function isNumber(arg) { return type(arg) === 'number'; } function isString(arg) { return type(arg) === 'string'; } function isFunction(arg) { return type(arg) === 'function'; } function isArray(arg) { return type(arg) === 'array'; } function isDate(arg) { return type(arg) === 'date'; } function isRegExp(arg) { return type(arg) === 'regexp'; } function isObject(arg) { return type(arg) === 'object'; } function isError(arg) { return type(arg) === 'error'; } function isNative(Ctor) { return isFunction(Ctor) && /native code/.test(Ctor.toString()); } function extend(source, from) { if (!from) { return source; } for (var key in from) { if (from.hasOwnProperty(key)) { source[key] = from[key]; } } return source; } function clone(obj) { return extend({}, obj); } function getPrototype(obj) { /* eslint-disable */ if (Object.getPrototypeOf) { return Object.getPrototypeOf(obj); } else if (obj.__proto__) { return obj.__proto__; } /* eslint-enable */ return obj.constructor.prototype; } function proxy(fn, context) { return function () { return fn.apply(context || this, arguments); }; } function isEmptyObject(obj) { if (!obj) { return true; } for (var prop in obj) { if (obj.hasOwnProperty(prop)) { return false; } } return true; } function debounce(func, wait, immediate) { var timeout = void 0; var args = void 0; var context = void 0; var timestamp = void 0; var result = void 0; var later = function later() { var last = +new Date() - timestamp; if (last < wait && last >= 0) { timeout = setTimeout(later, wait - last); } else { timeout = null; if (!immediate) { result = func.apply(context, args); if (!timeout) { context = null; args = null; } } } }; return function debounced() { context = this; args = arguments; timestamp = +new Date(); var callNow = immediate && !timeout; if (!timeout) { timeout = setTimeout(later, wait); } if (callNow) { result = func.apply(context, args); context = null; args = null; } return result; }; } function throttle(fn, threshhold, scope) { threshhold || (threshhold = 250); var last = void 0, deferTimer = void 0; return function () { var context = scope || this; var now = +new Date(); var args = arguments; if (last && now < last + threshhold) { clearTimeout(deferTimer); deferTimer = setTimeout(function () { last = now; fn.apply(context, args); }, threshhold); } else { last = now; fn.apply(context, args); } }; } var index = Object.freeze({ type: type, isBoolean: isBoolean, isNumber: isNumber, isString: isString, isFunction: isFunction, isArray: isArray, isDate: isDate, isRegExp: isRegExp, isObject: isObject, isError: isError, isNative: isNative, extend: extend, clone: clone, getPrototype: getPrototype, proxy: proxy, isEmptyObject: isEmptyObject, debounce: debounce, throttle: throttle }); var callbacks = []; var pending = false; var runNextTick = void 0; function nextHandler() { pending = false; var copies = callbacks.slice(0); callbacks = []; copies.forEach(function (task) { return task(); }); } function canUsePromise() { return 'Promise' in window && isFunction(Promise) && isNative(Promise); } function canUseMutationObserver() { return 'MutationObserver' in window && isFunction(MutationObserver) && (isNative(MutationObserver) || MutationObserver.toString() === '[object MutationObserverConstructor]'); } function installPromise() { var p = Promise.resolve(); var logErr = function logErr(err) { return console.error(err); }; runNextTick = function _runNextTick() { p.then(nextHandler)['catch'](logErr); }; } function installMutationObserver() { var observeNum = 1; var textNode = document.createTextNode(observeNum); var observer = new MutationObserver(nextHandler); observer.observe(textNode, { characterData: true }); runNextTick = function _runNextTick() { observeNum = (observeNum + 1) % 2; textNode.data = observeNum; }; } function installSetTimeout() { runNextTick = function _runNextTick() { var timer = setTimeout; timer(nextHandler, 0); }; } if (canUsePromise()) { installPromise(); } else if (canUseMutationObserver()) { installMutationObserver(); } else { installSetTimeout(); } function nextTick(cb, ctx) { var _resolve = void 0; callbacks.push(function () { if (cb) { try { cb.call(ctx); } catch (err) { console.error(err); } } else if (_resolve) { _resolve(ctx); } }); if (!pending) { pending = true; runNextTick(); } if (!cb && canUsePromise()) { return new Promise(function (resolve) { _resolve = resolve; }); } } var CurrentOwner = { current: null }; function isVNode(node) { return node && node.type === 'VirtualNode'; } function isVText(node) { return node && node.type === 'VirtualText'; } function isWidget(node) { return node && node.type === 'Widget'; } function isStateLess(node) { return node && node.type === 'StateLess'; } function isHook(arg) { if (arg && typeof arg.hook === 'function' && !arg.hasOwnProperty('hook') || arg && typeof arg.unhook === 'function' && !arg.hasOwnProperty('unhook')) { return true; } return false; } var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; var doc = document; function createElement(vnode, isSvg) { if (isWidget(vnode) || isStateLess(vnode)) { return vnode.init(); } if (isString(vnode) || isNumber(vnode)) { return doc.createTextNode(vnode); } if (isVText(vnode)) { return doc.createTextNode(vnode.text); } if (vnode === null || vnode === false) { return doc.createComment('Empty dom node'); } if (isVNode(vnode)) { if (vnode.isSvg) { isSvg = true; } else if (vnode.tagName === 'svg') { isSvg = true; } else if (vnode.tagName === 'foreignObject') { isSvg = false; } if (isSvg) { vnode.namespace = SVG_NAMESPACE; } var domNode = vnode.namespace === null ? doc.createElement(vnode.tagName) : doc.createElementNS ? doc.createElementNS(vnode.namespace, vnode.tagName) : doc.createElement(vnode.tagName); setProps(domNode, vnode.props, isSvg); if (isSvg) { vnode.isSvg = isSvg; } var children = vnode.children; if (children.length) { children.forEach(function (child) { if (child !== undefined && child !== null && child !== false && domNode.appendChild) { if (isWidget(child)) { child.parentContext = vnode.parentContext || {}; } var childNode = createElement(child, isSvg); if (childNode) { domNode.appendChild(childNode); } } }); } return domNode; } if (Array.isArray(vnode)) { var _domNode = doc.createDocumentFragment(); vnode.forEach(function (child) { if (child !== undefined && child !== null && child !== false && _domNode.appendChild) { var childNode = createElement(child, isSvg); if (childNode) { _domNode.appendChild(childNode); } return _domNode.appendChild(childNode); } }); return _domNode; } return null; } function setProps(domNode, props, isSvg) { for (var p in props) { if (p === 'children') { continue; } var propValue = props[p]; if (isHook(propValue)) { if (propValue.hook) { propValue.hook(domNode, p); } continue; } else if (p === 'style') { if (isString(propValue)) { domNode.setAttribute(p, propValue); } else if (isObject(propValue)) { for (var s in propValue) { var styleValue = propValue[s]; if (styleValue !== undefined) { try { domNode[p][s] = styleValue; } catch (err) {} } } } continue; } else if (isObject(propValue)) { if (p in domNode) { try { domNode[p] = propValue; } catch (err) {} } else { domNode.setAttribute(p, propValue); } continue; } else if (p !== 'list' && p !== 'type' && !isSvg && p in domNode) { try { domNode[p] = propValue == null ? '' : propValue; } catch (err) {} if (propValue == null || propValue === false) { domNode.removeAttribute(p); } continue; } else { if (propValue == null || propValue === false) { domNode.removeAttribute(p); } else { if (!isFunction(propValue)) { domNode.setAttribute(p, propValue); } } } } } var VText = function VText(text) { classCallCheck(this, VText); this.type = 'VirtualText'; this.text = text || ''; }; function createVText(text) { return new VText(text); } var VPatch = function VPatch(type, vnode, patch) { classCallCheck(this, VPatch); this.type = type; this.vnode = vnode; this.patch = patch; }; VPatch.NODE = 'NODE'; VPatch.VTEXT = 'VTEXT'; VPatch.VNODE = 'VNODE'; VPatch.WIDGET = 'WIDGET'; VPatch.STATELESS = 'STATELESS'; VPatch.PROPS = 'PROPS'; VPatch.ORDER = 'ORDER'; VPatch.INSERT = 'INSERT'; VPatch.REMOVE = 'REMOVE'; VPatch.prototype.type = 'VirtualPatch'; function diff(a, b) { var patches = { old: a }; walk(a, b, patches, 0); return patches; } function walk(a, b, patches, index) { if (a === b) { return; } var apply = patches[index]; var applyClear = false; if (!b) { if (!isWidget(a)) { clearState(a, patches, index); apply = patches[index]; } apply = appendPatch(apply, new VPatch(VPatch.REMOVE, a, null)); } else if (isVText(b)) { if (!isVText(a)) { applyClear = true; apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b)); } else if (a.text !== b.text) { apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b)); } } else if (isVNode(b)) { if (!isVNode(a)) { apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b)); applyClear = true; } else if (a.tagName === b.tagName && a.key === b.key) { var propsPatch = diffProps(a.props, b.props); if (propsPatch) { apply = appendPatch(apply, new VPatch(VPatch.PROPS, a, propsPatch)); } apply = diffChildren(a, b, apply, patches, index); } else { apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b)); applyClear = true; } } else if (isWidget(b)) { if (!isWidget(a)) { applyClear = true; } apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b)); } else if (Array.isArray(b)) { applyClear = true; b.forEach(function (item) { walk(null, item, patches, index); index++; }); } else if (isStateLess(b)) { applyClear = true; apply = appendPatch(apply, new VPatch(VPatch.STATELESS, a, b)); } if (apply) { patches[index] = apply; } if (applyClear) { clearState(a, patches, index); } } function diffProps(propsA, propsB) { var diff = null; for (var key in propsA) { if (!propsB.hasOwnProperty(key)) { diff = diff || {}; diff[key] = undefined; } var aValue = propsA[key]; var bValue = propsB[key]; if (aValue === bValue) { continue; } else if (isObject(aValue) && isObject(bValue)) { if (getPrototype(aValue) !== getPrototype(bValue)) { diff = diff || {}; diff[key] = bValue; } else if (isHook(bValue)) { diff = diff || {}; diff[key] = bValue; } else { var objDiff = diffProps(aValue, bValue); if (objDiff) { diff = diff || {}; diff[key] = objDiff; } } } else { diff = diff || {}; diff[key] = bValue; } } for (var _key in propsB) { if (!propsA.hasOwnProperty(_key)) { diff = diff || {}; diff[_key] = propsB[_key]; } } return diff; } function diffChildren(a, b, apply, patches, index) { var aChildren = a.children; var diffSet = diffList(aChildren, b.children, 'key'); var bChildren = diffSet.list; var len = Math.max(aChildren.length, bChildren.length); for (var i = 0; i < len; i++) { var leftNode = aChildren[i]; var rightNode = bChildren[i]; index += 1; if (!leftNode) { if (rightNode) { apply = appendPatch(apply, new VPatch(VPatch.INSERT, null, rightNode)); } } else { walk(leftNode, rightNode, patches, index); } if (isVNode(leftNode) && leftNode.count) { index += leftNode.count; } } if (diffSet.moves) { apply = appendPatch(apply, new VPatch(VPatch.ORDER, a, diffSet.moves)); } return apply; } function diffList(oldList, newList, key) { var newListKeyIndex = mapListKeyIndex(newList, key); var newListkeyMap = newListKeyIndex.keyMap; var newListFree = newListKeyIndex.free; if (newListFree.length === newList.length) { return { list: newList, moves: null }; } var oldListKeyIndex = mapListKeyIndex(oldList, key); var oldListkeyMap = oldListKeyIndex.keyMap; var oldListFree = oldListKeyIndex.free; if (oldListFree.length === oldList.length) { return { list: newList, moves: null }; } var listChange = []; var freeIndex = 0; var deletedItems = 0; listChange = oldList.map(function (item) { var itemKey = item[key]; if (itemKey) { if (newListkeyMap.hasOwnProperty(itemKey)) { return newList[newListkeyMap[itemKey]]; } deletedItems++; return null; } var itemIndex = newListFree[freeIndex++]; var freeItem = newList[itemIndex]; if (!freeItem) { deletedItems++; return null; } return freeItem; }); var lastFreeIndex = freeIndex >= newListFree.length ? newList.length : newListFree[freeIndex]; newList.forEach(function (newItem, index) { var itemKey = newItem[key]; if (itemKey) { if (!oldListkeyMap.hasOwnProperty(itemKey)) { listChange.push(newItem); } } else if (index >= lastFreeIndex) { listChange.push(newItem); } }); var simulate = listChange.slice(0); var simulateIndex = 0; var removes = []; var inserts = []; var simulateItem = void 0; for (var k = 0; k < newList.length;) { simulateItem = simulate[simulateIndex]; while (simulateItem === null && simulate.length) { removes.push(remove(simulate, simulateIndex, null)); simulateItem = simulate[simulateIndex]; } var newItem = newList[k]; var newItemKey = newItem[key]; var simulateItemKey = simulateItem[key]; if (!simulateItem || simulateItemKey !== newItemKey) { if (newItem[key]) { if (simulateItem && simulateItemKey) { if (newListkeyMap[simulateItemKey] !== k + 1) { removes.push(remove(simulate, simulateIndex, simulateItemKey)); simulateItem = simulate[simulateIndex]; if (!simulateItem || simulateItemKey !== newItemKey) { inserts.push({ key: newItemKey, to: k }); } else { simulateIndex++; } } else { inserts.push({ key: newItemKey, to: k }); } } else { inserts.push({ key: newItemKey, to: k }); } k++; } else if (simulateItem && simulateItemKey) { removes.push(remove(simulate, simulateIndex, simulateItemKey)); } } else { simulateIndex++; k++; } } while (simulateIndex < simulate.length) { simulateItem = simulate[simulateIndex]; removes.push(remove(simulate, simulateIndex, simulateItem && simulateItem.key)); } if (removes.length === deletedItems && !inserts.length) { return { list: listChange, moves: null }; } return { list: listChange, moves: { removes: removes, inserts: inserts } }; } function remove(arr, index, key) { arr.splice(index, 1); return { from: index, key: key }; } function clearState(vnode, patch, index) { unhook(vnode, patch, index); destroyWidgets(vnode, patch, index); } function unhook(vnode, patch, index) { if (isVNode(vnode)) { if (vnode.hooks) { patch[index] = appendPatch(patch[index], new VPatch(VPatch.PROPS, vnode, undefinedKeys(vnode.hooks))); } if (vnode.descendantHooks) { var children = vnode.children; var len = children.length; for (var i = 0; i < len; i++) { var child = children[i]; index += 1; unhook(child, patch, index); if (isVNode(child) && child.count) { index += child.count; } } } } else if (isStateLess(vnode)) { index += 1; unhook(vnode._renderd, patch, index); } } function destroyWidgets(vnode, patch, index) { if (isWidget(vnode)) { if (isFunction(vnode.destroy)) { patch[index] = appendPatch(patch[index], new VPatch(VPatch.REMOVE, vnode, null)); } } else if (isVNode(vnode) && vnode.hasWidgets) { vnode.children.forEach(function (child) { index += 1; destroyWidgets(child, patch, index); if (isVNode(child) && child.count) { index += child.count; } }); } else if (isStateLess(vnode)) { index += 1; destroyWidgets(vnode._renderd, patch, index); } } function mapListKeyIndex(list, key) { var keyMap = {}; var free = []; list.forEach(function (item, i) { if (item[key]) { keyMap[item[key]] = i; } else { free.push(i); } }); return { keyMap: keyMap, free: free }; } function undefinedKeys(obj) { var result = {}; for (var key in obj) { result[key] = undefined; } return result; } function appendPatch(apply, patch) { if (apply) { if (Array.isArray(apply)) { apply.push(patch); } else { apply = [apply, patch]; } return apply; } return [patch]; } /* eslint-disable */ if (!Object.is) { Object.is = function (x, y) { if (x === y) { return x !== 0 || 1 / x === 1 / y; } return x !== x && y !== y; }; } /* eslint-enable */ function shallowEqual(obj1, obj2) { if (obj1 === null || obj2 === null) { return false; } if (Object.is(obj1, obj2)) { return true; } var obj1Keys = obj1 ? Object.keys(obj1) : []; var obj2Keys = obj2 ? Object.keys(obj2) : []; if (obj1Keys.length !== obj2Keys.length) { return false; } for (var i = 0; i < obj1Keys.length; i++) { var obj1KeyItem = obj1Keys[i]; if (!obj2.hasOwnProperty(obj1KeyItem) || !Object.is(obj1[obj1KeyItem], obj2[obj1KeyItem])) { return false; } } return true; } function domIndex(rootNode, tree, patchIndices, nodes) { if (!patchIndices || patchIndices.length === 0) { return {}; } patchIndices.sort(function (v1, v2) { return v1 - v2; }); return recurse(rootNode, tree, patchIndices, nodes, 0); } function recurse(rootNode, tree, patchIndices, nodes, index) { nodes = nodes || {}; if (rootNode) { if (indexInRange(patchIndices, index, index)) { nodes[index] = rootNode; } var vChildren = tree.children; if (vChildren) { var childNodes = rootNode.childNodes; vChildren.forEach(function (vChild, i) { index++; vChild = vChild || {}; var nextIndex = index + (vChild.count || 0); if (indexInRange(patchIndices, index, nextIndex)) { recurse(childNodes[i], vChild, patchIndices, nodes, index); } index = nextIndex; }); } } return nodes; } function indexInRange(indices, left, right) { if (indices.length === 0) { return false; } var minIndex = 0; var maxIndex = indices.length - 1; var currentIndex = void 0; var currentItem = void 0; while (minIndex <= maxIndex) { currentIndex = (maxIndex + minIndex) / 2 >> 0; currentItem = indices[currentIndex]; if (minIndex === maxIndex) { return currentItem >= left && currentItem <= right; } if (currentItem < left) { minIndex = currentIndex + 1; } else if (currentItem > right) { maxIndex = currentIndex - 1; } else { return true; } } return false; } function patch(rootNode, patches) { var patchIndices = getPatchIndices(patches); if (patchIndices.length === 0) { return rootNode; } var oldTree = patches.old; var nodes = domIndex(rootNode, oldTree, patchIndices); patchIndices.forEach(function (index) { rootNode = applyPatch(rootNode, nodes[index], patches[index]); }); return rootNode; } function applyPatch(rootNode, domNode, patch) { if (!domNode) { return rootNode; } var newNode = void 0; if (!Array.isArray(patch)) { patch = [patch]; } patch.forEach(function (patchItem) { newNode = patchSingle(domNode, patchItem); if (domNode === rootNode) { rootNode = newNode; } }); return rootNode; } function patchSingle(domNode, vpatch) { var type$$1 = vpatch.type; var oldVNode = vpatch.vnode; var patchObj = vpatch.patch; switch (type$$1) { case VPatch.VTEXT: return patchVText(domNode, patchObj); case VPatch.VNODE: return patchVNode(domNode, patchObj); case VPatch.INSERT: return patchInsert(domNode, patchObj); case VPatch.WIDGET: return patchWidget(domNode, oldVNode, patchObj); case VPatch.STATELESS: return patchStateLess(domNode, oldVNode, patchObj); case VPatch.PROPS: return patchProps(domNode, patchObj, oldVNode.props, oldVNode.isSvg); case VPatch.ORDER: return patchOrder(domNode, patchObj); case VPatch.REMOVE: return patchRemove(domNode, oldVNode); default: return domNode; } } function patchVText(domNode, patch) { if (domNode === null) { return createElement(patch); } if (domNode.nodeType === 3) { if (domNode.textContent) { domNode.textContent = patch.text; } else { domNode.nodeValue = patch.text; } return domNode; } var parentNode = domNode.parentNode; var newNode = createElement(patch); if (parentNode) { parentNode.replaceChild(newNode, domNode); } return newNode; } function patchVNode(domNode, patch) { if (domNode === null) { return createElement(patch); } var parentNode = domNode.parentNode; var newNode = createElement(patch); if (parentNode && newNode !== domNode) { parentNode.replaceChild(newNode, domNode); } return newNode; } function patchInsert(parentNode, vnode) { var newNode = createElement(vnode); if (parentNode && newNode) { parentNode.appendChild(newNode); } return parentNode; } function patchWidget(domNode, vnode, patch) { var isUpdate = isUpdateWidget(vnode, patch); var newNode = void 0; if (isUpdate) { newNode = patch.update(vnode, domNode) || domNode; } else { newNode = createElement(patch); } var parentNode = domNode.parentNode; if (parentNode && domNode !== newNode) { parentNode.replaceChild(newNode, domNode); } if (!isUpdate && vnode) { destroyWidget(domNode, vnode); } return newNode; } function patchStateLess(domNode, vnode, patch) { var oldProps = vnode.props; var newProps = patch.props; if (shallowEqual(oldProps, newProps)) { return domNode; } var newNode = createElement(patch); var parentNode = domNode.parentNode; if (parentNode && domNode !== newNode) { parentNode.replaceChild(newNode, domNode); } return newNode; } function destroyWidget(domNode, widget) { if (isFunction(widget.destroy) && isWidget(widget)) { widget.destroy(domNode); } } function patchProps(domNode, patch, previousProps, isSvg) { for (var propName in patch) { if (propName === 'children') { continue; } var propValue = patch[propName]; var previousValue = previousProps[propName]; if (propValue == null || propValue === false) { if (isHook(previousValue) && previousValue.unhook) { previousValue.unhook(domNode, propName, propValue); continue; } else if (propName === 'style') { if (isString(previousValue)) { for (var styleName in previousValue) { domNode.style[styleName] = ''; } } else { domNode.removeAttribute(propName); } continue; } else if (propName in domNode) { if (isString(previousValue)) { domNode[propName] = ''; } else { domNode[propName] = null; } domNode.removeAttribute(propName); } else { domNode.removeAttribute(propName); } } else { if (isHook(propValue)) { if (isHook(previousValue) && previousValue.unhook) { previousValue.unhook(domNode, propName, propValue); } if (propValue && propValue.hook) { propValue.hook(domNode, propName, previousValue); } continue; } else if (propName === 'style') { if (isString(propValue)) { domNode.setAttribute(propName, propValue); } else { for (var _styleName in propValue) { var styleValue = propValue[_styleName]; if (styleValue != null && styleValue !== false) { try { domNode[propName][_styleName] = styleValue; } catch (err) {} } } } continue; } else if (isObject(propValue)) { if (previousValue && isObject(previousValue) && getPrototype(previousValue) !== getPrototype(propValue)) { if (propName in domNode) { try { domNode[propName] = propValue; } catch (err) {} } else { domNode.setAttribute(propName, propValue); } } continue; } else if (propName !== 'list' && propName !== 'type' && !isSvg && propName in domNode) { try { domNode[propName] = propValue; } catch (err) {} continue; } else if (!isFunction(propValue)) { domNode.setAttribute(propName, propValue); } } } return domNode; } function patchOrder(domNode, patch) { var removes = patch.removes; var inserts = patch.inserts; var childNodes = domNode.childNodes; var keyMap = {}; var node = void 0; var remove = void 0; var insert = void 0; for (var i = 0; i < removes.length; i++) { remove = removes[i]; node = childNodes[remove.from]; if (remove.key) { keyMap[remove.key] = node; } domNode.removeChild(node); } var length = childNodes.length; for (var j = 0; j < inserts.length; j++) { insert = inserts[j]; node = keyMap[insert.key]; domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to]); } return domNode; } function patchRemove(domNode, vnode) { var parentNode = domNode.parentNode; if (parentNode) { parentNode.removeChild(domNode); } if (isWidget(vnode)) { destroyWidget(domNode, vnode); } return null; } function isUpdateWidget(a, b) { if (isWidget(a) && isWidget(b)) { var keyA = a.props.key; var keyB = b.props.key; if ('name' in a && 'name' in b) { return a.name === b.name && keyA === keyB; } return a.init === b.init && keyA === keyB; } return false; } function getPatchIndices(patches) { var indices = []; if (patches) { for (var i in patches) { if (i !== 'old' && patches.hasOwnProperty(i)) { indices.push(Number(i)); } } } return indices; } var RefHook = function () { function RefHook(callback) { classCallCheck(this, RefHook); this.callback = callback; } RefHook.prototype.hook = function hook(node) { this.callback(node); }; RefHook.prototype.unhook = function unhook() { this.callback(null); }; return RefHook; }(); var readyComponents = []; function mountVNode(vnode, parentContext) { if (isObject(vnode)) { vnode.parentContext = parentContext; } return createElement(vnode); } function mountComponent(vnode) { var parentContext = vnode.parentContext; var componentPrototype = vnode.ComponentType.prototype; if (componentPrototype && isFunction(componentPrototype.render)) { vnode.component = new vnode.ComponentType(vnode.props, vnode.context); } var component = vnode.component; component.context = vnode.context || parentContext; if (isFunction(component.componentWillMount)) { component.componentWillMount(); component.state = component.getState(); } component._dirty = false; var rendered = renderComponent(component); component._rendered = rendered; if (isFunction(component.componentDidMount)) { readyComponents.push(component); } if (isFunction(vnode.props.ref)) { readyComponents.push(function () { return vnode.props.ref(component); }); } var dom = mountVNode(rendered, getChildContext(component, parentContext)); component.dom = dom; component._disable = false; return dom; } function mountStatelessComponent(vnode) { var ref = vnode.props.ref; delete vnode.props.ref; vnode._renderd = vnode.tagName(vnode.props, vnode.parentContext); var rendered = vnode._renderd; if (isVNode(rendered) && isFunction(ref)) { ref = new RefHook(ref); rendered.props.ref = ref; } return mountVNode(rendered, vnode.parentContext); } function getChildContext(component, context) { if (component.getChildContext) { return extend(context, component.getChildContext()); } return context; } function renderComponent(component) { CurrentOwner.current = component; var rendered = component.render(); if (isNumber(rendered) || isString(rendered)) { rendered = createVText(rendered); } CurrentOwner.current = null; return rendered; } function flushMount() { if (!readyComponents.length) { return; } var queue = readyComponents.slice(0); readyComponents.length = 0; queue.forEach(function (item) { if (isFunction(item)) { item(); } else if (item.componentDidMount) { item.componentDidMount(); } }); } function reRenderComponent(prev, current) { var component = current.component = prev.component; var nextProps = current.props; var nextContext = component.context; component._disable = true; if (isFunction(component.componentWillReceiveProps)) { component.componentWillReceiveProps(nextProps, nextContext); } component._disable = false; component.prevProps = component.props; component.prevState = component.state; component.prevContext = component.context; component.props = nextProps; component.context = nextContext; if (isFunction(current.props.ref)) { current.props.ref(component); } updateComponent(component); return component.dom; } function updateComponent(component, isForce) { var lastDom = component.dom; var props = component.props; var state = component.getState(); var context = component.context; var prevProps = component.prevProps || props; var prevContext = component.prevContext || context; component.props = prevProps; component.context = prevContext; var skip = false; if (!isForce && isFunction(component.shouldComponentUpdate) && component.shouldComponentUpdate(props, state, context) === false) { skip = true; } else if (isFunction(component.componentWillUpdate)) { component.componentWillUpdate(props, state, context); } component.props = props; component.state = state; component.context = context; component._dirty = false; if (!skip) { var lastRendered = component._rendered; var rendered = renderComponent(component); var childContext = getChildContext(component, context); component._rendered = rendered; component.dom = updateVNode(rendered, lastRendered, lastDom, childContext); if (component.componentDidUpdate) { component.componentDidUpdate(props, state, context); } } component.prevProps = component.props; component.prevState = component.state; component.prevContext = component.context; if (component._pendingCallbacks) { while (component._pendingCallbacks.length) { component._pendingCallbacks.pop().call(component); } } flushMount(); } function updateVNode(vnode, lastVNode, lastDom, childContext) { if (isObject(vnode)) { vnode.context = childContext; } var patches = diff(lastVNode, vnode); var domNode = patch(lastDom, patches); return domNode; } function unmountComponent(vnode) { var component = vnode.component; if (isFunction(component.componentWillUnmount)) { component.componentWillUnmount(); } var lastRendered = component._rendered; updateVNode(null, lastRendered, component.dom, component.context); component.dom = component._rendered = null; if (isFunction(vnode.props.ref)) { vnode.props.ref(null); } } var items = []; function enqueueRender(component) { if (!component._dirty && (component._dirty = true) && items.push(component) === 1) { nextTick(rerender); } } function rerender() { var p = void 0; var list = items.concat(); items.length = 0; while (p = list.pop()) { if (p._dirty) { updateComponent(p); } } } var Component = function (_Events) { inherits(Component, _Events); function Component(props, context) { classCallCheck(this, Component); var _this = possibleConstructorReturn(this, _Events.call(this)); if (!_this.state) { _this.state = {}; } _this.props = props || {}; _this.context = context || {}; _this._dirty = true; _this._disable = true; return _this; } Component.prototype.setState = function setState(state, callback) { if (state) { (this._pendingStates = this._pendingStates || []).push(state); } if (isFunction(callback)) { (this._pendingCallbacks = this._pendingCallbacks || []).push(callback); } if (!this._disable) { enqueueRender(this); } }; Component.prototype.getState = function getState() { var _this2 = this; var _pendingStates2 = this._pendingStates, _pendingStates = _pendingStates2 === undefined ? [] : _pendingStates2, state = this.state, props = this.props; if (!_pendingStates.length) { return state; } var stateClone = clone(state); var queue = _pendingStates.concat(); this._pendingStates.length = 0; queue.forEach(function (nextState) { if (isFunction(nextState)) { nextState = nextState.call(_this2, state, props); } extend(stateClone, nextState); }); return stateClone; }; Component.prototype.forceUpdate = function forceUpdate(callback) { if (isFunction(callback)) { (this._pendingCallbacks = this._pendingCallbacks || []).push(callback); } updateComponent(this, true); }; return Component; }(Events); var PureComponent = function (_Component) { inherits(PureComponent, _Component); function PureComponent() { var _temp, _this, _ret; classCallCheck(this, PureComponent); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.isPureComponent = true, _temp), possibleConstructorReturn(_this, _ret); } PureComponent.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) { return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); }; return PureComponent; }(Component); function isVChild(vnode) { return isVNode(vnode) || isString(vnode) || isNumber(vnode); } function render(vnode, container, callback) { if (!isVChild(vnode) && !isWidget(vnode) && !isStateLess(vnode)) { return null; } if (!container || container.nodeType !== 1) { throw new Error(container + ' should be a DOM Element'); } var dom = mountVNode(vnode, {}); if (dom) { container.appendChild(dom); } flushMount(); if (callback) { callback(); } return vnode.component || dom; } var VNode = function VNode(tagName, props, children, key, namespace, owner) { classCallCheck(this, VNode); this.type = 'VirtualNode'; this.tagName = tagName || 'DIV'; this.props = props || {}; this.children = children || []; this.key = key || null; this.namespace = isString(namespace) ? namespace : null; this._owner = owner; var count = this.children.length || 0; var descendants = 0; var hasWidgets = false; var descendantHooks = false; var hooks = void 0; for (var propName in props) { if (props.hasOwnProperty(propName)) { var property = props[propName]; if (isHook(property) && property.unhook) { if (!hooks) { hooks = {}; } hooks[propName] = property; } } } if (count) { this.children.forEach(function (child) { if (isVNode(child)) { descendants += child.count || 0; if (!hasWidgets && child.hasWidgets) { hasWidgets = true; } if (!descendantHooks && (child.hooks || child.descendantHooks)) { descendantHooks = true; } } else if (!hasWidgets && isWidget(child)) { if (isFunction(child.destroy)) { hasWidgets = true; } } }); } this.count = count + descendants; this.hasWidgets = hasWidgets; this.hooks = hooks; this.descendantHooks = descendantHooks; }; function h(tagName, props, children) { var key = void 0; var namespace = void 0; var owner = void 0; var childNodes = []; if (!children && isChildren(props)) { children = props; props = {}; } props = props || {}; if (props.hasOwnProperty('key') && props.key) { key = props.key; delete props.key; } if (props.hasOwnProperty('namespace') && props.namespace) { namespace = props.namespace; delete props.namespace; } if (props.hasOwnProperty('owner')) { owner = props.owner; delete props.owner; } if (props.hasOwnProperty('children') && props.children) { if (!children || !children.length) { children = props.children; } delete props.children; } if (children) { addChildren(childNodes, children, tagName); } return new VNode(tagName, props, childNodes, key, namespace, owner); } function addChildren(childNodes, children, tagName) { if (isString(children) || isNumber(children)) { children = String(children); childNodes.push(createVText(children)); } else if (isChild(children)) { childNodes.push(children); } else if (isArray(children)) { children.forEach(function (child) { return addChildren(childNodes, child, tagName); }); } } function isChild(node) { return isVNode(node) || isVText(node) || isWidget(node) || isStateLess(node); } function isChildren(x) { return isString(x) || isArray(x) || isChild(x); } var NS = { ev: 'http://www.w3.org/2001/xml-events', xlink: 'http://www.w3.org/1999/xlink', xml: 'http://www.w3.org/XML/1998/namespace' }; var ATTRS = { accentHeight: 'accent-height', accumulate: 0, additive: 0, alignmentBaseline: 'alignment-baseline', allowReorder: 'allowReorder', alphabetic: 0, amplitude: 0, arabicForm: 'arabic-form', ascent: 0, attributeName: 'attributeName', attributeType: 'attributeType', autoReverse: 'autoReverse', azimuth: 0, baseFrequency: 'baseFrequency', baseProfile: 'baseProfile', baselineShift: 'baseline-shift', bbox: 0, begin: 0, bias: 0, by: 0, calcMode: 'calcMode', capHeight: 'cap-height', clip: 0, clipPath: 'clip-path', clipRule: 'clip-rule', clipPathUnits: 'clipPathUnits', colorInterpolation: 'color-interpolation', colorInterpolationFilters: 'color-interpolation-filters', colorProfile: 'color-profile', colorRendering: 'color-rendering', contentScriptType: 'contentScriptType', contentStyleType: 'contentStyleType', cursor: 0, cx: 0, cy: 0, d: 0, decelerate: 0, descent: 0, diffuseConstant: 'diffuseConstant', direction: 0, display: 0, divisor: 0, dominantBaseline: 'dominant-baseline', dur: 0, dx: 0, dy: 0, edgeMode: 'edgeMode', elevation: 0, enableBackground: 'enable-background', end: 0, evEvent: 'ev:event', exponent: 0, externalResourcesRequired: 'externalResourcesRequired', fill: 0, fillOpacity: 'fill-opacity', fillRule: 'fill-rule', filter: 0, filterRes: 'filterRes', filterUnits: 'filterUnits', floodColor: 'flood-color', floodOpacity: 'flood-opacity', focusable: 0, fontFamily: 'font-family', fontSize: 'font-size', fontSizeAdjust: 'font-size-adjust', fontStretch: 'font-stretch', fontStyle: 'font-style', fontVariant: 'font-variant', fontWeight: 'font-weight', format: 0, from: 0, fx: 0, fy: 0, g1: 0, g2: 0, glyphName: 'glyph-name', glyphOrientationHorizontal: 'glyph-orientation-horizontal', glyphOrientationVertical: 'glyph-orientation-vertical', glyphRef: 'glyphRef', gradientTransform: 'gradientTransform', gradientUnits: 'gradientUnits', hanging: 0, horizAdvX: 'horiz-adv-x', horizOriginX: 'horiz-origin-x', ideographic: 0, imageRendering: 'image-rendering', 'in': 0, in2: 0, intercept: 0, k: 0, k1: 0, k2: 0, k3: 0, k4: 0, kernelMatrix: 'kernelMatrix', kernelUnitLength: 'kernelUnitLength', kerning: 0, keyPoints: 'keyPoints', keySplines: 'keySplines', keyTimes: 'keyTimes', lengthAdjust: 'lengthAdjust', letterSpacing: 'letter-spacing', lightingColor: 'lighting-color', limitingConeAngle: 'limitingConeAngle', local: 0, markerEnd: 'marker-end', markerMid: 'marker-mid', markerStart: 'marker-start', markerHeight: 'markerHeight', markerUnits: 'markerUnits', markerWidth: 'markerWidth', mask: 0, maskContentUnits: 'maskContentUnits', maskUnits: 'maskUnits', mathematical: 0, mode: 0, numOctaves: 'numOctaves', offset: 0, opacity: 0, operator: 0, order: 0, orient: 0, orientation: 0, origin: 0, overflow: 0, overlinePosition: 'overline-position', overlineThickness: 'overline-thickness', paintOrder: 'paint-order', panose1: 'panose-1', pathLength: 'pathLength', patternContentUnits: 'patternContentUnits', patternTransform: 'patternTransform', patternUnits: 'patternUnits', pointerEvents: 'pointer-events', points: 0, pointsAtX: 'pointsAtX', pointsAtY: 'pointsAtY', pointsAtZ: 'pointsAtZ', preserveAlpha: 'preserveAlpha', preserveAspectRatio: 'preserveAspectRatio', primitiveUnits: 'primitiveUnits', r: 0, radius: 0, refX: 'refX', refY: 'refY', renderingIntent: 'rendering-intent', repeatCount: 'repeatCount', repeatDur: 'repeatDur', requiredExtensions: 'requiredExtensions', requiredFeatures: 'requiredFeatures', restart: 0, result: 0, rotate: 0, rx: 0, ry: 0, scale: 0, seed: 0, shapeRendering: 'shape-rendering', slope: 0, spacing: 0, specularConstant: 'specularConstant', specularExponent: 'specularExponent', speed: 0, spreadMethod: 'spreadMethod', startOffset: 'startOffset', stdDeviation: 'stdDeviation', stemh: 0, stemv: 0, stitchTiles: 'stitchTiles', stopColor: 'stop-color', stopOpacity: 'stop-opacity', strikethroughPosition: 'strikethrough-position', strikethroughThickness: 'strikethrough-thickness', string: 0, stroke: 0, strokeDasharray: 'stroke-dasharray', strokeDashoffset: 'stroke-dashoffset', strokeLinecap: 'stroke-linecap', strokeLinejoin: 'stroke-linejoin', strokeMiterlimit: 'stroke-miterlimit', strokeOpacity: 'stroke-opacity', strokeWidth: 'stroke-width', surfaceScale: 'surfaceScale', systemLanguage: 'systemLanguage', tableValues: 'tableValues', targetX: 'targetX', targetY: 'targetY', textAnchor: 'text-anchor', textDecoration: 'text-decoration', textRendering: 'text-rendering', textLength: 'textLength', to: 0, transform: 0, u1: 0, u2: 0, underlinePosition: 'underline-position', underlineThickness: 'underline-thickness', unicode: 0, unicodeBidi: 'unicode-bidi', unicodeRange: 'unicode-range', unitsPerEm: 'units-per-em', vAlphabetic: 'v-alphabetic', vHanging: 'v-hanging', vIdeographic: 'v-ideographic', vMathematical: 'v-mathematical', values: 0, vectorEffect: 'vector-effect', version: 0, vertAdvY: 'vert-adv-y', vertOriginX: 'vert-origin-x', vertOriginY: 'vert-origin-y', viewBox: 'viewBox', viewTarget: 'viewTarget', visibility: 0, widths: 0, wordSpacing: 'word-spacing', writingMode: 'writing-mode', x: 0, xHeight: 'x-height', x1: 0, x2: 0, xChannelSelector: 'xChannelSelector', xlinkActuate: 'xlink:actuate', xlinkArcrole: 'xlink:arcrole', xlinkHref: 'xlink:href', xlinkRole: 'xlink:role', xlinkShow: 'xlink:show', xlinkTitle: 'xlink:title', xlinkType: 'xlink:type', xmlBase: 'xml:base', xmlId: 'xml:id', xmlns: 0, xmlnsXlink: 'xmlns:xlink', xmlLang: 'xml:lang', xmlSpace: 'xml:space', y: 0, y1: 0, y2: 0, yChannelSelector: 'yChannelSelector', z: 0, zoomAndPan: 'zoomAndPan' }; var SVGPropertyConfig = { Properties: {}, DOMAttributeNamespaces: { evEvent: NS.ev, xlinkActuate: NS.xlink, xlinkArcrole: NS.xlink, xlinkHref: NS.xlink, xlinkRole: NS.xlink, xlinkShow: N