初始化代码

This commit is contained in:
2025-12-22 17:13:05 +08:00
parent ed0de08e3a
commit 1f7e9d401b
2947 changed files with 526137 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
/*
解析和匹配 Css 的选择器
github地址https://github.com/jin-yufeng/Parser
文档地址https://jin-yufeng.github.io/Parser
authorJinYufeng
*/
const userAgentStyles = require("./config.js").userAgentStyles;
class CssHandler {
constructor(tagStyle = {}) {
this.styles = Object.assign({}, tagStyle);
};
getStyle(data) {
var style = '';
data = data.replace(/<[sS][tT][yY][lL][eE][\s\S]*?>([\s\S]*?)<\/[sS][tT][yY][lL][eE][\s\S]*?>/g, function() {
style += arguments[1];
return '';
})
this.styles = new CssParser(style, this.styles).parse();
return data;
};
parseCss(css) {
return new CssParser(css, {}, true).parse();
};
match(name, attrs) {
var tmp, matched = ((tmp = this.styles[name]) ? (tmp + ';') : '');
if (attrs.class) {
var classes = attrs.class.split(' ');
for (var i = 0; i < classes.length; i++)
if (tmp = this.styles['.' + classes[i]])
matched += (tmp + ';');
}
if (tmp = this.styles['#' + attrs.id])
matched += tmp;
return matched;
};
}
module.exports = CssHandler;
function isBlankChar(c) {
return c == ' ' || c == '\u00A0' || c == '\t' || c == '\r' || c == '\n' || c == '\f';
};
class CssParser {
constructor(data, tagStyle, api) {
this.data = data;
this.res = tagStyle;
if (!api)
for (var item in userAgentStyles) {
if (tagStyle[item]) tagStyle[item] = userAgentStyles[item] + ';' + tagStyle[item];
else tagStyle[item] = userAgentStyles[item];
}
this._floor = 0;
this._i = 0;
this._list = [];
this._comma = false;
this._sectionStart = 0;
this._state = this.Space;
};
parse() {
for (; this._i < this.data.length; this._i++)
this._state(this.data[this._i]);
return this.res;
};
// 状态机
Space(c) {
if (c == '.' || c == '#' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
this._sectionStart = this._i;
this._state = this.StyleName;
} else if (c == '/' && this.data[this._i + 1] == '*')
this.Comment();
else if (!isBlankChar(c) && c != ';')
this._state = this.Ignore;
};
Comment() {
this._i = this.data.indexOf("*/", this._i);
if (this._i == -1) this._i = this.data.length;
this._i++;
this._state = this.Space;
};
Ignore(c) {
if (c == '{') this._floor++;
else if (c == '}' && --this._floor <= 0) {
this._list = [];
this._state = this.Space;
}
};
StyleName(c) {
if (isBlankChar(c)) {
this._list.push(this.data.substring(this._sectionStart, this._i));
this._state = this.NameSpace;
} else if (c == '{') {
this._list.push(this.data.substring(this._sectionStart, this._i));
this._floor = 1;
this._sectionStart = this._i + 1;
this.Content();
} else if (c == ',') {
this._list.push(this.data.substring(this._sectionStart, this._i));
this._sectionStart = this._i + 1;
this._comma = true;
} else if (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9') && c != '.' && c != '#' &&
c != '-' && c != '_')
this._state = this.Ignore;
};
NameSpace(c) {
if (c == '{') {
this._floor = 1;
this._sectionStart = this._i + 1;
this.Content();
} else if (c == ',') {
this._comma = true;
this._sectionStart = this._i + 1;
this._state = this.StyleName;
} else if (!isBlankChar(c)) {
if (this._comma) {
this._state = this.StyleName;
this._sectionStart = this._i;
this._i--;
this._comma = false;
} else this._state = this.Ignore;
}
};
Content() {
this._i = this.data.indexOf('}', this._i);
if (this._i == -1) this._i = this.data.length;
// 去除空白符
var flag = false,
pos, content = this.data.substring(this._sectionStart, this._i);
for (var i = 0; i < content.length; i++) {
if (isBlankChar(content[i])) {
if (!flag) {
pos = i;
flag = true;
}
} else {
if (flag) {
if (pos == 0) content = content.substring(i);
else if (i - pos > 1) content = content.substring(0, pos) + (content[pos - 1] == ';' ? (pos--, '') : ' ') +
content.substring(i);
i = pos;
flag = false;
}
}
}
if (flag) content = content.substring(0, pos);
for (var i = 0; i < this._list.length; i++)
this.res[this._list[i]] = (this.res[this._list[i]] || '') + content;
this._list = [];
this._state = this.Space;
}
}

