@zumer/snapdom 1.9.9 → 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,132 +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
- | `localFonts` | array | `[]` | Array of local font descriptors `{ family, src, weight?, style? }` |
155
- | `iconFonts` | string \| RegExp \| (string \| RegExp)[] | `[]` | Additional icon font families or patterns |
156
- | `scale` | number | `1` | Output scale multiplier |
157
- | `dpr` | number | `devicePixelRatio` | Device pixel ratio |
158
- | `width` | number | - | Output specific width size |
159
- | `height` | number | - | Output specific height size |
160
- | `backgroundColor` | string | `"#fff"` | Fallback color for JPG/WebP |
161
- | `quality` | number | `1` | Quality for JPG/WebP (0 to 1) |
162
- | `useProxy` | string | '' | Specify a proxy for handling CORS images/fonts as fallback|
163
- | `type` | string | `svg` | Select `png`, `jpg`, `webp` Blob type|
164
- | `exclude` | string[] | - | CSS selectors for elements to exclude |
165
- | `filter` | function | - | Custom filter function ie `(el) => !el.classList.contains('hidden')` |
166
-
167
- ### Setting custom dimensions with width and height options
168
-
169
- 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.
170
146
 
171
- **Examples:**
147
+ All capture methods accept an `options` object:
172
148
 
173
- **1. Fixed width (proportional height)**
174
- 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`:
175
177
 
176
178
  ```js
177
- const result = await snapdom(element, {
178
- 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='
179
181
  });
180
182
  ```
181
183
 
182
- **2. Fixed height (proportional width)**
183
- 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:
184
196
 
185
197
  ```js
186
- const result = await snapdom(element, {
187
- 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
+ ]
188
204
  });
189
205
  ```
190
206
 
191
- **3. Fixed width and height (may distort image)**
192
- 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:
193
209
 
194
210
  ```js
195
- const result = await snapdom(element, {
196
- width: 800, // Outputs an 800px × 200px image (may stretch/squish content)
197
- height: 200
211
+ await snapdom.toPng(el, {
212
+ iconFonts: ['MyIcons', /^(Remix|Feather) Icons?$/i]
198
213
  });
199
214
  ```
200
215
 
201
- **Note:** If `scale` is different from 1, it takes priority over width and height.
202
- Example: `{ scale: 3, width: 500 }` ignores width and scales the image 3x instead.
203
-
204
-
205
- ### Cross-Origin Images
206
-
207
- 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.
208
218
 
209
219
  ```js
210
- const result = await snapdom(element, {
211
- 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
+ }
212
227
  });
213
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.
214
232
 
215
233
 
216
- ### Download options
234
+ ### Filtering nodes: `exclude` vs `filter`
217
235
 
236
+ * `exclude`: remove by **selector**.
237
+ * `filter`: advanced predicate per element (return `false` to drop).
238
+
239
+ **Example: filter out elements with `display:none`:**
218
240
  ```js
219
- {
220
- format?: "svg" | "png" | "jpg" | "jpeg" | "webp"; // default: "png"
221
- filename?: string; // default: "capture"
222
- 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;
223
250
  }
224
- ```
225
251
 
252
+ await snapdom.toPng(document.body, { filter: filterHidden });
253
+ ```
226
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
+ ```
227
261
  ### `preCache()` – Optional helper
228
262
 
229
- 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).
230
264
 
231
265
  ```js
232
266
  import { preCache } from '@zumer/snapdom';
233
267
 
234
- 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
+ });
235
274
  ```
236
275
 
237
- ```js
238
- import { snapdom, preCache } from './snapdom.mjs';
239
- window.addEventListener('load', async () => {
240
- await preCache();
241
- console.log('📦 Resources preloaded');
242
- });
243
- ```
276
+ ### Cache control
244
277
 
245
- **Options for `preCache()`:**
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:
246
280
 
247
- * `embedFonts` *(boolean, default: true)* — Inlines non-icon fonts during preload.
248
- * `localFonts` *(array)* — Array of `{ family, src, weight?, style? }` for local font sources.
249
- * `useProxy` *(string)* — Proxy for handling CORS images/fonts as fallback.
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) |
250
287
 
288
+ **Examples:**
251
289
 
290
+ ```js
291
+ // Use minimal but fast cache
292
+ await snapdom.toPng(el, { cache: 'auto' });
252
293
 
253
- ## Features
294
+ // Keep everything in memory between captures
295
+ await snapdom.toPng(el, { cache: 'full' });
254
296
 
255
- * Captures **shadow DOM** and Web Components
256
- * Supports `::before`, `::after` and `::first-letter` pseudo-elements
257
- * Inlines background images and fonts
258
- * Handles **Font Awesome**, **Material Icons**, and more
259
- * `data-capture="exclude"` to ignore an element
260
- * `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
+ ```
261
300
 
262
301
  ## Limitations
263
302