@pixldocs/canvas-renderer 0.5.77 → 0.5.79
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/dist/index.cjs +256 -219
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +256 -219
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -256,7 +256,7 @@ export declare function normalizeFontFamily(fontStack: string): string;
|
|
|
256
256
|
* Package version banner. Bump alongside package.json so we can confirm
|
|
257
257
|
* (via browser:log) that the deployed bundle matches the expected build.
|
|
258
258
|
*/
|
|
259
|
-
export declare const PACKAGE_VERSION = "0.5.
|
|
259
|
+
export declare const PACKAGE_VERSION = "0.5.79";
|
|
260
260
|
|
|
261
261
|
export declare interface PageSettings {
|
|
262
262
|
backgroundColor?: string;
|
package/dist/index.js
CHANGED
|
@@ -11645,6 +11645,232 @@ function applyContentBoundsPagination(config) {
|
|
|
11645
11645
|
if (!mutated) return config;
|
|
11646
11646
|
return { ...config, pages: resultPages };
|
|
11647
11647
|
}
|
|
11648
|
+
function normalizeFontFamily(fontStack) {
|
|
11649
|
+
const first = fontStack.split(",")[0].trim();
|
|
11650
|
+
return first.replace(/^['"]|['"]$/g, "");
|
|
11651
|
+
}
|
|
11652
|
+
const loadedFonts = /* @__PURE__ */ new Set();
|
|
11653
|
+
const loadingPromises = /* @__PURE__ */ new Map();
|
|
11654
|
+
function withTimeout(promise, timeoutMs = 4e3) {
|
|
11655
|
+
let timeoutId;
|
|
11656
|
+
return Promise.race([
|
|
11657
|
+
promise,
|
|
11658
|
+
new Promise((resolve) => {
|
|
11659
|
+
timeoutId = setTimeout(resolve, timeoutMs);
|
|
11660
|
+
})
|
|
11661
|
+
]).finally(() => {
|
|
11662
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
11663
|
+
});
|
|
11664
|
+
}
|
|
11665
|
+
async function loadGoogleFontCSS(rawFontFamily) {
|
|
11666
|
+
if (!rawFontFamily || typeof document === "undefined") return;
|
|
11667
|
+
const fontFamily = normalizeFontFamily(rawFontFamily);
|
|
11668
|
+
if (!fontFamily) return;
|
|
11669
|
+
if (loadedFonts.has(fontFamily)) return;
|
|
11670
|
+
const existing = loadingPromises.get(fontFamily);
|
|
11671
|
+
if (existing) return existing;
|
|
11672
|
+
const promise = (async () => {
|
|
11673
|
+
try {
|
|
11674
|
+
const encoded = encodeURIComponent(fontFamily);
|
|
11675
|
+
const url = `https://fonts.googleapis.com/css?family=${encoded}:300,400,500,600,700&display=swap`;
|
|
11676
|
+
const link = document.createElement("link");
|
|
11677
|
+
link.rel = "stylesheet";
|
|
11678
|
+
link.href = url;
|
|
11679
|
+
link.crossOrigin = "anonymous";
|
|
11680
|
+
await new Promise((resolve, reject) => {
|
|
11681
|
+
link.onload = () => resolve();
|
|
11682
|
+
link.onerror = () => reject(new Error(`Failed to load font: ${fontFamily}`));
|
|
11683
|
+
document.head.appendChild(link);
|
|
11684
|
+
});
|
|
11685
|
+
loadedFonts.add(fontFamily);
|
|
11686
|
+
} catch (e) {
|
|
11687
|
+
console.warn(`[@pixldocs/canvas-renderer] Font load failed: ${fontFamily}`, e);
|
|
11688
|
+
}
|
|
11689
|
+
})();
|
|
11690
|
+
loadingPromises.set(fontFamily, promise);
|
|
11691
|
+
await promise;
|
|
11692
|
+
loadingPromises.delete(fontFamily);
|
|
11693
|
+
}
|
|
11694
|
+
function collectFontsFromConfig(config) {
|
|
11695
|
+
var _a;
|
|
11696
|
+
const fonts = /* @__PURE__ */ new Set();
|
|
11697
|
+
fonts.add("Open Sans");
|
|
11698
|
+
fonts.add("Hind");
|
|
11699
|
+
function walk(nodes) {
|
|
11700
|
+
var _a2;
|
|
11701
|
+
if (!nodes) return;
|
|
11702
|
+
for (const node of nodes) {
|
|
11703
|
+
if (node.fontFamily) fonts.add(normalizeFontFamily(node.fontFamily));
|
|
11704
|
+
if ((_a2 = node.smartProps) == null ? void 0 : _a2.fontFamily) fonts.add(normalizeFontFamily(node.smartProps.fontFamily));
|
|
11705
|
+
if (node.styles && Array.isArray(node.styles)) {
|
|
11706
|
+
for (const lineStyle of node.styles) {
|
|
11707
|
+
if (lineStyle && typeof lineStyle === "object") {
|
|
11708
|
+
for (const charStyle of Object.values(lineStyle)) {
|
|
11709
|
+
if (charStyle == null ? void 0 : charStyle.fontFamily) fonts.add(normalizeFontFamily(charStyle.fontFamily));
|
|
11710
|
+
}
|
|
11711
|
+
}
|
|
11712
|
+
}
|
|
11713
|
+
}
|
|
11714
|
+
if (node.children) walk(node.children);
|
|
11715
|
+
}
|
|
11716
|
+
}
|
|
11717
|
+
for (const page of config.pages || []) {
|
|
11718
|
+
walk(page.children || []);
|
|
11719
|
+
}
|
|
11720
|
+
if ((_a = config.themeConfig) == null ? void 0 : _a.variables) {
|
|
11721
|
+
for (const def of Object.values(config.themeConfig.variables)) {
|
|
11722
|
+
if (def.value && typeof def.value === "string" && !def.value.startsWith("#") && !def.value.startsWith("rgb")) {
|
|
11723
|
+
if (def.label && /font/i.test(def.label)) {
|
|
11724
|
+
fonts.add(normalizeFontFamily(def.value));
|
|
11725
|
+
}
|
|
11726
|
+
}
|
|
11727
|
+
}
|
|
11728
|
+
}
|
|
11729
|
+
return fonts;
|
|
11730
|
+
}
|
|
11731
|
+
function collectFontDescriptorsFromConfig(config) {
|
|
11732
|
+
var _a;
|
|
11733
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11734
|
+
const descriptors = [];
|
|
11735
|
+
function add(family, weight, style) {
|
|
11736
|
+
const f = normalizeFontFamily(family);
|
|
11737
|
+
if (!f) return;
|
|
11738
|
+
const w = weight ?? 400;
|
|
11739
|
+
const s = style ?? "normal";
|
|
11740
|
+
const key = `${f}|${w}|${s}`;
|
|
11741
|
+
if (seen.has(key)) return;
|
|
11742
|
+
seen.add(key);
|
|
11743
|
+
descriptors.push({ family: f, weight: w, style: s });
|
|
11744
|
+
}
|
|
11745
|
+
function walk(nodes) {
|
|
11746
|
+
var _a2;
|
|
11747
|
+
if (!nodes) return;
|
|
11748
|
+
for (const node of nodes) {
|
|
11749
|
+
if (node.fontFamily) {
|
|
11750
|
+
add(node.fontFamily, node.fontWeight, node.fontStyle);
|
|
11751
|
+
if (node.type === "text") {
|
|
11752
|
+
for (const w of [300, 400, 500, 600, 700]) {
|
|
11753
|
+
add(node.fontFamily, w, node.fontStyle);
|
|
11754
|
+
}
|
|
11755
|
+
}
|
|
11756
|
+
}
|
|
11757
|
+
if ((_a2 = node.smartProps) == null ? void 0 : _a2.fontFamily) {
|
|
11758
|
+
add(node.smartProps.fontFamily, node.smartProps.fontWeight, node.smartProps.fontStyle);
|
|
11759
|
+
}
|
|
11760
|
+
if (node.styles) {
|
|
11761
|
+
const styleEntries = Array.isArray(node.styles) ? node.styles : Object.values(node.styles);
|
|
11762
|
+
for (const lineStyle of styleEntries) {
|
|
11763
|
+
if (lineStyle && typeof lineStyle === "object") {
|
|
11764
|
+
for (const charStyle of Object.values(lineStyle)) {
|
|
11765
|
+
if (charStyle == null ? void 0 : charStyle.fontFamily) {
|
|
11766
|
+
add(charStyle.fontFamily, charStyle.fontWeight, charStyle.fontStyle);
|
|
11767
|
+
}
|
|
11768
|
+
}
|
|
11769
|
+
}
|
|
11770
|
+
}
|
|
11771
|
+
}
|
|
11772
|
+
if (node.children) walk(node.children);
|
|
11773
|
+
}
|
|
11774
|
+
}
|
|
11775
|
+
add("Open Sans", 400, "normal");
|
|
11776
|
+
add("Hind", 400, "normal");
|
|
11777
|
+
add("Hind", 700, "normal");
|
|
11778
|
+
for (const page of config.pages || []) {
|
|
11779
|
+
walk(page.children || []);
|
|
11780
|
+
}
|
|
11781
|
+
if ((_a = config.themeConfig) == null ? void 0 : _a.variables) {
|
|
11782
|
+
for (const def of Object.values(config.themeConfig.variables)) {
|
|
11783
|
+
if (def.value && typeof def.value === "string" && !def.value.startsWith("#") && !def.value.startsWith("rgb")) {
|
|
11784
|
+
if (def.label && /font/i.test(def.label)) {
|
|
11785
|
+
add(def.value);
|
|
11786
|
+
}
|
|
11787
|
+
}
|
|
11788
|
+
}
|
|
11789
|
+
}
|
|
11790
|
+
return descriptors;
|
|
11791
|
+
}
|
|
11792
|
+
async function ensureFontsForResolvedConfig(config) {
|
|
11793
|
+
if (typeof document === "undefined") return;
|
|
11794
|
+
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
11795
|
+
const families = new Set(descriptors.map((d) => d.family));
|
|
11796
|
+
await withTimeout(Promise.all([...families].map((f) => loadGoogleFontCSS(f))), 3500);
|
|
11797
|
+
if (document.fonts) {
|
|
11798
|
+
descriptors.forEach((d) => {
|
|
11799
|
+
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
11800
|
+
const weightStr = String(d.weight);
|
|
11801
|
+
const spec = `${stylePrefix}${weightStr} 16px "${d.family}"`;
|
|
11802
|
+
document.fonts.load(spec).catch(() => {
|
|
11803
|
+
});
|
|
11804
|
+
});
|
|
11805
|
+
}
|
|
11806
|
+
}
|
|
11807
|
+
function configHasAutoShrinkText$1(config) {
|
|
11808
|
+
var _a;
|
|
11809
|
+
if (!((_a = config == null ? void 0 : config.pages) == null ? void 0 : _a.length)) return false;
|
|
11810
|
+
const walk = (nodes) => {
|
|
11811
|
+
for (const node of nodes || []) {
|
|
11812
|
+
if (!node) continue;
|
|
11813
|
+
if (node.type === "text" && node.overflowPolicy === "auto-shrink") return true;
|
|
11814
|
+
if (Array.isArray(node.children) && node.children.length && walk(node.children)) return true;
|
|
11815
|
+
}
|
|
11816
|
+
return false;
|
|
11817
|
+
};
|
|
11818
|
+
for (const page of config.pages) {
|
|
11819
|
+
if (walk(page.children || [])) return true;
|
|
11820
|
+
}
|
|
11821
|
+
return false;
|
|
11822
|
+
}
|
|
11823
|
+
async function awaitFontsForConfig(config, maxWaitMs) {
|
|
11824
|
+
if (typeof document === "undefined" || !document.fonts) return;
|
|
11825
|
+
await ensureFontsForResolvedConfig(config);
|
|
11826
|
+
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
11827
|
+
if (descriptors.length === 0) return;
|
|
11828
|
+
const loads = Promise.all(
|
|
11829
|
+
descriptors.map((d) => {
|
|
11830
|
+
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
11831
|
+
const spec = `${stylePrefix}${d.weight} 16px "${d.family}"`;
|
|
11832
|
+
return document.fonts.load(spec).catch(() => []);
|
|
11833
|
+
})
|
|
11834
|
+
).then(() => void 0);
|
|
11835
|
+
await Promise.race([
|
|
11836
|
+
loads,
|
|
11837
|
+
new Promise((resolve) => setTimeout(resolve, maxWaitMs))
|
|
11838
|
+
]);
|
|
11839
|
+
await Promise.race([
|
|
11840
|
+
document.fonts.ready.catch(() => void 0).then(() => void 0),
|
|
11841
|
+
new Promise((r) => setTimeout(r, Math.min(500, maxWaitMs)))
|
|
11842
|
+
]);
|
|
11843
|
+
const checkSpecs = [];
|
|
11844
|
+
for (const d of descriptors) {
|
|
11845
|
+
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
11846
|
+
checkSpecs.push(`${stylePrefix}${d.weight} 16px "${d.family}"`);
|
|
11847
|
+
}
|
|
11848
|
+
const startedAt = Date.now();
|
|
11849
|
+
const pollBudget = Math.min(maxWaitMs, 2500);
|
|
11850
|
+
const allReady = () => {
|
|
11851
|
+
for (const spec of checkSpecs) {
|
|
11852
|
+
try {
|
|
11853
|
+
if (!document.fonts.check(spec)) return false;
|
|
11854
|
+
} catch {
|
|
11855
|
+
}
|
|
11856
|
+
}
|
|
11857
|
+
return true;
|
|
11858
|
+
};
|
|
11859
|
+
while (!allReady() && Date.now() - startedAt < pollBudget) {
|
|
11860
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
11861
|
+
}
|
|
11862
|
+
await new Promise(
|
|
11863
|
+
(resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))
|
|
11864
|
+
);
|
|
11865
|
+
}
|
|
11866
|
+
async function awaitFontsBeforeTextReflow(config) {
|
|
11867
|
+
if (typeof document === "undefined" || !configHasAutoShrinkText$1(config)) return;
|
|
11868
|
+
try {
|
|
11869
|
+
await awaitFontsForConfig(config, 4e3);
|
|
11870
|
+
} catch (error) {
|
|
11871
|
+
console.warn("[@pixldocs/canvas-renderer] Font wait before text reflow failed:", error);
|
|
11872
|
+
}
|
|
11873
|
+
}
|
|
11648
11874
|
function repeatablePageToSection(page) {
|
|
11649
11875
|
return {
|
|
11650
11876
|
id: page.id,
|
|
@@ -11838,6 +12064,7 @@ async function resolveTemplateData(options) {
|
|
|
11838
12064
|
}
|
|
11839
12065
|
}
|
|
11840
12066
|
const repeatablePagesInput = deriveRepeatablePagesFromTemplate(config, inlineFormSchema, mergedFormData);
|
|
12067
|
+
await awaitFontsBeforeTextReflow(config);
|
|
11841
12068
|
const resolvedConfig = applyFormDataToConfig(
|
|
11842
12069
|
config,
|
|
11843
12070
|
mappings,
|
|
@@ -11982,6 +12209,7 @@ async function resolveFromForm(options) {
|
|
|
11982
12209
|
};
|
|
11983
12210
|
collectFormats(formConfig.sections);
|
|
11984
12211
|
}
|
|
12212
|
+
await awaitFontsBeforeTextReflow(templateConfig);
|
|
11985
12213
|
let resolvedConfig = applyFormDataToConfig(
|
|
11986
12214
|
templateConfig,
|
|
11987
12215
|
mappings,
|
|
@@ -12160,224 +12388,6 @@ function paintRepeatableSections(config, repeatableSections) {
|
|
|
12160
12388
|
}
|
|
12161
12389
|
}
|
|
12162
12390
|
}
|
|
12163
|
-
function normalizeFontFamily(fontStack) {
|
|
12164
|
-
const first = fontStack.split(",")[0].trim();
|
|
12165
|
-
return first.replace(/^['"]|['"]$/g, "");
|
|
12166
|
-
}
|
|
12167
|
-
const loadedFonts = /* @__PURE__ */ new Set();
|
|
12168
|
-
const loadingPromises = /* @__PURE__ */ new Map();
|
|
12169
|
-
function withTimeout(promise, timeoutMs = 4e3) {
|
|
12170
|
-
let timeoutId;
|
|
12171
|
-
return Promise.race([
|
|
12172
|
-
promise,
|
|
12173
|
-
new Promise((resolve) => {
|
|
12174
|
-
timeoutId = setTimeout(resolve, timeoutMs);
|
|
12175
|
-
})
|
|
12176
|
-
]).finally(() => {
|
|
12177
|
-
if (timeoutId) clearTimeout(timeoutId);
|
|
12178
|
-
});
|
|
12179
|
-
}
|
|
12180
|
-
async function loadGoogleFontCSS(rawFontFamily) {
|
|
12181
|
-
if (!rawFontFamily || typeof document === "undefined") return;
|
|
12182
|
-
const fontFamily = normalizeFontFamily(rawFontFamily);
|
|
12183
|
-
if (!fontFamily) return;
|
|
12184
|
-
if (loadedFonts.has(fontFamily)) return;
|
|
12185
|
-
const existing = loadingPromises.get(fontFamily);
|
|
12186
|
-
if (existing) return existing;
|
|
12187
|
-
const promise = (async () => {
|
|
12188
|
-
try {
|
|
12189
|
-
const encoded = encodeURIComponent(fontFamily);
|
|
12190
|
-
const url = `https://fonts.googleapis.com/css?family=${encoded}:300,400,500,600,700&display=swap`;
|
|
12191
|
-
const link = document.createElement("link");
|
|
12192
|
-
link.rel = "stylesheet";
|
|
12193
|
-
link.href = url;
|
|
12194
|
-
link.crossOrigin = "anonymous";
|
|
12195
|
-
await new Promise((resolve, reject) => {
|
|
12196
|
-
link.onload = () => resolve();
|
|
12197
|
-
link.onerror = () => reject(new Error(`Failed to load font: ${fontFamily}`));
|
|
12198
|
-
document.head.appendChild(link);
|
|
12199
|
-
});
|
|
12200
|
-
loadedFonts.add(fontFamily);
|
|
12201
|
-
} catch (e) {
|
|
12202
|
-
console.warn(`[@pixldocs/canvas-renderer] Font load failed: ${fontFamily}`, e);
|
|
12203
|
-
}
|
|
12204
|
-
})();
|
|
12205
|
-
loadingPromises.set(fontFamily, promise);
|
|
12206
|
-
await promise;
|
|
12207
|
-
loadingPromises.delete(fontFamily);
|
|
12208
|
-
}
|
|
12209
|
-
function collectFontsFromConfig(config) {
|
|
12210
|
-
var _a;
|
|
12211
|
-
const fonts = /* @__PURE__ */ new Set();
|
|
12212
|
-
fonts.add("Open Sans");
|
|
12213
|
-
fonts.add("Hind");
|
|
12214
|
-
function walk(nodes) {
|
|
12215
|
-
var _a2;
|
|
12216
|
-
if (!nodes) return;
|
|
12217
|
-
for (const node of nodes) {
|
|
12218
|
-
if (node.fontFamily) fonts.add(normalizeFontFamily(node.fontFamily));
|
|
12219
|
-
if ((_a2 = node.smartProps) == null ? void 0 : _a2.fontFamily) fonts.add(normalizeFontFamily(node.smartProps.fontFamily));
|
|
12220
|
-
if (node.styles && Array.isArray(node.styles)) {
|
|
12221
|
-
for (const lineStyle of node.styles) {
|
|
12222
|
-
if (lineStyle && typeof lineStyle === "object") {
|
|
12223
|
-
for (const charStyle of Object.values(lineStyle)) {
|
|
12224
|
-
if (charStyle == null ? void 0 : charStyle.fontFamily) fonts.add(normalizeFontFamily(charStyle.fontFamily));
|
|
12225
|
-
}
|
|
12226
|
-
}
|
|
12227
|
-
}
|
|
12228
|
-
}
|
|
12229
|
-
if (node.children) walk(node.children);
|
|
12230
|
-
}
|
|
12231
|
-
}
|
|
12232
|
-
for (const page of config.pages || []) {
|
|
12233
|
-
walk(page.children || []);
|
|
12234
|
-
}
|
|
12235
|
-
if ((_a = config.themeConfig) == null ? void 0 : _a.variables) {
|
|
12236
|
-
for (const def of Object.values(config.themeConfig.variables)) {
|
|
12237
|
-
if (def.value && typeof def.value === "string" && !def.value.startsWith("#") && !def.value.startsWith("rgb")) {
|
|
12238
|
-
if (def.label && /font/i.test(def.label)) {
|
|
12239
|
-
fonts.add(normalizeFontFamily(def.value));
|
|
12240
|
-
}
|
|
12241
|
-
}
|
|
12242
|
-
}
|
|
12243
|
-
}
|
|
12244
|
-
return fonts;
|
|
12245
|
-
}
|
|
12246
|
-
function collectFontDescriptorsFromConfig(config) {
|
|
12247
|
-
var _a;
|
|
12248
|
-
const seen = /* @__PURE__ */ new Set();
|
|
12249
|
-
const descriptors = [];
|
|
12250
|
-
function add(family, weight, style) {
|
|
12251
|
-
const f = normalizeFontFamily(family);
|
|
12252
|
-
if (!f) return;
|
|
12253
|
-
const w = weight ?? 400;
|
|
12254
|
-
const s = style ?? "normal";
|
|
12255
|
-
const key = `${f}|${w}|${s}`;
|
|
12256
|
-
if (seen.has(key)) return;
|
|
12257
|
-
seen.add(key);
|
|
12258
|
-
descriptors.push({ family: f, weight: w, style: s });
|
|
12259
|
-
}
|
|
12260
|
-
function walk(nodes) {
|
|
12261
|
-
var _a2;
|
|
12262
|
-
if (!nodes) return;
|
|
12263
|
-
for (const node of nodes) {
|
|
12264
|
-
if (node.fontFamily) {
|
|
12265
|
-
add(node.fontFamily, node.fontWeight, node.fontStyle);
|
|
12266
|
-
if (node.type === "text") {
|
|
12267
|
-
for (const w of [300, 400, 500, 600, 700]) {
|
|
12268
|
-
add(node.fontFamily, w, node.fontStyle);
|
|
12269
|
-
}
|
|
12270
|
-
}
|
|
12271
|
-
}
|
|
12272
|
-
if ((_a2 = node.smartProps) == null ? void 0 : _a2.fontFamily) {
|
|
12273
|
-
add(node.smartProps.fontFamily, node.smartProps.fontWeight, node.smartProps.fontStyle);
|
|
12274
|
-
}
|
|
12275
|
-
if (node.styles) {
|
|
12276
|
-
const styleEntries = Array.isArray(node.styles) ? node.styles : Object.values(node.styles);
|
|
12277
|
-
for (const lineStyle of styleEntries) {
|
|
12278
|
-
if (lineStyle && typeof lineStyle === "object") {
|
|
12279
|
-
for (const charStyle of Object.values(lineStyle)) {
|
|
12280
|
-
if (charStyle == null ? void 0 : charStyle.fontFamily) {
|
|
12281
|
-
add(charStyle.fontFamily, charStyle.fontWeight, charStyle.fontStyle);
|
|
12282
|
-
}
|
|
12283
|
-
}
|
|
12284
|
-
}
|
|
12285
|
-
}
|
|
12286
|
-
}
|
|
12287
|
-
if (node.children) walk(node.children);
|
|
12288
|
-
}
|
|
12289
|
-
}
|
|
12290
|
-
add("Open Sans", 400, "normal");
|
|
12291
|
-
add("Hind", 400, "normal");
|
|
12292
|
-
add("Hind", 700, "normal");
|
|
12293
|
-
for (const page of config.pages || []) {
|
|
12294
|
-
walk(page.children || []);
|
|
12295
|
-
}
|
|
12296
|
-
if ((_a = config.themeConfig) == null ? void 0 : _a.variables) {
|
|
12297
|
-
for (const def of Object.values(config.themeConfig.variables)) {
|
|
12298
|
-
if (def.value && typeof def.value === "string" && !def.value.startsWith("#") && !def.value.startsWith("rgb")) {
|
|
12299
|
-
if (def.label && /font/i.test(def.label)) {
|
|
12300
|
-
add(def.value);
|
|
12301
|
-
}
|
|
12302
|
-
}
|
|
12303
|
-
}
|
|
12304
|
-
}
|
|
12305
|
-
return descriptors;
|
|
12306
|
-
}
|
|
12307
|
-
async function ensureFontsForResolvedConfig(config) {
|
|
12308
|
-
if (typeof document === "undefined") return;
|
|
12309
|
-
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
12310
|
-
const families = new Set(descriptors.map((d) => d.family));
|
|
12311
|
-
await withTimeout(Promise.all([...families].map((f) => loadGoogleFontCSS(f))), 3500);
|
|
12312
|
-
if (document.fonts) {
|
|
12313
|
-
descriptors.forEach((d) => {
|
|
12314
|
-
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
12315
|
-
const weightStr = String(d.weight);
|
|
12316
|
-
const spec = `${stylePrefix}${weightStr} 16px "${d.family}"`;
|
|
12317
|
-
document.fonts.load(spec).catch(() => {
|
|
12318
|
-
});
|
|
12319
|
-
});
|
|
12320
|
-
}
|
|
12321
|
-
}
|
|
12322
|
-
function configHasAutoShrinkText$1(config) {
|
|
12323
|
-
var _a;
|
|
12324
|
-
if (!((_a = config == null ? void 0 : config.pages) == null ? void 0 : _a.length)) return false;
|
|
12325
|
-
const walk = (nodes) => {
|
|
12326
|
-
for (const node of nodes || []) {
|
|
12327
|
-
if (!node) continue;
|
|
12328
|
-
if (node.type === "text" && node.overflowPolicy === "auto-shrink") return true;
|
|
12329
|
-
if (Array.isArray(node.children) && node.children.length && walk(node.children)) return true;
|
|
12330
|
-
}
|
|
12331
|
-
return false;
|
|
12332
|
-
};
|
|
12333
|
-
for (const page of config.pages) {
|
|
12334
|
-
if (walk(page.children || [])) return true;
|
|
12335
|
-
}
|
|
12336
|
-
return false;
|
|
12337
|
-
}
|
|
12338
|
-
async function awaitFontsForConfig(config, maxWaitMs) {
|
|
12339
|
-
if (typeof document === "undefined" || !document.fonts) return;
|
|
12340
|
-
await ensureFontsForResolvedConfig(config);
|
|
12341
|
-
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
12342
|
-
if (descriptors.length === 0) return;
|
|
12343
|
-
const loads = Promise.all(
|
|
12344
|
-
descriptors.map((d) => {
|
|
12345
|
-
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
12346
|
-
const spec = `${stylePrefix}${d.weight} 16px "${d.family}"`;
|
|
12347
|
-
return document.fonts.load(spec).catch(() => []);
|
|
12348
|
-
})
|
|
12349
|
-
).then(() => void 0);
|
|
12350
|
-
await Promise.race([
|
|
12351
|
-
loads,
|
|
12352
|
-
new Promise((resolve) => setTimeout(resolve, maxWaitMs))
|
|
12353
|
-
]);
|
|
12354
|
-
await Promise.race([
|
|
12355
|
-
document.fonts.ready.catch(() => void 0).then(() => void 0),
|
|
12356
|
-
new Promise((r) => setTimeout(r, Math.min(500, maxWaitMs)))
|
|
12357
|
-
]);
|
|
12358
|
-
const checkSpecs = [];
|
|
12359
|
-
for (const d of descriptors) {
|
|
12360
|
-
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
12361
|
-
checkSpecs.push(`${stylePrefix}${d.weight} 16px "${d.family}"`);
|
|
12362
|
-
}
|
|
12363
|
-
const startedAt = Date.now();
|
|
12364
|
-
const pollBudget = Math.min(maxWaitMs, 2500);
|
|
12365
|
-
const allReady = () => {
|
|
12366
|
-
for (const spec of checkSpecs) {
|
|
12367
|
-
try {
|
|
12368
|
-
if (!document.fonts.check(spec)) return false;
|
|
12369
|
-
} catch {
|
|
12370
|
-
}
|
|
12371
|
-
}
|
|
12372
|
-
return true;
|
|
12373
|
-
};
|
|
12374
|
-
while (!allReady() && Date.now() - startedAt < pollBudget) {
|
|
12375
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
12376
|
-
}
|
|
12377
|
-
await new Promise(
|
|
12378
|
-
(resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))
|
|
12379
|
-
);
|
|
12380
|
-
}
|
|
12381
12391
|
const PREVIEW_DEBUG_PREFIX = "[canvas-renderer][preview-debug]";
|
|
12382
12392
|
function countUnderlinedNodes(config) {
|
|
12383
12393
|
var _a;
|
|
@@ -12568,7 +12578,7 @@ function PixldocsPreview(props) {
|
|
|
12568
12578
|
!canvasSettled && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
|
|
12569
12579
|
] });
|
|
12570
12580
|
}
|
|
12571
|
-
const PACKAGE_VERSION = "0.5.
|
|
12581
|
+
const PACKAGE_VERSION = "0.5.79";
|
|
12572
12582
|
const roundParityValue = (value) => {
|
|
12573
12583
|
if (typeof value !== "number") return value;
|
|
12574
12584
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -15478,6 +15488,25 @@ async function convertTextDecorationsToLines(svg) {
|
|
|
15478
15488
|
}
|
|
15479
15489
|
}
|
|
15480
15490
|
}
|
|
15491
|
+
async function convertSvgTextDecorationsToLinesString(svgStr) {
|
|
15492
|
+
if (typeof DOMParser === "undefined" || typeof XMLSerializer === "undefined") {
|
|
15493
|
+
return svgStr;
|
|
15494
|
+
}
|
|
15495
|
+
if (!/text-decoration/i.test(svgStr) && !/underline/i.test(svgStr)) {
|
|
15496
|
+
return svgStr;
|
|
15497
|
+
}
|
|
15498
|
+
try {
|
|
15499
|
+
const parser = new DOMParser();
|
|
15500
|
+
const docEl = parser.parseFromString(svgStr, "image/svg+xml");
|
|
15501
|
+
const rootSvg = docEl.documentElement;
|
|
15502
|
+
if (!rootSvg) return svgStr;
|
|
15503
|
+
await convertTextDecorationsToLines(rootSvg);
|
|
15504
|
+
const serializer = new XMLSerializer();
|
|
15505
|
+
return serializer.serializeToString(rootSvg);
|
|
15506
|
+
} catch {
|
|
15507
|
+
return svgStr;
|
|
15508
|
+
}
|
|
15509
|
+
}
|
|
15481
15510
|
async function rasterizeShadowMarkers(svg) {
|
|
15482
15511
|
var _a, _b, _c, _d, _e;
|
|
15483
15512
|
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
@@ -15746,6 +15775,14 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
15746
15775
|
const shouldStripBg = stripPageBackground ?? hasGradient;
|
|
15747
15776
|
const shouldOutlineText = options.outlineText !== false;
|
|
15748
15777
|
let pageSvg = page.svg;
|
|
15778
|
+
try {
|
|
15779
|
+
pageSvg = await convertSvgTextDecorationsToLinesString(pageSvg);
|
|
15780
|
+
} catch (underlineErr) {
|
|
15781
|
+
console.warn(
|
|
15782
|
+
"[canvas-renderer][pdf] underline-to-line conversion failed (raw stage):",
|
|
15783
|
+
underlineErr
|
|
15784
|
+
);
|
|
15785
|
+
}
|
|
15749
15786
|
if (shouldOutlineText) {
|
|
15750
15787
|
try {
|
|
15751
15788
|
const { convertAllTextToPath } = await import("./svgTextToPath-BP0Kppla.js");
|