@guodun/antdv 1.7.12 → 1.7.14

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.
Files changed (67) hide show
  1. package/dist/es/components/contract-signing-location/src/ContractSigningLocation.vue.mjs +373 -295
  2. package/dist/es/components/contract-signing-location/src/ContractSigningLocationCanvas.vue.mjs +219 -202
  3. package/dist/es/components/contract-signing-location/src/ContractSigningTemplatePage.vue.mjs +18 -18
  4. package/dist/es/components/contract-signing-location/src/template-source.mjs +62 -49
  5. package/dist/es/components/index.mjs +1 -0
  6. package/dist/es/components/pro-contract-template-designer/index.mjs +1 -0
  7. package/dist/es/components/pro-contract-template-designer/src/ContractTemplatePreviewPage.vue.mjs +37 -42
  8. package/dist/es/components/pro-contract-template-designer/src/ContractTemplateRendererPage.vue.mjs +69 -55
  9. package/dist/es/components/pro-contract-template-designer/src/ContractTemplateSingleRenderer.vue.mjs +278 -270
  10. package/dist/es/components/pro-contract-template-designer/src/DesignerPage.vue.mjs +344 -343
  11. package/dist/es/components/pro-contract-template-designer/src/ProContractTemplateDesigner.vue.mjs +1025 -964
  12. package/dist/es/components/pro-contract-template-designer/src/ProContractTemplateRenderer.vue.mjs +120 -74
  13. package/dist/es/components/pro-contract-template-designer/src/SigningLayoutCustomModal.vue.mjs +72 -59
  14. package/dist/es/components/pro-contract-template-designer/src/composables/use-template-designer.mjs +133 -132
  15. package/dist/es/components/pro-contract-template-designer/src/utils/contract-layout-check.mjs +239 -0
  16. package/dist/es/components/pro-contract-template-designer/src/utils/contract-print-document.mjs +95 -71
  17. package/dist/es/components/pro-contract-template-designer/src/utils/page-decorations.mjs +67 -76
  18. package/dist/es/components/pro-contract-template-designer/src/utils/signing-layout-presets.mjs +77 -61
  19. package/dist/es/components/pro-contract-template-designer/src/utils/template-renderer.mjs +96 -83
  20. package/dist/es/components/pro-contract-template-designer/src/utils/template-variable-render.mjs +23 -15
  21. package/dist/es/components/pro-contract-template-designer/style/index.css +1 -1
  22. package/dist/es/contract-print-css/index.mjs +134 -30
  23. package/dist/es/contract-print.mjs +2 -0
  24. package/dist/es/index.mjs +21 -20
  25. package/dist/lib/components/contract-signing-location/src/ContractSigningLocation.vue.cjs +1 -1
  26. package/dist/lib/components/contract-signing-location/src/ContractSigningLocationCanvas.vue.cjs +1 -1
  27. package/dist/lib/components/contract-signing-location/src/ContractSigningTemplatePage.vue.cjs +1 -1
  28. package/dist/lib/components/contract-signing-location/src/template-source.cjs +1 -1
  29. package/dist/lib/components/index.cjs +1 -1
  30. package/dist/lib/components/pro-contract-template-designer/index.cjs +1 -1
  31. package/dist/lib/components/pro-contract-template-designer/src/ContractTemplatePreviewPage.vue.cjs +1 -1
  32. package/dist/lib/components/pro-contract-template-designer/src/ContractTemplateRendererPage.vue.cjs +1 -1
  33. package/dist/lib/components/pro-contract-template-designer/src/ContractTemplateSingleRenderer.vue.cjs +1 -1
  34. package/dist/lib/components/pro-contract-template-designer/src/DesignerPage.vue.cjs +2 -2
  35. package/dist/lib/components/pro-contract-template-designer/src/ProContractTemplateDesigner.vue.cjs +1 -1
  36. package/dist/lib/components/pro-contract-template-designer/src/ProContractTemplateRenderer.vue.cjs +1 -1
  37. package/dist/lib/components/pro-contract-template-designer/src/SigningLayoutCustomModal.vue.cjs +1 -1
  38. package/dist/lib/components/pro-contract-template-designer/src/composables/use-template-designer.cjs +4 -4
  39. package/dist/lib/components/pro-contract-template-designer/src/utils/contract-layout-check.cjs +1 -0
  40. package/dist/lib/components/pro-contract-template-designer/src/utils/contract-print-document.cjs +50 -28
  41. package/dist/lib/components/pro-contract-template-designer/src/utils/page-decorations.cjs +1 -1
  42. package/dist/lib/components/pro-contract-template-designer/src/utils/signing-layout-presets.cjs +1 -1
  43. package/dist/lib/components/pro-contract-template-designer/src/utils/template-renderer.cjs +5 -5
  44. package/dist/lib/components/pro-contract-template-designer/src/utils/template-variable-render.cjs +1 -1
  45. package/dist/lib/components/pro-contract-template-designer/style/index.css +1 -1
  46. package/dist/lib/contract-print-css/index.cjs +74 -23
  47. package/dist/lib/contract-print.cjs +1 -0
  48. package/dist/lib/index.cjs +1 -1
  49. package/dist/theme/icon.css +1 -1
  50. package/dist/theme/index.css +1 -1
  51. package/dist/types/components/contract-signing-location/src/ContractSigningLocation.vue.d.ts +9 -0
  52. package/dist/types/components/contract-signing-location/src/ContractSigningLocationCanvas.vue.d.ts +7 -0
  53. package/dist/types/components/contract-signing-location/src/template-source.d.ts +6 -0
  54. package/dist/types/components/pro-contract-template-designer/index.d.ts +1 -0
  55. package/dist/types/components/pro-contract-template-designer/src/ContractTemplateSingleRenderer.vue.d.ts +2 -0
  56. package/dist/types/components/pro-contract-template-designer/src/ProContractTemplateDesigner.vue.d.ts +5 -1
  57. package/dist/types/components/pro-contract-template-designer/src/ProContractTemplateRenderer.vue.d.ts +7 -2
  58. package/dist/types/components/pro-contract-template-designer/src/composables/use-template-designer.d.ts +2 -2
  59. package/dist/types/components/pro-contract-template-designer/src/types.d.ts +36 -0
  60. package/dist/types/components/pro-contract-template-designer/src/utils/contract-layout-check.d.ts +104 -0
  61. package/dist/types/components/pro-contract-template-designer/src/utils/contract-print-document.d.ts +4 -1
  62. package/dist/types/components/pro-contract-template-designer/src/utils/page-decorations.d.ts +2 -8
  63. package/dist/types/components/pro-contract-template-designer/src/utils/signing-layout-presets.d.ts +9 -0
  64. package/dist/types/components/pro-contract-template-designer/src/utils/template-renderer.d.ts +6 -1
  65. package/dist/types/contract-print-css/index.d.ts +70 -0
  66. package/dist/types/contract-print.d.ts +2 -0
  67. package/package.json +14 -2
