@zumer/snapdom 1.9.8 → 1.9.10-dev.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/README.md CHANGED
@@ -89,10 +89,9 @@ import { snapdom } from './snapdom.mjs';
89
89
  ## Basic usage
90
90
 
91
91
  ### Reusable capture
92
-
93
92
  ```js
94
93
  const el = document.querySelector('#target');
95
- const result = await snapdom(el, { scale: 2 });
94
+ const result = await snapdom(el);
96
95
 
97
96
  const img = await result.toPng();
98
97
  document.body.appendChild(img);
@@ -101,7 +100,6 @@ await result.download({ format: 'jpg', filename: 'my-capture' });
101
100
  ```
102
101
 
103
102
  ### One-step shortcuts
104
-
105
103
  ```js
106
104
  const el = document.querySelector('#target');
107
105
  const png = await snapdom.toPng(el);
@@ -132,128 +130,173 @@ Returns an object with reusable export methods:
132
130
 
133
131
  ### Shortcut methods
134
132
 
135
- | Method | Description |
136
- | ------------------------------ | ------------------------------------- |
137
- | `snapdom.toImg(el, options?)` | Returns an `HTMLImageElement` |
138
- | `snapdom.toCanvas(el, options?) ` | Returns a `Canvas` |
139
- | `snapdom.toBlob(el, options?)` | Returns an SVG `Blob` |
140
- | `snapdom.toPng(el, options?)` | Returns a PNG image |
141
- | `snapdom.toJpg(el, options?)` | Returns a JPG image |
142
- | `snapdom.toWebp(el, options?)` | Returns a WebP image |
143
- | `snapdom.download(el, options?) ` | Triggers download in specified format |
133
+ | Method | Description |
134
+ | ------------------------------ | --------------------------------- |
135
+ | `snapdom.toImg(el, options?)` | Returns an `HTMLImageElement` |
136
+ | `snapdom.toCanvas(el, options?)` | Returns a `Canvas` |
137
+ | `snapdom.toBlob(el, options?)` | Returns an SVG or raster `Blob` |
138
+ | `snapdom.toPng(el, options?)` | Returns a PNG image |
139
+ | `snapdom.toJpg(el, options?)` | Returns a JPG image |
140
+ | `snapdom.toWebp(el, options?)` | Returns a WebP image |
141
+ | `snapdom.download(el, options?)` | Triggers a download |
144
142
 
145
143
  ## Options
146
144
 
147
- All capture methods accept an `options` object:
148
-
149
- | Option | Type | Default | Description |
150
- | ----------------- | -------- | -------- | ------------------------------------------ |
151
- | `compress` | boolean | `true` | Removes redundant styles |
152
- | `fast` | boolean | `true` | Skips idle delay for faster results |
153
- | `embedFonts` | boolean | `false` | Inlines fonts (icon fonts always embedded) |
154
- | `scale` | number | `1` | Output scale multiplier |
155
- | `dpr` | number | `devicePixelRatio` | Device pixel ratio |
156
- | `width` | number | - | Output specific width size |
157
- | `height` | number | - | Output specific height size |
158
- | `backgroundColor` | string | `"#fff"` | Fallback color for JPG/WebP |
159
- | `quality` | number | `1` | Quality for JPG/WebP (0 to 1) |
160
- | `useProxy` | string | '' | Specify a proxy for handling CORS images as fallback|
161
- | `type` | string | `svg` | Select `png`, `jpg`, `webp` Blob type|
162
- | `exclude` | string[] | - | CSS selectors for elements to exclude |
163
- | `filter` | function | - | Custom filter function ie `(el) => !el.classList.contains('hidden')` |
164
-
165
- ### Setting custom dimensions with width and height options
166
-
167
- Use the `width` and `height` options to generate an image with specific dimensions.
145
+ > ✅ **Note:** Style compression is now always on internally. The `compress` option has been removed.
168
146
 
169
- **Examples:**
147
+ All capture methods accept an `options` object:
170
148
 
171
- **1. Fixed width (proportional height)**
172
- Sets a specific width while maintaining the aspect ratio. Height adjusts proportionally.
149
+ | Option | Type | Default | Description |
150
+ | ----------------- | -------- | -------- | ----------------------------------------------- |
151
+ | `fast` | boolean | `true` | Skips small idle delays for faster results |
152
+ | `embedFonts` | boolean | `false` | Inlines non-icon fonts (icon fonts always on) |
153
+ | `localFonts` | array | `[]` | Local fonts `{ family, src, weight?, style? }` |
154
+ | `iconFonts` | string\|RegExp\|Array | `[]` | Extra icon font matchers |
155
+ | `excludeFonts` | object | `{}` | Exclude font families/domains/subsets during embedding |
156
+ | `scale` | number | `1` | Output scale multiplier |
157
+ | `dpr` | number | `devicePixelRatio` | Device pixel ratio |
158
+ | `width` | number | - | Output width |
159
+ | `height` | number | - | Output height |
160
+ | `backgroundColor` | string | `"#fff"` | Fallback color for JPG/WebP |
161
+ | `quality` | number | `1` | Quality for JPG/WebP (0 to 1) |
162
+ | `useProxy` | string | `''` | Proxy base for CORS fallbacks |
163
+ | `type` | string | `svg` | Default Blob type (`svg`\|`png`\|`jpg`\|`webp`) |
164
+ | `exclude` | string[] | - | CSS selectors to exclude |
165
+ | `filter` | function | - | Custom predicate `(el) => boolean` |
166
+ | `cache` | string | `"soft"` | Control internal caches: `disabled`, `soft`, `auto`, `full` |
167
+
168
+ ### Dimensions (`scale`, `width`, `height`)
169
+
170
+ * If `scale` is provided, it **takes precedence** over `width`/`height`.
171
+ * If only `width` is provided, height scales proportionally (and vice versa).
172
+ * Providing both `width` and `height` forces an exact size (may distort).
173
+
174
+ ### Cross-Origin Images & Fonts (`useProxy`)
175
+
176
+ By default snapDOM tries `crossOrigin="anonymous"` (or `use-credentials` for same-origin). If an asset is CORS-blocked, you can set `useProxy` to a prefix URL that forwards the actual `src`:
173
177
 
174
178
  ```js
