12 |
- // 小程序富文本插件 https://github.com/jin-yufeng/Parser
- "use strict";function _classCallCheck(t,i){if(!(t instanceof i))throw new TypeError("Cannot call a class as a function")}var _createClass=function(){function t(t,i){for(var s=0;s<i.length;s++){var e=i[s];e.enumerable=e.enumerable||!1,e.configurable=!0,"value"in e&&(e.writable=!0),Object.defineProperty(t,e.key,e)}}return function(i,s,e){return s&&t(i.prototype,s),e&&t(i,e),i}}(),cfg=require("./config.js"),blankChar=cfg.blankChar,CssHandler=require("./CssHandler.js"),screenWidth=wx.getSystemInfoSync().screenWidth;try{var emoji=require("./emoji.js")}catch(t){}var MpHtmlParser=function(){function t(i){var s=this,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};_classCallCheck(this,t),this.getName=function(t){return s.xml?t:t.toLowerCase()},this.isClose=function(){return">"==s.data[s.i]||"/"==s.data[s.i]&&">"==s.data[s.i+1]},this.section=function(){return s.data.substring(s.start,s.i)},this.parent=function(){return s.STACK[s.STACK.length-1]},this.siblings=function(){return s.STACK.length?s.parent().children:s.DOM},this.attrs={},this.compress=e.compress,this.CssHandler=new CssHandler(e.tagStyle,screenWidth),this.data=i,this.domain=e.domain,this.DOM=[],this.i=this.start=this.audioNum=this.imgNum=this.videoNum=0,this.protocol=this.domain&&this.domain.includes("://")?this.domain.split("://")[0]:"http",this.state=this.Text,this.STACK=[],this.useAnchor=e.useAnchor,this.xml=e.xml}return _createClass(t,[{key:"parse",value:function(){emoji&&(this.data=emoji.parseEmoji(this.data));for(var t;t=this.data[this.i];this.i++)this.state(t);for(this.state==this.Text&&this.setText();this.STACK.length;)this.popNode(this.STACK.pop());return this.DOM.length&&(this.DOM[0].PoweredBy="Parser",this.title&&(this.DOM[0].title=this.title)),this.DOM}},{key:"setAttr",value:function(){var t=this.getName(this.attrName);for(cfg.trustAttrs[t]&&(this.attrVal?this.attrs[t]="src"==t?this.getUrl(this.attrVal.replace(/&/g,"&")):this.attrVal:cfg.boolAttrs[t]&&(this.attrs[t]="T")),this.attrVal="";blankChar[this.data[this.i]];)this.i++;this.isClose()?this.setNode():(this.start=this.i,this.state=this.AttrName)}},{key:"setText",value:function(){var t,i=this.section();if(i)if(i=cfg.onText&&cfg.onText(i,function(){return t=!0})||i,t){this.data=this.data.substr(0,this.start)+i+this.data.substr(this.i);var s=this.start+i.length;for(this.i=this.start;this.i<s;this.i++)this.state(this.data[this.i])}else{if(!this.pre){for(var e,a=[],r=i.length;e=i[--r];)(!blankChar[e]||!blankChar[a[0]]&&(e=" "))&&a.unshift(e);if(" "==(i=a.join("")))return}for(var h,n,l=-1,o=this.siblings();;){if(-1==(l=i.indexOf("&",l+1)))break;if(-1==(h=i.indexOf(";",l+2)))break;"#"==i[l+1]?(n=parseInt(("x"==i[l+2]?"0":"")+i.substring(l+2,h)),isNaN(n)||(i=i.substr(0,l)+String.fromCharCode(n)+i.substr(h+1))):(n=i.substring(l+1,h),"nbsp"==n?i=i.substr(0,l)+" "+i.substr(h+1):"lt"!=n&&"gt"!=n&&"amp"!=n&&"ensp"!=n&&"emsp"!=n&&"quot"!=n&&"apos"!=n&&(l&&o.push({type:"text",text:i.substr(0,l)}),o.push({type:"text",text:"&"+n+";",en:1}),i=i.substr(h+1),l=-1))}i&&o.push({type:"text",text:i})}}},{key:"setNode",value:function(){var t={name:this.getName(this.tagName),attrs:this.attrs},i=cfg.selfClosingTags[t.name]||this.xml&&"/"==this.data[this.i];if(this.attrs={},cfg.ignoreTags[t.name])if(i)if("source"==t.name){var s=this.parent(),e=t.attrs;if(s&&e.src)if("video"==s.name||"audio"==s.name)s.attrs.source.push(e.src);else{var a,r=e.media;"picture"==s.name&&!s.attrs.src&&(!r||r.includes("px")&&(-1!=(a=r.indexOf("min-width"))&&-1!=(a=r.indexOf(":",a+8))&&screenWidth>parseInt(r.substr(a+1))||-1!=(a=r.indexOf("max-width"))&&-1!=(a=r.indexOf(":",a+8))&&screenWidth<parseInt(r.substr(a+1))))&&(s.attrs.src=e.src)}}else"base"!=t.name||this.domain||(this.domain=t.attrs.href);else this.remove(t);else this.matchAttr(t),i?cfg.filter&&0==cfg.filter(t,this)||this.siblings().push(t):(t.children=[],"pre"==t.name&&cfg.highlight&&(this.remove(t),this.pre=t.pre=!0),this.siblings().push(t),this.STACK.push(t));"/"==this.data[this.i]&&this.i++,this.start=this.i+1,this.state=this.Text}},{key:"remove",value:function(t){for(var i=t.name,s=this.i;;){if(-1==(this.i=this.data.indexOf("</",this.i+1)))return void(this.i="pre"==i||"svg"==i?s:this.data.length);for(this.start=this.i+=2;!blankChar[this.data[this.i]]&&!this.isClose();)this.i++;if(this.getName(this.section())==i){if("pre"==i)return this.data=this.data.substr(0,s+1)+cfg.highlight(this.data.substring(s+1,this.i-5),t.attrs)+this.data.substr(this.i-5),this.i=s;if("style"==i?this.CssHandler.getStyle(this.data.substring(s+1,this.i-7)):"title"==i&&(this.title=this.data.substring(s+1,this.i-7)),-1==(this.i=this.data.indexOf(">",this.i))&&(this.i=this.data.length),"svg"==i){var e=this.data.substring(s,this.i+1);t.attrs.xmlns||(e=' xmlns="http://www.w3.org/2000/svg"'+e);for(var a=s;"<"!=this.data[s];)s--;e=this.data.substring(s,a)+e;var r=this.parent();"100%"==t.attrs.width&&r&&(r.attrs.style||"").includes("inline")&&(r.attrs.style="width:300px;max-width:100%;"+r.attrs.style),this.siblings().push({name:"img",attrs:{src:"data:image/svg+xml;utf8,"+e.replace(/#/g,"%23")},svg:1})}return}}}},{key:"matchAttr",value:function(t){var i=t.attrs,s=this.CssHandler.match(t.name,i,t)+(i.style||""),e={};switch(i.id&&(1&this.compress?i.id=void 0:this.useAnchor&&this.bubble()),2&this.compress&&i.class&&(i.class=void 0),t.name){case"a":case"ad":this.bubble();break;case"font":if(i.color&&(e.color=i.color,i.color=void 0),i.face&&(e["font-family"]=i.face,i.face=void 0),i.size){var a=parseInt(i.size);a<1?a=1:a>7&&(a=7);var r=["xx-small","x-small","small","medium","large","x-large","xx-large"];e["font-size"]=r[a-1],i.size=void 0}break;case"video":case"audio":i.id?this[t.name+"Num"]++:i.id=t.name+ ++this[t.name+"Num"],"video"==t.name&&this.videoNum>3&&(t.lazyLoad=1),i.source=[],i.src&&i.source.push(i.src),i.controls||i.autoplay||console.warn("存在没有 controls 属性的 "+t.name+" 标签,可能导致无法播放",t),this.bubble();break;case"td":case"th":if(i.colspan||i.rowspan)for(var h,n=this.STACK.length;h=this.STACK[--n];)if("table"==h.name){h.c=void 0;break}}i.align&&(e["text-align"]=i.align,i.align=void 0),i.width&&(e.width=parseFloat(i.width)+(i.width.includes("%")?"%":"px"),i.width=void 0),i.height&&(e.height=parseFloat(i.height)+(i.height.includes("%")?"%":"px"),i.height=void 0);var l=s.replace(/"/g,'"').replace(/&/g,"&").split(";");s="";for(var o=0,c=l.length;o<c;o++){var d=l[o].split(":");if(!(d.length<2)){var u=d[0].trim().toLowerCase(),f=d.slice(1).join(":").trim();f.includes("-webkit")||f.includes("-moz")||f.includes("-ms")||f.includes("-o")||f.includes("safe")?s+=";"+u+":"+f:e[u]&&!f.includes("import")&&e[u].includes("import")||(e[u]=f)}}if("img"==t.name||"picture"==t.name){i["data-src"]&&(i.src=i.src||i["data-src"],i["data-src"]=void 0),!i.src&&"picture"!=t.name||i.ignore||(this.bubble()?((i.src||"").includes(".webp")&&(t.webp=1),i.i=(this.imgNum++).toString()):i.ignore="T"),i.ignore&&(e["max-width"]="100%");var m=function(t){return e[t]&&!e[t].includes("auto")};if(m("width")){var g=this.parent();e.width.includes("%")&&g&&(g.attrs.style||"").includes("inline")&&(g.attrs.style+=";max-width:100%",t.auto=1),parseInt(e.width)>screenWidth&&(e.height="auto"),m("height")&&(t.mode="scaleToFill")}else m("height")?t.mode="heightFix":t.auto=1}for(var p in e){var b=e[p];if((p.includes("flex")||"order"==p||"self-align"==p)&&(t.c=1),b.includes("url")){var v=b.indexOf("(");if(-1!=v++){for(;'"'==b[v]||"'"==b[v]||blankChar[b[v]];)v++;b=b.substr(0,v)+this.getUrl(b.substr(v))}}else b.includes("rpx")?b=b.replace(/[0-9.]+\s*rpx/g,function(t){return parseFloat(t)*screenWidth/750+"px"}):"white-space"==p&&b.includes("pre")&&(this.pre=t.pre=!0);s+=";"+p+":"+b}(s=s.substr(1))&&(i.style=s)}},{key:"popNode",value:function(t){if(t.pre){t.pre=this.pre=void 0;for(var i=this.STACK.length;i--;)this.STACK[i].pre&&(this.pre=!0)}if("head"==t.name||cfg.filter&&0==cfg.filter(t,this))return this.siblings().pop();var s=t.attrs;if("picture"==t.name)return t.name="img",s.src||"img"!=(t.children[0]||"").name||(s.src=t.children[0].attrs.src),t.children=void 0;if(cfg.blockTags[t.name]?t.name="div":cfg.trustTags[t.name]||(t.name="span"),t.c)if("ul"==t.name){for(var e=1,a=this.STACK.length;a--;)"ul"==this.STACK[a].name&&e++;if(1!=e)for(var r=t.children.length;r--;)t.children[r].floor=e}else if("ol"==t.name)for(var h,n=0,l=1;h=t.children[n++];)"li"==h.name&&(h.type="ol",h.num=function(t,i){if("a"==i)return String.fromCharCode(97+(t-1)%26);if("A"==i)return String.fromCharCode(65+(t-1)%26);if("i"==i||"I"==i){t=(t-1)%99+1;var s=["I","II","III","IV","V","VI","VII","VIII","IX"],e=["X","XX","XXX","XL","L","LX","LXX","LXXX","XC"],a=(e[Math.floor(t/10)-1]||"")+(s[t%10-1]||"");return"i"==i?a.toLowerCase():a}return t}(l++,s.type)+".");if("table"==t.name){var o=s.cellpadding,c=s.cellspacing,d=s.border;t.c&&(this.bubble(),s.style=(s.style||"")+";display:table",o||(o=2),c||(c=2)),d&&(s.style="border:"+d+"px solid gray;"+(s.style||"")),c&&(s.style="border-spacing:"+c+"px;"+(s.style||"")),(d||o||t.c)&&function i(s){for(var e,a=0;e=s[a];a++){var r=e.attrs.style||"";t.c&&"t"==e.name[0]&&(e.c=1,r+=";display:table-"+("th"==e.name||"td"==e.name?"cell":"tr"==e.name?"row":"row-group")),"th"==e.name||"td"==e.name?(d&&(r="border:"+d+"px solid gray;"+r),o&&(r="padding:"+o+"px;"+r)):i(e.children||[]),r&&(e.attrs.style=r)}}(t.children)}if(this.CssHandler.pop&&this.CssHandler.pop(t),"div"==t.name&&!Object.keys(s).length){var u=this.siblings();1==t.children.length&&"div"==t.children[0].name&&(u[u.length-1]=t.children[0])}}},{key:"bubble",value:function(){for(var t,i=this.STACK.length;t=this.STACK[--i];){if(cfg.richOnlyTags[t.name])return"table"!=t.name||Object.hasOwnProperty.call(t,"c")||(t.c=1),!1;t.c=1}return!0}},{key:"getUrl",value:function(t){return"/"==t[0]?"/"==t[1]?t=this.protocol+":"+t:this.domain&&(t=this.domain+t):this.domain&&0!=t.indexOf("data:")&&!t.includes("://")&&(t=this.domain+"/"+t),t}},{key:"Text",value:function(t){if("<"==t){var i=this.data[this.i+1],s=function(t){return t>="a"&&t<="z"||t>="A"&&t<="Z"};s(i)?(this.setText(),this.start=this.i+1,this.state=this.TagName):"/"==i?(this.setText(),s(this.data[++this.i+1])?(this.start=this.i+1,this.state=this.EndTag):this.Comment()):"!"==i&&(this.setText(),this.Comment())}}},{key:"Comment",value:function(){var t;t="--"==this.data.substring(this.i+2,this.i+4)?"--\x3e":"[CDATA["==this.data.substring(this.i+2,this.i+9)?"]]>":">",-1==(this.i=this.data.indexOf(t,this.i+2))?this.i=this.data.length:this.i+=t.length-1,this.start=this.i+1,this.state=this.Text}},{key:"TagName",value:function(t){if(blankChar[t]){for(this.tagName=this.section();blankChar[this.data[this.i]];)this.i++;this.isClose()?this.setNode():(this.start=this.i,this.state=this.AttrName)}else this.isClose()&&(this.tagName=this.section(),this.setNode())}},{key:"AttrName",value:function(t){var i=blankChar[t];if(i&&(this.attrName=this.section(),t=this.data[this.i]),"="==t){for(i||(this.attrName=this.section());blankChar[this.data[++this.i]];);this.start=this.i--,this.state=this.AttrValue}else i?this.setAttr():this.isClose()&&(this.attrName=this.section(),this.setAttr())}},{key:"AttrValue",value:function(t){if('"'==t||"'"==t){if(this.start++,-1==(this.i=this.data.indexOf(t,this.i+1)))return this.i=this.data.length;this.attrVal=this.section(),this.i++}else{for(;!blankChar[this.data[this.i]]&&!this.isClose();this.i++);this.attrVal=this.section()}this.setAttr()}},{key:"EndTag",value:function(t){if(blankChar[t]||">"==t||"/"==t){for(var i=this.getName(this.section()),s=this.STACK.length;s--&&this.STACK[s].name!=i;);if(-1!=s){for(var e;(e=this.STACK.pop()).name!=i;);this.popNode(e)}else"p"!=i&&"br"!=i||this.siblings().push({name:i,attrs:{}});this.i=this.data.indexOf(">",this.i),this.start=this.i+1,-1==this.i?this.i=this.data.length:this.state=this.Text}}}]),t}();module.exports=MpHtmlParser;
|