@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 +45 -20
- package/dist/snapdom.min.js +3 -3
- package/dist/snapdom.min.mjs +3 -3
- package/dist/snapdom.mjs +45 -20
- package/package.json +2 -2
package/dist/snapdom.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
/*
|
|
3
3
|
* snapdom
|
|
4
|
-
* v.1.
|
|
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
|
|
717
|
-
const height = img.height * scale
|
|
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(
|
|
722
|
-
ctx.drawImage(img, 0, 0);
|
|
723
|
-
canvas.style.width = `${
|
|
724
|
-
canvas.style.height = `${
|
|
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/dist/snapdom.min.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(()=>{var
|
|
2
|
-
`;return o}function J(
|
|
3
|
-
`}catch{console.warn("\u274C Failed to fetch CSS:",
|
|
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;})();
|
package/dist/snapdom.min.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
`;return o}function J(
|
|
3
|
-
`}catch{console.warn("\u274C Failed to fetch CSS:",
|
|
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.
|
|
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
|
|
717
|
-
const height = img.height * scale
|
|
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(
|
|
722
|
-
ctx.drawImage(img, 0, 0);
|
|
723
|
-
canvas.style.width = `${
|
|
724
|
-
canvas.style.height = `${
|
|
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.
|
|
4
|
-
"description": "snapDOM captures
|
|
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": {
|