175
- const result = await snapdom(element, {
176
- width: 400 // Outputs a 400px-wide image with auto-scaled height
179
+ await snapdom.toPng(el, {
180
+ useProxy: 'your-proxy' // Example 'https://api.allorigins.win/raw?url='
177
181
  });
178
182
  ```
179
183
 
180
- **2. Fixed height (proportional width)**
181
- Sets a specific height while maintaining the aspect ratio. Width adjusts proportionally.
184
+ **Tips**
185
+
186
+ * Keep the proxy **fast** and **cache-friendly** (adds big wins on repeated captures).
187
+ * The proxy is only used as a **fallback**; same-origin and CORS-enabled assets skip it.
188
+
189
+ ### Fonts
190
+
191
+ #### `embedFonts`
192
+ When `true`, snapDOM embeds **non-icon** `@font-face` rules detected as used within the captured subtree. Icon fonts (Font Awesome, Material Icons, etc.) are embedded **always**.
193
+
194
+ #### `localFonts`
195
+ If you serve fonts yourself or have data URLs, you can declare them here to avoid extra CSS discovery:
182
196
 
183
197
  ```js
184
- const result = await snapdom(element, {
185
- height: 200 // Outputs a 200px-tall image with auto-scaled width
198
+ await snapdom.toPng(el, {
199
+ embedFonts: true,
200
+ localFonts: [
201
+ { family: 'Inter', src: '/fonts/Inter-Variable.woff2', weight: 400, style: 'normal' },
202
+ { family: 'Inter', src: '/fonts/Inter-Italic.woff2', style: 'italic' }
203
+ ]
186
204
  });
187
205
  ```
188
206
 
189
- **3. Fixed width and height (may distort image)**
190
- Forces exact dimensions, potentially distorting the image if the aspect ratio differs.
207
+ #### `iconFonts`
208
+ Add custom icon families (names or regex matchers). Useful for private icon sets:
191
209
 
192
210
  ```js
193
- const result = await snapdom(element, {
194
- width: 800, // Outputs an 800px × 200px image (may stretch/squish content)
195
- height: 200
211
+ await snapdom.toPng(el, {
212
+ iconFonts: ['MyIcons', /^(Remix|Feather) Icons?$/i]
196
213
  });
197
214
  ```
198
215
 
199
- **Note:** If `scale` is different from 1, it takes priority over width and height.
200
- Example: `{ scale: 3, width: 500 }` ignores width and scales the image 3x instead.
201
-
202
-
203
- ### Cross-Origin Images
204
-
205
- By default, snapDOM loads images with `crossOrigin="anonymous"` or `crossOrigin="use-credentials"`. In case fails to get the images, `useProxy` can be used to deal with CORS images:
216
+ #### `excludeFonts`
217
+ Skip specific non-icon fonts to speed up capture or avoid unnecessary downloads.
206
218
 
207
219
  ```js
208
- const result = await snapdom(element, {
209
- useProxy: 'your/proxy/' //Example: 'https://corsproxy.io/?url=' or 'https://api.allorigins.win/raw?url='
220
+ await snapdom.toPng(el, {
221
+ embedFonts: true,
222
+ excludeFonts: {
223
+ families: ['Noto Serif', 'SomeHeavyFont'], // skip by family name
224
+ domains: ['fonts.gstatic.com', 'cdn.example'], // skip by source host
225
+ subsets: ['cyrillic-ext'] // skip by unicode-range subset tag
226
+ }
210
227
  });
211
228
  ```
229
+ *Notes*
230
+ - `excludeFonts` only applies to **non-icon** fonts. Icon fonts are always embedded.
231
+ - Matching is case-insensitive for `families`. Hosts are matched by substring against the resolved URL.
232
+
212
233
 
234
+ ### Filtering nodes: `exclude` vs `filter`
213
235
 
214
- ### Download options
236
+ * `exclude`: remove by **selector**.
237
+ * `filter`: advanced predicate per element (return `false` to drop).
215
238
 
239
+ **Example: filter out elements with `display:none`:**
216
240
  ```js
217
- {
218
- format?: "svg" | "png" | "jpg" | "jpeg" | "webp"; // default: "png"
219
- filename?: string; // default: "capture"
220
- backgroundColor?: string; // optional override
241
+ /**
242
+ * Example filter: skip elements with display:none
243
+ * @param {Element} el
244
+ * @returns {boolean} true = keep, false = exclude
245
+ */
246
+ function filterHidden(el) {
247
+ const cs = window.getComputedStyle(el);
248
+ if (cs.display === 'none') return false;
249
+ return true;
221
250
  }
222
- ```
223
251
 
252
+ await snapdom.toPng(document.body, { filter: filterHidden });
253
+ ```
224
254
 
255
+ **Example with `exclude`:** remove banners or tooltips by selector
256
+ ```js
257
+ await snapdom.toPng(el, {
258
+ exclude: ['.cookie-banner', '.tooltip', '[data-test="debug"]']
259
+ });
260
+ ```
225
261
  ### `preCache()` – Optional helper
226
262
 
227
- The `preCache()` function can be used to load external resources (like images and fonts) in advance. It is specially useful when the element to capture is big and complex.
263
+ Preloads external resources to avoid first-capture stalls (helpful for big/complex trees).
228
264
 
229
265
  ```js
230
266
  import { preCache } from '@zumer/snapdom';
231
267
 
232
- await preCache(document.body);
268
+ await preCache({
269
+ root: document.body,
270
+ embedFonts: true,
271
+ localFonts: [{ family: 'Inter', src: '/fonts/Inter.woff2', weight: 400 }],
272
+ useProxy: 'your-proxy'
273
+ });
233
274
  ```
234
275
 
235
- ```js
236
- import { snapdom, preCache } from './snapdom.mjs';
237
- window.addEventListener('load', async () => {
238
- await preCache();
239
- console.log('📦 Resources preloaded');
240
- });
241
- ```
276
+ ### Cache control
277
+
278
+ SnapDOM maintains internal caches for images, backgrounds, resources, styles, and fonts.
279
+ You can control how they are cleared between captures using the `cache` option:
242
280
 
243
- **Options for `preCache()`:**
281
+ | Mode | Description |
282
+ | ----------- | --------------------------------------------------------------------------- |
283
+ | `"disabled"`| No cache: clears absolutely everything on every capture |
284
+ | `"soft"` | Clears session caches (`styleMap`, `nodeMap`, `styleCache`) _(default)_ |
285
+ | `"auto"` | Minimal cleanup: only clears transient maps |
286
+ | `"full"` | Keeps all caches (nothing is cleared, maximum performance) |
244
287
 
245
- * `embedFonts` *(boolean, default: true)* — Inlines non-icon fonts during preload.
246
- * `useProxy` *(string)* — Proxy for handling CORS images as fallback.
288
+ **Examples:**
247
289
 
290
+ ```js
291
+ // Use minimal but fast cache
292
+ await snapdom.toPng(el, { cache: 'auto' });
248
293
 
249
- ## Features
294
+ // Keep everything in memory between captures
295
+ await snapdom.toPng(el, { cache: 'full' });
250
296
 
251
- * Captures **shadow DOM** and Web Components
252
- * Supports `::before`, `::after` and `::first-letter` pseudo-elements
253
- * Inlines background images and fonts
254
- * Handles **Font Awesome**, **Material Icons**, and more
255
- * `data-capture="exclude"` to ignore an element
256
- * `data-capture="placeholder"` with `data-placeholder-text` for masked replacements
297
+ // Force a full cleanup on every capture
298
+ await snapdom.toPng(el, { cache: 'disabled' });
299
+ ```
257
300
 
258
301
  ## Limitations
259
302