@pixui-dev/pixui-richtext-helper 0.2.10 → 0.2.12-beta.1
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.
- package/dist/RichText.d.ts +1 -1
- package/dist/RichText.js +1 -1
- package/dist/{richtext/RichTextCore.d.ts → RichTextCore.d.ts} +3 -1
- package/dist/{richtext/RichTextCore.js → RichTextCore.js} +290 -109
- package/dist/version.d.ts +1 -0
- package/dist/version.js +5 -0
- package/package.json +2 -2
- package/readme.md +26 -2
- package/dist/RichTextUtils.d.ts +0 -41
- package/dist/RichTextUtils.js +0 -533
package/dist/RichText.d.ts
CHANGED
package/dist/RichText.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LinkNodeType = exports.RichText = void 0;
|
|
4
|
-
var RichTextCore_1 = require("./
|
|
4
|
+
var RichTextCore_1 = require("./RichTextCore");
|
|
5
5
|
Object.defineProperty(exports, "LinkNodeType", { enumerable: true, get: function () { return RichTextCore_1.LinkNodeType; } });
|
|
6
6
|
/**
|
|
7
7
|
* 对外暴露的 RichText 组件。
|
|
@@ -57,6 +57,8 @@ export declare class RichTextCore {
|
|
|
57
57
|
private static convertAllPxToEm;
|
|
58
58
|
private static preprocess;
|
|
59
59
|
private static fixImgSizeUnit;
|
|
60
|
+
/** 合并 img 标签的 width 和 height 属性 */
|
|
61
|
+
private static consolidateImgSizeStyle;
|
|
60
62
|
/** 给 COS 图片自动追加 imageMogr2/thumbnail 参数 */
|
|
61
63
|
private static handleCosImageMogr2;
|
|
62
64
|
/** 列表处理(将 ol/ul/li 替换为 div 结构) */
|
|
@@ -83,7 +85,7 @@ export declare class RichTextCore {
|
|
|
83
85
|
private static handleTextIndent;
|
|
84
86
|
/** 处理 line-height / letter-spacing 属性 */
|
|
85
87
|
private static adjustLineHeightAndLetterSpacing;
|
|
86
|
-
/** 把 div 的 text-align 转移到子 text
|
|
88
|
+
/** 把 div 的 text-align 转移到子 text 上 */
|
|
87
89
|
private static transferTextAlign;
|
|
88
90
|
/** 删除空 text 节点 */
|
|
89
91
|
private static removeEmptyText;
|
|
@@ -15,23 +15,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) ||
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
})();
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
35
25
|
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
36
26
|
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
37
27
|
if (ar || !(i in from)) {
|
|
@@ -44,6 +34,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
44
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
35
|
exports.RichTextCore = exports.LinkNodeType = void 0;
|
|
46
36
|
var cheerio = __importStar(require("cheerio"));
|
|
37
|
+
var version_1 = require("./version");
|
|
47
38
|
/*****************************************************
|
|
48
39
|
* 类型、枚举定义
|
|
49
40
|
*****************************************************/
|
|
@@ -52,7 +43,12 @@ var LinkNodeType;
|
|
|
52
43
|
(function (LinkNodeType) {
|
|
53
44
|
LinkNodeType["IMG"] = "img";
|
|
54
45
|
LinkNodeType["DIV"] = "div";
|
|
55
|
-
})(LinkNodeType
|
|
46
|
+
})(LinkNodeType = exports.LinkNodeType || (exports.LinkNodeType = {}));
|
|
47
|
+
var textNodeStyle = [
|
|
48
|
+
{ key: "direction", isNumber: false },
|
|
49
|
+
{ key: "line-height", isNumber: true },
|
|
50
|
+
{ key: "letter-spacing", isNumber: true },
|
|
51
|
+
];
|
|
56
52
|
/*****************************************************
|
|
57
53
|
* 工具函数
|
|
58
54
|
*****************************************************/
|
|
@@ -134,15 +130,66 @@ var mergeStyles = function () {
|
|
|
134
130
|
return serializeStyleObject(mergedStyleObj);
|
|
135
131
|
};
|
|
136
132
|
var CLASS_STYLE_MAP = {
|
|
137
|
-
"ql-direction-rtl": function (old) { return mergeStyles("direction: rtl;"
|
|
138
|
-
"ql-align-right": function (old) { return mergeStyles("text-align: right;"
|
|
133
|
+
"ql-direction-rtl": function (old) { return mergeStyles(old, "direction: rtl;"); },
|
|
134
|
+
"ql-align-right": function (old) { return mergeStyles(old, "text-align: right;"); },
|
|
135
|
+
};
|
|
136
|
+
// data-list value → 需追加的 class 名
|
|
137
|
+
var DATA_LIST_CLASS_MAP = {
|
|
138
|
+
bullet: "ql-indent-0",
|
|
139
139
|
};
|
|
140
140
|
var _loop_1 = function (i) {
|
|
141
141
|
var cls = "ql-indent-".concat(i);
|
|
142
|
-
|
|
142
|
+
//如果之前加了ql-indent-x,取max
|
|
143
|
+
// 注意:此 mapper 可能在同一节点被多次调用(当存在多个 ql-indent-* 类时)
|
|
144
|
+
// 只有当当前 cls 对应的缩进值是该节点所有 ql-indent-* 中的最大值时才真正处理样式。
|
|
145
|
+
CLASS_STYLE_MAP[cls] = function (old, $elem) {
|
|
146
|
+
// 1) 计算该元素所有 ql-indent-* 中的最大值
|
|
147
|
+
var clsArr = ($elem.attr("class") || "").split(/\s+/).filter(Boolean);
|
|
148
|
+
var isRtl = clsArr.includes("ql-direction-rtl");
|
|
149
|
+
var maxIndentNum = 0;
|
|
150
|
+
clsArr.forEach(function (c) {
|
|
151
|
+
var m = c.match(/^ql-indent-(\d+)$/);
|
|
152
|
+
if (m) {
|
|
153
|
+
var n = parseInt(m[1]);
|
|
154
|
+
if (!isNaN(n) && n > maxIndentNum)
|
|
155
|
+
maxIndentNum = n;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
// 当前 cls 对应的缩进级别
|
|
159
|
+
var currentIndentMatch = cls.match(/^ql-indent-(\d+)$/);
|
|
160
|
+
var currentIndentNum = currentIndentMatch ? parseInt(currentIndentMatch[1]) : 0;
|
|
161
|
+
// 当前处理的不是最大缩进级别
|
|
162
|
+
if (currentIndentNum !== maxIndentNum) {
|
|
163
|
+
return old;
|
|
164
|
+
}
|
|
165
|
+
// H5 基准:0级=1.5em,之后每级递增3em → padding = 1.5em + 3em * level
|
|
166
|
+
var desiredPadEm = 1.5 + (maxIndentNum + 1) * 3;
|
|
167
|
+
var styleObj = parseStyleString(old);
|
|
168
|
+
// 依据方向选择缩进属性键
|
|
169
|
+
var paddingKey = isRtl ? "padding-right" : "padding-left";
|
|
170
|
+
// 已有 padding-left/right,需比较取更大者
|
|
171
|
+
var existPadEm = -1;
|
|
172
|
+
var existPad = styleObj[paddingKey];
|
|
173
|
+
if (existPad) {
|
|
174
|
+
var m = existPad.match(/^([0-9.]+)(px|em)?$/i);
|
|
175
|
+
if (m) {
|
|
176
|
+
var num = parseFloat(m[1]);
|
|
177
|
+
var unit = (m[2] || "px").toLowerCase();
|
|
178
|
+
if (!isNaN(num)) {
|
|
179
|
+
existPadEm = unit === "em" ? num : num / 16;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
var finalPadEm = existPadEm > desiredPadEm ? existPadEm : desiredPadEm;
|
|
184
|
+
styleObj[paddingKey] = "".concat(finalPadEm, "em");
|
|
185
|
+
// 设置 list-style-type
|
|
186
|
+
var markersList = ["disc", "circle", "square", "empty square"];
|
|
187
|
+
styleObj["list-style-type"] = markersList[maxIndentNum % markersList.length];
|
|
188
|
+
return mergeStyles(old, serializeStyleObject(styleObj));
|
|
189
|
+
};
|
|
143
190
|
};
|
|
144
191
|
// 动态生成段落缩进 ql-indent-1 ~ ql-indent-10
|
|
145
|
-
for (var i =
|
|
192
|
+
for (var i = 0; i <= 10; i++) {
|
|
146
193
|
_loop_1(i);
|
|
147
194
|
}
|
|
148
195
|
/*****************************************************
|
|
@@ -163,14 +210,17 @@ var RichTextCore = /** @class */ (function () {
|
|
|
163
210
|
// 重置全局状态
|
|
164
211
|
RichTextCore.linkNodes = [];
|
|
165
212
|
RichTextCore.hrefIdCnt = 0;
|
|
166
|
-
|
|
167
|
-
|
|
213
|
+
// href 属性先统一做 URI 编码
|
|
214
|
+
var preEncodedStr = str.replace(/href=(['"])(.*?)\1/g, function (_m, quote, hrefVal) {
|
|
215
|
+
return "href=".concat(quote).concat(encodeURIComponent(hrefVal)).concat(quote);
|
|
168
216
|
});
|
|
169
217
|
var $1 = cheerio.load(preEncodedStr, null, false);
|
|
170
218
|
//检查html,如果有text节点,说明是转换过的,直接返回
|
|
171
219
|
if ($1("text").length > 0) {
|
|
172
220
|
return str;
|
|
173
221
|
}
|
|
222
|
+
var oriNodeCount = $1("*").length;
|
|
223
|
+
console.log("pixui-richHelper转换---- 版本:" + " " + version_1.LIB_VERSION + " " + " 原始节点数:" + oriNodeCount);
|
|
174
224
|
// ---------- 第 1 步:段落分割(基础实现:根节点切分) ----------
|
|
175
225
|
var segments = RichTextCore.splitIntoSegments($1);
|
|
176
226
|
// ---------- 第 2/3 步:遍历 + 展平 ----------
|
|
@@ -337,6 +387,7 @@ var RichTextCore = /** @class */ (function () {
|
|
|
337
387
|
this.preprocess($);
|
|
338
388
|
this.fixImgSizeUnit($);
|
|
339
389
|
this.handleCosImageMogr2($, config);
|
|
390
|
+
this.consolidateImgSizeStyle($);
|
|
340
391
|
this.handleLists($, (config === null || config === void 0 ? void 0 : config.lineHeightScale) || 1);
|
|
341
392
|
this.replaceBrWithPlaceholder($);
|
|
342
393
|
this.handleAnchorTag($);
|
|
@@ -386,24 +437,39 @@ var RichTextCore = /** @class */ (function () {
|
|
|
386
437
|
// 根据映射表统一处理 class → style
|
|
387
438
|
$("*").each(function () {
|
|
388
439
|
var _this = this;
|
|
389
|
-
|
|
390
|
-
|
|
440
|
+
// 1) 先处理 data-list,可能追加 class
|
|
441
|
+
var dataList = $(this).attr("data-list");
|
|
442
|
+
if (dataList) {
|
|
443
|
+
var clsToAdd = DATA_LIST_CLASS_MAP[dataList];
|
|
444
|
+
if (clsToAdd) {
|
|
445
|
+
$(this).addClass(clsToAdd);
|
|
446
|
+
$(this).removeAttr("data-list");
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
// 2) 再处理 class → style 映射(包含刚刚追加的 class)
|
|
450
|
+
var classStrNow = $(this).attr("class") || "";
|
|
451
|
+
if (!classStrNow)
|
|
391
452
|
return;
|
|
392
|
-
var classArr =
|
|
453
|
+
var classArr = classStrNow.split(/\s+/).filter(Boolean);
|
|
393
454
|
if (classArr.length === 0)
|
|
394
455
|
return;
|
|
395
456
|
var styleStr = $(this).attr("style") || "";
|
|
396
457
|
var changed = false;
|
|
458
|
+
// 先累计样式,再统一移除命中的类,避免在 mapper 内部读取 class 时出现中途被修改导致的误判
|
|
459
|
+
var removedClasses = [];
|
|
397
460
|
classArr.forEach(function (cls) {
|
|
398
461
|
var mapper = CLASS_STYLE_MAP[cls];
|
|
399
462
|
if (mapper) {
|
|
400
463
|
styleStr = mapper(styleStr, $(_this));
|
|
401
|
-
|
|
464
|
+
removedClasses.push(cls);
|
|
402
465
|
changed = true;
|
|
403
466
|
}
|
|
404
467
|
});
|
|
405
468
|
if (changed) {
|
|
406
469
|
$(this).attr("style", styleStr);
|
|
470
|
+
if (removedClasses.length > 0) {
|
|
471
|
+
$(this).removeClass(removedClasses.join(" "));
|
|
472
|
+
}
|
|
407
473
|
}
|
|
408
474
|
});
|
|
409
475
|
// 在所有标题标签后插入换行 <br>
|
|
@@ -414,7 +480,7 @@ var RichTextCore = /** @class */ (function () {
|
|
|
414
480
|
$(this).after("<br>");
|
|
415
481
|
}
|
|
416
482
|
});
|
|
417
|
-
// 将所有的margin-left转换为padding-left
|
|
483
|
+
// 将所有的margin-left,margin-right转换为padding-left,padding-right
|
|
418
484
|
$("*").each(function () {
|
|
419
485
|
var oriStyle = $(this).attr("style") || "";
|
|
420
486
|
if (!oriStyle)
|
|
@@ -422,9 +488,12 @@ var RichTextCore = /** @class */ (function () {
|
|
|
422
488
|
var styleObj = parseStyleString(oriStyle);
|
|
423
489
|
// 1) 处理 margin-left 单独声明
|
|
424
490
|
var marginLeftVal = styleObj["margin-left"];
|
|
425
|
-
|
|
491
|
+
var marginRightVal = styleObj["margin-right"];
|
|
492
|
+
if (marginLeftVal !== undefined || marginRightVal !== undefined) {
|
|
426
493
|
delete styleObj["margin-left"];
|
|
494
|
+
delete styleObj["margin-right"];
|
|
427
495
|
styleObj["padding-left"] = styleObj["padding-left"] || marginLeftVal;
|
|
496
|
+
styleObj["padding-right"] = styleObj["padding-right"] || marginRightVal;
|
|
428
497
|
}
|
|
429
498
|
// 2) 处理 margin shorthand,提取 left
|
|
430
499
|
if (styleObj["margin"]) {
|
|
@@ -449,10 +518,9 @@ var RichTextCore = /** @class */ (function () {
|
|
|
449
518
|
bottom = parts[2];
|
|
450
519
|
left = parts[3];
|
|
451
520
|
}
|
|
452
|
-
// 将 left 移到 padding-left
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
}
|
|
521
|
+
// 将 left,right 移到 padding-left,padding-right
|
|
522
|
+
left && (styleObj["padding-left"] = styleObj["padding-left"] || left);
|
|
523
|
+
right && (styleObj["padding-right"] = styleObj["padding-right"] || right);
|
|
456
524
|
// 重构 margin,去掉 left(用 0 占位保持布局)
|
|
457
525
|
var newMargin = "".concat(top_1, " ").concat(right, " ").concat(bottom, " 0");
|
|
458
526
|
styleObj["margin"] = newMargin.trim();
|
|
@@ -473,6 +541,31 @@ var RichTextCore = /** @class */ (function () {
|
|
|
473
541
|
}
|
|
474
542
|
});
|
|
475
543
|
};
|
|
544
|
+
/** 合并 img 标签的 width 和 height 属性 */
|
|
545
|
+
RichTextCore.consolidateImgSizeStyle = function ($) {
|
|
546
|
+
$("img").each(function () {
|
|
547
|
+
var _this = this;
|
|
548
|
+
var styleObj = parseStyleString($(this).attr("style") || "");
|
|
549
|
+
var handleAttr = function (attrName) {
|
|
550
|
+
var attrVal = $(_this).attr(attrName);
|
|
551
|
+
if (!attrVal)
|
|
552
|
+
return;
|
|
553
|
+
var valStr = attrVal.trim();
|
|
554
|
+
if (/^\d+$/.test(valStr)) {
|
|
555
|
+
// 数字补 px
|
|
556
|
+
valStr = "".concat(valStr, "px");
|
|
557
|
+
}
|
|
558
|
+
// 若 style 中已存在同键,则以 style 内优先
|
|
559
|
+
if (!styleObj[attrName]) {
|
|
560
|
+
styleObj[attrName] = valStr;
|
|
561
|
+
}
|
|
562
|
+
$(_this).removeAttr(attrName);
|
|
563
|
+
};
|
|
564
|
+
handleAttr("width");
|
|
565
|
+
handleAttr("height");
|
|
566
|
+
$(this).attr("style", serializeStyleObject(styleObj));
|
|
567
|
+
});
|
|
568
|
+
};
|
|
476
569
|
/** 给 COS 图片自动追加 imageMogr2/thumbnail 参数 */
|
|
477
570
|
RichTextCore.handleCosImageMogr2 = function ($, config) {
|
|
478
571
|
var maxW = config === null || config === void 0 ? void 0 : config.addCosUrlImageMogr2_w;
|
|
@@ -546,17 +639,40 @@ var RichTextCore = /** @class */ (function () {
|
|
|
546
639
|
if (isOrdered) {
|
|
547
640
|
orderIndex = $child.prevAll("li").length + 1;
|
|
548
641
|
}
|
|
549
|
-
var marker = isOrdered ? "".concat(orderIndex, ".") : "•";
|
|
550
642
|
var paddingLeft = currentLevel * 2; // 每层缩进 2em
|
|
551
643
|
var $liClone = $child.clone();
|
|
552
644
|
$liClone.find("ol, ul").remove();
|
|
553
|
-
var textContent = $liClone.
|
|
645
|
+
var textContent = $liClone.html() || "";
|
|
554
646
|
var style = $child.attr("style") || "";
|
|
647
|
+
// 解析 style 判断 list-style-type
|
|
648
|
+
var styleObj = parseStyleString(style);
|
|
649
|
+
var listStyle = (styleObj["list-style-type"] || "").trim().toLowerCase();
|
|
650
|
+
// 查找有没有继承下来的属性
|
|
651
|
+
if (!listStyle) {
|
|
652
|
+
var parentStyleObj = parseStyleString($container.attr("style") || "");
|
|
653
|
+
listStyle = (parentStyleObj["list-style-type"] || "").trim().toLowerCase();
|
|
654
|
+
}
|
|
655
|
+
// 根据 list-style-type 与列表类型决定 marker
|
|
656
|
+
var BULLET_MARKER_MAP = {
|
|
657
|
+
disc: "●",
|
|
658
|
+
circle: "○",
|
|
659
|
+
square: "■",
|
|
660
|
+
"empty square": "□",
|
|
661
|
+
none: "",
|
|
662
|
+
};
|
|
663
|
+
var finalMarker = "";
|
|
664
|
+
if (listStyle && Object.prototype.hasOwnProperty.call(BULLET_MARKER_MAP, listStyle)) {
|
|
665
|
+
// 即使映射值为空字符串(none)也应使用
|
|
666
|
+
finalMarker = BULLET_MARKER_MAP[listStyle];
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
finalMarker = isOrdered ? "".concat(orderIndex, ".") : "•";
|
|
670
|
+
}
|
|
555
671
|
items.push({
|
|
556
672
|
level: currentLevel,
|
|
557
673
|
isOrdered: isOrdered,
|
|
558
674
|
orderIndex: orderIndex,
|
|
559
|
-
marker:
|
|
675
|
+
marker: finalMarker,
|
|
560
676
|
paddingLeft: paddingLeft,
|
|
561
677
|
textContent: textContent,
|
|
562
678
|
style: style,
|
|
@@ -598,14 +714,38 @@ var RichTextCore = /** @class */ (function () {
|
|
|
598
714
|
var marginTopVal = idx === 0 ? 1 * lineHeightScale : 0.5 * lineHeightScale;
|
|
599
715
|
var marginBottomVal = idx === items.length - 1 ? 1 * lineHeightScale : 0.5 * lineHeightScale;
|
|
600
716
|
var marginAdjust = ["margin-top: ".concat(marginTopVal, "em"), "margin-bottom: ".concat(marginBottomVal, "em")];
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
717
|
+
// 解析 direction 与缩进,按 H5 悬挂缩进思路改为三列布局
|
|
718
|
+
var styleObj = parseStyleString(it.style || "");
|
|
719
|
+
var isRtl = (styleObj["direction"] || "").trim().toLowerCase() === "rtl";
|
|
720
|
+
var paddingKey = isRtl ? "padding-right" : "padding-left";
|
|
721
|
+
var padVal = styleObj[paddingKey];
|
|
722
|
+
var markerEm = 1.2;
|
|
723
|
+
var markerPx = markerEm * BASE_FONT_SIZE; // 约 19.2px
|
|
724
|
+
var indentPx = it.level * 40; // 回退:嵌套层级
|
|
725
|
+
if (padVal) {
|
|
726
|
+
var m = padVal.match(/^([0-9.]+)(px|em)?$/i);
|
|
727
|
+
if (m) {
|
|
728
|
+
var num = parseFloat(m[1]);
|
|
729
|
+
var unit = (m[2] || "px").toLowerCase();
|
|
730
|
+
if (!isNaN(num)) {
|
|
731
|
+
var padPx = unit === "em" ? num * BASE_FONT_SIZE : num;
|
|
732
|
+
indentPx = Math.max(padPx - markerPx, 0);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
// 容器样式:移除 padding 与 list-style-type,设置 flex 布局并按方向翻转
|
|
737
|
+
delete styleObj["padding-left"];
|
|
738
|
+
delete styleObj["padding-right"];
|
|
739
|
+
delete styleObj["list-style-type"]; // 由三列布局承担
|
|
740
|
+
var rowDir = isRtl ? "row-reverse" : "row";
|
|
741
|
+
var outerStyle = mergeStyles.apply(void 0, __spreadArray(__spreadArray([serializeStyleObject(styleObj)], marginAdjust, false), ["flex-shrink: 0", "width: 100%", "display: flex", "flex-direction: ".concat(rowDir)], false));
|
|
742
|
+
// 三列:缩进列 + 标号列 + 文本列
|
|
743
|
+
var indentCol = "<key style=\"width:".concat(indentPx, "px;flex-shrink:0\"></key>");
|
|
744
|
+
var markerCol = it.marker
|
|
745
|
+
? "<key style=\"".concat(mergeStyles("flex-shrink: 0", "width: ".concat(markerEm, "em"), isRtl ? "padding-left: 0.3em" : "padding-right: 0.3em"), "\">").concat(it.marker, "</key>")
|
|
746
|
+
: "";
|
|
747
|
+
var textCol = "<text style=\"".concat(mergeStyles("flex: 1", "min-width: 0", "word-break: break-word"), "\">").concat(it.textContent, "</text>");
|
|
748
|
+
return "<div style=\"".concat(outerStyle, "\" data-list-item=\"true\">").concat(indentCol).concat(markerCol).concat(textCol, "</div>");
|
|
609
749
|
})
|
|
610
750
|
.join("");
|
|
611
751
|
placeholder.after(html);
|
|
@@ -676,7 +816,7 @@ var RichTextCore = /** @class */ (function () {
|
|
|
676
816
|
if (this.type === "text") {
|
|
677
817
|
var text = this.data.trim();
|
|
678
818
|
if (text.length > 0) {
|
|
679
|
-
$(this).replaceWith("<text style=\"".concat(mergeStyles("
|
|
819
|
+
$(this).replaceWith("<text style=\"".concat(mergeStyles("flex-shrink: 0", "flex-direction: row", "word-break: break-word"), "\">").concat(text, "</text>"));
|
|
680
820
|
}
|
|
681
821
|
}
|
|
682
822
|
});
|
|
@@ -699,7 +839,13 @@ var RichTextCore = /** @class */ (function () {
|
|
|
699
839
|
$(tag).each(function () {
|
|
700
840
|
var html = $(this).html();
|
|
701
841
|
var oriStyle = $(this).attr("style") || "";
|
|
702
|
-
$(this).
|
|
842
|
+
var isInListTextColumn = $(this).closest("[data-list-item='true']").length > 0 && $(this).closest("text").length > 0;
|
|
843
|
+
if (isInListTextColumn) {
|
|
844
|
+
$(this).replaceWith("<key style=\"".concat(mergeStyles(oriStyle, style, "flex-shrink: 0", "word-break: break-word"), "\">").concat(html, "</key>"));
|
|
845
|
+
}
|
|
846
|
+
else {
|
|
847
|
+
$(this).replaceWith("<text style=\"".concat(mergeStyles(oriStyle, style, "flex-shrink: 0", "word-break: break-word"), "\">").concat(html, "</text>"));
|
|
848
|
+
}
|
|
703
849
|
hasLeftover = true;
|
|
704
850
|
});
|
|
705
851
|
});
|
|
@@ -707,7 +853,13 @@ var RichTextCore = /** @class */ (function () {
|
|
|
707
853
|
$("span").each(function () {
|
|
708
854
|
var html = $(this).html();
|
|
709
855
|
var oriStyle = $(this).attr("style") || "";
|
|
710
|
-
$(this).
|
|
856
|
+
var isInListTextColumn = $(this).closest("[data-list-item='true']").length > 0 && $(this).closest("text").length > 0;
|
|
857
|
+
if (isInListTextColumn) {
|
|
858
|
+
$(this).replaceWith("<key style=\"".concat(mergeStyles(oriStyle, "flex-shrink: 0", "word-break: break-word"), "\">").concat(html, "</key>"));
|
|
859
|
+
}
|
|
860
|
+
else {
|
|
861
|
+
$(this).replaceWith("<text style=\"".concat(mergeStyles(oriStyle, "flex-shrink: 0", "word-break: break-word"), "\">").concat(html, "</text>"));
|
|
862
|
+
}
|
|
711
863
|
hasLeftover = true;
|
|
712
864
|
});
|
|
713
865
|
}
|
|
@@ -797,19 +949,29 @@ var RichTextCore = /** @class */ (function () {
|
|
|
797
949
|
var inListItem = $(this).closest("[data-list-item='true']").length > 0;
|
|
798
950
|
if (inListItem)
|
|
799
951
|
return;
|
|
800
|
-
var text = $(this).html();
|
|
801
952
|
var style = $(this).attr("style") || "";
|
|
802
|
-
|
|
803
|
-
var
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
953
|
+
var keyStyle = mergeStyles(style, "flex-shrink: 0");
|
|
954
|
+
var fragments = [];
|
|
955
|
+
$(this)
|
|
956
|
+
.contents()
|
|
957
|
+
.each(function () {
|
|
958
|
+
// 纯文本 → 包进 key
|
|
959
|
+
if (this.type === "text") {
|
|
960
|
+
var txt = this.data;
|
|
961
|
+
if (txt && txt.trim()) {
|
|
962
|
+
fragments.push("<key style=\"".concat(keyStyle, "\">").concat(txt, "</key>"));
|
|
963
|
+
}
|
|
964
|
+
else {
|
|
965
|
+
// 保留空白字符
|
|
966
|
+
fragments.push(txt);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
else {
|
|
970
|
+
// 其它节点(img、link等)保持原样
|
|
971
|
+
fragments.push($.html(this));
|
|
972
|
+
}
|
|
973
|
+
});
|
|
974
|
+
$(this).replaceWith(fragments.join(""));
|
|
813
975
|
});
|
|
814
976
|
var tagHtml = $(node).html() || "";
|
|
815
977
|
var tagStyle = $(node).attr("style") || "";
|
|
@@ -825,7 +987,7 @@ var RichTextCore = /** @class */ (function () {
|
|
|
825
987
|
}
|
|
826
988
|
}
|
|
827
989
|
// 保证外层tag的style不合并子div的style
|
|
828
|
-
$(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, ">"));
|
|
990
|
+
$(node).replaceWith("<".concat(tag, " style=\"").concat(mergeStyles(tagStyle, "flex-direction: row"), "\"").concat(idAttr).concat(customAttrs, "><text style=\"").concat(mergeStyles("flex-shrink: 0", "width: 100%", "word-break: break-word"), "\">").concat(tagHtml, "</text></").concat(tag, ">"));
|
|
829
991
|
}
|
|
830
992
|
});
|
|
831
993
|
};
|
|
@@ -836,7 +998,7 @@ var RichTextCore = /** @class */ (function () {
|
|
|
836
998
|
if (textIndent) {
|
|
837
999
|
var repeatCnt = parseInt(textIndent);
|
|
838
1000
|
if (repeatCnt > 0) {
|
|
839
|
-
var spacer = "<div style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size:
|
|
1001
|
+
var spacer = "<div style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 1em"), "\" class='pixui-richtext-indent-placeholder'>").concat("一".repeat(repeatCnt), "</div>");
|
|
840
1002
|
var textChild = $(this).children("text").first();
|
|
841
1003
|
if (textChild.length > 0) {
|
|
842
1004
|
var first = textChild.children().first();
|
|
@@ -851,64 +1013,83 @@ var RichTextCore = /** @class */ (function () {
|
|
|
851
1013
|
};
|
|
852
1014
|
/** 处理 line-height / letter-spacing 属性 */
|
|
853
1015
|
RichTextCore.adjustLineHeightAndLetterSpacing = function ($, config) {
|
|
1016
|
+
var stylesToHandle = textNodeStyle;
|
|
854
1017
|
$("text").each(function () {
|
|
855
1018
|
var $text = $(this);
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
var
|
|
860
|
-
var
|
|
861
|
-
|
|
862
|
-
var
|
|
863
|
-
|
|
864
|
-
|
|
1019
|
+
stylesToHandle.forEach(function (_a) {
|
|
1020
|
+
var key = _a.key, isNumber = _a.isNumber;
|
|
1021
|
+
var aggregatedNumber = -Infinity; // for max comparison
|
|
1022
|
+
var unit = "";
|
|
1023
|
+
var chosenValue;
|
|
1024
|
+
$text.children("div, key").each(function () {
|
|
1025
|
+
var styleObj = parseStyleString($(this).attr("style") || "");
|
|
1026
|
+
var valRaw = styleObj[key];
|
|
1027
|
+
if (valRaw !== undefined) {
|
|
1028
|
+
if (isNumber) {
|
|
1029
|
+
var match = valRaw.trim().match(/^([0-9.]+)([a-z%]*)$/i);
|
|
1030
|
+
if (match) {
|
|
1031
|
+
var numVal = parseFloat(match[1]);
|
|
1032
|
+
if (!isNaN(numVal) && numVal > aggregatedNumber) {
|
|
1033
|
+
aggregatedNumber = numVal;
|
|
1034
|
+
unit = match[2] || unit;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
else {
|
|
1039
|
+
if (chosenValue === undefined) {
|
|
1040
|
+
chosenValue = valRaw;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
// 移除子节点上该样式
|
|
1044
|
+
delete styleObj[key];
|
|
1045
|
+
$(this).attr("style", serializeStyleObject(styleObj));
|
|
865
1046
|
}
|
|
866
|
-
|
|
867
|
-
|
|
1047
|
+
});
|
|
1048
|
+
// 将聚合结果写入父 text
|
|
1049
|
+
var currentStyle = $text.attr("style") || "";
|
|
1050
|
+
if (isNumber && aggregatedNumber !== -Infinity) {
|
|
1051
|
+
var finalVal = aggregatedNumber;
|
|
1052
|
+
// line-height 需要乘以 scale
|
|
1053
|
+
if (key === "line-height") {
|
|
1054
|
+
var scale = (config === null || config === void 0 ? void 0 : config.lineHeightScale) || 1;
|
|
1055
|
+
finalVal = aggregatedNumber * scale;
|
|
1056
|
+
}
|
|
1057
|
+
var finalUnit = unit || (key === "letter-spacing" ? "em" : "");
|
|
1058
|
+
$text.attr("style", mergeStyles(currentStyle, "".concat(key, ": ").concat(finalVal).concat(finalUnit)));
|
|
868
1059
|
}
|
|
869
|
-
if (
|
|
870
|
-
|
|
871
|
-
delete styleObj["line-height"];
|
|
872
|
-
$(this).attr("style", serializeStyleObject(styleObj));
|
|
1060
|
+
else if (!isNumber && chosenValue !== undefined) {
|
|
1061
|
+
$text.attr("style", mergeStyles(currentStyle, "".concat(key, ": ").concat(chosenValue)));
|
|
873
1062
|
}
|
|
874
1063
|
});
|
|
875
|
-
var scale = (config === null || config === void 0 ? void 0 : config.lineHeightScale) || 1;
|
|
876
|
-
if (maxLineHeightVal > 0) {
|
|
877
|
-
var currentStyle = $text.attr("style") || "";
|
|
878
|
-
$text.attr("style", mergeStyles(currentStyle, "line-height: ".concat(maxLineHeightVal * scale).concat(lineHeightUnit)));
|
|
879
|
-
}
|
|
880
|
-
});
|
|
881
|
-
$("text").each(function () {
|
|
882
|
-
var $text = $(this);
|
|
883
|
-
var maxLS = 0;
|
|
884
|
-
$text.children("div").each(function () {
|
|
885
|
-
var ls = $(this).css("letter-spacing") || "0";
|
|
886
|
-
var lsNum = parseInt(ls);
|
|
887
|
-
maxLS = Math.max(maxLS, lsNum);
|
|
888
|
-
});
|
|
889
|
-
if (maxLS > 0) {
|
|
890
|
-
var currentStyle = $text.attr("style") || "";
|
|
891
|
-
$text.attr("style", mergeStyles(currentStyle, "letter-spacing: ".concat(maxLS, "em")));
|
|
892
|
-
}
|
|
893
1064
|
});
|
|
894
1065
|
};
|
|
895
|
-
/** 把 div 的 text-align 转移到子 text
|
|
1066
|
+
/** 把 div 的 text-align 转移到子 text 上 */
|
|
896
1067
|
RichTextCore.transferTextAlign = function ($) {
|
|
897
1068
|
$("div").each(function () {
|
|
898
|
-
var
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
1069
|
+
var styleObj = parseStyleString($(this).attr("style") || "");
|
|
1070
|
+
var keysToTransfer = ["text-align", "direction"];
|
|
1071
|
+
var transferVals = {};
|
|
1072
|
+
keysToTransfer.forEach(function (k) {
|
|
1073
|
+
if (styleObj[k] !== undefined) {
|
|
1074
|
+
transferVals[k] = styleObj[k];
|
|
1075
|
+
delete styleObj[k];
|
|
1076
|
+
}
|
|
1077
|
+
});
|
|
1078
|
+
if (Object.keys(transferVals).length === 0)
|
|
1079
|
+
return;
|
|
1080
|
+
// 写回 div 剩余 style
|
|
1081
|
+
$(this).attr("style", serializeStyleObject(styleObj));
|
|
1082
|
+
// 传递到子 text
|
|
1083
|
+
$(this)
|
|
1084
|
+
.children("text")
|
|
1085
|
+
.each(function () {
|
|
1086
|
+
var current = $(this).attr("style") || "";
|
|
1087
|
+
Object.entries(transferVals).forEach(function (_a) {
|
|
1088
|
+
var k = _a[0], v = _a[1];
|
|
1089
|
+
current = mergeStyles(current, "".concat(k, ": ").concat(v));
|
|
905
1090
|
});
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
var styleObj = parseStyleString(currentStyle);
|
|
909
|
-
delete styleObj["text-align"];
|
|
910
|
-
$(this).attr("style", serializeStyleObject(styleObj));
|
|
911
|
-
}
|
|
1091
|
+
$(this).attr("style", current);
|
|
1092
|
+
});
|
|
912
1093
|
});
|
|
913
1094
|
};
|
|
914
1095
|
/** 删除空 text 节点 */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const LIB_VERSION = "0.2.11";
|
package/dist/version.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixui-dev/pixui-richtext-helper",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12-beta.1",
|
|
4
4
|
"description": "pixui richtext helper",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -25,4 +25,4 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"cheerio": "1.0.0-rc.10"
|
|
27
27
|
}
|
|
28
|
-
}
|
|
28
|
+
}
|
package/readme.md
CHANGED
|
@@ -28,8 +28,11 @@ componentDidMount() { // 在节点渲染后绑定点击事件
|
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
## 注意
|
|
31
|
+
|
|
31
32
|
组件在转换长富文本(节点数量较多,参考节点数量大于100)的时候可能会比较慢阻塞活动显示,如果需要转换很长的富文本,建议询问管理端是否可以提供预转换服务,或者活动在前置虚拟机中预先转换以后保存到本地,活动中直接使用转换以后的结果。
|
|
32
33
|
|
|
34
|
+
组件当前只适配并测试过由floriazhang提供的管理端富文本编辑工具输出的富文本内容,除此之外的富文本内容不保证可以完全正确解析显示。
|
|
35
|
+
|
|
33
36
|
### 自定义节点样式
|
|
34
37
|
|
|
35
38
|
`convertRichTextToPixuiStyle` 在转换过程中会为特定节点增加 class 或 data-attribute,方便业务侧按需覆盖样式:
|
|
@@ -77,42 +80,63 @@ componentDidMount() { // 在节点渲染后绑定点击事件
|
|
|
77
80
|
|
|
78
81
|
版本更新记录
|
|
79
82
|
|
|
80
|
-
0.1.1-beta.5
|
|
83
|
+
0.1.1-beta.5
|
|
84
|
+
|
|
81
85
|
1. 新增:防止重复转换
|
|
82
86
|
|
|
83
87
|
0.2.0
|
|
88
|
+
|
|
84
89
|
1. 组件默认样式长度单位修改为em
|
|
85
90
|
2. 图片节点统一补充PA_RichTextImgTag的class
|
|
86
91
|
3. 将列表的margin-left统一修改为padding-left
|
|
87
92
|
4. 修复某些情况下多余的span标签
|
|
88
93
|
|
|
89
94
|
0.2.1
|
|
95
|
+
|
|
90
96
|
1. 组件代码结构调整
|
|
91
97
|
|
|
92
98
|
0.2.2
|
|
99
|
+
|
|
93
100
|
1. 去掉某些节点默认的lineheight:1
|
|
94
101
|
2. 超链接改为直接在节点中记录数据,方便预加载流程在不同的环境调用convert和bind
|
|
95
102
|
|
|
96
103
|
0.2.3
|
|
104
|
+
|
|
97
105
|
1. line-height 的单位支持浮点数
|
|
98
106
|
|
|
99
107
|
0.2.4
|
|
108
|
+
|
|
100
109
|
1. 拆分margin中的margin-left转换为padding-left
|
|
101
110
|
2. 修复在嵌套节点中加br不会被拆成不同段落的问题
|
|
102
111
|
|
|
103
112
|
0.2.5
|
|
113
|
+
|
|
104
114
|
1. 修复img节点丢失的问题
|
|
105
115
|
|
|
106
116
|
0.2.6
|
|
117
|
+
|
|
107
118
|
1. 修复在超链接中添加转义符导致跳转信息不完整的问题
|
|
108
119
|
2. 修复带超链接的img节点中出现一些多余的属性
|
|
109
120
|
3. 增加将富文本中的px单位的属性统一替换为em单位的选项
|
|
110
121
|
|
|
111
122
|
0.2.7
|
|
123
|
+
|
|
112
124
|
1. 增加addCosUrlImageMogr2_w参数
|
|
113
125
|
|
|
114
126
|
0.2.8
|
|
127
|
+
|
|
115
128
|
1. 补充首行缩进占位符的class
|
|
116
129
|
|
|
117
130
|
0.2.9
|
|
118
|
-
|
|
131
|
+
|
|
132
|
+
1. 增加对class ql-direction-rtl -> style="direction: rtl;"的转换支持
|
|
133
|
+
|
|
134
|
+
0.2.10
|
|
135
|
+
|
|
136
|
+
1. 增加对class ql-align-right -> style="text-align: right;"的转换支持
|
|
137
|
+
|
|
138
|
+
0.2.11(f1dcaccc3b6c72b82b6b76cea654d50d5ba7ccad)
|
|
139
|
+
|
|
140
|
+
1. 修复图片原始尺寸和样式尺寸不一样,某些pixui版本尺寸不对的问题
|
|
141
|
+
2. 修复direction属性不生效的问题
|
|
142
|
+
3. text节点下的文本节点从div标签改为pixui推荐的key标签
|
package/dist/RichTextUtils.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
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
|
-
*/
|
|
7
|
-
export declare namespace RichText {
|
|
8
|
-
/**
|
|
9
|
-
* 富文本中的超链接节点类型
|
|
10
|
-
*/
|
|
11
|
-
enum LinkNodeType {
|
|
12
|
-
IMG = "img",
|
|
13
|
-
DIV = "div"
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* 富文本超链接点击回调参数
|
|
17
|
-
*/
|
|
18
|
-
interface LinkClickParams {
|
|
19
|
-
/** 节点类型 */
|
|
20
|
-
type: LinkNodeType;
|
|
21
|
-
/** 原始href内容 */
|
|
22
|
-
href: string;
|
|
23
|
-
/** 节点id */
|
|
24
|
-
id: string;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* 富文本组件,将富文本转换成pixui的innerHtml可以使用的格式
|
|
28
|
-
* @param str 管理端下发的富文本
|
|
29
|
-
* @param config 配置
|
|
30
|
-
* @param config.lineHeightScale 行高缩放
|
|
31
|
-
* @returns pixui的innerHtml可以使用的格式
|
|
32
|
-
*/
|
|
33
|
-
const convertRichTextToPixuiStyle: (str: string, config?: {
|
|
34
|
-
lineHeightScale?: number;
|
|
35
|
-
}) => string;
|
|
36
|
-
/**
|
|
37
|
-
* 为富文本中的链接节点绑定点击事件
|
|
38
|
-
* @param linkClickHandler 点击事件回调函数
|
|
39
|
-
*/
|
|
40
|
-
const bindLinkClickEvents: (linkClickHandler: (params: LinkClickParams) => void) => void;
|
|
41
|
-
}
|
package/dist/RichTextUtils.js
DELETED
|
@@ -1,533 +0,0 @@
|
|
|
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 = void 0;
|
|
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
|
-
*/
|
|
53
|
-
var RichText;
|
|
54
|
-
(function (RichText) {
|
|
55
|
-
/**
|
|
56
|
-
* 富文本中的超链接节点类型
|
|
57
|
-
*/
|
|
58
|
-
var LinkNodeType;
|
|
59
|
-
(function (LinkNodeType) {
|
|
60
|
-
LinkNodeType["IMG"] = "img";
|
|
61
|
-
LinkNodeType["DIV"] = "div";
|
|
62
|
-
})(LinkNodeType = RichText.LinkNodeType || (RichText.LinkNodeType = {}));
|
|
63
|
-
// 存储需要绑定点击事件的节点信息
|
|
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
|
-
};
|
|
80
|
-
/**
|
|
81
|
-
* 富文本组件,将富文本转换成pixui的innerHtml可以使用的格式
|
|
82
|
-
* @param str 管理端下发的富文本
|
|
83
|
-
* @param config 配置
|
|
84
|
-
* @param config.lineHeightScale 行高缩放
|
|
85
|
-
* @returns pixui的innerHtml可以使用的格式
|
|
86
|
-
*/
|
|
87
|
-
RichText.convertRichTextToPixuiStyle = function (str, config) {
|
|
88
|
-
//将富文本内容转换为一个 段落div/h -> text -> 文字样式div/img -> 文本 的结构,保证pixui可以正常显示
|
|
89
|
-
var $ = cheerio.load(str, null, false);
|
|
90
|
-
var hrefIdCnt = 0;
|
|
91
|
-
linkNodes = []; // 重置链接节点信息
|
|
92
|
-
// 节点处理
|
|
93
|
-
{
|
|
94
|
-
var _loop_1 = function (i) {
|
|
95
|
-
var indent = "ql-indent-".concat(i);
|
|
96
|
-
var extStyle = "padding-left: ".concat(i * 2, "rem");
|
|
97
|
-
$(".".concat(indent)).each(function () {
|
|
98
|
-
var oriStyle = $(this).attr("style") || "";
|
|
99
|
-
$(this).attr("style", mergeStyles(oriStyle, extStyle));
|
|
100
|
-
$(this).removeClass(indent);
|
|
101
|
-
});
|
|
102
|
-
};
|
|
103
|
-
//合并ql-indent class到style中
|
|
104
|
-
for (var i = 1; i <= 10; i++) {
|
|
105
|
-
_loop_1(i);
|
|
106
|
-
}
|
|
107
|
-
$("img").each(function () {
|
|
108
|
-
//给纯数字的width,height添加px单位
|
|
109
|
-
var width = $(this).attr("width");
|
|
110
|
-
var height = $(this).attr("height");
|
|
111
|
-
if (width && width + "" == parseInt(width) + "") {
|
|
112
|
-
$(this).attr("width", "".concat(width, "px"));
|
|
113
|
-
}
|
|
114
|
-
if (height && height + "" == parseInt(height) + "") {
|
|
115
|
-
$(this).attr("height", "".concat(height, "px"));
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
// 处理列表项
|
|
119
|
-
{
|
|
120
|
-
/**
|
|
121
|
-
* pixui不支持ol,ul,li节点,将其递归转换成div并处理嵌套层级
|
|
122
|
-
* 记录每个列表容器的位置,在原位置插入转换后的结构
|
|
123
|
-
*/
|
|
124
|
-
// 第一步:找到所有顶层列表容器并标记其位置
|
|
125
|
-
var topLevelLists_1 = [];
|
|
126
|
-
// 递归收集列表项的函数
|
|
127
|
-
var collectListItems_1 = function ($container, currentLevel) {
|
|
128
|
-
if (currentLevel === void 0) { currentLevel = 0; }
|
|
129
|
-
var items = [];
|
|
130
|
-
$container.children().each(function () {
|
|
131
|
-
var $child = $(this);
|
|
132
|
-
if ($child.is("li")) {
|
|
133
|
-
var isOrdered = $child.parent().is("ol");
|
|
134
|
-
var orderIndex = 1;
|
|
135
|
-
if (isOrdered) {
|
|
136
|
-
// 计算在同一个ol中的序号
|
|
137
|
-
orderIndex = $child.prevAll("li").length + 1;
|
|
138
|
-
}
|
|
139
|
-
// 生成marker
|
|
140
|
-
var marker = isOrdered ? "".concat(orderIndex, ".") : "•";
|
|
141
|
-
// 计算缩进
|
|
142
|
-
var paddingLeft = currentLevel * 2; // 每层缩进2rem
|
|
143
|
-
// 获取li的直接文本内容,不包括嵌套的子列表
|
|
144
|
-
var $liClone = $child.clone();
|
|
145
|
-
$liClone.find("ol, ul").remove();
|
|
146
|
-
var textContent = $liClone.text().trim() || "";
|
|
147
|
-
var style = $child.attr("style") || "";
|
|
148
|
-
items.push({
|
|
149
|
-
level: currentLevel,
|
|
150
|
-
isOrdered: isOrdered,
|
|
151
|
-
orderIndex: orderIndex,
|
|
152
|
-
marker: marker,
|
|
153
|
-
paddingLeft: paddingLeft,
|
|
154
|
-
textContent: textContent,
|
|
155
|
-
style: style,
|
|
156
|
-
});
|
|
157
|
-
// 递归处理li内的子列表(只处理真正嵌套在当前li内的列表)
|
|
158
|
-
$child.find("ol, ul").each(function () {
|
|
159
|
-
// 确保这个列表是当前li的直接子元素,而不是更深层的
|
|
160
|
-
var $nestedList = $(this);
|
|
161
|
-
if ($nestedList.parent().closest("li")[0] === $child[0]) {
|
|
162
|
-
var childItems = collectListItems_1($nestedList, currentLevel + 1);
|
|
163
|
-
items.push.apply(items, childItems);
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
return items;
|
|
169
|
-
};
|
|
170
|
-
// 找到所有顶层列表(直接在body下或其他容器中的ol/ul)
|
|
171
|
-
$("ol, ul").each(function () {
|
|
172
|
-
var $list = $(this);
|
|
173
|
-
// 检查是否为顶层列表(不在其他列表内部)
|
|
174
|
-
if ($list.parents("ol, ul").length === 0) {
|
|
175
|
-
// 创建占位符标记原始位置
|
|
176
|
-
var placeholder = $("<div data-list-placeholder=\"true\"></div>");
|
|
177
|
-
$list.before(placeholder);
|
|
178
|
-
// 收集该列表的所有项目
|
|
179
|
-
var items = collectListItems_1($list, 1);
|
|
180
|
-
topLevelLists_1.push({
|
|
181
|
-
element: $list,
|
|
182
|
-
placeholder: placeholder,
|
|
183
|
-
items: items,
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
// 第二步:移除所有ol/ul/li结构
|
|
188
|
-
$("ol, ul, li").remove();
|
|
189
|
-
// 第三步:在每个占位符位置插入转换后的列表项
|
|
190
|
-
topLevelLists_1.forEach(function (listInfo) {
|
|
191
|
-
var placeholder = listInfo.placeholder, items = listInfo.items;
|
|
192
|
-
// 为该列表生成HTML
|
|
193
|
-
var listHtml = items
|
|
194
|
-
.map(function (item) {
|
|
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>") +
|
|
199
|
-
"</text>" +
|
|
200
|
-
"</div>");
|
|
201
|
-
})
|
|
202
|
-
.join("");
|
|
203
|
-
// 在占位符位置插入列表HTML
|
|
204
|
-
placeholder.after(listHtml);
|
|
205
|
-
// 移除占位符
|
|
206
|
-
placeholder.remove();
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
//pixui连续的br不生效,用透明文字占位
|
|
210
|
-
$("br").each(function () {
|
|
211
|
-
$(this).replaceWith("<span style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 20px"), "\" class='pixui-richtext-br-placeholder'>1</span>"));
|
|
212
|
-
});
|
|
213
|
-
//将 a 标签替换为简单div,处理 href,预处理内部样式标签并合并样式
|
|
214
|
-
$("a").each(function (i, ele) {
|
|
215
|
-
var id = "PA_RichTextHrefId_".concat(hrefIdCnt++);
|
|
216
|
-
var href = $(this).attr("href");
|
|
217
|
-
var originalStyle = $(this).attr("style") || "";
|
|
218
|
-
var textContent = $(this).text(); // 获取纯文本内容
|
|
219
|
-
// 收集内部样式标签的样式
|
|
220
|
-
var mergedStyles = [];
|
|
221
|
-
if ($(this).find("strong").length > 0) {
|
|
222
|
-
mergedStyles.push("font-weight: bold;");
|
|
223
|
-
}
|
|
224
|
-
if ($(this).find("em").length > 0) {
|
|
225
|
-
mergedStyles.push("font-style: italic;");
|
|
226
|
-
}
|
|
227
|
-
if ($(this).find("u").length > 0) {
|
|
228
|
-
mergedStyles.push("text-decoration: underline;");
|
|
229
|
-
}
|
|
230
|
-
if ($(this).find("s").length > 0) {
|
|
231
|
-
mergedStyles.push("text-decoration: line-through;");
|
|
232
|
-
}
|
|
233
|
-
// 收集内部span等标签的style属性
|
|
234
|
-
$(this)
|
|
235
|
-
.find("strong, em, u, s, span")
|
|
236
|
-
.each(function () {
|
|
237
|
-
var innerStyle = $(this).attr("style");
|
|
238
|
-
if (innerStyle) {
|
|
239
|
-
mergedStyles.push(innerStyle);
|
|
240
|
-
}
|
|
241
|
-
});
|
|
242
|
-
// 合并所有样式
|
|
243
|
-
var finalStyle = originalStyle;
|
|
244
|
-
if (mergedStyles.length > 0) {
|
|
245
|
-
finalStyle = mergeStyles.apply(void 0, __spreadArray([originalStyle], mergedStyles, false));
|
|
246
|
-
}
|
|
247
|
-
if (href) {
|
|
248
|
-
linkNodes.push({
|
|
249
|
-
type: LinkNodeType.DIV,
|
|
250
|
-
href: href,
|
|
251
|
-
id: id,
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
// 转换为简单div,样式已合并
|
|
255
|
-
$(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\" class=\"PA_RichTextHref_ATag\" >").concat(textContent, "</div>"));
|
|
256
|
-
});
|
|
257
|
-
//找到所有的文字节点,外层包裹text标签
|
|
258
|
-
$("*").each(function () {
|
|
259
|
-
// 跳过链接节点内部的文本处理
|
|
260
|
-
var nodeId = $(this).attr("id") || "";
|
|
261
|
-
if (nodeId.startsWith("PA_RichTextHrefId_")) {
|
|
262
|
-
return; // 跳过链接节点,不处理其内部文本
|
|
263
|
-
}
|
|
264
|
-
// 跳过列表项,因为已经处理完成
|
|
265
|
-
var isListItem = $(this).attr("data-list-item") === "true";
|
|
266
|
-
if (isListItem) {
|
|
267
|
-
return; // 跳过列表项
|
|
268
|
-
}
|
|
269
|
-
$(this)
|
|
270
|
-
.contents()
|
|
271
|
-
.each(function () {
|
|
272
|
-
// 检查当前文本节点是否在链接节点内部
|
|
273
|
-
var linkParent = $(this).closest("[id^='PA_RichTextHrefId_']");
|
|
274
|
-
if (linkParent.length > 0) {
|
|
275
|
-
return; // 跳过链接节点内部的文本
|
|
276
|
-
}
|
|
277
|
-
// 检查当前文本节点是否在列表项内部
|
|
278
|
-
var listParent = $(this).closest("[data-list-item='true']");
|
|
279
|
-
if (listParent.length > 0) {
|
|
280
|
-
return; // 跳过列表项内部的文本
|
|
281
|
-
}
|
|
282
|
-
if (this.type === "text") {
|
|
283
|
-
var text = this.data.trim();
|
|
284
|
-
if (text.length > 0) {
|
|
285
|
-
$(this).replaceWith("<text style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "flex-direction: row"), "\">").concat(text, "</text>"));
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
//将strong em u s标签替换成text标签
|
|
291
|
-
$("strong").each(function () {
|
|
292
|
-
var html = $(this).html();
|
|
293
|
-
var style = $(this).attr("style") || "";
|
|
294
|
-
$(this).replaceWith("<text style=\"".concat(mergeStyles(style, "font-weight: bold", "flex-shrink: 0"), "\">").concat(html, "</text>"));
|
|
295
|
-
});
|
|
296
|
-
$("em").each(function () {
|
|
297
|
-
var html = $(this).html();
|
|
298
|
-
var style = $(this).attr("style") || "";
|
|
299
|
-
$(this).replaceWith("<text style=\"".concat(mergeStyles(style, "font-style: italic", "flex-shrink: 0"), "\">").concat(html, "</text>"));
|
|
300
|
-
});
|
|
301
|
-
$("u").each(function () {
|
|
302
|
-
var html = $(this).html();
|
|
303
|
-
var style = $(this).attr("style") || "";
|
|
304
|
-
$(this).replaceWith("<text style=\"".concat(mergeStyles(style, "text-decoration: underline", "flex-shrink: 0"), "\">").concat(html, "</text>"));
|
|
305
|
-
});
|
|
306
|
-
$("s").each(function () {
|
|
307
|
-
var html = $(this).html();
|
|
308
|
-
var style = $(this).attr("style") || "";
|
|
309
|
-
$(this).replaceWith("<text style=\"".concat(mergeStyles(style, "text-decoration: line-through", "flex-shrink: 0"), "\">").concat(html, "</text>"));
|
|
310
|
-
});
|
|
311
|
-
$("span").each(function () {
|
|
312
|
-
var html = $(this).html();
|
|
313
|
-
var style = $(this).attr("style") || "";
|
|
314
|
-
$(this).replaceWith("<text style=\"".concat(mergeStyles(style, "flex-shrink: 0"), "\">").concat(html, "</text>"));
|
|
315
|
-
});
|
|
316
|
-
//p换成div
|
|
317
|
-
$("p").each(function () {
|
|
318
|
-
var html = $(this).html();
|
|
319
|
-
var style = $(this).attr("style") || "";
|
|
320
|
-
$(this).replaceWith("<div style=\"".concat(mergeStyles(style, "flex-shrink: 0", "width:100%"), "\">").concat(html, "</div>"));
|
|
321
|
-
});
|
|
322
|
-
//处理 img 上的 href
|
|
323
|
-
$("img").each(function (i, ele) {
|
|
324
|
-
var id = "PA_RichTextHrefId_".concat(hrefIdCnt++);
|
|
325
|
-
$(this).attr("id", id);
|
|
326
|
-
var href = $(this).attr("href");
|
|
327
|
-
if (href) {
|
|
328
|
-
linkNodes.push({
|
|
329
|
-
type: LinkNodeType.IMG,
|
|
330
|
-
href: href,
|
|
331
|
-
id: id,
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
$(this).attr("href", "");
|
|
335
|
-
$(this).attr("class", "PA_RichTextHref_ImgTag");
|
|
336
|
-
$(this).attr("data-href", href);
|
|
337
|
-
});
|
|
338
|
-
//补充 flex-shrink: 0
|
|
339
|
-
["h1", "h2", "h3", "h4", "h5", "h6", "a", "img", "div"].forEach(function (tag) {
|
|
340
|
-
$("".concat(tag)).each(function () {
|
|
341
|
-
// 跳过列表项内部的节点
|
|
342
|
-
var isListItem = $(this).attr("data-list-item") === "true";
|
|
343
|
-
var inListItem = $(this).closest("[data-list-item='true']").length > 0;
|
|
344
|
-
if (!isListItem && !inListItem) {
|
|
345
|
-
var style = $(this).attr("style") || "";
|
|
346
|
-
$(this).attr("style", mergeStyles(style, "flex-shrink: 0"));
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
// 层级处理
|
|
352
|
-
{
|
|
353
|
-
//一行中的文字配置了不同样式的时候文字节点会嵌套,导致pixui样式异常。将嵌套的text节点摊平,同时合并内外的style
|
|
354
|
-
while ($("text > text").length > 0) {
|
|
355
|
-
$("text").each(function () {
|
|
356
|
-
var $this = $(this);
|
|
357
|
-
var parentStyle = $this.attr("style") || "";
|
|
358
|
-
$this.children("text").each(function () {
|
|
359
|
-
var $child = $(this);
|
|
360
|
-
var childStyle = $child.attr("style") || "";
|
|
361
|
-
// 合并style属性,将父节点的style附加到子节点上
|
|
362
|
-
var mergedStyle = mergeStyles(parentStyle, childStyle);
|
|
363
|
-
// 更新子元素的style属性
|
|
364
|
-
$child.attr("style", mergedStyle);
|
|
365
|
-
});
|
|
366
|
-
//去掉父节点
|
|
367
|
-
if ($this.children("text").length > 0) {
|
|
368
|
-
$this.replaceWith($this.html() || "");
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
//!!一行的text节点会并列在父节点下无法换行,将其修改为div节点,外层再包一个text节点
|
|
373
|
-
// 会变成<段落div><text><单独一种样式div>文字
|
|
374
|
-
var nodearr_1 = [];
|
|
375
|
-
["h1", "h2", "h3", "h4", "h5", "h6", "div"].map(function (tag) {
|
|
376
|
-
// text的父节点
|
|
377
|
-
$("".concat(tag)).each(function () {
|
|
378
|
-
var nodeId = $(this).attr("id") || "";
|
|
379
|
-
var isListItem = $(this).attr("data-list-item") === "true";
|
|
380
|
-
var inListItem = $(this).closest("[data-list-item='true']").length > 0;
|
|
381
|
-
// 跳过链接节点、列表项本身以及列表项内部的节点
|
|
382
|
-
if (!nodeId.startsWith("PA_RichTextHrefId_") && !isListItem && !inListItem) {
|
|
383
|
-
nodearr_1.push(this);
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
});
|
|
387
|
-
nodearr_1.forEach(function (node) {
|
|
388
|
-
var tag = $(node).prop("tagName");
|
|
389
|
-
var nodeId = $(node).attr("id") || ""; // 保存节点ID
|
|
390
|
-
// 处理text子节点,将text内容转换为div
|
|
391
|
-
$(node)
|
|
392
|
-
.children("text")
|
|
393
|
-
.each(function () {
|
|
394
|
-
// 检查是否在列表项内部
|
|
395
|
-
var inListItem = $(this).closest("[data-list-item='true']").length > 0;
|
|
396
|
-
if (inListItem) {
|
|
397
|
-
return; // 跳过列表项内部的text节点
|
|
398
|
-
}
|
|
399
|
-
var text = $(this).html();
|
|
400
|
-
var style = $(this).attr("style") || "";
|
|
401
|
-
$(this).replaceWith("<div style=\"".concat(mergeStyles(style, "word-break: break-word", "flex-shrink: 0", "flex-direction: row"), "\">").concat(text, "</div>"));
|
|
402
|
-
});
|
|
403
|
-
var taghtml = $(node).html() || "";
|
|
404
|
-
var tagstyle = $(node).attr("style") || "";
|
|
405
|
-
// 构建标准结构 - 为所有节点构建div-text-div-文字结构
|
|
406
|
-
if (taghtml && taghtml.trim()) {
|
|
407
|
-
var idAttr = nodeId ? " id=\"".concat(nodeId, "\"") : "";
|
|
408
|
-
// 保留所有自定义属性
|
|
409
|
-
var customAttrs = "";
|
|
410
|
-
var attributes = $(node).get(0).attribs || {};
|
|
411
|
-
for (var _i = 0, _a = Object.entries(attributes); _i < _a.length; _i++) {
|
|
412
|
-
var _b = _a[_i], key = _b[0], value = _b[1];
|
|
413
|
-
if (key !== "style" && key !== "id") {
|
|
414
|
-
customAttrs += " ".concat(key, "=\"").concat(value, "\"");
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
//自己的子节点外套一个text,自己不变
|
|
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, ">"));
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
//text-indent 处理首行缩进
|
|
422
|
-
$("*").each(function () {
|
|
423
|
-
var textIndent = $(this).css("text-indent");
|
|
424
|
-
if (textIndent) {
|
|
425
|
-
/**
|
|
426
|
-
* 创建透明字符占位,样式会加在段落的p节点上,将透明字符添加到text节点下保证换行以后状态正确。
|
|
427
|
-
* 状态为<div style=text-indent:xxx><text><透明字符节点/><div style=样式>文字</div></text></div>
|
|
428
|
-
* 属性是几 em 就加几个字符
|
|
429
|
-
* */
|
|
430
|
-
var $spacerText = $("<div style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 16px"), "\">").concat("一".repeat(parseInt(textIndent)), "</div>"));
|
|
431
|
-
// 寻找子节点中的text节点
|
|
432
|
-
var textChild = $(this).children("text").first();
|
|
433
|
-
if (textChild.length > 0) {
|
|
434
|
-
var firstTextChild = textChild.children().first();
|
|
435
|
-
if (firstTextChild.length > 0) {
|
|
436
|
-
// 如果text节点有子节点,在第一个子节点前插入
|
|
437
|
-
firstTextChild.before($spacerText);
|
|
438
|
-
}
|
|
439
|
-
else {
|
|
440
|
-
// 如果text节点没有子节点,直接添加
|
|
441
|
-
textChild.append($spacerText);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
});
|
|
446
|
-
//pixui 的 line-height只在 text 上生效,所以将所有的 div 上的 line-height 转移到父 text 上
|
|
447
|
-
//当前的结构为 div > text > div,只处理一层就行
|
|
448
|
-
//遍历每个 text 的子 div,将其中最大的 line-height 转移到 text 上
|
|
449
|
-
$("text").each(function () {
|
|
450
|
-
var $text = $(this);
|
|
451
|
-
var maxLineHeight = 0;
|
|
452
|
-
$text.children("div").each(function () {
|
|
453
|
-
var lineHeight = parseInt($(this).css("line-height") || "1");
|
|
454
|
-
maxLineHeight = Math.max(maxLineHeight, lineHeight);
|
|
455
|
-
});
|
|
456
|
-
var lineHeightScale = (config === null || config === void 0 ? void 0 : config.lineHeightScale) || 1;
|
|
457
|
-
// pixui 中的实际显示的距离可能与网页中实际显示的距离差距较大
|
|
458
|
-
if (maxLineHeight > 0) {
|
|
459
|
-
$text.css("line-height", maxLineHeight * lineHeightScale + "");
|
|
460
|
-
}
|
|
461
|
-
});
|
|
462
|
-
//将div中的letter-spacing转移到text上
|
|
463
|
-
$("text").each(function () {
|
|
464
|
-
var $text = $(this);
|
|
465
|
-
var maxLetterSpacing = 0;
|
|
466
|
-
$text.children("div").each(function () {
|
|
467
|
-
var letterSpacing = $(this).css("letter-spacing") || "0";
|
|
468
|
-
var letterSpacingNum = parseInt(letterSpacing);
|
|
469
|
-
maxLetterSpacing = Math.max(maxLetterSpacing, letterSpacingNum);
|
|
470
|
-
});
|
|
471
|
-
if (maxLetterSpacing > 0) {
|
|
472
|
-
$text.css("letter-spacing", maxLetterSpacing + "rem");
|
|
473
|
-
}
|
|
474
|
-
});
|
|
475
|
-
//将div中的text-align转移到text子节点上
|
|
476
|
-
$("div").each(function () {
|
|
477
|
-
var textAlign = $(this).css("text-align") || "";
|
|
478
|
-
textAlign != "" &&
|
|
479
|
-
$(this)
|
|
480
|
-
.children("text")
|
|
481
|
-
.each(function () {
|
|
482
|
-
$(this).css("text-align", textAlign);
|
|
483
|
-
});
|
|
484
|
-
$(this).css("text-align", "");
|
|
485
|
-
});
|
|
486
|
-
//去除空的text节点
|
|
487
|
-
$("text").each(function () {
|
|
488
|
-
var t = $(this).html() || "";
|
|
489
|
-
if (t.trim() == "") {
|
|
490
|
-
$(this).remove();
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
var hTagRem_1 = ["2rem", "1.5rem", "1.17rem", "1rem", "0.83rem", "0.67rem"];
|
|
494
|
-
["h1", "h2", "h3", "h4", "h5", "h6"].map(function (tag) {
|
|
495
|
-
return $("".concat(tag)).each(function () {
|
|
496
|
-
var idx = parseInt(tag.replace("h", "")) - 1;
|
|
497
|
-
var style = $(this).attr("style") || "";
|
|
498
|
-
//如果没有fontsize
|
|
499
|
-
if (!style.includes("font-size")) {
|
|
500
|
-
$(this).attr("style", mergeStyles(style, "font-size:".concat(hTagRem_1[idx])));
|
|
501
|
-
}
|
|
502
|
-
});
|
|
503
|
-
});
|
|
504
|
-
//一些标签会没有结束/,手动补充
|
|
505
|
-
//手动替换nbsp
|
|
506
|
-
var res = $.html();
|
|
507
|
-
res = res.replaceAll(/<img([^>]+)>/g, "<img$1 />").replaceAll(/ /g, " ");
|
|
508
|
-
console.log(res);
|
|
509
|
-
return res;
|
|
510
|
-
}
|
|
511
|
-
};
|
|
512
|
-
/**
|
|
513
|
-
* 为富文本中的链接节点绑定点击事件
|
|
514
|
-
* @param linkClickHandler 点击事件回调函数
|
|
515
|
-
*/
|
|
516
|
-
RichText.bindLinkClickEvents = function (linkClickHandler) {
|
|
517
|
-
linkNodes.forEach(function (nodeInfo) {
|
|
518
|
-
var element = document.getElementById(nodeInfo.id);
|
|
519
|
-
if (element) {
|
|
520
|
-
element.onclick = function (e) {
|
|
521
|
-
e.stopPropagation();
|
|
522
|
-
e.preventDefault();
|
|
523
|
-
linkClickHandler({
|
|
524
|
-
type: nodeInfo.type,
|
|
525
|
-
href: nodeInfo.href,
|
|
526
|
-
id: nodeInfo.id,
|
|
527
|
-
});
|
|
528
|
-
return false;
|
|
529
|
-
};
|
|
530
|
-
}
|
|
531
|
-
});
|
|
532
|
-
};
|
|
533
|
-
})(RichText || (exports.RichText = RichText = {}));
|