@pixui-dev/pixui-richtext-helper 0.1.1-beta.1 → 0.1.1-beta.3

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.
@@ -0,0 +1,22 @@
1
+ import { RichText_Refactor, LinkNodeType, LinkClickParams } from "./richtext/RichText_Refactor";
2
+ /**
3
+ * 对外暴露的 RichText 组件。
4
+ * 保持旧版使用方式不变,内部委托给 RichText_Refactor 实现。
5
+ */
6
+ export declare const RichText: {
7
+ /** 链接节点类型枚举 */
8
+ LinkNodeType: typeof LinkNodeType;
9
+ /**
10
+ * 将富文本转换为 PixUI innerHTML 兼容格式
11
+ * @see RichText_Refactor.convertRichTextToPixuiStyle
12
+ */
13
+ convertRichTextToPixuiStyle: typeof RichText_Refactor.convertRichTextToPixuiStyle;
14
+ /**
15
+ * 绑定富文本中的链接点击事件
16
+ * @see RichText_Refactor.bindLinkClickEvents
17
+ */
18
+ bindLinkClickEvents: typeof RichText_Refactor.bindLinkClickEvents;
19
+ };
20
+ export type { LinkClickParams };
21
+ export { LinkNodeType };
22
+ export default RichText;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LinkNodeType = exports.RichText = void 0;
4
+ var RichText_Refactor_1 = require("./richtext/RichText_Refactor");
5
+ Object.defineProperty(exports, "LinkNodeType", { enumerable: true, get: function () { return RichText_Refactor_1.LinkNodeType; } });
6
+ /**
7
+ * 对外暴露的 RichText 组件。
8
+ * 保持旧版使用方式不变,内部委托给 RichText_Refactor 实现。
9
+ */
10
+ exports.RichText = {
11
+ /** 链接节点类型枚举 */
12
+ LinkNodeType: RichText_Refactor_1.LinkNodeType,
13
+ /**
14
+ * 将富文本转换为 PixUI innerHTML 兼容格式
15
+ * @see RichText_Refactor.convertRichTextToPixuiStyle
16
+ */
17
+ convertRichTextToPixuiStyle: RichText_Refactor_1.RichText_Refactor.convertRichTextToPixuiStyle,
18
+ /**
19
+ * 绑定富文本中的链接点击事件
20
+ * @see RichText_Refactor.bindLinkClickEvents
21
+ */
22
+ bindLinkClickEvents: RichText_Refactor_1.RichText_Refactor.bindLinkClickEvents,
23
+ };
24
+ exports.default = exports.RichText;
@@ -1,3 +1,9 @@
1
+ /**
2
+ * pixui富文本转换工具
3
+ * 将管理端下发的富文本转换成pixui的innerHtml可以使用的格式,被转换的富文本只应该包括文本和图片及相关的样式。
4
+ * 将富文本内容转换为:
5
+ * 段落div/h节点(不带样式,用来形成一个段落) -> text(只带text节点样式,pixui的段落需要在text节点下才能表现正常)-> <div>(带有文本的样式) 文本1 </div> <div>(带有文本的样式) 文本2 </div> <img>(带有图片的样式) 图片1 </img> <div>(带有文本的样式) 文本3 </div> (每个子div带有这一小段文本/图片的样式,这一段所有text节点下的div/img会被text节点正确的换行排列)
6
+ */
1
7
  export declare namespace RichText {
2
8
  /**
3
9
  * 富文本中的超链接节点类型
@@ -22,12 +28,10 @@ export declare namespace RichText {
22
28
  * @param str 管理端下发的富文本
23
29
  * @param config 配置
24
30
  * @param config.lineHeightScale 行高缩放
25
- * @param config.isToRem 是否将节点的 px 单位转换为 rem 的单位
26
31
  * @returns pixui的innerHtml可以使用的格式
27
32
  */
28
33
  const convertRichTextToPixuiStyle: (str: string, config?: {
29
34
  lineHeightScale?: number;
30
- isToRem?: boolean;
31
35
  }) => string;
32
36
  /**
33
37
  * 为富文本中的链接节点绑定点击事件
@@ -32,9 +32,24 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
36
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
37
+ if (ar || !(i in from)) {
38
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
39
+ ar[i] = from[i];
40
+ }
41
+ }
42
+ return to.concat(ar || Array.prototype.slice.call(from));
43
+ };
35
44
  Object.defineProperty(exports, "__esModule", { value: true });
36
45
  exports.RichText = void 0;
37
46
  var cheerio = __importStar(require("cheerio"));
47
+ /**
48
+ * pixui富文本转换工具
49
+ * 将管理端下发的富文本转换成pixui的innerHtml可以使用的格式,被转换的富文本只应该包括文本和图片及相关的样式。
50
+ * 将富文本内容转换为:
51
+ * 段落div/h节点(不带样式,用来形成一个段落) -> text(只带text节点样式,pixui的段落需要在text节点下才能表现正常)-> <div>(带有文本的样式) 文本1 </div> <div>(带有文本的样式) 文本2 </div> <img>(带有图片的样式) 图片1 </img> <div>(带有文本的样式) 文本3 </div> (每个子div带有这一小段文本/图片的样式,这一段所有text节点下的div/img会被text节点正确的换行排列)
52
+ */
38
53
  var RichText;
39
54
  (function (RichText) {
40
55
  /**
@@ -47,12 +62,26 @@ var RichText;
47
62
  })(LinkNodeType = RichText.LinkNodeType || (RichText.LinkNodeType = {}));
48
63
  // 存储需要绑定点击事件的节点信息
49
64
  var linkNodes = [];
65
+ // 添加工具函数来正确处理CSS样式拼接
66
+ var mergeStyles = function () {
67
+ var styles = [];
68
+ for (var _i = 0; _i < arguments.length; _i++) {
69
+ styles[_i] = arguments[_i];
70
+ }
71
+ return styles
72
+ .filter(function (style) { return style && style.trim(); })
73
+ .map(function (style) {
74
+ var trimmed = style.trim();
75
+ return trimmed.endsWith(";") ? trimmed : trimmed + ";";
76
+ })
77
+ .join(" ")
78
+ .replace(/\s*;\s*$/, ";"); // 确保最后只有一个分号
79
+ };
50
80
  /**
51
81
  * 富文本组件,将富文本转换成pixui的innerHtml可以使用的格式
52
82
  * @param str 管理端下发的富文本
53
83
  * @param config 配置
54
84
  * @param config.lineHeightScale 行高缩放
55
- * @param config.isToRem 是否将节点的 px 单位转换为 rem 的单位
56
85
  * @returns pixui的innerHtml可以使用的格式
57
86
  */
58
87
  RichText.convertRichTextToPixuiStyle = function (str, config) {
@@ -64,10 +93,10 @@ var RichText;
64
93
  {
65
94
  var _loop_1 = function (i) {
66
95
  var indent = "ql-indent-".concat(i);
67
- var extStyle = "padding-left: ".concat(i * 2, "rem;");
96
+ var extStyle = "padding-left: ".concat(i * 2, "rem");
68
97
  $(".".concat(indent)).each(function () {
69
98
  var oriStyle = $(this).attr("style") || "";
70
- $(this).attr("style", "".concat(oriStyle, " ").concat(extStyle));
99
+ $(this).attr("style", mergeStyles(oriStyle, extStyle));
71
100
  $(this).removeClass(indent);
72
101
  });
73
102
  };
@@ -86,26 +115,6 @@ var RichText;
86
115
  $(this).attr("height", "".concat(height, "px"));
87
116
  }
88
117
  });
89
- // 将px转换为rem,font-size不转换
90
- if (config === null || config === void 0 ? void 0 : config.isToRem) {
91
- $("*").each(function () {
92
- var $element = $(this);
93
- var style = $element.attr("style");
94
- if (style) {
95
- var newStyle = style.replace(/([\w-]+)\s*:\s*([^;]+)/g, function (match, property, value) {
96
- if (property.trim() !== "font-size" && property.trim() !== "letter-spacing") {
97
- var newValue = value.replace(/(\d+(?:\.\d+)?)px/g, function (pxMatch, pxValue) {
98
- var remValue = parseFloat(pxValue) / 100;
99
- return "".concat(remValue, "rem");
100
- });
101
- return "".concat(property, ": ").concat(newValue);
102
- }
103
- return match;
104
- });
105
- $element.attr("style", newStyle);
106
- }
107
- });
108
- }
109
118
  // 处理列表项
110
119
  {
111
120
  /**
@@ -183,10 +192,10 @@ var RichText;
183
192
  // 为该列表生成HTML
184
193
  var listHtml = items
185
194
  .map(function (item) {
186
- return ("<div style=\"".concat(item.style, " padding-left: ").concat(item.paddingLeft, "rem; flex-shrink: 0; width: 100%; flex-direction: row; display: flex;\" data-list-item=\"true\">") +
187
- "<text style=\"flex-shrink: 0; width: 100%; line-height: 1; display: flex; flex-direction: row;\">" +
188
- "<div style=\"word-break: break-word; flex-shrink: 0; margin-right: 0.5rem;\">".concat(item.marker, "</div>") +
189
- "<div style=\"word-break: break-word; flex-shrink: 0; flex: 1;\">".concat(item.textContent, "</div>") +
195
+ return ("<div style=\"".concat(mergeStyles(item.style, "padding-left: ".concat(item.paddingLeft, "rem"), "flex-shrink: 0", "width: 100%", "flex-direction: row", "display: flex"), "\" data-list-item=\"true\">") +
196
+ "<text style=\"".concat(mergeStyles("flex-shrink: 0", "width: 100%", "line-height: 1", "display: flex", "flex-direction: row"), "\">") +
197
+ "<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "margin-right: 0.5rem"), "\">").concat(item.marker, "</div>") +
198
+ "<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "flex: 1"), "\">").concat(item.textContent, "</div>") +
190
199
  "</text>" +
191
200
  "</div>");
192
201
  })
@@ -199,7 +208,7 @@ var RichText;
199
208
  }
200
209
  //pixui连续的br不生效,用透明文字占位
201
210
  $("br").each(function () {
202
- $(this).replaceWith("<span style='color: transparent; flex-shrink: 0;font-size: 20px;' class='pixui-richtext-br-placeholder'>1</span>");
211
+ $(this).replaceWith("<span style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 20px"), "\" class='pixui-richtext-br-placeholder'>1</span>"));
203
212
  });
204
213
  //将 a 标签替换为简单div,处理 href,预处理内部样式标签并合并样式
205
214
  $("a").each(function (i, ele) {
@@ -233,7 +242,7 @@ var RichText;
233
242
  // 合并所有样式
234
243
  var finalStyle = originalStyle;
235
244
  if (mergedStyles.length > 0) {
236
- finalStyle = finalStyle ? "".concat(finalStyle, "; ").concat(mergedStyles.join("; ")) : mergedStyles.join("; ");
245
+ finalStyle = mergeStyles.apply(void 0, __spreadArray([originalStyle], mergedStyles, false));
237
246
  }
238
247
  if (href) {
239
248
  linkNodes.push({
@@ -243,7 +252,7 @@ var RichText;
243
252
  });
244
253
  }
245
254
  // 转换为简单div,样式已合并
246
- $(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\">").concat(textContent, "</div>"));
255
+ $(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\" class=\"PA_RichTextHref_ATag\" >").concat(textContent, "</div>"));
247
256
  });
248
257
  //找到所有的文字节点,外层包裹text标签
249
258
  $("*").each(function () {
@@ -273,7 +282,7 @@ var RichText;
273
282
  if (this.type === "text") {
274
283
  var text = this.data.trim();
275
284
  if (text.length > 0) {
276
- $(this).replaceWith("<text style=\"word-break: break-word;flex-shrink: 0;flex-direction: row;\">".concat(text, "</text>"));
285
+ $(this).replaceWith("<text style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "flex-direction: row"), "\">").concat(text, "</text>"));
277
286
  }
278
287
  }
279
288
  });
@@ -282,33 +291,33 @@ var RichText;
282
291
  $("strong").each(function () {
283
292
  var html = $(this).html();
284
293
  var style = $(this).attr("style") || "";
285
- $(this).replaceWith("<text style=\"".concat(style, " font-weight: bold;flex-shrink: 0;\">").concat(html, "</text>"));
294
+ $(this).replaceWith("<text style=\"".concat(mergeStyles(style, "font-weight: bold", "flex-shrink: 0"), "\">").concat(html, "</text>"));
286
295
  });
287
296
  $("em").each(function () {
288
297
  var html = $(this).html();
289
298
  var style = $(this).attr("style") || "";
290
- $(this).replaceWith("<text style=\"".concat(style, " font-style: italic;flex-shrink: 0;\">").concat(html, "</text>"));
299
+ $(this).replaceWith("<text style=\"".concat(mergeStyles(style, "font-style: italic", "flex-shrink: 0"), "\">").concat(html, "</text>"));
291
300
  });
292
301
  $("u").each(function () {
293
302
  var html = $(this).html();
294
303
  var style = $(this).attr("style") || "";
295
- $(this).replaceWith("<text style=\"".concat(style, " text-decoration: underline;flex-shrink: 0;\">").concat(html, "</text>"));
304
+ $(this).replaceWith("<text style=\"".concat(mergeStyles(style, "text-decoration: underline", "flex-shrink: 0"), "\">").concat(html, "</text>"));
296
305
  });
297
306
  $("s").each(function () {
298
307
  var html = $(this).html();
299
308
  var style = $(this).attr("style") || "";
300
- $(this).replaceWith("<text style=\"".concat(style, " text-decoration: line-through;flex-shrink: 0;\">").concat(html, "</text>"));
309
+ $(this).replaceWith("<text style=\"".concat(mergeStyles(style, "text-decoration: line-through", "flex-shrink: 0"), "\">").concat(html, "</text>"));
301
310
  });
302
311
  $("span").each(function () {
303
312
  var html = $(this).html();
304
313
  var style = $(this).attr("style") || "";
305
- $(this).replaceWith("<text style=\"".concat(style, " flex-shrink: 0;\">").concat(html, "</text>"));
314
+ $(this).replaceWith("<text style=\"".concat(mergeStyles(style, "flex-shrink: 0"), "\">").concat(html, "</text>"));
306
315
  });
307
316
  //p换成div
308
317
  $("p").each(function () {
309
318
  var html = $(this).html();
310
319
  var style = $(this).attr("style") || "";
311
- $(this).replaceWith("<div style=\"".concat(style, " ;flex-shrink: 0;width:100%;\">").concat(html, "</div>"));
320
+ $(this).replaceWith("<div style=\"".concat(mergeStyles(style, "flex-shrink: 0", "width:100%"), "\">").concat(html, "</div>"));
312
321
  });
313
322
  //处理 img 上的 href
314
323
  $("img").each(function (i, ele) {
@@ -323,6 +332,8 @@ var RichText;
323
332
  });
324
333
  }
325
334
  $(this).attr("href", "");
335
+ $(this).attr("class", "PA_RichTextHref_ImgTag");
336
+ $(this).attr("data-href", href);
326
337
  });
327
338
  //补充 flex-shrink: 0
328
339
  ["h1", "h2", "h3", "h4", "h5", "h6", "a", "img", "div"].forEach(function (tag) {
@@ -332,7 +343,7 @@ var RichText;
332
343
  var inListItem = $(this).closest("[data-list-item='true']").length > 0;
333
344
  if (!isListItem && !inListItem) {
334
345
  var style = $(this).attr("style") || "";
335
- $(this).attr("style", "".concat(style, " flex-shrink: 0;"));
346
+ $(this).attr("style", mergeStyles(style, "flex-shrink: 0"));
336
347
  }
337
348
  });
338
349
  });
@@ -348,7 +359,7 @@ var RichText;
348
359
  var $child = $(this);
349
360
  var childStyle = $child.attr("style") || "";
350
361
  // 合并style属性,将父节点的style附加到子节点上
351
- var mergedStyle = "".concat(parentStyle, "; ").concat(childStyle);
362
+ var mergedStyle = mergeStyles(parentStyle, childStyle);
352
363
  // 更新子元素的style属性
353
364
  $child.attr("style", mergedStyle);
354
365
  });
@@ -387,7 +398,7 @@ var RichText;
387
398
  }
388
399
  var text = $(this).html();
389
400
  var style = $(this).attr("style") || "";
390
- $(this).replaceWith("<div style=\"".concat(style, "\">").concat(text, "</div>"));
401
+ $(this).replaceWith("<div style=\"".concat(mergeStyles(style, "word-break: break-word", "flex-shrink: 0", "flex-direction: row"), "\">").concat(text, "</div>"));
391
402
  });
392
403
  var taghtml = $(node).html() || "";
393
404
  var tagstyle = $(node).attr("style") || "";
@@ -404,7 +415,7 @@ var RichText;
404
415
  }
405
416
  }
406
417
  //自己的子节点外套一个text,自己不变
407
- $(node).replaceWith("<".concat(tag, " style=\"").concat(tagstyle, ";flex-direction: row;\"").concat(idAttr).concat(customAttrs, "><text style=\"flex-shrink: 0;width: 100%;\">").concat(taghtml, "</text></").concat(tag, ">"));
418
+ $(node).replaceWith("<".concat(tag, " style=\"").concat(mergeStyles(tagstyle, "flex-direction: row"), "\"").concat(idAttr).concat(customAttrs, "><text style=\"").concat(mergeStyles("flex-shrink: 0", "width: 100%"), "\">").concat(taghtml, "</text></").concat(tag, ">"));
408
419
  }
409
420
  });
410
421
  //text-indent 处理首行缩进
@@ -416,7 +427,7 @@ var RichText;
416
427
  * 状态为<div style=text-indent:xxx><text><透明字符节点/><div style=样式>文字</div></text></div>
417
428
  * 属性是几 em 就加几个字符
418
429
  * */
419
- var $spacerText = $("<div style=\"color: transparent; flex-shrink: 0;\">".concat("一".repeat(parseInt(textIndent)), "</div>"));
430
+ var $spacerText = $("<div style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 16px"), "\">").concat("一".repeat(parseInt(textIndent)), "</div>"));
420
431
  // 寻找子节点中的text节点
421
432
  var textChild = $(this).children("text").first();
422
433
  if (textChild.length > 0) {
@@ -486,7 +497,7 @@ var RichText;
486
497
  var style = $(this).attr("style") || "";
487
498
  //如果没有fontsize
488
499
  if (!style.includes("font-size")) {
489
- $(this).attr("style", "".concat(style, " font-size:").concat(hTagRem_1[idx]));
500
+ $(this).attr("style", mergeStyles(style, "font-size:".concat(hTagRem_1[idx])));
490
501
  }
491
502
  });
