@zumer/snapdom 1.2.5 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/snapdom.js CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  /*
3
3
  * snapdom
4
- * v.1.2.5
4
+ * v.1.3.0
5
5
  * Author Juan Martin Muda
6
6
  * License MIT
7
7
  **/
@@ -227,7 +227,7 @@
227
227
  canvas.width = image.width;
228
228
  canvas.height = image.height;
229
229
  const ctx = canvas.getContext("2d");
230
- ctx.drawImage(image, 0, 0);
230
+ ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
231
231
  try {
232
232
  const dataURL = canvas.toDataURL("image/png");
233
233
  imageCache.set(src, dataURL);
@@ -315,6 +315,26 @@
315
315
  if (node.nodeType !== Node.ELEMENT_NODE) return node.cloneNode(true);
316
316
  const clone = node.cloneNode(false);
317
317
  nodeMap.set(clone, node);
318
+ if (node instanceof HTMLInputElement) {
319
+ clone.value = node.value;
320
+ clone.setAttribute("value", node.value);
321
+ if (node.checked !== void 0) {
322
+ clone.checked = node.checked;
323
+ if (node.checked) clone.setAttribute("checked", "");
324
+ }
325
+ } else if (node instanceof HTMLTextAreaElement) {
326
+ clone.value = node.value;
327
+ clone.textContent = node.value;
328
+ } else if (node instanceof HTMLSelectElement) {
329
+ clone.value = node.value;
330
+ Array.from(clone.options).forEach((opt) => {
331
+ if (opt.value === node.value) {
332
+ opt.setAttribute("selected", "");
333
+ } else {
334
+ opt.removeAttribute("selected");
335
+ }
336
+ });
337
+ }
318
338
  inlineAllStyles(node, clone, styleMap, styleCache, compress);
319
339
  const frag = document.createDocumentFragment();
320
340
  node.childNodes.forEach((child) => {
@@ -467,18 +487,25 @@
467
487
  imgEl.style = "display:block;width:100%;height:100%;object-fit:contain;";
468
488
  pseudoEl.appendChild(imgEl);
469
489
  } catch (e) {
470
- console.error(
471
- `[snapdom] Error in pseudo ${pseudo} for`,
472
- source,
473
- e
474
- );
490
+ console.error(`[snapdom] Error in pseudo ${pseudo} for`, source, e);
475
491
  }
476
492
  }
477
493
  } else if (!isIconFont2 && cleanContent && cleanContent !== "none") {
478
494
  pseudoEl.textContent = cleanContent;
479
495
  }
496
+ if (hasBg && bg) {
497
+ const rawUrl = extractURL(bg);
498
+ if (rawUrl) {
499
+ try {
500
+ const dataUrl = await fetchImage(encodeURI(rawUrl));
501
+ pseudoEl.style.backgroundImage = `url(${dataUrl})`;
502
+ } catch (e) {
503
+ console.warn(`[snapdom] Failed to inline background-image for ${pseudo}`, e);
504
+ }
505
+ }
506
+ }
480
507
  const hasContent2 = pseudoEl.childNodes.length > 0 || pseudoEl.textContent && pseudoEl.textContent.trim() !== "";
481
- if (!hasContent2) continue;
508
+ if (!hasContent2 && !hasBg) continue;
482
509
  if (pseudo === "::before") {
483
510
  clone.insertBefore(pseudoEl, clone.firstChild);
484
511
  } else {
@@ -490,9 +517,7 @@
490
517
  }
491
518
  }
492
519
  const sChildren = Array.from(source.children);
493
- const cChildren = Array.from(clone.children).filter(
494
- (child) => !child.dataset.snapdomPseudo
495
- );
520
+ const cChildren = Array.from(clone.children).filter((child) => !child.dataset.snapdomPseudo);
496
521
  for (let i = 0; i < Math.min(sChildren.length, cChildren.length); i++) {
497
522
  await inlinePseudoElements(
498
523
  sChildren[i],
@@ -708,20 +733,20 @@
708
733
  }
709
734
  return img;
710
735
  }
