diff-dom-streaming
Version:
Diff DOM algorithm with streaming. Gets all modifications, insertions and removals between a DOM fragment and a stream HTML reader.
2 lines (1 loc) • 2.58 kB
JavaScript
var G=new Set(["HTML","HEAD","BODY"]),D=()=>new Promise((j)=>requestAnimationFrame(j));async function R(j,B,q){let z=await W(B,q),J=z.root;if(j.nodeType===9)j=j.documentElement;if(J.nodeType===11)await E(j,J,z);else await $(j,J,z)}async function $(j,B,q){if(j.nodeType!==B.nodeType)return q[0](()=>j.parentNode.replaceChild(B.cloneNode(!0),j));if(j.nodeType===1)await E(j,B,q),q[0](()=>{if(j.nodeName===B.nodeName){if(B.nodeName!=="BODY")T(j.attributes,B.attributes)}else{let z=B.nodeName==="TEMPLATE",J=B.cloneNode(z);while(j.firstChild)J.appendChild(j.firstChild);j.parentNode.replaceChild(J,j)}});else if(j.nodeValue!==B.nodeValue)q[0](()=>j.nodeValue=B.nodeValue)}function T(j,B){let q,z,J,U,V;for(q=j.length;q--;)if(z=j[q],U=z.namespaceURI,V=z.localName,J=B.getNamedItemNS(U,V),!J)j.removeNamedItemNS(U,V);for(q=B.length;q--;){if(z=B[q],U=z.namespaceURI,V=z.localName,J=j.getNamedItemNS(U,V),z.name==="data-action")continue;if(!J)B.removeNamedItemNS(U,V),j.setNamedItemNS(z);else if(J.value!==z.value)J.value=z.value}}async function E(j,B,q){let z,J,U,V,X=null,Q=j.firstChild,H=await q[1](B),Y=0;while(Q)if(Y++,z=Q,J=Z(z),Q=Q.nextSibling,J){if(!X)X={};X[J]=z}Q=j.firstChild;while(H){let M;if(X&&(U=Z(H))&&(V=X[U])){if(delete X[U],V!==Q)q[0](()=>j.insertBefore(V,Q));else Q=Q.nextSibling;await $(V,H,q)}else if(Q)if(z=Q,Q=Q.nextSibling,Z(z))M=H.cloneNode(!0),q[0](()=>j.insertBefore(M,z));else await $(z,H,q);else M=H.cloneNode(!0),q[0](()=>j.appendChild(M));if(H=await q[2](H),!M)Y--}q[0](()=>{for(J in X)Y--,j.removeChild(X[J]);while(--Y>=0)j.removeChild(j.lastChild)})}function Z(j){return j?.getAttribute?.("key")||j.id}async function W(j,B={}){let q=document.implementation.createHTMLDocument();q.open();let z=new TextDecoderStream,J=z.readable.getReader(),U=!0;j.pipeTo(z.writable),V();async function V(){try{while(!0){let{done:H,value:Y}=await J.read();if(H){U=!1;break}q.write(Y)}}finally{q.close()}}while(!q.documentElement||Q(q.documentElement))await D();function X(H){return async(Y)=>{if(!Y)return null;let M=Y[H];while(B.shouldIgnoreNode?.(M))M=M[H];if(M)await B.onNextNode?.(M);let F=H==="firstChild";while(Q(M,F))await D();return M}}function Q(H,Y){if(!H||!U||H.nextSibling)return!1;if(G.has(H.nodeName))return!q.body?.hasChildNodes?.();let M=H.parentElement;while(M){if(M.nextSibling)return!1;M=M.parentElement}return Y?U&&!H.hasChildNodes?.():U}return{root:q.documentElement,[1]:X("firstChild"),[2]:X("nextSibling"),[0]:(H)=>{if(B.transition&&document.startViewTransition)window.lastDiffTransition=document.startViewTransition(H);else H()}}}export{R as default};