@@ -0,0 +1,239 @@
1
+ import { CONTRACT_PRINT_STYLE_VERSION as e, resolveContractPagePadding as t } from "../../../../contract-print-css/index.mjs";
2
+ import { CONTRACT_PRINT_FRAME_TIMEOUT_MS as n, buildContractPrintDocument as r, isContractPrintFrameMessage as i, subscribeContractPrintFrameMessages as a, unsubscribeContractPrintFrameMessages as o } from "./contract-print-document.mjs";
3
+ import { buildPageDecorationClassNames as s, buildPageDecorationsHtml as c, normalizePageDecorations as l } from "./page-decorations.mjs";
4
+ import { buildTemplateRenderPages as u, normalizeRenderValues as d } from "./template-renderer.mjs";
5
+ //#region src/components/pro-contract-template-designer/src/utils/contract-layout-check.ts
6
+ var f = class extends Error {
7
+ constructor(e) {
8
+ super(e), this.name = "ContractTemplateLayoutMeasureError";
9
+ }
10
+ }, p = 256;
11
+ function m(e, n) {
12
+ let r = t(l(e.pageDecorations), n.pageNumber), i = {
13
+ pageIndex: n.pageIndex,
14
+ pageNumber: n.pageNumber,
15
+ pageId: e.id,
16
+ pageFormat: e.format,
17
+ width: e.width,
18
+ height: e.height,
19
+ paddingTop: r.top,
20
+ paddingBottom: r.bottom,
21
+ classNames: s(e.pageDecorations, n.pageNumber),
22
+ decorationsHtml: c(e.pageDecorations, n.pageNumber, n.totalPages, e.decorationVariables, e.decorationValues),
23
+ contentHtml: e.contentHtml
24
+ };
25
+ return {
26
+ ...n.fileId === void 0 ? {} : { fileId: n.fileId },
27
+ ...i,
28
+ key: h(i)
29
+ };
30
+ }
31
+ function h(t) {
32
+ return JSON.stringify([
33
+ e,
34
+ t.width,
35
+ t.height,
36
+ t.pageFormat,
37
+ t.paddingTop,
38
+ t.paddingBottom,
39
+ t.classNames,
40
+ t.decorationsHtml,
41
+ t.contentHtml
42
+ ]);
43
+ }
44
+ function g(e) {
45
+ if (e.layoutPages) return e.layoutPages;
46
+ let t = e.template, n = Array.isArray(t?.pages) ? t.pages : [], r = d(t, e.values);
47
+ return n.flatMap((i, a) => {
48
+ let o = u({
49
+ ...t,
50
+ pages: [i]
51
+ }, r, { mode: "display" })[0];
52
+ return o ? [m(o, {
53
+ ...e.fileId === void 0 ? {} : { fileId: e.fileId },
54
+ pageIndex: a,
55
+ pageNumber: a + 1,
56
+ totalPages: n.length
57
+ })] : [];
58
+ });
59
+ }
60
+ var _;
61
+ async function v(e, t = {}) {
62
+ let n = y(t);
63
+ try {
64
+ return await n.check(e, t);
65
+ } finally {
66
+ n.dispose();
67
+ }
68
+ }
69
+ function y(e = {}) {
70
+ let t = Math.max(1, Math.floor(e.cacheLimit ?? p)), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set(), i = !1;
71
+ A();
72
+ function a() {
73
+ return e.measure ?? _ ?? N;
74
+ }
75
+ function o(e) {
76
+ let t = n.get(e);
77
+ return t && (n.delete(e), n.set(e, t)), t;
78
+ }
79
+ function s(e, r) {
80
+ for (n.delete(e), n.set(e, r); n.size > t;) {
81
+ let e = n.keys().next().value;
82
+ if (e === void 0) break;
83
+ n.delete(e);
84
+ }
85
+ }
86
+ async function c(e, t, n) {
87
+ let r = o(e.key);
88
+ if (r) return b(e, r);
89
+ let i = n?.(e.key);
90
+ if (i && C(i)) return s(e.key, i), b(e, i);
91
+ let c;
92
+ try {
93
+ c = await a()(e, t);
94
+ } catch (n) {
95
+ if (t.aborted) throw E();
96
+ return x(e, n);
97
+ }
98
+ return C(c) ? (s(e.key, c), b(e, c)) : x(e, new f("合同排版度量结果无效"));
99
+ }
100
+ return {
101
+ async check(e, t = {}) {
102
+ if (i) throw E();
103
+ let n = new AbortController();
104
+ r.add(n);
105
+ let a = t.signal, o = () => n.abort();
106
+ a?.aborted ? n.abort() : a?.addEventListener("abort", o, { once: !0 });
107
+ try {
108
+ let r = [];
109
+ for (let i of e) for (let e of g(i)) {
110
+ w(n.signal);
111
+ let i = await c(e, n.signal, t.reuse);
112
+ w(n.signal), i && r.push(i), t.onPage?.(e, i);
113
+ }
114
+ return r;
115
+ } finally {
116
+ r.delete(n), a?.removeEventListener("abort", o);
117
+ }
118
+ },
119
+ clear() {
120
+ n.clear();
121
+ },
122
+ dispose() {
123
+ i || (i = !0, r.forEach((e) => e.abort()), r.clear(), n.clear(), j());
124
+ }
125
+ };
126
+ }
127
+ function b(e, t) {
128
+ let n = t.overflowHeight > 1, r = t.overflowWidth > 1;
129
+ if (!(!n && !r)) return {
130
+ ...S(e),
131
+ kind: "overflow",
132
+ overflowHeight: n ? t.overflowHeight : 0,
133
+ overflowWidth: r ? t.overflowWidth : 0
134
+ };
135
+ }
136
+ function x(e, t) {
137
+ return {
138
+ ...S(e),
139
+ kind: "measure-failed",
140
+ overflowHeight: 0,
141
+ overflowWidth: 0,
142
+ error: t instanceof Error && t.message ? t.message : String(t || "合同排版度量失败")
143
+ };
144
+ }
145
+ function S(e) {
146
+ return {
147
+ ...e.fileId === void 0 ? {} : { fileId: e.fileId },
148
+ pageIndex: e.pageIndex,
149
+ pageNumber: e.pageNumber,
150
+ pageId: e.pageId
151
+ };
152
+ }
153
+ function C(e) {
154
+ return e ? Number.isFinite(e.overflowHeight) && Number.isFinite(e.overflowWidth) && e.overflowHeight >= 0 && e.overflowWidth >= 0 : !1;
155
+ }
156
+ function w(e) {
157
+ if (e.aborted) throw E();
158
+ }
159
+ function T(e) {
160
+ return !!(e && typeof e == "object" && e.name === "AbortError");
161
+ }
162
+ function E() {
163
+ if (typeof DOMException < "u") return new DOMException("合同排版校验已取消", "AbortError");
164
+ let e = /* @__PURE__ */ Error("合同排版校验已取消");
165
+ return e.name = "AbortError", e;
166
+ }
167
+ var D, O = 0, k = Promise.resolve();
168
+ function A() {
169
+ O += 1;
170
+ }
171
+ function j() {
172
+ O = Math.max(0, O - 1), O === 0 && (D?.remove(), D = void 0);
173
+ }
174
+ function M() {
175
+ if (D?.isConnected) return D;
176
+ let e = document.createElement("iframe");
177
+ return e.setAttribute("aria-hidden", "true"), e.setAttribute("tabindex", "-1"), e.setAttribute("title", "合同排版校验"), e.setAttribute("referrerpolicy", "no-referrer"), e.setAttribute("sandbox", "allow-scripts allow-same-origin"), e.style.cssText = "position:fixed;left:-100000px;top:0;border:0;pointer-events:none;", document.body.append(e), D = e, e;
178
+ }
179
+ function N(e, t) {
180
+ let n = k.then(() => P(e, t));
181
+ return k = n.catch(() => void 0), n;
182
+ }
183
+ function P(e, t) {
184
+ if (t?.aborted) return Promise.reject(E());
185
+ if (typeof window > "u" || typeof document > "u" || !document.body) return Promise.reject(new f("当前运行环境不是浏览器环境,无法执行合同排版校验"));
186
+ let s = M(), c = F(), l = r({
187
+ messageId: c,
188
+ parentOrigin: window.location.origin,
189
+ pageId: e.pageId,
190
+ pageFormat: e.pageFormat,
191
+ width: e.width,
192
+ height: e.height,
193
+ paddingTop: e.paddingTop,
194
+ paddingBottom: e.paddingBottom,
195
+ classNames: e.classNames,
196
+ decorationsHtml: e.decorationsHtml,
197
+ contentHtml: e.contentHtml
198
+ });
199
+ return new Promise((r, u) => {
200
+ let d, p = (e) => {
201
+ d !== void 0 && clearTimeout(d), o(h), t?.removeEventListener("abort", m), e();
202
+ }, m = () => p(() => u(E())), h = (e) => {
203
+ let t = e.data;
204
+ if (e.source !== s.contentWindow || e.origin !== window.location.origin || !i(t) || t.messageId !== c) return;
205
+ if (t.type === "error") {
206
+ p(() => u(new f(t.error || "合同排版度量校验失败")));
207
+ return;
208
+ }
209
+ let n = t.metrics;
210
+ n && p(() => r(n));
211
+ };
212
+ d = setTimeout(() => {
213
+ p(() => u(new f(`合同排版度量校验超时(${n}ms)`)));
214
+ }, n), a(h), t?.addEventListener("abort", m, { once: !0 }), s.style.width = `${e.width}px`, s.style.height = `${e.height}px`, s.srcdoc = l;
215
+ });
216
+ }
217
+ function F() {
218
+ return typeof crypto < "u" && "randomUUID" in crypto ? `gd-contract-print-${crypto.randomUUID()}` : `gd-contract-print-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
219
+ }
220
+ function I(e, t = "generate") {
221
+ let n = `第 ${e.pageNumber} 页`;
222
+ if (e.kind === "measure-failed") return [`${n}无法确认排版(${L(e.error)}),请稍后重试`];
223
+ let r = [];
224
+ if (e.overflowHeight > 1) {
225
+ let i = Math.ceil(e.overflowHeight);
226
+ r.push(t === "design" ? `${n}按打印样式超出 ${i} px,生成合同时将被拦截` : `${n}正文超出纸张 ${i} px,请调整模板后再生成合同`);
227
+ }
228
+ if (e.overflowWidth > 1) {
229
+ let i = Math.ceil(e.overflowWidth);
230
+ r.push(t === "design" ? `${n}按打印样式超出纸张宽度 ${i} px,生成合同时将被拦截` : `${n}正文超出纸张宽度 ${i} px,请调整模板后再生成合同`);
231
+ }
232
+ return r;
233
+ }
234
+ function L(e) {
235
+ let t = e ?? "";
236
+ return t.includes("超时") ? "排版校验超时" : t.includes("合同图片加载失败") ? "底图图片未能加载" : t.includes("浏览器环境") ? "当前环境无法执行排版校验" : "字体或排版度量未通过";
237
+ }
238
+ //#endregion
239
+ export { g as buildContractTemplateLayoutPages, v as checkContractTemplateLayout, y as createContractTemplateLayoutChecker, m as createContractTemplateLayoutPage, I as describeContractTemplateLayoutIssue, T as isContractTemplateLayoutAbortError };
@@ -1,83 +1,84 @@
1
- import { CONTRACT_PRINT_FONT_FAMILY as e, CONTRACT_PRINT_FONT_TIMEOUT_MS as t, CONTRACT_PRINT_METRIC_NORMALIZE_CSS as n, CONTRACT_PRINT_SANS_FONT_FAMILY as r, buildContractPrintCss as i } from "../../../../contract-print-css/index.mjs";
2
- import { shallowRef as a } from "vue";
1
+ import { CONTRACT_PRINT_FONT_FAMILY as e, CONTRACT_PRINT_FONT_TIMEOUT_MS as t, CONTRACT_PRINT_METRIC_NORMALIZE_CSS as n, CONTRACT_PRINT_SANS_FONT_FAMILY as r, buildContractPrintCss as i, measureContractPageLayout as a } from "../../../../contract-print-css/index.mjs";
2
+ import { shallowRef as o } from "vue";
3
3
  //#region src/components/pro-contract-template-designer/src/utils/contract-print-document.ts
4
- var o = "gd-contract-print", s = .5, c = "合同签署位置:甲方(Company A)编号 2026-08-31。", l = t + 1e3, u = /* @__PURE__ */ new Set();
5
- function d(e) {
6
- u.forEach((t) => t(e));
7
- }
4
+ var s = "gd-contract-print", c = .5, l = "合同签署位置:甲方(Company A)编号 2026-08-31。", u = t + 1e3, d = /* @__PURE__ */ new Set();
8
5
  function f(e) {
9
- u.size || window.addEventListener("message", d), u.add(e);
6
+ d.forEach((t) => t(e));
10
7
  }
11
8
  function p(e) {
12
- u.delete(e), u.size || window.removeEventListener("message", d);
9
+ d.size || window.addEventListener("message", f), d.add(e);
10
+ }
11
+ function m(e) {
12
+ d.delete(e), d.size || window.removeEventListener("message", f);
13
13
  }
14
- var m = "合同签署位置甲乙双方", h = ":,()。;", g = "20260831", _ = {
14
+ var h = "合同签署位置甲乙双方", g = ":,()。;", _ = "20260831", v = {
15
15
  textWidth: 379.546875,
16
16
  sansTextWidth: 393,
17
17
  variableRowHeight: 28
18
- }, v = "合同排版度量校验失败,禁止生成签署坐标", y = a("");
19
- function b(e) {
20
- y.value = (e?.baseUrl?.trim() ?? "").replace(/\/+$/, "");
18
+ }, y = "合同排版度量校验失败,禁止生成签署坐标", b = "合同图片加载失败", x = o("");
19
+ function S(e) {
20
+ x.value = (e?.baseUrl?.trim() ?? "").replace(/\/+$/, "");
21
21
  }
22
- function x(e) {
22
+ function C(e) {
23
23
  let t = e?.trim();
24
- return t ? t.replace(/\/+$/, "") : y.value.trim().replace(/\/+$/, "");
24
+ return t ? t.replace(/\/+$/, "") : x.value.trim().replace(/\/+$/, "");
25
25
  }
26
- function S(e, t = typeof window > "u" ? "" : window.location.origin) {
26
+ function w(e, t = typeof window > "u" ? "" : window.location.origin) {
27
27
  let n = e.trim().replace(/\/+$/, "");
28
28
  return n ? /^https?:\/\//i.test(n) ? n : t ? new URL(n.startsWith("/") ? n : `/${n}`, `${t.replace(/\/+$/, "")}/`).href.replace(/\/+$/, "") : n.startsWith("/") ? n : `/${n}` : "";
29
29
  }
30
- function C(a) {
31
- let l = `gd-contract-print-${a.messageId}`, u = i({
32
- width: a.width,
33
- height: a.height,
30
+ function T(o) {
31
+ let u = `gd-contract-print-${o.messageId}`, d = i({
32
+ width: o.width,
33
+ height: o.height,
34
34
  pages: [{
35
- id: a.pageId,
35
+ id: o.pageId,
36
36
  pageSize: {
37
- width: a.width,
38
- height: a.height
37
+ width: o.width,
38
+ height: o.height
39
39
  }
40
40
  }]
41
- }), d = JSON.stringify({
42
- messageId: a.messageId,
43
- parentOrigin: a.parentOrigin,
44
- pageId: a.pageId,
45
- pageHeight: a.height,
41
+ }), f = JSON.stringify({
42
+ messageId: o.messageId,
43
+ parentOrigin: o.parentOrigin,
44
+ pageId: o.pageId,
45
+ pageHeight: o.height,
46
46
  timeoutMs: t,
47
+ imageErrorMessage: b,
47
48
  fontFamily: e,
48
49
  sansFontFamily: r,
49
50
  latinFontFamily: "\"GD Contract Latin\", serif",
50
51
  metricNormalizeCss: n.replace(/\s+/g, " ").trim(),
51
- sample: c,
52
- hanziSample: m,
53
- punctSample: h,
54
- digitSample: g,
52
+ sample: l,
53
+ hanziSample: h,
54
+ punctSample: g,
55
+ digitSample: _,
55
56
  hanziAdvance: 16,
56
57
  punctAdvance: 16,
57
58
  digitAdvance: 8,
58
- baseline: _,
59
- tolerance: s
60
- }).replace(/</g, "\\u003c"), f = `width:${a.width}px;min-height:${a.height}px;padding-top:${a.paddingTop}px;padding-bottom:${a.paddingBottom}px`;
59
+ baseline: v,
60
+ tolerance: c
61
+ }).replace(/</g, "\\u003c"), p = `width:${o.width}px;min-height:${o.height}px;padding-top:${o.paddingTop}px;padding-bottom:${o.paddingBottom}px`;
61
62
  return `<!doctype html>
62
63
  <html lang="zh-CN">
63
64
  <head>
64
65
  <meta charset="utf-8">
65
66
  <meta name="color-scheme" content="light">
66
- <meta http-equiv="Content-Security-Policy" content="default-src 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; connect-src 'none'; frame-src 'none'; worker-src 'none'; img-src data: blob: http: https:; font-src data: blob: http: https:; style-src 'unsafe-inline'; script-src 'nonce-${T(l)}'">
67
+ <meta http-equiv="Content-Security-Policy" content="default-src 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; connect-src 'none'; frame-src 'none'; worker-src 'none'; img-src data: blob: http: https:; font-src data: blob: http: https:; style-src 'unsafe-inline'; script-src 'nonce-${D(u)}'">
67
68
  <style data-contract-render-style="true">
68
- ${w(u)}
69
+ ${E(d)}
69
70
  </style>
70
71
  </head>
71
72
  <body>
72
- <section class="${T(a.classNames)}" data-page-id="${T(a.pageId)}" data-page-format="${T(a.pageFormat ?? "Custom")}" data-page-width="${a.width}" data-page-height="${a.height}" style="${f}">
73
- ${a.decorationsHtml}
74
- <div class="gd-contract-template-page__content">${a.contentHtml}</div>
73
+ <section class="${D(o.classNames)}" data-page-id="${D(o.pageId)}" data-page-format="${D(o.pageFormat ?? "Custom")}" data-page-width="${o.width}" data-page-height="${o.height}" style="${p}">
74
+ ${o.decorationsHtml}
75
+ <div class="gd-contract-template-page__content">${o.contentHtml}</div>
75
76
  </section>
76
- <script nonce="${T(l)}">
77
+ <script nonce="${D(u)}">
77
78
  (() => {
78
79
  'use strict'
79
- const config = ${d}
80
- const namespace = ${JSON.stringify(o)}
80
+ const config = ${f}
81
+ const namespace = ${JSON.stringify(s)}
81
82
  const page = document.querySelector('.gd-contract-template-page')
82
83
  let ready = false
83
84
  let observer
@@ -149,6 +150,7 @@ ${a.decorationsHtml}
149
150
  if (message.command.scroll)
150
151
  firstMatch?.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' })
151
152
  })
153
+ const measureLayout = ${a.toString()}
152
154
  const measure = () => {
153
155
  if (!page)
154
156
  throw new Error('合同打印页节点不存在')
@@ -193,10 +195,7 @@ ${a.decorationsHtml}
193
195
  })
