@pixui-dev/pixui-richtext-helper 0.2.0 → 0.2.2

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.
@@ -1,4 +1,4 @@
1
- import { RichText_Refactor, LinkNodeType, LinkClickParams } from "./richtext/RichText_Refactor";
1
+ import { RichTextCore, LinkNodeType, LinkClickParams } from "./richtext/RichTextCore";
2
2
  /**
3
3
  * 对外暴露的 RichText 组件。
4
4
  * 保持旧版使用方式不变,内部委托给 RichText_Refactor 实现。
@@ -8,14 +8,14 @@ export declare const RichText: {
8
8
  LinkNodeType: typeof LinkNodeType;
9
9
  /**
10
10
  * 将富文本转换为 PixUI innerHTML 兼容格式
11
- * @see RichText_Refactor.convertRichTextToPixuiStyle
11
+ * @see RichTextCore.convertRichTextToPixuiStyle
12
12
  */
13
- convertRichTextToPixuiStyle: typeof RichText_Refactor.convertRichTextToPixuiStyle;
13
+ convertRichTextToPixuiStyle: typeof RichTextCore.convertRichTextToPixuiStyle;
14
14
  /**
15
15
  * 绑定富文本中的链接点击事件
16
- * @see RichText_Refactor.bindLinkClickEvents
16
+ * @see RichTextCore.bindLinkClickEvents
17
17
  */
18
- bindLinkClickEvents: typeof RichText_Refactor.bindLinkClickEvents;
18
+ bindLinkClickEvents: typeof RichTextCore.bindLinkClickEvents;
19
19
  };
20
20
  export type { LinkClickParams };
21
21
  export { LinkNodeType };
package/dist/RichText.js CHANGED
@@ -1,24 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
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; } });
4
+ var RichTextCore_1 = require("./richtext/RichTextCore");
5
+ Object.defineProperty(exports, "LinkNodeType", { enumerable: true, get: function () { return RichTextCore_1.LinkNodeType; } });
6
6
  /**
7
7
  * 对外暴露的 RichText 组件。
8
8
  * 保持旧版使用方式不变,内部委托给 RichText_Refactor 实现。
9
9
  */
10
10
  exports.RichText = {
11
11
  /** 链接节点类型枚举 */
12
- LinkNodeType: RichText_Refactor_1.LinkNodeType,
12
+ LinkNodeType: RichTextCore_1.LinkNodeType,
13
13
  /**
14
14
  * 将富文本转换为 PixUI innerHTML 兼容格式
15
- * @see RichText_Refactor.convertRichTextToPixuiStyle
15
+ * @see RichTextCore.convertRichTextToPixuiStyle
16
16
  */
17
- convertRichTextToPixuiStyle: RichText_Refactor_1.RichText_Refactor.convertRichTextToPixuiStyle,
17
+ convertRichTextToPixuiStyle: RichTextCore_1.RichTextCore.convertRichTextToPixuiStyle,
18
18
  /**
19
19
  * 绑定富文本中的链接点击事件
20
- * @see RichText_Refactor.bindLinkClickEvents
20
+ * @see RichTextCore.bindLinkClickEvents
21
21
  */
22
- bindLinkClickEvents: RichText_Refactor_1.RichText_Refactor.bindLinkClickEvents,
22
+ bindLinkClickEvents: RichTextCore_1.RichTextCore.bindLinkClickEvents,
23
23
  };
24
24
  exports.default = exports.RichText;
@@ -13,11 +13,13 @@ export interface LinkClickParams {
13
13
  id: string;
14
14
  }
15
15
  /*****************************************************
16
- * RichText_Refactor 主类
16
+ * RichTextCore 主类
17
17
  *****************************************************/
