Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

forgo

Package Overview
Dependencies
Maintainers
1
Versions
140
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

forgo - npm Package Compare versions

Comparing version 2.1.3 to 2.2.0

2

dist/forgo.min.js

@@ -1,2 +0,2 @@

var ae=Object.defineProperty,pe=Object.defineProperties;var ce=Object.getOwnPropertyDescriptors;var W=Object.getOwnPropertySymbols;var ie=Object.prototype.hasOwnProperty,ue=Object.prototype.propertyIsEnumerable;var Y=(r,l,i)=>l in r?ae(r,l,{enumerable:!0,configurable:!0,writable:!0,value:i}):r[l]=i,R=(r,l)=>{for(var i in l||(l={}))ie.call(l,i)&&Y(r,i,l[i]);if(W)for(var i of W(l))ue.call(l,i)&&Y(r,i,l[i]);return r},E=(r,l)=>pe(r,ce(l));export const Fragment=Symbol.for("FORGO_FRAGMENT");const Ce="http://www.w3.org/1999/xhtml",xe="http://www.w3.org/1998/Math/MathML",me="http://www.w3.org/2000/svg",q=1,Te=2,k=3;export function createElement(r,l){var C;l=l!=null?l:{},l.children=arguments.length>3?S(Array.from(arguments).slice(2)):arguments.length===3?S(arguments[2]):void 0;const i=(C=l.key)!=null?C:void 0;return{type:r,props:l,key:i,__is_forgo_element__:!0}}export const h=createElement;function fe(r,l){return i=>{if(!r.__forgo_deleted)return l(i)}}export function createForgoInstance(r){var J;const l=r;l.__internal=(J=l.__internal)!=null?J:{Text:l.window.Text,HTMLElement:l.window.HTMLElement};function i(n,e,o,t){return Array.isArray(n)?U(n,e,o,t):L(n)?ge(n)?A(n,e,o,t):D(n)?K(n,e,o,t):z(n,e,o,t):n==null?C(n,e,o,t):T(n,e,o,t)}function C(n,e,o,t){return{nodes:[]}}function T(n,e,o,t){var d;if(e.type==="detached"){const p=l.document.createTextNode($(n));return b(n,p,!0,o,void 0),{nodes:[p]}}else{const p=l.document.createTextNode($(n)),s=e.parentElement.childNodes;if(e.length){let c=s[e.currentNodeIndex];if(c.nodeType===k){c.replaceWith(p);const u=(d=getForgoState(c))==null?void 0:d.components;return b(n,p,!0,o,u),{nodes:[p]}}else{const u=s[e.currentNodeIndex];return e.parentElement.insertBefore(p,u),b(n,p,!0,o,void 0),{nodes:[p]}}}else{const c=e.parentElement.childNodes;if(c.length===0||e.currentNodeIndex===0)e.parentElement.prepend(p);else{const u=c[e.currentNodeIndex];e.parentElement.insertBefore(p,u)}return b(n,p,!0,o,void 0),{nodes:[p]}}}}function A(n,e,o,t){if(e.type==="detached")return s(void 0,null);{const c=e.parentElement.childNodes;if(e.length){const u=Q(n,c,e.currentNodeIndex,e.length);return u.found?p(u.index,c,e):s(e.parentElement,c[e.currentNodeIndex])}else return s(e.parentElement,c[e.currentNodeIndex])}function d(c){if(n.props.dangerouslySetInnerHTML)c.innerHTML=n.props.dangerouslySetInnerHTML.__html;else{const u=n.props.children,a=S((Array.isArray(u)?u:[u]).filter(y=>y!=null));let m=0;for(const y of a){const{nodes:N}=i(y,{type:"search",parentElement:c,currentNodeIndex:m,length:c.childNodes.length-m},[],t);m+=N.length}const f=P(c.childNodes,m,c.childNodes.length);f.length&&_(f,[])}}function p(c,u,a){var N;const m=P(u,a.currentNodeIndex,c);_(m,o);const f=u[a.currentNodeIndex];d(f);const y=(N=getForgoState(f))==null?void 0:N.components;return b(n,f,!1,o,y),{nodes:[f]}}function s(c,u){const a=te(n,c);return c&&c.insertBefore(a,u),n.props.ref&&(n.props.ref.value=a),d(a),b(n,a,!0,o,void 0),{nodes:[a]}}}function z(n,e,o,t){const d=o.length;if(e.type==="detached")return s();if(e.length){if(t)return s();{const u=e.parentElement.childNodes,a=O(n,u,e.currentNodeIndex,e.length,o.length);return a.found?p(a.index,u,e):s()}}else return s();function p(u,a,m){const f=a[u],N=H(f).components[d],F=P(a,m.currentNodeIndex,u);if(_(F,o.concat(N)),!N.component.shouldUpdate||N.component.shouldUpdate(n.props,N.props)){const g=E(R({},N),{props:n.props}),x=g.component.render(n.props,g.args),w=o.concat(g),re=N.args.element.node,de=g.component.error?g.component:void 0,se=c(n.props,g.args,w,de,()=>{const le={type:"search",currentNodeIndex:m.currentNodeIndex,length:g.nodes.length,parentElement:m.parentElement};return I(x,le,w,g,t)});return g.component.afterRender&&g.component.afterRender(n.props,E(R({},g.args),{previousNode:re})),se}else{let g=B(m.parentElement.childNodes,N.args.element.node);return{nodes:P(m.parentElement.childNodes,g,g+N.nodes.length)}}}function s(){const u={element:{componentIndex:d},update:F=>G(u.element,F)},a=n.type,m=a(n.props,{environment:l});he(a,m);const f=m.error?m:void 0,y={key:n.key,ctor:a,component:m,props:n.props,args:u,nodes:[],isMounted:!1},N=o.concat(y);return c(n.props,u,N,f,()=>{const F=m.render(n.props,u),g=e.type==="detached"?e:{type:"search",currentNodeIndex:e.currentNodeIndex,length:t?e.length:0,parentElement:e.parentElement},x=i(F,g,N,t);return y.nodes=x.nodes,x.nodes.length>1&&(y.args.element.node=x.nodes[0]),m.afterRender&&m.afterRender(n.props,u),x})}function c(u,a,m,f,y){try{return y()}catch(N){if(f&&f.error){const F=E(R({},a),{error:N}),g=f.error(u,F);return i(g,e,m,t)}else throw N}}}function I(n,e,o,t,d){const p=e.parentElement.childNodes.length,s=i(n,e,o,d),c=e.parentElement.childNodes.length,u=p+s.nodes.length-c,a=e.currentNodeIndex+s.nodes.length,m=P(e.parentElement.childNodes,a,a+t.nodes.length-u),f=s.nodes.length>0?o:[];return _(m,f),t.nodes=s.nodes,s.nodes.length>1&&(t.args.element.node=s.nodes[0]),s}function U(n,e,o,t){const d=S(n);if(e.type==="detached")throw new Error("Arrays and fragments cannot be rendered at the top level.");{let p=[],s=e.currentNodeIndex,c=e.length;for(const u of d){const a=e.parentElement.childNodes.length,m=E(R({},e),{currentNodeIndex:s,length:c}),{nodes:f}=i(u,m,o,t);p=p.concat(f);const y=e.parentElement.childNodes.length,N=a+f.length-y;s+=f.length,c-=N}return{nodes:p}}}function K(n,e,o,t){return U(S(n),e,o,t)}function b(n,e,o,t,d){if(ee(n,e,o,t),d){const p=j(t,d);M(d,p),X(t,p)}else X(t,0)}function _(n,e){for(const o of n){const t=getForgoState(o);if(o.__forgo_deleted=!0,o.remove(),t){const d=t.components,p=j(e,d);M(t.components,p)}}}function j(n,e){let o=0;for(const t of n)if(e.length>o){if(e[o].component!==t.component)break;o++}else break;return o}function M(n,e){let o=!1;for(let t=e;t<n.length;t++){const d=n[t];d.component.unmount&&(o||d.nodes.every(p=>{if(p.isConnected){const s=H(p);return!s.components[t]||s.components[t].component!==d.component}else return!0}))&&(d.component.unmount(d.props,d.args),o=!0)}}function X(n,e){for(let o=e;o<n.length;o++){const t=n[o];t.component.mount&&!t.isMounted&&(t.isMounted=!0,t.component.mount(t.props,t.args))}}function Q(n,e,o,t){for(let d=o;d<o+t;d++){const p=e[d];if(Z(p)){const s=getForgoState(p);if(n.key){if((s==null?void 0:s.key)===n.key)return{found:!0,index:d}}else if(p.tagName.toLowerCase()===n.type&&(!s||!s.key))return{found:!0,index:d}}}return{found:!1}}function O(n,e,o,t,d){for(let p=o;p<o+t;p++){const s=e[p],c=getForgoState(s);if(c&&c.components.length>d){if(n.key){if(c.components[d].key===n.key)return{found:!0,index:p}}else if(c.components[d].ctor===n.type)return{found:!0,index:p}}}return{found:!1}}function ee(n,e,o,t){var p;const d=[];for(const s of t)d.push(s.component.afterRender?s.args.element.node:void 0),s.args.element.node=e;if(L(n)){const s=getForgoState(e);if(s&&s.props)for(const a in s.props)a in n.props||a!=="children"&&a!=="xmlns"&&(e.nodeType===k||e instanceof l.__internal.HTMLElement&&a in e?delete e[a]:e.removeAttribute(a));else if(!o&&Z(e)&&e.hasAttributes()){const a=Array.from(e.attributes);for(const m of a){const f=m.name;f in n.props||e.removeAttribute(f)}}const c=Object.entries(n.props);for(const[a,m]of c)if(((p=s==null?void 0:s.props)==null?void 0:p[a])!==m&&a!=="children"&&a!=="xmlns")if(e.nodeType===k)e[a]=m;else if(e instanceof l.__internal.HTMLElement)if(a==="style"){if(s===void 0||s.style===void 0||s.style!==n.props.style){const f=ye(n.props.style);e.style.cssText!==f&&(e.style.cssText=f)}}else a==="onblur"?e[a]=fe(e,m):a in e?e[a]=m:e.setAttribute(a,m);else typeof m=="string"?e.setAttribute(a,m):e[a]=m;const u={key:n.key,props:n.props,components:t};setForgoState(e,u)}else setForgoState(e,{components:t})}function ne(n,e){let o=Ne(e)?l.document.querySelector(e):e;if(o)if(o.nodeType===q){const t=o.childNodes.length>0,d=i(n,{type:"search",currentNodeIndex:0,length:o.childNodes.length,parentElement:o},[],t);if(d.nodes.length<o.childNodes.length){const p=P(o.childNodes,d.nodes.length,o.childNodes.length);for(const s of p)s.remove()}return d}else throw new Error("The container argument to the mount() function should be an HTML element.");else throw new Error(`The mount() function was called on a non-element (${typeof e=="string"?e:e==null?void 0:e.tagName}).`)}function oe(n){const e=i(n,{type:"detached"},[],!1);return{node:e.nodes[0],nodes:e.nodes}}function G(n,e){if(n&&n.node){const o=n.node.parentElement;if(o!==null){const t=H(n.node),d=t.components[n.componentIndex],p=e!==void 0?e:d.props;if(!d.component.shouldUpdate||d.component.shouldUpdate(p,d.props)){const s=E(R({},d),{props:p}),c=t.components.slice(0,n.componentIndex),u=c.concat(s),a=d.args.element.node,m=d.component.render(p,d.args);let f=B(o.childNodes,n.node);const y={type:"search",currentNodeIndex:f,length:d.nodes.length,parentElement:o},N=I(m,y,u,s,!1);for(let F=0;F<c.length;F++){const g=c[F],x=g.nodes.findIndex(w=>w===d.nodes[0]);if(g.nodes=g.nodes.slice(0,x).concat(N.nodes).concat(g.nodes.slice(x+d.nodes.length)),g.nodes.length===0){M(c,F);break}else g.args.element.node=g.nodes[0]}return d.component.afterRender&&d.component.afterRender(p,E(R({},d.args),{previousNode:a})),N}else{let s=B(o.childNodes,n.node);return{nodes:P(o.childNodes,s,s+d.nodes.length)}}}else return{nodes:[]}}else throw new Error("Missing node information in rerender() argument.")}function te(n,e){var t;const o=((t=n.props.xmlns)!=null?t:n.type==="svg")?me:e&&e.namespaceURI;return n.props.is?o?l.document.createElementNS(o,n.type,{is:n.props.is}):l.document.createElement(n.type,{is:n.props.is}):o?l.document.createElementNS(o,n.type):l.document.createElement(n.type)}return{mount:ne,render:oe,rerender:G}}const V=globalThis||window;let v=createForgoInstance({window:V,document:V.document});export function setCustomEnv(r){v=createForgoInstance(r)}export function mount(r,l){return v.mount(r,l)}export function render(r){return v.render(r)}export function rerender(r,l){return v.rerender(r,l)}function S(r){function l(i,C=[]){const T=Array.isArray(i)?i:D(i)?Array.isArray(i.props.children)?i.props.children:i.props.children!==void 0&&i.props.children!==null?[i.props.children]:[]:[i];for(const A of T)Array.isArray(A)||D(A)?l(A,C):C.push(A);return C}return l(r,[])}function $(r){return r.toString()}function L(r){return r!=null&&r.__is_forgo_element__===!0}function ge(r){return L(r)&&typeof r.type=="string"}function D(r){return r!=null&&r.type===Fragment}export function getForgoState(r){return r.__forgo}function H(r){if(r.__forgo)return r.__forgo;throw new Error("Missing forgo state on node.")}export function setForgoState(r,l){r.__forgo=l}function he(r,l){if(!l.render)throw new Error(`${r.name||"Unnamed"} component constructor must return an object having a render() function.`)}function Ne(r){return typeof r=="string"}function Z(r){return r.nodeType===q}function ye(r){return typeof r=="string"?r:r==null?"":Object.keys(r).reduce((l,i)=>l+i.split(/(?=[A-Z])/).join("-").toLowerCase()+":"+r[i]+";","")}function P(r,l,i){const C=[];for(let T=l;T<i;T++)C.push(r[T]);return C}function B(r,l){for(let i=0;i<r.length;i++)if(r[i]===l)return i;return-1}export{};
var ae=Object.defineProperty,ie=Object.defineProperties;var ue=Object.getOwnPropertyDescriptors;var V=Object.getOwnPropertySymbols;var fe=Object.prototype.hasOwnProperty,me=Object.prototype.propertyIsEnumerable;var W=(r,a,u)=>a in r?ae(r,a,{enumerable:!0,configurable:!0,writable:!0,value:u}):r[a]=u,R=(r,a)=>{for(var u in a||(a={}))fe.call(a,u)&&W(r,u,a[u]);if(V)for(var u of V(a))me.call(a,u)&&W(r,u,a[u]);return r},_=(r,a)=>ie(r,ue(a));const ge=["ref","dangerouslySetInnerHTML"];export const Fragment=Symbol.for("FORGO_FRAGMENT");const _e="http://www.w3.org/1999/xhtml",Ee="http://www.w3.org/1998/Math/MathML",Ne="http://www.w3.org/2000/svg",$=1,Pe=2,k=3;export function createElement(r,a){var C;a=a!=null?a:{},a.children=arguments.length>3?b(Array.from(arguments).slice(2)):arguments.length===3?b(arguments[2]):void 0;const u=(C=a.key)!=null?C:void 0;return{type:r,props:a,key:u,__is_forgo_element__:!0}}export const h=createElement;function he(r,a){return u=>{var C;if(!((C=r.__forgo)==null?void 0:C.deleted))return a(u)}}export function createForgoInstance(r){var q;const a=r;a.__internal=(q=a.__internal)!=null?q:{Text:a.window.Text,HTMLElement:a.window.HTMLElement};function u(o,e,n,s){return Array.isArray(o)?I(o,e,n,s):L(o)?ye(o)?P(o,e,n,s):D(o)?O(o,e,n,s):Q(o,e,n,s):o==null?C(o,e,n,s):T(o,e,n,s)}function C(o,e,n,s){return{nodes:[]}}function T(o,e,n,s){var l;if(e.type==="detached"){const d=a.document.createTextNode(z(o));return A(o,d,!0,n,void 0),{nodes:[d]}}else{const d=a.document.createTextNode(z(o)),c=e.parentElement.childNodes;if(e.length){let p=c[e.currentNodeIndex];if(p.nodeType===k){p.replaceWith(d);const t=(l=getForgoState(p))==null?void 0:l.components;return A(o,d,!0,n,t),{nodes:[d]}}else{const t=c[e.currentNodeIndex];return e.parentElement.insertBefore(d,t),A(o,d,!0,n,void 0),{nodes:[d]}}}else{const p=e.parentElement.childNodes;if(p.length===0||e.currentNodeIndex===0)e.parentElement.prepend(d);else{const t=p[e.currentNodeIndex];e.parentElement.insertBefore(d,t)}return A(o,d,!0,n,void 0),{nodes:[d]}}}}function P(o,e,n,s){if(e.type==="detached")return c(void 0,null);{const p=e.parentElement.childNodes;if(e.length){const t=ee(o,e.parentElement,e.currentNodeIndex,e.length);return t.found?d(t.index,p,e):c(e.parentElement,p[e.currentNodeIndex])}else return c(e.parentElement,p[e.currentNodeIndex])}function l(p){if(o.props.dangerouslySetInnerHTML)p.innerHTML=o.props.dangerouslySetInnerHTML.__html;else{const t=o.props.children,i=b((Array.isArray(t)?t:[t]).filter(y=>y!=null));let f=0;for(const y of i){const{nodes:g}=u(y,{type:"search",parentElement:p,currentNodeIndex:f,length:p.childNodes.length-f},[],s);f+=g.length}const N=E(p.childNodes,f,p.childNodes.length);N.length&&S(N)}}function d(p,t,i){var g;const f=E(t,i.currentNodeIndex,p);S(f);const N=t[i.currentNodeIndex],y=(g=getForgoState(N))==null?void 0:g.components;return l(N),j(N,n),A(o,N,!1,n,y),{nodes:[N]}}function c(p,t){const i=de(o,p);return p&&p.insertBefore(i,t),o.props.ref&&(o.props.ref.value=i),l(i),A(o,i,!0,n,void 0),{nodes:[i]}}}function Q(o,e,n,s){const l=n.length;if(e.type==="detached")return c();if(e.length){if(s)return c();{const t=e.parentElement.childNodes,i=oe(o,e.parentElement,e.currentNodeIndex,e.length,n.length);return i.found?d(i.index,t,e):c()}}else return c();function d(t,i,f){const N=i[t],g=H(N).components[l],F=E(i,f.currentNodeIndex,t);if(S(F),!g.component.shouldUpdate||g.component.shouldUpdate(o.props,g.props)){const m=_(R({},g),{props:o.props}),x=m.component.render(o.props,m.args),w=n.concat(m),se=g.args.element.node,le=m.component.error?m.component:void 0,ce=p(o.props,m.args,w,le,()=>{const pe={type:"search",currentNodeIndex:f.currentNodeIndex,length:m.nodes.length,parentElement:f.parentElement};return U(x,pe,w,m,s)});return m.component.afterRender&&m.component.afterRender(o.props,_(R({},m.args),{previousNode:se})),ce}else{let m=B(f.parentElement.childNodes,g.args.element.node);return{nodes:E(f.parentElement.childNodes,m,m+g.nodes.length)}}}function c(){const t={element:{componentIndex:l},update:F=>Y(t.element,F)},i=o.type,f=i(o.props,{environment:a});Fe(i,f);const N=f.error?f:void 0,y={key:o.key,ctor:i,component:f,props:o.props,args:t,nodes:[],isMounted:!1},g=n.concat(y);return p(o.props,t,g,N,()=>{const F=f.render(o.props,t),m=e.type==="detached"?e:{type:"search",currentNodeIndex:e.currentNodeIndex,length:s?e.length:0,parentElement:e.parentElement},x=u(F,m,g,s);return y.nodes=x.nodes,y.args.element.node=x.nodes[0],f.afterRender&&f.afterRender(o.props,t),x})}function p(t,i,f,N,y){try{return y()}catch(g){if(N&&N.error){const F=_(R({},i),{error:g}),m=N.error(t,F);return u(m,e,f,s)}else throw g}}}function U(o,e,n,s,l){const d=e.parentElement.childNodes.length,c=u(o,e,n,l),p=e.parentElement.childNodes.length,t=d+c.nodes.length-p,i=e.currentNodeIndex+c.nodes.length,f=E(e.parentElement.childNodes,i,i+s.nodes.length-t);return S(f),s.nodes=c.nodes,s.args.element.node=c.nodes[0],c}function I(o,e,n,s){const l=b(o);if(e.type==="detached")throw new Error("Arrays and fragments cannot be rendered at the top level.");{let d=[],c=e.currentNodeIndex,p=e.length;for(const t of l){const i=e.parentElement.childNodes.length,f=_(R({},e),{currentNodeIndex:c,length:p}),{nodes:N}=u(t,f,n,s);d=d.concat(N);const y=e.parentElement.childNodes.length,g=i+N.length-y;c+=N.length,p-=g}return{nodes:d}}}function O(o,e,n,s){return I(b(o),e,n,s)}function A(o,e,n,s,l){if(ne(o,e,n,s),l){const d=X(s,l);G(l,d),J(s,d)}else J(s,0)}function S(o){if(o.length){const e=o[0].parentElement,n=M(e);for(const s of o)s.remove(),n.push({node:s})}}function j(o,e){const n=M(o);for(const{node:s}of n){const l=getForgoState(s);if(l){l.deleted=!0;const d=l.components,c=X(e,d);G(l.components,c)}}Ce(o)}function X(o,e){let n=0;for(const s of o)if(e.length>n){if(e[n].component!==s.component)break;n++}else break;return n}function G(o,e){var s;let n=!1;for(let l=e;l<o.length;l++){const d=o[l],c=d.component;c.unmount&&(n||d.nodes.every(p=>{if(p.isConnected){const t=H(p);return!t.components[l]||t.components[l].component!==d.component}else return!0}))&&(((s=c.__forgo)==null?void 0:s.unmounted)||(c.unmount(d.props,d.args),c.__forgo||(c.__forgo={}),c.__forgo.unmounted=!0),n=!0)}}function J(o,e){for(let n=e;n<o.length;n++){const s=o[n];s.component.mount&&!s.isMounted&&(s.isMounted=!0,s.component.mount(s.props,s.args))}}function ee(o,e,n,s){const l=e.childNodes;for(let d=n;d<n+s;d++){const c=l[d];if(K(c)){const p=getForgoState(c);if(o.key){if((p==null?void 0:p.key)===o.key)return{found:!0,index:d}}else if(c.tagName.toLowerCase()===o.type&&(!p||!p.key))return{found:!0,index:d}}}if(o.key){const d=M(e);for(let c=0;c<d.length;c++){const{node:p}=d[c],t=getForgoState(p);if((t==null?void 0:t.key)===o.key){d.splice(c,1);const i=l[n];return i?e.insertBefore(p,i):e.appendChild(p),{found:!0,index:n}}}}return{found:!1}}function oe(o,e,n,s,l){const d=e.childNodes;for(let c=n;c<n+s;c++){const p=d[c],t=getForgoState(p);if(t&&t.components.length>l){if(o.key){if(t.components[l].key===o.key)return{found:!0,index:c}}else if(t.components[l].ctor===o.type)return{found:!0,index:c}}}if(o.key){const c=M(e);for(let p=0;p<c.length;p++){const{node:t}=c[p],i=getForgoState(t);if(i&&i.components.length>l&&i.components[l].key===o.key){c.splice(p,1);const f=d[n];return f?e.insertBefore(t,f):e.appendChild(t),{found:!0,index:n}}}}return{found:!1}}function ne(o,e,n,s){var l;if(s.length>0&&(s[s.length-1].args.element.node=e),L(o)){const d=getForgoState(e);if(d&&d.props)for(const t in d.props)t in o.props||t!=="children"&&t!=="xmlns"&&(e.nodeType===k||e instanceof a.__internal.HTMLElement&&t in e?delete e[t]:e.removeAttribute(t));else if(!n&&K(e)&&e.hasAttributes()){const t=Array.from(e.attributes);for(const i of t){const f=i.name;f in o.props||e.removeAttribute(f)}}const c=Object.entries(o.props);for(const[t,i]of c)if(!ge.includes(t)&&((l=d==null?void 0:d.props)==null?void 0:l[t])!==i&&t!=="children"&&t!=="xmlns")if(e.nodeType===k)e[t]=i;else if(e instanceof a.__internal.HTMLElement)if(t==="style"){if(d===void 0||d.style===void 0||d.style!==o.props.style){const f=Te(o.props.style);e.style.cssText!==f&&(e.style.cssText=f)}}else t==="onblur"?e[t]=he(e,i):t in e?e[t]=i:e.setAttribute(t,i);else typeof i=="string"?e.setAttribute(t,i):e[t]=i;const p={key:o.key,props:o.props,components:s};setForgoState(e,p)}else setForgoState(e,{components:s})}function te(o,e){let n=xe(e)?a.document.querySelector(e):e;if(n)if(n.nodeType===$){const s=n.childNodes.length>0,l=u(o,{type:"search",currentNodeIndex:0,length:n.childNodes.length,parentElement:n},[],s);if(l.nodes.length<n.childNodes.length){const d=E(n.childNodes,l.nodes.length,n.childNodes.length);for(const c of d)c.remove()}return l}else throw new Error("The container argument to the mount() function should be an HTML element.");else throw new Error(`The mount() function was called on a non-element (${typeof e=="string"?e:e==null?void 0:e.tagName}).`)}function re(o){const e=u(o,{type:"detached"},[],!1);return{node:e.nodes[0],nodes:e.nodes}}function Y(o,e){if(o&&o.node){const n=o.node.parentElement;if(n!==null){const s=H(o.node),l=s.components[o.componentIndex],d=e!==void 0?e:l.props;if(!l.component.shouldUpdate||l.component.shouldUpdate(d,l.props)){const c=_(R({},l),{props:d}),p=s.components.slice(0,o.componentIndex),t=p.concat(c),i=l.args.element.node,f=l.component.render(d,l.args);let N=B(n.childNodes,o.node);const y={type:"search",currentNodeIndex:N,length:l.nodes.length,parentElement:n},g=U(f,y,t,c,!1);for(let F=0;F<p.length;F++){const m=p[F],x=m.nodes.findIndex(w=>w===l.nodes[0]);m.nodes=m.nodes.slice(0,x).concat(g.nodes).concat(m.nodes.slice(x+l.nodes.length)),m.nodes.length>0&&(m.args.element.node=m.nodes[0])}return j(n,g.nodes.length>0?t:[]),l.component.afterRender&&l.component.afterRender(d,_(R({},l.args),{previousNode:i})),g}else{let c=B(n.childNodes,o.node);return{nodes:E(n.childNodes,c,c+l.nodes.length)}}}else return{nodes:[]}}else throw new Error("Missing node information in rerender() argument.")}function de(o,e){var s;const n=((s=o.props.xmlns)!=null?s:o.type==="svg")?Ne:e&&e.namespaceURI;return o.props.is?n?a.document.createElementNS(n,o.type,{is:o.props.is}):a.document.createElement(o.type,{is:o.props.is}):n?a.document.createElementNS(n,o.type):a.document.createElement(o.type)}return{mount:te,render:re,rerender:Y}}const Z=globalThis||window;let v=createForgoInstance({window:Z,document:Z.document});export function setCustomEnv(r){v=createForgoInstance(r)}export function mount(r,a){return v.mount(r,a)}export function render(r){return v.render(r)}export function rerender(r,a){return v.rerender(r,a)}function b(r){function a(u,C=[]){const T=Array.isArray(u)?u:D(u)?Array.isArray(u.props.children)?u.props.children:u.props.children!==void 0&&u.props.children!==null?[u.props.children]:[]:[u];for(const P of T)Array.isArray(P)||D(P)?a(P,C):C.push(P);return C}return a(r,[])}function z(r){return r.toString()}function L(r){return r!=null&&r.__is_forgo_element__===!0}function ye(r){return L(r)&&typeof r.type=="string"}function D(r){return r!=null&&r.type===Fragment}export function getForgoState(r){return r.__forgo}function H(r){if(r.__forgo)return r.__forgo;throw new Error("Missing forgo state on node.")}export function setForgoState(r,a){r.__forgo=a}function M(r){return r.__forgo_deletedNodes||(r.__forgo_deletedNodes=[]),r.__forgo_deletedNodes}function Ce(r){r.__forgo_deletedNodes||delete r.__forgo_deletedNodes}function Fe(r,a){if(!a.render)throw new Error(`${r.name||"Unnamed"} component constructor must return an object having a render() function.`)}function xe(r){return typeof r=="string"}function K(r){return r.nodeType===$}function Te(r){return typeof r=="string"?r:r==null?"":Object.keys(r).reduce((a,u)=>a+u.split(/(?=[A-Z])/).join("-").toLowerCase()+":"+r[u]+";","")}function E(r,a,u){const C=[];for(let T=a;T<u;T++)C.push(r[T]);return C}function B(r,a){for(let u=0;u<r.length;u++)if(r[u]===a)return u;return-1}export{};
//# sourceMappingURL=forgo.min.js.map