View File

@@ -0,0 +1,430 @@
/*
将 html 解析为适用于小程序 rich-text 的 DOM 结构
github地址https://github.com/jin-yufeng/Parser
文档地址https://jin-yufeng.github.io/Parser
authorJinYufeng
*/
const CssHandler = require("./CssHandler.js");
const config = require("./config.js");
var emoji; // 需要使用 emoji 补丁包时将此行改为 const emoji = require("./emoji.js");
function isBlankChar(c) {
return c == ' ' || c == '\u00A0' || c == '\t' || c == '\r' || c == '\n' || c == '\f';
};
class MpHtmlParser {
constructor(data, options = {}, cb) {
this.cb = cb;
this.CssHandler = new CssHandler(options.tagStyle);
this.data = data;
this.DOM = [];
// #ifdef MP-BAIDU || MP-TOUTIAO
this._imgMode = options.imgMode;
// #endif
this._attrName = '';
this._attrValue = '';
this._attrs = {};
this._domain = options.domain;
this._protocol = options.domain ? (options.domain.includes("://") ? this._domain.split("://")[0] : "http") :
undefined;
this._i = 0;
this._sectionStart = 0;
this._state = this.Text;
this._STACK = [];
this._tagName = '';
this._audioNum = 0;
this._imgNum = 0;
this._videoNum = 0;
this._useAnchor = options.useAnchor;
this._whiteSpace = false;
};
parse() {
if (this.CssHandler) this.data = this.CssHandler.getStyle(this.data);
if (emoji) this.data = emoji.parseEmoji(this.data);
// 高亮处理
if (config.highlight)
this.data = this.data.replace(/<[pP][rR][eE]([\s\S]*?)>([\s\S]*?)<\/[pP][rR][eE][\s\S]*?>/g, function() {
return "<pre" + arguments[1] + '>' + config.highlight(arguments[2], "<pre" + arguments[1] + '>') + "</pre>";
})
for (var len = this.data.length; this._i < len; this._i++)
this._state(this.data[this._i]);
if (this._state == this.Text) this.setText();
while (this._STACK.length)
this.popNode(this._STACK.pop());
// #ifdef MP-BAIDU || MP-TOUTIAO
const inlineTags = config.makeMap("abbr,b,big,code,del,em,font,i,ins,label,mark,q,s,small,span,strong,sub,sup,u")
// 将顶层标签的一些样式提取出来给 rich-text
const setContain = function(nodes) {
for (var element of nodes) {
if (element.type == "text")
continue;
if (!element.c) {
var res = "";
var style = element.attrs.style;
var reg = /float[^;]+(?![\s\S]*?float)/i;
if (reg.test(style)) res += reg.exec(style)[0];
reg = /margin[^;]+/gi;
if (reg.test(style)) res += (';' + style.match(reg).join(';'));
reg = /display\s*:\s*([^;]*)(?![\s\S]*?display)/i;
if (reg.test(style) && reg.exec(style)[1] != "flex") res += (';' + reg.exec(style)[0]);
else if (inlineTags[element.name]) res += ";display:inline";
else res += (";display:" + (element.name == 'img' ? 'inline-block' : 'block'));
reg = /flex[^;]*:[^;]+/gi;
if (reg.test(style)) res += (';' + style.match(reg).join(';'));
reg = /[^;\s]*width[^;]+/gi;
if (reg.test(style)) res += (';' + style.match(reg).join(';'));
element.attrs.containStyle = res;
if (/[^-]width[^pev;]+/.test(";" + style))
element.attrs.style += ";width:100%";
let addMargin = "";
if (/margin\s*:/.test(style)) addMargin = ';margin:0';
else if (/margin-top/.test(style)) addMargin = ';margin-top:0';
else if (/margin-bottom/.test(style)) addMargin = ';margin-bottom:0';
element.attrs.style = (element.attrs.style || '').replace(/margin[^;]*/gi, "");
element.attrs.style += addMargin;
} else setContain(element.children);
}
};
setContain(this.DOM);
// #endif
if (this.DOM.length) this.DOM[0].PoweredBy = "Parser";
// console.log(this.DOM)
if (this.cb)
this.cb(this.DOM)
else return this.DOM;
};
// 设置属性
setAttr() {
if (config.trustAttrs[this._attrName])
this._attrs[this._attrName] = (this._attrValue ? this._attrValue : (this._attrName == "src" ? "" : "true"));
this._attrValue = '';
while (isBlankChar(this.data[this._i])) this._i++;
if (this.checkClose()) this.setNode();
else this._state = this.AttrName;
};
// 设置文本节点
setText() {
var text = this.getSelection();
if (text) {
if (!this._whiteSpace) {
// 移除空白符
var flag = false,
has = false,
pos;
for (var i = 0; i < text.length; i++) {
if (isBlankChar(text[i])) {
if (!flag) {
pos = i;
flag = true;
}
} else {
has = true;
if (flag) {
if (i - pos > 1) text = text.substring(0, pos) + ' ' + text.substring(i);
i = pos;
flag = false;
}
}
}
if (flag) text = text.substring(0, pos) + ' ';
if (!text || !has) return;
}
// 检查实体
// #ifdef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO
var entities = {
lt: "<",
gt: ">",
amp: "&",
quot: '"',
apos: "'",
nbsp: "\u00A0",
ensp: "\u2002",
emsp: "\u2003",
ndash: "",
mdash: "—",
middot: "·",
lsquo: "",
rsquo: "",
ldquo: "“",
rdquo: "”",
bull: "•",
hellip: "…",
permil: "‰",
copy: "©",
reg: "®",
trade: "™",
times: "×",
divide: "÷",
cent: "¢",
pound: "£",
yen: "¥",
euro: "€",
sect: "§"
};
// #endif
var i = text.indexOf('&'),
j, decode;
while (i != -1 && i < text.length) {
j = text.indexOf(';', i);
if (j - i >= 2 && j - i <= 7) {
var entity = text.substring(i + 1, j);
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
if (!entity.includes("sp") && !entity.includes("lt") && !entity.includes("gt")) {
decode = true
break;
}
// #endif
// #ifdef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO
if (entities[entity]) text = text.substring(0, i) + entities[entity] + text.substring(j + 1);
// #endif
}
i = text.indexOf('&', i + 1);
}
var slibings = this._STACK.length ? this._STACK[this._STACK.length - 1].children : this.DOM;
if (slibings.length && slibings[slibings.length - 1].type == "text") {
slibings[slibings.length - 1].text += text;
if (decode) slibings[slibings.length - 1].decode = true;
} else
slibings.push({
type: "text",
text,
decode
})
}
};
// 设置元素节点
setNode() {
var slibings = this._STACK.length ? this._STACK[this._STACK.length - 1].children : this.DOM;
var node = {
name: this._tagName.toLowerCase(),
attrs: this._attrs
}
config.LabelAttrsHandler(node, this);
this._attrs = {};
if (this.data[this._i] == '>') {
if (!config.selfClosingTags[this._tagName]) {
if (config.ignoreTags[node.name]) {
var j = this._i;
// 处理要被移除的标签
while (this._i < this.data.length) {
this._i = this.data.indexOf("</", this._i);
if (this._i == -1) return this._i = this.data.length;
this._i += 2;
this._sectionStart = this._i;
while (!isBlankChar(this.data[this._i]) && this.data[this._i] != '>' && this.data[this._i] != '/') this._i++;
if (this.data.substring(this._sectionStart, this._i).toLowerCase() == node.name) {
this._i = this.data.indexOf('>', this._i);
if (this._i == -1) this._i = this.data.length;
else this._sectionStart = this._i + 1;
this._state = this.Text;
// 处理svg
if (node.name == "svg") {
var src = this.data.substring(j, this._i + 1);
if (!node.attrs.xmlns) src = " xmlns=\"http://www.w3.org/2000/svg\"" + src;
this._i = j;
while (this.data[j] != '<') j--;
src = this.data.substring(j, this._i) + src;
this._i = this._sectionStart - 1;
node.name = "img";
node.attrs = {
src: "data:image/svg+xml;utf8," + src.replace(/#/g, "%23"),
ignore: "true"
}
slibings.push(node);
}
break;
}
}
return;
} else this._STACK.push(node);
node.children = [];
}
} else this._i++;
this._sectionStart = this._i + 1;
this._state = this.Text;
if (!config.ignoreTags[node.name]) {
// 检查空白符是否有效
if (node.name == "pre" || (node.attrs.style && node.attrs.style.toLowerCase().includes("white-space") && node.attrs
.style.toLowerCase().includes("pre"))) {
this._whiteSpace = true;
node.pre = true;
}
slibings.push(node);
}
};
// 标签出栈处理
popNode(node) {
// 替换一些标签名
if (config.blockTags[node.name]) node.name = 'div';
else if (!config.trustTags[node.name]) node.name = 'span';
// 空白符处理
if (node.pre) {
this._whiteSpace = false;
node.pre = undefined;
for (var i = 0; i < this._STACK.length; i++)
if (this._STACK[i].pre)
this._whiteSpace = true;
}
// 处理表格的边框
if (node.name == 'table') {
if (node.attrs.border)
node.attrs.style = "border:" + node.attrs.border + "px solid gray;" + (node.attrs.style || '');
if (node.attrs.hasOwnProperty("cellspacing"))
node.attrs.style = "border-spacing:" + node.attrs.cellspacing + "px;" + (node.attrs.style || '');
function setBorder(elem) {
if (elem.name == 'th' || elem.name == 'td') {
if (node.attrs.border)
elem.attrs.style = "border:" + node.attrs.border + "px solid gray;" + (elem.attrs.style || '');
if (node.attrs.hasOwnProperty("cellpadding"))
elem.attrs.style = "padding:" + node.attrs.cellpadding + "px;" + (elem.attrs.style || '');
return;
}
if (elem.type == 'text') return;
for (var i = 0; i < elem.children.length; i++)
setBorder(elem.children[i]);
}
if (node.attrs.border || node.attrs.hasOwnProperty("cellpadding"))
for (var i = 0; i < node.children.length; i++)
setBorder(node.children[i]);
}
// 合并一些不必要的层,减小节点深度
if (node.children.length == 1 && node.name == "div" && node.children[0].name == "div") {
var child = node.children[0];
node.attrs.style = node.attrs.style || '';
child.attrs.style = child.attrs.style || '';
if (node.attrs.style.includes("padding") && (node.attrs.style.includes("margin") || child.attrs.style.includes(
"margin")) && node.attrs.style.includes("display") && child.attrs.style.includes("display") && !(node.attrs.id &&
node.attrs.id) && !(node.attrs.class && child.attrs.class)) {
if (child.attrs.style.includes("padding"))
child.attrs.style = "box-sizing:border-box;" + child.attrs.style;
node.attrs.style = node.attrs.style + ";" + child.attrs.style;
node.attrs.id = (child.attrs.id || '') + (node.attrs.id || '');
node.attrs.class = (child.attrs.class || '') + (node.attrs.class || '');
node.children = child.children;
}
}
// 多层样式处理
if (this.CssHandler.pop)
this.CssHandler.pop(node);
};
// 工具函数
checkClose() {
if (this.data[this._i] == '>' || (this.data[this._i] == '/' && this.data[this._i + 1] == '>'))
return true;
return false;
};
getSelection(trim) {
var str = (this._sectionStart == this._i ? '' : this.data.substring(this._sectionStart, this._i));
while (trim && isBlankChar(this.data[++this._i]));
if (trim) this._i--;
this._sectionStart = this._i + 1;
return str;
};
// 状态机
Text(c) {
if (c == '<') {
var next = this.data[this._i + 1];
if ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z')) {
this.setText();
this._state = this.TagName;
} else if (next == '/') {
this.setText();
this._i++;
next = this.data[this._i + 1];
if ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z')) {
this._sectionStart = this._i + 1;
this._state = this.EndTag;
} else
this._state = this.Comment;
} else if (next == '!') {
this.setText();
this._state = this.Comment;
}
}
};
Comment() {
if (this.data.substring(this._i + 1, this._i + 3) == "--" || this.data.substring(this._i + 1, this._i + 7) ==
"[CDATA[") {
this._i = this.data.indexOf("-->", this._i + 1);
if (this._i == -1) return this._i = this.data.length;
else this._i = this._i + 2;
} else {
this._i = this.data.indexOf(">", this._i + 1);
if (this._i == -1) return this._i = this.data.length;
}
this._sectionStart = this._i + 1;
this._state = this.Text;
};
TagName(c) {
if (isBlankChar(c)) {
this._tagName = this.getSelection(true);
if (this.checkClose()) this.setNode();
else this._state = this.AttrName;
} else if (this.checkClose()) {
this._tagName = this.getSelection();
this.setNode();
}
};
AttrName(c) {
if (isBlankChar(c)) {
this._attrName = this.getSelection(true).toLowerCase();
if (this.data[this._i] == '=') {
while (isBlankChar(this.data[++this._i]));
this._sectionStart = this._i;
this._i--;
this._state = this.AttrValue;
} else this.setAttr();
} else if (c == '=') {
this._attrName = this.getSelection().toLowerCase();
while (isBlankChar(this.data[++this._i]));
this._sectionStart = this._i;
this._i--;
this._state = this.AttrValue;
} else if (this.checkClose()) {
this._attrName = this.getSelection().toLowerCase();
this.setAttr();
}
};
AttrValue(c) {
if (c == '"' || c == "'") {
this._sectionStart++;
if ((this._i = this.data.indexOf(c, this._i + 1)) == -1) return this._i = this.data.length;
} else
for (; !isBlankChar(this.data[this._i] && this.data[this._i] != '/' && this.data[this._i] != '>'); this._i++);
this._attrValue = this.getSelection();
while (this._attrValue.includes("&quot;")) this._attrValue = this._attrValue.replace("&quot;", '');
this.setAttr();
};
EndTag(c) {
if (isBlankChar(c) || c == '>' || c == '/') {
var name = this.getSelection().toLowerCase();
var flag = false;
for (var i = this._STACK.length - 1; i >= 0; i--)
if (this._STACK[i].name == name) {
flag = true;
break;
}
if (flag) {
var node;
while (flag) {
node = this._STACK.pop();
if (node.name == name) flag = false;
this.popNode(node);
}
} else if (name == 'p' || name == "br") {
var slibings = this._STACK.length ? this._STACK[this._STACK.length - 1].children : this.DOM;
var node = {
name
}
slibings.push(node);
}
this._i = this.data.indexOf('>', this._i);
if (this._i == -1) this._i = this.data.length;
else this._state = this.Text;
}
};
};
module.exports = {
parseHtml: (data, options) => new Promise((resolve) => new MpHtmlParser(data, options, resolve).parse()),
parseHtmlSync: (data, options) => new MpHtmlParser(data, options).parse()
};

