@pixui-dev/pixui-richtext-helper 0.1.1-beta.2 → 0.1.1-beta.3
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 +22 -0
- package/dist/RichText.js +24 -0
- package/dist/RichTextUtils.d.ts +6 -0
- package/dist/RichTextUtils.js +7 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -4
- package/dist/richtext/RichText_Refactor.d.ts +77 -0
- package/dist/richtext/RichText_Refactor.js +637 -0
- package/package.json +4 -3
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { RichText_Refactor, LinkNodeType, LinkClickParams } from "./richtext/RichText_Refactor";
|
|
2
|
+
/**
|
|
3
|
+
* 对外暴露的 RichText 组件。
|
|
4
|
+
* 保持旧版使用方式不变,内部委托给 RichText_Refactor 实现。
|
|
5
|
+
*/
|
|
6
|
+
export declare const RichText: {
|
|
7
|
+
/** 链接节点类型枚举 */
|
|
8
|
+
LinkNodeType: typeof LinkNodeType;
|
|
9
|
+
/**
|
|
10
|
+
* 将富文本转换为 PixUI innerHTML 兼容格式
|
|
11
|
+
* @see RichText_Refactor.convertRichTextToPixuiStyle
|
|
12
|
+
*/
|
|
13
|
+
convertRichTextToPixuiStyle: typeof RichText_Refactor.convertRichTextToPixuiStyle;
|
|
14
|
+
/**
|
|
15
|
+
* 绑定富文本中的链接点击事件
|
|
16
|
+
* @see RichText_Refactor.bindLinkClickEvents
|
|
17
|
+
*/
|
|
18
|
+
bindLinkClickEvents: typeof RichText_Refactor.bindLinkClickEvents;
|
|
19
|
+
};
|
|
20
|
+
export type { LinkClickParams };
|
|
21
|
+
export { LinkNodeType };
|
|
22
|
+
export default RichText;
|
package/dist/RichText.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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; } });
|
|
6
|
+
/**
|
|
7
|
+
* 对外暴露的 RichText 组件。
|
|
8
|
+
* 保持旧版使用方式不变,内部委托给 RichText_Refactor 实现。
|
|
9
|
+
*/
|
|
10
|
+
exports.RichText = {
|
|
11
|
+
/** 链接节点类型枚举 */
|
|
12
|
+
LinkNodeType: RichText_Refactor_1.LinkNodeType,
|
|
13
|
+
/**
|
|
14
|
+
* 将富文本转换为 PixUI innerHTML 兼容格式
|
|
15
|
+
* @see RichText_Refactor.convertRichTextToPixuiStyle
|
|
16
|
+
*/
|
|
17
|
+
convertRichTextToPixuiStyle: RichText_Refactor_1.RichText_Refactor.convertRichTextToPixuiStyle,
|
|
18
|
+
/**
|
|
19
|
+
* 绑定富文本中的链接点击事件
|
|
20
|
+
* @see RichText_Refactor.bindLinkClickEvents
|
|
21
|
+
*/
|
|
22
|
+
bindLinkClickEvents: RichText_Refactor_1.RichText_Refactor.bindLinkClickEvents,
|
|
23
|
+
};
|
|
24
|
+
exports.default = exports.RichText;
|
package/dist/RichTextUtils.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
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
|
+
*/
|
|
1
7
|
export declare namespace RichText {
|
|
2
8
|
/**
|
|
3
9
|
* 富文本中的超链接节点类型
|
package/dist/RichTextUtils.js
CHANGED
|
@@ -44,6 +44,12 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
45
|
exports.RichText = void 0;
|
|
46
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
|
+
*/
|
|
47
53
|
var RichText;
|
|
48
54
|
(function (RichText) {
|
|
49
55
|
/**
|
|
@@ -246,7 +252,7 @@ var RichText;
|
|
|
246
252
|
});
|
|
247
253
|
}
|
|
248
254
|
// 转换为简单div,样式已合并
|
|
249
|
-
$(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\" class=\"PA_RichTextHref_ATag\"
|
|
255
|
+
$(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\" class=\"PA_RichTextHref_ATag\" >").concat(textContent, "</div>"));
|
|
250
256
|
});
|
|
251
257
|
//找到所有的文字节点,外层包裹text标签
|
|
252
258
|
$("*").each(function () {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { RichText } from "./
|
|
2
|
-
export { RichText as default } from "./
|
|
1
|
+
export { RichText } from "./RichText";
|
|
2
|
+
export { RichText as default } from "./RichText";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = exports.RichText = void 0;
|
|
4
|
-
var
|
|
5
|
-
Object.defineProperty(exports, "RichText", { enumerable: true, get: function () { return
|
|
6
|
-
var
|
|
7
|
-
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return
|
|
4
|
+
var RichText_1 = require("./RichText");
|
|
5
|
+
Object.defineProperty(exports, "RichText", { enumerable: true, get: function () { return RichText_1.RichText; } });
|
|
6
|
+
var RichText_2 = require("./RichText");
|
|
7
|
+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return RichText_2.RichText; } });
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*****************************************************
|
|
2
|
+
* 类型、枚举定义
|
|
3
|
+
*****************************************************/
|
|
4
|
+
/** 链接节点的类型 */
|
|
5
|
+
export declare enum LinkNodeType {
|
|
6
|
+
IMG = "img",
|
|
7
|
+
DIV = "div"
|
|
8
|
+
}
|
|
9
|
+
/** 点击回调参数 */
|
|
10
|
+
export interface LinkClickParams {
|
|
11
|
+
type: LinkNodeType;
|
|
12
|
+
href: string;
|
|
13
|
+
id: string;
|
|
14
|
+
}
|
|
15
|
+
/*****************************************************
|
|
16
|
+
* RichText_Refactor 主类
|
|
17
|
+
*****************************************************/
|
|
18
|
+
export declare class RichText_Refactor {
|
|
19
|
+
private static linkNodes;
|
|
20
|
+
private static hrefIdCnt;
|
|
21
|
+
/**
|
|
22
|
+
* 富文本转换为 PixUI innerHTML 兼容格式
|
|
23
|
+
* @param str 原始富文本 HTML
|
|
24
|
+
* @param config 可选配置
|
|
25
|
+
*/
|
|
26
|
+
static convertRichTextToPixuiStyle(str: string, config?: {
|
|
27
|
+
lineHeightScale?: number;
|
|
28
|
+
}): string;
|
|
29
|
+
/**
|
|
30
|
+
* 绑定链接点击事件
|
|
31
|
+
*/
|
|
32
|
+
static bindLinkClickEvents(linkClickHandler: (params: LinkClickParams) => void): void;
|
|
33
|
+
/*****************************************************
|
|
34
|
+
* 内部流程函数
|
|
35
|
+
*****************************************************/
|
|
36
|
+
/**
|
|
37
|
+
* 将 HTML 切分为基础段落片段。
|
|
38
|
+
* 简易实现:以顶级节点为粒度切分,再根据最外层列表节点进行分割。
|
|
39
|
+
*/
|
|
40
|
+
private static splitIntoSegments;
|
|
41
|
+
/**
|
|
42
|
+
* 处理单个段落片段,返回转换后的片段 HTML
|
|
43
|
+
*/
|
|
44
|
+
private static processSegment;
|
|
45
|
+
private static handleIndentClass;
|
|
46
|
+
private static fixImgSizeUnit;
|
|
47
|
+
/** 列表处理(将 ol/ul/li 替换为 div 结构) */
|
|
48
|
+
private static handleLists;
|
|
49
|
+
/** 将连续 <br> 替换为透明占位文字,确保 PixUI 换行 */
|
|
50
|
+
private static replaceBrWithPlaceholder;
|
|
51
|
+
/** 处理 <a> 标签:转为 div、保留样式、记录链接 */
|
|
52
|
+
private static handleAnchorTag;
|
|
53
|
+
/** 用 text 标签包裹纯文本节点 */
|
|
54
|
+
private static wrapTextNodes;
|
|
55
|
+
/** strong / em / u / s / span 等标签替换成 text */
|
|
56
|
+
private static replaceStyleTags;
|
|
57
|
+
/** p → div */
|
|
58
|
+
private static replacePTag;
|
|
59
|
+
/** img 的 href 转移处理 & 记录链接 */
|
|
60
|
+
private static handleImgHref;
|
|
61
|
+
/** 给指定标签补 flex-shrink:0 */
|
|
62
|
+
private static addFlexShrink;
|
|
63
|
+
/** 把嵌套的 text 展平 */
|
|
64
|
+
private static flattenNestedText;
|
|
65
|
+
/** 将同一行的 text 节点转为 div 并外包一层 text */
|
|
66
|
+
private static convertSiblingTextToDiv;
|
|
67
|
+
/** text-indent 首行缩进处理 */
|
|
68
|
+
private static handleTextIndent;
|
|
69
|
+
/** line-height / letter-spacing 调整 */
|
|
70
|
+
private static adjustLineHeightAndLetterSpacing;
|
|
71
|
+
/** 把 div 的 text-align 转移到子 text 上 */
|
|
72
|
+
private static transferTextAlign;
|
|
73
|
+
/** 删除空 text 节点 */
|
|
74
|
+
private static removeEmptyText;
|
|
75
|
+
/** 补默认 heading 字体大小 */
|
|
76
|
+
private static fixHeadingFontSize;
|
|
77
|
+
}
|
|
@@ -0,0 +1,637 @@
|
|
|
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_Refactor = exports.LinkNodeType = void 0;
|
|
46
|
+
var cheerio = __importStar(require("cheerio"));
|
|
47
|
+
/*****************************************************
|
|
48
|
+
* 类型、枚举定义
|
|
49
|
+
*****************************************************/
|
|
50
|
+
/** 链接节点的类型 */
|
|
51
|
+
var LinkNodeType;
|
|
52
|
+
(function (LinkNodeType) {
|
|
53
|
+
LinkNodeType["IMG"] = "img";
|
|
54
|
+
LinkNodeType["DIV"] = "div";
|
|
55
|
+
})(LinkNodeType || (exports.LinkNodeType = LinkNodeType = {}));
|
|
56
|
+
/*****************************************************
|
|
57
|
+
* 工具函数
|
|
58
|
+
*****************************************************/
|
|
59
|
+
/**
|
|
60
|
+
* 解析 style 字符串为对象
|
|
61
|
+
*/
|
|
62
|
+
var parseStyleString = function (styleStr) {
|
|
63
|
+
var result = {};
|
|
64
|
+
if (!styleStr || !styleStr.trim())
|
|
65
|
+
return result;
|
|
66
|
+
// 分割多个样式声明
|
|
67
|
+
var declarations = styleStr.split(";").filter(function (decl) { return decl.trim(); });
|
|
68
|
+
declarations.forEach(function (decl) {
|
|
69
|
+
var colonIndex = decl.indexOf(":");
|
|
70
|
+
if (colonIndex > 0) {
|
|
71
|
+
var property = decl.substring(0, colonIndex).trim();
|
|
72
|
+
var value = decl.substring(colonIndex + 1).trim();
|
|
73
|
+
if (property && value) {
|
|
74
|
+
result[property] = value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return result;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* 将样式对象序列化为字符串
|
|
82
|
+
*/
|
|
83
|
+
var serializeStyleObject = function (styleObj) {
|
|
84
|
+
return (Object.entries(styleObj)
|
|
85
|
+
.map(function (_a) {
|
|
86
|
+
var property = _a[0], value = _a[1];
|
|
87
|
+
return "".concat(property, ": ").concat(value);
|
|
88
|
+
})
|
|
89
|
+
.join("; ") + (Object.keys(styleObj).length > 0 ? ";" : ""));
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* 合并多个 style 字符串,自动处理分号与空格,后合并的覆盖前面的(符合CSS优先级规则)
|
|
93
|
+
*/
|
|
94
|
+
var mergeStyles = function () {
|
|
95
|
+
var styles = [];
|
|
96
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
97
|
+
styles[_i] = arguments[_i];
|
|
98
|
+
}
|
|
99
|
+
var mergedStyleObj = {};
|
|
100
|
+
// 过滤空值并解析每个样式字符串
|
|
101
|
+
var validStyles = styles.filter(function (s) { return !!s && s.trim().length > 0; });
|
|
102
|
+
// 按顺序合并,后面的覆盖前面的
|
|
103
|
+
validStyles.forEach(function (styleStr) {
|
|
104
|
+
var styleObj = parseStyleString(styleStr);
|
|
105
|
+
Object.assign(mergedStyleObj, styleObj);
|
|
106
|
+
});
|
|
107
|
+
return serializeStyleObject(mergedStyleObj);
|
|
108
|
+
};
|
|
109
|
+
/*****************************************************
|
|
110
|
+
* RichText_Refactor 主类
|
|
111
|
+
*****************************************************/
|
|
112
|
+
var RichText_Refactor = /** @class */ (function () {
|
|
113
|
+
function RichText_Refactor() {
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 富文本转换为 PixUI innerHTML 兼容格式
|
|
117
|
+
* @param str 原始富文本 HTML
|
|
118
|
+
* @param config 可选配置
|
|
119
|
+
*/
|
|
120
|
+
RichText_Refactor.convertRichTextToPixuiStyle = function (str, config) {
|
|
121
|
+
// 重置全局状态
|
|
122
|
+
RichText_Refactor.linkNodes = [];
|
|
123
|
+
RichText_Refactor.hrefIdCnt = 0;
|
|
124
|
+
// ---------- 第 1 步:段落分割(基础实现:根节点切分) ----------
|
|
125
|
+
var segments = RichText_Refactor.splitIntoSegments(str);
|
|
126
|
+
// ---------- 第 2/3 步:遍历 + 展平 ----------
|
|
127
|
+
// 为保证兼容性,我们直接对 HTML 进行逐段处理并在内部构建 PixUI 结构。
|
|
128
|
+
// 这样既保持分段概念,又可复用旧逻辑的稳定性。
|
|
129
|
+
var processedSegments = segments.map(function (seg) { return RichText_Refactor.processSegment(seg, config); });
|
|
130
|
+
// ---------- 第 4 步:拼装 ----------
|
|
131
|
+
var Result = processedSegments.join("");
|
|
132
|
+
console.log(Result);
|
|
133
|
+
return Result;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* 绑定链接点击事件
|
|
137
|
+
*/
|
|
138
|
+
RichText_Refactor.bindLinkClickEvents = function (linkClickHandler) {
|
|
139
|
+
RichText_Refactor.linkNodes.forEach(function (nodeInfo) {
|
|
140
|
+
var element = document.getElementById(nodeInfo.id);
|
|
141
|
+
if (element) {
|
|
142
|
+
element.onclick = function (e) {
|
|
143
|
+
e.stopPropagation();
|
|
144
|
+
e.preventDefault();
|
|
145
|
+
linkClickHandler({
|
|
146
|
+
type: nodeInfo.type,
|
|
147
|
+
href: nodeInfo.href,
|
|
148
|
+
id: nodeInfo.id,
|
|
149
|
+
});
|
|
150
|
+
return false;
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
/*****************************************************
|
|
156
|
+
* 内部流程函数
|
|
157
|
+
*****************************************************/
|
|
158
|
+
/**
|
|
159
|
+
* 将 HTML 切分为基础段落片段。
|
|
160
|
+
* 简易实现:以顶级节点为粒度切分,再根据最外层列表节点进行分割。
|
|
161
|
+
*/
|
|
162
|
+
RichText_Refactor.splitIntoSegments = function (html) {
|
|
163
|
+
var $ = cheerio.load(html, null, false);
|
|
164
|
+
var segments = [];
|
|
165
|
+
// 如果有 body,取其直接子节点;否则取根节点下的直接子节点
|
|
166
|
+
var roots = $("body").length > 0 ? $("body").children() : $.root().children();
|
|
167
|
+
roots.each(function () {
|
|
168
|
+
var nodeHtml = $(this).toString();
|
|
169
|
+
// 切分包含最外层列表的片段
|
|
170
|
+
if (/^<\s*(ol|ul)/i.test(nodeHtml)) {
|
|
171
|
+
segments.push(nodeHtml);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// 进一步检查内部是否存在最外层的 ol/ul,需要分成 前段 + 列表 + 后段
|
|
175
|
+
var inner$_1 = cheerio.load(nodeHtml, null, false);
|
|
176
|
+
var outerLists_1 = [];
|
|
177
|
+
inner$_1("ol, ul").each(function () {
|
|
178
|
+
if (inner$_1(this).parents("ol, ul").length === 0) {
|
|
179
|
+
outerLists_1.push(inner$_1(this).toString());
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
if (outerLists_1.length === 0) {
|
|
183
|
+
segments.push(nodeHtml);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
var tempHtml_1 = nodeHtml;
|
|
187
|
+
outerLists_1.forEach(function (listHtml) {
|
|
188
|
+
var idx = tempHtml_1.indexOf(listHtml);
|
|
189
|
+
if (idx >= 0) {
|
|
190
|
+
var before = tempHtml_1.substring(0, idx);
|
|
191
|
+
if (before.trim())
|
|
192
|
+
segments.push(before);
|
|
193
|
+
segments.push(listHtml);
|
|
194
|
+
tempHtml_1 = tempHtml_1.substring(idx + listHtml.length);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
if (tempHtml_1.trim())
|
|
198
|
+
segments.push(tempHtml_1);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
// fallback:原样返回
|
|
203
|
+
if (segments.length === 0)
|
|
204
|
+
segments.push(html);
|
|
205
|
+
return segments;
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* 处理单个段落片段,返回转换后的片段 HTML
|
|
209
|
+
*/
|
|
210
|
+
RichText_Refactor.processSegment = function (segmentHtml, config) {
|
|
211
|
+
var $ = cheerio.load(segmentHtml, null, false);
|
|
212
|
+
// 按旧实现顺序进行处理,但重构为独立函数划分
|
|
213
|
+
this.handleIndentClass($);
|
|
214
|
+
this.fixImgSizeUnit($);
|
|
215
|
+
this.handleLists($);
|
|
216
|
+
this.replaceBrWithPlaceholder($);
|
|
217
|
+
this.handleAnchorTag($);
|
|
218
|
+
this.wrapTextNodes($);
|
|
219
|
+
this.replaceStyleTags($);
|
|
220
|
+
this.replacePTag($);
|
|
221
|
+
this.handleImgHref($);
|
|
222
|
+
this.addFlexShrink($);
|
|
223
|
+
this.flattenNestedText($);
|
|
224
|
+
this.convertSiblingTextToDiv($);
|
|
225
|
+
this.handleTextIndent($);
|
|
226
|
+
this.adjustLineHeightAndLetterSpacing($, config);
|
|
227
|
+
this.transferTextAlign($);
|
|
228
|
+
this.removeEmptyText($);
|
|
229
|
+
this.fixHeadingFontSize($);
|
|
230
|
+
// 最后:修正 img 结束标签、nbsp
|
|
231
|
+
var res = $.html();
|
|
232
|
+
res = res.replaceAll(/<img([^>]+)>/g, "<img$1 />").replaceAll(/ /g, " ");
|
|
233
|
+
return res;
|
|
234
|
+
};
|
|
235
|
+
// ------------------------------
|
|
236
|
+
// 各独立处理步骤实现
|
|
237
|
+
// ------------------------------
|
|
238
|
+
RichText_Refactor.handleIndentClass = function ($) {
|
|
239
|
+
var _loop_1 = function (i) {
|
|
240
|
+
var indent = "ql-indent-".concat(i);
|
|
241
|
+
var extStyle = "padding-left: ".concat(i * 2, "rem");
|
|
242
|
+
$(".".concat(indent)).each(function () {
|
|
243
|
+
var ori = $(this).attr("style") || "";
|
|
244
|
+
$(this).attr("style", mergeStyles(ori, extStyle));
|
|
245
|
+
$(this).removeClass(indent);
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
for (var i = 1; i <= 10; i++) {
|
|
249
|
+
_loop_1(i);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
RichText_Refactor.fixImgSizeUnit = function ($) {
|
|
253
|
+
$("img").each(function () {
|
|
254
|
+
var width = $(this).attr("width");
|
|
255
|
+
var height = $(this).attr("height");
|
|
256
|
+
if (width && width + "" === parseInt(width) + "") {
|
|
257
|
+
$(this).attr("width", "".concat(width, "px"));
|
|
258
|
+
}
|
|
259
|
+
if (height && height + "" === parseInt(height) + "") {
|
|
260
|
+
$(this).attr("height", "".concat(height, "px"));
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
};
|
|
264
|
+
/** 列表处理(将 ol/ul/li 替换为 div 结构) */
|
|
265
|
+
RichText_Refactor.handleLists = function ($) {
|
|
266
|
+
var topLevelLists = [];
|
|
267
|
+
var collectListItems = function ($container, currentLevel) {
|
|
268
|
+
if (currentLevel === void 0) { currentLevel = 0; }
|
|
269
|
+
var items = [];
|
|
270
|
+
$container.children().each(function () {
|
|
271
|
+
var $child = $(this);
|
|
272
|
+
if ($child.is("li")) {
|
|
273
|
+
var isOrdered = $child.parent().is("ol");
|
|
274
|
+
var orderIndex = 1;
|
|
275
|
+
if (isOrdered) {
|
|
276
|
+
orderIndex = $child.prevAll("li").length + 1;
|
|
277
|
+
}
|
|
278
|
+
var marker = isOrdered ? "".concat(orderIndex, ".") : "•";
|
|
279
|
+
var paddingLeft = currentLevel * 2; // 每层缩进 2rem
|
|
280
|
+
var $liClone = $child.clone();
|
|
281
|
+
$liClone.find("ol, ul").remove();
|
|
282
|
+
var textContent = $liClone.text().trim() || "";
|
|
283
|
+
var style = $child.attr("style") || "";
|
|
284
|
+
items.push({
|
|
285
|
+
level: currentLevel,
|
|
286
|
+
isOrdered: isOrdered,
|
|
287
|
+
orderIndex: orderIndex,
|
|
288
|
+
marker: marker,
|
|
289
|
+
paddingLeft: paddingLeft,
|
|
290
|
+
textContent: textContent,
|
|
291
|
+
style: style,
|
|
292
|
+
});
|
|
293
|
+
// 处理子列表
|
|
294
|
+
$child.find("ol, ul").each(function () {
|
|
295
|
+
var $nestedList = $(this);
|
|
296
|
+
if ($nestedList.parent().closest("li")[0] === $child[0]) {
|
|
297
|
+
var childItems = collectListItems($nestedList, currentLevel + 1);
|
|
298
|
+
items.push.apply(items, childItems);
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
return items;
|
|
304
|
+
};
|
|
305
|
+
// 找到所有顶层列表
|
|
306
|
+
$("ol, ul").each(function () {
|
|
307
|
+
var $list = $(this);
|
|
308
|
+
if ($list.parents("ol, ul").length === 0) {
|
|
309
|
+
var placeholder = $("<div data-list-placeholder=\"true\"></div>");
|
|
310
|
+
$list.before(placeholder);
|
|
311
|
+
var items = collectListItems($list, 1);
|
|
312
|
+
topLevelLists.push({
|
|
313
|
+
element: $list,
|
|
314
|
+
placeholder: placeholder,
|
|
315
|
+
items: items,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
// 移除原列表结构
|
|
320
|
+
$("ol, ul, li").remove();
|
|
321
|
+
// 插入新列表
|
|
322
|
+
topLevelLists.forEach(function (listInfo) {
|
|
323
|
+
var placeholder = listInfo.placeholder, items = listInfo.items;
|
|
324
|
+
var html = items
|
|
325
|
+
.map(function (it) {
|
|
326
|
+
return ("<div style=\"".concat(mergeStyles(it.style, "padding-left: ".concat(it.paddingLeft, "rem"), "flex-shrink: 0", "width: 100%", "flex-direction: row", "display: flex"), "\" data-list-item=\"true\">") +
|
|
327
|
+
"<text style=\"".concat(mergeStyles("flex-shrink: 0", "width: 100%", "line-height: 1", "display: flex", "flex-direction: row"), "\">") +
|
|
328
|
+
"<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "margin-right: 0.5rem"), "\">").concat(it.marker, "</div>") +
|
|
329
|
+
"<div style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "flex: 1"), "\">").concat(it.textContent, "</div>") +
|
|
330
|
+
"</text></div>");
|
|
331
|
+
})
|
|
332
|
+
.join("");
|
|
333
|
+
placeholder.after(html);
|
|
334
|
+
placeholder.remove();
|
|
335
|
+
});
|
|
336
|
+
};
|
|
337
|
+
/** 将连续 <br> 替换为透明占位文字,确保 PixUI 换行 */
|
|
338
|
+
RichText_Refactor.replaceBrWithPlaceholder = function ($) {
|
|
339
|
+
$("br").each(function () {
|
|
340
|
+
$(this).replaceWith("<span style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 20px"), "\" class='pixui-richtext-br-placeholder'>1</span>"));
|
|
341
|
+
});
|
|
342
|
+
};
|
|
343
|
+
/** 处理 <a> 标签:转为 div、保留样式、记录链接 */
|
|
344
|
+
RichText_Refactor.handleAnchorTag = function ($) {
|
|
345
|
+
var self = this;
|
|
346
|
+
$("a").each(function () {
|
|
347
|
+
var id = "PA_RichTextHrefId_".concat(self.hrefIdCnt++);
|
|
348
|
+
var href = $(this).attr("href");
|
|
349
|
+
var originalStyle = $(this).attr("style") || "";
|
|
350
|
+
var textContent = $(this).text();
|
|
351
|
+
var mergedStyles = [];
|
|
352
|
+
// 收集子元素的样式
|
|
353
|
+
if ($(this).find("strong").length > 0)
|
|
354
|
+
mergedStyles.push("font-weight: bold;");
|
|
355
|
+
if ($(this).find("em").length > 0)
|
|
356
|
+
mergedStyles.push("font-style: italic;");
|
|
357
|
+
if ($(this).find("u").length > 0)
|
|
358
|
+
mergedStyles.push("text-decoration: underline;");
|
|
359
|
+
if ($(this).find("s").length > 0)
|
|
360
|
+
mergedStyles.push("text-decoration: line-through;");
|
|
361
|
+
$(this)
|
|
362
|
+
.find("strong, em, u, s, span")
|
|
363
|
+
.each(function () {
|
|
364
|
+
var innerStyle = $(this).attr("style");
|
|
365
|
+
if (innerStyle)
|
|
366
|
+
mergedStyles.push(innerStyle);
|
|
367
|
+
});
|
|
368
|
+
var finalStyle = mergeStyles.apply(void 0, __spreadArray([originalStyle], mergedStyles, false));
|
|
369
|
+
if (href) {
|
|
370
|
+
self.linkNodes.push({ type: LinkNodeType.DIV, href: href, id: id });
|
|
371
|
+
}
|
|
372
|
+
// 确保link节点在正确的text层级内
|
|
373
|
+
var $parent = $(this).parent();
|
|
374
|
+
var isInText = $parent.is("text") || $parent.closest("text").length > 0;
|
|
375
|
+
if (isInText) {
|
|
376
|
+
// 如果已经在text内,直接替换为div
|
|
377
|
+
$(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\" class=\"PA_RichTextHref_ATag\">").concat(textContent, "</div>"));
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
// 如果不在text内,需要确保在正确的层级
|
|
381
|
+
$(this).replaceWith("<div style=\"".concat(finalStyle, "\" id=\"").concat(id, "\" class=\"PA_RichTextHref_ATag\">").concat(textContent, "</div>"));
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
/** 用 text 标签包裹纯文本节点 */
|
|
386
|
+
RichText_Refactor.wrapTextNodes = function ($) {
|
|
387
|
+
var self = this;
|
|
388
|
+
$("*").each(function () {
|
|
389
|
+
var nodeId = $(this).attr("id") || "";
|
|
390
|
+
if (nodeId.startsWith("PA_RichTextHrefId_"))
|
|
391
|
+
return;
|
|
392
|
+
var isListItem = $(this).attr("data-list-item") === "true";
|
|
393
|
+
if (isListItem)
|
|
394
|
+
return;
|
|
395
|
+
$(this)
|
|
396
|
+
.contents()
|
|
397
|
+
.each(function () {
|
|
398
|
+
var linkParent = $(this).closest("[id^='PA_RichTextHrefId_']");
|
|
399
|
+
if (linkParent.length > 0)
|
|
400
|
+
return;
|
|
401
|
+
var listParent = $(this).closest("[data-list-item='true']");
|
|
402
|
+
if (listParent.length > 0)
|
|
403
|
+
return;
|
|
404
|
+
if (this.type === "text") {
|
|
405
|
+
var text = this.data.trim();
|
|
406
|
+
if (text.length > 0) {
|
|
407
|
+
$(this).replaceWith("<text style=\"".concat(mergeStyles("word-break: break-word", "flex-shrink: 0", "flex-direction: row"), "\">").concat(text, "</text>"));
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
};
|
|
413
|
+
/** strong / em / u / s / span 等标签替换成 text */
|
|
414
|
+
RichText_Refactor.replaceStyleTags = function ($) {
|
|
415
|
+
var tagToStyle = {
|
|
416
|
+
strong: "font-weight: bold",
|
|
417
|
+
em: "font-style: italic",
|
|
418
|
+
u: "text-decoration: underline",
|
|
419
|
+
s: "text-decoration: line-through",
|
|
420
|
+
};
|
|
421
|
+
Object.entries(tagToStyle).forEach(function (_a) {
|
|
422
|
+
var tag = _a[0], style = _a[1];
|
|
423
|
+
$(tag).each(function () {
|
|
424
|
+
var html = $(this).html();
|
|
425
|
+
var oriStyle = $(this).attr("style") || "";
|
|
426
|
+
$(this).replaceWith("<text style=\"".concat(mergeStyles(oriStyle, style, "flex-shrink: 0"), "\">").concat(html, "</text>"));
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
$("span").each(function () {
|
|
430
|
+
var html = $(this).html();
|
|
431
|
+
var oriStyle = $(this).attr("style") || "";
|
|
432
|
+
$(this).replaceWith("<text style=\"".concat(mergeStyles(oriStyle, "flex-shrink: 0"), "\">").concat(html, "</text>"));
|
|
433
|
+
});
|
|
434
|
+
};
|
|
435
|
+
/** p → div */
|
|
436
|
+
RichText_Refactor.replacePTag = function ($) {
|
|
437
|
+
$("p").each(function () {
|
|
438
|
+
var html = $(this).html();
|
|
439
|
+
var style = $(this).attr("style") || "";
|
|
440
|
+
$(this).replaceWith("<div style=\"".concat(mergeStyles(style, "flex-shrink: 0", "width:100%"), "\">").concat(html, "</div>"));
|
|
441
|
+
});
|
|
442
|
+
};
|
|
443
|
+
/** img 的 href 转移处理 & 记录链接 */
|
|
444
|
+
RichText_Refactor.handleImgHref = function ($) {
|
|
445
|
+
var self = this;
|
|
446
|
+
$("img").each(function () {
|
|
447
|
+
var id = "PA_RichTextHrefId_".concat(self.hrefIdCnt++);
|
|
448
|
+
$(this).attr("id", id);
|
|
449
|
+
var href = $(this).attr("href");
|
|
450
|
+
if (href) {
|
|
451
|
+
self.linkNodes.push({ type: LinkNodeType.IMG, href: href, id: id });
|
|
452
|
+
}
|
|
453
|
+
$(this).attr("href", "");
|
|
454
|
+
$(this).attr("class", "PA_RichTextHref_ImgTag");
|
|
455
|
+
$(this).attr("data-href", href);
|
|
456
|
+
});
|
|
457
|
+
};
|
|
458
|
+
/** 给指定标签补 flex-shrink:0 */
|
|
459
|
+
RichText_Refactor.addFlexShrink = function ($) {
|
|
460
|
+
["h1", "h2", "h3", "h4", "h5", "h6", "a", "img", "div"].forEach(function (tag) {
|
|
461
|
+
$(tag).each(function () {
|
|
462
|
+
var isListItem = $(this).attr("data-list-item") === "true";
|
|
463
|
+
var inListItem = $(this).closest("[data-list-item='true']").length > 0;
|
|
464
|
+
if (!isListItem && !inListItem) {
|
|
465
|
+
var style = $(this).attr("style") || "";
|
|
466
|
+
$(this).attr("style", mergeStyles(style, "flex-shrink: 0"));
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
};
|
|
471
|
+
/** 把嵌套的 text 展平 */
|
|
472
|
+
RichText_Refactor.flattenNestedText = function ($) {
|
|
473
|
+
while ($("text > text").length > 0) {
|
|
474
|
+
$("text").each(function () {
|
|
475
|
+
var $this = $(this);
|
|
476
|
+
var parentStyle = $this.attr("style") || "";
|
|
477
|
+
$this.children("text").each(function () {
|
|
478
|
+
var $child = $(this);
|
|
479
|
+
var childStyle = $child.attr("style") || "";
|
|
480
|
+
var mergedStyle = mergeStyles(parentStyle, childStyle);
|
|
481
|
+
$child.attr("style", mergedStyle);
|
|
482
|
+
});
|
|
483
|
+
if ($this.children("text").length > 0) {
|
|
484
|
+
$this.replaceWith($this.html() || "");
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
/** 将同一行的 text 节点转为 div 并外包一层 text */
|
|
490
|
+
RichText_Refactor.convertSiblingTextToDiv = function ($) {
|
|
491
|
+
var nodeArr = [];
|
|
492
|
+
["h1", "h2", "h3", "h4", "h5", "h6", "div"].forEach(function (tag) {
|
|
493
|
+
$(tag).each(function () {
|
|
494
|
+
var nodeId = $(this).attr("id") || "";
|
|
495
|
+
var isListItem = $(this).attr("data-list-item") === "true";
|
|
496
|
+
var inListItem = $(this).closest("[data-list-item='true']").length > 0;
|
|
497
|
+
if (!nodeId.startsWith("PA_RichTextHrefId_") && !isListItem && !inListItem) {
|
|
498
|
+
nodeArr.push(this);
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
nodeArr.forEach(function (node) {
|
|
503
|
+
var tag = $(node).prop("tagName");
|
|
504
|
+
var nodeId = $(node).attr("id") || "";
|
|
505
|
+
// 处理子元素:将text转为div,但保留link节点
|
|
506
|
+
$(node)
|
|
507
|
+
.children("text")
|
|
508
|
+
.each(function () {
|
|
509
|
+
var inListItem = $(this).closest("[data-list-item='true']").length > 0;
|
|
510
|
+
if (inListItem)
|
|
511
|
+
return;
|
|
512
|
+
var text = $(this).html();
|
|
513
|
+
var style = $(this).attr("style") || "";
|
|
514
|
+
// 检查是否包含link节点
|
|
515
|
+
var hasLink = $(this).find('[id^="PA_RichTextHrefId_"]').length > 0;
|
|
516
|
+
if (hasLink) {
|
|
517
|
+
// 如果包含link节点,需要特殊处理以保持link在正确位置
|
|
518
|
+
var $tempDiv = $("<div style=\"".concat(mergeStyles(style, "word-break: break-word", "flex-shrink: 0", "flex-direction: row"), "\">").concat(text, "</div>"));
|
|
519
|
+
$(this).replaceWith($tempDiv);
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
// 普通text节点直接转换
|
|
523
|
+
$(this).replaceWith("<div style=\"".concat(mergeStyles(style, "word-break: break-word", "flex-shrink: 0", "flex-direction: row"), "\">").concat(text, "</div>"));
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
var tagHtml = $(node).html() || "";
|
|
527
|
+
var tagStyle = $(node).attr("style") || "";
|
|
528
|
+
if (tagHtml.trim()) {
|
|
529
|
+
var idAttr = nodeId ? " id=\"".concat(nodeId, "\"") : "";
|
|
530
|
+
var customAttrs = "";
|
|
531
|
+
var attribs = ($(node).get(0) || {}).attribs || {};
|
|
532
|
+
for (var _i = 0, _a = Object.entries(attribs); _i < _a.length; _i++) {
|
|
533
|
+
var _b = _a[_i], k = _b[0], v = _b[1];
|
|
534
|
+
if (k !== "style" && k !== "id") {
|
|
535
|
+
customAttrs += " ".concat(k, "=\"").concat(v, "\"");
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
// 保证外层tag的style不合并子div的style
|
|
539
|
+
$(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, ">"));
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
};
|
|
543
|
+
/** text-indent 首行缩进处理 */
|
|
544
|
+
RichText_Refactor.handleTextIndent = function ($) {
|
|
545
|
+
$("*").each(function () {
|
|
546
|
+
var textIndent = $(this).css("text-indent");
|
|
547
|
+
if (textIndent) {
|
|
548
|
+
var repeatCnt = parseInt(textIndent);
|
|
549
|
+
if (repeatCnt > 0) {
|
|
550
|
+
var spacer = "<div style=\"".concat(mergeStyles("color: transparent", "flex-shrink: 0", "font-size: 16px"), "\">").concat("一".repeat(repeatCnt), "</div>");
|
|
551
|
+
var textChild = $(this).children("text").first();
|
|
552
|
+
if (textChild.length > 0) {
|
|
553
|
+
var first = textChild.children().first();
|
|
554
|
+
if (first.length > 0)
|
|
555
|
+
first.before(spacer);
|
|
556
|
+
else
|
|
557
|
+
textChild.append(spacer);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
};
|
|
563
|
+
/** line-height / letter-spacing 调整 */
|
|
564
|
+
RichText_Refactor.adjustLineHeightAndLetterSpacing = function ($, config) {
|
|
565
|
+
$("text").each(function () {
|
|
566
|
+
var $text = $(this);
|
|
567
|
+
var maxLineHeight = 0;
|
|
568
|
+
$text.children("div").each(function () {
|
|
569
|
+
var lh = parseInt($(this).css("line-height") || "1");
|
|
570
|
+
maxLineHeight = Math.max(maxLineHeight, lh);
|
|
571
|
+
});
|
|
572
|
+
var scale = (config === null || config === void 0 ? void 0 : config.lineHeightScale) || 1;
|
|
573
|
+
if (maxLineHeight > 0) {
|
|
574
|
+
var currentStyle = $text.attr("style") || "";
|
|
575
|
+
$text.attr("style", mergeStyles(currentStyle, "line-height: ".concat(maxLineHeight * scale)));
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
$("text").each(function () {
|
|
579
|
+
var $text = $(this);
|
|
580
|
+
var maxLS = 0;
|
|
581
|
+
$text.children("div").each(function () {
|
|
582
|
+
var ls = $(this).css("letter-spacing") || "0";
|
|
583
|
+
var lsNum = parseInt(ls);
|
|
584
|
+
maxLS = Math.max(maxLS, lsNum);
|
|
585
|
+
});
|
|
586
|
+
if (maxLS > 0) {
|
|
587
|
+
var currentStyle = $text.attr("style") || "";
|
|
588
|
+
$text.attr("style", mergeStyles(currentStyle, "letter-spacing: ".concat(maxLS, "rem")));
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
};
|
|
592
|
+
/** 把 div 的 text-align 转移到子 text 上 */
|
|
593
|
+
RichText_Refactor.transferTextAlign = function ($) {
|
|
594
|
+
$("div").each(function () {
|
|
595
|
+
var ta = $(this).css("text-align") || "";
|
|
596
|
+
if (ta) {
|
|
597
|
+
$(this)
|
|
598
|
+
.children("text")
|
|
599
|
+
.each(function () {
|
|
600
|
+
var currentStyle = $(this).attr("style") || "";
|
|
601
|
+
$(this).attr("style", mergeStyles(currentStyle, "text-align: ".concat(ta)));
|
|
602
|
+
});
|
|
603
|
+
// 清除div的text-align
|
|
604
|
+
var currentStyle = $(this).attr("style") || "";
|
|
605
|
+
var styleObj = parseStyleString(currentStyle);
|
|
606
|
+
delete styleObj["text-align"];
|
|
607
|
+
$(this).attr("style", serializeStyleObject(styleObj));
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
};
|
|
611
|
+
/** 删除空 text 节点 */
|
|
612
|
+
RichText_Refactor.removeEmptyText = function ($) {
|
|
613
|
+
$("text").each(function () {
|
|
614
|
+
var t = $(this).html() || "";
|
|
615
|
+
if (t.trim() === "")
|
|
616
|
+
$(this).remove();
|
|
617
|
+
});
|
|
618
|
+
};
|
|
619
|
+
/** 补默认 heading 字体大小 */
|
|
620
|
+
RichText_Refactor.fixHeadingFontSize = function ($) {
|
|
621
|
+
var hRem = ["2rem", "1.5rem", "1.17rem", "1rem", "0.83rem", "0.67rem"];
|
|
622
|
+
["h1", "h2", "h3", "h4", "h5", "h6"].forEach(function (tag) {
|
|
623
|
+
$(tag).each(function () {
|
|
624
|
+
var idx = parseInt(tag.replace("h", "")) - 1;
|
|
625
|
+
var style = $(this).attr("style") || "";
|
|
626
|
+
if (!style.includes("font-size")) {
|
|
627
|
+
$(this).attr("style", mergeStyles(style, "font-size:".concat(hRem[idx])));
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
});
|
|
631
|
+
};
|
|
632
|
+
// 存储需要绑定点击事件的节点
|
|
633
|
+
RichText_Refactor.linkNodes = [];
|
|
634
|
+
RichText_Refactor.hrefIdCnt = 0;
|
|
635
|
+
return RichText_Refactor;
|
|
636
|
+
}());
|
|
637
|
+
exports.RichText_Refactor = RichText_Refactor;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixui-dev/pixui-richtext-helper",
|
|
3
|
-
"version": "0.1.1-beta.
|
|
3
|
+
"version": "0.1.1-beta.3",
|
|
4
4
|
"description": "pixui richtext helper",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
"author": "jnjnjnzhang",
|
|
20
20
|
"license": "ISC",
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@types/node": "^22.
|
|
23
|
-
"
|
|
22
|
+
"@types/node": "^22.15.33",
|
|
23
|
+
"ts-node": "^10.9.2",
|
|
24
|
+
"typescript": "^5.8.3"
|
|
24
25
|
},
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"cheerio": "1.0.0-rc.10"
|