12 小时以前 35722562e9e13f0504acc15b740d042ecb810199
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
 * 画布内容与渲染产物都走 HTML 字符串,任何来自用户(设计器属性面板)的文本
 * 都必须先转义再拼进标签,否则在渲染期会变成注入点。
 */
export function escapeHtml(value: unknown): string {
  return String(value ?? '')
    .replaceAll('&', '&')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#39;');
}
 
/**
 * 转义之后再把换行折成 <br>。
 * <p>
 * 页脚落款、多行文本常在一个属性里塞多行(AI 导入会把原件页脚与签署行合并成一段),
 * 只转义的话换行符会被 HTML 的空白折叠吃掉,几行内容连成一整片。
 */
export function escapeHtmlMultiline(value: unknown): string {
  return escapeHtml(value).replace(/\r\n?|\n/g, '<br>');
}
 
/** 拼一段内联样式,过滤掉空值 */
export function cssStyle(style: Record<string, number | string | undefined>): string {
  return Object.entries(style)
    .filter(([, value]) => value !== undefined && value !== '')
    .map(([key, value]) => `${key}:${value}`)
    .join(';');
}