@pixldocs/canvas-renderer 0.5.188 → 0.5.189
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 +49 -9
- package/dist/{index-0rk-MRGy.cjs → index-CmrxeQ_K.cjs} +73 -6
- package/dist/{index-0rk-MRGy.cjs.map → index-CmrxeQ_K.cjs.map} +1 -1
- package/dist/{index-CjZZhQH6.js → index-lQXXPpb8.js} +104 -37
- package/dist/{index-CjZZhQH6.js.map → index-lQXXPpb8.js.map} +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +32 -31
- package/dist/{vectorPdfExport-B2Cf-9eT.cjs → vectorPdfExport-BAAJU0RL.cjs} +4 -4
- package/dist/{vectorPdfExport-B2Cf-9eT.cjs.map → vectorPdfExport-BAAJU0RL.cjs.map} +1 -1
- package/dist/{vectorPdfExport-CSh0zFox.js → vectorPdfExport-Ch-qwcNJ.js} +4 -4
- package/dist/{vectorPdfExport-CSh0zFox.js.map → vectorPdfExport-Ch-qwcNJ.js.map} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -483,7 +483,7 @@ const blurFieldIds = ['text-reference-name', 'text-phone', 'text-address'];
|
|
|
483
483
|
the resolved config before handing it to the imperative renderer, so the
|
|
484
484
|
blur is baked into the exported pixels.
|
|
485
485
|
|
|
486
|
-
### Biodata teaser previews — blur by flat form key (v0.5.187
|
|
486
|
+
### Biodata teaser previews — blur by flat form key (v0.5.187+, hardened in v0.5.189)
|
|
487
487
|
|
|
488
488
|
Form-driven apps (BioMaker, the pixldocs.com Use page, etc.) already
|
|
489
489
|
speak the **flat form-key** language produced by `applyFormDataToConfig`
|
|
@@ -499,7 +499,10 @@ Instead of reverse-engineering `config.__cloneIdMap` keys or the
|
|
|
499
499
|
flat keys straight to `<PixldocsPreview>` and the package resolves them:
|
|
500
500
|
|
|
501
501
|
```tsx
|
|
502
|
-
import {
|
|
502
|
+
import {
|
|
503
|
+
PixldocsPreview,
|
|
504
|
+
buildTeaserBlurFlatKeys,
|
|
505
|
+
} from '@pixldocs/canvas-renderer';
|
|
503
506
|
|
|
504
507
|
// e.g. for a biodata teaser: blur every detail-row VALUE after row 3.
|
|
505
508
|
const blurFlatFormKeys = buildTeaserBlurFlatKeys(sectionState, schema, {
|
|
@@ -509,11 +512,14 @@ const blurFlatFormKeys = buildTeaserBlurFlatKeys(sectionState, schema, {
|
|
|
509
512
|
|
|
510
513
|
<PixldocsPreview
|
|
511
514
|
config={displayConfig}
|
|
515
|
+
pageIndex={pageIndex}
|
|
512
516
|
frostedBlur
|
|
513
517
|
blurFlatFormKeys={blurFlatFormKeys}
|
|
514
518
|
// Optional — defaults to { bindings: 'value' } so only `*_value` keys
|
|
515
|
-
// are honoured. Pass 'all' to blur labels / titles too.
|
|
516
|
-
|
|
519
|
+
// are honoured. Pass 'all' to blur labels / titles too. `pageIndex` is
|
|
520
|
+
// forwarded into the resolver so verification scopes to the page
|
|
521
|
+
// currently being rendered (recommended for stacked multi-page previews).
|
|
522
|
+
blurFlatFormKeyOptions={{ bindings: 'value', pageIndex }}
|
|
517
523
|
/>
|
|
518
524
|
```
|
|
519
525
|
|
|
@@ -521,10 +527,22 @@ Notes:
|
|
|
521
527
|
|
|
522
528
|
- Matching is done on `config.__cloneIdMap` and handles all alias
|
|
523
529
|
variants (`grp-…_4_value`, `…_4_field_detail_section_N_field_N_value`,
|
|
524
|
-
with or without the wrapper `field_` prefix).
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
530
|
+
with or without the wrapper `field_` prefix). **As of v0.5.189**
|
|
531
|
+
every resolved id is then verified against the actual rendered page
|
|
532
|
+
tree (`config.pages[*]`) — stale or alias map entries that don't
|
|
533
|
+
match a real element are dropped silently. This eliminates the
|
|
534
|
+
"phantom frost rectangle near a section title" class of bug that
|
|
535
|
+
showed up in templates with nested repeatables, where
|
|
536
|
+
`__cloneIdMap` returned ids like `text-…__cgroup-…_e4` but the
|
|
537
|
+
rendered tree used `text-…__cgrp-…_pN_grp-…_eN`.
|
|
538
|
+
- Pass `pageIndex` in `blurFlatFormKeyOptions` to scope verification
|
|
539
|
+
to a single page — clones that landed on a different page will not
|
|
540
|
+
contribute overlays to this page. This is the recommended pattern
|
|
541
|
+
for stacked multi-page previews. Default is `'all'` (verify across
|
|
542
|
+
every page).
|
|
543
|
+
- Use `skipTreeVerification: true` only if you fully trust your
|
|
544
|
+
`__cloneIdMap` (e.g. you just built the config in-process and
|
|
545
|
+
haven't mutated the tree since).
|
|
528
546
|
- Defaults to `bindings: 'value'`, i.e. only flat keys whose last
|
|
529
547
|
segment is `value` resolve. This is exactly the biodata teaser
|
|
530
548
|
pattern: blur row values, leave labels / section titles / full-name /
|
|
@@ -533,6 +551,26 @@ Notes:
|
|
|
533
551
|
PNG/PDF download path, resolve the same keys to exact ids and bake
|
|
534
552
|
them in (see below).
|
|
535
553
|
|
|
554
|
+
#### `buildTeaserBlurFlatKeys(sectionState, sections, options)`
|
|
555
|
+
|
|
556
|
+
Emits the flat form-keys for every repeatable-section entry **after**
|
|
557
|
+
`afterRow` (1-indexed). Walks nested repeatables recursively.
|
|
558
|
+
|
|
559
|
+
- `sectionState` — the same `SectionFormState` you'd hand to
|
|
560
|
+
`resolveFromForm` / `<PixldocsPreview sectionState={…}>`.
|
|
561
|
+
- `sections` — `InferredSection[]` for the active form schema (you
|
|
562
|
+
already have these from `inferFormSchemaFromTemplate` or from the
|
|
563
|
+
`form_schemas` row converted via `fromFormDefSections`).
|
|
564
|
+
- `options.afterRow` — keep the first N entries sharp; blur entries
|
|
565
|
+
`N+1, N+2, …`.
|
|
566
|
+
- `options.bindings` — `'value'` (default) emits only `_value` keys
|
|
567
|
+
(the canonical biodata teaser pattern); `'all'` emits every entry
|
|
568
|
+
field key.
|
|
569
|
+
|
|
570
|
+
Returned keys can be fed straight into the `blurFlatFormKeys` prop
|
|
571
|
+
above and into `resolveBlurElementExactIdsFromFlatFormKeys` for the
|
|
572
|
+
watermarked download path below.
|
|
573
|
+
|
|
536
574
|
#### Watermarked downloads — same resolver + `injectPreviewBlur`
|
|
537
575
|
|
|
538
576
|
```ts
|
|
@@ -544,7 +582,9 @@ import {
|
|
|
544
582
|
const exactIds = resolveBlurElementExactIdsFromFlatFormKeys(
|
|
545
583
|
resolvedConfig,
|
|
546
584
|
blurFlatFormKeys,
|
|
547
|
-
// { bindings: 'value' } by default
|
|
585
|
+
// { bindings: 'value', pageIndex: 'all' } by default. For the
|
|
586
|
+
// download path you usually want 'all' since the export covers
|
|
587
|
+
// every page.
|
|
548
588
|
);
|
|
549
589
|
|
|
550
590
|
const exportConfig = injectPreviewBlur(resolvedConfig, {
|
|
@@ -16257,6 +16257,23 @@ function addAllToSet(val, out) {
|
|
|
16257
16257
|
out.add(val);
|
|
16258
16258
|
return true;
|
|
16259
16259
|
}
|
|
16260
|
+
function collectPageTreeElementIds(config, pageIndex = "all") {
|
|
16261
|
+
const out = /* @__PURE__ */ new Set();
|
|
16262
|
+
const pages = config == null ? void 0 : config.pages;
|
|
16263
|
+
if (!Array.isArray(pages)) return out;
|
|
16264
|
+
const targets = pageIndex === "all" ? pages : pages[pageIndex] != null ? [pages[pageIndex]] : [];
|
|
16265
|
+
const walk = (node) => {
|
|
16266
|
+
if (!node || typeof node !== "object") return;
|
|
16267
|
+
if (typeof node.id === "string") out.add(node.id);
|
|
16268
|
+
const children = node.children || node.elements;
|
|
16269
|
+
if (Array.isArray(children)) for (const c of children) walk(c);
|
|
16270
|
+
};
|
|
16271
|
+
for (const page of targets) {
|
|
16272
|
+
const children = (page == null ? void 0 : page.children) || (page == null ? void 0 : page.elements);
|
|
16273
|
+
if (Array.isArray(children)) for (const c of children) walk(c);
|
|
16274
|
+
}
|
|
16275
|
+
return out;
|
|
16276
|
+
}
|
|
16260
16277
|
function resolveBlurElementExactIdsFromFlatFormKeys(config, flatFormKeys, options) {
|
|
16261
16278
|
const cloneIdMap = (config == null ? void 0 : config.__cloneIdMap) || {};
|
|
16262
16279
|
if (!cloneIdMap || typeof cloneIdMap !== "object") return [];
|
|
@@ -16281,10 +16298,59 @@ function resolveBlurElementExactIdsFromFlatFormKeys(config, flatFormKeys, option
|
|
|
16281
16298
|
}
|
|
16282
16299
|
}
|
|
16283
16300
|
}
|
|
16284
|
-
|
|
16301
|
+
if (out.size === 0) return [];
|
|
16302
|
+
if (options == null ? void 0 : options.skipTreeVerification) return Array.from(out);
|
|
16303
|
+
const treeIds = collectPageTreeElementIds(
|
|
16304
|
+
config,
|
|
16305
|
+
(options == null ? void 0 : options.pageIndex) ?? "all"
|
|
16306
|
+
);
|
|
16307
|
+
if (treeIds.size === 0) return Array.from(out);
|
|
16308
|
+
const verified = [];
|
|
16309
|
+
for (const id of out) if (treeIds.has(id)) verified.push(id);
|
|
16310
|
+
return verified;
|
|
16311
|
+
}
|
|
16312
|
+
function buildTeaserBlurFlatKeys(sectionState, sections, options) {
|
|
16313
|
+
const afterRow = Math.max(0, options.afterRow | 0);
|
|
16314
|
+
const bindings = options.bindings ?? "value";
|
|
16315
|
+
const out = [];
|
|
16316
|
+
if (!sectionState || !Array.isArray(sections)) return out;
|
|
16317
|
+
const repeatables = sections.filter((s) => (s == null ? void 0 : s.type) === "repeatable");
|
|
16318
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
16319
|
+
for (const r of repeatables) {
|
|
16320
|
+
if (!r.parentId) continue;
|
|
16321
|
+
const arr = childrenByParent.get(r.parentId) || [];
|
|
16322
|
+
arr.push(r);
|
|
16323
|
+
childrenByParent.set(r.parentId, arr);
|
|
16324
|
+
}
|
|
16325
|
+
const emitForEntryFields = (section, keyPrefix, entryIdx1) => {
|
|
16326
|
+
const fields = section.entryFields || [];
|
|
16327
|
+
for (const f of fields) {
|
|
16328
|
+
if (!(f == null ? void 0 : f.key)) continue;
|
|
16329
|
+
if (bindings === "value" && f.key !== "value") continue;
|
|
16330
|
+
out.push(`${keyPrefix}_${f.key}`);
|
|
16331
|
+
}
|
|
16332
|
+
};
|
|
16333
|
+
const walkRepeatable = (section, parentKeyPrefix) => {
|
|
16334
|
+
const entries = sectionState == null ? void 0 : sectionState[section.id];
|
|
16335
|
+
if (!Array.isArray(entries)) return;
|
|
16336
|
+
for (let i = 0; i < entries.length; i++) {
|
|
16337
|
+
const entryIdx1 = i + 1;
|
|
16338
|
+
const isBlurred = entryIdx1 > afterRow;
|
|
16339
|
+
const keyPrefix = parentKeyPrefix ? `${parentKeyPrefix}_field_${section.id}_${entryIdx1}` : `field_${section.id}_${entryIdx1}`;
|
|
16340
|
+
if (isBlurred) emitForEntryFields(section, keyPrefix);
|
|
16341
|
+
const children = childrenByParent.get(section.id) || [];
|
|
16342
|
+
for (const child of children) walkRepeatable(child, keyPrefix);
|
|
16343
|
+
}
|
|
16344
|
+
};
|
|
16345
|
+
for (const r of repeatables) {
|
|
16346
|
+
if (r.parentId) continue;
|
|
16347
|
+
walkRepeatable(r, "");
|
|
16348
|
+
}
|
|
16349
|
+
return out;
|
|
16285
16350
|
}
|
|
16286
16351
|
const previewBlur = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
16287
16352
|
__proto__: null,
|
|
16353
|
+
buildTeaserBlurFlatKeys,
|
|
16288
16354
|
hasAnyPreviewBlur,
|
|
16289
16355
|
injectPreviewBlur,
|
|
16290
16356
|
resolveBlurElementExactIdsFromFlatFormKeys
|
|
@@ -16769,9 +16835,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
16769
16835
|
}
|
|
16770
16836
|
return svgString;
|
|
16771
16837
|
}
|
|
16772
|
-
const resolvedPackageVersion = "0.5.
|
|
16838
|
+
const resolvedPackageVersion = "0.5.189";
|
|
16773
16839
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
16774
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
16840
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.189";
|
|
16775
16841
|
const roundParityValue = (value) => {
|
|
16776
16842
|
if (typeof value !== "number") return value;
|
|
16777
16843
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -17279,7 +17345,7 @@ class PixldocsRenderer {
|
|
|
17279
17345
|
await this.waitForCanvasScene(container, cloned, i);
|
|
17280
17346
|
}
|
|
17281
17347
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
17282
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
17348
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-BAAJU0RL.cjs"));
|
|
17283
17349
|
const prepared = preparePagesForExport(
|
|
17284
17350
|
cloned.pages,
|
|
17285
17351
|
canvasWidth,
|
|
@@ -19424,7 +19490,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
19424
19490
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
19425
19491
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
19426
19492
|
try {
|
|
19427
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
19493
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-BAAJU0RL.cjs"));
|
|
19428
19494
|
try {
|
|
19429
19495
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
19430
19496
|
} catch {
|
|
@@ -19775,6 +19841,7 @@ exports.assemblePdfFromSvgs = assemblePdfFromSvgs;
|
|
|
19775
19841
|
exports.awaitFontsForConfig = awaitFontsForConfig;
|
|
19776
19842
|
exports.bakeEdgeFade = bakeEdgeFade;
|
|
19777
19843
|
exports.buildRoundedTrianglePath = buildRoundedTrianglePath;
|
|
19844
|
+
exports.buildTeaserBlurFlatKeys = buildTeaserBlurFlatKeys;
|
|
19778
19845
|
exports.canvasImageLoader = canvasImageLoader;
|
|
19779
19846
|
exports.captureFabricCanvasSvgForPdf = captureFabricCanvasSvgForPdf;
|
|
19780
19847
|
exports.collectFontDescriptorsFromConfig = collectFontDescriptorsFromConfig;
|
|
@@ -19820,4 +19887,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
19820
19887
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
19821
19888
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
19822
19889
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
19823
|
-
//# sourceMappingURL=index-
|
|
19890
|
+
//# sourceMappingURL=index-CmrxeQ_K.cjs.map
|