123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415 |
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (factory((global.Inferno = global.Inferno || {})));
- }(this, (function (exports) { 'use strict';
- var NO_OP = '$NO_OP';
- var ERROR_MSG = 'a runtime error occured! Use Inferno in development environment to find the error.';
- // This should be boolean and not reference to window.document
- var isBrowser = !!(typeof window !== 'undefined' && window.document);
- // this is MUCH faster than .constructor === Array and instanceof Array
- // in Node 7 and the later versions of V8, slower in older versions though
- var isArray = Array.isArray;
- function isStringOrNumber(o) {
- var type = typeof o;
- return type === 'string' || type === 'number';
- }
- function isNullOrUndef(o) {
- return isUndefined(o) || isNull(o);
- }
- function isInvalid(o) {
- return isNull(o) || o === false || isTrue(o) || isUndefined(o);
- }
- function isFunction(o) {
- return typeof o === 'function';
- }
- function isString(o) {
- return typeof o === 'string';
- }
- function isNumber(o) {
- return typeof o === 'number';
- }
- function isNull(o) {
- return o === null;
- }
- function isTrue(o) {
- return o === true;
- }
- function isUndefined(o) {
- return o === void 0;
- }
- function isDefined(o) {
- return o !== void 0;
- }
- function isObject(o) {
- return typeof o === 'object';
- }
- function throwError(message) {
- if (!message) {
- message = ERROR_MSG;
- }
- throw new Error(("Inferno Error: " + message));
- }
- function warning(message) {
- // tslint:disable-next-line:no-console
- console.error(message);
- }
- function combineFrom(first, second) {
- var out = {};
- if (first) {
- for (var key in first) {
- out[key] = first[key];
- }
- }
- if (second) {
- for (var key$1 in second) {
- out[key$1] = second[key$1];
- }
- }
- return out;
- }
- function getTagName(input) {
- var tagName;
- if (isArray(input)) {
- var arrayText = input.length > 3 ? input.slice(0, 3).toString() + ',...' : input.toString();
- tagName = 'Array(' + arrayText + ')';
- }
- else if (isStringOrNumber(input)) {
- tagName = 'Text(' + input + ')';
- }
- else if (isInvalid(input)) {
- tagName = 'InvalidVNode(' + input + ')';
- }
- else {
- var flags = input.flags;
- if (flags & 481 /* Element */) {
- tagName = "<" + (input.type) + (input.className ? ' class="' + input.className + '"' : '') + ">";
- }
- else if (flags & 16 /* Text */) {
- tagName = "Text(" + (input.children) + ")";
- }
- else if (flags & 1024 /* Portal */) {
- tagName = "Portal*";
- }
- else {
- var type = input.type;
- // Fallback for IE
- var componentName = type.name || type.displayName || type.constructor.name || (type.toString().match(/^function\s*([^\s(]+)/) || [])[1];
- tagName = "<" + componentName + " />";
- }
- }
- return '>> ' + tagName + '\n';
- }
- function DEV_ValidateKeys(vNodeTree, vNode, forceKeyed) {
- var foundKeys = [];
- for (var i = 0, len = vNodeTree.length; i < len; i++) {
- var childNode = vNodeTree[i];
- if (isArray(childNode)) {
- return 'Encountered ARRAY in mount, array must be flattened, or normalize used. Location: \n' + getTagName(childNode);
- }
- if (isInvalid(childNode)) {
- if (forceKeyed) {
- return 'Encountered invalid node when preparing to keyed algorithm. Location: \n' + getTagName(childNode);
- }
- else if (foundKeys.length !== 0) {
- return 'Encountered invalid node with mixed keys. Location: \n' + getTagName(childNode);
- }
- continue;
- }
- if (typeof childNode === 'object') {
- childNode.isValidated = true;
- }
- var key = childNode.key;
- if (!isNullOrUndef(key) && !isStringOrNumber(key)) {
- return 'Encountered child vNode where key property is not string or number. Location: \n' + getTagName(childNode);
- }
- var children = childNode.children;
- var childFlags = childNode.childFlags;
- if (!isInvalid(children)) {
- var val = (void 0);
- if (childFlags & 12 /* MultipleChildren */) {
- val = DEV_ValidateKeys(children, childNode, childNode.childFlags & 8 /* HasKeyedChildren */);
- }
- else if (childFlags === 2 /* HasVNodeChildren */) {
- val = DEV_ValidateKeys([children], childNode, childNode.childFlags & 8 /* HasKeyedChildren */);
- }
- if (val) {
- val += getTagName(childNode);
- return val;
- }
- }
- if (forceKeyed && isNullOrUndef(key)) {
- return ('Encountered child without key during keyed algorithm. If this error points to Array make sure children is flat list. Location: \n' +
- getTagName(childNode));
- }
- else if (!forceKeyed && isNullOrUndef(key)) {
- if (foundKeys.length !== 0) {
- return 'Encountered children with key missing. Location: \n' + getTagName(childNode);
- }
- continue;
- }
- if (foundKeys.indexOf(key) > -1) {
- return 'Encountered two children with same key: {' + key + '}. Location: \n' + getTagName(childNode);
- }
- foundKeys.push(key);
- }
- }
- function validateVNodeElementChildren(vNode) {
- {
- if (vNode.childFlags & 1 /* HasInvalidChildren */) {
- return;
- }
- if (vNode.flags & 64 /* InputElement */) {
- throwError("input elements can't have children.");
- }
- if (vNode.flags & 128 /* TextareaElement */) {
- throwError("textarea elements can't have children.");
- }
- if (vNode.flags & 481 /* Element */) {
- var voidTypes = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
- var tag = vNode.type.toLowerCase();
- if (tag === 'media') {
- throwError("media elements can't have children.");
- }
- var idx = voidTypes.indexOf(tag);
- if (idx !== -1) {
- throwError(((voidTypes[idx]) + " elements can't have children."));
- }
- }
- }
- }
- function validateKeys(vNode) {
- {
- // Checks if there is any key missing or duplicate keys
- if (vNode.isValidated === false && vNode.children && vNode.flags & 481 /* Element */) {
- var error = DEV_ValidateKeys(Array.isArray(vNode.children) ? vNode.children : [vNode.children], vNode, (vNode.childFlags & 8 /* HasKeyedChildren */) > 0);
- if (error) {
- throwError(error + getTagName(vNode));
- }
- }
- vNode.isValidated = true;
- }
- }
- var keyPrefix = '$';
- function getVNode(childFlags, children, className, flags, key, props, ref, type) {
- return {
- childFlags: childFlags,
- children: children,
- className: className,
- dom: null,
- flags: flags,
- isValidated: false,
- key: key === void 0 ? null : key,
- parentVNode: null,
- props: props === void 0 ? null : props,
- ref: ref === void 0 ? null : ref,
- type: type
- };
- }
- function createVNode(flags, type, className, children, childFlags, props, key, ref) {
- {
- if (flags & 14 /* Component */) {
- throwError('Creating Component vNodes using createVNode is not allowed. Use Inferno.createComponentVNode method.');
- }
- }
- var childFlag = childFlags === void 0 ? 1 /* HasInvalidChildren */ : childFlags;
- var vNode = getVNode(childFlag, children, className, flags, key, props, ref, type);
- var optsVNode = options.createVNode;
- if (typeof optsVNode === 'function') {
- optsVNode(vNode);
- }
- if (childFlag === 0 /* UnknownChildren */) {
- normalizeChildren(vNode, vNode.children);
- }
- {
- validateVNodeElementChildren(vNode);
- }
- return vNode;
- }
- function createComponentVNode(flags, type, props, key, ref) {
- {
- if (flags & 1 /* HtmlElement */) {
- throwError('Creating element vNodes using createComponentVNode is not allowed. Use Inferno.createVNode method.');
- }
- }
- if ((flags & 2 /* ComponentUnknown */) > 0) {
- flags = isDefined(type.prototype) && isFunction(type.prototype.render) ? 4 /* ComponentClass */ : 8 /* ComponentFunction */;
- }
- // set default props
- var defaultProps = type.defaultProps;
- if (!isNullOrUndef(defaultProps)) {
- if (!props) {
- props = {}; // Props can be referenced and modified at application level so always create new object
- }
- for (var prop in defaultProps) {
- if (isUndefined(props[prop])) {
- props[prop] = defaultProps[prop];
- }
- }
- }
- if ((flags & 8 /* ComponentFunction */) > 0) {
- var defaultHooks = type.defaultHooks;
- if (!isNullOrUndef(defaultHooks)) {
- if (!ref) {
- // As ref cannot be referenced from application level, we can use the same refs object
- ref = defaultHooks;
- }
- else {
- for (var prop$1 in defaultHooks) {
- if (isUndefined(ref[prop$1])) {
- ref[prop$1] = defaultHooks[prop$1];
- }
- }
- }
- }
- }
- var vNode = getVNode(1 /* HasInvalidChildren */, null, null, flags, key, props, ref, type);
- var optsVNode = options.createVNode;
- if (isFunction(optsVNode)) {
- optsVNode(vNode);
- }
- return vNode;
- }
- function createTextVNode(text, key) {
- return getVNode(1 /* HasInvalidChildren */, isNullOrUndef(text) ? '' : text, null, 16 /* Text */, key, null, null, null);
- }
- function normalizeProps(vNode) {
- var props = vNode.props;
- if (props) {
- if (vNode.flags & 481 /* Element */) {
- if (isDefined(props.children) && isNullOrUndef(vNode.children)) {
- normalizeChildren(vNode, props.children);
- }
- if (isDefined(props.className)) {
- vNode.className = props.className || null;
- props.className = undefined;
- }
- }
- if (isDefined(props.key)) {
- vNode.key = props.key;
- props.key = undefined;
- }
- if (isDefined(props.ref)) {
- vNode.ref = props.ref;
- props.ref = undefined;
- }
- }
- return vNode;
- }
- function directClone(vNodeToClone) {
- var newVNode;
- var flags = vNodeToClone.flags;
- if (flags & 14 /* Component */) {
- var props;
- var propsToClone = vNodeToClone.props;
- if (!isNull(propsToClone)) {
- props = {};
- for (var key in propsToClone) {
- props[key] = propsToClone[key];
- }
- }
- newVNode = createComponentVNode(flags, vNodeToClone.type, props, vNodeToClone.key, vNodeToClone.ref);
- }
- else if (flags & 481 /* Element */) {
- var children = vNodeToClone.children;
- newVNode = createVNode(flags, vNodeToClone.type, vNodeToClone.className, children, 0 /* UnknownChildren */, vNodeToClone.props, vNodeToClone.key, vNodeToClone.ref);
- }
- else if (flags & 16 /* Text */) {
- newVNode = createTextVNode(vNodeToClone.children, vNodeToClone.key);
- }
- else if (flags & 1024 /* Portal */) {
- newVNode = vNodeToClone;
- }
- return newVNode;
- }
- function createVoidVNode() {
- return createTextVNode('', null);
- }
- function _normalizeVNodes(nodes, result, index, currentKey) {
- for (var len = nodes.length; index < len; index++) {
- var n = nodes[index];
- if (!isInvalid(n)) {
- var newKey = currentKey + keyPrefix + index;
- if (isArray(n)) {
- _normalizeVNodes(n, result, 0, newKey);
- }
- else {
- if (isStringOrNumber(n)) {
- n = createTextVNode(n, newKey);
- }
- else {
- var oldKey = n.key;
- var isPrefixedKey = isString(oldKey) && oldKey[0] === keyPrefix;
- if (!isNull(n.dom) || isPrefixedKey) {
- n = directClone(n);
- }
- if (isNull(oldKey) || isPrefixedKey) {
- n.key = newKey;
- }
- else {
- n.key = currentKey + oldKey;
- }
- }
- result.push(n);
- }
- }
- }
- }
- function getFlagsForElementVnode(type) {
- if (type === 'svg') {
- return 32 /* SvgElement */;
- }
- if (type === 'input') {
- return 64 /* InputElement */;
- }
- if (type === 'select') {
- return 256 /* SelectElement */;
- }
- if (type === 'textarea') {
- return 128 /* TextareaElement */;
- }
- return 1 /* HtmlElement */;
- }
- function normalizeChildren(vNode, children) {
- var newChildren;
- var newChildFlags;
- // Don't change children to match strict equal (===) true in patching
- if (isInvalid(children)) {
- newChildFlags = 1 /* HasInvalidChildren */;
- newChildren = children;
- }
- else if (isString(children)) {
- newChildFlags = 2 /* HasVNodeChildren */;
- newChildren = createTextVNode(children);
- }
- else if (isNumber(children)) {
- newChildFlags = 2 /* HasVNodeChildren */;
- newChildren = createTextVNode(children + '');
- }
- else if (isArray(children)) {
- var len = children.length;
- if (len === 0) {
- newChildren = null;
- newChildFlags = 1 /* HasInvalidChildren */;
- }
- else {
- // we assign $ which basically means we've flagged this array for future note
- // if it comes back again, we need to clone it, as people are using it
- // in an immutable way
- // tslint:disable-next-line
- if (Object.isFrozen(children) || children['$'] === true) {
- children = children.slice();
- }
- newChildFlags = 8 /* HasKeyedChildren */;
- for (var i = 0; i < len; i++) {
- var n = children[i];
- if (isInvalid(n) || isArray(n)) {
- newChildren = newChildren || children.slice(0, i);
- _normalizeVNodes(children, newChildren, i, '');
- break;
- }
- else if (isStringOrNumber(n)) {
- newChildren = newChildren || children.slice(0, i);
- newChildren.push(createTextVNode(n, keyPrefix + i));
- }
- else {
- var key = n.key;
- var isNullDom = isNull(n.dom);
- var isNullKey = isNull(key);
- var isPrefixed = !isNullKey && key[0] === keyPrefix;
- if (!isNullDom || isNullKey || isPrefixed) {
- newChildren = newChildren || children.slice(0, i);
- if (!isNullDom || isPrefixed) {
- n = directClone(n);
- }
- if (isNullKey || isPrefixed) {
- n.key = keyPrefix + i;
- }
- newChildren.push(n);
- }
- else if (newChildren) {
- newChildren.push(n);
- }
- }
- }
- newChildren = newChildren || children;
- newChildren.$ = true;
- }
- }
- else {
- newChildren = children;
- if (!isNull(children.dom)) {
- newChildren = directClone(children);
- }
- newChildFlags = 2 /* HasVNodeChildren */;
- }
- vNode.children = newChildren;
- vNode.childFlags = newChildFlags;
- {
- validateVNodeElementChildren(vNode);
- }
- return vNode;
- }
- var options = {
- afterMount: null,
- afterRender: null,
- afterUpdate: null,
- beforeRender: null,
- beforeUnmount: null,
- createVNode: null,
- roots: []
- };
- /**
- * Links given data to event as first parameter
- * @param {*} data data to be linked, it will be available in function as first parameter
- * @param {Function} event Function to be called when event occurs
- * @returns {{data: *, event: Function}}
- */
- function linkEvent(data, event) {
- if (isFunction(event)) {
- return { data: data, event: event };
- }
- return null; // Return null when event is invalid, to avoid creating unnecessary event handlers
- }
- var xlinkNS = 'http://www.w3.org/1999/xlink';
- var xmlNS = 'http://www.w3.org/XML/1998/namespace';
- var svgNS = 'http://www.w3.org/2000/svg';
- var namespaces = {
- 'xlink:actuate': xlinkNS,
- 'xlink:arcrole': xlinkNS,
- 'xlink:href': xlinkNS,
- 'xlink:role': xlinkNS,
- 'xlink:show': xlinkNS,
- 'xlink:title': xlinkNS,
- 'xlink:type': xlinkNS,
- 'xml:base': xmlNS,
- 'xml:lang': xmlNS,
- 'xml:space': xmlNS
- };
- // We need EMPTY_OBJ defined in one place.
- // Its used for comparison so we cant inline it into shared
- var EMPTY_OBJ = {};
- var LIFECYCLE = [];
- {
- Object.freeze(EMPTY_OBJ);
- }
- function appendChild(parentDom, dom) {
- parentDom.appendChild(dom);
- }
- function insertOrAppend(parentDom, newNode, nextNode) {
- if (isNullOrUndef(nextNode)) {
- appendChild(parentDom, newNode);
- }
- else {
- parentDom.insertBefore(newNode, nextNode);
- }
- }
- function documentCreateElement(tag, isSVG) {
- if (isSVG === true) {
- return document.createElementNS(svgNS, tag);
- }
- return document.createElement(tag);
- }
- function replaceChild(parentDom, newDom, lastDom) {
- parentDom.replaceChild(newDom, lastDom);
- }
- function removeChild(parentDom, dom) {
- parentDom.removeChild(dom);
- }
- function callAll(arrayFn) {
- var listener;
- while ((listener = arrayFn.shift()) !== undefined) {
- listener();
- }
- }
- var attachedEventCounts = {};
- var attachedEvents = {};
- function handleEvent(name, nextEvent, dom) {
- var eventsLeft = attachedEventCounts[name];
- var eventsObject = dom.$EV;
- if (nextEvent) {
- if (!eventsLeft) {
- attachedEvents[name] = attachEventToDocument(name);
- attachedEventCounts[name] = 0;
- }
- if (!eventsObject) {
- eventsObject = dom.$EV = {};
- }
- if (!eventsObject[name]) {
- attachedEventCounts[name]++;
- }
- eventsObject[name] = nextEvent;
- }
- else if (eventsObject && eventsObject[name]) {
- attachedEventCounts[name]--;
- if (eventsLeft === 1) {
- document.removeEventListener(normalizeEventName(name), attachedEvents[name]);
- attachedEvents[name] = null;
- }
- eventsObject[name] = nextEvent;
- }
- }
- function dispatchEvents(event, target, isClick, name, eventData) {
- var dom = target;
- while (!isNull(dom)) {
- // Html Nodes can be nested fe: span inside button in that scenario browser does not handle disabled attribute on parent,
- // because the event listener is on document.body
- // Don't process clicks on disabled elements
- if (isClick && dom.disabled) {
- return;
- }
- var eventsObject = dom.$EV;
- if (eventsObject) {
- var currentEvent = eventsObject[name];
- if (currentEvent) {
- // linkEvent object
- eventData.dom = dom;
- if (currentEvent.event) {
- currentEvent.event(currentEvent.data, event);
- }
- else {
- currentEvent(event);
- }
- if (event.cancelBubble) {
- return;
- }
- }
- }
- dom = dom.parentNode;
- }
- }
- function normalizeEventName(name) {
- return name.substr(2).toLowerCase();
- }
- function stopPropagation() {
- this.cancelBubble = true;
- this.stopImmediatePropagation();
- }
- function attachEventToDocument(name) {
- var docEvent = function (event) {
- var type = event.type;
- var isClick = type === 'click' || type === 'dblclick';
- if (isClick && event.button !== 0) {
- // Firefox incorrectly triggers click event for mid/right mouse buttons.
- // This bug has been active for 12 years.
- // https://bugzilla.mozilla.org/show_bug.cgi?id=184051
- event.preventDefault();
- event.stopPropagation();
- return false;
- }
- event.stopPropagation = stopPropagation;
- // Event data needs to be object to save reference to currentTarget getter
- var eventData = {
- dom: document
- };
- try {
- Object.defineProperty(event, 'currentTarget', {
- configurable: true,
- get: function get() {
- return eventData.dom;
- }
- });
- }
- catch (e) {
- /* safari7 and phantomJS will crash */
- }
- dispatchEvents(event, event.target, isClick, name, eventData);
- };
- document.addEventListener(normalizeEventName(name), docEvent);
- return docEvent;
- }
- function isSameInnerHTML(dom, innerHTML) {
- var tempdom = document.createElement('i');
- tempdom.innerHTML = innerHTML;
- return tempdom.innerHTML === dom.innerHTML;
- }
- function isSamePropsInnerHTML(dom, props) {
- return Boolean(props && props.dangerouslySetInnerHTML && props.dangerouslySetInnerHTML.__html && isSameInnerHTML(dom, props.dangerouslySetInnerHTML.__html));
- }
- function triggerEventListener(props, methodName, e) {
- if (props[methodName]) {
- var listener = props[methodName];
- if (listener.event) {
- listener.event(listener.data, e);
- }
- else {
- listener(e);
- }
- }
- else {
- var nativeListenerName = methodName.toLowerCase();
- if (props[nativeListenerName]) {
- props[nativeListenerName](e);
- }
- }
- }
- function createWrappedFunction(methodName, applyValue) {
- var fnMethod = function (e) {
- e.stopPropagation();
- var vNode = this.$V;
- // If vNode is gone by the time event fires, no-op
- if (!vNode) {
- return;
- }
- var props = vNode.props || EMPTY_OBJ;
- var dom = vNode.dom;
- if (isString(methodName)) {
- triggerEventListener(props, methodName, e);
- }
- else {
- for (var i = 0; i < methodName.length; i++) {
- triggerEventListener(props, methodName[i], e);
- }
- }
- if (isFunction(applyValue)) {
- var newVNode = this.$V;
- var newProps = newVNode.props || EMPTY_OBJ;
- applyValue(newProps, dom, false, newVNode);
- }
- };
- Object.defineProperty(fnMethod, 'wrapped', {
- configurable: false,
- enumerable: false,
- value: true,
- writable: false
- });
- return fnMethod;
- }
- function isCheckedType(type) {
- return type === 'checkbox' || type === 'radio';
- }
- var onTextInputChange = createWrappedFunction('onInput', applyValueInput);
- var wrappedOnChange = createWrappedFunction(['onClick', 'onChange'], applyValueInput);
- /* tslint:disable-next-line:no-empty */
- function emptywrapper(event) {
- event.stopPropagation();
- }
- emptywrapper.wrapped = true;
- function inputEvents(dom, nextPropsOrEmpty) {
- if (isCheckedType(nextPropsOrEmpty.type)) {
- dom.onchange = wrappedOnChange;
- dom.onclick = emptywrapper;
- }
- else {
- dom.oninput = onTextInputChange;
- }
- }
- function applyValueInput(nextPropsOrEmpty, dom) {
- var type = nextPropsOrEmpty.type;
- var value = nextPropsOrEmpty.value;
- var checked = nextPropsOrEmpty.checked;
- var multiple = nextPropsOrEmpty.multiple;
- var defaultValue = nextPropsOrEmpty.defaultValue;
- var hasValue = !isNullOrUndef(value);
- if (type && type !== dom.type) {
- dom.setAttribute('type', type);
- }
- if (!isNullOrUndef(multiple) && multiple !== dom.multiple) {
- dom.multiple = multiple;
- }
- if (!isNullOrUndef(defaultValue) && !hasValue) {
- dom.defaultValue = defaultValue + '';
- }
- if (isCheckedType(type)) {
- if (hasValue) {
- dom.value = value;
- }
- if (!isNullOrUndef(checked)) {
- dom.checked = checked;
- }
- }
- else {
- if (hasValue && dom.value !== value) {
- dom.defaultValue = value;
- dom.value = value;
- }
- else if (!isNullOrUndef(checked)) {
- dom.checked = checked;
- }
- }
- }
- function updateChildOptionGroup(vNode, value) {
- var type = vNode.type;
- if (type === 'optgroup') {
- var children = vNode.children;
- var childFlags = vNode.childFlags;
- if (childFlags & 12 /* MultipleChildren */) {
- for (var i = 0, len = children.length; i < len; i++) {
- updateChildOption(children[i], value);
- }
- }
- else if (childFlags === 2 /* HasVNodeChildren */) {
- updateChildOption(children, value);
- }
- }
- else {
- updateChildOption(vNode, value);
- }
- }
- function updateChildOption(vNode, value) {
- var props = vNode.props || EMPTY_OBJ;
- var dom = vNode.dom;
- // we do this as multiple may have changed
- dom.value = props.value;
- if ((isArray(value) && value.indexOf(props.value) !== -1) || props.value === value) {
- dom.selected = true;
- }
- else if (!isNullOrUndef(value) || !isNullOrUndef(props.selected)) {
- dom.selected = props.selected || false;
- }
- }
- var onSelectChange = createWrappedFunction('onChange', applyValueSelect);
- function selectEvents(dom) {
- dom.onchange = onSelectChange;
- }
- function applyValueSelect(nextPropsOrEmpty, dom, mounting, vNode) {
- var multiplePropInBoolean = Boolean(nextPropsOrEmpty.multiple);
- if (!isNullOrUndef(nextPropsOrEmpty.multiple) && multiplePropInBoolean !== dom.multiple) {
- dom.multiple = multiplePropInBoolean;
- }
- var childFlags = vNode.childFlags;
- if ((childFlags & 1 /* HasInvalidChildren */) === 0) {
- var children = vNode.children;
- var value = nextPropsOrEmpty.value;
- if (mounting && isNullOrUndef(value)) {
- value = nextPropsOrEmpty.defaultValue;
- }
- if (childFlags & 12 /* MultipleChildren */) {
- for (var i = 0, len = children.length; i < len; i++) {
- updateChildOptionGroup(children[i], value);
- }
- }
- else if (childFlags === 2 /* HasVNodeChildren */) {
- updateChildOptionGroup(children, value);
- }
- }
- }
- var onTextareaInputChange = createWrappedFunction('onInput', applyValueTextArea);
- var wrappedOnChange$1 = createWrappedFunction('onChange');
- function textAreaEvents(dom, nextPropsOrEmpty) {
- dom.oninput = onTextareaInputChange;
- if (nextPropsOrEmpty.onChange) {
- dom.onchange = wrappedOnChange$1;
- }
- }
- function applyValueTextArea(nextPropsOrEmpty, dom, mounting) {
- var value = nextPropsOrEmpty.value;
- var domValue = dom.value;
- if (isNullOrUndef(value)) {
- if (mounting) {
- var defaultValue = nextPropsOrEmpty.defaultValue;
- if (!isNullOrUndef(defaultValue) && defaultValue !== domValue) {
- dom.defaultValue = defaultValue;
- dom.value = defaultValue;
- }
- }
- }
- else if (domValue !== value) {
- /* There is value so keep it controlled */
- dom.defaultValue = value;
- dom.value = value;
- }
- }
- /**
- * There is currently no support for switching same input between controlled and nonControlled
- * If that ever becomes a real issue, then re design controlled elements
- * Currently user must choose either controlled or non-controlled and stick with that
- */
- function processElement(flags, vNode, dom, nextPropsOrEmpty, mounting, isControlled) {
- if (flags & 64 /* InputElement */) {
- applyValueInput(nextPropsOrEmpty, dom);
- }
- else if (flags & 256 /* SelectElement */) {
- applyValueSelect(nextPropsOrEmpty, dom, mounting, vNode);
- }
- else if (flags & 128 /* TextareaElement */) {
- applyValueTextArea(nextPropsOrEmpty, dom, mounting);
- }
- if (isControlled) {
- dom.$V = vNode;
- }
- }
- function addFormElementEventHandlers(flags, dom, nextPropsOrEmpty) {
- if (flags & 64 /* InputElement */) {
- inputEvents(dom, nextPropsOrEmpty);
- }
- else if (flags & 256 /* SelectElement */) {
- selectEvents(dom);
- }
- else if (flags & 128 /* TextareaElement */) {
- textAreaEvents(dom, nextPropsOrEmpty);
- }
- }
- function isControlledFormElement(nextPropsOrEmpty) {
- return nextPropsOrEmpty.type && isCheckedType(nextPropsOrEmpty.type) ? !isNullOrUndef(nextPropsOrEmpty.checked) : !isNullOrUndef(nextPropsOrEmpty.value);
- }
- function remove(vNode, parentDom) {
- unmount(vNode);
- if (!isNull(parentDom)) {
- removeChild(parentDom, vNode.dom);
- // Let carbage collector free memory
- vNode.dom = null;
- }
- }
- function unmount(vNode) {
- var flags = vNode.flags;
- if (flags & 481 /* Element */) {
- var ref = vNode.ref;
- var props = vNode.props;
- if (isFunction(ref)) {
- ref(null);
- }
- var children = vNode.children;
- var childFlags = vNode.childFlags;
- if (childFlags & 12 /* MultipleChildren */) {
- unmountAllChildren(children);
- }
- else if (childFlags === 2 /* HasVNodeChildren */) {
- unmount(children);
- }
- if (!isNull(props)) {
- for (var name in props) {
- switch (name) {
- case 'onClick':
- case 'onDblClick':
- case 'onFocusIn':
- case 'onFocusOut':
- case 'onKeyDown':
- case 'onKeyPress':
- case 'onKeyUp':
- case 'onMouseDown':
- case 'onMouseMove':
- case 'onMouseUp':
- case 'onSubmit':
- case 'onTouchEnd':
- case 'onTouchMove':
- case 'onTouchStart':
- handleEvent(name, null, vNode.dom);
- break;
- default:
- break;
- }
- }
- }
- }
- else if (flags & 14 /* Component */) {
- var instance = vNode.children;
- var ref$1 = vNode.ref;
- if (flags & 4 /* ComponentClass */) {
- if (isFunction(options.beforeUnmount)) {
- options.beforeUnmount(vNode);
- }
- if (isFunction(instance.componentWillUnmount)) {
- instance.componentWillUnmount();
- }
- if (isFunction(ref$1)) {
- ref$1(null);
- }
- instance.$UN = true;
- unmount(instance.$LI);
- }
- else {
- if (!isNullOrUndef(ref$1) && isFunction(ref$1.onComponentWillUnmount)) {
- ref$1.onComponentWillUnmount(vNode.dom, vNode.props || EMPTY_OBJ);
- }
- unmount(instance);
- }
- }
- else if (flags & 1024 /* Portal */) {
- var children$1 = vNode.children;
- if (!isNull(children$1) && isObject(children$1)) {
- remove(children$1, vNode.type);
- }
- }
- }
- function unmountAllChildren(children) {
- for (var i = 0, len = children.length; i < len; i++) {
- unmount(children[i]);
- }
- }
- function removeAllChildren(dom, children) {
- unmountAllChildren(children);
- dom.textContent = '';
- }
- function createLinkEvent(linkEvent, nextValue) {
- return function (e) {
- linkEvent(nextValue.data, e);
- };
- }
- function patchEvent(name, lastValue, nextValue, dom) {
- var nameLowerCase = name.toLowerCase();
- if (!isFunction(nextValue) && !isNullOrUndef(nextValue)) {
- var linkEvent = nextValue.event;
- if (linkEvent && isFunction(linkEvent)) {
- dom[nameLowerCase] = createLinkEvent(linkEvent, nextValue);
- }
- else {
- // Development warning
- {
- throwError(("an event on a VNode \"" + name + "\". was not a function or a valid linkEvent."));
- }
- }
- }
- else {
- var domEvent = dom[nameLowerCase];
- // if the function is wrapped, that means it's been controlled by a wrapper
- if (!domEvent || !domEvent.wrapped) {
- dom[nameLowerCase] = nextValue;
- }
- }
- }
- function getNumberStyleValue(style, value) {
- switch (style) {
- case 'animationIterationCount':
- case 'borderImageOutset':
- case 'borderImageSlice':
- case 'borderImageWidth':
- case 'boxFlex':
- case 'boxFlexGroup':
- case 'boxOrdinalGroup':
- case 'columnCount':
- case 'fillOpacity':
- case 'flex':
- case 'flexGrow':
- case 'flexNegative':
- case 'flexOrder':
- case 'flexPositive':
- case 'flexShrink':
- case 'floodOpacity':
- case 'fontWeight':
- case 'gridColumn':
- case 'gridRow':
- case 'lineClamp':
- case 'lineHeight':
- case 'opacity':
- case 'order':
- case 'orphans':
- case 'stopOpacity':
- case 'strokeDasharray':
- case 'strokeDashoffset':
- case 'strokeMiterlimit':
- case 'strokeOpacity':
- case 'strokeWidth':
- case 'tabSize':
- case 'widows':
- case 'zIndex':
- case 'zoom':
- return value;
- default:
- return value + 'px';
- }
- }
- // We are assuming here that we come from patchProp routine
- // -nextAttrValue cannot be null or undefined
- 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) {
- // do not add a hasOwnProperty check here, it affects performance
- value = nextAttrValue[style];
- if (value !== lastAttrValue[style]) {
- domStyle[style] = isNumber(value) ? getNumberStyleValue(style, value) : value;
- }
- }
- for (style in lastAttrValue) {
- if (isNullOrUndef(nextAttrValue[style])) {
- domStyle[style] = '';
- }
- }
- }
- else {
- for (style in nextAttrValue) {
- value = nextAttrValue[style];
- domStyle[style] = isNumber(value) ? getNumberStyleValue(style, value) : value;
- }
- }
- }
- function patchProp(prop, lastValue, nextValue, dom, isSVG, hasControlledValue, lastVNode) {
- switch (prop) {
- case 'onClick':
- case 'onDblClick':
- case 'onFocusIn':
- case 'onFocusOut':
- case 'onKeyDown':
- case 'onKeyPress':
- case 'onKeyUp':
- case 'onMouseDown':
- case 'onMouseMove':
- case 'onMouseUp':
- case 'onSubmit':
- case 'onTouchEnd':
- case 'onTouchMove':
- case 'onTouchStart':
- handleEvent(prop, nextValue, dom);
- break;
- case 'children':
- case 'childrenType':
- case 'className':
- case 'defaultValue':
- case 'key':
- case 'multiple':
- case 'ref':
- return;
- case 'allowfullscreen':
- case 'autoFocus':
- case 'autoplay':
- case 'capture':
- case 'checked':
- case 'controls':
- case 'default':
- case 'disabled':
- case 'hidden':
- case 'indeterminate':
- case 'loop':
- case 'muted':
- case 'novalidate':
- case 'open':
- case 'readOnly':
- case 'required':
- case 'reversed':
- case 'scoped':
- case 'seamless':
- case 'selected':
- prop = prop === 'autoFocus' ? prop.toLowerCase() : prop;
- dom[prop] = !!nextValue;
- break;
- case 'defaultChecked':
- case 'value':
- case 'volume':
- if (hasControlledValue && prop === 'value') {
- return;
- }
- var value = isNullOrUndef(nextValue) ? '' : nextValue;
- if (dom[prop] !== value) {
- dom[prop] = value;
- }
- break;
- case 'dangerouslySetInnerHTML':
- var lastHtml = (lastValue && lastValue.__html) || '';
- var nextHtml = (nextValue && nextValue.__html) || '';
- if (lastHtml !== nextHtml) {
- if (!isNullOrUndef(nextHtml) && !isSameInnerHTML(dom, nextHtml)) {
- if (!isNull(lastVNode)) {
- if (lastVNode.childFlags & 12 /* MultipleChildren */) {
- unmountAllChildren(lastVNode.children);
- }
- else if (lastVNode.childFlags === 2 /* HasVNodeChildren */) {
- unmount(lastVNode.children);
- }
- lastVNode.children = null;
- lastVNode.childFlags = 1 /* HasInvalidChildren */;
- }
- dom.innerHTML = nextHtml;
- }
- }
- break;
- default:
- if (prop[0] === 'o' && prop[1] === 'n') {
- patchEvent(prop, lastValue, nextValue, dom);
- }
- else if (isNullOrUndef(nextValue)) {
- dom.removeAttribute(prop);
- }
- else if (prop === 'style') {
- patchStyle(lastValue, nextValue, dom);
- }
- else if (isSVG && namespaces[prop]) {
- // We optimize for NS being boolean. Its 99.9% time false
- // If we end up in this path we can read property again
- dom.setAttributeNS(namespaces[prop], prop, nextValue);
- }
- else {
- dom.setAttribute(prop, nextValue);
- }
- break;
- }
- }
- function mountProps(vNode, flags, props, dom, isSVG) {
- var hasControlledValue = false;
- var isFormElement = (flags & 448 /* FormElement */) > 0;
- if (isFormElement) {
- hasControlledValue = isControlledFormElement(props);
- if (hasControlledValue) {
- addFormElementEventHandlers(flags, dom, props);
- }
- }
- for (var prop in props) {
- // do not add a hasOwnProperty check here, it affects performance
- patchProp(prop, null, props[prop], dom, isSVG, hasControlledValue, null);
- }
- if (isFormElement) {
- processElement(flags, vNode, dom, props, true, hasControlledValue);
- }
- }
- function createClassComponentInstance(vNode, Component, props, context) {
- var instance = new Component(props, context);
- vNode.children = instance;
- instance.$V = vNode;
- instance.$BS = false;
- instance.context = context;
- if (instance.props === EMPTY_OBJ) {
- instance.props = props;
- }
- instance.$UN = false;
- if (isFunction(instance.componentWillMount)) {
- instance.$BR = true;
- instance.componentWillMount();
- if (instance.$PSS) {
- var state = instance.state;
- var pending = instance.$PS;
- if (isNull(state)) {
- instance.state = pending;
- }
- else {
- for (var key in pending) {
- state[key] = pending[key];
- }
- }
- instance.$PSS = false;
- instance.$PS = null;
- }
- instance.$BR = false;
- }
- if (isFunction(options.beforeRender)) {
- options.beforeRender(instance);
- }
- var input = handleComponentInput(instance.render(props, instance.state, context), vNode);
- var childContext;
- if (isFunction(instance.getChildContext)) {
- childContext = instance.getChildContext();
- }
- if (isNullOrUndef(childContext)) {
- instance.$CX = context;
- }
- else {
- instance.$CX = combineFrom(context, childContext);
- }
- if (isFunction(options.afterRender)) {
- options.afterRender(instance);
- }
- instance.$LI = input;
- return instance;
- }
- function handleComponentInput(input, componentVNode) {
- // Development validation
- {
- if (isArray(input)) {
- throwError('a valid Inferno VNode (or null) must be returned from a component render. You may have returned an array or an invalid object.');
- }
- }
- if (isInvalid(input)) {
- input = createVoidVNode();
- }
- else if (isStringOrNumber(input)) {
- input = createTextVNode(input, null);
- }
- else {
- if (input.dom) {
- input = directClone(input);
- }
- if (input.flags & 14 /* Component */) {
- // if we have an input that is also a component, we run into a tricky situation
- // where the root vNode needs to always have the correct DOM entry
- // we can optimise this in the future, but this gets us out of a lot of issues
- input.parentVNode = componentVNode;
- }
- }
- return input;
- }
- function mount(vNode, parentDom, lifecycle, context, isSVG) {
- var flags = vNode.flags;
- if (flags & 481 /* Element */) {
- return mountElement(vNode, parentDom, lifecycle, context, isSVG);
- }
- if (flags & 14 /* Component */) {
- return mountComponent(vNode, parentDom, lifecycle, context, isSVG, (flags & 4 /* ComponentClass */) > 0);
- }
- if (flags & 512 /* Void */ || flags & 16 /* Text */) {
- return mountText(vNode, parentDom);
- }
- if (flags & 1024 /* Portal */) {
- mount(vNode.children, vNode.type, lifecycle, context, false);
- return (vNode.dom = mountText(createVoidVNode(), parentDom));
- }
- // Development validation, in production we don't need to throw because it crashes anyway
- {
- if (typeof vNode === 'object') {
- throwError(("mount() received an object that's not a valid VNode, you should stringify it first, fix createVNode flags or call normalizeChildren. Object: \"" + (JSON.stringify(vNode)) + "\"."));
- }
- else {
- throwError(("mount() expects a valid VNode, instead it received an object with the type \"" + (typeof vNode) + "\"."));
- }
- }
- }
- function mountText(vNode, parentDom) {
- var dom = (vNode.dom = document.createTextNode(vNode.children));
- if (!isNull(parentDom)) {
- appendChild(parentDom, dom);
- }
- return dom;
- }
- function mountElement(vNode, parentDom, lifecycle, context, isSVG) {
- var flags = vNode.flags;
- var children = vNode.children;
- var props = vNode.props;
- var className = vNode.className;
- var ref = vNode.ref;
- var childFlags = vNode.childFlags;
- isSVG = isSVG || (flags & 32 /* SvgElement */) > 0;
- var dom = documentCreateElement(vNode.type, isSVG);
- vNode.dom = dom;
- if (!isNullOrUndef(className) && className !== '') {
- if (isSVG) {
- dom.setAttribute('class', className);
- }
- else {
- dom.className = className;
- }
- }
- {
- validateKeys(vNode);
- }
- if (!isNull(parentDom)) {
- appendChild(parentDom, dom);
- }
- if ((childFlags & 1 /* HasInvalidChildren */) === 0) {
- var childrenIsSVG = isSVG === true && vNode.type !== 'foreignObject';
- if (childFlags === 2 /* HasVNodeChildren */) {
- mount(children, dom, lifecycle, context, childrenIsSVG);
- }
- else if (childFlags & 12 /* MultipleChildren */) {
- mountArrayChildren(children, dom, lifecycle, context, childrenIsSVG);
- }
- }
- if (!isNull(props)) {
- mountProps(vNode, flags, props, dom, isSVG);
- }
- {
- if (isString(ref)) {
- throwError('string "refs" are not supported in Inferno 1.0. Use callback "refs" instead.');
- }
- }
- if (isFunction(ref)) {
- mountRef(dom, ref, lifecycle);
- }
- return dom;
- }
- function mountArrayChildren(children, dom, lifecycle, context, isSVG) {
- for (var i = 0, len = children.length; i < len; i++) {
- var child = children[i];
- if (!isNull(child.dom)) {
- children[i] = child = directClone(child);
- }
- mount(child, dom, lifecycle, context, isSVG);
- }
- }
- function mountComponent(vNode, parentDom, lifecycle, context, isSVG, isClass) {
- var dom;
- var type = vNode.type;
- var props = vNode.props || EMPTY_OBJ;
- var ref = vNode.ref;
- if (isClass) {
- var instance = createClassComponentInstance(vNode, type, props, context);
- vNode.dom = dom = mount(instance.$LI, null, lifecycle, instance.$CX, isSVG);
- mountClassComponentCallbacks(vNode, ref, instance, lifecycle);
- instance.$UPD = false;
- }
- else {
- var input = handleComponentInput(type(props, context), vNode);
- vNode.children = input;
- vNode.dom = dom = mount(input, null, lifecycle, context, isSVG);
- mountFunctionalComponentCallbacks(props, ref, dom, lifecycle);
- }
- if (!isNull(parentDom)) {
- appendChild(parentDom, dom);
- }
- return dom;
- }
- function createClassMountCallback(instance, hasAfterMount, afterMount, vNode, hasDidMount) {
- return function () {
- instance.$UPD = true;
- if (hasAfterMount) {
- afterMount(vNode);
- }
- if (hasDidMount) {
- instance.componentDidMount();
- }
- instance.$UPD = false;
- };
- }
- function mountClassComponentCallbacks(vNode, ref, instance, lifecycle) {
- if (isFunction(ref)) {
- ref(instance);
- }
- else {
- {
- if (isStringOrNumber(ref)) {
- throwError('string "refs" are not supported in Inferno 1.0. Use callback "refs" instead.');
- }
- else if (!isNullOrUndef(ref) && isObject(ref) && vNode.flags & 4 /* ComponentClass */) {
- throwError('functional component lifecycle events are not supported on ES2015 class components.');
- }
- }
- }
- var hasDidMount = isFunction(instance.componentDidMount);
- var afterMount = options.afterMount;
- var hasAfterMount = isFunction(afterMount);
- if (hasDidMount || hasAfterMount) {
- lifecycle.push(createClassMountCallback(instance, hasAfterMount, afterMount, vNode, hasDidMount));
- }
- }
- // Create did mount callback lazily to avoid creating function context if not needed
- function createOnMountCallback(ref, dom, props) {
- return function () { return ref.onComponentDidMount(dom, props); };
- }
- function mountFunctionalComponentCallbacks(props, ref, dom, lifecycle) {
- if (!isNullOrUndef(ref)) {
- if (isFunction(ref.onComponentWillMount)) {
- ref.onComponentWillMount(props);
- }
- if (isFunction(ref.onComponentDidMount)) {
- lifecycle.push(createOnMountCallback(ref, dom, props));
- }
- }
- }
- function mountRef(dom, value, lifecycle) {
- lifecycle.push(function () { return value(dom); });
- }
- function hydrateComponent(vNode, dom, lifecycle, context, isSVG, isClass) {
- var type = vNode.type;
- var ref = vNode.ref;
- var props = vNode.props || EMPTY_OBJ;
- if (isClass) {
- var instance = createClassComponentInstance(vNode, type, props, context);
- var input = instance.$LI;
- hydrateVNode(input, dom, lifecycle, instance.$CX, isSVG);
- vNode.dom = input.dom;
- mountClassComponentCallbacks(vNode, ref, instance, lifecycle);
- instance.$UPD = false; // Mount finished allow going sync
- }
- else {
- var input$1 = handleComponentInput(type(props, context), vNode);
- hydrateVNode(input$1, dom, lifecycle, context, isSVG);
- vNode.children = input$1;
- vNode.dom = input$1.dom;
- mountFunctionalComponentCallbacks(props, ref, dom, lifecycle);
- }
- }
- function hydrateElement(vNode, dom, lifecycle, context, isSVG) {
- var children = vNode.children;
- var props = vNode.props;
- var className = vNode.className;
- var flags = vNode.flags;
- var ref = vNode.ref;
- isSVG = isSVG || (flags & 32 /* SvgElement */) > 0;
- if (dom.nodeType !== 1 || dom.tagName.toLowerCase() !== vNode.type) {
- {
- warning("Inferno hydration: Server-side markup doesn't match client-side markup or Initial render target is not empty");
- }
- var newDom = mountElement(vNode, null, lifecycle, context, isSVG);
- vNode.dom = newDom;
- replaceChild(dom.parentNode, newDom, dom);
- }
- else {
- vNode.dom = dom;
- var childNode = dom.firstChild;
- var childFlags = vNode.childFlags;
- if ((childFlags & 1 /* HasInvalidChildren */) === 0) {
- var nextSibling = null;
- while (childNode) {
- nextSibling = childNode.nextSibling;
- if (childNode.nodeType === 8) {
- if (childNode.data === '!') {
- dom.replaceChild(document.createTextNode(''), childNode);
- }
- else {
- dom.removeChild(childNode);
- }
- }
- childNode = nextSibling;
- }
- childNode = dom.firstChild;
- if (childFlags === 2 /* HasVNodeChildren */) {
- if (isNull(childNode)) {
- mount(children, dom, lifecycle, context, isSVG);
- }
- else {
- nextSibling = childNode.nextSibling;
- hydrateVNode(children, childNode, lifecycle, context, isSVG);
- childNode = nextSibling;
- }
- }
- else if (childFlags & 12 /* MultipleChildren */) {
- for (var i = 0, len = children.length; i < len; i++) {
- var child = children[i];
- if (isNull(childNode)) {
- mount(child, dom, lifecycle, context, isSVG);
- }
- else {
- nextSibling = childNode.nextSibling;
- hydrateVNode(child, childNode, lifecycle, context, isSVG);
- childNode = nextSibling;
- }
- }
- }
- // clear any other DOM nodes, there should be only a single entry for the root
- while (childNode) {
- nextSibling = childNode.nextSibling;
- dom.removeChild(childNode);
- childNode = nextSibling;
- }
- }
- else if (!isNull(dom.firstChild) && !isSamePropsInnerHTML(dom, props)) {
- dom.textContent = ''; // dom has content, but VNode has no children remove everything from DOM
- if (flags & 448 /* FormElement */) {
- // If element is form element, we need to clear defaultValue also
- dom.defaultValue = '';
- }
- }
- if (!isNull(props)) {
- mountProps(vNode, flags, props, dom, isSVG);
- }
- if (isNullOrUndef(className)) {
- if (dom.className !== '') {
- dom.removeAttribute('class');
- }
- }
- else if (isSVG) {
- dom.setAttribute('class', className);
- }
- else {
- dom.className = className;
- }
- if (isFunction(ref)) {
- mountRef(dom, ref, lifecycle);
- }
- else {
- {
- if (isString(ref)) {
- throwError('string "refs" are not supported in Inferno 1.0. Use callback "refs" instead.');
- }
- }
- }
- }
- }
- function hydrateText(vNode, dom) {
- if (dom.nodeType !== 3) {
- var newDom = mountText(vNode, null);
- vNode.dom = newDom;
- replaceChild(dom.parentNode, newDom, dom);
- }
- else {
- var text = vNode.children;
- if (dom.nodeValue !== text) {
- dom.nodeValue = text;
- }
- vNode.dom = dom;
- }
- }
- function hydrateVNode(vNode, dom, lifecycle, context, isSVG) {
- var flags = vNode.flags;
- if (flags & 14 /* Component */) {
- hydrateComponent(vNode, dom, lifecycle, context, isSVG, (flags & 4 /* ComponentClass */) > 0);
- }
- else if (flags & 481 /* Element */) {
- hydrateElement(vNode, dom, lifecycle, context, isSVG);
- }
- else if (flags & 16 /* Text */) {
- hydrateText(vNode, dom);
- }
- else if (flags & 512 /* Void */) {
- vNode.dom = dom;
- }
- else {
- {
- throwError(("hydrate() expects a valid VNode, instead it received an object with the type \"" + (typeof vNode) + "\"."));
- }
- throwError();
- }
- }
- function hydrate(input, parentDom, callback) {
- var dom = parentDom.firstChild;
- if (!isNull(dom)) {
- if (!isInvalid(input)) {
- hydrateVNode(input, dom, LIFECYCLE, EMPTY_OBJ, false);
- }
- dom = parentDom.firstChild;
- // clear any other DOM nodes, there should be only a single entry for the root
- while ((dom = dom.nextSibling)) {
- parentDom.removeChild(dom);
- }
- }
- if (LIFECYCLE.length > 0) {
- callAll(LIFECYCLE);
- }
- if (!parentDom.$V) {
- options.roots.push(parentDom);
- }
- parentDom.$V = input;
- if (isFunction(callback)) {
- callback();
- }
- }
- function replaceWithNewNode(lastNode, nextNode, parentDom, lifecycle, context, isSVG) {
- unmount(lastNode);
- replaceChild(parentDom, mount(nextNode, null, lifecycle, context, isSVG), lastNode.dom);
- }
- function patch(lastVNode, nextVNode, parentDom, lifecycle, context, isSVG) {
- if (lastVNode !== nextVNode) {
- var nextFlags = nextVNode.flags;
- if (lastVNode.flags !== nextFlags || nextFlags & 2048 /* ReCreate */) {
- replaceWithNewNode(lastVNode, nextVNode, parentDom, lifecycle, context, isSVG);
- }
- else if (nextFlags & 481 /* Element */) {
- patchElement(lastVNode, nextVNode, parentDom, lifecycle, context, isSVG);
- }
- else if (nextFlags & 14 /* Component */) {
- patchComponent(lastVNode, nextVNode, parentDom, lifecycle, context, isSVG, (nextFlags & 4 /* ComponentClass */) > 0);
- }
- else if (nextFlags & 16 /* Text */) {
- patchText(lastVNode, nextVNode, parentDom);
- }
- else if (nextFlags & 512 /* Void */) {
- nextVNode.dom = lastVNode.dom;
- }
- else {
- // Portal
- patchPortal(lastVNode, nextVNode, lifecycle, context);
- }
- }
- }
- function patchPortal(lastVNode, nextVNode, lifecycle, context) {
- var lastContainer = lastVNode.type;
- var nextContainer = nextVNode.type;
- var nextChildren = nextVNode.children;
- patchChildren(lastVNode.childFlags, nextVNode.childFlags, lastVNode.children, nextChildren, lastContainer, lifecycle, context, false);
- nextVNode.dom = lastVNode.dom;
- if (lastContainer !== nextContainer && !isInvalid(nextChildren)) {
- var node = nextChildren.dom;
- lastContainer.removeChild(node);
- nextContainer.appendChild(node);
- }
- }
- function patchElement(lastVNode, nextVNode, parentDom, lifecycle, context, isSVG) {
- var nextTag = nextVNode.type;
- if (lastVNode.type !== nextTag) {
- replaceWithNewNode(lastVNode, nextVNode, parentDom, lifecycle, context, isSVG);
- }
- else {
- var dom = lastVNode.dom;
- var nextFlags = nextVNode.flags;
- var lastProps = lastVNode.props;
- var nextProps = nextVNode.props;
- var isFormElement = false;
- var hasControlledValue = false;
- var nextPropsOrEmpty;
- nextVNode.dom = dom;
- isSVG = isSVG || (nextFlags & 32 /* SvgElement */) > 0;
- // inlined patchProps -- starts --
- if (lastProps !== nextProps) {
- var lastPropsOrEmpty = lastProps || EMPTY_OBJ;
- nextPropsOrEmpty = nextProps || EMPTY_OBJ;
- if (nextPropsOrEmpty !== EMPTY_OBJ) {
- isFormElement = (nextFlags & 448 /* FormElement */) > 0;
- if (isFormElement) {
- hasControlledValue = isControlledFormElement(nextPropsOrEmpty);
- }
- for (var prop in nextPropsOrEmpty) {
- var lastValue = lastPropsOrEmpty[prop];
- var nextValue = nextPropsOrEmpty[prop];
- if (lastValue !== nextValue) {
- patchProp(prop, lastValue, nextValue, dom, isSVG, hasControlledValue, lastVNode);
- }
- }
- }
- if (lastPropsOrEmpty !== EMPTY_OBJ) {
- for (var prop$1 in lastPropsOrEmpty) {
- // do not add a hasOwnProperty check here, it affects performance
- if (!nextPropsOrEmpty.hasOwnProperty(prop$1) && !isNullOrUndef(lastPropsOrEmpty[prop$1])) {
- patchProp(prop$1, lastPropsOrEmpty[prop$1], null, dom, isSVG, hasControlledValue, lastVNode);
- }
- }
- }
- }
- var lastChildren = lastVNode.children;
- var nextChildren = nextVNode.children;
- var nextRef = nextVNode.ref;
- var lastClassName = lastVNode.className;
- var nextClassName = nextVNode.className;
- if (lastChildren !== nextChildren) {
- {
- validateKeys(nextVNode);
- }
- patchChildren(lastVNode.childFlags, nextVNode.childFlags, lastChildren, nextChildren, dom, lifecycle, context, isSVG && nextTag !== 'foreignObject');
- }
- if (isFormElement) {
- processElement(nextFlags, nextVNode, dom, nextPropsOrEmpty, false, hasControlledValue);
- }
- // inlined patchProps -- ends --
- if (lastClassName !== nextClassName) {
- if (isNullOrUndef(nextClassName)) {
- dom.removeAttribute('class');
- }
- else if (isSVG) {
- dom.setAttribute('class', nextClassName);
- }
- else {
- dom.className = nextClassName;
- }
- }
- if (isFunction(nextRef) && lastVNode.ref !== nextRef) {
- mountRef(dom, nextRef, lifecycle);
- }
- else {
- {
- if (isString(nextRef)) {
- throwError('string "refs" are not supported in Inferno 1.0. Use callback "refs" instead.');
- }
- }
- }
- }
- }
- function patchChildren(lastChildFlags, nextChildFlags, lastChildren, nextChildren, parentDOM, lifecycle, context, isSVG) {
- switch (lastChildFlags) {
- case 2 /* HasVNodeChildren */:
- switch (nextChildFlags) {
- case 2 /* HasVNodeChildren */:
- patch(lastChildren, nextChildren, parentDOM, lifecycle, context, isSVG);
- break;
- case 1 /* HasInvalidChildren */:
- remove(lastChildren, parentDOM);
- break;
- default:
- remove(lastChildren, parentDOM);
- mountArrayChildren(nextChildren, parentDOM, lifecycle, context, isSVG);
- break;
- }
- break;
- case 1 /* HasInvalidChildren */:
- switch (nextChildFlags) {
- case 2 /* HasVNodeChildren */:
- mount(nextChildren, parentDOM, lifecycle, context, isSVG);
- break;
- case 1 /* HasInvalidChildren */:
- break;
- default:
- mountArrayChildren(nextChildren, parentDOM, lifecycle, context, isSVG);
- break;
- }
- break;
- default:
- if (nextChildFlags & 12 /* MultipleChildren */) {
- var lastLength = lastChildren.length;
- var nextLength = nextChildren.length;
- // Fast path's for both algorithms
- if (lastLength === 0) {
- if (nextLength > 0) {
- mountArrayChildren(nextChildren, parentDOM, lifecycle, context, isSVG);
- }
- }
- else if (nextLength === 0) {
- removeAllChildren(parentDOM, lastChildren);
- }
- else if (nextChildFlags === 8 /* HasKeyedChildren */ && lastChildFlags === 8 /* HasKeyedChildren */) {
- patchKeyedChildren(lastChildren, nextChildren, parentDOM, lifecycle, context, isSVG, lastLength, nextLength);
- }
- else {
- patchNonKeyedChildren(lastChildren, nextChildren, parentDOM, lifecycle, context, isSVG, lastLength, nextLength);
- }
- }
- else if (nextChildFlags === 1 /* HasInvalidChildren */) {
- removeAllChildren(parentDOM, lastChildren);
- }
- else {
- removeAllChildren(parentDOM, lastChildren);
- mount(nextChildren, parentDOM, lifecycle, context, isSVG);
- }
- break;
- }
- }
- function updateClassComponent(instance, nextState, nextVNode, nextProps, parentDom, lifecycle, context, isSVG, force, fromSetState) {
- var lastState = instance.state;
- var lastProps = instance.props;
- nextVNode.children = instance;
- var lastInput = instance.$LI;
- var renderOutput;
- if (instance.$UN) {
- {
- throwError('Inferno Error: Can only update a mounted or mounting component. This usually means you called setState() or forceUpdate() on an unmounted component. This is a no-op.');
- }
- return;
- }
- if (lastProps !== nextProps || nextProps === EMPTY_OBJ) {
- if (!fromSetState && isFunction(instance.componentWillReceiveProps)) {
- instance.$BR = true;
- instance.componentWillReceiveProps(nextProps, context);
- // If instance component was removed during its own update do nothing...
- if (instance.$UN) {
- return;
- }
- instance.$BR = false;
- }
- if (instance.$PSS) {
- nextState = combineFrom(nextState, instance.$PS);
- instance.$PSS = false;
- instance.$PS = null;
- }
- }
- /* Update if scu is not defined, or it returns truthy value or force */
- var hasSCU = isFunction(instance.shouldComponentUpdate);
- if (force || !hasSCU || (hasSCU && instance.shouldComponentUpdate(nextProps, nextState, context))) {
- if (isFunction(instance.componentWillUpdate)) {
- instance.$BS = true;
- instance.componentWillUpdate(nextProps, nextState, context);
- instance.$BS = false;
- }
- instance.props = nextProps;
- instance.state = nextState;
- instance.context = context;
- if (isFunction(options.beforeRender)) {
- options.beforeRender(instance);
- }
- renderOutput = instance.render(nextProps, nextState, context);
- if (isFunction(options.afterRender)) {
- options.afterRender(instance);
- }
- var didUpdate = renderOutput !== NO_OP;
- var childContext;
- if (isFunction(instance.getChildContext)) {
- childContext = instance.getChildContext();
- }
- if (isNullOrUndef(childContext)) {
- childContext = context;
- }
- else {
- childContext = combineFrom(context, childContext);
- }
- instance.$CX = childContext;
- if (didUpdate) {
- var nextInput = (instance.$LI = handleComponentInput(renderOutput, nextVNode));
- patch(lastInput, nextInput, parentDom, lifecycle, childContext, isSVG);
- if (isFunction(instance.componentDidUpdate)) {
- instance.componentDidUpdate(lastProps, lastState);
- }
- if (isFunction(options.afterUpdate)) {
- options.afterUpdate(nextVNode);
- }
- }
- }
- else {
- instance.props = nextProps;
- instance.state = nextState;
- instance.context = context;
- }
- nextVNode.dom = instance.$LI.dom;
- }
- function patchComponent(lastVNode, nextVNode, parentDom, lifecycle, context, isSVG, isClass) {
- var nextType = nextVNode.type;
- var lastKey = lastVNode.key;
- var nextKey = nextVNode.key;
- if (lastVNode.type !== nextType || lastKey !== nextKey) {
- replaceWithNewNode(lastVNode, nextVNode, parentDom, lifecycle, context, isSVG);
- }
- else {
- var nextProps = nextVNode.props || EMPTY_OBJ;
- if (isClass) {
- var instance = lastVNode.children;
- instance.$UPD = true;
- updateClassComponent(instance, instance.state, nextVNode, nextProps, parentDom, lifecycle, context, isSVG, false, false);
- instance.$V = nextVNode;
- instance.$UPD = false;
- }
- else {
- var shouldUpdate = true;
- var lastProps = lastVNode.props;
- var nextHooks = nextVNode.ref;
- var nextHooksDefined = !isNullOrUndef(nextHooks);
- var lastInput = lastVNode.children;
- nextVNode.dom = lastVNode.dom;
- nextVNode.children = lastInput;
- if (nextHooksDefined && isFunction(nextHooks.onComponentShouldUpdate)) {
- shouldUpdate = nextHooks.onComponentShouldUpdate(lastProps, nextProps);
- }
- if (shouldUpdate !== false) {
- if (nextHooksDefined && isFunction(nextHooks.onComponentWillUpdate)) {
- nextHooks.onComponentWillUpdate(lastProps, nextProps);
- }
- var nextInput = nextType(nextProps, context);
- if (nextInput !== NO_OP) {
- nextInput = handleComponentInput(nextInput, nextVNode);
- patch(lastInput, nextInput, parentDom, lifecycle, context, isSVG);
- nextVNode.children = nextInput;
- nextVNode.dom = nextInput.dom;
- if (nextHooksDefined && isFunction(nextHooks.onComponentDidUpdate)) {
- nextHooks.onComponentDidUpdate(lastProps, nextProps);
- }
- }
- }
- else if (lastInput.flags & 14 /* Component */) {
- lastInput.parentVNode = nextVNode;
- }
- }
- }
- }
- function patchText(lastVNode, nextVNode, parentDom) {
- var nextText = nextVNode.children;
- var textNode = parentDom.firstChild;
- var dom;
- // Guard against external change on DOM node.
- if (isNull(textNode)) {
- parentDom.textContent = nextText;
- dom = parentDom.firstChild;
- }
- else {
- dom = lastVNode.dom;
- if (nextText !== lastVNode.children) {
- dom.nodeValue = nextText;
- }
- }
- nextVNode.dom = dom;
- }
- function patchNonKeyedChildren(lastChildren, nextChildren, dom, lifecycle, context, isSVG, lastChildrenLength, nextChildrenLength) {
- var commonLength = lastChildrenLength > nextChildrenLength ? nextChildrenLength : lastChildrenLength;
- var i = 0;
- for (; i < commonLength; i++) {
- var nextChild = nextChildren[i];
- if (nextChild.dom) {
- nextChild = nextChildren[i] = directClone(nextChild);
- }
- patch(lastChildren[i], nextChild, dom, lifecycle, context, isSVG);
- }
- if (lastChildrenLength < nextChildrenLength) {
- for (i = commonLength; i < nextChildrenLength; i++) {
- var nextChild$1 = nextChildren[i];
- if (nextChild$1.dom) {
- nextChild$1 = nextChildren[i] = directClone(nextChild$1);
- }
- mount(nextChild$1, dom, lifecycle, context, isSVG);
- }
- }
- else if (lastChildrenLength > nextChildrenLength) {
- for (i = commonLength; i < lastChildrenLength; i++) {
- remove(lastChildren[i], dom);
- }
- }
- }
- function patchKeyedChildren(a, b, dom, lifecycle, 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];
- if (bStartNode.dom) {
- b[bStart] = bStartNode = directClone(bStartNode);
- }
- if (bEndNode.dom) {
- b[bEnd] = bEndNode = directClone(bEndNode);
- }
- // 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, lifecycle, context, isSVG);
- aStart++;
- bStart++;
- if (aStart > aEnd || bStart > bEnd) {
- break outer;
- }
- aStartNode = a[aStart];
- bStartNode = b[bStart];
- if (bStartNode.dom) {
- b[bStart] = bStartNode = directClone(bStartNode);
- }
- }
- // Sync nodes with the same key at the end.
- while (aEndNode.key === bEndNode.key) {
- patch(aEndNode, bEndNode, dom, lifecycle, context, isSVG);
- aEnd--;
- bEnd--;
- if (aStart > aEnd || bStart > bEnd) {
- break outer;
- }
- aEndNode = a[aEnd];
- bEndNode = b[bEnd];
- if (bEndNode.dom) {
- b[bEnd] = bEndNode = directClone(bEndNode);
- }
- }
- }
- if (aStart > aEnd) {
- if (bStart <= bEnd) {
- nextPos = bEnd + 1;
- nextNode = nextPos < bLength ? b[nextPos].dom : null;
- while (bStart <= bEnd) {
- node = b[bStart];
- if (node.dom) {
- b[bStart] = node = directClone(node);
- }
- bStart++;
- insertOrAppend(dom, mount(node, null, lifecycle, context, isSVG), nextNode);
- }
- }
- }
- else if (bStart > bEnd) {
- while (aStart <= aEnd) {
- remove(a[aStart++], dom);
- }
- }
- else {
- var aLeft = aEnd - aStart + 1;
- var bLeft = bEnd - bStart + 1;
- var sources = new Array(bLeft);
- 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;
- }
- if (bNode.dom) {
- b[j] = bNode = directClone(bNode);
- }
- patch(aNode, bNode, dom, lifecycle, context, isSVG);
- patched++;
- a[i] = null;
- break;
- }
- }
- }
- }
- }
- else {
- var keyIndex = {};
- // Map keys by their index in array
- for (i = bStart; i <= bEnd; i++) {
- keyIndex[b[i].key] = i;
- }
- // Try to patch same keys
- for (i = aStart; i <= aEnd; i++) {
- aNode = a[i];
- if (patched < bLeft) {
- j = keyIndex[aNode.key];
- if (isDefined(j)) {
- bNode = b[j];
- sources[j - bStart] = i;
- if (pos > j) {
- moved = true;
- }
- else {
- pos = j;
- }
- if (bNode.dom) {
- b[j] = bNode = directClone(bNode);
- }
- patch(aNode, bNode, dom, lifecycle, context, isSVG);
- patched++;
- a[i] = null;
- }
- }
- }
- }
- // fast-path: if nothing patched remove all old and add all new
- if (aLeft === aLength && patched === 0) {
- removeAllChildren(dom, a);
- mountArrayChildren(b, dom, lifecycle, context, isSVG);
- }
- else {
- i = aLeft - patched;
- while (i > 0) {
- aNode = a[aStart++];
- if (!isNull(aNode)) {
- remove(aNode, dom);
- i--;
- }
- }
- if (moved) {
- var seq = lis_algorithm(sources);
- j = seq.length - 1;
- for (i = bLeft - 1; i >= 0; i--) {
- if (sources[i] === -1) {
- pos = i + bStart;
- node = b[pos];
- if (node.dom) {
- b[pos] = node = directClone(node);
- }
- nextPos = pos + 1;
- insertOrAppend(dom, mount(node, null, lifecycle, context, isSVG), nextPos < bLength ? b[nextPos].dom : null);
- }
- else if (j < 0 || i !== seq[j]) {
- pos = i + bStart;
- node = b[pos];
- nextPos = pos + 1;
- insertOrAppend(dom, node.dom, nextPos < bLength ? b[nextPos].dom : null);
- }
- else {
- j--;
- }
- }
- }
- else if (patched !== bLeft) {
- // when patched count doesn't match b length we need to insert those new ones
- // loop backwards so we can use insertBefore
- for (i = bLeft - 1; i >= 0; i--) {
- if (sources[i] === -1) {
- pos = i + bStart;
- node = b[pos];
- if (node.dom) {
- b[pos] = node = directClone(node);
- }
- nextPos = pos + 1;
- insertOrAppend(dom, mount(node, null, lifecycle, context, isSVG), nextPos < bLength ? b[nextPos].dom : null);
- }
- }
- }
- }
- }
- }
- // // https://en.wikipedia.org/wiki/Longest_increasing_subsequence
- function lis_algorithm(arr) {
- var p = arr.slice();
- var result = [0];
- var i;
- var j;
- var u;
- var v;
- var c;
- var len = arr.length;
- for (i = 0; i < len; i++) {
- var arrI = arr[i];
- if (arrI !== -1) {
- j = result[result.length - 1];
- if (arr[j] < arrI) {
- p[i] = j;
- result.push(i);
- continue;
- }
- u = 0;
- v = result.length - 1;
- while (u < v) {
- c = ((u + v) / 2) | 0;
- if (arr[result[c]] < arrI) {
- u = c + 1;
- }
- else {
- v = c;
- }
- }
- if (arrI < arr[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;
- }
- var roots = options.roots;
- {
- if (isBrowser && document.body === null) {
- warning('Inferno warning: you cannot initialize inferno without "document.body". Wait on "DOMContentLoaded" event, add script to bottom of body, or use async/defer attributes on script tag.');
- }
- }
- var documentBody = isBrowser ? document.body : null;
- function render(input, parentDom, callback) {
- // Development warning
- {
- if (documentBody === parentDom) {
- throwError('you cannot render() to the "document.body". Use an empty element as a container instead.');
- }
- }
- if (input === NO_OP) {
- return;
- }
- var rootLen = roots.length;
- var rootInput;
- var index;
- for (index = 0; index < rootLen; index++) {
- if (roots[index] === parentDom) {
- rootInput = parentDom.$V;
- break;
- }
- }
- if (isUndefined(rootInput)) {
- if (!isInvalid(input)) {
- if (input.dom) {
- input = directClone(input);
- }
- if (isNull(parentDom.firstChild)) {
- mount(input, parentDom, LIFECYCLE, EMPTY_OBJ, false);
- parentDom.$V = input;
- roots.push(parentDom);
- }
- else {
- hydrate(input, parentDom);
- }
- rootInput = input;
- }
- }
- else {
- if (isNullOrUndef(input)) {
- remove(rootInput, parentDom);
- roots.splice(index, 1);
- }
- else {
- if (input.dom) {
- input = directClone(input);
- }
- patch(rootInput, input, parentDom, LIFECYCLE, EMPTY_OBJ, false);
- rootInput = parentDom.$V = input;
- }
- }
- if (LIFECYCLE.length > 0) {
- callAll(LIFECYCLE);
- }
- if (isFunction(callback)) {
- callback();
- }
- if (rootInput && rootInput.flags & 14 /* Component */) {
- return rootInput.children;
- }
- }
- function createRenderer(parentDom) {
- return function renderer(lastInput, nextInput) {
- if (!parentDom) {
- parentDom = lastInput;
- }
- render(nextInput, parentDom);
- };
- }
- function createPortal(children, container) {
- return createVNode(1024 /* Portal */, container, null, children, 0 /* UnknownChildren */, null, isInvalid(children) ? null : children.key, null);
- }
- var resolvedPromise = typeof Promise === 'undefined' ? null : Promise.resolve();
- var fallbackMethod = typeof requestAnimationFrame === 'undefined' ? setTimeout : requestAnimationFrame;
- function nextTick(fn) {
- if (resolvedPromise) {
- return resolvedPromise.then(fn);
- }
- return fallbackMethod(fn);
- }
- function queueStateChanges(component, newState, callback) {
- if (isFunction(newState)) {
- newState = newState(component.state, component.props, component.context);
- }
- var pending = component.$PS;
- if (isNullOrUndef(pending)) {
- component.$PS = newState;
- }
- else {
- for (var stateKey in newState) {
- pending[stateKey] = newState[stateKey];
- }
- }
- if (!component.$PSS && !component.$BR) {
- if (!component.$UPD) {
- component.$PSS = true;
- component.$UPD = true;
- applyState(component, false, callback);
- component.$UPD = false;
- }
- else {
- // Async
- var queue = component.$QU;
- if (isNull(queue)) {
- queue = component.$QU = [];
- nextTick(promiseCallback(component, queue));
- }
- if (isFunction(callback)) {
- queue.push(callback);
- }
- }
- }
- else {
- component.$PSS = true;
- if (component.$BR && isFunction(callback)) {
- LIFECYCLE.push(callback.bind(component));
- }
- }
- }
- function promiseCallback(component, queue) {
- return function () {
- component.$QU = null;
- component.$UPD = true;
- applyState(component, false, function () {
- for (var i = 0, len = queue.length; i < len; i++) {
- queue[i].call(component);
- }
- });
- component.$UPD = false;
- };
- }
- function applyState(component, force, callback) {
- if (component.$UN) {
- return;
- }
- if (force || !component.$BR) {
- component.$PSS = false;
- var pendingState = component.$PS;
- var prevState = component.state;
- var nextState = combineFrom(prevState, pendingState);
- var props = component.props;
- var context = component.context;
- component.$PS = null;
- var vNode = component.$V;
- var lastInput = component.$LI;
- var parentDom = lastInput.dom && lastInput.dom.parentNode;
- updateClassComponent(component, nextState, vNode, props, parentDom, LIFECYCLE, context, (vNode.flags & 32 /* SvgElement */) > 0, force, true);
- if (component.$UN) {
- return;
- }
- if ((component.$LI.flags & 1024 /* Portal */) === 0) {
- var dom = component.$LI.dom;
- while (!isNull((vNode = vNode.parentVNode))) {
- if ((vNode.flags & 14 /* Component */) > 0) {
- vNode.dom = dom;
- }
- }
- }
- if (LIFECYCLE.length > 0) {
- callAll(LIFECYCLE);
- }
- }
- else {
- component.state = component.$PS;
- component.$PS = null;
- }
- if (isFunction(callback)) {
- callback.call(component);
- }
- }
- var Component = function Component(props, context) {
- this.state = null;
- // Internal properties
- this.$BR = false; // BLOCK RENDER
- this.$BS = true; // BLOCK STATE
- this.$PSS = false; // PENDING SET STATE
- this.$PS = null; // PENDING STATE (PARTIAL or FULL)
- this.$LI = null; // LAST INPUT
- this.$V = null; // VNODE
- this.$UN = false; // UNMOUNTED
- this.$CX = null; // CHILDCONTEXT
- this.$UPD = true; // UPDATING
- this.$QU = null; // QUEUE
- /** @type {object} */
- this.props = props || EMPTY_OBJ;
- /** @type {object} */
- this.context = context || EMPTY_OBJ; // context should not be mutable
- };
- Component.prototype.forceUpdate = function forceUpdate (callback) {
- if (this.$UN) {
- return;
- }
- applyState(this, true, callback);
- };
- Component.prototype.setState = function setState (newState, callback) {
- if (this.$UN) {
- return;
- }
- if (!this.$BS) {
- queueStateChanges(this, newState, callback);
- }
- else {
- // Development warning
- {
- throwError('cannot update state via setState() in componentWillUpdate() or constructor.');
- }
- return;
- }
- };
- // tslint:disable-next-line:no-empty
- Component.prototype.render = function render (nextProps, nextState, nextContext) { };
- // Public
- Component.defaultProps = null;
- {
- /* tslint:disable-next-line:no-empty */
- var testFunc = function testFn() { };
- if ((testFunc.name || testFunc.toString()).indexOf('testFn') === -1) {
- warning("It looks like you're using a minified copy of the development build " +
- 'of Inferno. When deploying Inferno apps to production, make sure to use ' +
- 'the production build which skips development warnings and is faster. ' +
- 'See http://infernojs.org for more details.');
- }
- }
- var version = "4.0.4";
- exports.Component = Component;
- exports.EMPTY_OBJ = EMPTY_OBJ;
- exports.NO_OP = NO_OP;
- exports.createComponentVNode = createComponentVNode;
- exports.createPortal = createPortal;
- exports.createRenderer = createRenderer;
- exports.createTextVNode = createTextVNode;
- exports.createVNode = createVNode;
- exports.directClone = directClone;
- exports.getFlagsForElementVnode = getFlagsForElementVnode;
- exports.getNumberStyleValue = getNumberStyleValue;
- exports.hydrate = hydrate;
- exports.linkEvent = linkEvent;
- exports.normalizeProps = normalizeProps;
- exports.options = options;
- exports.render = render;
- exports.version = version;
- Object.defineProperty(exports, '__esModule', { value: true });
- })));
|