@pixui-dev/pixui-richtext-helper 0.2.12 → 0.2.14
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/RichTextCore.d.ts +0 -18
- package/dist/RichTextCore.js +45 -110
- package/package.json +1 -1
- package/readme.md +1 -1
package/dist/RichTextCore.d.ts
CHANGED
|
@@ -12,20 +12,6 @@ export interface LinkClickParams {
|
|
|
12
12
|
href: string;
|
|
13
13
|
id: string;
|
|
14
14
|
}
|
|
15
|
-
/** 单个阶段耗时 */
|
|
16
|
-
export interface ConvertDebugPhase {
|
|
17
|
-
name: string;
|
|
18
|
-
ms: number;
|
|
19
|
-
}
|
|
20
|
-
/** 转换调试统计 */
|
|
21
|
-
export interface ConvertDebugStats {
|
|
22
|
-
totalMs: number;
|
|
23
|
-
highLevel: ConvertDebugPhase[];
|
|
24
|
-
detail: ConvertDebugPhase[];
|
|
25
|
-
segmentsCount: number;
|
|
26
|
-
version: string;
|
|
27
|
-
timestamp: number;
|
|
28
|
-
}
|
|
29
15
|
/*****************************************************
|
|
30
16
|
* RichTextCore 主类
|
|
31
17
|
*****************************************************/
|
|
@@ -34,8 +20,6 @@ export declare class RichTextCore {
|
|
|
34
20
|
private static hrefIdCnt;
|
|
35
21
|
/** 所有链接节点统一的 class 名 */
|
|
36
22
|
private static readonly LINK_NODE_CLASS;
|
|
37
|
-
/** 上一次转换的调试统计(仅在 debug 模式下填充) */
|
|
38
|
-
static lastDebugStats: ConvertDebugStats | undefined;
|
|
39
23
|
/**
|
|
40
24
|
* 富文本转换为 PixUI innerHTML 兼容格式
|
|
41
25
|
* @param str 原始富文本 HTML
|
|
@@ -48,8 +32,6 @@ export declare class RichTextCore {
|
|
|
48
32
|
lineHeightScale?: number;
|
|
49
33
|
convertPxToEm?: boolean;
|
|
50
34
|
addCosUrlImageMogr2_w?: number;
|
|
51
|
-
debug?: boolean;
|
|
52
|
-
onDebugStats?: (stats: ConvertDebugStats) => void;
|
|
53
35
|
}): string;
|
|
54
36
|
/**
|
|
55
37
|
* 绑定链接点击事件
|
package/dist/RichTextCore.js
CHANGED
|
@@ -146,6 +146,7 @@ var _loop_1 = function (i) {
|
|
|
146
146
|
// 1) 计算该元素所有 ql-indent-* 中的最大值
|
|
147
147
|
var clsArr = ($elem.attr("class") || "").split(/\s+/).filter(Boolean);
|
|
148
148
|
var isRtl = clsArr.includes("ql-direction-rtl");
|
|
149
|
+
var isList = clsArr.includes("ql-indent-0");
|
|
149
150
|
var maxIndentNum = 0;
|
|
150
151
|
clsArr.forEach(function (c) {
|
|
151
152
|
var m = c.match(/^ql-indent-(\d+)$/);
|
|
@@ -162,8 +163,13 @@ var _loop_1 = function (i) {
|
|
|
162
163
|
if (currentIndentNum !== maxIndentNum) {
|
|
163
164
|
return old;
|
|
164
165
|
}
|
|
165
|
-
|
|
166
|
-
|
|
166
|
+
var desiredPadEm;
|
|
167
|
+
if (isList) {
|
|
168
|
+
desiredPadEm = (maxIndentNum + 1) * 3;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
desiredPadEm = maxIndentNum * 3;
|
|
172
|
+
}
|
|
167
173
|
var styleObj = parseStyleString(old);
|
|
168
174
|
// 依据方向选择缩进属性键
|
|
169
175
|
var paddingKey = isRtl ? "padding-right" : "padding-left";
|
|
@@ -207,85 +213,29 @@ var RichTextCore = /** @class */ (function () {
|
|
|
207
213
|
* @param config.addCosUrlImageMogr2_w 添加cos url图片的mogr2_w参数,如果是cos的图片,可以使用这个配置设置图片宽度最大值。组件会增加参数为 xxx.jpg?imageMogr2/thumbnail/<width>x的参数。参数值取min(img节点样式宽度,addCosUrlImageMogr2_w)
|
|
208
214
|
*/
|
|
209
215
|
RichTextCore.convertRichTextToPixuiStyle = function (str, config) {
|
|
210
|
-
var debug = !!(config === null || config === void 0 ? void 0 : config.debug);
|
|
211
|
-
var now = function () { return Date.now(); };
|
|
212
|
-
var highLevelPhases = [];
|
|
213
|
-
var detailTotals = {};
|
|
214
|
-
var measure = function (name, fn) {
|
|
215
|
-
if (!debug)
|
|
216
|
-
return fn();
|
|
217
|
-
var s = now();
|
|
218
|
-
var r = fn();
|
|
219
|
-
var e = now();
|
|
220
|
-
highLevelPhases.push({ name: name, ms: e - s });
|
|
221
|
-
return r;
|
|
222
|
-
};
|
|
223
216
|
// 重置全局状态
|
|
224
217
|
RichTextCore.linkNodes = [];
|
|
225
218
|
RichTextCore.hrefIdCnt = 0;
|
|
226
219
|
// href 属性先统一做 URI 编码
|
|
227
|
-
var preEncodedStr =
|
|
228
|
-
|
|
220
|
+
var preEncodedStr = str.replace(/href=(['"])(.*?)\1/g, function (_m, quote, hrefVal) {
|
|
221
|
+
return "href=".concat(quote).concat(encodeURIComponent(hrefVal)).concat(quote);
|
|
222
|
+
});
|
|
223
|
+
var $1 = cheerio.load(preEncodedStr, null, false);
|
|
229
224
|
//检查html,如果有text节点,说明是转换过的,直接返回
|
|
230
225
|
if ($1("text").length > 0) {
|
|
231
|
-
if (debug) {
|
|
232
|
-
var stats = {
|
|
233
|
-
totalMs: highLevelPhases.reduce(function (a, b) { return a + b.ms; }, 0),
|
|
234
|
-
highLevel: highLevelPhases,
|
|
235
|
-
detail: Object.entries(detailTotals).map(function (_a) {
|
|
236
|
-
var name = _a[0], ms = _a[1];
|
|
237
|
-
return ({ name: name, ms: ms });
|
|
238
|
-
}),
|
|
239
|
-
segmentsCount: 0,
|
|
240
|
-
version: version_1.LIB_VERSION,
|
|
241
|
-
timestamp: now(),
|
|
242
|
-
};
|
|
243
|
-
RichTextCore.lastDebugStats = stats;
|
|
244
|
-
(config === null || config === void 0 ? void 0 : config.onDebugStats) && config.onDebugStats(stats);
|
|
245
|
-
}
|
|
246
226
|
return str;
|
|
247
227
|
}
|
|
248
228
|
var oriNodeCount = $1("*").length;
|
|
249
229
|
console.log("pixui-richHelper转换---- 版本:" + " " + version_1.LIB_VERSION + " " + " 原始节点数:" + oriNodeCount);
|
|
250
230
|
// ---------- 第 1 步:段落分割(基础实现:根节点切分) ----------
|
|
251
|
-
var segments =
|
|
231
|
+
var segments = RichTextCore.splitIntoSegments($1);
|
|
252
232
|
// ---------- 第 2/3 步:遍历 + 展平 ----------
|
|
253
233
|
// 为保证兼容性,我们直接对 HTML 进行逐段处理并在内部构建 PixUI 结构。
|
|
254
234
|
// 这样既保持分段概念,又可复用旧逻辑的稳定性。
|
|
255
|
-
var processedSegments =
|
|
256
|
-
return segments.map(function (seg) {
|
|
257
|
-
return RichTextCore.processSegment(seg, {
|
|
258
|
-
lineHeightScale: config === null || config === void 0 ? void 0 : config.lineHeightScale,
|
|
259
|
-
convertPxToEm: config === null || config === void 0 ? void 0 : config.convertPxToEm,
|
|
260
|
-
addCosUrlImageMogr2_w: config === null || config === void 0 ? void 0 : config.addCosUrlImageMogr2_w,
|
|
261
|
-
debug: debug,
|
|
262
|
-
debugTotals: detailTotals,
|
|
263
|
-
});
|
|
264
|
-
});
|
|
265
|
-
});
|
|
235
|
+
var processedSegments = segments.map(function (seg) { return RichTextCore.processSegment(seg, config); });
|
|
266
236
|
// ---------- 第 4 步:拼装 ----------
|
|
267
|
-
var Result =
|
|
268
|
-
|
|
269
|
-
console.log(Result);
|
|
270
|
-
if (debug) {
|
|
271
|
-
var detailList = Object.entries(detailTotals)
|
|
272
|
-
.map(function (_a) {
|
|
273
|
-
var name = _a[0], ms = _a[1];
|
|
274
|
-
return ({ name: name, ms: ms });
|
|
275
|
-
})
|
|
276
|
-
.sort(function (a, b) { return b.ms - a.ms; });
|
|
277
|
-
var totalMs = highLevelPhases.reduce(function (a, b) { return a + b.ms; }, 0);
|
|
278
|
-
var stats = {
|
|
279
|
-
totalMs: totalMs,
|
|
280
|
-
highLevel: highLevelPhases,
|
|
281
|
-
detail: detailList,
|
|
282
|
-
segmentsCount: segments.length,
|
|
283
|
-
version: version_1.LIB_VERSION,
|
|
284
|
-
timestamp: now(),
|
|
285
|
-
};
|
|
286
|
-
RichTextCore.lastDebugStats = stats;
|
|
287
|
-
(config === null || config === void 0 ? void 0 : config.onDebugStats) && config.onDebugStats(stats);
|
|
288
|
-
}
|
|
237
|
+
var Result = processedSegments.join("");
|
|
238
|
+
// console.log(Result);
|
|
289
239
|
return Result;
|
|
290
240
|
};
|
|
291
241
|
/**
|
|
@@ -438,73 +388,58 @@ var RichTextCore = /** @class */ (function () {
|
|
|
438
388
|
* 处理单个段落片段,返回转换后的片段 HTML
|
|
439
389
|
*/
|
|
440
390
|
RichTextCore.processSegment = function (segmentHtml, config) {
|
|
441
|
-
var _this = this;
|
|
442
|
-
var debug = !!(config === null || config === void 0 ? void 0 : config.debug);
|
|
443
|
-
var totals = config === null || config === void 0 ? void 0 : config.debugTotals;
|
|
444
|
-
var now = function () { return Date.now(); };
|
|
445
|
-
var time = function (name, fn) {
|
|
446
|
-
if (!debug)
|
|
447
|
-
return fn();
|
|
448
|
-
var s = now();
|
|
449
|
-
fn();
|
|
450
|
-
var e = now();
|
|
451
|
-
if (totals)
|
|
452
|
-
totals[name] = (totals[name] || 0) + (e - s);
|
|
453
|
-
};
|
|
454
391
|
var $ = cheerio.load(segmentHtml, null, false);
|
|
455
392
|
// 预处理:data-list → class、class → style、标题后补 <br>、margin→padding 合并
|
|
456
|
-
|
|
393
|
+
this.preprocess($);
|
|
457
394
|
// 规范图片尺寸单位:img 的 width/height 数字补 px
|
|
458
|
-
|
|
395
|
+
this.fixImgSizeUnit($);
|
|
459
396
|
// COS 图片缩略参数:按最小可用宽度收敛/追加 imageMogr2/thumbnail/<w>x
|
|
460
|
-
|
|
397
|
+
this.handleCosImageMogr2($, config);
|
|
461
398
|
// 合并img的width,height属性到 style,属性存在以 style 优先,移除 width/height 属性
|
|
462
|
-
|
|
399
|
+
this.consolidateImgSizeStyle($);
|
|
463
400
|
// 列表规范化:ol/ul/li 转三列布局(缩进/标号/文本),保留缩进与方向。节点结构:段落div(缩进key节点、标号key节点、text节点区域)
|
|
464
|
-
|
|
401
|
+
this.handleLists($, (config === null || config === void 0 ? void 0 : config.lineHeightScale) || 1);
|
|
465
402
|
// 换行处理:<br> → 透明占位 div,确保 PixUI 内正确换行
|
|
466
|
-
|
|
403
|
+
this.replaceBrWithPlaceholder($);
|
|
467
404
|
// 超链接:<a> → 可点击的 div,汇聚子样式并记录 data-link-*
|
|
468
|
-
|
|
405
|
+
this.handleAnchorTag($);
|
|
469
406
|
// 文本包装:将普通文本包入 <text>(跳过列表/链接/换行占位)
|
|
470
|
-
|
|
407
|
+
this.wrapTextNodes($);
|
|
471
408
|
// 样式标签:strong/em/u/s/span → 文本节点(列表文本列下改为 <key>)
|
|
472
|
-
|
|
409
|
+
this.replaceStyleTags($);
|
|
473
410
|
// 列表文本列规范化:裸文本统一包裹为 <key>,清理空白
|
|
474
|
-
|
|
411
|
+
this.normalizeListItemPlainTextToKey($);
|
|
475
412
|
// 段落:<p> → <div>,补 flex-shrink 与 width:100%
|
|
476
|
-
|
|
413
|
+
this.replacePTag($);
|
|
477
414
|
// 图片链接:img 的 href 转移至 data-link-href,并登记点击节点
|
|
478
|
-
|
|
415
|
+
this.handleImgHref($);
|
|
479
416
|
// 防收缩:常见块级元素补 flex-shrink:0(不作用于列表项)
|
|
480
|
-
|
|
417
|
+
this.addFlexShrink($);
|
|
481
418
|
// 扁平化:合并 text 样式并去掉嵌套的父 <text>
|
|
482
|
-
|
|
419
|
+
this.flattenNestedText($);
|
|
483
420
|
// 同级文本:拆分为 <key> 片段并统一包入父 <text>
|
|
484
|
-
|
|
421
|
+
this.convertSiblingTextToDiv($);
|
|
485
422
|
// 首行缩进:text-indent 转透明占位
|
|
486
|
-
|
|
423
|
+
this.handleTextIndent($);
|
|
487
424
|
// 行高与字间距:聚合到父 <text> 并按配置缩放 line-height
|
|
488
|
-
|
|
425
|
+
this.adjustLineHeightAndLetterSpacing($, config);
|
|
489
426
|
// 文本对齐与方向:从 div 下沉至子 <text>
|
|
490
|
-
|
|
427
|
+
this.transferTextAlign($);
|
|
491
428
|
// 清理空 <text>
|
|
492
|
-
|
|
429
|
+
this.removeEmptyText($);
|
|
493
430
|
// this.fixHeadingFontSize($);
|
|
494
431
|
// 最后:修正 img 结束标签、nbsp
|
|
495
432
|
var res = $.html();
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}
|
|
507
|
-
});
|
|
433
|
+
res = res
|
|
434
|
+
.replaceAll(/<img([^>]+)>/g, "<img$1 />")
|
|
435
|
+
.replaceAll(/ /g, " ")
|
|
436
|
+
.replaceAll(/&/g, "&")
|
|
437
|
+
.replaceAll(/"/g, '"')
|
|
438
|
+
.replaceAll("\"", "\"");
|
|
439
|
+
// 统一进行px到em转换
|
|
440
|
+
if (config === null || config === void 0 ? void 0 : config.convertPxToEm) {
|
|
441
|
+
res = this.convertAllPxToEm(res);
|
|
442
|
+
}
|
|
508
443
|
return res;
|
|
509
444
|
};
|
|
510
445
|
/**
|
package/package.json
CHANGED