UNPKG

inferno

Version:

An extremely fast, React-like JavaScript library for building modern user interfaces

1,324 lines (1,307 loc) 102 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Inferno = global.Inferno || {})); })(this, (function (exports) { 'use strict'; var ERROR_MSG = 'a runtime error occured! Use Inferno in development environment to find the error.'; var isArray = Array.isArray; function isStringOrNumber(o) { var type = typeof o; return type === 'string' || type === 'number'; } function isNullOrUndef(o) { return o === void 0 || o === null; } function isInvalid(o) { return o === null || o === false || o === true || o === void 0; } 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 isUndefined(o) { return o === void 0; } function throwError(message) { if (!message) { message = ERROR_MSG; } throw new Error("Inferno Error: " + message); } function warning(message) { console.error(message); } /** * 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 } // object.event should always be function, otherwise its badly created object. function isLinkEventObject(o) { return !isNull(o) && typeof o === 'object'; } function _extends$4() { return _extends$4 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$4.apply(null, arguments); } // We need EMPTY_OBJ defined in one place. // It's used for comparison, so we can't inline it into shared var EMPTY_OBJ = {}; // @ts-expect-error hack for fragment type var Fragment = '$F'; var AnimationQueues = function AnimationQueues() { this.componentDidAppear = []; this.componentWillDisappear = []; this.componentWillMove = []; }; { Object.freeze(EMPTY_OBJ); } function normalizeEventName(name) { return name.substring(2).toLowerCase(); } function appendChild(parentDOM, dom) { parentDOM.appendChild(dom); } function insertOrAppend(parentDOM, newNode, nextNode) { if (isNull(nextNode)) { appendChild(parentDOM, newNode); } else { parentDOM.insertBefore(newNode, nextNode); } } function documentCreateElement(tag, isSVG) { if (isSVG) { return document.createElementNS('http://www.w3.org/2000/svg', tag); } return document.createElement(tag); } function replaceChild(parentDOM, newDom, lastDom) { parentDOM.replaceChild(newDom, lastDom); } function removeChild(parentDOM, childNode) { parentDOM.removeChild(childNode); } function callAll(arrayFn) { for (var i = 0; i < arrayFn.length; i++) { arrayFn[i](); } } function findChildVNode(vNode, startEdge, flags) { var children = vNode.children; if ((flags & 4 /* VNodeFlags.ComponentClass */) !== 0) { return children.$LI; } if ((flags & 8192 /* VNodeFlags.Fragment */) !== 0) { return vNode.childFlags === 2 /* ChildFlags.HasVNodeChildren */ ? children : children[startEdge ? 0 : children.length - 1]; } return children; } function findDOMFromVNode(vNode, startEdge) { var flags; var v = vNode; while (!isNullOrUndef(v)) { flags = v.flags; if ((flags & 1521 /* VNodeFlags.DOMRef */) !== 0) { return v.dom; } v = findChildVNode(v, startEdge, flags); } return null; } function callAllAnimationHooks(animationQueue, callback) { var animationsLeft = animationQueue.length; // Picking from the top because it is faster, invocation order should be irrelevant // since all animations are to be run, and we can't predict the order in which they complete. var fn; while ((fn = animationQueue.pop()) !== undefined) { fn(function () { if (--animationsLeft <= 0 && isFunction(callback)) { callback(); } }); } } function callAllMoveAnimationHooks(animationQueue) { // Start the animations. for (var i = 0; i < animationQueue.length; i++) { animationQueue[i].fn(); } // Perform the actual DOM moves when all measurements of initial // position have been performed. The rest of the animations are done // async. for (var _i = 0; _i < animationQueue.length; _i++) { var tmp = animationQueue[_i]; insertOrAppend(tmp.parent, tmp.dom, tmp.next); } animationQueue.splice(0, animationQueue.length); } function clearVNodeDOM(vNode, parentDOM, deferredRemoval) { while (!isNullOrUndef(vNode)) { var flags = vNode.flags; if ((flags & 1521 /* VNodeFlags.DOMRef */) !== 0) { // On deferred removals the node might disappear because of later operations if (!deferredRemoval || vNode.dom.parentNode === parentDOM) { removeChild(parentDOM, vNode.dom); } return; } var children = vNode.children; if ((flags & 4 /* VNodeFlags.ComponentClass */) !== 0) { vNode = children.$LI; } if ((flags & 8 /* VNodeFlags.ComponentFunction */) !== 0) { vNode = children; } if ((flags & 8192 /* VNodeFlags.Fragment */) !== 0) { if (vNode.childFlags === 2 /* ChildFlags.HasVNodeChildren */) { vNode = children; } else { for (var i = 0, len = children.length; i < len; ++i) { clearVNodeDOM(children[i], parentDOM, false); } return; } } } } function createDeferComponentClassRemovalCallback(vNode, parentDOM) { return function () { // Mark removal as deferred to trigger check that node still exists clearVNodeDOM(vNode, parentDOM, true); }; } function removeVNodeDOM(vNode, parentDOM, animations) { if (animations.componentWillDisappear.length > 0) { // Wait until animations are finished before removing actual dom nodes callAllAnimationHooks(animations.componentWillDisappear, createDeferComponentClassRemovalCallback(vNode, parentDOM)); } else { clearVNodeDOM(vNode, parentDOM, false); } } function addMoveAnimationHook(animations, parentVNode, refOrInstance, dom, parentDOM, nextNode, flags, props) { animations.componentWillMove.push({ dom: dom, fn: function fn() { if ((flags & 4 /* VNodeFlags.ComponentClass */) !== 0) { refOrInstance.componentWillMove(parentVNode, parentDOM, dom); } else if ((flags & 8 /* VNodeFlags.ComponentFunction */) !== 0) { refOrInstance.onComponentWillMove(parentVNode, parentDOM, dom, props); } }, next: nextNode, parent: parentDOM }); } function moveVNodeDOM(parentVNode, vNode, parentDOM, nextNode, animations) { var refOrInstance; var instanceProps; var instanceFlags = vNode.flags; while (!isNullOrUndef(vNode)) { var flags = vNode.flags; if ((flags & 1521 /* VNodeFlags.DOMRef */) !== 0) { if (!isNullOrUndef(refOrInstance) && (isFunction(refOrInstance.componentWillMove) || isFunction(refOrInstance.onComponentWillMove))) { addMoveAnimationHook(animations, parentVNode, refOrInstance, vNode.dom, parentDOM, nextNode, instanceFlags, instanceProps); } else { // TODO: Should we delay this too to support mixing animated moves with regular? insertOrAppend(parentDOM, vNode.dom, nextNode); } return; } var children = vNode.children; if ((flags & 4 /* VNodeFlags.ComponentClass */) !== 0) { refOrInstance = vNode.children; // TODO: We should probably deprecate this in V9 since it is inconsitent with other class component hooks instanceProps = vNode.props; vNode = children.$LI; } else if ((flags & 8 /* VNodeFlags.ComponentFunction */) !== 0) { refOrInstance = vNode.ref; instanceProps = vNode.props; vNode = children; } else if ((flags & 8192 /* VNodeFlags.Fragment */) !== 0) { if (vNode.childFlags === 2 /* ChildFlags.HasVNodeChildren */) { vNode = children; } else { for (var i = 0, len = children.length; i < len; ++i) { moveVNodeDOM(parentVNode, children[i], parentDOM, nextNode, animations); } return; } } } } function getComponentName(instance) { var _ref, _ref2, _instance$name; // TODO: Fallback for IE return (_ref = (_ref2 = (_instance$name = instance.name) != null ? _instance$name : instance.displayName) != null ? _ref2 : instance.constructor.name) != null ? _ref : (instance.toString().match(/^function\s*([^\s(]+)/) || [])[1]; } function createDerivedState(instance, nextProps, state) { if (isFunction(instance.constructor.getDerivedStateFromProps)) { return _extends$4({}, state, instance.constructor.getDerivedStateFromProps(nextProps, state)); } return state; } var renderCheck = { v: false }; var options = { createVNode: null }; function setTextContent(dom, children) { dom.textContent = children; } // Calling this function assumes, nextValue is linkEvent function isLastValueSameLinkEvent(lastValue, nextValue) { return isLinkEventObject(lastValue) && lastValue.event === nextValue.event && lastValue.data === nextValue.data; } function mergeUnsetProperties(to, from) { for (var propName in from) { // @ts-expect-error merge objects if (isUndefined(to[propName])) { // @ts-expect-error merge objects to[propName] = from[propName]; } } // @ts-expect-error merge objects return to; } function safeCall1(method, arg1) { return isFunction(method) && (method(arg1), true); } 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 /* VNodeFlags.Element */) { tagName = "<" + input.type + (input.className ? ' class="' + input.className + '"' : '') + ">"; } else if (flags & 16 /* VNodeFlags.Text */) { tagName = "Text(" + input.children + ")"; } else if (flags & 1024 /* VNodeFlags.Portal */) { tagName = "Portal*"; } else { tagName = "<" + getComponentName(input.type) + " />"; } } return '>> ' + tagName + '\n'; } function DEV_VALIDATE_KEYS(vNodeTree, 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 (Object.keys(foundKeys).length !== 0) { return 'Encountered invalid node with mixed keys. Location: \n' + getTagName(childNode); } continue; } if (typeof childNode === 'object') { if (childNode.isValidated) { continue; } childNode.isValidated = true; } // Key can be undefined, null too. But typescript complains for no real reason 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 /* ChildFlags.MultipleChildren */) { val = DEV_VALIDATE_KEYS(children, (childFlags & 8 /* ChildFlags.HasKeyedChildren */) !== 0); } else if (childFlags === 2 /* ChildFlags.HasVNodeChildren */) { val = DEV_VALIDATE_KEYS([children], false); } 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 (Object.keys(foundKeys).length !== 0) { return 'Encountered children with key missing. Location: \n' + getTagName(childNode); } continue; } if (foundKeys[key]) { return 'Encountered two children with same key: {' + key + '}. Location: \n' + getTagName(childNode); } foundKeys[key] = true; } return null; } function validateVNodeElementChildren(vNode) { { if (vNode.childFlags === 1 /* ChildFlags.HasInvalidChildren */) { return; } if (vNode.flags & 64 /* VNodeFlags.InputElement */) { throwError("input elements can't have children."); } if (vNode.flags & 128 /* VNodeFlags.TextareaElement */) { throwError("textarea elements can't have children."); } if (vNode.flags & 481 /* VNodeFlags.Element */) { var voidTypes = { area: true, base: true, br: true, col: true, command: true, embed: true, hr: true, img: true, input: true, keygen: true, link: true, meta: true, param: true, source: true, track: true, wbr: true }; var tag = vNode.type.toLowerCase(); if (tag === 'media') { throwError("media elements can't have children."); } if (voidTypes[tag]) { throwError(tag + " elements can't have children."); } } } } function validateKeys(vNode) { { // Checks if there is any key missing or duplicate keys if (!vNode.isValidated && vNode.children && vNode.flags & 481 /* VNodeFlags.Element */) { var error = DEV_VALIDATE_KEYS(Array.isArray(vNode.children) ? vNode.children : [vNode.children], (vNode.childFlags & 8 /* ChildFlags.HasKeyedChildren */) > 0); if (error) { throwError(error + getTagName(vNode)); } } vNode.isValidated = true; } } function throwIfObjectIsNotVNode(input) { if (!isNumber(input.flags)) { throwError("normalization received an object that's not a valid VNode, you should stringify it first or fix createVNode flags. Object: \"" + JSON.stringify(input) + "\"."); } } function _extends$3() { return _extends$3 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$3.apply(null, arguments); } var keyPrefix = '$'; function V(childFlags, children, className, flags, key, props, ref, type) { { this.isValidated = false; } this.childFlags = childFlags; this.children = children; this.className = className; this.dom = null; this.flags = flags; this.key = key === void 0 ? null : key; this.props = props === void 0 ? null : props; this.ref = ref === void 0 ? null : ref; this.type = type; } function createVNode(flags, type, className, children, childFlags, props, key, ref) { { if (flags & 14 /* VNodeFlags.Component */) { throwError('Creating Component vNodes using createVNode is not allowed. Use Inferno.createComponentVNode method.'); } } var childFlag = childFlags === void 0 ? 1 /* ChildFlags.HasInvalidChildren */ : childFlags; var vNode = new V(childFlag, children, className, flags, key, props, ref, type); if (options.createVNode) { options.createVNode(vNode); } if (childFlag === 0 /* ChildFlags.UnknownChildren */) { normalizeChildren(vNode, vNode.children); } { validateVNodeElementChildren(vNode); } return vNode; } function mergeDefaultHooks(flags, type, ref) { if (flags & 4 /* VNodeFlags.ComponentClass */) { return ref; } var defaultHooks = (flags & 32768 /* VNodeFlags.ForwardRef */ ? type.render : type).defaultHooks; if (isNullOrUndef(defaultHooks)) { return ref; } if (isNullOrUndef(ref)) { return defaultHooks; } return mergeUnsetProperties(ref, defaultHooks); } function mergeDefaultProps(flags, type, props) { // set default props var defaultProps = (flags & 32768 /* VNodeFlags.ForwardRef */ ? type.render : type).defaultProps; if (isNullOrUndef(defaultProps)) { return props; } if (isNullOrUndef(props)) { return _extends$3({}, defaultProps); } return mergeUnsetProperties(props, defaultProps); } function resolveComponentFlags(flags, type) { var _type$prototype; if (flags & 12 /* VNodeFlags.ComponentKnown */) { return flags; } if ((_type$prototype = type.prototype) != null && _type$prototype.render) { return 4 /* VNodeFlags.ComponentClass */; } if (type.render) { return 32776 /* VNodeFlags.ForwardRefComponent */; } return 8 /* VNodeFlags.ComponentFunction */; } function createComponentVNode(flags, type, props, key, ref) { { if ((flags & 1 /* VNodeFlags.HtmlElement */) !== 0) { throwError('Creating element vNodes using createComponentVNode is not allowed. Use Inferno.createVNode method.'); } } flags = resolveComponentFlags(flags, type); var vNode = new V(1 /* ChildFlags.HasInvalidChildren */, null, null, flags, key, mergeDefaultProps(flags, type, props), mergeDefaultHooks(flags, type, ref), type); if (isFunction(options.createVNode)) { options.createVNode(vNode); } return vNode; } function createTextVNode(text, key) { return new V(1 /* ChildFlags.HasInvalidChildren */, isNullOrUndef(text) || text === true || text === false ? '' : text, null, 16 /* VNodeFlags.Text */, key, null, null, null); } function createFragment(children, childFlags, key) { var fragment = createVNode(8192 /* VNodeFlags.Fragment */, 8192 /* VNodeFlags.Fragment */, null, children, childFlags, null, key, null); switch (fragment.childFlags) { case 1 /* ChildFlags.HasInvalidChildren */: fragment.children = createVoidVNode(); fragment.childFlags = 2 /* ChildFlags.HasVNodeChildren */; break; case 16 /* ChildFlags.HasTextChildren */: fragment.children = [createTextVNode(children)]; fragment.childFlags = 4 /* ChildFlags.HasNonKeyedChildren */; break; } return fragment; } function normalizeProps(vNode) { var props = vNode.props; if (props) { var flags = vNode.flags; if (flags & 481 /* VNodeFlags.Element */) { if (props.children !== void 0 && isNullOrUndef(vNode.children)) { normalizeChildren(vNode, props.children); } if (props.className !== void 0) { if (isNullOrUndef(vNode.className)) { vNode.className = props.className || null; } props.className = undefined; } } if (props.key !== void 0) { vNode.key = props.key; props.key = undefined; } if (props.ref !== void 0) { if (flags & 8 /* VNodeFlags.ComponentFunction */) { vNode.ref = _extends$3({}, vNode.ref, props.ref); } else { vNode.ref = props.ref; } props.ref = undefined; } } return vNode; } /* * Fragment is different from normal vNode, * because when it needs to be cloned we need to clone its children too * But not normalize, because otherwise those possibly get KEY and re-mount */ function cloneFragment(vNodeToClone) { var oldChildren = vNodeToClone.children; var childFlags = vNodeToClone.childFlags; return createFragment(childFlags === 2 /* ChildFlags.HasVNodeChildren */ ? directClone(oldChildren) : oldChildren.map(directClone), childFlags, vNodeToClone.key); } function directClone(vNodeToClone) { var flags = vNodeToClone.flags & -16385 /* VNodeFlags.ClearInUse */; var props = vNodeToClone.props; if (flags & 14 /* VNodeFlags.Component */) { if (!isNull(props)) { var propsToClone = props; props = {}; for (var key in propsToClone) { props[key] = propsToClone[key]; } } } if ((flags & 8192 /* VNodeFlags.Fragment */) === 0) { return new V(vNodeToClone.childFlags, vNodeToClone.children, vNodeToClone.className, flags, vNodeToClone.key, props, vNodeToClone.ref, vNodeToClone.type); } return cloneFragment(vNodeToClone); } function createVoidVNode() { return createTextVNode('', null); } function createPortal(children, container) { var normalizedRoot = normalizeRoot(children); return createVNode(1024 /* VNodeFlags.Portal */, 1024 /* VNodeFlags.Portal */, null, normalizedRoot, 0 /* ChildFlags.UnknownChildren */, null, normalizedRoot.key, container); } 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 { { throwIfObjectIsNotVNode(n); } var oldKey = n.key; var isPrefixedKey = isString(oldKey) && oldKey[0] === keyPrefix; if (n.flags & 81920 /* VNodeFlags.InUseOrNormalized */ || isPrefixedKey) { n = directClone(n); } n.flags |= 65536 /* VNodeFlags.Normalized */; if (!isPrefixedKey) { if (isNull(oldKey)) { n.key = newKey; } else { n.key = currentKey + oldKey; } } else if (oldKey.substring(0, currentKey.length) !== currentKey) { n.key = currentKey + oldKey; } } result.push(n); } } } } function getFlagsForElementVnode(type) { switch (type) { case 'svg': return 32 /* VNodeFlags.SvgElement */; case 'input': return 64 /* VNodeFlags.InputElement */; case 'select': return 256 /* VNodeFlags.SelectElement */; case 'textarea': return 128 /* VNodeFlags.TextareaElement */; // @ts-expect-error Fragment is special case case Fragment: return 8192 /* VNodeFlags.Fragment */; default: return 1 /* VNodeFlags.HtmlElement */; } } function normalizeChildren(vNode, children) { var newChildren; var newChildFlags = 1 /* ChildFlags.HasInvalidChildren */; // Don't change children to match strict equal (===) true in patching if (isInvalid(children)) { newChildren = children; } else if (isStringOrNumber(children)) { newChildFlags = 16 /* ChildFlags.HasTextChildren */; newChildren = children; } else if (isArray(children)) { var len = children.length; 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 { { throwIfObjectIsNotVNode(n); } var key = n.key; var needsCloning = (n.flags & 81920 /* VNodeFlags.InUseOrNormalized */) > 0; var isNullKey = isNull(key); var isPrefixed = isString(key) && key[0] === keyPrefix; if (needsCloning || isNullKey || isPrefixed) { newChildren = newChildren || children.slice(0, i); if (needsCloning || isPrefixed) { n = directClone(n); } if (isNullKey || isPrefixed) { n.key = keyPrefix + i; } newChildren.push(n); } else if (newChildren) { newChildren.push(n); } n.flags |= 65536 /* VNodeFlags.Normalized */; } } newChildren = newChildren || children; if (newChildren.length === 0) { newChildFlags = 1 /* ChildFlags.HasInvalidChildren */; } else { newChildFlags = 8 /* ChildFlags.HasKeyedChildren */; } } else { newChildren = children; newChildren.flags |= 65536 /* VNodeFlags.Normalized */; if (children.flags & 81920 /* VNodeFlags.InUseOrNormalized */) { newChildren = directClone(children); } newChildFlags = 2 /* ChildFlags.HasVNodeChildren */; } vNode.children = newChildren; vNode.childFlags = newChildFlags; return vNode; } function normalizeRoot(input) { if (isInvalid(input) || isStringOrNumber(input)) { return createTextVNode(input, null); } if (isArray(input)) { return createFragment(input, 0 /* ChildFlags.UnknownChildren */, null); } return input.flags & 16384 /* VNodeFlags.InUse */ ? directClone(input) : input; } var xlinkNS = 'http://www.w3.org/1999/xlink'; var xmlNS = 'http://www.w3.org/XML/1998/namespace'; 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 }; function getDelegatedEventObject(v) { return { onClick: v, onDblClick: v, onFocusIn: v, onFocusOut: v, onKeyDown: v, onKeyPress: v, onKeyUp: v, onMouseDown: v, onMouseMove: v, onMouseUp: v, onTouchEnd: v, onTouchMove: v, onTouchStart: v }; } var attachedEventCounts = getDelegatedEventObject(0); var attachedEvents = getDelegatedEventObject(null); var syntheticEvents = getDelegatedEventObject(true); function updateOrAddSyntheticEvent(name, dom) { var eventsObject = dom.$EV; if (!eventsObject) { eventsObject = dom.$EV = getDelegatedEventObject(null); } if (!eventsObject[name]) { if (++attachedEventCounts[name] === 1) { attachedEvents[name] = attachEventToDocument(name); } } return eventsObject; } function unmountSyntheticEvent(name, dom) { var eventsObject = dom.$EV; if (eventsObject != null && eventsObject[name]) { if (--attachedEventCounts[name] === 0) { document.removeEventListener(normalizeEventName(name), attachedEvents[name]); attachedEvents[name] = null; } eventsObject[name] = null; } } function handleSyntheticEvent(name, lastEvent, nextEvent, dom) { if (isFunction(nextEvent)) { updateOrAddSyntheticEvent(name, dom)[name] = nextEvent; } else if (isLinkEventObject(nextEvent)) { if (isLastValueSameLinkEvent(lastEvent, nextEvent)) { return; } updateOrAddSyntheticEvent(name, dom)[name] = nextEvent; } else { unmountSyntheticEvent(name, dom); } } // TODO: When browsers fully support event.composedPath we could loop it through instead of using parentNode property function getTargetNode(event) { return isFunction(event.composedPath) ? event.composedPath()[0] : event.target; } function dispatchEvents(event, isClick, name, eventData) { var dom = getTargetNode(event); do { // 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 (!isNullOrUndef(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; } while (!isNull(dom)); } function stopPropagation() { this.cancelBubble = true; if (!this.immediatePropagationStopped) { this.stopImmediatePropagation(); } } function isDefaultPrevented() { return this.defaultPrevented; } function isPropagationStopped() { return this.cancelBubble; } function extendEventProperties(event) { // Event data needs to be an object to save reference to currentTarget getter var eventData = { dom: document }; event.isDefaultPrevented = isDefaultPrevented; event.isPropagationStopped = isPropagationStopped; event.stopPropagation = stopPropagation; Object.defineProperty(event, 'currentTarget', { configurable: true, get: function get() { return eventData.dom; } }); return eventData; } function rootEvent(name) { var isClick = name === 'onClick' || name === 'onDblClick'; return function (event) { dispatchEvents(event, isClick, name, extendEventProperties(event)); }; } function attachEventToDocument(name) { var attachedEvent = rootEvent(name); document.addEventListener(normalizeEventName(name), attachedEvent); return attachedEvent; } function isSameInnerHTML(dom, innerHTML) { var temp = document.createElement('i'); temp.innerHTML = innerHTML; return temp.innerHTML === dom.innerHTML; } function triggerEventListener(props, methodName, e) { var listener = props[methodName]; if (listener) { if (listener.event) { listener.event(listener.data, e); } else { listener(e); } } else { var nativeListenerName = methodName.toLowerCase(); if (isFunction(props[nativeListenerName])) { props[nativeListenerName](e); } } } function createWrappedFunction(methodName, applyValue) { var fnWrapper = function fnWrapper(e) { var _vNode$props; var vNode = this.$V; // If vNode is gone by the time event fires, no-op if (isNullOrUndef(vNode)) { return; } var props = (_vNode$props = vNode.props) != null ? _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$props; var newVNode = this.$V; var newProps = (_newVNode$props = newVNode.props) != null ? _newVNode$props : EMPTY_OBJ; applyValue(newProps, dom, false, newVNode); } }; Object.defineProperty(fnWrapper, 'wrapped', { configurable: false, enumerable: false, value: true, writable: false }); return fnWrapper; } function attachEvent(dom, eventName, handler) { var previousKey = "$" + eventName; var previousArgs = dom[previousKey]; if (previousArgs) { if (previousArgs[1].wrapped) { return; } dom.removeEventListener(previousArgs[0], previousArgs[1]); dom[previousKey] = null; } if (isFunction(handler)) { dom.addEventListener(eventName, handler); dom[previousKey] = [eventName, handler]; } } function isCheckedType(type) { return type === 'checkbox' || type === 'radio'; } var onTextInputChange = createWrappedFunction('onInput', applyValueInput); var wrappedOnChange$1 = createWrappedFunction(['onClick', 'onChange'], applyValueInput); function stopPropagationWrapper(event) { event.stopPropagation(); } stopPropagationWrapper.wrapped = true; function inputEvents(dom, nextPropsOrEmpty) { if (isCheckedType(nextPropsOrEmpty.type)) { attachEvent(dom, 'change', wrappedOnChange$1); attachEvent(dom, 'click', stopPropagationWrapper); } else { attachEvent(dom, 'input', 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 != null && type !== dom.type) { dom.setAttribute('type', type); } if (!isNullOrUndef(multiple) && multiple !== dom.multiple) { dom.multiple = multiple; } if (!isNullOrUndef(defaultValue) && !hasValue) { if (defaultValue !== dom.value) { dom.value = defaultValue + ''; } 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 updateChildOptions(vNode, value) { if (vNode.type === 'option') { updateChildOption(vNode, value); } else { var children = vNode.children; var flags = vNode.flags; if ((flags & 4 /* VNodeFlags.ComponentClass */) !== 0) { updateChildOptions(children.$LI, value); } else if ((flags & 8 /* VNodeFlags.ComponentFunction */) !== 0) { updateChildOptions(children, value); } else if (vNode.childFlags === 2 /* ChildFlags.HasVNodeChildren */) { updateChildOptions(children, value); } else if ((vNode.childFlags & 12 /* ChildFlags.MultipleChildren */) !== 0) { for (var i = 0, len = children.length; i < len; ++i) { updateChildOptions(children[i], value); } } } } function updateChildOption(vNode, value) { var _vNode$props; var props = (_vNode$props = vNode.props) != null ? _vNode$props : EMPTY_OBJ; var propsValue = props.value; var dom = vNode.dom; // we do this as multiple prop may have changed dom.value = propsValue; if (propsValue === value || isArray(value) && value.includes(propsValue)) { dom.selected = true; } else if (!isNullOrUndef(value) || !isNullOrUndef(props.selected)) { dom.selected = Boolean(props.selected); } } var onSelectChange = createWrappedFunction('onChange', applyValueSelect); function selectEvents(dom) { attachEvent(dom, 'change', onSelectChange); } function applyValueSelect(nextPropsOrEmpty, dom, mounting, vNode) { var multiplePropInBoolean = Boolean(nextPropsOrEmpty.multiple); if (!isNullOrUndef(nextPropsOrEmpty.multiple) && multiplePropInBoolean !== dom.multiple) { dom.multiple = multiplePropInBoolean; } var index = nextPropsOrEmpty.selectedIndex; if (index === -1) { dom.selectedIndex = -1; } var childFlags = vNode.childFlags; if (childFlags !== 1 /* ChildFlags.HasInvalidChildren */) { var value = nextPropsOrEmpty.value; if (isNumber(index) && index > -1 && !isNullOrUndef(dom.options[index])) { value = dom.options[index].value; } if (mounting && isNullOrUndef(value)) { value = nextPropsOrEmpty.defaultValue; } updateChildOptions(vNode, value); } } var onTextareaInputChange = createWrappedFunction('onInput', applyValueTextArea); var wrappedOnChange = createWrappedFunction('onChange'); function textAreaEvents(dom, nextPropsOrEmpty) { attachEvent(dom, 'input', onTextareaInputChange); if (isFunction(nextPropsOrEmpty.onChange)) { attachEvent(dom, 'change', wrappedOnChange); } } 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; } } function processElement(flags, vNode, dom, nextPropsOrEmpty, mounting, isControlled) { if ((flags & 64 /* VNodeFlags.InputElement */) !== 0) { applyValueInput(nextPropsOrEmpty, dom); } else if ((flags & 256 /* VNodeFlags.SelectElement */) !== 0) { applyValueSelect(nextPropsOrEmpty, dom, mounting, vNode); } else if ((flags & 128 /* VNodeFlags.TextareaElement */) !== 0) { applyValueTextArea(nextPropsOrEmpty, dom, mounting); } if (isControlled) { dom.$V = vNode; } } function addFormElementEventHandlers(flags, dom, nextPropsOrEmpty) { if ((flags & 64 /* VNodeFlags.InputElement */) !== 0) { inputEvents(dom, nextPropsOrEmpty); } else if ((flags & 256 /* VNodeFlags.SelectElement */) !== 0) { selectEvents(dom); } else if ((flags & 128 /* VNodeFlags.TextareaElement */) !== 0) { textAreaEvents(dom, nextPropsOrEmpty); } } function isControlledFormElement(nextPropsOrEmpty) { return isCheckedType(nextPropsOrEmpty.type) ? !isNullOrUndef(nextPropsOrEmpty.checked) : !isNullOrUndef(nextPropsOrEmpty.value); } function createRef() { return { current: null }; } // TODO: Make this return value typed function forwardRef(render) { { if (!isFunction(render)) { warning("forwardRef requires a render function but was given " + (render === null ? 'null' : typeof render) + "."); return; } } return { render: render }; } function unmountRef(ref) { if (!isNullOrUndef(ref)) { if (!safeCall1(ref, null) && ref.current) { ref.current = null; } } } function mountRef(ref, value, lifecycle) { if (!isNullOrUndef(ref) && (isFunction(ref) || ref.current !== void 0)) { lifecycle.push(function () { if (!safeCall1(ref, value) && ref.current !== void 0) { ref.current = value; } }); } } function remove(vNode, parentDOM, animations) { unmount(vNode, animations); removeVNodeDOM(vNode, parentDOM, animations); } function unmount(vNode, animations) { var flags = vNode.flags; var children = vNode.children; var ref; if ((flags & 481 /* VNodeFlags.Element */) !== 0) { ref = vNode.ref; var props = vNode.props; unmountRef(ref); var childFlags = vNode.childFlags; if (!isNull(props)) { var keys = Object.keys(props); for (var i = 0, len = keys.length; i < len; i++) { var key = keys[i]; if (syntheticEvents[key]) { unmountSyntheticEvent(key, vNode.dom); } } } if (childFlags & 12 /* ChildFlags.MultipleChildren */) { unmountAllChildren(children, animations); } else if (childFlags === 2 /* ChildFlags.HasVNodeChildren */) { unmount(children, animations); } } else if (children) { if (flags & 4 /* VNodeFlags.ComponentClass */) { if (isFunction(children.componentWillUnmount)) { // TODO: Possible entrypoint children.componentWillUnmount(); } // If we have a componentWillDisappear on this component, block children from animating var childAnimations = animations; if (isFunction(children.componentWillDisappear)) { childAnimations = new AnimationQueues(); addDisappearAnimationHook(animations, children, children.$LI.dom, flags, undefined); } unmountRef(vNode.ref); children.$UN = true; unmount(children.$LI, childAnimations); } else if (flags & 8 /* VNodeFlags.ComponentFunction */) { // If we have a onComponentWillDisappear on this component, block children from animating var _childAnimations = animations; ref = vNode.ref; if (!isNullOrUndef(ref)) { var domEl = null; if (isFunction(ref.onComponentWillUnmount)) { domEl = findDOMFromVNode(vNode, true); ref.onComponentWillUnmount(domEl, vNode.props || EMPTY_OBJ); } if (isFunction(ref.onComponentWillDisappear)) { _childAnimations = new AnimationQueues(); domEl = domEl || findDOMFromVNode(vNode, true); addDisappearAnimationHook(animations, ref, domEl, flags, vNode.props); } } unmount(children, _childAnimations); } else if (flags & 1024 /* VNodeFlags.Portal */) { remove(children, vNode.ref, animations); } else if (flags & 8192 /* VNodeFlags.Fragment */) { if (vNode.childFlags & 12 /* ChildFlags.MultipleChildren */) { unmountAllChildren(children, animations); } } } } function unmountAllChildren(children, animations) { for (var i = 0, len = children.length; i < len; ++i) { unmount(children[i], animations); } } function createClearAllCallback(children, parentDOM) { return function () { // We need to remove children one by one because elements can be added during animation if (parentDOM) { for (var i = 0; i < children.length; i++) { var vNode = children[i]; clearVNodeDOM(vNode, parentDOM, false); } } }; } function clearDOM(parentDOM, children, animations) { if (animations.componentWillDisappear.length > 0) { // Wait until animations are finished before removing actual dom nodes // Be aware that the element could be removed by a later operation callAllAnimationHooks(animations.componentWillDisappear, createClearAllCallback(children, parentDOM)); } else { // Optimization for clearing dom parentDOM.textContent = ''; } } function removeAllChildren(dom, vNode, children, animations) { unmountAllChildren(children, animations); if (vNode.flags & 8192 /* VNodeFlags.Fragment */) { removeVNodeDOM(vNode, dom, animations); } else { clearDOM(dom, children, animations); } } // Only add animations to queue in browser function addDisappearAnimationHook(animations, instanceOrRef, dom, flags, props) { // @ts-expect-error TODO: Here is something weird check this behavior animations.componentWillDisappear.push(function (callback) { if (flags & 4 /* VNodeFlags.ComponentClass */) { instanceOrRef.componentWillDisappear(dom, callback); } else if (flags & 8 /* VNodeFlags.ComponentFunction */) { instanceOrRef.onComponentWillDisappear(dom, props, callback); } }); } function wrapLinkEvent(nextValue) { // This variable makes sure there is no "this" context in callback var ev = nextValue.event; return function (e) { ev(nextValue.data, e); }; } function patchEvent(name, lastValue, nextValue, dom) { if (isLinkEventObject(nextValue)) { if (isLastValueSameLinkEvent(lastValue, nextValue)) { return; } nextValue = wrapLinkEvent(nextValue); } attachEvent(dom, normalizeEventName(name), nextValue); } // We are assuming here that we come from patchProp routine // -nextAttrValue cannot be null or undefined function patchStyle(lastAttrValue, nextAttrValue, dom) { if (isNullOrUndef(nextAttrValue)) { dom.removeAttribute('style'); return; } 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.setProperty(style, value); } } for (style in lastAttrValue) { if (isNullOrUndef(nextAttrValue[style])) { domStyle.removeProperty(style); } } } else { for (style in nextAttrValue) { value = nextAttrValue[style]; domStyle.setProperty(style, value); } } } function patchDangerInnerHTML(lastValue, nextValue, lastVNode, dom, animations) { var lastHtml = (lastValue == null ? void 0 : lastValue.__html) || ''; var nextHtml = (nextValue == null ? void 0 : nextValue.__html) || ''; if (lastHtml !== nextHtml) { if (!isNullOrUndef(nextHtml) && !isSameInnerHTML(dom, nextHtml)) { if (!isNull(lastVNode)) { if (lastVNode.childFlags & 12 /* ChildFlags.MultipleChildren */) { unmountAllChildren(lastVNode.children, animations); } else if (lastVNode.childFlags === 2 /* ChildFlags.HasVNodeChildren */) { unmount(lastVNode.children, animations); } lastVNode.children = null; lastVNode.childFlags = 1 /* ChildFlags.HasInvalidChildren */; } dom.innerHTML = nextHtml; } } } function patchDomProp(nextValue, dom, prop) { var value = isNullOrUndef(nextValue) ? '' : nextValue; if (dom[prop] !== value) { dom[prop] = value; } } function patchProp(prop, lastValue, nextValue, dom, isSVG, hasControlledValue, lastVNode, animations) { switch (prop) { case 'children': case 'childrenType': case 'className': case 'defaultValue': case 'key': case 'multiple': case 'ref': case 'selectedIndex': break; case 'autoFocus': dom.autofocus = !!nextValue; break; case 'allowfulls