nervjs
Version:
A react-like framework based on virtual-dom
1,178 lines (1,170 loc) • 72.2 kB
JavaScript
!function(global, factory) {
'object' == typeof exports && 'undefined' != typeof module ? factory(exports) : 'function' == typeof define && define.amd ? define([ 'exports' ], factory) : factory(global.Nerv = global.Nerv || {});
}(this, function(exports) {
'use strict';
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 (null === arg) return arg + ''; else return 'object' === (void 0 === arg ? 'undefined' : _typeof(arg)) || 'function' == typeof arg ? class2type[toString.call(arg)] || 'object' : void 0 === arg ? 'undefined' : _typeof(arg);
}
function isBoolean(arg) {
return 'boolean' === type(arg);
}
function isNumber(arg) {
return 'number' === type(arg);
}
function isString(arg) {
return 'string' === type(arg);
}
function isFunction(arg) {
return 'function' === type(arg);
}
function isArray(arg) {
return 'array' === type(arg);
}
function isDate(arg) {
return 'date' === type(arg);
}
function isRegExp(arg) {
return 'regexp' === type(arg);
}
function isObject(arg) {
return 'object' === type(arg);
}
function isError(arg) {
return 'error' === type(arg);
}
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) {
if (Object.getPrototypeOf) return Object.getPrototypeOf(obj); else if (obj.__proto__) return obj.__proto__;
return obj.constructor.prototype;
}
function proxy(fn, context) {
return function() {
return fn.apply(context || this, arguments);
};
}
function isEmptyObject(obj) {
if (!obj) return !0;
for (var prop in obj) if (obj.hasOwnProperty(prop)) return !1;
return !0;
}
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() {
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);
}
};
}
function nextHandler() {
pending = !1;
var copies = callbacks.slice(0);
callbacks = [];
copies.forEach(function(task) {
return task();
});
}
function canUsePromise() {
return 'Promise' in window && isFunction(Promise) && isNative(Promise);
}
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 = !0;
runNextTick();
}
if (!cb && canUsePromise()) return new Promise(function(resolve) {
_resolve = resolve;
});
}
function isVNode(node) {
return node && 'VirtualNode' === node.type;
}
function isVText(node) {
return node && 'VirtualText' === node.type;
}
function isWidget(node) {
return node && 'Widget' === node.type;
}
function isStateLess(node) {
return node && 'StateLess' === node.type;
}
function isHook(arg) {
if (arg && 'function' == typeof arg.hook && !arg.hasOwnProperty('hook') || arg && 'function' == typeof arg.unhook && !arg.hasOwnProperty('unhook')) return !0; else return !1;
}
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 (null === vnode || !1 === vnode) return doc.createComment('Empty dom node');
if (isVNode(vnode)) {
if (vnode.isSvg) isSvg = !0; else if ('svg' === vnode.tagName) isSvg = !0; else if ('foreignObject' === vnode.tagName) isSvg = !1;
if (isSvg) vnode.namespace = SVG_NAMESPACE;
var domNode = null === vnode.namespace ? 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 (void 0 !== child && null !== child && !1 !== child && 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 (void 0 !== child && null !== child && !1 !== child && _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 ('children' !== p) {
var propValue = props[p];
if (!isHook(propValue)) {
if ('style' === p) {
if (isString(propValue)) domNode.setAttribute(p, propValue); else if (isObject(propValue)) for (var s in propValue) {
var styleValue = propValue[s];
if (void 0 !== styleValue) 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 ('list' !== p && 'type' !== p && !isSvg && p in domNode) {
try {
domNode[p] = null == propValue ? '' : propValue;
} catch (err) {}
if (null == propValue || !1 === propValue) domNode.removeAttribute(p);
continue;
} else if (null == propValue || !1 === propValue) domNode.removeAttribute(p); else if (!isFunction(propValue)) domNode.setAttribute(p, propValue);
} else if (propValue.hook) propValue.hook(domNode, p);
}
}
function createVText(text) {
return new VText(text);
}
function diff(a, b) {
var patches = {
old: a
};
walk(a, b, patches, 0);
return patches;
}
function walk(a, b, patches, index) {
if (a !== b) {
var apply = patches[index];
var applyClear = !1;
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 = !0;
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 = !0;
} 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 = !0;
} else if (isWidget(b)) {
if (!isWidget(a)) applyClear = !0;
apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b));
} else if (Array.isArray(b)) {
applyClear = !0;
b.forEach(function(item) {
walk(null, item, patches, index);
index++;
});
} else if (isStateLess(b)) {
applyClear = !0;
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] = void 0;
}
var aValue = propsA[key];
var bValue = propsB[key];
if (aValue !== bValue) 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 (null === simulateItem && 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
}; else 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] = void 0;
return result;
}
function appendPatch(apply, patch) {
if (apply) {
if (Array.isArray(apply)) apply.push(patch); else apply = [ apply, patch ];
return apply;
}
return [ patch ];
}
function shallowEqual(obj1, obj2) {
if (null === obj1 || null === obj2) return !1;
if (Object.is(obj1, obj2)) return !0;
var obj1Keys = obj1 ? Object.keys(obj1) : [];
var obj2Keys = obj2 ? Object.keys(obj2) : [];
if (obj1Keys.length !== obj2Keys.length) return !1;
for (var i = 0; i < obj1Keys.length; i++) {
var obj1KeyItem = obj1Keys[i];
if (!obj2.hasOwnProperty(obj1KeyItem) || !Object.is(obj1[obj1KeyItem], obj2[obj1KeyItem])) return !1;
}
return !0;
}
function domIndex(rootNode, tree, patchIndices, nodes) {
if (!patchIndices || 0 === patchIndices.length) 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 (0 === indices.length) return !1;
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 !0;
}
return !1;
}
function patch(rootNode, patches) {
var patchIndices = getPatchIndices(patches);
if (0 === patchIndices.length) 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 (null === domNode) return createElement(patch);
if (3 === domNode.nodeType) {
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 (null === domNode) 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 ('children' !== propName) {
var propValue = patch[propName];
var previousValue = previousProps[propName];
if (null == propValue || !1 === propValue) if (isHook(previousValue) && previousValue.unhook) {
previousValue.unhook(domNode, propName, propValue);
continue;
} else if ('style' === propName) {
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 ('style' === propName) {
if (isString(propValue)) domNode.setAttribute(propName, propValue); else for (var _styleName in propValue) {
var styleValue = propValue[_styleName];
if (null != styleValue && !1 !== styleValue) 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 ('list' !== propName && 'type' !== propName && !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; else return a.init === b.init && keyA === keyB;
}
return !1;
}
function getPatchIndices(patches) {
var indices = [];
if (patches) for (var i in patches) if ('old' !== i && patches.hasOwnProperty(i)) indices.push(Number(i));
return indices;
}
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 = !1;
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 = !1;
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()); else 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) {
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 = !0;
if (isFunction(component.componentWillReceiveProps)) component.componentWillReceiveProps(nextProps, nextContext);
component._disable = !1;
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 = !1;
if (!isForce && isFunction(component.shouldComponentUpdate) && !1 === component.shouldComponentUpdate(props, state, context)) skip = !0; else if (isFunction(component.componentWillUpdate)) component.componentWillUpdate(props, state, context);
component.props = props;
component.state = state;
component.context = context;
component._dirty = !1;
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);
}
function enqueueRender(component) {
if (!component._dirty && (component._dirty = !0) && 1 === items.push(component)) nextTick(rerender);
}
function rerender() {
var p = void 0;
var list = items.concat();
items.length = 0;
while (p = list.pop()) if (p._dirty) updateComponent(p);
}
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 || 1 !== container.nodeType) 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;
}
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);
}
function getEventName(name) {
if ('onDoubleClick' === name) name = 'ondblclick'; else if ('onTouchTap' === name) name = 'onclick';
return name.toLowerCase();
}
function parseEventName(name) {
return name.substr(2);
}
function stopPropagation() {
this.cancelBubble = !0;
this.stopImmediatePropagation();
}
function dispatchEvent(event, target, items, count, eventData) {
var eventsToTrigger = items.get(target);
if (eventsToTrigger) {
count--;
eventData.currentTarget = target;
eventsToTrigger(event);
if (event.cancelBubble) return;
}
if (count > 0) {
var parentDom = target.parentNode;
if (null === parentDom || 'click' === event.type && 1 === parentDom.nodeType && parentDom.disabled) return;
dispatchEvent(event, parentDom, items, count, eventData);
}
}
function attachEventToDocument(doc, eventName, delegatedRoots) {
var eventHandler = function(event) {
var count = delegatedRoots.items.size();
if (count > 0) {
var eventData = {
currentTarget: event.target
};
Object.defineProperties(event, {
currentTarget: {
configurable: !0,
get: function() {
return eventData.currentTarget;
}
},
stopPropagation: {
value: stopPropagation
}
});
dispatchEvent(event, event.target, delegatedRoots.items, count, eventData);
}
};
doc.addEventListener(parseEventName(eventName), eventHandler, !1);
return eventHandler;
}
function attachEventToNode(node, eventName, delegatedRoots) {
var eventHandler = function(event) {
var eventToTrigger = delegatedRoots.get(node);
if (eventToTrigger && eventToTrigger.eventHandler) {
var eventData = {
currentTarget: node
};
Object.defineProperties(event, {
currentTarget: {
configurable: !0,
get: function() {
return eventData.currentTarget;
}
}
});
eventToTrigger.eventHandler(event);
}
};
node.addEventListener(parseEventName(eventName), eventHandler, !1);
return eventHandler;
}
function transformPropsForRealTag(tagName, props) {
var newProps = {};
var DOMAttributeNamespaces = SVGPropertyConfig.DOMAttributeNamespaces;
for (var propName in props) {
var propValue = props[propName];
var originalPropName = propName;
var domAttributeName = SVGPropertyConfig.DOMAttributeNames[propName];
propName = domAttributeName || propName;
if (!DOMAttributeNamespaces.hasOwnProperty(originalPropName) || !(isString(propValue) || isNumber(propValue) || isBoolean(propValue))) if ('id' !== propName && 'className' !== propName && 'namespace' !== propName || void 0 === propValue) if ('ref' !== propName) if ('dangerouslySetInnerHTML' !== propName) if ('o' !== propName.charAt(0) || 'n' !== propName.charAt(1)) if ('defaultValue' !== propName) {
if ('style' !== propName) newProps[propName] = propValue; else if (isString(propValue)) newProps[propName] = propValue; else if (isObject(propValue)) for (var styleName in propValue) {
var styleValue = propValue[styleName];
if (void 0 !== styleValue && (isString(styleValue) || !isNaN(styleValue))) {
styleValue = isNumber(styleValue) && !1 === IS_NON_DIMENSIONAL.test(styleName) ? styleValue + 'px' : styleValue;
newProps[propName] = newProps[propName] || {};
newProps[propName][styleName] = styleValue;
}
}
} else newProps.value = props.value || props.defaultValue; else newProps[propName] = !(propValue instanceof EventHook) ? new EventHook(propName, propValue) : propValue; else newProps[propName] = !(propValue instanceof HtmlHook) ? new HtmlHook(propValue) : propValue; else newProps[propName] = !(propValue instanceof RefHook) ? new RefHook(propValue) : propValue; else newProps[propName] = propValue; else {
var namespace = DOMAttributeNamespaces[originalPropName];
newProps[propName] = !(propValue instanceof AttributeHook) ? new AttributeHook(namespace, propValue) : propValue;
}
}
return newProps;
}
function transformPropsForComponent(props) {
var newProps = {};
for (var propName in props) {
var propValue = props[propName];
newProps[propName] = propValue;
}
return newProps;
}
function createElement$2(tagName, properties) {
var children = EMPTY_CHILDREN;
for (var i = 2, len = arguments.length; i < len; i++) {
var argumentsItem = arguments[i];
if (Array.isArray(argumentsItem)) argumentsItem.forEach(function(item) {
if (children === EMPTY_CHILDREN) children = [ item ]; else children.push(item);
}); else if (children === EMPTY_CHILDREN) children = [ argumentsItem ]; else children.push(argumentsItem);
}
var props = void 0;
if (isString(tagName)) {
props = transformPropsForRealTag(tagName, properties);
props.owner = CurrentOwner.current;
return h(tagName, props, children);
} else if (isFunction(tagName)) {
props = transformPropsForComponent(properties);
if (props.children) {
if (!Array.isArray(props.children)) props.children = [ props.children ];
} else props.children = children;
props.owner = CurrentOwner.current;
return tagName.prototype && tagName.prototype.render ? new ComponentWrapper(tagName, props) : new StateLessComponent(tagName, props);
}
return tagName;
}
function cloneElement(vnode, props) {
var properties = clone(vnode.props);
if (properties.attributes) {
properties = extend(properties, properties.attributes);
delete properties.attributes;
}
properties = extend(properties, props);
if (vnode.key) properties.key = vnode.key;
if (vnode.namespace) properties.namespace = vnode.namespace;
return createElement$2(vnode.tagName, properties, arguments.length > 2 ? [].slice.call(arguments, 2) : vnode.props.children);
}
var _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(obj) {
return typeof obj;
} : function(obj) {
return obj && "function" == typeof Symbol && 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 ("function" != typeof superClass && null !== superClass) 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: !1,
writable: !0,
configurable: !0
}
});
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 && ("object" == typeof call || "function" == typeof call) ? call : self;
};
var Events = function() {
function Events(opts) {
classCallCheck(this, Events);
if (void 0 !== opts && opts.callbacks) this.callbacks = opts.callbacks; else this.callbacks = {};
}
Events.prototype.on = function(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(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)) {
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(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+/;
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 = !1;
var runNextTick = void 0;
if (canUsePromise()) !function() {
var p = Promise.resolve();
var logErr = function(err) {
return console.error(err);
};
runNextTick = function() {
p.then(nextHandler).catch(logErr);
};
}(); else if (function() {
return 'MutationObserver' in window && isFunction(MutationObserver) && (isNative(MutationObserver) || '[object MutationObserverConstructor]' === MutationObserver.toString());
}()) !function() {
var observeNum = 1;
var textNode = document.createTextNode(observeNum);
var observer = new MutationObserver(nextHandler);
observer.observe(textNode, {
characterData: !0
});
runNextTick = function() {
observeNum = (observeNum + 1) % 2;
textNode.data = observeNum;
};
}(); else !function() {
runNextTick = function() {
var timer = setTimeout;
timer(nextHandler, 0);
};
}();
var CurrentOwner = {
current: null
};
var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
var doc = document;
var VText = function VText(text) {
classCallCheck(this, VText);
this.type = 'VirtualText';
this.text = 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';
V