18
- export declare class RichText_Refactor {
18
+ export declare class RichTextCore {
19
19
  private static linkNodes;
20
20
  private static hrefIdCnt;
21
+ /** 所有链接节点统一的 class 名 */
22
+ private static readonly LINK_NODE_CLASS;
21
23
  /**
22
24
  * 富文本转换为 PixUI innerHTML 兼容格式
23
25
  * @param str 原始富文本 HTML
@@ -42,7 +42,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
42
42
  return to.concat(ar || Array.prototype.slice.call(from));
43
43
  };
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
- exports.RichText_Refactor = exports.LinkNodeType = void 0;
45
+ exports.RichTextCore = exports.LinkNodeType = void 0;
46
46
  var cheerio = __importStar(require("cheerio"));
47
47
  /*****************************************************
48
48
  * 类型、枚举定义
@@ -107,31 +107,31 @@ var mergeStyles = function () {
107
107
  return serializeStyleObject(mergedStyleObj);
108
108
  };
109
109
  /*****************************************************
110
- * RichText_Refactor 主类
110
+ * RichTextCore 主类
111
111
  *****************************************************/
112
- var RichText_Refactor = /** @class */ (function () {
113
- function RichText_Refactor() {
112
+ var RichTextCore = /** @class */ (function () {
113
+ function RichTextCore() {
114
114
  }
115
115
  /**
116
116
  * 富文本转换为 PixUI innerHTML 兼容格式
117
117
  * @param str 原始富文本 HTML
118
118
  * @param config 可选配置
119
119
  */
120
- RichText_Refactor.convertRichTextToPixuiStyle = function (str, config) {
120
+ RichTextCore.convertRichTextToPixuiStyle = function (str, config) {
121
121
  // 重置全局状态
122
- RichText_Refactor.linkNodes = [];
123
- RichText_Refactor.hrefIdCnt = 0;
122
+ RichTextCore.linkNodes = [];
123
+ RichTextCore.hrefIdCnt = 0;
124
124
  var $1 = cheerio.load(str, null, false);
125
125
  //检查html,如果有text节点,说明是转换过的,直接返回
126
126
  if ($1("text").length > 0) {
127
127
  return str;
128
128
  }
129
129
  // ---------- 第 1 步:段落分割(基础实现:根节点切分) ----------
130
- var segments = RichText_Refactor.splitIntoSegments($1);
130
+ var segments = RichTextCore.splitIntoSegments($1);
131
131
  // ---------- 第 2/3 步:遍历 + 展平 ----------
132
132
  // 为保证兼容性,我们直接对 HTML 进行逐段处理并在内部构建 PixUI 结构。
133
133
  // 这样既保持分段概念,又可复用旧逻辑的稳定性。
134
- var processedSegments = segments.map(function (seg) { return RichText_Refactor.processSegment(seg, config); });
134
+ var processedSegments = segments.map(function (seg) { return RichTextCore.processSegment(seg, config); });
135
135
  // ---------- 第 4 步:拼装 ----------
136
136
  var Result = processedSegments.join("");
137
137
  // console.log(Result);
@@ -140,22 +140,31 @@ var RichText_Refactor = /** @class */ (function () {
140
140
  /**
141
141
  * 绑定链接点击事件
142
142
  */
143
- RichText_Refactor.bindLinkClickEvents = function (linkClickHandler) {
144
- RichText_Refactor.linkNodes.forEach(function (nodeInfo) {
145
- var element = document.getElementById(nodeInfo.id);
146
- if (element) {
147
- element.onclick = function (e) {
143
+ RichTextCore.bindLinkClickEvents = function (linkClickHandler) {
144
+ // 直接查询统一的 class
145
+ setTimeout(function () {
146
+ var elements = Array.from(document.querySelectorAll(".".concat(RichTextCore.LINK_NODE_CLASS)));
147
+ elements.forEach(function (el) {
148
+ var hrefEncoded = el.getAttribute("data-link-href") || "";
149
+ var href = decodeURIComponent(hrefEncoded);
150
+ var typeStr = el.getAttribute("data-link-type");
151
+ var type = typeStr === LinkNodeType.IMG ? LinkNodeType.IMG : LinkNodeType.DIV;
152
+ // 避免重复绑定
153
+ if (el._pixui_link_bound)
154
+ return;
155
+ el._pixui_link_bound = true;
156
+ el.onclick = function (e) {
148
157
  e.stopPropagation();
149
158
  e.preventDefault();
150
159
  linkClickHandler({
151
- type: nodeInfo.type,
152
- href: nodeInfo.href,
153
- id: nodeInfo.id,
160
+ type: type,
161
+ href: href,
162
+ id: el.id,
154
163
  });
155
164
  return false;
156
165
  };
157
- }
158
- });
166
+ });
167
+ }, 100);
159
168
  };
160
169
  /*****************************************************
161
170
  * 内部流程函数
@@ -164,7 +173,7 @@ var RichText_Refactor = /** @class */ (function () {
164
173
  * 将 HTML 切分为基础段落片段。
165
174
  * 简易实现:以顶级节点为粒度切分,再根据最外层列表节点进行分割。
166
175
  */
167
- RichText_Refactor.splitIntoSegments = function ($) {
176
+ RichTextCore.splitIntoSegments = function ($) {
168
177
  var segments = [];
169
178
  // 如果有 body,取其直接子节点;否则取根节点下的直接子节点
170
179
  var roots = $("body").length > 0 ? $("body").children() : $.root().children();
@@ -211,7 +220,7 @@ var RichText_Refactor = /** @class */ (function () {
211
220
  /**
212
221
  * 处理单个段落片段,返回转换后的片段 HTML
213
222
  */
214
- RichText_Refactor.processSegment = function (segmentHtml, config) {
223
+ RichTextCore.processSegment = function (segmentHtml, config) {
215
224
  var $ = cheerio.load(segmentHtml, null, false);
216
225
  // 按旧实现顺序进行处理,但重构为独立函数划分
217
226
  this.preprocess($);
@@ -244,7 +253,7 @@ var RichText_Refactor = /** @class */ (function () {
244
253
  // ------------------------------
245
254
  // 各独立处理步骤实现
246
255
  // ------------------------------
247
- RichText_Refactor.preprocess = function ($) {
256
+ RichTextCore.preprocess = function ($) {
248
257
  var _loop_1 = function (i) {
249
258
  var indent = "ql-indent-".concat(i);
250
259
  var extStyle = "padding-left: ".concat(i * 2, "em");
@@ -282,7 +291,7 @@ var RichText_Refactor = /** @class */ (function () {
282
291
  }
283
292
  });
284
293
  };
285
- RichText_Refactor.fixImgSizeUnit = function ($) {
294
+ RichTextCore.fixImgSizeUnit = function ($) {
286
295
  $("img").each(function () {
287
296
  var width = $(this).attr("width");
288
297
  var height = $(this).attr("height");
@@ -295,7 +304,7 @@ var RichText_Refactor = /** @class */ (function () {
295
304
  });
296
305
  };
297
306
  /** 列表处理(将 ol/ul/li 替换为 div 结构) */
298
- RichText_Refactor.handleLists = function ($, lineHeightScale) {
307
+ RichTextCore.handleLists = function ($, lineHeightScale) {
299
308
  if (lineHeightScale === void 0) { lineHeightScale = 1; }
300
309
  var topLevelLists = [];
301
310
  var collectListItems = function ($container, currentLevel) {
@@ -365,7 +374,7 @@ var RichText_Refactor = /** @class */ (function () {
365
374
  "width: 100%",
366
375
  "flex-direction: row",
367
376
  "display: flex"], false)), "\" data-list-item=\"true\">") +
368
- "<text style=\"".concat(mergeStyles("flex-shrink: 0", "width: 100%", "line-height: 1", "display: flex", "flex-direction: row"), "\">") +
377
+ "<text style=\"".concat(mergeStyles("flex-shrink: 0", "width: 100%", "display: flex", "flex-direction: row"), "\">") +
369
378
  "<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "padding-right: 0.5em"), "\">").concat(it.marker, "</div>") +
370
379
  "<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "flex: 1"), "\">").concat(it.textContent, "</div>") +
371
380
  "</text></div>");
@@ -376,13 +385,13 @@ var RichText_Refactor = /** @class */ (function () {
376
385
  });
377
386
  };
378
387
  /** 将连续 <br> 替换为透明占位文字,确保 PixUI 换行 */
379
- RichText_Refactor.replaceBrWithPlaceholder = function ($) {
388
+ RichTextCore.replaceBrWithPlaceholder = function ($) {
380
389
  $("br").each(function () {
381
390
  $(this).replaceWith("<div style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 20px"), "\" class='pixui-richtext-br-placeholder'>1</div>"));
382
391
  });
383
392
  };
384
393
  /** 处理 <a> 标签:转为 div、保留样式、记录链接 */
385
- RichText_Refactor.handleAnchorTag = function ($) {
394
+ RichTextCore.handleAnchorTag = function ($) {
386
395
  var self = this;
387
396
  $("a").each(function () {
388
397
  var id = "PA_RichTextHrefId_".concat(self.hrefIdCnt++);
@@ -407,14 +416,15 @@ var RichText_Refactor = /** @class */ (function () {
407
416
  mergedStyles.push(innerStyle);
408
417
  });
409
418
  var finalStyle = mergeStyles.apply(void 0, __spreadArray([originalStyle], mergedStyles, false));
419
+ var encodedHref = href ? encodeURIComponent(href) : "";
410
420
  if (href) {
411
421
  self.linkNodes.push({ type: LinkNodeType.DIV, href: href, id: id });
412
422
  }
413
- $(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\" class=\"PA_RichTextHref_ATag\">").concat(textContent, "</div>"));
423
+ $(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\" class=\"").concat(RichTextCore.LINK_NODE_CLASS, " PA_RichTextHref_ATag\" data-link-type=\"div\" data-link-href=\"").concat(encodedHref, "\">").concat(textContent, "</div>"));
414
424
  });
415
425
  };
416
426
  /** 用 text 标签包裹纯文本节点 */
417
- RichText_Refactor.wrapTextNodes = function ($) {
427
+ RichTextCore.wrapTextNodes = function ($) {
418
428
  var self = this;
419
429
  $("*").each(function () {
420
430
  var nodeId = $(this).attr("id") || "";
@@ -442,7 +452,7 @@ var RichText_Refactor = /** @class */ (function () {
442
452
  });
443
453
  };
444
454
  /** strong / em / u / s / span 等标签替换成 text */
445
- RichText_Refactor.replaceStyleTags = function ($) {
455
+ RichTextCore.replaceStyleTags = function ($) {
446
456
  var tagToStyle = {
447
457
  strong: "font-weight: bold",
448
458
  em: "font-style: italic",
@@ -472,7 +482,7 @@ var RichText_Refactor = /** @class */ (function () {
472
482
  }
473
483
  };
474
484
  /** p → div */
475
- RichText_Refactor.replacePTag = function ($) {
485
+ RichTextCore.replacePTag = function ($) {
476
486
  $("p").each(function () {
477
487
  var html = $(this).html();
478
488
  var style = $(this).attr("style") || "";
@@ -480,7 +490,7 @@ var RichText_Refactor = /** @class */ (function () {
480
490
  });
481
491
  };
482
492
  /** img 的 href 转移处理 & 记录链接 */
483
- RichText_Refactor.handleImgHref = function ($) {
493
+ RichTextCore.handleImgHref = function ($) {
484
494
  var self = this;
485
495
  $("img").each(function () {
486
496
  var id = "PA_RichTextHrefId_".concat(self.hrefIdCnt++);
@@ -489,16 +499,21 @@ var RichText_Refactor = /** @class */ (function () {
489
499
  if (href) {
490
500
  self.linkNodes.push({ type: LinkNodeType.IMG, href: href, id: id });
491
501
  }
502
+ // 将链接信息以转义形式保存在 data- 属性中,避免默认跳转
503
+ var encodedHref = href ? encodeURIComponent(href) : "";
504
+ $(this).attr("data-link-type", "img");
505
+ $(this).attr("data-link-href", encodedHref);
492
506
  $(this).attr("href", "");
493
507
  var prevClass = $(this).attr("class") || "";
494
508
  var newClasses = new Set(prevClass.split(/\s+/).filter(Boolean));
495
509
  newClasses.add("PA_RichTextHref_ImgTag"); // 超链接专用标记(保持原有逻辑)
496
510
  newClasses.add("PA_RichTextImgTag"); // 富文本图片通用标记
511
+ newClasses.add(RichTextCore.LINK_NODE_CLASS); // 统一链接标记
497
512
  $(this).attr("class", Array.from(newClasses).join(" "));
498
513
  });
499
514
  };
500
515
  /** 给指定标签补 flex-shrink:0 */
501
- RichText_Refactor.addFlexShrink = function ($) {
516
+ RichTextCore.addFlexShrink = function ($) {
502
517
  ["h1", "h2", "h3", "h4", "h5", "h6", "a", "img", "div"].forEach(function (tag) {
503
518
  $(tag).each(function () {
504
519
  var isListItem = $(this).attr("data-list-item") === "true";
@@ -511,7 +526,7 @@ var RichText_Refactor = /** @class */ (function () {
511
526
  });
512
527
  };
513
528
  /** 把嵌套的 text 展平 */
514
- RichText_Refactor.flattenNestedText = function ($) {
529
+ RichTextCore.flattenNestedText = function ($) {
515
530
  while ($("text > text").length > 0) {
516
531
  $("text").each(function () {
517
532
  var $this = $(this);
@@ -529,7 +544,7 @@ var RichText_Refactor = /** @class */ (function () {
529
544
  }
530
545
  };
531
546
  /** 将同一行的 text 节点转为 div 并外包一层 text */
532
- RichText_Refactor.convertSiblingTextToDiv = function ($) {
547
+ RichTextCore.convertSiblingTextToDiv = function ($) {
533
548
  var nodeArr = [];
534
549
  ["h1", "h2", "h3", "h4", "h5", "h6", "div"].forEach(function (tag) {
535
550
  $(tag).each(function () {
@@ -578,12 +593,12 @@ var RichText_Refactor = /** @class */ (function () {
578
593
  }
579
594
  }
580
595
  // 保证外层tag的style不合并子div的style
581
- $(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, ">"));
596
+ $(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, ">"));
582
597
  }
583
598
  });
584
599
  };
585
600
  /** text-indent 首行缩进处理 */
586
- RichText_Refactor.handleTextIndent = function ($) {
601
+ RichTextCore.handleTextIndent = function ($) {
587
602
  $("*").each(function () {
588
603
  var textIndent = $(this).css("text-indent");
589
604
  if (textIndent) {
@@ -603,7 +618,7 @@ var RichText_Refactor = /** @class */ (function () {
603
618
  });
604
619
  };
605
620
  /** line-height / letter-spacing 调整 */
606
- RichText_Refactor.adjustLineHeightAndLetterSpacing = function ($, config) {
621
+ RichTextCore.adjustLineHeightAndLetterSpacing = function ($, config) {
607
622
  $("text").each(function () {
608
623
  var $text = $(this);
609
624
  var maxLineHeight = 0;
@@ -632,7 +647,7 @@ var RichText_Refactor = /** @class */ (function () {
632
647
  });
633
648
  };
634
649
  /** 把 div 的 text-align 转移到子 text 上 */
635
- RichText_Refactor.transferTextAlign = function ($) {
650
+ RichTextCore.transferTextAlign = function ($) {
636
651
  $("div").each(function () {
637
652
  var ta = $(this).css("text-align") || "";
638
653
  if (ta) {
@@ -651,7 +666,7 @@ var RichText_Refactor = /** @class */ (function () {
651
666
  });
652
667
  };
653
668
  /** 删除空 text 节点 */
654
- RichText_Refactor.removeEmptyText = function ($) {
669
+ RichTextCore.removeEmptyText = function ($) {
655
670
  $("text").each(function () {
656
671
  var t = $(this).html() || "";
657
672
  if (t.trim() === "")
@@ -659,7 +674,7 @@ var RichText_Refactor = /** @class */ (function () {
659
674
  });
660
675
  };
661
676
  /** 补默认 heading 字体大小 */
662
- RichText_Refactor.fixHeadingFontSize = function ($) {
677
+ RichTextCore.fixHeadingFontSize = function ($) {
663
678
  var hRem = ["2em", "1.5em", "1.17em", "1em", "0.83em", "0.67em"];
664
679
  ["h1", "h2", "h3", "h4", "h5", "h6"].forEach(function (tag) {
665
680
  $(tag).each(function () {
@@ -672,8 +687,10 @@ var RichText_Refactor = /** @class */ (function () {
672
687
  });
673
688
  };
674
689
  // 存储需要绑定点击事件的节点
675
- RichText_Refactor.linkNodes = [];
676
- RichText_Refactor.hrefIdCnt = 0;
677
- return RichText_Refactor;
690
+ RichTextCore.linkNodes = [];
691
+ RichTextCore.hrefIdCnt = 0;
692
+ /** 所有链接节点统一的 class 名 */
693
+ RichTextCore.LINK_NODE_CLASS = "PA_RichTextLinkNode";
694
+ return RichTextCore;
678
695
  }());
679
- exports.RichText_Refactor = RichText_Refactor;
696
+ exports.RichTextCore = RichTextCore;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixui-dev/pixui-richtext-helper",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "pixui richtext helper",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "scripts": {
13
13
  "test": "echo \"Error: no test specified\" && exit 1",
14
- "build": "tsc"
14
+ "build": "rm -rf dist && tsc"
15
15
  },
16
16
  "publishConfig": {
17
17
  "access": "public"
package/readme.md CHANGED
@@ -76,3 +76,10 @@ componentDidMount() { // 在节点渲染后绑定点击事件
76
76
  2. 图片节点统一补充PA_RichTextImgTag的class
77
77
  3. 将列表的margin-left统一修改为padding-left
78
78
  4. 修复某些情况下多余的span标签
79
+
80
+ 0.2.1
81
+ 1. 组件代码结构调整
82
+
83
+ 0.2.2
84
+ 1. 去掉某些节点默认的lineheight:1
85
+ 2. 超链接改为直接在节点中记录数据,方便预加载流程在不同的环境调用convert和bind