@pixui-dev/pixui-richtext-helper 0.2.2 → 0.2.4
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/RichTextCore.d.ts +1 -1
- package/dist/richtext/RichTextCore.js +113 -43
- package/package.json +1 -1
- package/readme.md +10 -0
|
@@ -171,48 +171,71 @@ var RichTextCore = /** @class */ (function () {
|
|
|
171
171
|
*****************************************************/
|
|
172
172
|
/**
|
|
173
173
|
* 将 HTML 切分为基础段落片段。
|
|
174
|
-
*
|
|
174
|
+
* 递归拆分,任何层级的 <br> 都会被拆成独立段落
|
|
175
175
|
*/
|
|
176
176
|
RichTextCore.splitIntoSegments = function ($) {
|
|
177
177
|
var segments = [];
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
178
|
+
var wrapNode = function ($node, inner) {
|
|
179
|
+
var _a;
|
|
180
|
+
var tagName = $node.prop("tagName");
|
|
181
|
+
if (!tagName)
|
|
182
|
+
return inner; // root
|
|
183
|
+
var attribsObj = ((_a = $node.get(0)) === null || _a === void 0 ? void 0 : _a.attribs) || {};
|
|
184
|
+
var attribHtml = "";
|
|
185
|
+
for (var _i = 0, _b = Object.entries(attribsObj); _i < _b.length; _i++) {
|
|
186
|
+
var _c = _b[_i], k = _c[0], v = _c[1];
|
|
187
|
+
attribHtml += " ".concat(k, "=\"").concat(v, "\"");
|
|
185
188
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
return "<".concat(tagName.toLowerCase()).concat(attribHtml, ">").concat(inner, "</").concat(tagName.toLowerCase(), ">");
|
|
190
|
+
};
|
|
191
|
+
var dfs = function ($elem) {
|
|
192
|
+
var node = $elem.get(0);
|
|
193
|
+
if (!node)
|
|
194
|
+
return [];
|
|
195
|
+
// text / comment nodes直接返回
|
|
196
|
+
if (node.type === "text" || node.type === "comment") {
|
|
197
|
+
return [$.html(node)];
|
|
198
|
+
}
|
|
199
|
+
var tagName = ($elem.prop("tagName") || "").toLowerCase();
|
|
200
|
+
if (tagName === "br") {
|
|
201
|
+
return ["<br>"]; // 用占位标识,后续流程会处理
|
|
202
|
+
}
|
|
203
|
+
var buffer = [];
|
|
204
|
+
var segs = [];
|
|
205
|
+
var childrenArr = $elem.contents().toArray();
|
|
206
|
+
childrenArr.forEach(function (child) {
|
|
207
|
+
var childSegs = dfs($(child));
|
|
208
|
+
childSegs.forEach(function (seg) {
|
|
209
|
+
if (seg === "<br>") {
|
|
210
|
+
var htmlPart = buffer.join("");
|
|
211
|
+
if (htmlPart.trim()) {
|
|
212
|
+
segs.push(wrapNode($elem, htmlPart));
|
|
213
|
+
}
|
|
214
|
+
segs.push("<br>");
|
|
215
|
+
buffer = [];
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
buffer.push(seg);
|
|
193
219
|
}
|
|
194
220
|
});
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
segments.push(listHtml);
|
|
207
|
-
tempHtml_1 = tempHtml_1.substring(idx + listHtml.length);
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
if (tempHtml_1.trim())
|
|
211
|
-
segments.push(tempHtml_1);
|
|
212
|
-
}
|
|
221
|
+
});
|
|
222
|
+
// flush remaining
|
|
223
|
+
if (buffer.length > 0) {
|
|
224
|
+
var htmlPart = buffer.join("");
|
|
225
|
+
if (htmlPart.trim())
|
|
226
|
+
segs.push(wrapNode($elem, htmlPart));
|
|
227
|
+
}
|
|
228
|
+
// 如果此节点本身为列表 (<ol>/<ul>),不再拆分内部以保持原逻辑
|
|
229
|
+
if (tagName === "ol" || tagName === "ul") {
|
|
230
|
+
// 直接返回整块 html,不再分片
|
|
231
|
+
return [$.html(node)];
|
|
213
232
|
}
|
|
233
|
+
return segs;
|
|
234
|
+
};
|
|
235
|
+
var rootChildren = $("body").length > 0 ? $("body").children() : $.root().children();
|
|
236
|
+
rootChildren.each(function (_, el) {
|
|
237
|
+
segments.push.apply(segments, dfs($(el)));
|
|
214
238
|
});
|
|
215
|
-
// fallback:原样返回
|
|
216
239
|
if (segments.length === 0)
|
|
217
240
|
segments.push($.html());
|
|
218
241
|
return segments;
|
|
@@ -280,15 +303,45 @@ var RichTextCore = /** @class */ (function () {
|
|
|
280
303
|
if (!oriStyle)
|
|
281
304
|
return;
|
|
282
305
|
var styleObj = parseStyleString(oriStyle);
|
|
306
|
+
// 1) 处理 margin-left 单独声明
|
|
283
307
|
var marginLeftVal = styleObj["margin-left"];
|
|
284
308
|
if (marginLeftVal !== undefined) {
|
|
285
|
-
// 移除 margin-left
|
|
286
309
|
delete styleObj["margin-left"];
|
|
287
|
-
// 如果原本没有 padding-left,则直接设置;若已有,简单覆盖(遵循后写优先规则)
|
|
288
310
|
styleObj["padding-left"] = styleObj["padding-left"] || marginLeftVal;
|
|
289
|
-
// 写回合并后的样式
|
|
290
|
-
$(this).attr("style", serializeStyleObject(styleObj));
|
|
291
311
|
}
|
|
312
|
+
// 2) 处理 margin shorthand,提取 left
|
|
313
|
+
if (styleObj["margin"]) {
|
|
314
|
+
var marginStr = styleObj["margin"].trim();
|
|
315
|
+
var parts = marginStr.split(/\s+/);
|
|
316
|
+
var top_1 = "", right = "", bottom = "", left = "";
|
|
317
|
+
if (parts.length === 1) {
|
|
318
|
+
top_1 = right = bottom = left = parts[0];
|
|
319
|
+
}
|
|
320
|
+
else if (parts.length === 2) {
|
|
321
|
+
top_1 = bottom = parts[0];
|
|
322
|
+
right = left = parts[1];
|
|
323
|
+
}
|
|
324
|
+
else if (parts.length === 3) {
|
|
325
|
+
top_1 = parts[0];
|
|
326
|
+
right = left = parts[1];
|
|
327
|
+
bottom = parts[2];
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
top_1 = parts[0];
|
|
331
|
+
right = parts[1];
|
|
332
|
+
bottom = parts[2];
|
|
333
|
+
left = parts[3];
|
|
334
|
+
}
|
|
335
|
+
// 将 left 移到 padding-left
|
|
336
|
+
if (left) {
|
|
337
|
+
styleObj["padding-left"] = styleObj["padding-left"] || left;
|
|
338
|
+
}
|
|
339
|
+
// 重构 margin,去掉 left(用 0 占位保持布局)
|
|
340
|
+
var newMargin = "".concat(top_1, " ").concat(right, " ").concat(bottom, " 0");
|
|
341
|
+
styleObj["margin"] = newMargin.trim();
|
|
342
|
+
}
|
|
343
|
+
// 写回合并后的样式
|
|
344
|
+
$(this).attr("style", serializeStyleObject(styleObj));
|
|
292
345
|
});
|
|
293
346
|
};
|
|
294
347
|
RichTextCore.fixImgSizeUnit = function ($) {
|
|
@@ -442,6 +495,9 @@ var RichTextCore = /** @class */ (function () {
|
|
|
442
495
|
var listParent = $(this).closest("[data-list-item='true']");
|
|
443
496
|
if (listParent.length > 0)
|
|
444
497
|
return;
|
|
498
|
+
var brParent = $(this).closest(".pixui-richtext-br-placeholder");
|
|
499
|
+
if (brParent.length > 0)
|
|
500
|
+
return;
|
|
445
501
|
if (this.type === "text") {
|
|
446
502
|
var text = this.data.trim();
|
|
447
503
|
if (text.length > 0) {
|
|
@@ -621,15 +677,29 @@ var RichTextCore = /** @class */ (function () {
|
|
|
621
677
|
RichTextCore.adjustLineHeightAndLetterSpacing = function ($, config) {
|
|
622
678
|
$("text").each(function () {
|
|
623
679
|
var $text = $(this);
|
|
624
|
-
var
|
|
680
|
+
var maxLineHeightVal = 0;
|
|
681
|
+
var lineHeightUnit = "";
|
|
625
682
|
$text.children("div").each(function () {
|
|
626
|
-
var
|
|
627
|
-
|
|
683
|
+
var lhRaw = ($(this).css("line-height") || "").trim();
|
|
684
|
+
var match = lhRaw.match(/^([0-9.]+)([a-z%]*)$/i);
|
|
685
|
+
if (match) {
|
|
686
|
+
var val = parseFloat(match[1]);
|
|
687
|
+
if (!isNaN(val)) {
|
|
688
|
+
maxLineHeightVal = Math.max(maxLineHeightVal, val);
|
|
689
|
+
}
|
|
690
|
+
if (!lineHeightUnit && match[2])
|
|
691
|
+
lineHeightUnit = match[2];
|
|
692
|
+
}
|
|
693
|
+
if (lhRaw) {
|
|
694
|
+
var styleObj = parseStyleString($(this).attr("style") || "");
|
|
695
|
+
delete styleObj["line-height"];
|
|
696
|
+
$(this).attr("style", serializeStyleObject(styleObj));
|
|
697
|
+
}
|
|
628
698
|
});
|
|
629
699
|
var scale = (config === null || config === void 0 ? void 0 : config.lineHeightScale) || 1;
|
|
630
|
-
if (
|
|
700
|
+
if (maxLineHeightVal > 0) {
|
|
631
701
|
var currentStyle = $text.attr("style") || "";
|
|
632
|
-
$text.attr("style", mergeStyles(currentStyle, "line-height: ".concat(
|
|
702
|
+
$text.attr("style", mergeStyles(currentStyle, "line-height: ".concat(maxLineHeightVal * scale).concat(lineHeightUnit)));
|
|
633
703
|
}
|
|
634
704
|
});
|
|
635
705
|
$("text").each(function () {
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -27,6 +27,9 @@ componentDidMount() { // 在节点渲染后绑定点击事件
|
|
|
27
27
|
}
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
## 注意
|
|
31
|
+
组件在转换长富文本(节点数量较多,参考节点数量大于100)的时候可能会比较慢阻塞活动显示,如果需要转换很长的富文本,建议询问管理端是否可以提供预转换服务,或者活动在前置虚拟机中预先转换以后保存到本地,活动中直接使用转换以后的结果。
|
|
32
|
+
|
|
30
33
|
### 自定义节点样式
|
|
31
34
|
|
|
32
35
|
`convertRichTextToPixuiStyle` 在转换过程中会为特定节点增加 class 或 data-attribute,方便业务侧按需覆盖样式:
|
|
@@ -83,3 +86,10 @@ componentDidMount() { // 在节点渲染后绑定点击事件
|
|
|
83
86
|
0.2.2
|
|
84
87
|
1. 去掉某些节点默认的lineheight:1
|
|
85
88
|
2. 超链接改为直接在节点中记录数据,方便预加载流程在不同的环境调用convert和bind
|
|
89
|
+
|
|
90
|
+
0.2.3
|
|
91
|
+
1. line-height 的单位支持浮点数
|
|
92
|
+
|
|
93
|
+
0.2.4
|
|
94
|
+
1. 拆分margin中的margin-left转换为padding-left
|
|
95
|
+
2. 修复在嵌套节点中加br不会被拆成不同段落的问题
|