194
196
  : []
195
197
  const metrics = {
196
- pageWidth: page.offsetWidth,
197
- pageHeight: page.offsetHeight,
198
- contentHeight: page.scrollHeight,
199
- overflowHeight: Math.max(0, page.scrollHeight - config.pageHeight),
198
+ ...measureLayout(page, { width: ${o.width}, height: config.pageHeight }),
200
199
  paddingTop: Number.parseFloat(pageStyle.paddingTop),
201
200
  paddingBottom: Number.parseFloat(pageStyle.paddingBottom),
202
201
  paddingLeft: Number.parseFloat(pageStyle.paddingLeft),
@@ -236,13 +235,45 @@ ${a.decorationsHtml}
236
235
  throw new Error('合同排版度量不一致:' + key + ' expected=' + expected + ' actual=' + actual + ' tolerance=' + config.tolerance)
237
236
  }
238
237
  }
239
- const withTimeout = (promise) => Promise.race([
240
- promise,
241
- new Promise((_, reject) => setTimeout(() => reject(new Error('合同排版度量校验超时(' + config.timeoutMs + 'ms)')), config.timeoutMs)),
242
- ])
243
- const start = async () => {
238
+ const waitForAssets = async () => {
244
239
  if (document.fonts)
245
- await withTimeout(document.fonts.ready)
240
+ await document.fonts.ready
241
+ await Promise.all(Array.from(document.images).map(async image => {
242
+ image.loading = 'eager'
243
+ if (!image.complete)
244
+ await new Promise((resolve, reject) => {
245
+ image.addEventListener('load', resolve, { once: true })
246
+ image.addEventListener('error', () => reject(new Error(config.imageErrorMessage)), { once: true })
247
+ })
248
+ if (!image.naturalWidth)
249
+ throw new Error(config.imageErrorMessage)
250
+ if (image.decode)
251
+ await image.decode()
252
+ }))
253
+ }
254
+ // 字体与图片共用同一个截止时间,两段等待累计不超过 config.timeoutMs;父侧超时必须大于它。
255
+ const waitWithSharedDeadline = (promise) => {
256
+ let timer
257
+ const deadline = new Promise((_, reject) => {
258
+ timer = setTimeout(() => reject(new Error('合同排版度量校验超时(' + config.timeoutMs + 'ms)')), config.timeoutMs)
259
+ })
260
+ return Promise.race([promise, deadline]).finally(() => clearTimeout(timer))
261
+ }
262
+ // 布局度量异常必须经 error 消息回到父页,不能在 ResizeObserver 或 fonts 事件里变成未捕获异常。
263
+ const reportMetrics = () => {
264
+ if (!ready)
265
+ return
266
+ try {
267
+ post('metrics', { metrics: measure() })
268
+ }
269
+ catch (error) {
270
+ ready = false
271
+ observer?.disconnect()
272
+ post('error', { error: error instanceof Error ? error.message : String(error) })
273
+ }
274
+ }
275
+ const start = async () => {
276
+ await waitWithSharedDeadline(waitForAssets())
246
277
  const metrics = measure()
247
278
  try {
248
279
  assertMetrics(metrics)
@@ -253,19 +284,11 @@ ${a.decorationsHtml}
253
284
  }
254
285
  ready = true
255
286
  post('ready', { metrics })
256
- observer = new ResizeObserver(() => {
257
- if (!ready)
258
- return
259
- try {
260
- post('metrics', { metrics: measure() })
261
- }
262
- catch (error) {
263
- ready = false
264
- observer?.disconnect()
265
- post('error', { error: error instanceof Error ? error.message : String(error) })
266
- }
267
- })
287
+ observer = new ResizeObserver(reportMetrics)
268
288
  observer.observe(page)
289
+ const content = page.querySelector('.gd-contract-template-page__content')
290
+ if (content) observer.observe(content)
291
+ document.fonts?.addEventListener('loadingdone', reportMetrics)
269
292
  }
270
293
  start().catch((error) => {
271
294
  post('error', { error: error instanceof Error ? error.message : String(error) })
@@ -276,23 +299,23 @@ ${a.decorationsHtml}
276
299
  </body>
277
300
  </html>`;
278
301
  }
279
- function w(e) {
302
+ function E(e) {
280
303
  return e.replace(/<\/style/gi, "<\\/style");
281
304
  }
282
- function T(e) {
305
+ function D(e) {
283
306
  return String(e).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
284
307
  }
285
- function E(e) {
308
+ function O(e) {
286
309
  if (!e || typeof e != "object") return !1;
287
310
  let t = e;
288
- return t.namespace === "gd-contract-print" && typeof t.messageId == "string" && /^gd-contract-print-[A-Za-z0-9-]{8,160}$/.test(t.messageId) && (t.type === "ready" || t.type === "metrics" || t.type === "error" || t.type === "interaction") ? t.type === "error" ? typeof t.error == "string" && t.error.length <= 2e3 : t.type === "interaction" ? D(t.interaction) : O(t.metrics) : !1;
311
+ return t.namespace === "gd-contract-print" && typeof t.messageId == "string" && /^gd-contract-print-[A-Za-z0-9-]{8,160}$/.test(t.messageId) && (t.type === "ready" || t.type === "metrics" || t.type === "error" || t.type === "interaction") ? t.type === "error" ? typeof t.error == "string" && t.error.length <= 2e3 : t.type === "interaction" ? k(t.interaction) : A(t.metrics) : !1;
289
312
  }
290
- function D(e) {
313
+ function k(e) {
291
314
  if (!e || typeof e != "object") return !1;
292
315
  let t = e;
293
316
  return typeof t.key != "string" || !/^[A-Za-z][A-Za-z0-9_]{1,63}$/.test(t.key) || typeof t.pageId != "string" || !t.pageId || t.pageId.length > 256 ? !1 : t.kind === "select" ? !0 : t.kind === "input" && (t.value === void 0 || typeof t.value == "string" && t.value.length <= 1e6 || typeof t.value == "number" && Number.isFinite(t.value) || typeof t.value == "boolean");
294
317
  }
295
- function O(e) {
318
+ function A(e) {
296
319
  if (!e || typeof e != "object") return !1;
297
320
  let t = e;
298
321
  if (![
@@ -300,6 +323,7 @@ function O(e) {
300
323
  "pageHeight",
301
324
  "contentHeight",
302
325
  "overflowHeight",
326
+ "overflowWidth",
303
327
  "paddingTop",
304
328
  "paddingBottom",
305
329
  "paddingLeft",
@@ -317,4 +341,4 @@ function O(e) {
317
341
  return n.length > 1e3 || !n.every((e) => Number.isFinite(e) && e >= -1e7 && e <= 1e7) || !Array.isArray(t.blocks) || t.blocks.length > 1e4 ? !1 : t.blocks.every((e) => !!e && typeof e.text == "string" && e.text.length <= 1e3 && Number.isFinite(e.top) && Math.abs(e.top) <= 1e7 && Number.isFinite(e.lineCount) && e.lineCount >= 0 && e.lineCount <= 1e6);
318
342
  }
319
343
  //#endregion
320
- export { v as CONTRACT_PRINT_FONT_UNCONFIGURED_MESSAGE, l as CONTRACT_PRINT_FRAME_TIMEOUT_MS, o as CONTRACT_PRINT_MESSAGE_NAMESPACE, C as buildContractPrintDocument, b as configureContractPrintFonts, E as isContractPrintFrameMessage, x as resolveContractFontBaseUrl, f as subscribeContractPrintFrameMessages, S as toAbsoluteContractFontBaseUrl, p as unsubscribeContractPrintFrameMessages };
344
+ export { y as CONTRACT_PRINT_FONT_UNCONFIGURED_MESSAGE, u as CONTRACT_PRINT_FRAME_TIMEOUT_MS, b as CONTRACT_PRINT_IMAGE_ERROR_MESSAGE, s as CONTRACT_PRINT_MESSAGE_NAMESPACE, T as buildContractPrintDocument, S as configureContractPrintFonts, O as isContractPrintFrameMessage, C as resolveContractFontBaseUrl, p as subscribeContractPrintFrameMessages, w as toAbsoluteContractFontBaseUrl, m as unsubscribeContractPrintFrameMessages };