parser.js
17.5 KB
"use strict";const C=require("../../../../common/vendor.js"),w={trustTags:j("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,ruby,rt,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,ul,video"),blockTags:j("address,article,aside,body,caption,center,cite,footer,header,html,nav,pre,section"),inlineTags:j("abbr,b,big,code,del,em,i,ins,label,q,small,span,strong,sub,sup"),ignoreTags:j("area,base,canvas,embed,frame,head,iframe,input,link,map,meta,param,rp,script,source,style,textarea,title,track,wbr"),voidTags:j("area,base,br,col,circle,ellipse,embed,frame,hr,img,input,line,link,meta,param,path,polygon,rect,source,track,use,wbr"),entities:{lt:"<",gt:">",quot:'"',apos:"'",ensp:" ",emsp:" ",nbsp:" ",semi:";",ndash:"–",mdash:"—",middot:"·",lsquo:"‘",rsquo:"’",ldquo:"“",rdquo:"”",bull:"•",hellip:"…",larr:"←",uarr:"↑",rarr:"→",darr:"↓"},tagStyle:{address:"font-style:italic",big:"display:inline;font-size:1.2em",caption:"display:table-caption;text-align:center",center:"text-align:center",cite:"font-style:italic",dd:"margin-left:40px",mark:"background-color:yellow",pre:"font-family:monospace;white-space:pre",s:"text-decoration:line-through",small:"display:inline;font-size:0.8em",strike:"text-decoration:line-through",u:"text-decoration:underline"},svgDict:{animatetransform:"animateTransform",lineargradient:"linearGradient",viewbox:"viewBox",attributename:"attributeName",repeatcount:"repeatCount",repeatdur:"repeatDur"}},I={},{windowWidth:L,system:q}=C.index.getSystemInfoSync(),T=j(` ,\r,
, ,\f`);let F=0;function j(t){const i=Object.create(null),e=t.split(",");for(let o=e.length;o--;)i[e[o]]=!0;return i}function A(t,i){let e=t.indexOf("&");for(;e!==-1;){const o=t.indexOf(";",e+3);let d;if(o===-1)break;t[e+1]==="#"?(d=parseInt((t[e+2]==="x"?"0":"")+t.substring(e+2,o)),isNaN(d)||(t=t.substr(0,e)+String.fromCharCode(d)+t.substr(o+1))):(d=t.substring(e+1,o),(w.entities[d]||d==="amp"&&i)&&(t=t.substr(0,e)+(w.entities[d]||"&")+t.substr(o+1))),e=t.indexOf("&",e+1)}return t}function z(t){let i=t.length-1;for(let e=i;e>=-1;e--)(e===-1||t[e].c||!t[e].name||t[e].name!=="div"&&t[e].name!=="p"&&t[e].name[0]!=="h"||(t[e].attrs.style||"").includes("inline"))&&(i-e>=5&&t.splice(e+1,i-e,{name:"div",attrs:{},children:t.slice(e+1,i+1)}),i=e-1)}function b(t){this.options=t||{},this.tagStyle=Object.assign({},w.tagStyle,this.options.tagStyle),this.imgList=t.imgList||[],this.imgList._unloadimgs=0,this.plugins=t.plugins||[],this.attrs=Object.create(null),this.stack=[],this.nodes=[],this.pre=(this.options.containerStyle||"").includes("white-space")&&this.options.containerStyle.includes("pre")?2:0}b.prototype.parse=function(t){for(let i=this.plugins.length;i--;)this.plugins[i].onUpdate&&(t=this.plugins[i].onUpdate(t,w)||t);for(new O(this).parse(t);this.stack.length;)this.popNode();return this.nodes.length>50&&z(this.nodes),this.nodes};b.prototype.expose=function(){for(let t=this.stack.length;t--;){const i=this.stack[t];if(i.c||i.name==="a"||i.name==="video"||i.name==="audio")return;i.c=1}};b.prototype.hook=function(t){for(let i=this.plugins.length;i--;)if(this.plugins[i].onParse&&this.plugins[i].onParse(t,this)===!1)return!1;return!0};b.prototype.getUrl=function(t){const i=this.options.domain;return t[0]==="/"?t[1]==="/"?t=(i?i.split("://")[0]:"http")+":"+t:i&&(t=i+t):!t.includes("data:")&&!t.includes("://")&&i&&(t=i+"/"+t),t};b.prototype.parseStyle=function(t){const i=t.attrs,e=(this.tagStyle[t.name]||"").split(";").concat((i.style||"").split(";")),o={};let d="";i.id&&!this.xml&&(this.options.useAnchor?this.expose():t.name!=="img"&&t.name!=="a"&&t.name!=="video"&&t.name!=="audio"&&(i.id=void 0)),i.width&&(o.width=parseFloat(i.width)+(i.width.includes("%")?"%":"px"),i.width=void 0),i.height&&(o.height=parseFloat(i.height)+(i.height.includes("%")?"%":"px"),i.height=void 0);for(let h=0,l=e.length;h<l;h++){const s=e[h].split(":");if(s.length<2)continue;const n=s.shift().trim().toLowerCase();let a=s.join(":").trim();if(a[0]==="-"&&a.lastIndexOf("-")>0||a.includes("safe"))d+=`;${n}:${a}`;else if(!o[n]||a.includes("import")||!o[n].includes("import")){if(a.includes("url")){let r=a.indexOf("(")+1;if(r){for(;a[r]==='"'||a[r]==="'"||T[a[r]];)r++;a=a.substr(0,r)+this.getUrl(a.substr(r))}}else a.includes("rpx")&&(a=a.replace(/[0-9.]+\s*rpx/g,r=>parseFloat(r)*L/750+"px"));o[n]=a}}return t.attrs.style=d,o};b.prototype.onTagName=function(t){this.tagName=this.xml?t:t.toLowerCase(),this.tagName==="svg"&&(this.xml=(this.xml||0)+1)};b.prototype.onAttrName=function(t){t=this.xml?t:t.toLowerCase(),t.substr(0,5)==="data-"?t==="data-src"&&!this.attrs.src?this.attrName="src":this.tagName==="img"||this.tagName==="a"?this.attrName=t:this.attrName=void 0:(this.attrName=t,this.attrs[t]="T")};b.prototype.onAttrVal=function(t){const i=this.attrName||"";i==="style"||i==="href"?this.attrs[i]=A(t,!0):i.includes("src")?this.attrs[i]=this.getUrl(A(t,!0)):i&&(this.attrs[i]=t)};b.prototype.onOpenTag=function(t){const i=Object.create(null);i.name=this.tagName,i.attrs=this.attrs,this.options.nodes.length&&(i.type="node"),this.attrs=Object.create(null);const e=i.attrs,o=this.stack[this.stack.length-1],d=o?o.children:this.nodes,h=this.xml?t:w.voidTags[i.name];if(I[i.name]&&(e.class=I[i.name]+(e.class?" "+e.class:"")),i.name==="embed"){const l=e.src||"";l.includes(".mp4")||l.includes(".3gp")||l.includes(".m3u8")||(e.type||"").includes("video")?i.name="video":(l.includes(".mp3")||l.includes(".wav")||l.includes(".aac")||l.includes(".m4a")||(e.type||"").includes("audio"))&&(i.name="audio"),e.autostart&&(e.autoplay="T"),e.controls="T"}if((i.name==="video"||i.name==="audio")&&(i.name==="video"&&!e.id&&(e.id="v"+F++),!e.controls&&!e.autoplay&&(e.controls="T"),i.src=[],e.src&&(i.src.push(e.src),e.src=void 0),this.expose()),h){if(!this.hook(i)||w.ignoreTags[i.name]){i.name==="base"&&!this.options.domain?this.options.domain=e.href:i.name==="source"&&o&&(o.name==="video"||o.name==="audio")&&e.src&&o.src.push(e.src);return}const l=this.parseStyle(i);if(i.name==="img"){if(e.src&&(e.src.includes("webp")&&(i.webp="T"),e.src.includes("data:")&&!e["original-src"]&&(e.ignore="T"),!e.ignore||i.webp||e.src.includes("cloud://"))){for(let n=this.stack.length;n--;){const a=this.stack[n];a.name==="a"&&(i.a=a.attrs),a.name==="table"&&!i.webp&&!e.src.includes("cloud://")&&(!l.display||l.display.includes("inline")?i.t="inline-block":i.t=l.display,l.display=void 0);const r=a.attrs.style||"";if(r.includes("flex:")&&!r.includes("flex:0")&&!r.includes("flex: 0")&&(!l.width||parseInt(l.width)>100)){l.width="100% !important",l.height="";for(let g=n+1;g<this.stack.length;g++)this.stack[g].attrs.style=(this.stack[g].attrs.style||"").replace("inline-","")}else if(r.includes("flex")&&l.width==="100%")for(let g=n+1;g<this.stack.length;g++){const f=this.stack[g].attrs.style||"";if(!f.includes(";width")&&!f.includes(" width")&&f.indexOf("width")!==0){l.width="";break}}else r.includes("inline-block")&&(l.width&&l.width[l.width.length-1]==="%"?(a.attrs.style+=";max-width:"+l.width,l.width=""):a.attrs.style+=";max-width:100%");a.c=1}e.i=this.imgList.length.toString();let s=e["original-src"]||e.src;if(this.imgList.includes(s)){let n=s.indexOf("://");if(n!==-1){n+=3;let a=s.substr(0,n);for(;n<s.length&&s[n]!=="/";n++)a+=Math.random()>.5?s[n].toUpperCase():s[n];a+=s.substr(n),s=a}}this.imgList.push(s),i.t||(this.imgList._unloadimgs+=1)}l.display==="inline"&&(l.display=""),e.ignore&&(l["max-width"]=l["max-width"]||"100%",e.style+=";-webkit-touch-callout:none"),parseInt(l.width)>L&&(l.height=void 0),isNaN(parseInt(l.width))||(i.w="T"),!isNaN(parseInt(l.height))&&(!l.height.includes("%")||o&&(o.attrs.style||"").includes("height"))&&(i.h="T")}else if(i.name==="svg"){d.push(i),this.stack.push(i),this.popNode();return}for(const s in l)l[s]&&(e.style+=`;${s}:${l[s].replace(" !important","")}`);e.style=e.style.substr(1)||void 0,e.style||delete e.style}else(i.name==="pre"||(e.style||"").includes("white-space")&&e.style.includes("pre"))&&this.pre!==2&&(this.pre=i.pre=1),i.children=[],this.stack.push(i);d.push(i)};b.prototype.onCloseTag=function(t){t=this.xml?t:t.toLowerCase();let i;for(i=this.stack.length;i--&&this.stack[i].name!==t;);if(i!==-1)for(;this.stack.length>i;)this.popNode();else(t==="p"||t==="br")&&(this.stack.length?this.stack[this.stack.length-1].children:this.nodes).push({name:t,attrs:{class:I[t]||"",style:this.tagStyle[t]||""}})};b.prototype.popNode=function(){const t=this.stack.pop();let i=t.attrs;const e=t.children,o=this.stack[this.stack.length-1],d=o?o.children:this.nodes;if(!this.hook(t)||w.ignoreTags[t.name]){t.name==="title"&&e.length&&e[0].type==="text"&&this.options.setTitle&&C.index.setNavigationBarTitle({title:e[0].text}),d.pop();return}if(t.pre&&this.pre!==2){this.pre=t.pre=void 0;for(let s=this.stack.length;s--;)this.stack[s].pre&&(this.pre=1)}const h={};if(t.name==="svg"){if(this.xml>1){this.xml--;return}let s="";const n=i.style;i.style="",i.xmlns="http://www.w3.org/2000/svg",function a(r){if(r.type==="text"){s+=r.text;return}const g=w.svgDict[r.name]||r.name;s+="<"+g;for(const f in r.attrs){const v=r.attrs[f];v&&(s+=` ${w.svgDict[f]||f}="${v}"`)}if(!r.children)s+="/>";else{s+=">";for(let f=0;f<r.children.length;f++)a(r.children[f]);s+="</"+g+">"}}(t),t.name="img",t.attrs={src:"data:image/svg+xml;utf8,"+s.replace(/#/g,"%23"),style:n,ignore:"T"},t.children=void 0,this.xml=!1;return}if(i.align&&(t.name==="table"?i.align==="center"?h["margin-inline-start"]=h["margin-inline-end"]="auto":h.float=i.align:h["text-align"]=i.align,i.align=void 0),i.dir&&(h.direction=i.dir,i.dir=void 0),t.name==="font"&&(i.color&&(h.color=i.color,i.color=void 0),i.face&&(h["font-family"]=i.face,i.face=void 0),i.size)){let s=parseInt(i.size);isNaN(s)||(s<1?s=1:s>7&&(s=7),h["font-size"]=["x-small","small","medium","large","x-large","xx-large","xxx-large"][s-1]),i.size=void 0}if((i.class||"").includes("align-center")&&(h["text-align"]="center"),Object.assign(h,this.parseStyle(t)),t.name!=="table"&&parseInt(h.width)>L&&(h["max-width"]="100%",h["box-sizing"]="border-box"),w.blockTags[t.name]?t.name="div":!w.trustTags[t.name]&&!this.xml&&(t.name="span"),t.name==="a"||t.name==="ad")this.expose();else if(t.name==="video")(h.height||"").includes("auto")&&(h.height=void 0);else if((t.name==="ul"||t.name==="ol")&&t.c){const s={a:"lower-alpha",A:"upper-alpha",i:"lower-roman",I:"upper-roman"};s[i.type]&&(i.style+=";list-style-type:"+s[i.type],i.type=void 0);for(let n=e.length;n--;)e[n].name==="li"&&(e[n].c=1)}else if(t.name==="table"){let s=parseFloat(i.cellpadding),n=parseFloat(i.cellspacing);const a=parseFloat(i.border),r=h["border-color"],g=h["border-style"];if(t.c&&(isNaN(s)&&(s=2),isNaN(n)&&(n=2)),a&&(i.style+=`;border:${a}px ${g||"solid"} ${r||"gray"}`),t.flag&&t.c){h.display="grid",n?(h["grid-gap"]=n+"px",h.padding=n+"px"):a&&(i.style+=";border-left:0;border-top:0");const f=[],v=[],$=[],k={};(function y(u){for(let x=0;x<u.length;x++)u[x].name==="tr"?v.push(u[x]):y(u[x].children||[])})(e);for(let y=1;y<=v.length;y++){let u=1;for(let x=0;x<v[y-1].children.length;x++){const p=v[y-1].children[x];if(p.name==="td"||p.name==="th"){for(;k[y+"."+u];)u++;let c=p.attrs.style||"",N=c.indexOf("width")?c.indexOf(";width"):0;if(N!==-1){let m=c.indexOf(";",N+6);m===-1&&(m=c.length),p.attrs.colspan||(f[u]=c.substring(N?N+7:6,m)),c=c.substr(0,N)+c.substr(m)}if(c+=";display:flex",N=c.indexOf("vertical-align"),N!==-1){const m=c.substr(N+15,10);m.includes("middle")?c+=";align-items:center":m.includes("bottom")&&(c+=";align-items:flex-end")}else c+=";align-items:center";if(N=c.indexOf("text-align"),N!==-1){const m=c.substr(N+11,10);m.includes("center")?c+=";justify-content: center":m.includes("right")&&(c+=";justify-content: right")}if(c=(a?`;border:${a}px ${g||"solid"} ${r||"gray"}`+(n?"":";border-right:0;border-bottom:0"):"")+(s?`;padding:${s}px`:"")+";"+c,p.attrs.colspan&&(c+=`;grid-column-start:${u};grid-column-end:${u+parseInt(p.attrs.colspan)}`,p.attrs.rowspan||(c+=`;grid-row-start:${y};grid-row-end:${y+1}`),u+=parseInt(p.attrs.colspan)-1),p.attrs.rowspan){c+=`;grid-row-start:${y};grid-row-end:${y+parseInt(p.attrs.rowspan)}`,p.attrs.colspan||(c+=`;grid-column-start:${u};grid-column-end:${u+1}`);for(let m=1;m<p.attrs.rowspan;m++)for(let S=0;S<(p.attrs.colspan||1);S++)k[y+m+"."+(u-S)]=1}c&&(p.attrs.style=c),$.push(p),u++}}if(y===1){let x="";for(let p=1;p<u;p++)x+=(f[p]?f[p]:"auto")+" ";h["grid-template-columns"]=x}}t.children=$}else t.c&&(h.display="table"),isNaN(n)||(h["border-spacing"]=n+"px"),(a||s)&&function f(v){for(let $=0;$<v.length;$++){const k=v[$];k.name==="th"||k.name==="td"?(a&&(k.attrs.style=`border:${a}px ${g||"solid"} ${r||"gray"};${k.attrs.style||""}`),s&&(k.attrs.style=`padding:${s}px;${k.attrs.style||""}`)):k.children&&f(k.children)}}(e);if(this.options.scrollTable&&!(i.style||"").includes("inline")){const f=Object.assign({},t);t.name="div",t.attrs={style:"overflow:auto"},t.children=[f],i=f.attrs}}else if((t.name==="td"||t.name==="th")&&(i.colspan||i.rowspan)){for(let s=this.stack.length;s--;)if(this.stack[s].name==="table"){this.stack[s].flag=1;break}}else if(t.name==="ruby"){t.name="span";for(let s=0;s<e.length-1;s++)e[s].type==="text"&&e[s+1].name==="rt"&&(e[s]={name:"div",attrs:{style:"display:inline-block;text-align:center"},children:[{name:"div",attrs:{style:"font-size:50%;"+(e[s+1].attrs.style||"")},children:e[s+1].children},e[s]]},e.splice(s+1,1))}else t.c&&function s(n){n.c=2;for(let a=n.children.length;a--;){const r=n.children[a];r.name&&(w.inlineTags[r.name]||(r.attrs.style||"").includes("inline")&&r.children)&&!r.c&&s(r),(!r.c||r.name==="table")&&(n.c=1)}}(t);if((h.display||"").includes("flex")&&!t.c)for(let s=e.length;s--;){const n=e[s];n.f&&(n.attrs.style=(n.attrs.style||"")+n.f,n.f=void 0)}const l=o&&((o.attrs.style||"").includes("flex")||(o.attrs.style||"").includes("grid"))&&!(t.c&&C.wx$1.getNFCAdapter);l&&(t.f=";max-width:100%"),e.length>=50&&t.c&&!(h.display||"").includes("flex")&&z(e);for(const s in h)if(h[s]){const n=`;${s}:${h[s].replace(" !important","")}`;l&&(s.includes("flex")&&s!=="flex-direction"||s==="align-self"||s.includes("grid")||h[s][0]==="-"||s.includes("width")&&n.includes("%"))?(t.f+=n,s==="width"&&(i.style+=";width:100%")):i.style+=n}i.style=i.style.substr(1)||void 0;for(const s in i)i[s]||delete i[s]};b.prototype.onText=function(t){if(!this.pre){let e="",o;for(let d=0,h=t.length;d<h;d++)T[t[d]]?(e[e.length-1]!==" "&&(e+=" "),t[d]===`
`&&!o&&(o=!0)):e+=t[d];if(e===" "){if(o)return;{const d=this.stack[this.stack.length-1];if(d&&d.name[0]==="t")return}}t=e}const i=Object.create(null);i.type="text",i.text=A(t),this.hook(i)&&(this.options.selectable==="force"&&q.includes("iOS")&&!C.index.canIUse("rich-text.user-select")&&this.expose(),(this.stack.length?this.stack[this.stack.length-1].children:this.nodes).push(i))};function O(t){this.handler=t}O.prototype.parse=function(t){this.content=t||"",this.i=0,this.start=0,this.state=this.text;for(let i=this.content.length;this.i!==-1&&this.i<i;)this.state()};O.prototype.checkClose=function(t){const i=this.content[this.i]==="/";return this.content[this.i]===">"||i&&this.content[this.i+1]===">"?(t&&this.handler[t](this.content.substring(this.start,this.i)),this.i+=i?2:1,this.start=this.i,this.handler.onOpenTag(i),this.handler.tagName==="script"?(this.i=this.content.indexOf("</",this.i),this.i!==-1&&(this.i+=2,this.start=this.i),this.state=this.endTag):this.state=this.text,!0):!1};O.prototype.text=function(){if(this.i=this.content.indexOf("<",this.i),this.i===-1){this.start<this.content.length&&this.handler.onText(this.content.substring(this.start,this.content.length));return}const t=this.content[this.i+1];if(t>="a"&&t<="z"||t>="A"&&t<="Z")this.start!==this.i&&this.handler.onText(this.content.substring(this.start,this.i)),this.start=++this.i,this.state=this.tagName;else if(t==="/"||t==="!"||t==="?"){this.start!==this.i&&this.handler.onText(this.content.substring(this.start,this.i));const i=this.content[this.i+2];if(t==="/"&&(i>="a"&&i<="z"||i>="A"&&i<="Z")){this.i+=2,this.start=this.i,this.state=this.endTag;return}let e="-->";(t!=="!"||this.content[this.i+2]!=="-"||this.content[this.i+3]!=="-")&&(e=">"),this.i=this.content.indexOf(e,this.i),this.i!==-1&&(this.i+=e.length,this.start=this.i)}else this.i++};O.prototype.tagName=function(){if(T[this.content[this.i]]){for(this.handler.onTagName(this.content.substring(this.start,this.i));T[this.content[++this.i]];);this.i<this.content.length&&!this.checkClose()&&(this.start=this.i,this.state=this.attrName)}else this.checkClose("onTagName")||this.i++};O.prototype.attrName=function(){let t=this.content[this.i];if(T[t]||t==="="){this.handler.onAttrName(this.content.substring(this.start,this.i));let i=t==="=";const e=this.content.length;for(;++this.i<e;)if(t=this.content[this.i],!T[t]){if(this.checkClose())return;if(i){this.start=this.i,this.state=this.attrVal;return}if(this.content[this.i]==="=")i=!0;else{this.start=this.i,this.state=this.attrName;return}}}else this.checkClose("onAttrName")||this.i++};O.prototype.attrVal=function(){const t=this.content[this.i],i=this.content.length;if(t==='"'||t==="'"){if(this.start=++this.i,this.i=this.content.indexOf(t,this.i),this.i===-1)return;this.handler.onAttrVal(this.content.substring(this.start,this.i))}else for(;this.i<i;this.i++)if(T[this.content[this.i]]){this.handler.onAttrVal(this.content.substring(this.start,this.i));break}else if(this.checkClose("onAttrVal"))return;for(;T[this.content[++this.i]];);this.i<i&&!this.checkClose()&&(this.start=this.i,this.state=this.attrName)};O.prototype.endTag=function(){const t=this.content[this.i];if(T[t]||t===">"||t==="/"){if(this.handler.onCloseTag(this.content.substring(this.start,this.i)),t!==">"&&(this.i=this.content.indexOf(">",this.i),this.i===-1))return;this.start=++this.i,this.state=this.text}else this.i++};exports.Parser=b;