smooth-screenshot 1.1.2 → 1.1.4

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 CHANGED
@@ -6,6 +6,8 @@
6
6
  [![types](https://img.shields.io/npm/types/smooth-screenshot)](https://www.npmjs.com/package/smooth-screenshot)
7
7
  [![license](https://img.shields.io/npm/l/smooth-screenshot)](./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 namespace = source.namespaceURI ?? XHTML_NS;
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 === XHTML_NS ? doc.createElement(source.localName) : doc.createElementNS(namespace, source.localName);
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 = {};
@@ -738,14 +756,13 @@ async function embedResources(clone, context) {
738
756
  }
739
757
 
740
758
  // src/serialize/foreign-object-svg.ts
741
- var SVG_NS = "http://www.w3.org/2000/svg";
742
- var XHTML_NS2 = "http://www.w3.org/1999/xhtml";
743
759
  function buildSvgString(params) {
744
760
  const {
745
761
  clone,
746
762
  doc,
747
763
  fullWidth,
748
764
  fullHeight,
765
+ scale,
749
766
  pseudoRules,
750
767
  fontCss,
751
768
  backgroundColor,
@@ -753,25 +770,26 @@ function buildSvgString(params) {
753
770
  } = params;
754
771
  const outW = crop ? crop.width : fullWidth;
755
772
  const outH = crop ? crop.height : fullHeight;
756
- const svg = doc.createElementNS(SVG_NS, "svg");
757
- svg.setAttribute("xmlns", SVG_NS);
758
- svg.setAttribute("width", String(outW));
759
- svg.setAttribute("height", String(outH));
773
+ const svgNs2 = svgNamespace(doc);
774
+ const svg = doc.createElementNS(svgNs2, "svg");
775
+ svg.setAttribute("xmlns", svgNs2);
776
+ svg.setAttribute("width", String(Math.round(outW * scale)));
777
+ svg.setAttribute("height", String(Math.round(outH * scale)));
760
778
  svg.setAttribute("viewBox", `0 0 ${outW} ${outH}`);
761
779
  if (backgroundColor) {
762
- const rect = doc.createElementNS(SVG_NS, "rect");
780
+ const rect = doc.createElementNS(svgNs2, "rect");
763
781
  rect.setAttribute("width", "100%");
764
782
  rect.setAttribute("height", "100%");
765
783
  rect.setAttribute("fill", backgroundColor);
766
784
  svg.appendChild(rect);
767
785
  }
768
- const foreignObject = doc.createElementNS(SVG_NS, "foreignObject");
786
+ const foreignObject = doc.createElementNS(svgNs2, "foreignObject");
769
787
  foreignObject.setAttribute("x", String(crop ? -crop.x : 0));
770
788
  foreignObject.setAttribute("y", String(crop ? -crop.y : 0));
771
789
  foreignObject.setAttribute("width", String(fullWidth));
772
790
  foreignObject.setAttribute("height", String(fullHeight));
773
791
  const container = doc.createElement("div");
774
- container.setAttribute("xmlns", XHTML_NS2);
792
+ container.setAttribute("xmlns", xhtmlNamespace(doc));
775
793
  if (fontCss || pseudoRules.length > 0) {
776
794
  const style = doc.createElement("style");
777
795
  style.textContent = `${fontCss}
@@ -830,9 +848,9 @@ function drawSvgToCanvas(svgImage, deviceWidth, deviceHeight, context) {
830
848
  return canvas;
831
849
  }
832
850
  async function* rgbaBands(svgImage, geometry2, maxTile, context) {
833
- const { outWidth, outHeight, deviceWidth, deviceHeight } = geometry2;
834
- const rx = outWidth / deviceWidth;
835
- const ry = outHeight / deviceHeight;
851
+ const { deviceWidth, deviceHeight } = geometry2;
852
+ const rx = (svgImage.naturalWidth || deviceWidth) / deviceWidth;
853
+ const ry = (svgImage.naturalHeight || deviceHeight) / deviceHeight;
836
854
  const bandRows = Math.max(
837
855
  1,
838
856
  Math.min(maxTile, Math.floor(MAX_BAND_BYTES / (deviceWidth * 4)) || 1)
@@ -1143,6 +1161,7 @@ async function prepare(target, context, backgroundColor) {
1143
1161
  doc: context.ownerDocument,
1144
1162
  fullWidth,
1145
1163
  fullHeight,
1164
+ scale: context.options.scale,
1146
1165
  pseudoRules,
1147
1166
  fontCss,
1148
1167
  backgroundColor,