711
- async function toCanvas(url, { dpr = 1, scale = 1 }) {
736
+ async function toCanvas(url, { dpr = 1, scale = 1 } = {}) {
712
737
  const img = new Image();
713
738
  img.src = url;
714
739
  await img.decode();
715
740
  const canvas = document.createElement("canvas");
716
- const width = img.width * scale * dpr;
717
- const height = img.height * scale * dpr;
718
- canvas.width = Math.ceil(width);
719
- canvas.height = Math.ceil(height);
741
+ const width = img.width * scale;
742
+ const height = img.height * scale;
743
+ canvas.width = Math.ceil(width * dpr);
744
+ canvas.height = Math.ceil(height * dpr);
720
745
  const ctx = canvas.getContext("2d");
721
- ctx.scale(scale * dpr, scale * dpr);
722
- ctx.drawImage(img, 0, 0);
723
- canvas.style.width = `${canvas.width / dpr}px`;
724
- canvas.style.height = `${canvas.height / dpr}px`;
746
+ ctx.scale(dpr, dpr);
747
+ ctx.drawImage(img, 0, 0, width, height);
748
+ canvas.style.width = `${width}px`;
749
+ canvas.style.height = `${height}px`;
725
750
  return canvas;
726
751
  }
727
752
  async function toBlob(url) {
@@ -1,3 +1,3 @@
1
- (()=>{var S=new Map,E=new Map,R=new Map,T=new Map,k=new Map,U=new WeakMap;var ct=["div","span","p","a","img","ul","li","button","input","select","textarea","label","section","article","header","footer","nav","main","aside","h1","h2","h3","h4","h5","h6","svg","path","circle","rect","line","g","table","thead","tbody","tr","td","th"];function _(){for(let t of ct)H(t)}function H(t){if(T.has(t))return T.get(t);if(new Set(["script","style","meta","link","noscript","template"]).has(t)){let i={};return T.set(t,i),i}let o=document.getElementById("snapdom-sandbox");o||(o=document.createElement("div"),o.id="snapdom-sandbox",o.style.position="absolute",o.style.left="-9999px",o.style.top="-9999px",o.style.width="0",o.style.height="0",o.style.overflow="hidden",document.body.appendChild(o));let n=document.createElement(t);n.style.all="initial",o.appendChild(n);let a=getComputedStyle(n),r={};for(let i of a)r[i]=a.getPropertyValue(i);return o.removeChild(n),T.set(t,r),r}function B(t,e,o=!1){let n=[],a=H(e);for(let[r,i]of Object.entries(t))if(!o)i&&n.push(`${r}:${i}`);else{let c=a[r];i&&i!==c&&n.push(`${r}:${i}`)}return n.sort().join(";")}function Y(t){let e=new Set;return t.nodeType!==Node.ELEMENT_NODE&&t.nodeType!==Node.DOCUMENT_FRAGMENT_NODE?[]:(t.tagName&&e.add(t.tagName.toLowerCase()),typeof t.querySelectorAll=="function"&&t.querySelectorAll("*").forEach(o=>e.add(o.tagName.toLowerCase())),Array.from(e))}function K(t){let e=new Map;for(let n of t){let a=T.get(n);if(!a)continue;let r=Object.entries(a).map(([i,c])=>`${i}:${c};`).sort().join("");e.has(r)||e.set(r,[]),e.get(r).push(n)}let o="";for(let[n,a]of e.entries())o+=`${a.join(",")} { ${n} }
2
- `;return o}function J(t){let e=new Set(t.values()),o=new Map,n=1;for(let a of e)o.set(a,`c${n++}`);return o}function N(t,{fast:e=!1}={}){if(e)return t();"requestIdleCallback"in window?requestIdleCallback(t,{timeout:50}):setTimeout(t,1)}function A(t,e=null){if(!(t instanceof Element))return window.getComputedStyle(t,e);let o=U.get(t);if(o||(o=new Map,U.set(t,o)),!o.has(e)){let n=window.getComputedStyle(t,e);o.set(e,n)}return o.get(e)}function X(t){let e=t.replace(/^['"]|['"]$/g,"");if(e.startsWith("\\"))try{return String.fromCharCode(parseInt(e.replace("\\",""),16))}catch{return e}return e}function v(t){let e=t.indexOf("url(");if(e===-1)return null;let o=t.slice(e+4).trim();return o.endsWith(")")&&(o=o.slice(0,-1).trim()),(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),o}function M(t){return[/font\s*awesome/i,/material\s*icons/i,/ionicons/i,/glyphicons/i,/feather/i,/bootstrap\s*icons/i,/remix\s*icons/i,/heroicons/i].some(o=>o.test(t))}function x(t,e=3e3){return S.has(t)?Promise.resolve(S.get(t)):new Promise((o,n)=>{let a=setTimeout(()=>{n(new Error("Image load timed out"))},e),r=new Image;r.crossOrigin="anonymous",r.onload=async()=>{clearTimeout(a);try{await r.decode();let i=document.createElement("canvas");i.width=r.width,i.height=r.height,i.getContext("2d").drawImage(r,0,0);try{let s=i.toDataURL("image/png");S.set(t,s),o(s)}catch{n(new Error("CORS restrictions prevented image capture"))}}catch(i){n(i)}},r.onerror=i=>{clearTimeout(a),n(new Error("Failed to load image: "+(i.message||"Unknown error")))},r.src=t})}function F(t){let e={};for(let o of t)e[o]=t.getPropertyValue(o);return e}function D(){return/^((?!chrome|android).)*safari/i.test(navigator.userAgent)}function V(t,e,o,n,a){if(t.tagName==="STYLE")return;n.has(t)||n.set(t,A(t));let r=n.get(t),i=F(r),c=t.tagName?.toLowerCase()||"div",s=B(i,c,a);o.set(e,s)}function O(t,e,o,n,a){if(t.nodeType===Node.ELEMENT_NODE&&t.getAttribute("data-capture")==="exclude"){let c=document.createElement("div"),s=t.getBoundingClientRect();return c.style.cssText=`display: inline-block; width: ${s.width}px; height: ${s.height}px; visibility: hidden;`,c}if(t.tagName==="IFRAME"){let c=document.createElement("div");return c.textContent="",c.style.cssText=`width: ${t.offsetWidth}px; height: ${t.offsetHeight}px; background: repeating-linear-gradient(45deg, #ddd, #ddd 5px, #f9f9f9 5px, #f9f9f9 10px);display: flex;align-items: center;justify-content: center;font-size: 12px;color: #555; border: 1px solid #aaa;`,c}if(t.nodeType===Node.ELEMENT_NODE&&t.getAttribute("data-capture")==="placeholder"){let c=t.cloneNode(!1);n.set(c,t),V(t,c,e,o,a);let s=document.createElement("div");return s.textContent=t.getAttribute("data-placeholder-text")||"",s.style.cssText="color: #666;font-size: 12px;text-align: center;line-height: 1.4;padding: 0.5em;box-sizing: border-box;",c.appendChild(s),c}if(t.tagName==="CANVAS"){let c=t.toDataURL(),s=document.createElement("img");return s.src=c,s.width=t.width,s.height=t.height,s.style.display="inline-block",s.style.width=`${t.width}px`,s.style.height=`${t.height}px`,s}if(t.nodeType===Node.TEXT_NODE){if(t.parentElement?.shadowRoot){let c=t.parentElement.tagName.toLowerCase();if(customElements.get(c))return null}return t.cloneNode(!0)}if(t.nodeType!==Node.ELEMENT_NODE)return t.cloneNode(!0);let r=t.cloneNode(!1);n.set(r,t),V(t,r,e,o,a);let i=document.createDocumentFragment();if(t.childNodes.forEach(c=>{let s=O(c,e,o,n,a);s&&i.appendChild(s)}),r.appendChild(i),t.shadowRoot){let c=Array.from(t.shadowRoot.children).filter(l=>l.tagName!=="STYLE").map(l=>O(l,e,o,n)).filter(Boolean),s=document.createDocumentFragment();c.forEach(l=>s.appendChild(l)),r.appendChild(s)}return r}async function G(t,e,o,n=32,a="#000"){e=e.replace(/^['"]+|['"]+$/g,"");let r=window.devicePixelRatio||1,c=document.createElement("canvas").getContext("2d");c.font=o?`${o} ${n}px "${e}"`:`${n}px "${e}"`;let s=c.measureText(t),l=s.actualBoundingBoxAscent||n*.8,d=s.actualBoundingBoxDescent||n*.2,f=l+d,m=s.width,h=document.createElement("canvas");h.width=Math.ceil(m*r),h.height=Math.ceil(f*r);let p=h.getContext("2d");return p.scale(r,r),p.font=c.font,p.textAlign="left",p.textBaseline="alphabetic",p.fillStyle=a,p.fillText(t,0,l),h.toDataURL()}async function W({ignoreIconFonts:t=!0,preCached:e=!1}){let o=Array.from(document.querySelectorAll('link[rel="stylesheet"]')).filter(a=>a.href),n="";for(let a of o)try{let i=await(await fetch(a.href)).text();if(t&&(M(a.href)||M(i)))continue;let c=/url\(([^)]+)\)/g,s=await Promise.all(Array.from(i.matchAll(c)).map(async d=>{let f=v(d[0]);if(!f)return null;let m=f;m.startsWith("http")||(m=new URL(m,a.href).href);try{m=encodeURI(m)}catch{console.warn("[snapdom] Failed to encode font URL:",m)}if(t&&M(m))return null;if(R.has(m))return{original:d[0],inlined:`url(${R.get(m)})`};try{let p=await(await fetch(m)).blob(),w=await new Promise(C=>{let b=new FileReader;b.onload=()=>C(b.result),b.readAsDataURL(p)});return R.set(m,w),{original:d[0],inlined:`url(${w})`}}catch{return console.warn("\u274C Failed to fetch font:",m),null}})),l=i;for(let d of s)d&&(l=l.replace(d.original,d.inlined));n+=l+`
3
- `}catch{console.warn("\u274C Failed to fetch CSS:",a.href)}if(n&&e){let a=document.createElement("style");a.setAttribute("data-snapdom","embedFonts"),a.textContent=n,document.head.appendChild(a)}return n}async function q(t,e,o,n,a,r=!1){if(!(t instanceof Element)||!(e instanceof Element))return;for(let s of["::before","::after"])try{let l=A(t,s);if(!l)continue;let d=l.getPropertyValue("content"),f=l.getPropertyValue("background-image"),m=d&&d!=="none"&&d!=='""'&&d!=="''",h=f&&f.startsWith("url(");if(m||h){let p=l.getPropertyValue("font-family"),w=parseInt(l.getPropertyValue("font-size"))||32,C=parseInt(l.getPropertyValue("font-weight"))||!1,b=l.getPropertyValue("color")||"#000",u=document.createElement("span");u.dataset.snapdomPseudo=s;let I=F(l),P=B(I,"span",a);o.set(u,P);let j=p&&/font.*awesome|material|bootstrap|glyphicons|ionicons|remixicon|simple-line-icons|octicons|feather|typicons|weathericons/i.test(p),y=X(d);if(!r&&j&&y.length===1){let $=document.createElement("img");$.src=await G(y,p,C,w,b),$.style="display:block;width:100%;height:100%;object-fit:contain;",u.appendChild($)}else if(y.startsWith("url(")){let $=v(y);if($)try{let L=document.createElement("img"),it=await x(encodeURI($));L.src=it,L.style="display:block;width:100%;height:100%;object-fit:contain;",u.appendChild(L)}catch(L){console.error(`[snapdom] Error in pseudo ${s} for`,t,L)}}else!j&&y&&y!=="none"&&(u.textContent=y);if(!(u.childNodes.length>0||u.textContent&&u.textContent.trim()!==""))continue;s==="::before"?e.insertBefore(u,e.firstChild):e.appendChild(u)}}catch(l){console.warn(`[snapdom] Failed to capture ${s} for`,t,l)}let i=Array.from(t.children),c=Array.from(e.children).filter(s=>!s.dataset.snapdomPseudo);for(let s=0;s<Math.min(i.length,c.length);s++)await q(i[s],c[s],o,n,a,r)}async function Q(t,e=!1,o=!1){let n=new Map,a=new WeakMap,r=new Map,i;try{i=O(t,n,a,r,e)}catch(s){throw console.warn("deepClone failed:",s),s}try{await q(t,i,n,a,e,o)}catch(s){console.warn("inlinePseudoElements failed:",s)}let c="";if(e){let s=J(n);c=Array.from(s.entries()).map(([l,d])=>`.${d}{${l}}`).join("");for(let[l,d]of n.entries()){if(l.tagName==="STYLE")continue;let f=s.get(d);f&&l.classList.add(f);let m=l.style?.backgroundImage;l.removeAttribute("style"),m&&m!=="none"&&(l.style.backgroundImage=m)}}else for(let[s,l]of n.entries())s.tagName!=="STYLE"&&s.setAttribute("style",l.replace(/;/g,"; "));for(let[s,l]of r.entries()){let d=l.scrollLeft,f=l.scrollTop;if((d||f)&&s instanceof HTMLElement){s.style.overflow="hidden",s.style.scrollbarWidth="none",s.style.msOverflowStyle="none";let h=document.createElement("div");for(h.style.transform=`translate(${-d}px, ${-f}px)`,h.style.willChange="transform",h.style.display="inline-block",h.style.width="100%";s.firstChild;)h.appendChild(s.firstChild);s.appendChild(h)}}return{clone:i,classCSS:c,styleCache:a}}async function Z(t){let e=Array.from(t.querySelectorAll("img")),o=async n=>{let a=n.src;try{let r=await x(a);n.src=r,n.width||(n.width=n.naturalWidth||100),n.height||(n.height=n.naturalHeight||100)}catch{let r=document.createElement("div");r.style=`width: ${n.width||100}px; height: ${n.height||100}px; background: #ccc; display: inline-block; text-align: center; line-height: ${n.height||100}px; color: #666; font-size: 12px;`,r.innerText="img",n.replaceWith(r)}};for(let n=0;n<e.length;n+=4){let a=e.slice(n,n+4).map(o);await Promise.allSettled(a)}}async function tt(t,e,o){let n=[[t,e]];for(;n.length;){let[a,r]=n.shift(),i=o.get(a)||A(a);o.has(a)||o.set(a,i);let c=i.getPropertyValue("background-image"),s=v(c);if(s)try{let f=encodeURI(s),m;E.has(f)?m=E.get(f):(m=await x(f),E.set(f,m)),r.style.backgroundImage=`url(${m})`}catch{r.style.backgroundImage="none"}let l=Array.from(a.children),d=Array.from(r.children);for(let f=0;f<Math.min(l.length,d.length);f++)n.push([l[f],d[f]])}}async function et(t,e={}){if(!t)throw new Error("Element cannot be null or undefined");let{compress:o=!0,embedFonts:n=!1,fast:a=!0,scale:r=1}=e,i,c,s,l="",d="",f,m;if({clone:i,classCSS:c,styleCache:s}=await Q(t,o,n),await new Promise(p=>{N(async()=>{await Z(i),p()},{fast:a})}),await new Promise(p=>{N(async()=>{await tt(t,i,s),p()},{fast:a})}),n&&await new Promise(p=>{N(async()=>{l=await W({ignoreIconFonts:!n}),p()},{fast:a})}),o){let p=Y(i).sort(),w=p.join(",");k.has(w)?d=k.get(w):await new Promise(C=>{N(()=>{d=K(p),k.set(w,d),C()},{fast:a})})}await new Promise(p=>{N(()=>{let w=t.getBoundingClientRect(),C=Math.ceil(w.width),b=Math.ceil(w.height);i.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),i.style.transformOrigin="top left",r!==1&&D()&&(i.style.scale=`${r}`);let u="http://www.w3.org/2000/svg",I=document.createElementNS(u,"foreignObject");I.setAttribute("width","100%"),I.setAttribute("height","100%");let P=document.createElement("style");P.textContent=d+l+"svg{overflow:visible;}"+c,I.appendChild(P),I.appendChild(i);let y=new XMLSerializer().serializeToString(I);m=`<svg xmlns="${u}" width="${C}" height="${b}" viewBox="0 0 ${C} ${b}">`+y+"</svg>",f=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(m)}`,p()},{fast:a})});let h=document.getElementById("snapdom-sandbox");return h&&h.style.position==="absolute"&&h.remove(),f}async function lt(t,{dpr:e=1,scale:o=1}){let n=new Image;return n.src=t,await n.decode(),D?(n.width=n.width*o,n.height=n.height*o):(n.width=n.width/o,n.height=n.height/o),n}async function nt(t,{dpr:e=1,scale:o=1}){let n=new Image;n.src=t,await n.decode();let a=document.createElement("canvas"),r=n.width*o*e,i=n.height*o*e;a.width=Math.ceil(r),a.height=Math.ceil(i);let c=a.getContext("2d");return c.scale(o*e,o*e),c.drawImage(n,0,0),a.style.width=`${a.width/e}px`,a.style.height=`${a.height/e}px`,a}async function ot(t){let e=decodeURIComponent(t.split(",")[1]);return new Blob([e],{type:"image/svg+xml"})}async function at(t,{dpr:e=1,scale:o=1},n){let a=await nt(t,{dpr:e,scale:o});if(!n)return a;let r=document.createElement("canvas");r.width=a.width,r.height=a.height;let i=r.getContext("2d");return i.fillStyle=n,i.fillRect(0,0,r.width,r.height),i.drawImage(a,0,0),r}async function z(t,{dpr:e=1,scale:o=1,backgroundColor:n="#fff",quality:a},r="png"){let i=await at(t,{dpr:e,scale:o},n),c=new Image;return c.src=i.toDataURL(`image/${r}`,a),await c.decode(),c.style.width=`${i.width/e}px`,c.style.height=`${i.height/e}px`,c}async function dt(t,{dpr:e=1,scale:o=1,backgroundColor:n="#fff",format:a="png",filename:r="capture"}={}){if(a==="svg"){let m=await ot(t),h=URL.createObjectURL(m),p=document.createElement("a");p.href=h,p.download=`${r}.svg`,p.click(),URL.revokeObjectURL(h);return}let i=["jpg","jpeg","webp"].includes(a)?"#fff":void 0,s=await at(t,{dpr:e,scale:o},n??i),l={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp"}[a]||"image/png",d=s.toDataURL(l),f=document.createElement("a");f.href=d,f.download=`${r}.${a}`,f.click()}async function g(t,e={}){if(e={scale:1,...e},!t)throw new Error("Element cannot be null or undefined");return await g.capture(t,e)}g.capture=async(t,e={})=>{let o=await et(t,e),n=window.devicePixelRatio||1,a=e.scale||1;return{url:o,options:e,toRaw:()=>o,toImg:()=>lt(o,{dpr:n,scale:a}),toCanvas:()=>nt(o,{dpr:n,scale:a}),toBlob:()=>ot(o),toPng:r=>z(o,{dpr:n,scale:a,...r},"png"),toJpg:r=>z(o,{dpr:n,scale:a,...r},"jpeg"),toWebp:r=>z(o,{dpr:n,scale:a,...r},"webp"),download:({format:r="png",filename:i="capture",backgroundColor:c}={})=>dt(o,{dpr:n,scale:a,backgroundColor:c,format:r,filename:i})}};g.toRaw=async(t,e)=>(await g.capture(t,e)).toRaw();g.toImg=async(t,e)=>(await g.capture(t,e)).toImg();g.toCanvas=async(t,e)=>(await g.capture(t,e)).toCanvas();g.toBlob=async(t,e)=>(await g.capture(t,e)).toBlob();g.toPng=async(t,e)=>(await g.capture(t,e)).toPng(e);g.toJpg=async(t,e)=>(await g.capture(t,e)).toJpg(e);g.toWebp=async(t,e)=>(await g.capture(t,e)).toWebp(e);g.download=async(t,e={})=>{let{format:o="png",filename:n="capture",backgroundColor:a,...r}=e;return await(await g.capture(t,r)).download({format:o,filename:n,backgroundColor:a})};async function rt(t=document,e={}){let{embedFonts:o=!0,reset:n=!1,preWarm:a=!0}=e;if(n){S.clear(),E.clear(),R.clear(),k.clear(),U.clear();return}await document.fonts.ready,_();let r=[],i=[];t?.querySelectorAll&&(r=Array.from(t.querySelectorAll("img[src]")),i=Array.from(t.querySelectorAll("*")));let c=[];for(let s of r){let l=s.src;S.has(l)||c.push(x(l).then(d=>S.set(l,d)).catch(()=>{}))}for(let s of i){let l=getComputedStyle(s).backgroundImage,d=v(l);d&&!E.has(d)&&c.push(x(d).then(f=>E.set(d,f)).catch(()=>{}))}o&&await W({ignoreIconFonts:!o,preCached:!0}),await Promise.all(c)}window.snapdom=g;window.preCache=rt;})();
1
+ (()=>{var I=new Map,$=new Map,T=new Map,R=new Map,A=new Map,U=new WeakMap;var ce=["div","span","p","a","img","ul","li","button","input","select","textarea","label","section","article","header","footer","nav","main","aside","h1","h2","h3","h4","h5","h6","svg","path","circle","rect","line","g","table","thead","tbody","tr","td","th"];function z(){for(let e of ce)_(e)}function _(e){if(R.has(e))return R.get(e);if(new Set(["script","style","meta","link","noscript","template"]).has(e)){let i={};return R.set(e,i),i}let o=document.getElementById("snapdom-sandbox");o||(o=document.createElement("div"),o.id="snapdom-sandbox",o.style.position="absolute",o.style.left="-9999px",o.style.top="-9999px",o.style.width="0",o.style.height="0",o.style.overflow="hidden",document.body.appendChild(o));let n=document.createElement(e);n.style.all="initial",o.appendChild(n);let r=getComputedStyle(n),a={};for(let i of r)a[i]=r.getPropertyValue(i);return o.removeChild(n),R.set(e,a),a}function M(e,t,o=!1){let n=[],r=_(t);for(let[a,i]of Object.entries(e))if(!o)i&&n.push(`${a}:${i}`);else{let c=r[a];i&&i!==c&&n.push(`${a}:${i}`)}return n.sort().join(";")}function Y(e){let t=new Set;return e.nodeType!==Node.ELEMENT_NODE&&e.nodeType!==Node.DOCUMENT_FRAGMENT_NODE?[]:(e.tagName&&t.add(e.tagName.toLowerCase()),typeof e.querySelectorAll=="function"&&e.querySelectorAll("*").forEach(o=>t.add(o.tagName.toLowerCase())),Array.from(t))}function K(e){let t=new Map;for(let n of e){let r=R.get(n);if(!r)continue;let a=Object.entries(r).map(([i,c])=>`${i}:${c};`).sort().join("");t.has(a)||t.set(a,[]),t.get(a).push(n)}let o="";for(let[n,r]of t.entries())o+=`${r.join(",")} { ${n} }
2
+ `;return o}function J(e){let t=new Set(e.values()),o=new Map,n=1;for(let r of t)o.set(r,`c${n++}`);return o}function L(e,{fast:t=!1}={}){if(t)return e();"requestIdleCallback"in window?requestIdleCallback(e,{timeout:50}):setTimeout(e,1)}function N(e,t=null){if(!(e instanceof Element))return window.getComputedStyle(e,t);let o=U.get(e);if(o||(o=new Map,U.set(e,o)),!o.has(t)){let n=window.getComputedStyle(e,t);o.set(t,n)}return o.get(t)}function X(e){let t=e.replace(/^['"]|['"]$/g,"");if(t.startsWith("\\"))try{return String.fromCharCode(parseInt(t.replace("\\",""),16))}catch{return t}return t}function S(e){let t=e.indexOf("url(");if(t===-1)return null;let o=e.slice(t+4).trim();return o.endsWith(")")&&(o=o.slice(0,-1).trim()),(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),o}function B(e){return[/font\s*awesome/i,/material\s*icons/i,/ionicons/i,/glyphicons/i,/feather/i,/bootstrap\s*icons/i,/remix\s*icons/i,/heroicons/i].some(o=>o.test(e))}function x(e,t=3e3){return I.has(e)?Promise.resolve(I.get(e)):new Promise((o,n)=>{let r=setTimeout(()=>{n(new Error("Image load timed out"))},t),a=new Image;a.crossOrigin="anonymous",a.onload=async()=>{clearTimeout(r);try{await a.decode();let i=document.createElement("canvas");i.width=a.width,i.height=a.height,i.getContext("2d").drawImage(a,0,0,i.width,i.height);try{let s=i.toDataURL("image/png");I.set(e,s),o(s)}catch{n(new Error("CORS restrictions prevented image capture"))}}catch(i){n(i)}},a.onerror=i=>{clearTimeout(r),n(new Error("Failed to load image: "+(i.message||"Unknown error")))},a.src=e})}function F(e){let t={};for(let o of e)t[o]=e.getPropertyValue(o);return t}function D(){return/^((?!chrome|android).)*safari/i.test(navigator.userAgent)}function V(e,t,o,n,r){if(e.tagName==="STYLE")return;n.has(e)||n.set(e,N(e));let a=n.get(e),i=F(a),c=e.tagName?.toLowerCase()||"div",s=M(i,c,r);o.set(t,s)}function O(e,t,o,n,r){if(e.nodeType===Node.ELEMENT_NODE&&e.getAttribute("data-capture")==="exclude"){let c=document.createElement("div"),s=e.getBoundingClientRect();return c.style.cssText=`display: inline-block; width: ${s.width}px; height: ${s.height}px; visibility: hidden;`,c}if(e.tagName==="IFRAME"){let c=document.createElement("div");return c.textContent="",c.style.cssText=`width: ${e.offsetWidth}px; height: ${e.offsetHeight}px; background: repeating-linear-gradient(45deg, #ddd, #ddd 5px, #f9f9f9 5px, #f9f9f9 10px);display: flex;align-items: center;justify-content: center;font-size: 12px;color: #555; border: 1px solid #aaa;`,c}if(e.nodeType===Node.ELEMENT_NODE&&e.getAttribute("data-capture")==="placeholder"){let c=e.cloneNode(!1);n.set(c,e),V(e,c,t,o,r);let s=document.createElement("div");return s.textContent=e.getAttribute("data-placeholder-text")||"",s.style.cssText="color: #666;font-size: 12px;text-align: center;line-height: 1.4;padding: 0.5em;box-sizing: border-box;",c.appendChild(s),c}if(e.tagName==="CANVAS"){let c=e.toDataURL(),s=document.createElement("img");return s.src=c,s.width=e.width,s.height=e.height,s.style.display="inline-block",s.style.width=`${e.width}px`,s.style.height=`${e.height}px`,s}if(e.nodeType===Node.TEXT_NODE){if(e.parentElement?.shadowRoot){let c=e.parentElement.tagName.toLowerCase();if(customElements.get(c))return null}return e.cloneNode(!0)}if(e.nodeType!==Node.ELEMENT_NODE)return e.cloneNode(!0);let a=e.cloneNode(!1);n.set(a,e),e instanceof HTMLInputElement?(a.value=e.value,a.setAttribute("value",e.value),e.checked!==void 0&&(a.checked=e.checked,e.checked&&a.setAttribute("checked",""))):e instanceof HTMLTextAreaElement?(a.value=e.value,a.textContent=e.value):e instanceof HTMLSelectElement&&(a.value=e.value,Array.from(a.options).forEach(c=>{c.value===e.value?c.setAttribute("selected",""):c.removeAttribute("selected")})),V(e,a,t,o,r);let i=document.createDocumentFragment();if(e.childNodes.forEach(c=>{let s=O(c,t,o,n,r);s&&i.appendChild(s)}),a.appendChild(i),e.shadowRoot){let c=Array.from(e.shadowRoot.children).filter(l=>l.tagName!=="STYLE").map(l=>O(l,t,o,n)).filter(Boolean),s=document.createDocumentFragment();c.forEach(l=>s.appendChild(l)),a.appendChild(s)}return a}async function G(e,t,o,n=32,r="#000"){t=t.replace(/^['"]+|['"]+$/g,"");let a=window.devicePixelRatio||1,c=document.createElement("canvas").getContext("2d");c.font=o?`${o} ${n}px "${t}"`:`${n}px "${t}"`;let s=c.measureText(e),l=s.actualBoundingBoxAscent||n*.8,d=s.actualBoundingBoxDescent||n*.2,f=l+d,m=s.width,p=document.createElement("canvas");p.width=Math.ceil(m*a),p.height=Math.ceil(f*a);let h=p.getContext("2d");return h.scale(a,a),h.font=c.font,h.textAlign="left",h.textBaseline="alphabetic",h.fillStyle=r,h.fillText(e,0,l),p.toDataURL()}async function W({ignoreIconFonts:e=!0,preCached:t=!1}){let o=Array.from(document.querySelectorAll('link[rel="stylesheet"]')).filter(r=>r.href),n="";for(let r of o)try{let i=await(await fetch(r.href)).text();if(e&&(B(r.href)||B(i)))continue;let c=/url\(([^)]+)\)/g,s=await Promise.all(Array.from(i.matchAll(c)).map(async d=>{let f=S(d[0]);if(!f)return null;let m=f;m.startsWith("http")||(m=new URL(m,r.href).href);try{m=encodeURI(m)}catch{console.warn("[snapdom] Failed to encode font URL:",m)}if(e&&B(m))return null;if(T.has(m))return{original:d[0],inlined:`url(${T.get(m)})`};try{let h=await(await fetch(m)).blob(),w=await new Promise(E=>{let v=new FileReader;v.onload=()=>E(v.result),v.readAsDataURL(h)});return T.set(m,w),{original:d[0],inlined:`url(${w})`}}catch{return console.warn("\u274C Failed to fetch font:",m),null}})),l=i;for(let d of s)d&&(l=l.replace(d.original,d.inlined));n+=l+`
3
+ `}catch{console.warn("\u274C Failed to fetch CSS:",r.href)}if(n&&t){let r=document.createElement("style");r.setAttribute("data-snapdom","embedFonts"),r.textContent=n,document.head.appendChild(r)}return n}async function q(e,t,o,n,r,a=!1){if(!(e instanceof Element)||!(t instanceof Element))return;for(let s of["::before","::after"])try{let l=N(e,s);if(!l)continue;let d=l.getPropertyValue("content"),f=l.getPropertyValue("background-image"),m=d&&d!=="none"&&d!=='""'&&d!=="''",p=f&&f.startsWith("url(");if(m||p){let h=l.getPropertyValue("font-family"),w=parseInt(l.getPropertyValue("font-size"))||32,E=parseInt(l.getPropertyValue("font-weight"))||!1,v=l.getPropertyValue("color")||"#000",g=document.createElement("span");g.dataset.snapdomPseudo=s;let k=F(l),P=M(k,"span",r);o.set(g,P);let j=h&&/font.*awesome|material|bootstrap|glyphicons|ionicons|remixicon|simple-line-icons|octicons|feather|typicons|weathericons/i.test(h),C=X(d);if(!a&&j&&C.length===1){let y=document.createElement("img");y.src=await G(C,h,E,w,v),y.style="display:block;width:100%;height:100%;object-fit:contain;",g.appendChild(y)}else if(C.startsWith("url(")){let y=S(C);if(y)try{let b=document.createElement("img"),ie=await x(encodeURI(y));b.src=ie,b.style="display:block;width:100%;height:100%;object-fit:contain;",g.appendChild(b)}catch(b){console.error(`[snapdom] Error in pseudo ${s} for`,e,b)}}else!j&&C&&C!=="none"&&(g.textContent=C);if(p&&f){let y=S(f);if(y)try{let b=await x(encodeURI(y));g.style.backgroundImage=`url(${b})`}catch(b){console.warn(`[snapdom] Failed to inline background-image for ${s}`,b)}}if(!(g.childNodes.length>0||g.textContent&&g.textContent.trim()!=="")&&!p)continue;s==="::before"?t.insertBefore(g,t.firstChild):t.appendChild(g)}}catch(l){console.warn(`[snapdom] Failed to capture ${s} for`,e,l)}let i=Array.from(e.children),c=Array.from(t.children).filter(s=>!s.dataset.snapdomPseudo);for(let s=0;s<Math.min(i.length,c.length);s++)await q(i[s],c[s],o,n,r,a)}async function Q(e,t=!1,o=!1){let n=new Map,r=new WeakMap,a=new Map,i;try{i=O(e,n,r,a,t)}catch(s){throw console.warn("deepClone failed:",s),s}try{await q(e,i,n,r,t,o)}catch(s){console.warn("inlinePseudoElements failed:",s)}let c="";if(t){let s=J(n);c=Array.from(s.entries()).map(([l,d])=>`.${d}{${l}}`).join("");for(let[l,d]of n.entries()){if(l.tagName==="STYLE")continue;let f=s.get(d);f&&l.classList.add(f);let m=l.style?.backgroundImage;l.removeAttribute("style"),m&&m!=="none"&&(l.style.backgroundImage=m)}}else for(let[s,l]of n.entries())s.tagName!=="STYLE"&&s.setAttribute("style",l.replace(/;/g,"; "));for(let[s,l]of a.entries()){let d=l.scrollLeft,f=l.scrollTop;if((d||f)&&s instanceof HTMLElement){s.style.overflow="hidden",s.style.scrollbarWidth="none",s.style.msOverflowStyle="none";let p=document.createElement("div");for(p.style.transform=`translate(${-d}px, ${-f}px)`,p.style.willChange="transform",p.style.display="inline-block",p.style.width="100%";s.firstChild;)p.appendChild(s.firstChild);s.appendChild(p)}}return{clone:i,classCSS:c,styleCache:r}}async function Z(e){let t=Array.from(e.querySelectorAll("img")),o=async n=>{let r=n.src;try{let a=await x(r);n.src=a,n.width||(n.width=n.naturalWidth||100),n.height||(n.height=n.naturalHeight||100)}catch{let a=document.createElement("div");a.style=`width: ${n.width||100}px; height: ${n.height||100}px; background: #ccc; display: inline-block; text-align: center; line-height: ${n.height||100}px; color: #666; font-size: 12px;`,a.innerText="img",n.replaceWith(a)}};for(let n=0;n<t.length;n+=4){let r=t.slice(n,n+4).map(o);await Promise.allSettled(r)}}async function ee(e,t,o){let n=[[e,t]];for(;n.length;){let[r,a]=n.shift(),i=o.get(r)||N(r);o.has(r)||o.set(r,i);let c=i.getPropertyValue("background-image"),s=S(c);if(s)try{let f=encodeURI(s),m;$.has(f)?m=$.get(f):(m=await x(f),$.set(f,m)),a.style.backgroundImage=`url(${m})`}catch{a.style.backgroundImage="none"}let l=Array.from(r.children),d=Array.from(a.children);for(let f=0;f<Math.min(l.length,d.length);f++)n.push([l[f],d[f]])}}async function te(e,t={}){if(!e)throw new Error("Element cannot be null or undefined");let{compress:o=!0,embedFonts:n=!1,fast:r=!0,scale:a=1}=t,i,c,s,l="",d="",f,m;if({clone:i,classCSS:c,styleCache:s}=await Q(e,o,n),await new Promise(h=>{L(async()=>{await Z(i),h()},{fast:r})}),await new Promise(h=>{L(async()=>{await ee(e,i,s),h()},{fast:r})}),n&&await new Promise(h=>{L(async()=>{l=await W({ignoreIconFonts:!n}),h()},{fast:r})}),o){let h=Y(i).sort(),w=h.join(",");A.has(w)?d=A.get(w):await new Promise(E=>{L(()=>{d=K(h),A.set(w,d),E()},{fast:r})})}await new Promise(h=>{L(()=>{let w=e.getBoundingClientRect(),E=Math.ceil(w.width),v=Math.ceil(w.height);i.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),i.style.transformOrigin="top left",a!==1&&D()&&(i.style.scale=`${a}`);let g="http://www.w3.org/2000/svg",k=document.createElementNS(g,"foreignObject");k.setAttribute("width","100%"),k.setAttribute("height","100%");let P=document.createElement("style");P.textContent=d+l+"svg{overflow:visible;}"+c,k.appendChild(P),k.appendChild(i);let C=new XMLSerializer().serializeToString(k);m=`<svg xmlns="${g}" width="${E}" height="${v}" viewBox="0 0 ${E} ${v}">`+C+"</svg>",f=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(m)}`,h()},{fast:r})});let p=document.getElementById("snapdom-sandbox");return p&&p.style.position==="absolute"&&p.remove(),f}async function le(e,{dpr:t=1,scale:o=1}){let n=new Image;return n.src=e,await n.decode(),D?(n.width=n.width*o,n.height=n.height*o):(n.width=n.width/o,n.height=n.height/o),n}async function ne(e,{dpr:t=1,scale:o=1}={}){let n=new Image;n.src=e,await n.decode();let r=document.createElement("canvas"),a=n.width*o,i=n.height*o;r.width=Math.ceil(a*t),r.height=Math.ceil(i*t);let c=r.getContext("2d");return c.scale(t,t),c.drawImage(n,0,0,a,i),r.style.width=`${a}px`,r.style.height=`${i}px`,r}async function oe(e){let t=decodeURIComponent(e.split(",")[1]);return new Blob([t],{type:"image/svg+xml"})}async function ae(e,{dpr:t=1,scale:o=1},n){let r=await ne(e,{dpr:t,scale:o});if(!n)return r;let a=document.createElement("canvas");a.width=r.width,a.height=r.height;let i=a.getContext("2d");return i.fillStyle=n,i.fillRect(0,0,a.width,a.height),i.drawImage(r,0,0),a}async function H(e,{dpr:t=1,scale:o=1,backgroundColor:n="#fff",quality:r},a="png"){let i=await ae(e,{dpr:t,scale:o},n),c=new Image;return c.src=i.toDataURL(`image/${a}`,r),await c.decode(),c.style.width=`${i.width/t}px`,c.style.height=`${i.height/t}px`,c}async function de(e,{dpr:t=1,scale:o=1,backgroundColor:n="#fff",format:r="png",filename:a="capture"}={}){if(r==="svg"){let m=await oe(e),p=URL.createObjectURL(m),h=document.createElement("a");h.href=p,h.download=`${a}.svg`,h.click(),URL.revokeObjectURL(p);return}let i=["jpg","jpeg","webp"].includes(r)?"#fff":void 0,s=await ae(e,{dpr:t,scale:o},n??i),l={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp"}[r]||"image/png",d=s.toDataURL(l),f=document.createElement("a");f.href=d,f.download=`${a}.${r}`,f.click()}async function u(e,t={}){if(t={scale:1,...t},!e)throw new Error("Element cannot be null or undefined");return await u.capture(e,t)}u.capture=async(e,t={})=>{let o=await te(e,t),n=window.devicePixelRatio||1,r=t.scale||1;return{url:o,options:t,toRaw:()=>o,toImg:()=>le(o,{dpr:n,scale:r}),toCanvas:()=>ne(o,{dpr:n,scale:r}),toBlob:()=>oe(o),toPng:a=>H(o,{dpr:n,scale:r,...a},"png"),toJpg:a=>H(o,{dpr:n,scale:r,...a},"jpeg"),toWebp:a=>H(o,{dpr:n,scale:r,...a},"webp"),download:({format:a="png",filename:i="capture",backgroundColor:c}={})=>de(o,{dpr:n,scale:r,backgroundColor:c,format:a,filename:i})}};u.toRaw=async(e,t)=>(await u.capture(e,t)).toRaw();u.toImg=async(e,t)=>(await u.capture(e,t)).toImg();u.toCanvas=async(e,t)=>(await u.capture(e,t)).toCanvas();u.toBlob=async(e,t)=>(await u.capture(e,t)).toBlob();u.toPng=async(e,t)=>(await u.capture(e,t)).toPng(t);u.toJpg=async(e,t)=>(await u.capture(e,t)).toJpg(t);u.toWebp=async(e,t)=>(await u.capture(e,t)).toWebp(t);u.download=async(e,t={})=>{let{format:o="png",filename:n="capture",backgroundColor:r,...a}=t;return await(await u.capture(e,a)).download({format:o,filename:n,backgroundColor:r})};async function re(e=document,t={}){let{embedFonts:o=!0,reset:n=!1,preWarm:r=!0}=t;if(n){I.clear(),$.clear(),T.clear(),A.clear(),U.clear();return}await document.fonts.ready,z();let a=[],i=[];e?.querySelectorAll&&(a=Array.from(e.querySelectorAll("img[src]")),i=Array.from(e.querySelectorAll("*")));let c=[];for(let s of a){let l=s.src;I.has(l)||c.push(x(l).then(d=>I.set(l,d)).catch(()=>{}))}for(let s of i){let l=getComputedStyle(s).backgroundImage,d=S(l);d&&!$.has(d)&&c.push(x(d).then(f=>$.set(d,f)).catch(()=>{}))}o&&await W({ignoreIconFonts:!o,preCached:!0}),await Promise.all(c)}window.snapdom=u;window.preCache=re;})();
@@ -1,3 +1,3 @@
1
- var S=new Map,E=new Map,R=new Map,T=new Map,k=new Map,U=new WeakMap;var it=["div","span","p","a","img","ul","li","button","input","select","textarea","label","section","article","header","footer","nav","main","aside","h1","h2","h3","h4","h5","h6","svg","path","circle","rect","line","g","table","thead","tbody","tr","td","th"];function _(){for(let t of it)H(t)}function H(t){if(T.has(t))return T.get(t);if(new Set(["script","style","meta","link","noscript","template"]).has(t)){let i={};return T.set(t,i),i}let o=document.getElementById("snapdom-sandbox");o||(o=document.createElement("div"),o.id="snapdom-sandbox",o.style.position="absolute",o.style.left="-9999px",o.style.top="-9999px",o.style.width="0",o.style.height="0",o.style.overflow="hidden",document.body.appendChild(o));let n=document.createElement(t);n.style.all="initial",o.appendChild(n);let a=getComputedStyle(n),r={};for(let i of a)r[i]=a.getPropertyValue(i);return o.removeChild(n),T.set(t,r),r}function B(t,e,o=!1){let n=[],a=H(e);for(let[r,i]of Object.entries(t))if(!o)i&&n.push(`${r}:${i}`);else{let c=a[r];i&&i!==c&&n.push(`${r}:${i}`)}return n.sort().join(";")}function Y(t){let e=new Set;return t.nodeType!==Node.ELEMENT_NODE&&t.nodeType!==Node.DOCUMENT_FRAGMENT_NODE?[]:(t.tagName&&e.add(t.tagName.toLowerCase()),typeof t.querySelectorAll=="function"&&t.querySelectorAll("*").forEach(o=>e.add(o.tagName.toLowerCase())),Array.from(e))}function K(t){let e=new Map;for(let n of t){let a=T.get(n);if(!a)continue;let r=Object.entries(a).map(([i,c])=>`${i}:${c};`).sort().join("");e.has(r)||e.set(r,[]),e.get(r).push(n)}let o="";for(let[n,a]of e.entries())o+=`${a.join(",")} { ${n} }
2
- `;return o}function J(t){let e=new Set(t.values()),o=new Map,n=1;for(let a of e)o.set(a,`c${n++}`);return o}function N(t,{fast:e=!1}={}){if(e)return t();"requestIdleCallback"in window?requestIdleCallback(t,{timeout:50}):setTimeout(t,1)}function A(t,e=null){if(!(t instanceof Element))return window.getComputedStyle(t,e);let o=U.get(t);if(o||(o=new Map,U.set(t,o)),!o.has(e)){let n=window.getComputedStyle(t,e);o.set(e,n)}return o.get(e)}function X(t){let e=t.replace(/^['"]|['"]$/g,"");if(e.startsWith("\\"))try{return String.fromCharCode(parseInt(e.replace("\\",""),16))}catch{return e}return e}function v(t){let e=t.indexOf("url(");if(e===-1)return null;let o=t.slice(e+4).trim();return o.endsWith(")")&&(o=o.slice(0,-1).trim()),(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),o}function M(t){return[/font\s*awesome/i,/material\s*icons/i,/ionicons/i,/glyphicons/i,/feather/i,/bootstrap\s*icons/i,/remix\s*icons/i,/heroicons/i].some(o=>o.test(t))}function x(t,e=3e3){return S.has(t)?Promise.resolve(S.get(t)):new Promise((o,n)=>{let a=setTimeout(()=>{n(new Error("Image load timed out"))},e),r=new Image;r.crossOrigin="anonymous",r.onload=async()=>{clearTimeout(a);try{await r.decode();let i=document.createElement("canvas");i.width=r.width,i.height=r.height,i.getContext("2d").drawImage(r,0,0);try{let s=i.toDataURL("image/png");S.set(t,s),o(s)}catch{n(new Error("CORS restrictions prevented image capture"))}}catch(i){n(i)}},r.onerror=i=>{clearTimeout(a),n(new Error("Failed to load image: "+(i.message||"Unknown error")))},r.src=t})}function F(t){let e={};for(let o of t)e[o]=t.getPropertyValue(o);return e}function D(){return/^((?!chrome|android).)*safari/i.test(navigator.userAgent)}function V(t,e,o,n,a){if(t.tagName==="STYLE")return;n.has(t)||n.set(t,A(t));let r=n.get(t),i=F(r),c=t.tagName?.toLowerCase()||"div",s=B(i,c,a);o.set(e,s)}function O(t,e,o,n,a){if(t.nodeType===Node.ELEMENT_NODE&&t.getAttribute("data-capture")==="exclude"){let c=document.createElement("div"),s=t.getBoundingClientRect();return c.style.cssText=`display: inline-block; width: ${s.width}px; height: ${s.height}px; visibility: hidden;`,c}if(t.tagName==="IFRAME"){let c=document.createElement("div");return c.textContent="",c.style.cssText=`width: ${t.offsetWidth}px; height: ${t.offsetHeight}px; background: repeating-linear-gradient(45deg, #ddd, #ddd 5px, #f9f9f9 5px, #f9f9f9 10px);display: flex;align-items: center;justify-content: center;font-size: 12px;color: #555; border: 1px solid #aaa;`,c}if(t.nodeType===Node.ELEMENT_NODE&&t.getAttribute("data-capture")==="placeholder"){let c=t.cloneNode(!1);n.set(c,t),V(t,c,e,o,a);let s=document.createElement("div");return s.textContent=t.getAttribute("data-placeholder-text")||"",s.style.cssText="color: #666;font-size: 12px;text-align: center;line-height: 1.4;padding: 0.5em;box-sizing: border-box;",c.appendChild(s),c}if(t.tagName==="CANVAS"){let c=t.toDataURL(),s=document.createElement("img");return s.src=c,s.width=t.width,s.height=t.height,s.style.display="inline-block",s.style.width=`${t.width}px`,s.style.height=`${t.height}px`,s}if(t.nodeType===Node.TEXT_NODE){if(t.parentElement?.shadowRoot){let c=t.parentElement.tagName.toLowerCase();if(customElements.get(c))return null}return t.cloneNode(!0)}if(t.nodeType!==Node.ELEMENT_NODE)return t.cloneNode(!0);let r=t.cloneNode(!1);n.set(r,t),V(t,r,e,o,a);let i=document.createDocumentFragment();if(t.childNodes.forEach(c=>{let s=O(c,e,o,n,a);s&&i.appendChild(s)}),r.appendChild(i),t.shadowRoot){let c=Array.from(t.shadowRoot.children).filter(l=>l.tagName!=="STYLE").map(l=>O(l,e,o,n)).filter(Boolean),s=document.createDocumentFragment();c.forEach(l=>s.appendChild(l)),r.appendChild(s)}return r}async function G(t,e,o,n=32,a="#000"){e=e.replace(/^['"]+|['"]+$/g,"");let r=window.devicePixelRatio||1,c=document.createElement("canvas").getContext("2d");c.font=o?`${o} ${n}px "${e}"`:`${n}px "${e}"`;let s=c.measureText(t),l=s.actualBoundingBoxAscent||n*.8,d=s.actualBoundingBoxDescent||n*.2,f=l+d,m=s.width,h=document.createElement("canvas");h.width=Math.ceil(m*r),h.height=Math.ceil(f*r);let p=h.getContext("2d");return p.scale(r,r),p.font=c.font,p.textAlign="left",p.textBaseline="alphabetic",p.fillStyle=a,p.fillText(t,0,l),h.toDataURL()}async function W({ignoreIconFonts:t=!0,preCached:e=!1}){let o=Array.from(document.querySelectorAll('link[rel="stylesheet"]')).filter(a=>a.href),n="";for(let a of o)try{let i=await(await fetch(a.href)).text();if(t&&(M(a.href)||M(i)))continue;let c=/url\(([^)]+)\)/g,s=await Promise.all(Array.from(i.matchAll(c)).map(async d=>{let f=v(d[0]);if(!f)return null;let m=f;m.startsWith("http")||(m=new URL(m,a.href).href);try{m=encodeURI(m)}catch{console.warn("[snapdom] Failed to encode font URL:",m)}if(t&&M(m))return null;if(R.has(m))return{original:d[0],inlined:`url(${R.get(m)})`};try{let p=await(await fetch(m)).blob(),w=await new Promise(C=>{let b=new FileReader;b.onload=()=>C(b.result),b.readAsDataURL(p)});return R.set(m,w),{original:d[0],inlined:`url(${w})`}}catch{return console.warn("\u274C Failed to fetch font:",m),null}})),l=i;for(let d of s)d&&(l=l.replace(d.original,d.inlined));n+=l+`
3
- `}catch{console.warn("\u274C Failed to fetch CSS:",a.href)}if(n&&e){let a=document.createElement("style");a.setAttribute("data-snapdom","embedFonts"),a.textContent=n,document.head.appendChild(a)}return n}async function q(t,e,o,n,a,r=!1){if(!(t instanceof Element)||!(e instanceof Element))return;for(let s of["::before","::after"])try{let l=A(t,s);if(!l)continue;let d=l.getPropertyValue("content"),f=l.getPropertyValue("background-image"),m=d&&d!=="none"&&d!=='""'&&d!=="''",h=f&&f.startsWith("url(");if(m||h){let p=l.getPropertyValue("font-family"),w=parseInt(l.getPropertyValue("font-size"))||32,C=parseInt(l.getPropertyValue("font-weight"))||!1,b=l.getPropertyValue("color")||"#000",u=document.createElement("span");u.dataset.snapdomPseudo=s;let I=F(l),P=B(I,"span",a);o.set(u,P);let j=p&&/font.*awesome|material|bootstrap|glyphicons|ionicons|remixicon|simple-line-icons|octicons|feather|typicons|weathericons/i.test(p),y=X(d);if(!r&&j&&y.length===1){let $=document.createElement("img");$.src=await G(y,p,C,w,b),$.style="display:block;width:100%;height:100%;object-fit:contain;",u.appendChild($)}else if(y.startsWith("url(")){let $=v(y);if($)try{let L=document.createElement("img"),st=await x(encodeURI($));L.src=st,L.style="display:block;width:100%;height:100%;object-fit:contain;",u.appendChild(L)}catch(L){console.error(`[snapdom] Error in pseudo ${s} for`,t,L)}}else!j&&y&&y!=="none"&&(u.textContent=y);if(!(u.childNodes.length>0||u.textContent&&u.textContent.trim()!==""))continue;s==="::before"?e.insertBefore(u,e.firstChild):e.appendChild(u)}}catch(l){console.warn(`[snapdom] Failed to capture ${s} for`,t,l)}let i=Array.from(t.children),c=Array.from(e.children).filter(s=>!s.dataset.snapdomPseudo);for(let s=0;s<Math.min(i.length,c.length);s++)await q(i[s],c[s],o,n,a,r)}async function Q(t,e=!1,o=!1){let n=new Map,a=new WeakMap,r=new Map,i;try{i=O(t,n,a,r,e)}catch(s){throw console.warn("deepClone failed:",s),s}try{await q(t,i,n,a,e,o)}catch(s){console.warn("inlinePseudoElements failed:",s)}let c="";if(e){let s=J(n);c=Array.from(s.entries()).map(([l,d])=>`.${d}{${l}}`).join("");for(let[l,d]of n.entries()){if(l.tagName==="STYLE")continue;let f=s.get(d);f&&l.classList.add(f);let m=l.style?.backgroundImage;l.removeAttribute("style"),m&&m!=="none"&&(l.style.backgroundImage=m)}}else for(let[s,l]of n.entries())s.tagName!=="STYLE"&&s.setAttribute("style",l.replace(/;/g,"; "));for(let[s,l]of r.entries()){let d=l.scrollLeft,f=l.scrollTop;if((d||f)&&s instanceof HTMLElement){s.style.overflow="hidden",s.style.scrollbarWidth="none",s.style.msOverflowStyle="none";let h=document.createElement("div");for(h.style.transform=`translate(${-d}px, ${-f}px)`,h.style.willChange="transform",h.style.display="inline-block",h.style.width="100%";s.firstChild;)h.appendChild(s.firstChild);s.appendChild(h)}}return{clone:i,classCSS:c,styleCache:a}}async function Z(t){let e=Array.from(t.querySelectorAll("img")),o=async n=>{let a=n.src;try{let r=await x(a);n.src=r,n.width||(n.width=n.naturalWidth||100),n.height||(n.height=n.naturalHeight||100)}catch{let r=document.createElement("div");r.style=`width: ${n.width||100}px; height: ${n.height||100}px; background: #ccc; display: inline-block; text-align: center; line-height: ${n.height||100}px; color: #666; font-size: 12px;`,r.innerText="img",n.replaceWith(r)}};for(let n=0;n<e.length;n+=4){let a=e.slice(n,n+4).map(o);await Promise.allSettled(a)}}async function tt(t,e,o){let n=[[t,e]];for(;n.length;){let[a,r]=n.shift(),i=o.get(a)||A(a);o.has(a)||o.set(a,i);let c=i.getPropertyValue("background-image"),s=v(c);if(s)try{let f=encodeURI(s),m;E.has(f)?m=E.get(f):(m=await x(f),E.set(f,m)),r.style.backgroundImage=`url(${m})`}catch{r.style.backgroundImage="none"}let l=Array.from(a.children),d=Array.from(r.children);for(let f=0;f<Math.min(l.length,d.length);f++)n.push([l[f],d[f]])}}async function et(t,e={}){if(!t)throw new Error("Element cannot be null or undefined");let{compress:o=!0,embedFonts:n=!1,fast:a=!0,scale:r=1}=e,i,c,s,l="",d="",f,m;if({clone:i,classCSS:c,styleCache:s}=await Q(t,o,n),await new Promise(p=>{N(async()=>{await Z(i),p()},{fast:a})}),await new Promise(p=>{N(async()=>{await tt(t,i,s),p()},{fast:a})}),n&&await new Promise(p=>{N(async()=>{l=await W({ignoreIconFonts:!n}),p()},{fast:a})}),o){let p=Y(i).sort(),w=p.join(",");k.has(w)?d=k.get(w):await new Promise(C=>{N(()=>{d=K(p),k.set(w,d),C()},{fast:a})})}await new Promise(p=>{N(()=>{let w=t.getBoundingClientRect(),C=Math.ceil(w.width),b=Math.ceil(w.height);i.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),i.style.transformOrigin="top left",r!==1&&D()&&(i.style.scale=`${r}`);let u="http://www.w3.org/2000/svg",I=document.createElementNS(u,"foreignObject");I.setAttribute("width","100%"),I.setAttribute("height","100%");let P=document.createElement("style");P.textContent=d+l+"svg{overflow:visible;}"+c,I.appendChild(P),I.appendChild(i);let y=new XMLSerializer().serializeToString(I);m=`<svg xmlns="${u}" width="${C}" height="${b}" viewBox="0 0 ${C} ${b}">`+y+"</svg>",f=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(m)}`,p()},{fast:a})});let h=document.getElementById("snapdom-sandbox");return h&&h.style.position==="absolute"&&h.remove(),f}async function ct(t,{dpr:e=1,scale:o=1}){let n=new Image;return n.src=t,await n.decode(),D?(n.width=n.width*o,n.height=n.height*o):(n.width=n.width/o,n.height=n.height/o),n}async function nt(t,{dpr:e=1,scale:o=1}){let n=new Image;n.src=t,await n.decode();let a=document.createElement("canvas"),r=n.width*o*e,i=n.height*o*e;a.width=Math.ceil(r),a.height=Math.ceil(i);let c=a.getContext("2d");return c.scale(o*e,o*e),c.drawImage(n,0,0),a.style.width=`${a.width/e}px`,a.style.height=`${a.height/e}px`,a}async function ot(t){let e=decodeURIComponent(t.split(",")[1]);return new Blob([e],{type:"image/svg+xml"})}async function at(t,{dpr:e=1,scale:o=1},n){let a=await nt(t,{dpr:e,scale:o});if(!n)return a;let r=document.createElement("canvas");r.width=a.width,r.height=a.height;let i=r.getContext("2d");return i.fillStyle=n,i.fillRect(0,0,r.width,r.height),i.drawImage(a,0,0),r}async function z(t,{dpr:e=1,scale:o=1,backgroundColor:n="#fff",quality:a},r="png"){let i=await at(t,{dpr:e,scale:o},n),c=new Image;return c.src=i.toDataURL(`image/${r}`,a),await c.decode(),c.style.width=`${i.width/e}px`,c.style.height=`${i.height/e}px`,c}async function lt(t,{dpr:e=1,scale:o=1,backgroundColor:n="#fff",format:a="png",filename:r="capture"}={}){if(a==="svg"){let m=await ot(t),h=URL.createObjectURL(m),p=document.createElement("a");p.href=h,p.download=`${r}.svg`,p.click(),URL.revokeObjectURL(h);return}let i=["jpg","jpeg","webp"].includes(a)?"#fff":void 0,s=await at(t,{dpr:e,scale:o},n??i),l={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp"}[a]||"image/png",d=s.toDataURL(l),f=document.createElement("a");f.href=d,f.download=`${r}.${a}`,f.click()}async function g(t,e={}){if(e={scale:1,...e},!t)throw new Error("Element cannot be null or undefined");return await g.capture(t,e)}g.capture=async(t,e={})=>{let o=await et(t,e),n=window.devicePixelRatio||1,a=e.scale||1;return{url:o,options:e,toRaw:()=>o,toImg:()=>ct(o,{dpr:n,scale:a}),toCanvas:()=>nt(o,{dpr:n,scale:a}),toBlob:()=>ot(o),toPng:r=>z(o,{dpr:n,scale:a,...r},"png"),toJpg:r=>z(o,{dpr:n,scale:a,...r},"jpeg"),toWebp:r=>z(o,{dpr:n,scale:a,...r},"webp"),download:({format:r="png",filename:i="capture",backgroundColor:c}={})=>lt(o,{dpr:n,scale:a,backgroundColor:c,format:r,filename:i})}};g.toRaw=async(t,e)=>(await g.capture(t,e)).toRaw();g.toImg=async(t,e)=>(await g.capture(t,e)).toImg();g.toCanvas=async(t,e)=>(await g.capture(t,e)).toCanvas();g.toBlob=async(t,e)=>(await g.capture(t,e)).toBlob();g.toPng=async(t,e)=>(await g.capture(t,e)).toPng(e);g.toJpg=async(t,e)=>(await g.capture(t,e)).toJpg(e);g.toWebp=async(t,e)=>(await g.capture(t,e)).toWebp(e);g.download=async(t,e={})=>{let{format:o="png",filename:n="capture",backgroundColor:a,...r}=e;return await(await g.capture(t,r)).download({format:o,filename:n,backgroundColor:a})};async function dt(t=document,e={}){let{embedFonts:o=!0,reset:n=!1,preWarm:a=!0}=e;if(n){S.clear(),E.clear(),R.clear(),k.clear(),U.clear();return}await document.fonts.ready,_();let r=[],i=[];t?.querySelectorAll&&(r=Array.from(t.querySelectorAll("img[src]")),i=Array.from(t.querySelectorAll("*")));let c=[];for(let s of r){let l=s.src;S.has(l)||c.push(x(l).then(d=>S.set(l,d)).catch(()=>{}))}for(let s of i){let l=getComputedStyle(s).backgroundImage,d=v(l);d&&!E.has(d)&&c.push(x(d).then(f=>E.set(d,f)).catch(()=>{}))}o&&await W({ignoreIconFonts:!o,preCached:!0}),await Promise.all(c)}export{dt as preCache,g as snapdom};
1
+ var I=new Map,$=new Map,T=new Map,R=new Map,A=new Map,U=new WeakMap;var ie=["div","span","p","a","img","ul","li","button","input","select","textarea","label","section","article","header","footer","nav","main","aside","h1","h2","h3","h4","h5","h6","svg","path","circle","rect","line","g","table","thead","tbody","tr","td","th"];function z(){for(let e of ie)_(e)}function _(e){if(R.has(e))return R.get(e);if(new Set(["script","style","meta","link","noscript","template"]).has(e)){let i={};return R.set(e,i),i}let o=document.getElementById("snapdom-sandbox");o||(o=document.createElement("div"),o.id="snapdom-sandbox",o.style.position="absolute",o.style.left="-9999px",o.style.top="-9999px",o.style.width="0",o.style.height="0",o.style.overflow="hidden",document.body.appendChild(o));let n=document.createElement(e);n.style.all="initial",o.appendChild(n);let r=getComputedStyle(n),a={};for(let i of r)a[i]=r.getPropertyValue(i);return o.removeChild(n),R.set(e,a),a}function M(e,t,o=!1){let n=[],r=_(t);for(let[a,i]of Object.entries(e))if(!o)i&&n.push(`${a}:${i}`);else{let c=r[a];i&&i!==c&&n.push(`${a}:${i}`)}return n.sort().join(";")}function Y(e){let t=new Set;return e.nodeType!==Node.ELEMENT_NODE&&e.nodeType!==Node.DOCUMENT_FRAGMENT_NODE?[]:(e.tagName&&t.add(e.tagName.toLowerCase()),typeof e.querySelectorAll=="function"&&e.querySelectorAll("*").forEach(o=>t.add(o.tagName.toLowerCase())),Array.from(t))}function K(e){let t=new Map;for(let n of e){let r=R.get(n);if(!r)continue;let a=Object.entries(r).map(([i,c])=>`${i}:${c};`).sort().join("");t.has(a)||t.set(a,[]),t.get(a).push(n)}let o="";for(let[n,r]of t.entries())o+=`${r.join(",")} { ${n} }
2
+ `;return o}function J(e){let t=new Set(e.values()),o=new Map,n=1;for(let r of t)o.set(r,`c${n++}`);return o}function L(e,{fast:t=!1}={}){if(t)return e();"requestIdleCallback"in window?requestIdleCallback(e,{timeout:50}):setTimeout(e,1)}function N(e,t=null){if(!(e instanceof Element))return window.getComputedStyle(e,t);let o=U.get(e);if(o||(o=new Map,U.set(e,o)),!o.has(t)){let n=window.getComputedStyle(e,t);o.set(t,n)}return o.get(t)}function X(e){let t=e.replace(/^['"]|['"]$/g,"");if(t.startsWith("\\"))try{return String.fromCharCode(parseInt(t.replace("\\",""),16))}catch{return t}return t}function S(e){let t=e.indexOf("url(");if(t===-1)return null;let o=e.slice(t+4).trim();return o.endsWith(")")&&(o=o.slice(0,-1).trim()),(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),o}function B(e){return[/font\s*awesome/i,/material\s*icons/i,/ionicons/i,/glyphicons/i,/feather/i,/bootstrap\s*icons/i,/remix\s*icons/i,/heroicons/i].some(o=>o.test(e))}function x(e,t=3e3){return I.has(e)?Promise.resolve(I.get(e)):new Promise((o,n)=>{let r=setTimeout(()=>{n(new Error("Image load timed out"))},t),a=new Image;a.crossOrigin="anonymous",a.onload=async()=>{clearTimeout(r);try{await a.decode();let i=document.createElement("canvas");i.width=a.width,i.height=a.height,i.getContext("2d").drawImage(a,0,0,i.width,i.height);try{let s=i.toDataURL("image/png");I.set(e,s),o(s)}catch{n(new Error("CORS restrictions prevented image capture"))}}catch(i){n(i)}},a.onerror=i=>{clearTimeout(r),n(new Error("Failed to load image: "+(i.message||"Unknown error")))},a.src=e})}function F(e){let t={};for(let o of e)t[o]=e.getPropertyValue(o);return t}function D(){return/^((?!chrome|android).)*safari/i.test(navigator.userAgent)}function V(e,t,o,n,r){if(e.tagName==="STYLE")return;n.has(e)||n.set(e,N(e));let a=n.get(e),i=F(a),c=e.tagName?.toLowerCase()||"div",s=M(i,c,r);o.set(t,s)}function O(e,t,o,n,r){if(e.nodeType===Node.ELEMENT_NODE&&e.getAttribute("data-capture")==="exclude"){let c=document.createElement("div"),s=e.getBoundingClientRect();return c.style.cssText=`display: inline-block; width: ${s.width}px; height: ${s.height}px; visibility: hidden;`,c}if(e.tagName==="IFRAME"){let c=document.createElement("div");return c.textContent="",c.style.cssText=`width: ${e.offsetWidth}px; height: ${e.offsetHeight}px; background: repeating-linear-gradient(45deg, #ddd, #ddd 5px, #f9f9f9 5px, #f9f9f9 10px);display: flex;align-items: center;justify-content: center;font-size: 12px;color: #555; border: 1px solid #aaa;`,c}if(e.nodeType===Node.ELEMENT_NODE&&e.getAttribute("data-capture")==="placeholder"){let c=e.cloneNode(!1);n.set(c,e),V(e,c,t,o,r);let s=document.createElement("div");return s.textContent=e.getAttribute("data-placeholder-text")||"",s.style.cssText="color: #666;font-size: 12px;text-align: center;line-height: 1.4;padding: 0.5em;box-sizing: border-box;",c.appendChild(s),c}if(e.tagName==="CANVAS"){let c=e.toDataURL(),s=document.createElement("img");return s.src=c,s.width=e.width,s.height=e.height,s.style.display="inline-block",s.style.width=`${e.width}px`,s.style.height=`${e.height}px`,s}if(e.nodeType===Node.TEXT_NODE){if(e.parentElement?.shadowRoot){let c=e.parentElement.tagName.toLowerCase();if(customElements.get(c))return null}return e.cloneNode(!0)}if(e.nodeType!==Node.ELEMENT_NODE)return e.cloneNode(!0);let a=e.cloneNode(!1);n.set(a,e),e instanceof HTMLInputElement?(a.value=e.value,a.setAttribute("value",e.value),e.checked!==void 0&&(a.checked=e.checked,e.checked&&a.setAttribute("checked",""))):e instanceof HTMLTextAreaElement?(a.value=e.value,a.textContent=e.value):e instanceof HTMLSelectElement&&(a.value=e.value,Array.from(a.options).forEach(c=>{c.value===e.value?c.setAttribute("selected",""):c.removeAttribute("selected")})),V(e,a,t,o,r);let i=document.createDocumentFragment();if(e.childNodes.forEach(c=>{let s=O(c,t,o,n,r);s&&i.appendChild(s)}),a.appendChild(i),e.shadowRoot){let c=Array.from(e.shadowRoot.children).filter(l=>l.tagName!=="STYLE").map(l=>O(l,t,o,n)).filter(Boolean),s=document.createDocumentFragment();c.forEach(l=>s.appendChild(l)),a.appendChild(s)}return a}async function G(e,t,o,n=32,r="#000"){t=t.replace(/^['"]+|['"]+$/g,"");let a=window.devicePixelRatio||1,c=document.createElement("canvas").getContext("2d");c.font=o?`${o} ${n}px "${t}"`:`${n}px "${t}"`;let s=c.measureText(e),l=s.actualBoundingBoxAscent||n*.8,d=s.actualBoundingBoxDescent||n*.2,f=l+d,m=s.width,p=document.createElement("canvas");p.width=Math.ceil(m*a),p.height=Math.ceil(f*a);let h=p.getContext("2d");return h.scale(a,a),h.font=c.font,h.textAlign="left",h.textBaseline="alphabetic",h.fillStyle=r,h.fillText(e,0,l),p.toDataURL()}async function W({ignoreIconFonts:e=!0,preCached:t=!1}){let o=Array.from(document.querySelectorAll('link[rel="stylesheet"]')).filter(r=>r.href),n="";for(let r of o)try{let i=await(await fetch(r.href)).text();if(e&&(B(r.href)||B(i)))continue;let c=/url\(([^)]+)\)/g,s=await Promise.all(Array.from(i.matchAll(c)).map(async d=>{let f=S(d[0]);if(!f)return null;let m=f;m.startsWith("http")||(m=new URL(m,r.href).href);try{m=encodeURI(m)}catch{console.warn("[snapdom] Failed to encode font URL:",m)}if(e&&B(m))return null;if(T.has(m))return{original:d[0],inlined:`url(${T.get(m)})`};try{let h=await(await fetch(m)).blob(),w=await new Promise(E=>{let v=new FileReader;v.onload=()=>E(v.result),v.readAsDataURL(h)});return T.set(m,w),{original:d[0],inlined:`url(${w})`}}catch{return console.warn("\u274C Failed to fetch font:",m),null}})),l=i;for(let d of s)d&&(l=l.replace(d.original,d.inlined));n+=l+`
3
+ `}catch{console.warn("\u274C Failed to fetch CSS:",r.href)}if(n&&t){let r=document.createElement("style");r.setAttribute("data-snapdom","embedFonts"),r.textContent=n,document.head.appendChild(r)}return n}async function q(e,t,o,n,r,a=!1){if(!(e instanceof Element)||!(t instanceof Element))return;for(let s of["::before","::after"])try{let l=N(e,s);if(!l)continue;let d=l.getPropertyValue("content"),f=l.getPropertyValue("background-image"),m=d&&d!=="none"&&d!=='""'&&d!=="''",p=f&&f.startsWith("url(");if(m||p){let h=l.getPropertyValue("font-family"),w=parseInt(l.getPropertyValue("font-size"))||32,E=parseInt(l.getPropertyValue("font-weight"))||!1,v=l.getPropertyValue("color")||"#000",g=document.createElement("span");g.dataset.snapdomPseudo=s;let k=F(l),P=M(k,"span",r);o.set(g,P);let j=h&&/font.*awesome|material|bootstrap|glyphicons|ionicons|remixicon|simple-line-icons|octicons|feather|typicons|weathericons/i.test(h),C=X(d);if(!a&&j&&C.length===1){let y=document.createElement("img");y.src=await G(C,h,E,w,v),y.style="display:block;width:100%;height:100%;object-fit:contain;",g.appendChild(y)}else if(C.startsWith("url(")){let y=S(C);if(y)try{let b=document.createElement("img"),se=await x(encodeURI(y));b.src=se,b.style="display:block;width:100%;height:100%;object-fit:contain;",g.appendChild(b)}catch(b){console.error(`[snapdom] Error in pseudo ${s} for`,e,b)}}else!j&&C&&C!=="none"&&(g.textContent=C);if(p&&f){let y=S(f);if(y)try{let b=await x(encodeURI(y));g.style.backgroundImage=`url(${b})`}catch(b){console.warn(`[snapdom] Failed to inline background-image for ${s}`,b)}}if(!(g.childNodes.length>0||g.textContent&&g.textContent.trim()!=="")&&!p)continue;s==="::before"?t.insertBefore(g,t.firstChild):t.appendChild(g)}}catch(l){console.warn(`[snapdom] Failed to capture ${s} for`,e,l)}let i=Array.from(e.children),c=Array.from(t.children).filter(s=>!s.dataset.snapdomPseudo);for(let s=0;s<Math.min(i.length,c.length);s++)await q(i[s],c[s],o,n,r,a)}async function Q(e,t=!1,o=!1){let n=new Map,r=new WeakMap,a=new Map,i;try{i=O(e,n,r,a,t)}catch(s){throw console.warn("deepClone failed:",s),s}try{await q(e,i,n,r,t,o)}catch(s){console.warn("inlinePseudoElements failed:",s)}let c="";if(t){let s=J(n);c=Array.from(s.entries()).map(([l,d])=>`.${d}{${l}}`).join("");for(let[l,d]of n.entries()){if(l.tagName==="STYLE")continue;let f=s.get(d);f&&l.classList.add(f);let m=l.style?.backgroundImage;l.removeAttribute("style"),m&&m!=="none"&&(l.style.backgroundImage=m)}}else for(let[s,l]of n.entries())s.tagName!=="STYLE"&&s.setAttribute("style",l.replace(/;/g,"; "));for(let[s,l]of a.entries()){let d=l.scrollLeft,f=l.scrollTop;if((d||f)&&s instanceof HTMLElement){s.style.overflow="hidden",s.style.scrollbarWidth="none",s.style.msOverflowStyle="none";let p=document.createElement("div");for(p.style.transform=`translate(${-d}px, ${-f}px)`,p.style.willChange="transform",p.style.display="inline-block",p.style.width="100%";s.firstChild;)p.appendChild(s.firstChild);s.appendChild(p)}}return{clone:i,classCSS:c,styleCache:r}}async function Z(e){let t=Array.from(e.querySelectorAll("img")),o=async n=>{let r=n.src;try{let a=await x(r);n.src=a,n.width||(n.width=n.naturalWidth||100),n.height||(n.height=n.naturalHeight||100)}catch{let a=document.createElement("div");a.style=`width: ${n.width||100}px; height: ${n.height||100}px; background: #ccc; display: inline-block; text-align: center; line-height: ${n.height||100}px; color: #666; font-size: 12px;`,a.innerText="img",n.replaceWith(a)}};for(let n=0;n<t.length;n+=4){let r=t.slice(n,n+4).map(o);await Promise.allSettled(r)}}async function ee(e,t,o){let n=[[e,t]];for(;n.length;){let[r,a]=n.shift(),i=o.get(r)||N(r);o.has(r)||o.set(r,i);let c=i.getPropertyValue("background-image"),s=S(c);if(s)try{let f=encodeURI(s),m;$.has(f)?m=$.get(f):(m=await x(f),$.set(f,m)),a.style.backgroundImage=`url(${m})`}catch{a.style.backgroundImage="none"}let l=Array.from(r.children),d=Array.from(a.children);for(let f=0;f<Math.min(l.length,d.length);f++)n.push([l[f],d[f]])}}async function te(e,t={}){if(!e)throw new Error("Element cannot be null or undefined");let{compress:o=!0,embedFonts:n=!1,fast:r=!0,scale:a=1}=t,i,c,s,l="",d="",f,m;if({clone:i,classCSS:c,styleCache:s}=await Q(e,o,n),await new Promise(h=>{L(async()=>{await Z(i),h()},{fast:r})}),await new Promise(h=>{L(async()=>{await ee(e,i,s),h()},{fast:r})}),n&&await new Promise(h=>{L(async()=>{l=await W({ignoreIconFonts:!n}),h()},{fast:r})}),o){let h=Y(i).sort(),w=h.join(",");A.has(w)?d=A.get(w):await new Promise(E=>{L(()=>{d=K(h),A.set(w,d),E()},{fast:r})})}await new Promise(h=>{L(()=>{let w=e.getBoundingClientRect(),E=Math.ceil(w.width),v=Math.ceil(w.height);i.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),i.style.transformOrigin="top left",a!==1&&D()&&(i.style.scale=`${a}`);let g="http://www.w3.org/2000/svg",k=document.createElementNS(g,"foreignObject");k.setAttribute("width","100%"),k.setAttribute("height","100%");let P=document.createElement("style");P.textContent=d+l+"svg{overflow:visible;}"+c,k.appendChild(P),k.appendChild(i);let C=new XMLSerializer().serializeToString(k);m=`<svg xmlns="${g}" width="${E}" height="${v}" viewBox="0 0 ${E} ${v}">`+C+"</svg>",f=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(m)}`,h()},{fast:r})});let p=document.getElementById("snapdom-sandbox");return p&&p.style.position==="absolute"&&p.remove(),f}async function ce(e,{dpr:t=1,scale:o=1}){let n=new Image;return n.src=e,await n.decode(),D?(n.width=n.width*o,n.height=n.height*o):(n.width=n.width/o,n.height=n.height/o),n}async function ne(e,{dpr:t=1,scale:o=1}={}){let n=new Image;n.src=e,await n.decode();let r=document.createElement("canvas"),a=n.width*o,i=n.height*o;r.width=Math.ceil(a*t),r.height=Math.ceil(i*t);let c=r.getContext("2d");return c.scale(t,t),c.drawImage(n,0,0,a,i),r.style.width=`${a}px`,r.style.height=`${i}px`,r}async function oe(e){let t=decodeURIComponent(e.split(",")[1]);return new Blob([t],{type:"image/svg+xml"})}async function ae(e,{dpr:t=1,scale:o=1},n){let r=await ne(e,{dpr:t,scale:o});if(!n)return r;let a=document.createElement("canvas");a.width=r.width,a.height=r.height;let i=a.getContext("2d");return i.fillStyle=n,i.fillRect(0,0,a.width,a.height),i.drawImage(r,0,0),a}async function H(e,{dpr:t=1,scale:o=1,backgroundColor:n="#fff",quality:r},a="png"){let i=await ae(e,{dpr:t,scale:o},n),c=new Image;return c.src=i.toDataURL(`image/${a}`,r),await c.decode(),c.style.width=`${i.width/t}px`,c.style.height=`${i.height/t}px`,c}async function le(e,{dpr:t=1,scale:o=1,backgroundColor:n="#fff",format:r="png",filename:a="capture"}={}){if(r==="svg"){let m=await oe(e),p=URL.createObjectURL(m),h=document.createElement("a");h.href=p,h.download=`${a}.svg`,h.click(),URL.revokeObjectURL(p);return}let i=["jpg","jpeg","webp"].includes(r)?"#fff":void 0,s=await ae(e,{dpr:t,scale:o},n??i),l={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp"}[r]||"image/png",d=s.toDataURL(l),f=document.createElement("a");f.href=d,f.download=`${a}.${r}`,f.click()}async function u(e,t={}){if(t={scale:1,...t},!e)throw new Error("Element cannot be null or undefined");return await u.capture(e,t)}u.capture=async(e,t={})=>{let o=await te(e,t),n=window.devicePixelRatio||1,r=t.scale||1;return{url:o,options:t,toRaw:()=>o,toImg:()=>ce(o,{dpr:n,scale:r}),toCanvas:()=>ne(o,{dpr:n,scale:r}),toBlob:()=>oe(o),toPng:a=>H(o,{dpr:n,scale:r,...a},"png"),toJpg:a=>H(o,{dpr:n,scale:r,...a},"jpeg"),toWebp:a=>H(o,{dpr:n,scale:r,...a},"webp"),download:({format:a="png",filename:i="capture",backgroundColor:c}={})=>le(o,{dpr:n,scale:r,backgroundColor:c,format:a,filename:i})}};u.toRaw=async(e,t)=>(await u.capture(e,t)).toRaw();u.toImg=async(e,t)=>(await u.capture(e,t)).toImg();u.toCanvas=async(e,t)=>(await u.capture(e,t)).toCanvas();u.toBlob=async(e,t)=>(await u.capture(e,t)).toBlob();u.toPng=async(e,t)=>(await u.capture(e,t)).toPng(t);u.toJpg=async(e,t)=>(await u.capture(e,t)).toJpg(t);u.toWebp=async(e,t)=>(await u.capture(e,t)).toWebp(t);u.download=async(e,t={})=>{let{format:o="png",filename:n="capture",backgroundColor:r,...a}=t;return await(await u.capture(e,a)).download({format:o,filename:n,backgroundColor:r})};async function de(e=document,t={}){let{embedFonts:o=!0,reset:n=!1,preWarm:r=!0}=t;if(n){I.clear(),$.clear(),T.clear(),A.clear(),U.clear();return}await document.fonts.ready,z();let a=[],i=[];e?.querySelectorAll&&(a=Array.from(e.querySelectorAll("img[src]")),i=Array.from(e.querySelectorAll("*")));let c=[];for(let s of a){let l=s.src;I.has(l)||c.push(x(l).then(d=>I.set(l,d)).catch(()=>{}))}for(let s of i){let l=getComputedStyle(s).backgroundImage,d=S(l);d&&!$.has(d)&&c.push(x(d).then(f=>$.set(d,f)).catch(()=>{}))}o&&await W({ignoreIconFonts:!o,preCached:!0}),await Promise.all(c)}export{de as preCache,u as snapdom};
package/dist/snapdom.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  /*
3
3
  * snapdom
4
- * v.1.2.5
4
+ * v.1.3.0
5
5
  * Author Juan Martin Muda
6
6
  * License MIT
7
7
  **/
@@ -227,7 +227,7 @@ function fetchImage(src, timeout = 3e3) {
227
227
  canvas.width = image.width;
228
228
  canvas.height = image.height;
229
229
  const ctx = canvas.getContext("2d");
230
- ctx.drawImage(image, 0, 0);
230
+ ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
231
231
  try {
232
232
  const dataURL = canvas.toDataURL("image/png");
233
233
  imageCache.set(src, dataURL);
@@ -315,6 +315,26 @@ function deepClone(node, styleMap, styleCache, nodeMap, compress) {
315
315
  if (node.nodeType !== Node.ELEMENT_NODE) return node.cloneNode(true);
316
316
  const clone = node.cloneNode(false);
317
317
  nodeMap.set(clone, node);
318
+ if (node instanceof HTMLInputElement) {
319
+ clone.value = node.value;
320
+ clone.setAttribute("value", node.value);
321
+ if (node.checked !== void 0) {
322
+ clone.checked = node.checked;
323
+ if (node.checked) clone.setAttribute("checked", "");
324
+ }
325
+ } else if (node instanceof HTMLTextAreaElement) {
326
+ clone.value = node.value;
327
+ clone.textContent = node.value;
328
+ } else if (node instanceof HTMLSelectElement) {
329
+ clone.value = node.value;
330
+ Array.from(clone.options).forEach((opt) => {
331
+ if (opt.value === node.value) {
332
+ opt.setAttribute("selected", "");
333
+ } else {
334
+ opt.removeAttribute("selected");
335
+ }
336
+ });
337
+ }
318
338
  inlineAllStyles(node, clone, styleMap, styleCache, compress);
319
339
  const frag = document.createDocumentFragment();
320
340
  node.childNodes.forEach((child) => {
@@ -467,18 +487,25 @@ async function inlinePseudoElements(source, clone, styleMap, styleCache, compres
467
487
  imgEl.style = "display:block;width:100%;height:100%;object-fit:contain;";
468
488
  pseudoEl.appendChild(imgEl);
469
489
  } catch (e) {
470
- console.error(
471
- `[snapdom] Error in pseudo ${pseudo} for`,
472
- source,
473
- e
474
- );
490
+ console.error(`[snapdom] Error in pseudo ${pseudo} for`, source, e);
475
491
  }
476
492
  }
477
493
  } else if (!isIconFont2 && cleanContent && cleanContent !== "none") {
478
494
  pseudoEl.textContent = cleanContent;
479
495
  }
496
+ if (hasBg && bg) {
497
+ const rawUrl = extractURL(bg);
498
+ if (rawUrl) {
499
+ try {
500
+ const dataUrl = await fetchImage(encodeURI(rawUrl));
501
+ pseudoEl.style.backgroundImage = `url(${dataUrl})`;
502
+ } catch (e) {
503
+ console.warn(`[snapdom] Failed to inline background-image for ${pseudo}`, e);
504
+ }
505
+ }
506
+ }
480
507
  const hasContent2 = pseudoEl.childNodes.length > 0 || pseudoEl.textContent && pseudoEl.textContent.trim() !== "";
481
- if (!hasContent2) continue;
508
+ if (!hasContent2 && !hasBg) continue;
482
509
  if (pseudo === "::before") {
483
510
  clone.insertBefore(pseudoEl, clone.firstChild);
484
511
  } else {
@@ -490,9 +517,7 @@ async function inlinePseudoElements(source, clone, styleMap, styleCache, compres
490
517
  }
491
518
  }
492
519
  const sChildren = Array.from(source.children);
493
- const cChildren = Array.from(clone.children).filter(
494
- (child) => !child.dataset.snapdomPseudo
495
- );
520
+ const cChildren = Array.from(clone.children).filter((child) => !child.dataset.snapdomPseudo);
496
521
  for (let i = 0; i < Math.min(sChildren.length, cChildren.length); i++) {
497
522
  await inlinePseudoElements(
498
523
  sChildren[i],
@@ -708,20 +733,20 @@ async function toImg(url, { dpr = 1, scale = 1 }) {
708
733
  }
709
734
  return img;
710
735
  }
711
- async function toCanvas(url, { dpr = 1, scale = 1 }) {
736
+ async function toCanvas(url, { dpr = 1, scale = 1 } = {}) {
712
737
  const img = new Image();
713
738
  img.src = url;
714
739
  await img.decode();
715
740
  const canvas = document.createElement("canvas");
716
- const width = img.width * scale * dpr;
717
- const height = img.height * scale * dpr;
718
- canvas.width = Math.ceil(width);
719
- canvas.height = Math.ceil(height);
741
+ const width = img.width * scale;
742
+ const height = img.height * scale;
743
+ canvas.width = Math.ceil(width * dpr);
744
+ canvas.height = Math.ceil(height * dpr);
720
745
  const ctx = canvas.getContext("2d");
721
- ctx.scale(scale * dpr, scale * dpr);
722
- ctx.drawImage(img, 0, 0);
723
- canvas.style.width = `${canvas.width / dpr}px`;
724
- canvas.style.height = `${canvas.height / dpr}px`;
746
+ ctx.scale(dpr, dpr);
747
+ ctx.drawImage(img, 0, 0, width, height);
748
+ canvas.style.width = `${width}px`;
749
+ canvas.style.height = `${height}px`;
725
750
  return canvas;
726
751
  }
727
752
  async function toBlob(url) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zumer/snapdom",
3
- "version": "1.2.5",
4
- "description": "snapDOM captures DOM elements as images with exceptional speed and minimal overhead. Designed to avoid bottlenecks and long tasks.",
3
+ "version": "1.3.0",
4
+ "description": "snapDOM captures HTML elements to images with exceptional speed and accuracy.",
5
5
  "main": "dist/snapdom.js",
6
6
  "module": "dist/snapdom.mjs",
7
7
  "scripts": {