View File

@@ -0,0 +1,247 @@
// <<<<<<< HEAD
/* 配置文件 */
// =======
/* 配置文件 xxx*/
// >>>>>>> 53c74b30a29ef2e569158438db4f5df4b7480643
function makeMap(str) {
var map = Object.create(null),
list = str.split(',');
for (var item of list)
map[item] = true;
return map;
}
// 信任的属性列表,不在列表中的属性将被移除
const trustAttrs = makeMap(
"align,alt,app-id,appId,"
// #ifdef MP-BAIDU
+
"appid,apid,"
// #endif
+
"author,autoplay,border,cellpadding,cellspacing,class,color,colspan,controls,data-src,dir,face,height,href,id,ignore,loop,muted,name,path,poster,rowspan,size,span,src,start,style,type,lbType,lbtype,"
// #ifdef MP-WEIXIN || MP-QQ
+
"unit-id,unitId,"
// #endif
+
"width,xmlns"
);
// 信任的标签,将保持标签名不变
const trustTags = makeMap(
"a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,u,ul,video,iframe"
);
// 块级标签,将被转为 div
const blockTags = makeMap("address,article,aside,body,center,cite,footer,header,html,nav,pre,section");
// 被移除的标签(其中 svg 系列标签会被转为图片)
const ignoreTags = makeMap(
"area,base,basefont,canvas,circle,command,ellipse,embed,frame,head,input,isindex,keygen,line,link,map,meta,param,path,polygon,rect,script,source,svg,textarea,track,use,wbr,"
);
// 只能用 rich-text 显示的标签(其中图片不能预览、不能显示视频、音频等)
const richOnlyTags = makeMap(
"a,ad,audio,colgroup,fieldset,legend,li,ol,sub,sup,table,tbody,td,tfoot,th,thead,tr,ul,video,iframe,");
// 自闭合标签
const selfClosingTags = makeMap(
"area,base,basefont,br,col,circle,ellipse,embed,frame,hr,img,input,isindex,keygen,line,link,meta,param,path,polygon,rect,source,track,use,wbr,"
);
// 默认的标签样式
var userAgentStyles = {
a: "color:#366092;word-break:break-all;padding:1.5px 0 1.5px 0",
address: "font-style:italic",
blockquote: "background-color:#f6f6f6;border-left:3px solid #dbdbdb;color:#6c6c6c;padding:5px 0 5px 10px",
center: "text-align:center",
cite: "font-style:italic",
code: "padding:0 1px 0 1px;margin-left:2px;margin-right:2px;background-color:#f8f8f8;border-radius:3px",
dd: "margin-left:40px",
img: "max-width:100%",
mark: "background-color:yellow",
pre: "font-family:monospace;white-space:pre;overflow:scroll",
s: "text-decoration:line-through",
u: "text-decoration:underline"
};
// #ifndef MP-ALIPAY || H5
const SDKVersion = uni.getSystemInfoSync().SDKVersion;
function versionHigherThan(version = '') {
var v1 = SDKVersion.split('.'),
v2 = version.split('.');
while (v1.length != v2.length)
v1.length < v2.length ? v1.push('0') : v2.push('0');
for (var i = 0; i < v1.length; i++) {
if (v1[i] == v2[i]) continue;
if (parseInt(v1[i]) > parseInt(v2[i])) return true;
return false;
}
return true;
};
// #endif
// #ifdef MP-WEIXIN || MP-QQ
// 版本兼容
if (versionHigherThan("2.7.1")) {
trustTags.bdi = true;
trustTags.bdo = true;
trustTags.caption = true;
trustTags.rt = true;
trustTags.ruby = true;
ignoreTags.rp = true;
trustTags.big = true;
trustTags.small = true;
trustTags.pre = true;
trustTags.iframe = true;
richOnlyTags.bdi = true;
richOnlyTags.bdo = true;
richOnlyTags.caption = true;
richOnlyTags.rt = true;
richOnlyTags.ruby = true;
richOnlyTags.pre = true;
blockTags.pre = undefined;
} else {
blockTags.caption = true;
userAgentStyles.big = "display:inline;font-size:1.2em";
userAgentStyles.small = "display:inline;font-size:0.8em";
}
// #endif
function bubbling(Parser) {
for (var i = Parser._STACK.length - 1; i >= 0; i--) {
if (!richOnlyTags[Parser._STACK[i].name])
Parser._STACK[i].c = 1;
else return false;
}
return true;
}
module.exports = {
// 高亮处理函数
highlight: null,
// 处理标签的属性,需要通过组件递归方式显示的标签需要调用 bubbling(Parser)
LabelAttrsHandler(node, Parser) {
node.attrs.style = Parser.CssHandler.match(node.name, node.attrs, node) + (node.attrs.style || '');
switch (node.name) {
case "ul":
case "ol":
case "li":
case "dd":
case "dl":
case "dt":
case "div":
case "span":
case "em":
case 'p':
let default_p_style = "max-width: 100% !important;display:block;"
if (node.attrs.style) {
node.attrs.style = node.attrs.style.includes('width:') ? default_p_style : node.attrs.style + default_p_style
}
if (node.attrs.align) {
node.attrs.style = "text-align:" + node.attrs.align + ';' + node.attrs.style;
node.attrs.align = undefined;
}
break;
case "img":
if (node.attrs.height) {
node.attrs.height = 'auto'
}
let default_style = "max-width: 100% !important;display:block;"
if (node.attrs.style) {
node.attrs.style = node.attrs.style.includes('height:') ? default_style : node.attrs.style + default_style
}
if (node.attrs["data-src"]) {
node.attrs.src = node.attrs.src || node.attrs["data-src"];
node.attrs["data-src"] = undefined;
}
// #ifdef MP-BAIDU || MP-TOUTIAO
if (Parser._imgMode == "widthFix") node.attrs.style = node.attrs.style + ";height:auto !important;";
// #endif
if (node.attrs.src) {
if (!node.attrs.ignore) {
if (bubbling(Parser)) node.attrs.i = (Parser._imgNum++).toString();
else node.attrs.ignore = "true";
}
if (Parser._domain && node.attrs.src[0] == '/') {
if (node.attrs.src[1] == '/') node.attrs.src = Parser._protocol + ":" + node.attrs.src;
else node.attrs.src = Parser._domain + node.attrs.src;
}
}
break;
case 'a':
case "ad":
bubbling(Parser);
break;
case "font":
if (node.attrs.color) {
node.attrs.style = "color:" + node.attrs.color + ';' + node.attrs.style;
node.attrs.color = undefined;
}
if (node.attrs.face) {
node.attrs.style = "font-family:" + node.attrs.face + ';' + node.attrs.style;
node.attrs.face = undefined;
}
if (node.attrs.size) {
var size = parseInt(node.attrs.size);
if (size < 1) size = 1;
else if (size > 7) size = 7;
var map = ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"];
node.attrs.style = "font-size:" + map[size - 1] + ';' + node.attrs.style;
node.attrs.size = undefined;
}
break;
case 'iframe':
case "video":
case "audio":
node.attrs.loop = node.attrs.hasOwnProperty('loop') || false;
node.attrs.controls = node.attrs.hasOwnProperty(
'controls') || true;
node.attrs.autoplay = node.attrs.hasOwnProperty('autoplay') || false;
if (node.attrs.id) Parser['_' + node.name + "Num"]++;
else node.attrs.id = (node.name + (++Parser['_' + node.name + "Num"]));
if (node.name == "video") {
node.attrs.style = node.attrs.style || '';
if (node.attrs.width) {
node.attrs.style = "width:" + parseFloat(node.attrs.width) + (node.attrs.height.includes('%') ? '%' : "px") +
';' + node.attrs.style;
node.attrs.width = undefined;
}
if (node.attrs.height) {
node.attrs.style = "height:" + parseFloat(node.attrs.height) + (node.attrs.height.includes('%') ? '%' : "px") +
';' + node.attrs.style;
node.attrs.height = undefined;
}
if (Parser._videoNum > 3) node.lazyLoad = true;
}
// 新增iframe【create_by_xx】
if (node.name == 'iframe') {
// console.log(node.attrs, "====iframe attrs");
}
node.attrs.source = [];
if (node.attrs.src) node.attrs.source.push(node.attrs.src);
if (!node.attrs.controls && !node.attrs.autoplay)
console.warn("存在没有controls属性的 " + node.name + " 标签,可能导致无法播放", node);
bubbling(Parser);
break;
case "source":
var parent = Parser._STACK[Parser._STACK.length - 1];
if (parent && (parent.name == "video" || parent.name == "audio")) {
parent.attrs.source.push(node.attrs.src);
if (!parent.attrs.src) parent.attrs.src = node.attrs.src;
}
break;
}
if (Parser._domain && node.attrs.style.includes("url"))
node.attrs.style = node.attrs.style.replace(/url\s*\(['"\s]*(\S*?)['"\s]*\)/, function() {
var src = arguments[1];
if (src && src[0] == '/') {
if (src[1] == '/') return "url(" + Parser._protocol + ':' + src + ')';
else return "url(" + Parser._domain + src + ')';
} else return arguments[0];
})
if (!node.attrs.style) node.attrs.style = undefined;
if (Parser._useAnchor && node.attrs.id) bubbling(Parser);
},
trustAttrs,
trustTags,
blockTags,
ignoreTags,
selfClosingTags,
userAgentStyles,
// #ifndef MP-ALIPAY || H5
versionHigherThan,
// #endif
makeMap
}