nervjs
Version:
A react-like framework based on virtual-dom
1,594 lines (1,569 loc) • 70.5 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.Nerv = {})));
}(this, (function (exports) { 'use strict';
// tslint:disable-next-line
var global = function () {
var local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('global object is unavailable in this environment');
}
}
return local;
}();
var isBrowser = typeof window !== 'undefined';
// tslint:disable-next-line:no-empty
function noop() {}
var fakeDoc = {
createElement: noop,
createElementNS: noop,
createTextNode: noop
};
var doc = isBrowser ? document : fakeDoc;
function isNumber(arg) {
return typeof arg === 'number';
}
var isSupportSVG = isFunction(doc.createAttributeNS);
function isString(arg) {
return typeof arg === 'string';
}
function isFunction(arg) {
return typeof arg === 'function';
}
function isBoolean(arg) {
return arg === true || arg === false;
}
var isArray = Array.isArray;
function isUndefined(o) {
return o === undefined;
}
var canUsePromise = 'Promise' in global;
var resolved;
if (canUsePromise) {
resolved = Promise.resolve();
}
var nextTick = function (fn) {
var args = [],
len = arguments.length - 1;
while (len-- > 0) args[len] = arguments[len + 1];
fn = isFunction(fn) ? fn.bind.apply(fn, [null].concat(args)) : fn;
if (canUsePromise) {
return resolved.then(fn);
}
var timerFunc = 'requestAnimationFrame' in global ? requestAnimationFrame : setTimeout;
timerFunc(fn);
};
/* istanbul ignore next */
// tslint:disable-next-line
Object.is = Object.is || function (x, y) {
if (x === y) {
return x !== 0 || 1 / x === 1 / y;
}
return x !== x && y !== y;
};
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;
}
var SimpleMap = function SimpleMap() {
this.cache = [];
this.size = 0;
};
SimpleMap.prototype.set = function set(k, v) {
var this$1 = this;
var len = this.cache.length;
if (!len) {
this.cache.push({ k: k, v: v });
this.size += 1;
return;
}
for (var i = 0; i < len; i++) {
var item = this$1.cache[i];
if (item.k === k) {
item.v = v;
return;
}
}
this.cache.push({ k: k, v: v });
this.size += 1;
};
SimpleMap.prototype.get = function get(k) {
var this$1 = this;
var len = this.cache.length;
if (!len) {
return;
}
for (var i = 0; i < len; i++) {
var item = this$1.cache[i];
if (item.k === k) {
return item.v;
}
}
};
SimpleMap.prototype.has = function has(k) {
var this$1 = this;
var len = this.cache.length;
if (!len) {
return false;
}
for (var i = 0; i < len; i++) {
var item = this$1.cache[i];
if (item.k === k) {
return true;
}
}
return false;
};
SimpleMap.prototype['delete'] = function delete$1(k) {
var this$1 = this;
var len = this.cache.length;
for (var i = 0; i < len; i++) {
var item = this$1.cache[i];
if (item.k === k) {
this$1.cache.splice(i, 1);
this$1.size -= 1;
return true;
}
}
return false;
};
SimpleMap.prototype.clear = function clear() {
var this$1 = this;
var len = this.cache.length;
this.size = 0;
if (!len) {
return;
}
while (len) {
this$1.cache.pop();
len--;
}
};
var MapClass = 'Map' in global ? Map : SimpleMap;
function isAttrAnEvent(attr) {
return attr[0] === 'o' && attr[1] === 'n';
}
var extend = function () {
if ('assign' in Object) {
return function (source, from) {
if (!from) {
return source;
}
Object.assign(source, from);
return source;
};
} else {
return function (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);
}
var Current = {
current: null
};
var EMPTY_CHILDREN = [];
var EMPTY_OBJ = {};
function isNullOrUndef(o) {
return o === undefined || o === null;
}
function isInvalid(o) {
return isNullOrUndef(o) || o === true || o === false;
}
function isVNode(node) {
return !isNullOrUndef(node) && node.vtype === 2 /* Node */;
}
function isVText(node) {
return !isNullOrUndef(node) && node.vtype === 1 /* Text */;
}
function isComponent(instance) {
return !isInvalid(instance) && instance.isReactComponent === EMPTY_OBJ;
}
function isPortal(vtype, node) {
return (vtype & 32 /* Portal */) > 0;
}
function isComposite(node) {
return !isNullOrUndef(node) && node.vtype === 4 /* Composite */;
}
function isValidElement(node) {
return !isNullOrUndef(node) && node.vtype;
}
// tslint:disable-next-line:no-empty
function noop$1() {}
// typescript will compile the enum's value for us.
// eg.
// Composite = 1 << 2 => Composite = 4
var VType;
(function (VType) {
VType[VType["Text"] = 1] = "Text";
VType[VType["Node"] = 2] = "Node";
VType[VType["Composite"] = 4] = "Composite";
VType[VType["Stateless"] = 8] = "Stateless";
VType[VType["Void"] = 16] = "Void";
VType[VType["Portal"] = 32] = "Portal";
})(VType || (VType = {}));
var Ref = {
update: function update(lastVnode, nextVnode, domNode) {
var prevRef = lastVnode != null && lastVnode.ref;
var nextRef = nextVnode != null && nextVnode.ref;
if (prevRef !== nextRef) {
this.detach(lastVnode, prevRef, lastVnode.dom);
this.attach(nextVnode, nextRef, domNode);
}
},
attach: function attach(vnode, ref, domNode) {
var node = isComposite(vnode) ? vnode.component : domNode;
if (isFunction(ref)) {
ref(node);
} else if (isString(ref)) {
var inst = vnode._owner;
if (inst && isFunction(inst.render)) {
inst.refs[ref] = node;
}
}
},
detach: function detach(vnode, ref, domNode) {
var node = isComposite(vnode) ? vnode.component : domNode;
if (isFunction(ref)) {
ref(null);
} else if (isString(ref)) {
var inst = vnode._owner;
if (inst.refs[ref] === node && isFunction(inst.render)) {
delete inst.refs[ref];
}
}
}
};
var ONINPUT = 'oninput';
var ONPROPERTYCHANGE = 'onpropertychange';
var isiOS = isBrowser && !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
var delegatedEvents = new MapClass();
var unbubbleEvents = {
onmousemove: 1,
ontouchmove: 1,
onmouseleave: 1,
onmouseenter: 1,
onload: 1,
onunload: 1,
onscroll: 1,
onfocus: 1,
onblur: 1,
onrowexit: 1,
onbeforeunload: 1,
onstop: 1,
ondragdrop: 1,
ondragenter: 1,
ondragexit: 1,
ondraggesture: 1,
ondragover: 1,
oncontextmenu: 1,
onerror: 1,
onabort: 1,
oncanplay: 1,
oncanplaythrough: 1,
ondurationchange: 1,
onemptied: 1,
onended: 1,
onloadeddata: 1,
onloadedmetadata: 1,
onloadstart: 1,
onencrypted: 1,
onpause: 1,
onplay: 1,
onplaying: 1,
onprogress: 1,
onratechange: 1,
onseeking: 1,
onseeked: 1,
onstalled: 1,
onsuspend: 1,
ontimeupdate: 1,
onvolumechange: 1,
onwaiting: 1
};
unbubbleEvents[ONPROPERTYCHANGE] = 1;
var bindFocus = false;
/* istanbul ignore next */
if (isBrowser && navigator.userAgent.indexOf('MSIE 9') >= 0) {
var elements = [];
var values = [];
doc.addEventListener('selectionchange', function () {
var el = doc.activeElement;
if (detectCanUseOnInputNode(el)) {
var index = elements.indexOf(el);
var element = elements[index] || elements.push(el);
if (element.value !== values[index]) {
var ev = doc.createEvent('CustomEvent');
ev.initCustomEvent('input', true, true, undefined);
values[index] = element.value;
el.dispatchEvent(ev);
}
}
});
}
if (typeof Event !== 'undefined' && !Event.prototype.persist) {
// tslint:disable-next-line:no-empty
Event.prototype.persist = noop$1;
}
function attachEvent(domNode, eventName, handler) {
eventName = fixEvent(domNode, eventName);
/* istanbul ignore next */
if (eventName === ONPROPERTYCHANGE) {
processOnPropertyChangeEvent(domNode, handler);
return;
}
var delegatedRoots = delegatedEvents.get(eventName);
if (unbubbleEvents[eventName] === 1) {
if (!delegatedRoots) {
delegatedRoots = new MapClass();
}
var event = attachEventToNode(domNode, eventName, delegatedRoots);
delegatedEvents.set(eventName, delegatedRoots);
if (isFunction(handler)) {
delegatedRoots.set(domNode, {
eventHandler: handler,
event: event
});
}
} else {
if (!delegatedRoots) {
delegatedRoots = {
items: new MapClass()
};
delegatedRoots.event = attachEventToDocument(doc, eventName, delegatedRoots);
delegatedEvents.set(eventName, delegatedRoots);
}
if (isFunction(handler)) {
if (isiOS) {
domNode.onclick = noop$1;
}
delegatedRoots.items.set(domNode, handler);
}
}
}
function detachEvent(domNode, eventName, handler) {
eventName = fixEvent(domNode, eventName);
if (eventName === ONPROPERTYCHANGE) {
return;
}
var delegatedRoots = delegatedEvents.get(eventName);
if (unbubbleEvents[eventName] === 1 && delegatedRoots) {
var event = delegatedRoots.get(domNode);
if (event) {
domNode.removeEventListener(parseEventName(eventName), event.event, false);
/* istanbul ignore next */
var delegatedRootsSize = delegatedRoots.size;
if (delegatedRoots['delete'](domNode) && delegatedRootsSize === 0) {
delegatedEvents['delete'](eventName);
}
}
} else if (delegatedRoots && delegatedRoots.items) {
var items = delegatedRoots.items;
if (items['delete'](domNode) && items.size === 0) {
doc.removeEventListener(parseEventName(eventName), delegatedRoots.event, false);
delegatedEvents['delete'](eventName);
}
}
}
var propertyChangeActiveElement;
var propertyChangeActiveElementValue;
var propertyChangeActiveElementValueProp;
var propertyChangeActiveHandlers = {};
/* istanbul ignore next */
function propertyChangeHandler(event) {
if (event.propertyName !== 'value') {
return;
}
var target = event.target || event.srcElement;
var val = target.value;
if (val === propertyChangeActiveElementValue) {
return;
}
propertyChangeActiveElementValue = val;
var handler = propertyChangeActiveHandlers[target.name];
if (isFunction(handler)) {
handler.call(target, event);
}
}
/* istanbul ignore next */
function processOnPropertyChangeEvent(node, handler) {
propertyChangeActiveHandlers[node.name] = handler;
if (!bindFocus) {
// bindFocus = true
node.addEventListener('focusin', function () {
unbindOnPropertyChange();
bindOnPropertyChange(node);
}, false);
node.addEventListener('focusout', unbindOnPropertyChange, false);
}
}
/* istanbul ignore next */
function bindOnPropertyChange(node) {
propertyChangeActiveElement = node;
propertyChangeActiveElementValue = node.value;
propertyChangeActiveElementValueProp = Object.getOwnPropertyDescriptor(node.constructor.prototype, 'value');
Object.defineProperty(propertyChangeActiveElement, 'value', {
get: function get() {
return propertyChangeActiveElementValueProp.get.call(this);
},
set: function set(val) {
propertyChangeActiveElementValue = val;
propertyChangeActiveElementValueProp.set.call(this, val);
}
});
propertyChangeActiveElement.addEventListener('propertychange', propertyChangeHandler, false);
}
/* istanbul ignore next */
function unbindOnPropertyChange() {
if (!propertyChangeActiveElement) {
return;
}
delete propertyChangeActiveElement.value;
propertyChangeActiveElement.removeEventListener('propertychange', propertyChangeHandler, false);
propertyChangeActiveElement = null;
propertyChangeActiveElementValue = null;
propertyChangeActiveElementValueProp = null;
}
function detectCanUseOnInputNode(node) {
var nodeName = node.nodeName && node.nodeName.toLowerCase();
var type = node.type;
return nodeName === 'input' && /text|password/.test(type) || nodeName === 'textarea';
}
function fixEvent(node, eventName) {
if (eventName === 'onDoubleClick') {
eventName = 'ondblclick';
} else if (eventName === 'onTouchTap') {
eventName = 'onclick';
// tslint:disable-next-line:prefer-conditional-expression
} else if (eventName === 'onChange' && detectCanUseOnInputNode(node)) {
eventName = ONINPUT in window ? ONINPUT : ONPROPERTYCHANGE;
} else {
eventName = eventName.toLowerCase();
}
return eventName;
}
function parseEventName(name) {
return name.substr(2);
}
/* istanbul ignore next */
function stopPropagation() {
this.cancelBubble = true;
this.stopImmediatePropagation();
}
function dispatchEvent(event, target, items, count, eventData) {
var eventsToTrigger = items.get(target);
if (eventsToTrigger) {
count--;
eventData.currentTarget = target;
// for React synthetic event compatibility
Object.defineProperties(event, {
nativeEvent: {
value: event
}
});
eventsToTrigger(event);
if (event.cancelBubble) {
return;
}
}
if (count > 0) {
var parentDom = target.parentNode;
if (parentDom === null || event.type === 'click' && parentDom.nodeType === 1 && parentDom.disabled) {
return;
}
dispatchEvent(event, parentDom, items, count, eventData);
}
}
function attachEventToDocument(d, eventName, delegatedRoots) {
var eventHandler = function (event) {
var items = delegatedRoots.items;
var count = items.size;
if (count > 0) {
var eventData = {
currentTarget: event.target
};
/* istanbul ignore next */
try {
Object.defineProperties(event, {
currentTarget: {
configurable: true,
get: function get() {
return eventData.currentTarget;
}
},
stopPropagation: {
value: stopPropagation
}
});
} catch (error) {
// some browsers crashed
// see: https://stackoverflow.com/questions/44052813/why-cannot-redefine-property
}
dispatchEvent(event, event.target, delegatedRoots.items, count, eventData);
}
};
d.addEventListener(parseEventName(eventName), eventHandler, false);
return eventHandler;
}
function attachEventToNode(node, eventName, delegatedRoots) {
var eventHandler = function (event) {
var eventToTrigger = delegatedRoots.get(node);
if (eventToTrigger && eventToTrigger.eventHandler) {
var eventData = {
currentTarget: node
};
/* istanbul ignore next */
Object.defineProperties(event, {
currentTarget: {
configurable: true,
get: function get() {
return eventData.currentTarget;
}
}
});
eventToTrigger.eventHandler(event);
}
};
node.addEventListener(parseEventName(eventName), eventHandler, false);
return eventHandler;
}
var options = {
afterMount: noop$1,
afterUpdate: noop$1,
beforeUnmount: noop$1,
roots: [],
debug: false
};
function unmountChildren(children, parentDom) {
if (isArray(children)) {
for (var i = 0, len = children.length; i < len; i++) {
unmount(children[i], parentDom);
}
} else {
unmount(children, parentDom);
}
}
function unmount(vnode, parentDom) {
if (isInvalid(vnode)) {
return;
}
var vtype = vnode.vtype;
// Bitwise operators for better performance
// see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
var dom = vnode.dom;
if ((vtype & (4 /* Composite */ | 8 /* Stateless */)) > 0) {
options.beforeUnmount(vnode);
vnode.destroy();
} else if ((vtype & 2 /* Node */) > 0) {
var props = vnode.props;
var children = vnode.children;
var ref = vnode.ref;
unmountChildren(children);
for (var propName in props) {
if (isAttrAnEvent(propName)) {
detachEvent(dom, propName, props[propName]);
}
}
if (ref !== null) {
Ref.detach(vnode, ref, dom);
}
} else if (vtype & 32 /* Portal */) {
unmountChildren(vnode.children, vnode.type);
}
if (!isNullOrUndef(parentDom) && !isNullOrUndef(dom)) {
parentDom.removeChild(dom);
}
// vnode.dom = null
}
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: {
'ev:event': NS.ev,
'xlink:actuate': NS.xlink,
'xlink:arcrole': NS.xlink,
'xlink:href': NS.xlink,
'xlink:role': NS.xlink,
'xlink:show': NS.xlink,
'xlink:title': NS.xlink,
'xlink:type': NS.xlink,
'xml:base': NS.xml,
'xml:id': NS.xml,
'xml:lang': NS.xml,
'xml:space': NS.xml
},
DOMAttributeNames: {}
};
Object.keys(ATTRS).forEach(function (key) {
SVGPropertyConfig.Properties[key] = 0;
if (ATTRS[key]) {
SVGPropertyConfig.DOMAttributeNames[key] = ATTRS[key];
}
});
/* tslint:disable: no-empty*/
function patch(lastVnode, nextVnode, parentNode, context, isSvg) {
var lastDom = lastVnode.dom;
var newDom;
if (isSameVNode(lastVnode, nextVnode)) {
var vtype = nextVnode.vtype;
if (vtype & 2 /* Node */) {
isSvg = isNullOrUndef(isSvg) ? lastVnode.isSvg : isSvg;
if (isSvg) {
nextVnode.isSvg = isSvg;
}
patchProps(lastDom, nextVnode.props, lastVnode.props, lastVnode, isSvg);
patchChildren(lastDom, lastVnode.children, nextVnode.children, context, isSvg);
if (nextVnode.ref !== null) {
Ref.update(lastVnode, nextVnode, lastDom);
}
newDom = lastDom;
} else if ((vtype & (4 /* Composite */ | 8 /* Stateless */)) > 0) {
newDom = nextVnode.update(lastVnode, nextVnode, context);
options.afterUpdate(nextVnode);
} else if (vtype & 1 /* Text */) {
return patchVText(lastVnode, nextVnode);
} else if (vtype & 32 /* Portal */) {
patchChildren(lastVnode.type, lastVnode.children, nextVnode.children, context, isSvg);
}
// @TODO: test case
nextVnode.dom = newDom || lastDom;
} else if (isArray(lastVnode) && isArray(nextVnode)) {
patchArrayChildren(lastDom, lastVnode, nextVnode, context, false);
} else {
unmount(lastVnode);
newDom = createElement(nextVnode, isSvg, context);
if (nextVnode !== null) {
nextVnode.dom = newDom;
}
if (parentNode !== null) {
parentNode.replaceChild(newDom, lastDom);
}
}
return newDom;
}
function patchArrayChildren(parentDom, lastChildren, nextChildren, context, isSvg) {
var lastLength = lastChildren.length;
var nextLength = nextChildren.length;
if (lastLength === 0) {
if (nextLength > 0) {
for (var i = 0; i < nextLength; i++) {
mountChild(nextChildren[i], parentDom, context, isSvg);
}
}
} else if (nextLength === 0) {
unmountChildren(lastChildren);
parentDom.textContent = '';
} else {
if (isKeyed(lastChildren, nextChildren)) {
patchKeyedChildren(lastChildren, nextChildren, parentDom, context, isSvg, lastLength, nextLength);
} else {
patchNonKeyedChildren(parentDom, lastChildren, nextChildren, context, isSvg, lastLength, nextLength);
}
}
}
function patchChildren(parentDom, lastChildren, nextChildren, context, isSvg) {
// @TODO: is a better way to compatible with react-router?
// if (lastChildren === nextChildren) {
// return
// }
var lastChildrenIsArray = isArray(lastChildren);
var nextChildrenIsArray = isArray(nextChildren);
if (lastChildrenIsArray && nextChildrenIsArray) {
patchArrayChildren(parentDom, lastChildren, nextChildren, context, isSvg);
} else if (!lastChildrenIsArray && !nextChildrenIsArray) {
patch(lastChildren, nextChildren, parentDom, context, isSvg);
} else if (lastChildrenIsArray && !nextChildrenIsArray) {
patchArrayChildren(parentDom, lastChildren, [nextChildren], context, isSvg);
} else if (!lastChildrenIsArray && nextChildrenIsArray) {
patchArrayChildren(parentDom, [lastChildren], nextChildren, context, isSvg);
}
}
function patchNonKeyedChildren(parentDom, lastChildren, nextChildren, context, isSvg, lastLength, nextLength) {
var minLength = Math.min(lastLength, nextLength);
var i = 0;
while (i < minLength) {
patch(lastChildren[i], nextChildren[i], parentDom, context, isSvg);
i++;
}
if (lastLength < nextLength) {
for (i = minLength; i < nextLength; i++) {
if (parentDom !== null) {
parentDom.appendChild(createElement(nextChildren[i], isSvg, context));
}
}
} else if (lastLength > nextLength) {
for (i = minLength; i < lastLength; i++) {
unmount(lastChildren[i], parentDom);
}
}
}
/**
*
* Virtual DOM patching algorithm based on ivi by
* Boris Kaul (@localvoid)
* Licensed under the MIT License
* https://github.com/ivijs/ivi/blob/master/LICENSE
*
*/
function patchKeyedChildren(a, b, dom, context, isSvg, aLength, bLength) {
var aEnd = aLength - 1;
var bEnd = bLength - 1;
var aStart = 0;
var bStart = 0;
var i;
var j;
var aNode;
var bNode;
var nextNode;
var nextPos;
var node;
var aStartNode = a[aStart];
var bStartNode = b[bStart];
var aEndNode = a[aEnd];
var bEndNode = b[bEnd];
// Step 1
// tslint:disable-next-line
outer: {
// Sync nodes with the same key at the beginning.
while (aStartNode.key === bStartNode.key) {
patch(aStartNode, bStartNode, dom, context, isSvg);
aStart++;
bStart++;
if (aStart > aEnd || bStart > bEnd) {
break outer;
}
aStartNode = a[aStart];
bStartNode = b[bStart];
}
// Sync nodes with the same key at the end.
while (aEndNode.key === bEndNode.key) {
patch(aEndNode, bEndNode, dom, context, isSvg);
aEnd--;
bEnd--;
if (aStart > aEnd || bStart > bEnd) {
break outer;
}
aEndNode = a[aEnd];
bEndNode = b[bEnd];
}
}
if (aStart > aEnd) {
if (bStart <= bEnd) {
nextPos = bEnd + 1;
nextNode = nextPos < bLength ? b[nextPos].dom : null;
while (bStart <= bEnd) {
node = b[bStart];
bStart++;
attachNewNode(dom, createElement(node, isSvg, context), nextNode);
}
}
} else if (bStart > bEnd) {
while (aStart <= aEnd) {
unmount(a[aStart++], dom);
}
} else {
var aLeft = aEnd - aStart + 1;
var bLeft = bEnd - bStart + 1;
var sources = new Array(bLeft);
// Mark all nodes as inserted.
for (i = 0; i < bLeft; i++) {
sources[i] = -1;
}
var moved = false;
var pos = 0;
var patched = 0;
// When sizes are small, just loop them through
if (bLeft <= 4 || aLeft * bLeft <= 16) {
for (i = aStart; i <= aEnd; i++) {
aNode = a[i];
if (patched < bLeft) {
for (j = bStart; j <= bEnd; j++) {
bNode = b[j];
if (aNode.key === bNode.key) {
sources[j - bStart] = i;
if (pos > j) {
moved = true;
} else {
pos = j;
}
patch(aNode, bNode, dom, context, isSvg);
patched++;
a[i] = null;
break;
}
}
}
}
} else {
var keyIndex = new MapClass();
for (i = bStart; i <= bEnd; i++) {
keyIndex.set(b[i].key, i);
}
for (i = aStart; i <= aEnd; i++) {
aNode = a[i];
if (patched < bLeft) {
j = keyIndex.get(aNode.key);
if (j !== undefined) {
bNode = b[j];
sources[j - bStart] = i;
if (pos > j) {
moved = true;
} else {
pos = j;
}
patch(aNode, bNode, dom, context, isSvg);
patched++;
a[i] = null;
}
}
}
}
if (aLeft === aLength && patched === 0) {
unmountChildren(a);
dom.textContent = '';
while (bStart < bLeft) {
node = b[bStart];
bStart++;
attachNewNode(dom, createElement(node, isSvg, context), null);
}
} else {
i = aLeft - patched;
while (i > 0) {
aNode = a[aStart++];
if (aNode !== null) {
unmount(aNode, dom);
i--;
}
}
if (moved) {
var seq = lis(sources);
j = seq.length - 1;
for (i = bLeft - 1; i >= 0; i--) {
if (sources[i] === -1) {
pos = i + bStart;
node = b[pos];
nextPos = pos + 1;
attachNewNode(dom, createElement(node, isSvg, context), nextPos < bLength ? b[nextPos].dom : null);
} else {
if (j < 0 || i !== seq[j]) {
pos = i + bStart;
node = b[pos];
nextPos = pos + 1;
attachNewNode(dom, node.dom, nextPos < bLength ? b[nextPos].dom : null);
} else {
j--;
}
}
}
} else if (patched !== bLeft) {
for (i = bLeft - 1; i >= 0; i--) {
if (sources[i] === -1) {
pos = i + bStart;
node = b[pos];
nextPos = pos + 1;
attachNewNode(dom, createElement(node, isSvg, context), nextPos < bLength ? b[nextPos].dom : null);
}
}
}
}
}
}
function attachNewNode(parentDom, newNode, nextNode) {
if (isNullOrUndef(nextNode)) {
parentDom.appendChild(newNode);
} else {
parentDom.insertBefore(newNode, nextNode);
}
}
/**
* Slightly modified Longest Increased Subsequence algorithm, it ignores items that have -1 value, they're representing
* new items.
*
* http://en.wikipedia.org/wiki/Longest_increasing_subsequence
*
* @param a Array of numbers.
* @returns Longest increasing subsequence.
*/
function lis(a) {
var p = a.slice();
var result = [];
result.push(0);
var u;
var v;
for (var i = 0, il = a.length; i < il; ++i) {
if (a[i] === -1) {
continue;
}
var j = result[result.length - 1];
if (a[j] < a[i]) {
p[i] = j;
result.push(i);
continue;
}
u = 0;
v = result.length - 1;
while (u < v) {
var c = (u + v) / 2 | 0;
if (a[result[c]] < a[i]) {
u = c + 1;
} else {
v = c;
}
}
if (a[i] < a[result[u]]) {
if (u > 0) {
p[i] = result[u - 1];
}
result[u] = i;
}
}
u = result.length;
v = result[u - 1];
while (u-- > 0) {
result[u] = v;
v = p[v];
}
return result;
}
function isKeyed(lastChildren, nextChildren) {
return nextChildren.length > 0 && !isNullOrUndef(nextChildren[0]) && !isNullOrUndef(nextChildren[0].key) && lastChildren.length > 0 && !isNullOrUndef(lastChildren[0]) && !isNullOrUndef(lastChildren[0].key);
}
function isSameVNode(a, b) {
if (isInvalid(a) || isInvalid(b) || isArray(a) || isArray(b)) {
return false;
}
return a.type === b.type && a.vtype === b.vtype && a.key === b.key;
}
function patchVText(lastVNode, nextVNode) {
var dom = lastVNode.dom;
if (dom === null) {
return;
}
var nextText = nextVNode.text;
nextVNode.dom = dom;
if (lastVNode.text !== nextText) {
dom.nodeValue = nextText;
}
return dom;
}
var skipProps = {
children: 1,
key: 1,
ref: 1,
owner: 1
};
var IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i;
function setStyle(domStyle, style, value) {
if (isNullOrUndef(value) || isNumber(value) && isNaN(value)) {
domStyle[style] = '';
return;
}
if (style === 'float') {
domStyle['cssFloat'] = value;
domStyle['styleFloat'] = value;
return;
}
domStyle[style] = !isNumber(value) || IS_NON_DIMENSIONAL.test(style) ? value : value + 'px';
}
function patchEvent(eventName, lastEvent, nextEvent, domNode) {
if (lastEvent !== nextEvent) {
if (isFunction(lastEvent)) {
detachEvent(domNode, eventName, lastEvent);
}
attachEvent(domNode, eventName, nextEvent);
}
}
function patchStyle(lastAttrValue, nextAttrValue, dom) {
var domStyle = dom.style;
var style;
var value;
if (isString(nextAttrValue)) {
domStyle.cssText = nextAttrValue;
return;
}
if (!isNullOrUndef(lastAttrValue) && !isString(lastAttrValue)) {
for (style in nextAttrValue) {
value = nextAttrValue[style];
if (value !== lastAttrValue[style]) {
setStyle(domStyle, style, value);
}
}
for (style in lastAttrValue) {
if (isNullOrUndef(nextAttrValue[style])) {
domStyle[style] = '';
}
}
} else {
for (style in nextAttrValue) {
value = nextAttrValue[style];
setStyle(domStyle, style, value);
}
}
}
function patchProp(domNode, prop, lastValue, nextValue, lastVnode, isSvg) {
// fix the value update for textarea/input
if (lastValue !== nextValue || prop === 'value') {
if (prop === 'className') {
prop = 'class';
}
if (skipProps[prop] === 1) {
return;
} else if (prop === 'class' && !isSvg) {
domNode.className = nextValue;
} else if (prop === 'dangerouslySetInnerHTML') {
var lastHtml = lastValue && lastValue.__html;
var nextHtml = nextValue && nextValue.__html;
if (lastHtml !== nextHtml) {
if (!isNullOrUndef(nextHtml)) {
if (isValidElement(lastVnode) && lastVnode.children !== EMPTY_CHILDREN) {
unmountChildren(lastVnode.children);
lastVnode.children = [];
}
domNode.innerHTML = nextHtml;
}
}
} else if (isAttrAnEvent(prop)) {
patchEvent(prop, lastValue, nextValue, domNode);
} else if (prop === 'style') {
patchStyle(lastValue, nextValue, domNode);
} else if (prop !== 'list' && prop !== 'type' && !isSvg && prop in domNode) {
setProperty(domNode, prop, nextValue == null ? '' : nextValue);
if (nextValue == null || nextValue === false) {
domNode.removeAttribute(prop);
}
} else if (isNullOrUndef(nextValue) || nextValue === false) {
domNode.removeAttribute(prop);
} else {
var namespace = SVGPropertyConfig.DOMAttributeNamespaces[prop];
if (isSvg && namespace) {
if (nextValue) {
domNode.setAttributeNS(namespace, prop, nextValue);
} else {
var colonPosition = prop.indexOf(':');
var localName = colonPosition > -1 ? prop.substr(colonPosition + 1) : prop;
domNode.removeAttributeNS(namespace, localName);
}
} else {
if (!isFunction(nextValue)) {
domNode.setAttribute(prop, nextValue);
}
// WARNING: Non-event attributes with function values:
// https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html#changes-in-detail
}
}
}
}
function setProperty(node, name, value) {
try {
node[name] = value;
} catch (e) {}
}
function patchProps(domNode, nextProps, previousProps, lastVnode, isSvg) {
for (var propName in previousProps) {
var value = previousProps[propName];
if (isNullOrUndef(nextProps[propName]) && !isNullOrUndef(value)) {
if (isAttrAnEvent(propName)) {
detachEvent(domNode, propName, value);
} else if (propName === 'dangerouslySetInnerHTML') {
domNode.textContent = '';
} else if (propName === 'className') {
domNode.removeAttribute('class');
} else {
domNode.removeAttribute(propName);
}
}
}
for (var propName$1 in nextProps) {
patchProp(domNode, propName$1, previousProps[propName$1], nextProps[propName$1], lastVnode, isSvg);
}
}
var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
function createElement(vnode, isSvg, parentContext, parentComponent) {
var domNode;
if (isValidElement(vnode)) {
var vtype = vnode.vtype;
if (vtype & (4 /* Composite */ | 8 /* Stateless */)) {
domNode = vnode.init(parentContext, parentComponent);
options.afterMount(vnode);
} else if (vtype & 1 /* Text */) {
domNode = doc.createTextNode(vnode.text);
vnode.dom = domNode;
} else if (vtype & 2 /* Node */) {
domNode = mountVNode$1(vnode, isSvg, parentContext, parentComponent);
} else if (vtype & 16 /* Void */) {
domNode = vnode.dom = doc.createTextNode('');
} else if (isPortal(vtype, vnode)) {
vnode.type.appendChild(createElement(vnode.children, isSvg, parentContext, parentComponent));
domNode = doc.createTextNode('');
}
} else if (isString(vnode) || isNumber(vnode)) {
domNode = doc.createTextNode(vnode);
} else if (isNullOrUndef(vnode) || isBoolean(vnode)) {
domNode = doc.createTextNode('');
} else if (isArray(vnode)) {
domNode = doc.createDocumentFragment();
vnode.forEach(function (child) {
if (!isInvalid(child)) {
var childNode = createElement(child, isSvg, parentContext, parentComponent);
if (childNode) {
domNode.appendChild(childNode);
}
}
});
} else {
throw new Error('Unsupported VNode.');
}
return domNode;
}
function mountVNode$1(vnode, isSvg, parentContext, parentComponent) {
if (vnode.isSvg) {
isSvg = true;
} else if (vnode.type === 'svg') {
isSvg = true;
/* istanbul ignore next */
} else if (!isSupportSVG) {
isSvg = false;
}
if (isSvg) {
vnode.namespace = SVG_NAMESPACE;
vnode.isSvg = isSvg;
}
var domNode = !isSvg ? doc.createElement(vnode.type) : doc.createElementNS(vnode.namespace, vnode.type);
setProps(domNode, vnode, isSvg);
if (vnode.type === 'foreignObject') {
isSvg = false;
}
var children = vnode.children;
if (isArray(children)) {
for (var i = 0, len = children.length; i < len; i++) {
mountChild(children[i], domNode, parentContext, isSvg, parentComponent);
}
} else {
mountChild(children, domNode, parentContext, isSvg, parentComponent);
}
vnode.dom = domNode;
if (vnode.ref !== null) {
Ref.attach(vnode, vnode.ref, domNode);
}
return domNode;
}
function mountChild(child, domNode, parentContext, isSvg, parentComponent) {
child.parentContext = parentContext || EMPTY_OBJ;
var childNode = createElement(child, isSvg, parentContext, parentComponent);
if (childNode !== null) {
domNode.appendChild(childNode);
}
}
function setProps(domNode, vnode, isSvg) {
var props = vnode.props;
for (var p in props) {
patchProp(domNode, p, null, props[p], null, isSvg);
}
}
function createVText(text) {
return {
text: text,
vtype: 1 /* Text */
, dom: null
};
}
function createVoid() {
return {
dom: null,
vtype: 16 /* Void */
};
}
// import { extend, isFunction, isNumber, isString } from 'nerv-utils'
var readyComponents = [];
function errorCatcher(fn, component) {
try {
return fn();
} catch (error) {
errorHandler(component, error);
}
}
function errorHandler(component, error) {
var boundary;
while (true) {
if (isFunction(component.componentDidCatch)) {
boundary = component;
break;
} else if (component._parentComponent) {
component = component._parentComponent;
} else {
break;
}
}
if (boundary) {
var _disable = boundary._disable;
boundary._disable = false;
boundary.componentDidCatch(error);
boundary._disable = _disable;
} else {
throw error;
}
}
function ensureVirtualNode(rendered) {
if (isNumber(rendered) || isString(rendered)) {
return createVText(rendered);
} else if (isInvalid(rendered)) {
return createVoid();
}
return rendered;
}
function mountVNode(vnode, parentContext, parentComponent) {
return createElement(vnode, false, parentContext, parentComponent);
}
function mountComponent(vnode, parentContext, parentComponent) {
var ref = vnode.ref;
vnode.component = new vnode.type(vnode.props, parentContext);
var component = vnode.component;
component.vnode = vnode;
if (isComponent(parentComponent)) {
component._parentComponent = parentComponent;
}
if (isFunction(component.componentWillMount)) {
errorCatcher(function () {
component.componentWillMount();
}, component);
component.state = component.getState();
component.clearCallBacks();
}
component._dirty = false;
var rendered = renderComponent(component);
rendered.parentVNode = vnode;
component._rendered = rendered;
if (isFunction(component.componentDidMount)) {
readyComponents.push(component);
}
if (!isNullOrUndef(ref)) {
Ref.attach(vnode, ref, vnode.dom);
}
var dom = vnode.dom = mountVNode(rendered, getChildContext(component, parentContext), component);
component._disable = false;
return dom;
}
function mountStatelessComponent(vnode, parentContext) {
var rendered = vnode.type(vnode.props, parentContext);
vnode._rendered = ensureVirtualNode(rendered);
vnode._rendered.parentVNode = vnode;
return vnode.dom = mountVNode(vnode._rendered, parentContext);
}
function getChildContext(component, context) {
if (context === void 0) context = EMPTY_OBJ;
if (component.getChildContext) {
return extend(clone(context), component.getChildContext());
}
return clone(context);
}
function renderComponent(component) {
Current.current = component;
var rendered;
errorCatcher(function () {
rendered = component.render();
}, component);
rendered = ensureVirtualNode(rendered);
Current.current = null;
return rendered;
}
function flushMount() {
if (!readyComponents.length) {
return;
}
// @TODO: perf
var queue = readyComponents.slice(0);
readyComponents.length = 0;
queue.forEach(function (item) {
if (isFunction(item)) {
item();
} else if (item.componentDidMount) {
errorCatcher(function () {
item.componentDidMount();
}, item);
}
});
}
function reRenderComponent(prev, current) {
var component = current.component = prev.component;
var nextProps = curren