@pixui-dev/pixui-richtext-helper 0.1.1-beta.5 → 0.2.0
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.
|
@@ -42,7 +42,7 @@ export declare class RichText_Refactor {
|
|
|
42
42
|
* 处理单个段落片段,返回转换后的片段 HTML
|
|
43
43
|
*/
|
|
44
44
|
private static processSegment;
|
|
45
|
-
private static
|
|
45
|
+
private static preprocess;
|
|
46
46
|
private static fixImgSizeUnit;
|
|
47
47
|
/** 列表处理(将 ol/ul/li 替换为 div 结构) */
|
|
48
48
|
private static handleLists;
|
|
@@ -214,7 +214,7 @@ var RichText_Refactor = /** @class */ (function () {
|
|
|
214
214
|
RichText_Refactor.processSegment = function (segmentHtml, config) {
|
|
215
215
|
var $ = cheerio.load(segmentHtml, null, false);
|
|
216
216
|
// 按旧实现顺序进行处理,但重构为独立函数划分
|
|
217
|
-
this.
|
|
217
|
+
this.preprocess($);
|
|
218
218
|
this.fixImgSizeUnit($);
|
|
219
219
|
this.handleLists($, (config === null || config === void 0 ? void 0 : config.lineHeightScale) || 1);
|
|
220
220
|
this.replaceBrWithPlaceholder($);
|
|
@@ -230,19 +230,24 @@ var RichText_Refactor = /** @class */ (function () {
|
|
|
230
230
|
this.adjustLineHeightAndLetterSpacing($, config);
|
|
231
231
|
this.transferTextAlign($);
|
|
232
232
|
this.removeEmptyText($);
|
|
233
|
-
this.fixHeadingFontSize($);
|
|
233
|
+
// this.fixHeadingFontSize($);
|
|
234
234
|
// 最后:修正 img 结束标签、nbsp
|
|
235
235
|
var res = $.html();
|
|
236
|
-
res = res
|
|
236
|
+
res = res
|
|
237
|
+
.replaceAll(/<img([^>]+)>/g, "<img$1 />")
|
|
238
|
+
.replaceAll(/ /g, " ")
|
|
239
|
+
.replaceAll(/&/g, "&")
|
|
240
|
+
.replaceAll(/"/g, '"')
|
|
241
|
+
.replaceAll("\"", "\"");
|
|
237
242
|
return res;
|
|
238
243
|
};
|
|
239
244
|
// ------------------------------
|
|
240
245
|
// 各独立处理步骤实现
|
|
241
246
|
// ------------------------------
|
|
242
|
-
RichText_Refactor.
|
|
247
|
+
RichText_Refactor.preprocess = function ($) {
|
|
243
248
|
var _loop_1 = function (i) {
|
|
244
249
|
var indent = "ql-indent-".concat(i);
|
|
245
|
-
var extStyle = "padding-left: ".concat(i * 2, "
|
|
250
|
+
var extStyle = "padding-left: ".concat(i * 2, "em");
|
|
246
251
|
$(".".concat(indent)).each(function () {
|
|
247
252
|
var ori = $(this).attr("style") || "";
|
|
248
253
|
$(this).attr("style", mergeStyles(ori, extStyle));
|
|
@@ -252,6 +257,30 @@ var RichText_Refactor = /** @class */ (function () {
|
|
|
252
257
|
for (var i = 1; i <= 10; i++) {
|
|
253
258
|
_loop_1(i);
|
|
254
259
|
}
|
|
260
|
+
// 在所有标题标签后插入换行 <br>
|
|
261
|
+
$("h1, h2, h3, h4, h5, h6").each(function () {
|
|
262
|
+
// 若标题后紧跟已有换行则不再追加
|
|
263
|
+
var next = $(this).next();
|
|
264
|
+
if (!next.is("br")) {
|
|
265
|
+
$(this).after("<br>");
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
// 将所有的margin-left转换为padding-left
|
|
269
|
+
$("*").each(function () {
|
|
270
|
+
var oriStyle = $(this).attr("style") || "";
|
|
271
|
+
if (!oriStyle)
|
|
272
|
+
return;
|
|
273
|
+
var styleObj = parseStyleString(oriStyle);
|
|
274
|
+
var marginLeftVal = styleObj["margin-left"];
|
|
275
|
+
if (marginLeftVal !== undefined) {
|
|
276
|
+
// 移除 margin-left
|
|
277
|
+
delete styleObj["margin-left"];
|
|
278
|
+
// 如果原本没有 padding-left,则直接设置;若已有,简单覆盖(遵循后写优先规则)
|
|
279
|
+
styleObj["padding-left"] = styleObj["padding-left"] || marginLeftVal;
|
|
280
|
+
// 写回合并后的样式
|
|
281
|
+
$(this).attr("style", serializeStyleObject(styleObj));
|
|
282
|
+
}
|
|
283
|
+
});
|
|
255
284
|
};
|
|
256
285
|
RichText_Refactor.fixImgSizeUnit = function ($) {
|
|
257
286
|
$("img").each(function () {
|
|
@@ -281,7 +310,7 @@ var RichText_Refactor = /** @class */ (function () {
|
|
|
281
310
|
orderIndex = $child.prevAll("li").length + 1;
|
|
282
311
|
}
|
|
283
312
|
var marker = isOrdered ? "".concat(orderIndex, ".") : "•";
|
|
284
|
-
var paddingLeft = currentLevel * 2; // 每层缩进
|
|
313
|
+
var paddingLeft = currentLevel * 2; // 每层缩进 2em
|
|
285
314
|
var $liClone = $child.clone();
|
|
286
315
|
$liClone.find("ol, ul").remove();
|
|
287
316
|
var textContent = $liClone.text().trim() || "";
|
|
@@ -328,16 +357,16 @@ var RichText_Refactor = /** @class */ (function () {
|
|
|
328
357
|
var placeholder = listInfo.placeholder, items = listInfo.items;
|
|
329
358
|
var html = items
|
|
330
359
|
.map(function (it, idx) {
|
|
331
|
-
// 所有列表项默认上下 0.5 * lineHeightScale
|
|
360
|
+
// 所有列表项默认上下 0.5 * lineHeightScale em
|
|
332
361
|
var marginTopVal = idx === 0 ? 1 * lineHeightScale : 0.5 * lineHeightScale;
|
|
333
362
|
var marginBottomVal = idx === items.length - 1 ? 1 * lineHeightScale : 0.5 * lineHeightScale;
|
|
334
|
-
var marginAdjust = ["margin-top: ".concat(marginTopVal, "
|
|
335
|
-
return ("<div style=\"".concat(mergeStyles.apply(void 0, __spreadArray(__spreadArray([it.style], marginAdjust, false), ["padding-left: ".concat(it.paddingLeft, "
|
|
363
|
+
var marginAdjust = ["margin-top: ".concat(marginTopVal, "em"), "margin-bottom: ".concat(marginBottomVal, "em")];
|
|
364
|
+
return ("<div style=\"".concat(mergeStyles.apply(void 0, __spreadArray(__spreadArray([it.style], marginAdjust, false), ["padding-left: ".concat(it.paddingLeft, "em"), "flex-shrink: 0",
|
|
336
365
|
"width: 100%",
|
|
337
366
|
"flex-direction: row",
|
|
338
367
|
"display: flex"], false)), "\" data-list-item=\"true\">") +
|
|
339
368
|
"<text style=\"".concat(mergeStyles("flex-shrink: 0", "width: 100%", "line-height: 1", "display: flex", "flex-direction: row"), "\">") +
|
|
340
|
-
"<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "
|
|
369
|
+
"<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "padding-right: 0.5em"), "\">").concat(it.marker, "</div>") +
|
|
341
370
|
"<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "flex: 1"), "\">").concat(it.textContent, "</div>") +
|
|
342
371
|
"</text></div>");
|
|
343
372
|
})
|
|
@@ -349,7 +378,7 @@ var RichText_Refactor = /** @class */ (function () {
|
|
|
349
378
|
/** 将连续 <br> 替换为透明占位文字,确保 PixUI 换行 */
|
|
350
379
|
RichText_Refactor.replaceBrWithPlaceholder = function ($) {
|
|
351
380
|
$("br").each(function () {
|
|
352
|
-
$(this).replaceWith("<
|
|
381
|
+
$(this).replaceWith("<div style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 20px"), "\" class='pixui-richtext-br-placeholder'>1</div>"));
|
|
353
382
|
});
|
|
354
383
|
};
|
|
355
384
|
/** 处理 <a> 标签:转为 div、保留样式、记录链接 */
|
|
@@ -420,19 +449,27 @@ var RichText_Refactor = /** @class */ (function () {
|
|
|
420
449
|
u: "text-decoration: underline",
|
|
421
450
|
s: "text-decoration: line-through",
|
|
422
451
|
};
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
452
|
+
var hasLeftover = true;
|
|
453
|
+
while (hasLeftover) {
|
|
454
|
+
hasLeftover = false;
|
|
455
|
+
// 处理 strong / em / u / s
|
|
456
|
+
Object.entries(tagToStyle).forEach(function (_a) {
|
|
457
|
+
var tag = _a[0], style = _a[1];
|
|
458
|
+
$(tag).each(function () {
|
|
459
|
+
var html = $(this).html();
|
|
460
|
+
var oriStyle = $(this).attr("style") || "";
|
|
461
|
+
$(this).replaceWith("<text style=\"".concat(mergeStyles(oriStyle, style, "flex-shrink: 0"), "\">").concat(html, "</text>"));
|
|
462
|
+
hasLeftover = true;
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
// 处理 span
|
|
466
|
+
$("span").each(function () {
|
|
426
467
|
var html = $(this).html();
|
|
427
468
|
var oriStyle = $(this).attr("style") || "";
|
|
428
|
-
$(this).replaceWith("<text style=\"".concat(mergeStyles(oriStyle,
|
|
469
|
+
$(this).replaceWith("<text style=\"".concat(mergeStyles(oriStyle, "flex-shrink: 0"), "\">").concat(html, "</text>"));
|
|
470
|
+
hasLeftover = true;
|
|
429
471
|
});
|
|
430
|
-
}
|
|
431
|
-
$("span").each(function () {
|
|
432
|
-
var html = $(this).html();
|
|
433
|
-
var oriStyle = $(this).attr("style") || "";
|
|
434
|
-
$(this).replaceWith("<text style=\"".concat(mergeStyles(oriStyle, "flex-shrink: 0"), "\">").concat(html, "</text>"));
|
|
435
|
-
});
|
|
472
|
+
}
|
|
436
473
|
};
|
|
437
474
|
/** p → div */
|
|
438
475
|
RichText_Refactor.replacePTag = function ($) {
|
|
@@ -453,8 +490,11 @@ var RichText_Refactor = /** @class */ (function () {
|
|
|
453
490
|
self.linkNodes.push({ type: LinkNodeType.IMG, href: href, id: id });
|
|
454
491
|
}
|
|
455
492
|
$(this).attr("href", "");
|
|
456
|
-
$(this).attr("class"
|
|
457
|
-
|
|
493
|
+
var prevClass = $(this).attr("class") || "";
|
|
494
|
+
var newClasses = new Set(prevClass.split(/\s+/).filter(Boolean));
|
|
495
|
+
newClasses.add("PA_RichTextHref_ImgTag"); // 超链接专用标记(保持原有逻辑)
|
|
496
|
+
newClasses.add("PA_RichTextImgTag"); // 富文本图片通用标记
|
|
497
|
+
$(this).attr("class", Array.from(newClasses).join(" "));
|
|
458
498
|
});
|
|
459
499
|
};
|
|
460
500
|
/** 给指定标签补 flex-shrink:0 */
|
|
@@ -587,7 +627,7 @@ var RichText_Refactor = /** @class */ (function () {
|
|
|
587
627
|
});
|
|
588
628
|
if (maxLS > 0) {
|
|
589
629
|
var currentStyle = $text.attr("style") || "";
|
|
590
|
-
$text.attr("style", mergeStyles(currentStyle, "letter-spacing: ".concat(maxLS, "
|
|
630
|
+
$text.attr("style", mergeStyles(currentStyle, "letter-spacing: ".concat(maxLS, "em")));
|
|
591
631
|
}
|
|
592
632
|
});
|
|
593
633
|
};
|
|
@@ -620,7 +660,7 @@ var RichText_Refactor = /** @class */ (function () {
|
|
|
620
660
|
};
|
|
621
661
|
/** 补默认 heading 字体大小 */
|
|
622
662
|
RichText_Refactor.fixHeadingFontSize = function ($) {
|
|
623
|
-
var hRem = ["
|
|
663
|
+
var hRem = ["2em", "1.5em", "1.17em", "1em", "0.83em", "0.67em"];
|
|
624
664
|
["h1", "h2", "h3", "h4", "h5", "h6"].forEach(function (tag) {
|
|
625
665
|
$(tag).each(function () {
|
|
626
666
|
var idx = parseInt(tag.replace("h", "")) - 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixui-dev/pixui-richtext-helper",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "pixui richtext helper",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
"license": "ISC",
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^22.15.33",
|
|
23
|
-
"ts-node": "^10.9.2",
|
|
24
23
|
"typescript": "^5.8.3"
|
|
25
24
|
},
|
|
26
25
|
"dependencies": {
|
package/readme.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
安装
|
|
2
2
|
|
|
3
3
|
```bash
|
|
4
|
-
yarn add pixui-richtext-helper
|
|
4
|
+
yarn add @pixui-dev/pixui-richtext-helper
|
|
5
5
|
```
|
|
6
6
|
|
|
7
7
|
使用
|
|
8
8
|
|
|
9
9
|
```tsx
|
|
10
|
-
import { RichText } from "pixui-richtext-helper";
|
|
10
|
+
import { RichText } from "@pixui-dev/pixui-richtext-helper";
|
|
11
11
|
|
|
12
12
|
const richText; // 从管理端获取的富文本数据
|
|
13
13
|
const pixuiStyle = RichText.convertRichTextToPixuiStyle(richText);
|
|
@@ -26,3 +26,53 @@ componentDidMount() { // 在节点渲染后绑定点击事件
|
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
```
|
|
29
|
+
|
|
30
|
+
### 自定义节点样式
|
|
31
|
+
|
|
32
|
+
`convertRichTextToPixuiStyle` 在转换过程中会为特定节点增加 class 或 data-attribute,方便业务侧按需覆盖样式:
|
|
33
|
+
|
|
34
|
+
| 节点类型 | 标记 | 说明 |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| 超链接文本(`div`) | `.PA_RichTextHref_ATag` | 原 `a` 标签被替换后的容器,可通过样式控制颜色、下划线等效果 |
|
|
37
|
+
| 带超链接的图片(`img`) | `.PA_RichTextHref_ImgTag` | 图片本身存在跳转链接时添加 |
|
|
38
|
+
| 所有图片(`img`) | `.PA_RichTextImgTag` | 富文本中的通用图片标记 |
|
|
39
|
+
| 占位换行节点(`div`/`span`) | `.pixui-richtext-br-placeholder` | 连续 `<br>` 会被替换为透明字符占位,可调整段落之间的间距 |
|
|
40
|
+
| 列表条目容器(`div`) | `data-list-item="true"` | 每个列表项均带此属性,方便定制行距、缩进等 |
|
|
41
|
+
| 超链接节点(任何) | `id="PA_RichTextHrefId_xxx"` | 与 `bindLinkClickEvents` 配合,可用 `[id^="PA_RichTextHrefId_"]` 选择 |
|
|
42
|
+
|
|
43
|
+
示例:
|
|
44
|
+
|
|
45
|
+
```css
|
|
46
|
+
/* 修改超链接颜色及鼠标样式 */
|
|
47
|
+
.PA_RichTextHref_ATag {
|
|
48
|
+
color: #1e90ff;
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
text-decoration: underline;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* 统一图片最大宽度 */
|
|
54
|
+
.PA_RichTextImgTag {
|
|
55
|
+
max-width: 100%;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* 调整列表行距 */
|
|
59
|
+
[data-list-item="true"] {
|
|
60
|
+
line-height: 20px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* 自定义换行占位符大小 */
|
|
64
|
+
.pixui-richtext-br-placeholder {
|
|
65
|
+
font-size: 12px;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
版本更新记录
|
|
70
|
+
|
|
71
|
+
0.1.1-beta.5
|
|
72
|
+
1. 新增:防止重复转换
|
|
73
|
+
|
|
74
|
+
0.2.0
|
|
75
|
+
1. 组件默认样式长度单位修改为em
|
|
76
|
+
2. 图片节点统一补充PA_RichTextImgTag的class
|
|
77
|
+
3. 将列表的margin-left统一修改为padding-left
|
|
78
|
+
4. 修复某些情况下多余的span标签
|