492
503
  });
@@ -494,7 +505,7 @@ var RichText;
494
505
  //手动替换nbsp
495
506
  var res = $.html();
496
507
  res = res.replaceAll(/<img([^>]+)>/g, "<img$1 />").replaceAll(/&nbsp;/g, " ");
497
- // console.log(res);
508
+ console.log(res);
498
509
  return res;
499
510
  }
500
511
  };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { RichText } from "./RichTextUtils";
2
- export { RichText as default } from "./RichTextUtils";
1
+ export { RichText } from "./RichText";
2
+ export { RichText as default } from "./RichText";
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = exports.RichText = void 0;
4
- var RichTextUtils_1 = require("./RichTextUtils");
5
- Object.defineProperty(exports, "RichText", { enumerable: true, get: function () { return RichTextUtils_1.RichText; } });
6
- var RichTextUtils_2 = require("./RichTextUtils");
7
- Object.defineProperty(exports, "default", { enumerable: true, get: function () { return RichTextUtils_2.RichText; } });
4
+ var RichText_1 = require("./RichText");
5
+ Object.defineProperty(exports, "RichText", { enumerable: true, get: function () { return RichText_1.RichText; } });
6
+ var RichText_2 = require("./RichText");
7
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return RichText_2.RichText; } });
@@ -0,0 +1,77 @@
1
+ /*****************************************************
2
+ * 类型、枚举定义
3
+ *****************************************************/
4
+ /** 链接节点的类型 */
5
+ export declare enum LinkNodeType {
6
+ IMG = "img",
7
+ DIV = "div"
8
+ }
9
+ /** 点击回调参数 */
10
+ export interface LinkClickParams {
11
+ type: LinkNodeType;
12
+ href: string;
13
+ id: string;
14
+ }
15
+ /*****************************************************
16
+ * RichText_Refactor 主类
17
+ *****************************************************/
18
+ export declare class RichText_Refactor {
19
+ private static linkNodes;
20
+ private static hrefIdCnt;
21
+ /**
22
+ * 富文本转换为 PixUI innerHTML 兼容格式
23
+ * @param str 原始富文本 HTML
24
+ * @param config 可选配置
25
+ */
26
+ static convertRichTextToPixuiStyle(str: string, config?: {
27
+ lineHeightScale?: number;
28
+ }): string;
29
+ /**
30
+ * 绑定链接点击事件
31
+ */
32
+ static bindLinkClickEvents(linkClickHandler: (params: LinkClickParams) => void): void;
33
+ /*****************************************************
34
+ * 内部流程函数
35
+ *****************************************************/
36
+ /**
37
+ * 将 HTML 切分为基础段落片段。
38
+ * 简易实现:以顶级节点为粒度切分,再根据最外层列表节点进行分割。
39
+ */
40
+ private static splitIntoSegments;
41
+ /**
42
+ * 处理单个段落片段,返回转换后的片段 HTML
43
+ */
44
+ private static processSegment;
45
+ private static handleIndentClass;
46
+ private static fixImgSizeUnit;
47
+ /** 列表处理(将 ol/ul/li 替换为 div 结构) */
48
+ private static handleLists;
49
+ /** 将连续 <br> 替换为透明占位文字,确保 PixUI 换行 */
50
+ private static replaceBrWithPlaceholder;
51
+ /** 处理 <a> 标签:转为 div、保留样式、记录链接 */
52
+ private static handleAnchorTag;
53
+ /** 用 text 标签包裹纯文本节点 */
54
+ private static wrapTextNodes;
55
+ /** strong / em / u / s / span 等标签替换成 text */
56
+ private static replaceStyleTags;
57
+ /** p → div */
58
+ private static replacePTag;
59
+ /** img 的 href 转移处理 & 记录链接 */
60
+ private static handleImgHref;
61
+ /** 给指定标签补 flex-shrink:0 */
62
+ private static addFlexShrink;
63
+ /** 把嵌套的 text 展平 */
64
+ private static flattenNestedText;
65
+ /** 将同一行的 text 节点转为 div 并外包一层 text */
66
+ private static convertSiblingTextToDiv;
67
+ /** text-indent 首行缩进处理 */
68
+ private static handleTextIndent;
69
+ /** line-height / letter-spacing 调整 */
70
+ private static adjustLineHeightAndLetterSpacing;
71
+ /** 把 div 的 text-align 转移到子 text 上 */
72
+ private static transferTextAlign;
73
+ /** 删除空 text 节点 */
74
+ private static removeEmptyText;
75
+ /** 补默认 heading 字体大小 */
76
+ private static fixHeadingFontSize;
77
+ }
@@ -0,0 +1,637 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
36
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
37
+ if (ar || !(i in from)) {
38
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
39
+ ar[i] = from[i];
40
+ }
41
+ }
42
+ return to.concat(ar || Array.prototype.slice.call(from));
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.RichText_Refactor = exports.LinkNodeType = void 0;
46
+ var cheerio = __importStar(require("cheerio"));
47
+ /*****************************************************
48
+ * 类型、枚举定义
49
+ *****************************************************/
50
+ /** 链接节点的类型 */
51
+ var LinkNodeType;
52
+ (function (LinkNodeType) {
53
+ LinkNodeType["IMG"] = "img";
54
+ LinkNodeType["DIV"] = "div";
55
+ })(LinkNodeType || (exports.LinkNodeType = LinkNodeType = {}));
56
+ /*****************************************************
57
+ * 工具函数
58
+ *****************************************************/
59
+ /**
60
+ * 解析 style 字符串为对象
61
+ */
62
+ var parseStyleString = function (styleStr) {
63
+ var result = {};
64
+ if (!styleStr || !styleStr.trim())
65
+ return result;
66
+ // 分割多个样式声明
67
+ var declarations = styleStr.split(";").filter(function (decl) { return decl.trim(); });
68
+ declarations.forEach(function (decl) {
69
+ var colonIndex = decl.indexOf(":");
70
+ if (colonIndex > 0) {
71
+ var property = decl.substring(0, colonIndex).trim();
72
+ var value = decl.substring(colonIndex + 1).trim();
73
+ if (property && value) {
74
+ result[property] = value;
75
+ }
76
+ }
77
+ });
78
+ return result;
79
+ };
80
+ /**
81
+ * 将样式对象序列化为字符串
82
+ */
83
+ var serializeStyleObject = function (styleObj) {
84
+ return (Object.entries(styleObj)
85
+ .map(function (_a) {
86
+ var property = _a[0], value = _a[1];
87
+ return "".concat(property, ": ").concat(value);
88
+ })
89
+ .join("; ") + (Object.keys(styleObj).length > 0 ? ";" : ""));
90
+ };
91
+ /**
92
+ * 合并多个 style 字符串,自动处理分号与空格,后合并的覆盖前面的(符合CSS优先级规则)
93
+ */
94
+ var mergeStyles = function () {
95
+ var styles = [];
96
+ for (var _i = 0; _i < arguments.length; _i++) {
97
+ styles[_i] = arguments[_i];
98
+ }
99
+ var mergedStyleObj = {};
100
+ // 过滤空值并解析每个样式字符串
101
+ var validStyles = styles.filter(function (s) { return !!s && s.trim().length > 0; });
102
+ // 按顺序合并,后面的覆盖前面的
103
+ validStyles.forEach(function (styleStr) {
104
+ var styleObj = parseStyleString(styleStr);
105
+ Object.assign(mergedStyleObj, styleObj);
106
+ });
107
+ return serializeStyleObject(mergedStyleObj);
108
+ };
109
+ /*****************************************************
110
+ * RichText_Refactor 主类
111
+ *****************************************************/
112
+ var RichText_Refactor = /** @class */ (function () {
113
+ function RichText_Refactor() {
114
+ }
115
+ /**
116
+ * 富文本转换为 PixUI innerHTML 兼容格式
117
+ * @param str 原始富文本 HTML
118
+ * @param config 可选配置
119
+ */
120
+ RichText_Refactor.convertRichTextToPixuiStyle = function (str, config) {
121
+ // 重置全局状态
122
+ RichText_Refactor.linkNodes = [];
123
+ RichText_Refactor.hrefIdCnt = 0;
124
+ // ---------- 第 1 步:段落分割(基础实现:根节点切分) ----------
125
+ var segments = RichText_Refactor.splitIntoSegments(str);
126
+ // ---------- 第 2/3 步:遍历 + 展平 ----------
127
+ // 为保证兼容性,我们直接对 HTML 进行逐段处理并在内部构建 PixUI 结构。
128
+ // 这样既保持分段概念,又可复用旧逻辑的稳定性。
129
+ var processedSegments = segments.map(function (seg) { return RichText_Refactor.processSegment(seg, config); });
130
+ // ---------- 第 4 步:拼装 ----------
131
+ var Result = processedSegments.join("");
132
+ console.log(Result);
133
+ return Result;
134
+ };
135
+ /**
136
+ * 绑定链接点击事件
137
+ */
138
+ RichText_Refactor.bindLinkClickEvents = function (linkClickHandler) {
139
+ RichText_Refactor.linkNodes.forEach(function (nodeInfo) {
140
+ var element = document.getElementById(nodeInfo.id);
141
+ if (element) {
142
+ element.onclick = function (e) {
143
+ e.stopPropagation();
144
+ e.preventDefault();
145
+ linkClickHandler({
146
+ type: nodeInfo.type,
147
+ href: nodeInfo.href,
148
+ id: nodeInfo.id,
149
+ });
150
+ return false;
151
+ };
152
+ }
153
+ });
154
+ };
155
+ /*****************************************************
156
+ * 内部流程函数
157
+ *****************************************************/
158
+ /**
159
+ * 将 HTML 切分为基础段落片段。
160
+ * 简易实现:以顶级节点为粒度切分,再根据最外层列表节点进行分割。
161
+ */
162
+ RichText_Refactor.splitIntoSegments = function (html) {
163
+ var $ = cheerio.load(html, null, false);
164
+ var segments = [];
165
+ // 如果有 body,取其直接子节点;否则取根节点下的直接子节点
166
+ var roots = $("body").length > 0 ? $("body").children() : $.root().children();
167
+ roots.each(function () {
168
+ var nodeHtml = $(this).toString();
169
+ // 切分包含最外层列表的片段
170
+ if (/^<\s*(ol|ul)/i.test(nodeHtml)) {
171
+ segments.push(nodeHtml);
172
+ }
173
+ else {
174
+ // 进一步检查内部是否存在最外层的 ol/ul,需要分成 前段 + 列表 + 后段
175
+ var inner$_1 = cheerio.load(nodeHtml, null, false);
176
+ var outerLists_1 = [];
177
+ inner$_1("ol, ul").each(function () {
178
+ if (inner$_1(this).parents("ol, ul").length === 0) {
179
+ outerLists_1.push(inner$_1(this).toString());
180
+ }
181
+ });
182
+ if (outerLists_1.length === 0) {
183
+ segments.push(nodeHtml);
184
+ }
185
+ else {
186
+ var tempHtml_1 = nodeHtml;
187
+ outerLists_1.forEach(function (listHtml) {
188
+ var idx = tempHtml_1.indexOf(listHtml);
189
+ if (idx >= 0) {
190
+ var before = tempHtml_1.substring(0, idx);
191
+ if (before.trim())
192
+ segments.push(before);
193
+ segments.push(listHtml);
194
+ tempHtml_1 = tempHtml_1.substring(idx + listHtml.length);
195
+ }
196
+ });
197
+ if (tempHtml_1.trim())
198
+ segments.push(tempHtml_1);
199
+ }
200
+ }
201
+ });
202
+ // fallback:原样返回
203
+ if (segments.length === 0)
204
+ segments.push(html);
205
+ return segments;
206
+ };
207
+ /**
208
+ * 处理单个段落片段,返回转换后的片段 HTML
209
+ */
210
+ RichText_Refactor.processSegment = function (segmentHtml, config) {
211
+ var $ = cheerio.load(segmentHtml, null, false);
212
+ // 按旧实现顺序进行处理,但重构为独立函数划分
213
+ this.handleIndentClass($);
214
+ this.fixImgSizeUnit($);
215
+ this.handleLists($);
216
+ this.replaceBrWithPlaceholder($);
217
+ this.handleAnchorTag($);
218
+ this.wrapTextNodes($);
219
+ this.replaceStyleTags($);
220
+ this.replacePTag($);
221
+ this.handleImgHref($);
222
+ this.addFlexShrink($);
223
+ this.flattenNestedText($);
224
+ this.convertSiblingTextToDiv($);
225
+ this.handleTextIndent($);
226
+ this.adjustLineHeightAndLetterSpacing($, config);
227
+ this.transferTextAlign($);
228
+ this.removeEmptyText($);
229
+ this.fixHeadingFontSize($);
230
+ // 最后:修正 img 结束标签、nbsp
231
+ var res = $.html();
232
+ res = res.replaceAll(/<img([^>]+)>/g, "<img$1 />").replaceAll(/&nbsp;/g, " ");
233
+ return res;
234
+ };
235
+ // ------------------------------
236
+ // 各独立处理步骤实现
237
+ // ------------------------------
238
+ RichText_Refactor.handleIndentClass = function ($) {
239
+ var _loop_1 = function (i) {
240
+ var indent = "ql-indent-".concat(i);
241
+ var extStyle = "padding-left: ".concat(i * 2, "rem");
242
+ $(".".concat(indent)).each(function () {
243
+ var ori = $(this).attr("style") || "";
244
+ $(this).attr("style", mergeStyles(ori, extStyle));
245
+ $(this).removeClass(indent);
246
+ });
247
+ };
248
+ for (var i = 1; i <= 10; i++) {
249
+ _loop_1(i);
250
+ }
251
+ };
252
+ RichText_Refactor.fixImgSizeUnit = function ($) {
253
+ $("img").each(function () {
254
+ var width = $(this).attr("width");
255
+ var height = $(this).attr("height");
256
+ if (width && width + "" === parseInt(width) + "") {
257
+ $(this).attr("width", "".concat(width, "px"));
258
+ }
259
+ if (height && height + "" === parseInt(height) + "") {
260
+ $(this).attr("height", "".concat(height, "px"));
261
+ }
262
+ });
263
+ };
264
+ /** 列表处理(将 ol/ul/li 替换为 div 结构) */
265
+ RichText_Refactor.handleLists = function ($) {
266
+ var topLevelLists = [];
267
+ var collectListItems = function ($container, currentLevel) {
268
+ if (currentLevel === void 0) { currentLevel = 0; }
269
+ var items = [];
270
+ $container.children().each(function () {
271
+ var $child = $(this);
272
+ if ($child.is("li")) {
273
+ var isOrdered = $child.parent().is("ol");
274
+ var orderIndex = 1;
275
+ if (isOrdered) {
276
+ orderIndex = $child.prevAll("li").length + 1;
277
+ }
278
+ var marker = isOrdered ? "".concat(orderIndex, ".") : "•";
279
+ var paddingLeft = currentLevel * 2; // 每层缩进 2rem
280
+ var $liClone = $child.clone();
281
+ $liClone.find("ol, ul").remove();
282
+ var textContent = $liClone.text().trim() || "";
283
+ var style = $child.attr("style") || "";
284
+ items.push({
285
+ level: currentLevel,
286
+ isOrdered: isOrdered,
287
+ orderIndex: orderIndex,
288
+ marker: marker,
289
+ paddingLeft: paddingLeft,
290
+ textContent: textContent,
291
+ style: style,
292
+ });
293
+ // 处理子列表
294
+ $child.find("ol, ul").each(function () {
295
+ var $nestedList = $(this);
296
+ if ($nestedList.parent().closest("li")[0] === $child[0]) {
297
+ var childItems = collectListItems($nestedList, currentLevel + 1);
298
+ items.push.apply(items, childItems);
299
+ }
300
+ });
301
+ }
302
+ });
303
+ return items;
304
+ };
305
+ // 找到所有顶层列表
306
+ $("ol, ul").each(function () {
307
+ var $list = $(this);
308
+ if ($list.parents("ol, ul").length === 0) {
309
+ var placeholder = $("<div data-list-placeholder=\"true\"></div>");
310
+ $list.before(placeholder);
311
+ var items = collectListItems($list, 1);
312
+ topLevelLists.push({
313
+ element: $list,
314
+ placeholder: placeholder,
315
+ items: items,
316
+ });
317
+ }
318
+ });
319
+ // 移除原列表结构
320
+ $("ol, ul, li").remove();
321
+ // 插入新列表
322
+ topLevelLists.forEach(function (listInfo) {
323
+ var placeholder = listInfo.placeholder, items = listInfo.items;
324
+ var html = items
325
+ .map(function (it) {
326
+ return ("<div style=\"".concat(mergeStyles(it.style, "padding-left: ".concat(it.paddingLeft, "rem"), "flex-shrink: 0", "width: 100%", "flex-direction: row", "display: flex"), "\" data-list-item=\"true\">") +
327
+ "<text style=\"".concat(mergeStyles("flex-shrink: 0", "width: 100%", "line-height: 1", "display: flex", "flex-direction: row"), "\">") +
328
+ "<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "margin-right: 0.5rem"), "\">").concat(it.marker, "</div>") +
329
+ "<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "flex: 1"), "\">").concat(it.textContent, "</div>") +
330
+ "</text></div>");
331
+ })
332
+ .join("");
333
+ placeholder.after(html);
334
+ placeholder.remove();
335
+ });
336
+ };
337
+ /** 将连续 <br> 替换为透明占位文字,确保 PixUI 换行 */
338
+ RichText_Refactor.replaceBrWithPlaceholder = function ($) {
339
+ $("br").each(function () {
340
+ $(this).replaceWith("<span style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 20px"), "\" class='pixui-richtext-br-placeholder'>1</span>"));
341
+ });
342
+ };
343
+ /** 处理 <a> 标签:转为 div、保留样式、记录链接 */
344
+ RichText_Refactor.handleAnchorTag = function ($) {
345
+ var self = this;
346
+ $("a").each(function () {
347
+ var id = "PA_RichTextHrefId_".concat(self.hrefIdCnt++);
348
+ var href = $(this).attr("href");
349
+ var originalStyle = $(this).attr("style") || "";
350
+ var textContent = $(this).text();
351
+ var mergedStyles = [];
352
+ // 收集子元素的样式
353
+ if ($(this).find("strong").length > 0)
354
+ mergedStyles.push("font-weight: bold;");
355
+ if ($(this).find("em").length > 0)
356
+ mergedStyles.push("font-style: italic;");
357
+ if ($(this).find("u").length > 0)
358
+ mergedStyles.push("text-decoration: underline;");
359
+ if ($(this).find("s").length > 0)
360
+ mergedStyles.push("text-decoration: line-through;");
361
+ $(this)
362
+ .find("strong, em, u, s, span")
363
+ .each(function () {
364
+ var innerStyle = $(this).attr("style");
365
+ if (innerStyle)
366
+ mergedStyles.push(innerStyle);
367
+ });
368
+ var finalStyle = mergeStyles.apply(void 0, __spreadArray([originalStyle], mergedStyles, false));
369
+ if (href) {
370
+ self.linkNodes.push({ type: LinkNodeType.DIV, href: href, id: id });
371
+ }
372
+ // 确保link节点在正确的text层级内
373
+ var $parent = $(this).parent();
374
+ var isInText = $parent.is("text") || $parent.closest("text").length > 0;
375
+ if (isInText) {
376
+ // 如果已经在text内,直接替换为div
377
+ $(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\" class=\"PA_RichTextHref_ATag\">").concat(textContent, "</div>"));
378
+ }
379
+ else {
380
+ // 如果不在text内,需要确保在正确的层级
381
+ $(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\" class=\"PA_RichTextHref_ATag\">").concat(textContent, "</div>"));
382
+ }
383
+ });
384
+ };
385
+ /** 用 text 标签包裹纯文本节点 */
386
+ RichText_Refactor.wrapTextNodes = function ($) {
387
+ var self = this;
388
+ $("*").each(function () {
389
+ var nodeId = $(this).attr("id") || "";
390
+ if (nodeId.startsWith("PA_RichTextHrefId_"))
391
+ return;
392
+ var isListItem = $(this).attr("data-list-item") === "true";
393
+ if (isListItem)
394
+ return;
395
+ $(this)
396
+ .contents()
397
+ .each(function () {
398
+ var linkParent = $(this).closest("[id^='PA_RichTextHrefId_']");
399
+ if (linkParent.length > 0)
400
+ return;
401
+ var listParent = $(this).closest("[data-list-item='true']");
402
+ if (listParent.length > 0)
403
+ return;
404
+ if (this.type === "text") {
405
+ var text = this.data.trim();
406
+ if (text.length > 0) {
407
+ $(this).replaceWith("<text style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "flex-direction: row"), "\">").concat(text, "</text>"));
408
+ }
409
+ }
410
+ });
411
+ });
412
+ };
413
+ /** strong / em / u / s / span 等标签替换成 text */
414
+ RichText_Refactor.replaceStyleTags = function ($) {
415
+ var tagToStyle = {
416
+ strong: "font-weight: bold",
417
+ em: "font-style: italic",
418
+ u: "text-decoration: underline",
419
+ s: "text-decoration: line-through",
420
+ };
421
+ Object.entries(tagToStyle).forEach(function (_a) {
422
+ var tag = _a[0], style = _a[1];
423
+ $(tag).each(function () {
424
+ var html = $(this).html();
425
+ var oriStyle = $(this).attr("style") || "";
426
+ $(this).replaceWith("<text style=\"".concat(mergeStyles(oriStyle, style, "flex-shrink: 0"), "\">").concat(html, "</text>"));
427
+ });
428
+ });
429
+ $("span").each(function () {
430
+ var html = $(this).html();
431
+ var oriStyle = $(this).attr("style") || "";
432
+ $(this).replaceWith("<text style=\"".concat(mergeStyles(oriStyle, "flex-shrink: 0"), "\">").concat(html, "</text>"));
433
+ });
434
+ };
435
+ /** p → div */
436
+ RichText_Refactor.replacePTag = function ($) {
437
+ $("p").each(function () {
438
+ var html = $(this).html();
439
+ var style = $(this).attr("style") || "";
440
+ $(this).replaceWith("<div style=\"".concat(mergeStyles(style, "flex-shrink: 0", "width:100%"), "\">").concat(html, "</div>"));
441
+ });
442
+ };
443
+ /** img 的 href 转移处理 & 记录链接 */
444
+ RichText_Refactor.handleImgHref = function ($) {
445
+ var self = this;
446
+ $("img").each(function () {
447
+ var id = "PA_RichTextHrefId_".concat(self.hrefIdCnt++);
448
+ $(this).attr("id", id);
449
+ var href = $(this).attr("href");
450
+ if (href) {
451
+ self.linkNodes.push({ type: LinkNodeType.IMG, href: href, id: id });
452
+ }
453
+ $(this).attr("href", "");
454
+ $(this).attr("class", "PA_RichTextHref_ImgTag");
455
+ $(this).attr("data-href", href);
456
+ });
457
+ };
458
+ /** 给指定标签补 flex-shrink:0 */
459
+ RichText_Refactor.addFlexShrink = function ($) {
460
+ ["h1", "h2", "h3", "h4", "h5", "h6", "a", "img", "div"].forEach(function (tag) {
461
+ $(tag).each(function () {
462
+ var isListItem = $(this).attr("data-list-item") === "true";
463
+ var inListItem = $(this).closest("[data-list-item='true']").length > 0;
464
+ if (!isListItem && !inListItem) {
465
+ var style = $(this).attr("style") || "";
466
+ $(this).attr("style", mergeStyles(style, "flex-shrink: 0"));
467
+ }
468
+ });
469
+ });
470
+ };
471
+ /** 把嵌套的 text 展平 */
472
+ RichText_Refactor.flattenNestedText = function ($) {
473
+ while ($("text > text").length > 0) {
474
+ $("text").each(function () {
475
+ var $this = $(this);
476
+ var parentStyle = $this.attr("style") || "";
477
+ $this.children("text").each(function () {
478
+ var $child = $(this);
479
+ var childStyle = $child.attr("style") || "";
480
+ var mergedStyle = mergeStyles(parentStyle, childStyle);
481
+ $child.attr("style", mergedStyle);
482
+ });
483
+ if ($this.children("text").length > 0) {
484
+ $this.replaceWith($this.html() || "");
485
+ }
486
+ });
487
+ }
488
+ };
489
+ /** 将同一行的 text 节点转为 div 并外包一层 text */
490
+ RichText_Refactor.convertSiblingTextToDiv = function ($) {
491
+ var nodeArr = [];
492
+ ["h1", "h2", "h3", "h4", "h5", "h6", "div"].forEach(function (tag) {
493
+ $(tag).each(function () {
494
+ var nodeId = $(this).attr("id") || "";
495
+ var isListItem = $(this).attr("data-list-item") === "true";
496
+ var inListItem = $(this).closest("[data-list-item='true']").length > 0;
497
+ if (!nodeId.startsWith("PA_RichTextHrefId_") && !isListItem && !inListItem) {
498
+ nodeArr.push(this);
499
+ }
500
+ });
501
+ });
502
+ nodeArr.forEach(function (node) {
503
+ var tag = $(node).prop("tagName");
504
+ var nodeId = $(node).attr("id") || "";
505
+ // 处理子元素:将text转为div,但保留link节点
506
+ $(node)
507
+ .children("text")
508
+ .each(function () {
509
+ var inListItem = $(this).closest("[data-list-item='true']").length > 0;
510
+ if (inListItem)
511
+ return;
512
+ var text = $(this).html();
513
+ var style = $(this).attr("style") || "";
514
+ // 检查是否包含link节点
515
+ var hasLink = $(this).find('[id^="PA_RichTextHrefId_"]').length > 0;
516
+ if (hasLink) {
517
+ // 如果包含link节点,需要特殊处理以保持link在正确位置
518
+ var $tempDiv = $("<div style=\"".concat(mergeStyles(style, "word-break: break-word", "flex-shrink: 0", "flex-direction: row"), "\">").concat(text, "</div>"));
519
+ $(this).replaceWith($tempDiv);
520
+ }
521
+ else {
522
+ // 普通text节点直接转换
523
+ $(this).replaceWith("<div style=\"".concat(mergeStyles(style, "word-break: break-word", "flex-shrink: 0", "flex-direction: row"), "\">").concat(text, "</div>"));
524
+ }
525
+ });
526
+ var tagHtml = $(node).html() || "";
527
+ var tagStyle = $(node).attr("style") || "";
528
+ if (tagHtml.trim()) {
529
+ var idAttr = nodeId ? " id=\"".concat(nodeId, "\"") : "";
530
+ var customAttrs = "";
531
+ var attribs = ($(node).get(0) || {}).attribs || {};
532
+ for (var _i = 0, _a = Object.entries(attribs); _i < _a.length; _i++) {
533
+ var _b = _a[_i], k = _b[0], v = _b[1];
534
+ if (k !== "style" && k !== "id") {
535
+ customAttrs += " ".concat(k, "=\"").concat(v, "\"");
536
+ }
537
+ }
538
+ // 保证外层tag的style不合并子div的style
539
+ $(node).replaceWith("<".concat(tag, " style=\"").concat(mergeStyles(tagStyle, "flex-direction: row"), "\"").concat(idAttr).concat(customAttrs, "><text style=\"").concat(mergeStyles("flex-shrink: 0", "width: 100%", "line-height: 1"), "\">").concat(tagHtml, "</text></").concat(tag, ">"));
540
+ }
541
+ });
542
+ };
543
+ /** text-indent 首行缩进处理 */
544
+ RichText_Refactor.handleTextIndent = function ($) {
545
+ $("*").each(function () {
546
+ var textIndent = $(this).css("text-indent");
547
+ if (textIndent) {
548
+ var repeatCnt = parseInt(textIndent);
549
+ if (repeatCnt > 0) {
550
+ var spacer = "<div style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 16px"), "\">").concat("一".repeat(repeatCnt), "</div>");
551
+ var textChild = $(this).children("text").first();
552
+ if (textChild.length > 0) {
553
+ var first = textChild.children().first();
554
+ if (first.length > 0)
555
+ first.before(spacer);
556
+ else
557
+ textChild.append(spacer);
558
+ }
559
+ }
560
+ }
561
+ });
562
+ };
563
+ /** line-height / letter-spacing 调整 */
564
+ RichText_Refactor.adjustLineHeightAndLetterSpacing = function ($, config) {
565
+ $("text").each(function () {
566
+ var $text = $(this);
567
+ var maxLineHeight = 0;
568
+ $text.children("div").each(function () {
569
+ var lh = parseInt($(this).css("line-height") || "1");
570
+ maxLineHeight = Math.max(maxLineHeight, lh);
571
+ });
572
+ var scale = (config === null || config === void 0 ? void 0 : config.lineHeightScale) || 1;
573
+ if (maxLineHeight > 0) {
574
+ var currentStyle = $text.attr("style") || "";
575
+ $text.attr("style", mergeStyles(currentStyle, "line-height: ".concat(maxLineHeight * scale)));
576
+ }
577
+ });
578
+ $("text").each(function () {
579
+ var $text = $(this);
580
+ var maxLS = 0;
581
+ $text.children("div").each(function () {
582
+ var ls = $(this).css("letter-spacing") || "0";
583
+ var lsNum = parseInt(ls);
584
+ maxLS = Math.max(maxLS, lsNum);
585
+ });
586
+ if (maxLS > 0) {
587
+ var currentStyle = $text.attr("style") || "";
588
+ $text.attr("style", mergeStyles(currentStyle, "letter-spacing: ".concat(maxLS, "rem")));
589
+ }
590
+ });
591
+ };
592
+ /** 把 div 的 text-align 转移到子 text 上 */
593
+ RichText_Refactor.transferTextAlign = function ($) {
594
+ $("div").each(function () {
595
+ var ta = $(this).css("text-align") || "";
596
+ if (ta) {
597
+ $(this)
598
+ .children("text")
599
+ .each(function () {
600
+ var currentStyle = $(this).attr("style") || "";
601
+ $(this).attr("style", mergeStyles(currentStyle, "text-align: ".concat(ta)));
602
+ });
603
+ // 清除div的text-align
604
+ var currentStyle = $(this).attr("style") || "";
605
+ var styleObj = parseStyleString(currentStyle);
606
+ delete styleObj["text-align"];
607
+ $(this).attr("style", serializeStyleObject(styleObj));
608
+ }
609
+ });
610
+ };
611
+ /** 删除空 text 节点 */
612
+ RichText_Refactor.removeEmptyText = function ($) {
613
+ $("text").each(function () {
614
+ var t = $(this).html() || "";
615
+ if (t.trim() === "")
616
+ $(this).remove();
617
+ });
618
+ };
619
+ /** 补默认 heading 字体大小 */
620
+ RichText_Refactor.fixHeadingFontSize = function ($) {
621
+ var hRem = ["2rem", "1.5rem", "1.17rem", "1rem", "0.83rem", "0.67rem"];
622
+ ["h1", "h2", "h3", "h4", "h5", "h6"].forEach(function (tag) {
623
+ $(tag).each(function () {
624
+ var idx = parseInt(tag.replace("h", "")) - 1;
625
+ var style = $(this).attr("style") || "";
626
+ if (!style.includes("font-size")) {
627
+ $(this).attr("style", mergeStyles(style, "font-size:".concat(hRem[idx])));
628
+ }
629
+ });
630
+ });
631
+ };
632
+ // 存储需要绑定点击事件的节点
633
+ RichText_Refactor.linkNodes = [];
634
+ RichText_Refactor.hrefIdCnt = 0;
635
+ return RichText_Refactor;
636
+ }());
637
+ exports.RichText_Refactor = RichText_Refactor;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixui-dev/pixui-richtext-helper",
3
- "version": "0.1.1-beta.1",
3
+ "version": "0.1.1-beta.3",
4
4
  "description": "pixui richtext helper",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,8 +19,9 @@
19
19
  "author": "jnjnjnzhang",
20
20
  "license": "ISC",
21
21
  "devDependencies": {
22
- "@types/node": "^22.5.4",
23
- "typescript": "^5.0.0"
22
+ "@types/node": "^22.15.33",
23
+ "ts-node": "^10.9.2",
24
+ "typescript": "^5.8.3"
24
25
  },
25
26
  "dependencies": {
26
27
  "cheerio": "1.0.0-rc.10"