You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
8.5 KiB
248 lines
8.5 KiB
2 years ago
|
/* 配置文件 */
|
||
|
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
|
||
|
}
|