@@ -40,2 +40,5 @@ export declare type ForgoRef<T> = {

shouldUpdate?: (newProps: TProps, oldProps: TProps) => boolean;
__forgo?: {
unmounted?: boolean;
};
};

@@ -82,2 +85,3 @@ export declare type ForgoElementBase<TProps extends ForgoElementProps> = {

};
deleted?: boolean;
};

@@ -118,2 +122,11 @@ export declare type DOMCSSProperties = {

};
export declare type DeletedNode = {
node: ChildNode;
};
declare global {
interface ChildNode {
__forgo?: NodeAttachedState;
__forgo_deletedNodes?: DeletedNode[];
}
}
export declare const Fragment: unique symbol;

@@ -147,8 +160,2 @@ export declare function createElement<TProps extends ForgoElementProps & {

import type { JSXTypes } from "./jsxTypes";
declare global {
interface ChildNode {
__forgo?: NodeAttachedState;
__forgo_deleted?: boolean;
}
}
export { JSXTypes as JSX };

@@ -0,1 +1,4 @@

// Since we'll set any attribute the user passes us, we need to be sure not to
// set Forgo-only attributes that don't make sense to appear in the DOM
const suppressedAttributes = ["ref", "dangerouslySetInnerHTML"];
/*

@@ -42,3 +45,4 @@ Fragment constructor.

return (e) => {
if (!node.__forgo_deleted) {
var _a;
if (!((_a = node.__forgo) === null || _a === void 0 ? void 0 : _a.deleted)) {
return value(e);

@@ -170,3 +174,3 @@ }

if (nodeInsertionOptions.length) {
const searchResult = findReplacementCandidateForElement(forgoElement, childNodes, nodeInsertionOptions.currentNodeIndex, nodeInsertionOptions.length);
const searchResult = findReplacementCandidateForElement(forgoElement, nodeInsertionOptions.parentElement, nodeInsertionOptions.currentNodeIndex, nodeInsertionOptions.length);
if (searchResult.found) {

@@ -207,3 +211,3 @@ return renderExistingElement(searchResult.index, childNodes, nodeInsertionOptions);

if (nodesToRemove.length) {
unloadNodes(nodesToRemove, []);
markNodesForUnloading(nodesToRemove);
}

@@ -216,6 +220,7 @@ }

const nodesToRemove = sliceNodes(childNodes, nodeInsertionOptions.currentNodeIndex, insertAt);
unloadNodes(nodesToRemove, pendingAttachStates);
markNodesForUnloading(nodesToRemove);
const targetElement = childNodes[nodeInsertionOptions.currentNodeIndex];
const oldComponentState = (_a = getForgoState(targetElement)) === null || _a === void 0 ? void 0 : _a.components;
renderChildNodes(targetElement);
const oldComponentState = (_a = getForgoState(targetElement)) === null || _a === void 0 ? void 0 : _a.components;
unloadMarkedNodes(targetElement, pendingAttachStates);
syncStateAndProps(forgoElement, targetElement, false, pendingAttachStates, oldComponentState);

@@ -257,3 +262,3 @@ return { nodes: [targetElement] };

const childNodes = nodeInsertionOptions.parentElement.childNodes;
const searchResult = findReplacementCandidateForComponent(forgoElement, childNodes, nodeInsertionOptions.currentNodeIndex, nodeInsertionOptions.length, pendingAttachStates.length);
const searchResult = findReplacementCandidateForComponent(forgoElement, nodeInsertionOptions.parentElement, nodeInsertionOptions.currentNodeIndex, nodeInsertionOptions.length, pendingAttachStates.length);
if (searchResult.found) {

@@ -280,3 +285,3 @@ return renderExistingComponent(searchResult.index, childNodes, nodeInsertionOptions);

const nodesToRemove = sliceNodes(childNodes, nodeInsertionOptions.currentNodeIndex, insertAt);
unloadNodes(nodesToRemove, pendingAttachStates.concat(componentState));
markNodesForUnloading(nodesToRemove);
if (!componentState.component.shouldUpdate ||

@@ -357,5 +362,3 @@ componentState.component.shouldUpdate(forgoElement.props, componentState.props)) {

newComponentState.nodes = renderResult.nodes;
if (renderResult.nodes.length > 1) {
newComponentState.args.element.node = renderResult.nodes[0];
}
newComponentState.args.element.node = renderResult.nodes[0];
if (component.afterRender) {

@@ -394,11 +397,7 @@ // No previousNode since new component. So just args and not afterRenderArgs.

const nodesToRemove = sliceNodes(insertionOptions.parentElement.childNodes, newIndex, newIndex + componentState.nodes.length - numNodesReused);
// If renderResult returned no nodes (ie, null or undefined), then all state will be discarded.
const statesThatWillBeAttached = renderResult.nodes.length > 0 ? statesToAttach : [];
unloadNodes(nodesToRemove, statesThatWillBeAttached);
markNodesForUnloading(nodesToRemove);
// In case we rendered an array, set the node to the first node.
// We do this because args.element.node would be set to the last node otherwise.
componentState.nodes = renderResult.nodes;
if (renderResult.nodes.length > 1) {
componentState.args.element.node = renderResult.nodes[0];
}
componentState.args.element.node = renderResult.nodes[0];
return renderResult;

@@ -453,12 +452,28 @@ }

/*
Unmount components from nodes.
We unmount only after first incompatible state, since compatible states
will be reattached to new candidate node.
This doesn't unmount components attached to these nodes,
but moves the node itself from the DOM to parentNode.__forgo_deletedNodes.
We sort of "mark" it for deletion, but it may be resurrected when a keyed,
off-order forgo node matches a deleted node.
*/
function unloadNodes(nodes, pendingAttachStates) {
for (const node of nodes) {
function markNodesForUnloading(nodes) {
if (nodes.length) {
const parentElement = nodes[0].parentElement;
const deletedNodes = getDeletedNodes(parentElement);
for (const node of nodes) {
node.remove();
deletedNodes.push({ node });
}
}
}
/*
Unmount components from nodes.
We unmount only after first incompatible state, since compatible states
will be reattached to new candidate node.
*/
function unloadMarkedNodes(parentElement, pendingAttachStates) {
const deletedNodes = getDeletedNodes(parentElement);
for (const { node } of deletedNodes) {
const state = getForgoState(node);
node.__forgo_deleted = true;
node.remove();
if (state) {
state.deleted = true;
const oldComponentStates = state.components;

@@ -469,2 +484,3 @@ const indexOfFirstIncompatibleState = findIndexOfFirstIncompatibleState(pendingAttachStates, oldComponentStates);

}
clearDeletedNodes(parentElement);
}

@@ -501,2 +517,3 @@ /*

function unmountComponents(states, from) {
var _a;
// If the parent has already unmounted, we can skip checks on children.

@@ -506,3 +523,4 @@ let parentHasUnmounted = false;

const state = states[i];
if (state.component.unmount) {
const component = state.component;
if (component.unmount) {
// Render if:

@@ -519,8 +537,14 @@ // - parent has already unmounted

else {
const componentState = getExistingForgoState(x);
return (!componentState.components[i] ||
componentState.components[i].component !== state.component);
const stateOnCurrentNode = getExistingForgoState(x);
return (!stateOnCurrentNode.components[i] ||
stateOnCurrentNode.components[i].component !== state.component);
}
})) {
state.component.unmount(state.props, state.args);
if (!((_a = component.__forgo) === null || _a === void 0 ? void 0 : _a.unmounted)) {
component.unmount(state.props, state.args);
if (!component.__forgo) {
component.__forgo = {};
}
component.__forgo.unmounted = true;
}
parentHasUnmounted = true;

@@ -550,3 +574,4 @@ }

*/
function findReplacementCandidateForElement(forgoElement, nodes, searchFrom, length) {
function findReplacementCandidateForElement(forgoElement, parentElement, searchFrom, length) {
const nodes = parentElement.childNodes;
for (let i = searchFrom; i < searchFrom + length; i++) {

@@ -571,2 +596,23 @@ const node = nodes[i];

}
// Let's check deleted nodes as well.
if (forgoElement.key) {
const deletedNodes = getDeletedNodes(parentElement);
for (let i = 0; i < deletedNodes.length; i++) {
const { node } = deletedNodes[i];
const stateOnNode = getForgoState(node);
if ((stateOnNode === null || stateOnNode === void 0 ? void 0 : stateOnNode.key) === forgoElement.key) {
// Remove it from deletedNodes.
deletedNodes.splice(i, 1);
// Append it to the beginning of the node list.
const firstNodeInSearchList = nodes[searchFrom];
if (firstNodeInSearchList) {
parentElement.insertBefore(node, firstNodeInSearchList);
}
else {
parentElement.appendChild(node);
}
return { found: true, index: searchFrom };
}
}
}
return { found: false };

@@ -580,3 +626,4 @@ }

*/
function findReplacementCandidateForComponent(forgoElement, nodes, searchFrom, length, componentIndex) {
function findReplacementCandidateForComponent(forgoElement, parentElement, searchFrom, length, componentIndex) {
const nodes = parentElement.childNodes;
for (let i = searchFrom; i < searchFrom + length; i++) {

@@ -598,2 +645,25 @@ const node = nodes[i];

}
// Let's check deleted nodes as well.
if (forgoElement.key) {
const deletedNodes = getDeletedNodes(parentElement);
for (let i = 0; i < deletedNodes.length; i++) {
const { node } = deletedNodes[i];
const stateOnNode = getForgoState(node);
if (stateOnNode && stateOnNode.components.length > componentIndex) {
if (stateOnNode.components[componentIndex].key === forgoElement.key) {
// Remove it from deletedNodes.
deletedNodes.splice(i, 1);
// Append it to the beginning of the node list.
const firstNodeInSearchList = nodes[searchFrom];
if (firstNodeInSearchList) {
parentElement.insertBefore(node, firstNodeInSearchList);
}
else {
parentElement.appendChild(node);
}
return { found: true, index: searchFrom };
}
}
}
}
return { found: false };

@@ -607,10 +677,8 @@ }

var _a;
// Capture previous nodes if afterRender is defined;
const previousNodes = [];
// We have to inject node into the args object.
// components are already holding a reference to the args object.
// They don't know yet that args.element.node is undefined.
for (const state of pendingAttachStates) {
previousNodes.push(state.component.afterRender ? state.args.element.node : undefined);
state.args.element.node = node;
if (pendingAttachStates.length > 0) {
pendingAttachStates[pendingAttachStates.length - 1].args.element.node =
node;
}

@@ -661,2 +729,4 @@ if (isForgoElement(forgoNode)) {

for (const [key, value] of entries) {
if (suppressedAttributes.includes(key))
continue;
// The browser will sometimes perform side effects if an attribute is

@@ -794,3 +864,11 @@ // set, even if its value hasn't changed, so only update attrs if

const renderResult = renderComponentAndRemoveStaleNodes(forgoNode, insertionOptions, statesToAttach, newComponentState, false);
// We have to propagate node changes up the tree.
// We have to propagate node changes up the component Tree.
// Reason 1:
// Imaging Parent rendering Child1 & Child2
// Child1 renders [div1, div2], and Child2 renders [div3, div4].
// When Child1's rerender is called, it might return [p1] instead of [div1, div2]
// Now, Parent's node list (ie state.nodes) must be refreshed to [p1, div3, div4] from [div1, div2, div3, div4]
// Reason 2:
// If Child2 was rerendered (instead of Child1), attachProps() will incorrectly fixup parentState.element.node to div3, then to div4.
// That's just how attachProps() works. We need to ressign parentState.element.node to p1.
for (let i = 0; i < parentStates.length; i++) {

@@ -807,12 +885,10 @@ const parentState = parentStates[i];

.concat(parentState.nodes.slice(indexOfOriginalRootNode + originalComponentState.nodes.length));
// If there are no nodes, call unmount on it (and child states)
if (parentState.nodes.length === 0) {
unmountComponents(parentStates, i);
break;
}
else {
// The root node might have changed, so fix it up anyway.
// Fix up the root node for parent.
if (parentState.nodes.length > 0) {
// The root node might have changed, so fix it up just in case.
parentState.args.element.node = parentState.nodes[0];
}
}
// Unload marked nodes.
unloadMarkedNodes(parentElement, renderResult.nodes.length > 0 ? statesToAttach : []);
// Unmount rendered component itself if all nodes are gone.

@@ -960,2 +1036,17 @@ // if (renderResult.nodes.length === 0) {

/*
We maintain a list of deleted childNodes on an element.
In case we need to resurrect it - on account of a subsequent out-of-order key referring that node.
*/
function getDeletedNodes(element) {
if (!element.__forgo_deletedNodes) {
element.__forgo_deletedNodes = [];
}
return element.__forgo_deletedNodes;
}
function clearDeletedNodes(element) {
if (!element.__forgo_deletedNodes) {
delete element.__forgo_deletedNodes;
}
}
/*
Throw if component is a non-component

@@ -962,0 +1053,0 @@ */

{
"name": "forgo",
"version": "2.1.3",
"version": "2.2.0",
"main": "./dist/index.js",

@@ -5,0 +5,0 @@ "type": "module",

@@ -341,2 +341,34 @@ # forgo

### Rendering nothing
A stateless component may elect to render nothing by returning `null` from the `render()` method:
```jsx
function EmptyComponent(initialProps) {
return {
render(props, args) {
return null;
}
};
}
```
This does not work for stateful components. Forgo tracks component state by attaching it to the component's DOM element. This allows Forgo to operate without a virtual DOM (like React has), but means that if your component render returns `null` Forgo will unmount your component. If the component unmounts itself, there is not a way to request it remount itself, although it will be recreated if the parent rerenders.
If you want a component to skip rendering its usual output, return an empty element, like so:
```jsx
function EmptyComponent(initialProps) {
// This will be discarded if the render returns null.
// To keep it, always return an element.
const myState = Math.random();
return {
render(props, args) {
return <div></div>;
}
};
}
```
## Error handling

@@ -707,4 +739,11 @@

## Core Team
- [github/jeswin](https://github.com/jeswin)
- [github/spiffytech](https://github.com/spiffytech)
## Getting Help
You can reach out to me via twitter or email. If you find issues, please file a bug on [Github](https://github.com/forgojs/forgo/issues).
If you find issues, please file a bug on [Github](https://github.com/forgojs/forgo/issues). You can also reach out to us via Twitter (@forgojs).

@@ -17,2 +17,5 @@ /*

// Since we'll set any attribute the user passes us, we need to be sure not to
// set Forgo-only attributes that don't make sense to appear in the DOM
const suppressedAttributes = ["ref", "dangerouslySetInnerHTML"];
export type ForgoDOMElementProps = {

@@ -77,2 +80,3 @@ xmlns?: string;

shouldUpdate?: (newProps: TProps, oldProps: TProps) => boolean;
__forgo?: { unmounted?: boolean };
};

@@ -165,2 +169,3 @@

style?: { [key: string]: any };
deleted?: boolean;
};

@@ -240,2 +245,13 @@

export type DeletedNode = {
node: ChildNode;
};
declare global {
interface ChildNode {
__forgo?: NodeAttachedState;
__forgo_deletedNodes?: DeletedNode[];
}
}
/*

@@ -289,3 +305,3 @@ Fragment constructor.

return (e: any) => {
if (!node.__forgo_deleted) {
if (!node.__forgo?.deleted) {
return value(e);

@@ -502,3 +518,3 @@ }

forgoElement,
childNodes,
nodeInsertionOptions.parentElement,
nodeInsertionOptions.currentNodeIndex,

@@ -568,3 +584,3 @@ nodeInsertionOptions.length

if (nodesToRemove.length) {
unloadNodes(nodesToRemove, []);
markNodesForUnloading(nodesToRemove);
}

@@ -585,3 +601,3 @@ }

);
unloadNodes(nodesToRemove, pendingAttachStates);
markNodesForUnloading(nodesToRemove);

@@ -592,6 +608,7 @@ const targetElement = childNodes[

const oldComponentState = getForgoState(targetElement)?.components;
renderChildNodes(targetElement);
unloadMarkedNodes(targetElement, pendingAttachStates);
const oldComponentState = getForgoState(targetElement)?.components;
syncStateAndProps(

@@ -662,3 +679,3 @@ forgoElement,

forgoElement,
childNodes,
nodeInsertionOptions.parentElement,
nodeInsertionOptions.currentNodeIndex,

@@ -704,3 +721,3 @@ nodeInsertionOptions.length,

);
unloadNodes(nodesToRemove, pendingAttachStates.concat(componentState));
markNodesForUnloading(nodesToRemove);

@@ -846,5 +863,3 @@ if (

newComponentState.nodes = renderResult.nodes;
if (renderResult.nodes.length > 1) {
newComponentState.args.element.node = renderResult.nodes[0];
}
newComponentState.args.element.node = renderResult.nodes[0];

@@ -922,6 +937,3 @@ if (component.afterRender) {

// If renderResult returned no nodes (ie, null or undefined), then all state will be discarded.
const statesThatWillBeAttached =
renderResult.nodes.length > 0 ? statesToAttach : [];
unloadNodes(nodesToRemove, statesThatWillBeAttached);
markNodesForUnloading(nodesToRemove);

@@ -931,5 +943,3 @@ // In case we rendered an array, set the node to the first node.

componentState.nodes = renderResult.nodes;
if (renderResult.nodes.length > 1) {
componentState.args.element.node = renderResult.nodes[0];
}
componentState.args.element.node = renderResult.nodes[0];

@@ -1036,15 +1046,33 @@ return renderResult;

/*
Unmount components from nodes.
We unmount only after first incompatible state, since compatible states
will be reattached to new candidate node.
This doesn't unmount components attached to these nodes,
but moves the node itself from the DOM to parentNode.__forgo_deletedNodes.
We sort of "mark" it for deletion, but it may be resurrected when a keyed,
off-order forgo node matches a deleted node.
*/
function unloadNodes(
nodes: ChildNode[],
function markNodesForUnloading(nodes: ChildNode[]) {
if (nodes.length) {
const parentElement = nodes[0].parentElement as HTMLElement;
const deletedNodes = getDeletedNodes(parentElement);
for (const node of nodes) {
node.remove();
deletedNodes.push({ node });
}
}
}
/*
Unmount components from nodes.
We unmount only after first incompatible state, since compatible states
will be reattached to new candidate node.
*/
function unloadMarkedNodes(
parentElement: Element,
pendingAttachStates: NodeAttachedComponentState<any>[]
) {
for (const node of nodes) {
const deletedNodes = getDeletedNodes(parentElement);
for (const { node } of deletedNodes) {
const state = getForgoState(node);
node.__forgo_deleted = true;
node.remove();
if (state) {
state.deleted = true;
const oldComponentStates = state.components;

@@ -1058,2 +1086,3 @@ const indexOfFirstIncompatibleState = findIndexOfFirstIncompatibleState(

}
clearDeletedNodes(parentElement);
}

@@ -1104,3 +1133,4 @@

const state = states[i];
if (state.component.unmount) {
const component = state.component;
if (component.unmount) {
// Render if:

@@ -1117,6 +1147,6 @@ // - parent has already unmounted

} else {
const componentState = getExistingForgoState(x);
const stateOnCurrentNode = getExistingForgoState(x);
return (
!componentState.components[i] ||
componentState.components[i].component !== state.component
!stateOnCurrentNode.components[i] ||
stateOnCurrentNode.components[i].component !== state.component
);

@@ -1126,3 +1156,9 @@ }

) {
state.component.unmount(state.props, state.args);
if (!component.__forgo?.unmounted) {
component.unmount!(state.props, state.args);
if (!component.__forgo) {
component.__forgo = {};
}
component.__forgo.unmounted = true;
}
parentHasUnmounted = true;

@@ -1165,6 +1201,7 @@ }

forgoElement: ForgoDOMElement<TProps>,
nodes: NodeListOf<ChildNode>,
parentElement: Element,
searchFrom: number,
length: number
): CandidateSearchResult {
const nodes = parentElement.childNodes;
for (let i = searchFrom; i < searchFrom + length; i++) {

@@ -1190,2 +1227,22 @@ const node = nodes[i] as ChildNode;

}
// Let's check deleted nodes as well.
if (forgoElement.key) {
const deletedNodes = getDeletedNodes(parentElement);
for (let i = 0; i < deletedNodes.length; i++) {
const { node } = deletedNodes[i];
const stateOnNode = getForgoState(node);
if (stateOnNode?.key === forgoElement.key) {
// Remove it from deletedNodes.
deletedNodes.splice(i, 1);
// Append it to the beginning of the node list.
const firstNodeInSearchList = nodes[searchFrom];
if (firstNodeInSearchList) {
parentElement.insertBefore(node, firstNodeInSearchList);
} else {
parentElement.appendChild(node);
}
return { found: true, index: searchFrom };
}
}
}
return { found: false };

@@ -1202,3 +1259,3 @@ }

forgoElement: ForgoComponentElement<TProps>,
nodes: NodeListOf<ChildNode>,
parentElement: Element,
searchFrom: number,

@@ -1208,2 +1265,3 @@ length: number,

): CandidateSearchResult {
const nodes = parentElement.childNodes;
for (let i = searchFrom; i < searchFrom + length; i++) {

@@ -1226,2 +1284,24 @@ const node = nodes[i] as ChildNode;

}
// Let's check deleted nodes as well.
if (forgoElement.key) {
const deletedNodes = getDeletedNodes(parentElement);
for (let i = 0; i < deletedNodes.length; i++) {
const { node } = deletedNodes[i];
const stateOnNode = getForgoState(node);
if (stateOnNode && stateOnNode.components.length > componentIndex) {
if (stateOnNode.components[componentIndex].key === forgoElement.key) {
// Remove it from deletedNodes.
deletedNodes.splice(i, 1);
// Append it to the beginning of the node list.
const firstNodeInSearchList = nodes[searchFrom];
if (firstNodeInSearchList) {
parentElement.insertBefore(node, firstNodeInSearchList);
} else {
parentElement.appendChild(node);
}
return { found: true, index: searchFrom };
}
}
}
}
return { found: false };

@@ -1240,13 +1320,8 @@ }

) {
// Capture previous nodes if afterRender is defined;
const previousNodes: (ChildNode | undefined)[] = [];
// We have to inject node into the args object.
// components are already holding a reference to the args object.
// They don't know yet that args.element.node is undefined.
for (const state of pendingAttachStates) {
previousNodes.push(
state.component.afterRender ? state.args.element.node : undefined
);
state.args.element.node = node;
if (pendingAttachStates.length > 0) {
pendingAttachStates[pendingAttachStates.length - 1].args.element.node =
node;
}

@@ -1296,2 +1371,4 @@

for (const [key, value] of entries) {
if (suppressedAttributes.includes(key)) continue;
// The browser will sometimes perform side effects if an attribute is

@@ -1495,3 +1572,11 @@ // set, even if its value hasn't changed, so only update attrs if

// We have to propagate node changes up the tree.
// We have to propagate node changes up the component Tree.
// Reason 1:
// Imaging Parent rendering Child1 & Child2
// Child1 renders [div1, div2], and Child2 renders [div3, div4].
// When Child1's rerender is called, it might return [p1] instead of [div1, div2]
// Now, Parent's node list (ie state.nodes) must be refreshed to [p1, div3, div4] from [div1, div2, div3, div4]
// Reason 2:
// If Child2 was rerendered (instead of Child1), attachProps() will incorrectly fixup parentState.element.node to div3, then to div4.
// That's just how attachProps() works. We need to ressign parentState.element.node to p1.
for (let i = 0; i < parentStates.length; i++) {

@@ -1517,8 +1602,5 @@ const parentState = parentStates[i];

// If there are no nodes, call unmount on it (and child states)
if (parentState.nodes.length === 0) {
unmountComponents(parentStates, i);
break;
} else {
// The root node might have changed, so fix it up anyway.
// Fix up the root node for parent.
if (parentState.nodes.length > 0) {
// The root node might have changed, so fix it up just in case.
parentState.args.element.node = parentState.nodes[0];

@@ -1528,2 +1610,8 @@ }

// Unload marked nodes.
unloadMarkedNodes(
parentElement,
renderResult.nodes.length > 0 ? statesToAttach : []
);
// Unmount rendered component itself if all nodes are gone.

@@ -1714,2 +1802,19 @@ // if (renderResult.nodes.length === 0) {

/*
We maintain a list of deleted childNodes on an element.
In case we need to resurrect it - on account of a subsequent out-of-order key referring that node.
*/
function getDeletedNodes(element: Element): DeletedNode[] {
if (!element.__forgo_deletedNodes) {
element.__forgo_deletedNodes = [];
}
return element.__forgo_deletedNodes;
}
function clearDeletedNodes(element: Element) {
if (!element.__forgo_deletedNodes) {
delete element.__forgo_deletedNodes;
}
}
/*
Throw if component is a non-component

@@ -1789,9 +1894,2 @@ */

declare global {
interface ChildNode {
__forgo?: NodeAttachedState;
__forgo_deleted?: boolean;
}
}
export { JSXTypes as JSX };

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc