smooth-screenshot 1.1.1 → 1.1.3
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/README.md +2 -0
- package/dist/index.cjs +53 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +53 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
[](https://www.npmjs.com/package/smooth-screenshot)
|
|
7
7
|
[](./LICENSE)
|
|
8
8
|
|
|
9
|
+
**[Live demo & docs → luccas-carvalho.github.io/smooth-screenshot](https://luccas-carvalho.github.io/smooth-screenshot/)**
|
|
10
|
+
|
|
9
11
|
**Capture any DOM element to PNG, JPEG, WebP, SVG, or PDF — without ever freezing the UI.**
|
|
10
12
|
|
|
11
13
|
Most DOM-to-image libraries do all their work in one synchronous burst: on a large
|
package/dist/index.cjs
CHANGED
|
@@ -250,8 +250,25 @@ function createContext(target, options) {
|
|
|
250
250
|
return context;
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
+
// src/util/ns.ts
|
|
254
|
+
var svgNs = null;
|
|
255
|
+
var xhtmlNs = null;
|
|
256
|
+
function svgNamespace(doc) {
|
|
257
|
+
if (svgNs === null) {
|
|
258
|
+
const probe = doc.createElement("div");
|
|
259
|
+
probe.innerHTML = "<svg></svg>";
|
|
260
|
+
svgNs = probe.firstElementChild.namespaceURI ?? "";
|
|
261
|
+
}
|
|
262
|
+
return svgNs;
|
|
263
|
+
}
|
|
264
|
+
function xhtmlNamespace(doc) {
|
|
265
|
+
if (xhtmlNs === null) {
|
|
266
|
+
xhtmlNs = doc.createElement("div").namespaceURI ?? "";
|
|
267
|
+
}
|
|
268
|
+
return xhtmlNs;
|
|
269
|
+
}
|
|
270
|
+
|
|
253
271
|
// src/clone/default-style.ts
|
|
254
|
-
var XHTML_NS = "http://www.w3.org/1999/xhtml";
|
|
255
272
|
function ensureSandbox(context) {
|
|
256
273
|
if (context.sandbox?.contentDocument) {
|
|
257
274
|
return context.sandbox.contentDocument;
|
|
@@ -267,7 +284,8 @@ function ensureSandbox(context) {
|
|
|
267
284
|
return doc;
|
|
268
285
|
}
|
|
269
286
|
function getDefaultStyle(context, source) {
|
|
270
|
-
const
|
|
287
|
+
const xhtmlNs2 = xhtmlNamespace(context.ownerDocument);
|
|
288
|
+
const namespace = source.namespaceURI ?? xhtmlNs2;
|
|
271
289
|
const key = `${namespace}|${source.localName}`;
|
|
272
290
|
const cached = context.defaultStyleCache.get(key);
|
|
273
291
|
if (cached) return cached;
|
|
@@ -278,7 +296,7 @@ function getDefaultStyle(context, source) {
|
|
|
278
296
|
context.defaultStyleCache.set(key, empty);
|
|
279
297
|
return empty;
|
|
280
298
|
}
|
|
281
|
-
const element = namespace ===
|
|
299
|
+
const element = namespace === xhtmlNs2 ? doc.createElement(source.localName) : doc.createElementNS(namespace, source.localName);
|
|
282
300
|
doc.body.appendChild(element);
|
|
283
301
|
const computed = sandboxWindow.getComputedStyle(element);
|
|
284
302
|
const record = {};
|
|
@@ -292,15 +310,40 @@ function getDefaultStyle(context, source) {
|
|
|
292
310
|
}
|
|
293
311
|
|
|
294
312
|
// src/clone/copy-styles.ts
|
|
313
|
+
var PHYSICAL_BORDER_WIDTHS = [
|
|
314
|
+
"border-top-width",
|
|
315
|
+
"border-right-width",
|
|
316
|
+
"border-bottom-width",
|
|
317
|
+
"border-left-width"
|
|
318
|
+
];
|
|
319
|
+
function isBorderStyleOrColor(name) {
|
|
320
|
+
if (!name.startsWith("border")) return false;
|
|
321
|
+
if (name.startsWith("border-image") || name.startsWith("border-radius")) {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
return name.endsWith("style") || name.endsWith("color");
|
|
325
|
+
}
|
|
295
326
|
function copyStyle(source, target, context) {
|
|
296
327
|
const computed = context.ownerWindow.getComputedStyle(source);
|
|
297
328
|
const defaults = getDefaultStyle(context, source);
|
|
298
|
-
const
|
|
329
|
+
const toCopy = /* @__PURE__ */ new Set();
|
|
299
330
|
for (let i = 0; i < computed.length; i++) {
|
|
300
331
|
const name = computed[i];
|
|
301
332
|
if (!name) continue;
|
|
302
333
|
const value = computed.getPropertyValue(name);
|
|
303
334
|
if (value === "" || defaults[name] === value) continue;
|
|
335
|
+
toCopy.add(name);
|
|
336
|
+
}
|
|
337
|
+
if (Array.from(toCopy).some(isBorderStyleOrColor)) {
|
|
338
|
+
for (const width of PHYSICAL_BORDER_WIDTHS) toCopy.add(width);
|
|
339
|
+
}
|
|
340
|
+
if (toCopy.has("outline-style") || toCopy.has("outline-color") || toCopy.has("outline")) {
|
|
341
|
+
toCopy.add("outline-width");
|
|
342
|
+
}
|
|
343
|
+
const targetStyle = target.style;
|
|
344
|
+
for (const name of toCopy) {
|
|
345
|
+
const value = computed.getPropertyValue(name);
|
|
346
|
+
if (value === "") continue;
|
|
304
347
|
targetStyle.setProperty(name, value, computed.getPropertyPriority(name));
|
|
305
348
|
}
|
|
306
349
|
}
|
|
@@ -713,8 +756,6 @@ async function embedResources(clone, context) {
|
|
|
713
756
|
}
|
|
714
757
|
|
|
715
758
|
// src/serialize/foreign-object-svg.ts
|
|
716
|
-
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
717
|
-
var XHTML_NS2 = "http://www.w3.org/1999/xhtml";
|
|
718
759
|
function buildSvgString(params) {
|
|
719
760
|
const {
|
|
720
761
|
clone,
|
|
@@ -728,25 +769,26 @@ function buildSvgString(params) {
|
|
|
728
769
|
} = params;
|
|
729
770
|
const outW = crop ? crop.width : fullWidth;
|
|
730
771
|
const outH = crop ? crop.height : fullHeight;
|
|
731
|
-
const
|
|
732
|
-
svg.
|
|
772
|
+
const svgNs2 = svgNamespace(doc);
|
|
773
|
+
const svg = doc.createElementNS(svgNs2, "svg");
|
|
774
|
+
svg.setAttribute("xmlns", svgNs2);
|
|
733
775
|
svg.setAttribute("width", String(outW));
|
|
734
776
|
svg.setAttribute("height", String(outH));
|
|
735
777
|
svg.setAttribute("viewBox", `0 0 ${outW} ${outH}`);
|
|
736
778
|
if (backgroundColor) {
|
|
737
|
-
const rect = doc.createElementNS(
|
|
779
|
+
const rect = doc.createElementNS(svgNs2, "rect");
|
|
738
780
|
rect.setAttribute("width", "100%");
|
|
739
781
|
rect.setAttribute("height", "100%");
|
|
740
782
|
rect.setAttribute("fill", backgroundColor);
|
|
741
783
|
svg.appendChild(rect);
|
|
742
784
|
}
|
|
743
|
-
const foreignObject = doc.createElementNS(
|
|
785
|
+
const foreignObject = doc.createElementNS(svgNs2, "foreignObject");
|
|
744
786
|
foreignObject.setAttribute("x", String(crop ? -crop.x : 0));
|
|
745
787
|
foreignObject.setAttribute("y", String(crop ? -crop.y : 0));
|
|
746
788
|
foreignObject.setAttribute("width", String(fullWidth));
|
|
747
789
|
foreignObject.setAttribute("height", String(fullHeight));
|
|
748
790
|
const container = doc.createElement("div");
|
|
749
|
-
container.setAttribute("xmlns",
|
|
791
|
+
container.setAttribute("xmlns", xhtmlNamespace(doc));
|
|
750
792
|
if (fontCss || pseudoRules.length > 0) {
|
|
751
793
|
const style = doc.createElement("style");
|
|
752
794
|
style.textContent = `${fontCss}
|