├── README.md ├── package.json └── rich-parse ├── helper ├── html2json.js ├── htmlparser.js └── wx-discode.js ├── render-nodes ├── recursion.wxml ├── render-nodes.js ├── render-nodes.json ├── render-nodes.wxml └── render-nodes.wxss ├── rich-parse.js ├── rich-parse.json ├── rich-parse.wxml └── rich-parse.wxss /README.md: -------------------------------------------------------------------------------- 1 | # 微信小程序富文本解析组件 2 | 3 | ## 代码从 https://github.com/icindy/wxParse fork。 4 | 5 | 于 wxParse 的差异: 6 | 7 | 1. 使用自定义组件重写逻辑 8 | 2. 解决 wxParse 中的 template 不能循环使用的问题 9 | 10 | ## 特性 11 | 12 | | 支持特性 | 13 | | ------------- | 14 | | - [x] HTML的大部分标签解析 | 15 | | - [x] 内联style | 16 | | - [x] 标签Class | 17 | | - [x] 图片自适应规则 | 18 | | - [x] 图片多图片预览 | 19 | | - [x] 模版层级可扩展性 | 20 | | - [x] 多数据循环方式 | 21 | | - [x] 内联style | 22 | | - [x] a标签跳转 | 23 | 24 | ## 基本使用方法 25 | 26 | 1. Copy文件夹 `rich-parse` 到放置自定义组件的地方 27 | 28 | 2. 引入必要文件 29 | 30 | ``` 31 | // 在使用的View中引入 rich-parse 32 | { 33 | "usingComponents": { 34 | "rich-parse": "/自定义组件路径/rich-parse/rich-parse" 35 | } 36 | } 37 | ``` 38 | 39 | 3. 使用 40 | ``` 41 | 42 | // content 是字符串内容,type 默认 html,可选 md。 43 | // md 解析器需要手动配置,函数挂在 global.md2html 上才有效 44 | ``` 45 | 46 | 4. a 标签使用 47 | ``` 48 | 49 | ``` 50 | 51 | 5. 图片预览 52 | ``` 53 | 54 | ``` 55 | 56 | ## 相关文章 57 | 58 | * [wxDiscode-微信小程序特殊字符转义符转化工具类](http://weappdev.com/t/wxdiscode/203) 59 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wx-rich-parse", 3 | "version": "1.0.0", 4 | "description": "微信小程序富文本解析组件", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/jamieYou/wx-rich-parse.git" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "bugs": { 12 | "url": "https://github.com/jamieYou/wx-rich-parse/issues" 13 | }, 14 | "homepage": "https://github.com/jamieYou/wx-rich-parse#readme" 15 | } 16 | -------------------------------------------------------------------------------- /rich-parse/helper/html2json.js: -------------------------------------------------------------------------------- 1 | /** 2 | * html2Json 改造来自: https://github.com/Jxck/html2json 3 | * 4 | * 5 | * author: Di (微信小程序开发工程师) 6 | * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) 7 | * 垂直微信小程序开发交流社区 8 | * 9 | * github地址: https://github.com/icindy/wxParse 10 | * 11 | * for: 微信小程序富文本解析 12 | * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 13 | */ 14 | 15 | /* eslint-disable */ 16 | 17 | var __placeImgeUrlHttps = "https"; 18 | var __emojisReg = ''; 19 | var __emojisBaseSrc = ''; 20 | var __emojis = {}; 21 | var wxDiscode = require('./wx-discode.js'); 22 | var HTMLParser = require('./htmlparser.js'); 23 | // Empty Elements - HTML 5 24 | var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr"); 25 | // Block Elements - HTML 5 26 | var block = makeMap("br,a,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video"); 27 | 28 | // Inline Elements - HTML 5 29 | var inline = makeMap("abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var"); 30 | 31 | // Elements that you can, intentionally, leave open 32 | // (and which close themselves) 33 | var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr"); 34 | 35 | // Attributes that have their values filled in disabled="disabled" 36 | var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"); 37 | 38 | // Special Elements (can contain anything) 39 | var special = makeMap("wxxxcode-style,script,style,view,scroll-view,block"); 40 | function makeMap(str) { 41 | var obj = {}, items = str.split(","); 42 | for (var i = 0; i < items.length; i++) 43 | obj[items[i]] = true; 44 | return obj; 45 | } 46 | 47 | function q(v) { 48 | return '"' + v + '"'; 49 | } 50 | 51 | function removeDOCTYPE(html) { 52 | return html 53 | .replace(/<\?xml.*\?>\n/, '') 54 | .replace(/<.*!doctype.*\>\n/, '') 55 | .replace(/<.*!DOCTYPE.*\>\n/, ''); 56 | } 57 | 58 | function trimHtml(html) { 59 | return html 60 | .replace(/\r?\n+/g, '') 61 | .replace(//ig, '') 62 | .replace(/\/\*.*?\*\//ig, '') 63 | .replace(/[ ]+ 196 | // add to parents 197 | var parent = bufArray[0] || results; 198 | if (parent.nodes === undefined) { 199 | parent.nodes = []; 200 | } 201 | parent.nodes.push(node); 202 | } else { 203 | bufArray.unshift(node); 204 | } 205 | }, 206 | end: function (tag) { 207 | //debug(tag); 208 | // merge into parent tag 209 | var node = bufArray.shift(); 210 | if (node.tag !== tag) console.error('invalid state: mismatch end tag'); 211 | 212 | //当有缓存source资源时于于video补上src资源 213 | if(node.tag === 'video' && results.source){ 214 | node.attr.src = results.source; 215 | delete results.source; 216 | } 217 | 218 | if (bufArray.length === 0) { 219 | results.nodes.push(node); 220 | } else { 221 | var parent = bufArray[0]; 222 | if (parent.nodes === undefined) { 223 | parent.nodes = []; 224 | } 225 | parent.nodes.push(node); 226 | } 227 | }, 228 | chars: function (text) { 229 | //debug(text); 230 | var node = { 231 | node: 'text', 232 | text: text, 233 | textArray:transEmojiStr(text) 234 | }; 235 | 236 | if (bufArray.length === 0) { 237 | node.index = index.toString() 238 | index += 1 239 | results.nodes.push(node); 240 | } else { 241 | var parent = bufArray[0]; 242 | if (parent.nodes === undefined) { 243 | parent.nodes = []; 244 | } 245 | node.index = parent.index + '.' + parent.nodes.length 246 | parent.nodes.push(node); 247 | } 248 | }, 249 | comment: function (text) { 250 | //debug(text); 251 | // var node = { 252 | // node: 'comment', 253 | // text: text, 254 | // }; 255 | // var parent = bufArray[0]; 256 | // if (parent.nodes === undefined) { 257 | // parent.nodes = []; 258 | // } 259 | // parent.nodes.push(node); 260 | }, 261 | }); 262 | return results; 263 | }; 264 | 265 | function transEmojiStr(str){ 266 | // var eReg = new RegExp("["+__reg+' '+"]"); 267 | // str = str.replace(/\[([^\[\]]+)\]/g,':$1:') 268 | 269 | var emojiObjs = []; 270 | //如果正则表达式为空 271 | if(__emojisReg.length == 0 || !__emojis){ 272 | var emojiObj = {} 273 | emojiObj.node = "text"; 274 | emojiObj.text = str; 275 | array = [emojiObj]; 276 | return array; 277 | } 278 | //这个地方需要调整 279 | str = str.replace(/\[([^\[\]]+)\]/g,':$1:') 280 | var eReg = new RegExp("[:]"); 281 | var array = str.split(eReg); 282 | for(var i = 0; i < array.length; i++){ 283 | var ele = array[i]; 284 | var emojiObj = {}; 285 | if(__emojis[ele]){ 286 | emojiObj.node = "element"; 287 | emojiObj.tag = "emoji"; 288 | emojiObj.text = __emojis[ele]; 289 | emojiObj.baseSrc= __emojisBaseSrc; 290 | }else{ 291 | emojiObj.node = "text"; 292 | emojiObj.text = ele; 293 | } 294 | emojiObjs.push(emojiObj); 295 | } 296 | 297 | return emojiObjs; 298 | } 299 | 300 | function emojisInit(reg='',baseSrc="/wxParse/emojis/",emojis){ 301 | __emojisReg = reg; 302 | __emojisBaseSrc=baseSrc; 303 | __emojis=emojis; 304 | } 305 | 306 | module.exports = { 307 | html2json: html2json, 308 | emojisInit:emojisInit 309 | }; 310 | 311 | -------------------------------------------------------------------------------- /rich-parse/helper/htmlparser.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser 4 | * 5 | * author: Di (微信小程序开发工程师) 6 | * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) 7 | * 垂直微信小程序开发交流社区 8 | * 9 | * github地址: https://github.com/icindy/wxParse 10 | * 11 | * for: 微信小程序富文本解析 12 | * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 13 | */ 14 | // Regular Expressions for parsing tags and attributes 15 | /* eslint-disable */ 16 | 17 | var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/, 18 | endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/, 19 | attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; 20 | 21 | // Empty Elements - HTML 5 22 | var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr"); 23 | 24 | // Block Elements - HTML 5 25 | var block = makeMap("a,address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video"); 26 | 27 | // Inline Elements - HTML 5 28 | var inline = makeMap("abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var"); 29 | 30 | // Elements that you can, intentionally, leave open 31 | // (and which close themselves) 32 | var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr"); 33 | 34 | // Attributes that have their values filled in disabled="disabled" 35 | var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"); 36 | 37 | // Special Elements (can contain anything) 38 | var special = makeMap("wxxxcode-style,script,style,view,scroll-view,block"); 39 | 40 | function HTMLParser(html, handler) { 41 | var index, chars, match, stack = [], last = html; 42 | stack.last = function () { 43 | return this[this.length - 1]; 44 | }; 45 | 46 | while (html) { 47 | chars = true; 48 | 49 | // Make sure we're not in a script or style element 50 | if (!stack.last() || !special[stack.last()]) { 51 | 52 | // Comment 53 | if (html.indexOf(""); 55 | 56 | if (index >= 0) { 57 | if (handler.comment) 58 | handler.comment(html.substring(4, index)); 59 | html = html.substring(index + 3); 60 | chars = false; 61 | } 62 | 63 | // end tag 64 | } else if (html.indexOf("]*>"), function (all, text) { 102 | text = text.replace(/|/g, "$1$2"); 103 | if (handler.chars) 104 | handler.chars(text); 105 | 106 | return ""; 107 | }); 108 | 109 | 110 | parseEndTag("", stack.last()); 111 | } 112 | 113 | if (html == last) 114 | throw "Parse Error: " + html; 115 | last = html; 116 | } 117 | 118 | // Clean up any remaining tags 119 | parseEndTag(); 120 | 121 | function parseStartTag(tag, tagName, rest, unary) { 122 | tagName = tagName.toLowerCase(); 123 | 124 | if (block[tagName]) { 125 | while (stack.last() && inline[stack.last()]) { 126 | parseEndTag("", stack.last()); 127 | } 128 | } 129 | 130 | if (closeSelf[tagName] && stack.last() == tagName) { 131 | parseEndTag("", tagName); 132 | } 133 | 134 | unary = empty[tagName] || !!unary; 135 | 136 | if (!unary) 137 | stack.push(tagName); 138 | 139 | if (handler.start) { 140 | var attrs = []; 141 | 142 | rest.replace(attr, function (match, name) { 143 | var value = arguments[2] ? arguments[2] : 144 | arguments[3] ? arguments[3] : 145 | arguments[4] ? arguments[4] : 146 | fillAttrs[name] ? name : ""; 147 | 148 | attrs.push({ 149 | name: name, 150 | value: value, 151 | escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') //" 152 | }); 153 | }); 154 | 155 | if (handler.start) { 156 | handler.start(tagName, attrs, unary); 157 | } 158 | 159 | } 160 | } 161 | 162 | function parseEndTag(tag, tagName) { 163 | // If no tag name is provided, clean shop 164 | if (!tagName) 165 | var pos = 0; 166 | 167 | // Find the closest opened tag of the same type 168 | else { 169 | tagName = tagName.toLowerCase(); 170 | for (var pos = stack.length - 1; pos >= 0; pos--) 171 | if (stack[pos] == tagName) 172 | break; 173 | } 174 | if (pos >= 0) { 175 | // Close all the open elements, up the stack 176 | for (var i = stack.length - 1; i >= pos; i--) 177 | if (handler.end) 178 | handler.end(stack[i]); 179 | 180 | // Remove the open elements from the stack 181 | stack.length = pos; 182 | } 183 | } 184 | }; 185 | 186 | 187 | function makeMap(str) { 188 | var obj = {}, items = str.split(","); 189 | for (var i = 0; i < items.length; i++) 190 | obj[items[i]] = true; 191 | return obj; 192 | } 193 | 194 | module.exports = HTMLParser; 195 | -------------------------------------------------------------------------------- /rich-parse/helper/wx-discode.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | // HTML 支持的数学符号 4 | function strNumDiscode(str){ 5 | str = str.replace(/∀/g, '∀'); 6 | str = str.replace(/∂/g, '∂'); 7 | str = str.replace(/&exists;/g, '∃'); 8 | str = str.replace(/∅/g, '∅'); 9 | str = str.replace(/∇/g, '∇'); 10 | str = str.replace(/∈/g, '∈'); 11 | str = str.replace(/∉/g, '∉'); 12 | str = str.replace(/∋/g, '∋'); 13 | str = str.replace(/∏/g, '∏'); 14 | str = str.replace(/∑/g, '∑'); 15 | str = str.replace(/−/g, '−'); 16 | str = str.replace(/∗/g, '∗'); 17 | str = str.replace(/√/g, '√'); 18 | str = str.replace(/∝/g, '∝'); 19 | str = str.replace(/∞/g, '∞'); 20 | str = str.replace(/∠/g, '∠'); 21 | str = str.replace(/∧/g, '∧'); 22 | str = str.replace(/∨/g, '∨'); 23 | str = str.replace(/∩/g, '∩'); 24 | str = str.replace(/∩/g, '∪'); 25 | str = str.replace(/∫/g, '∫'); 26 | str = str.replace(/∴/g, '∴'); 27 | str = str.replace(/∼/g, '∼'); 28 | str = str.replace(/≅/g, '≅'); 29 | str = str.replace(/≈/g, '≈'); 30 | str = str.replace(/≠/g, '≠'); 31 | str = str.replace(/≤/g, '≤'); 32 | str = str.replace(/≥/g, '≥'); 33 | str = str.replace(/⊂/g, '⊂'); 34 | str = str.replace(/⊃/g, '⊃'); 35 | str = str.replace(/⊄/g, '⊄'); 36 | str = str.replace(/⊆/g, '⊆'); 37 | str = str.replace(/⊇/g, '⊇'); 38 | str = str.replace(/⊕/g, '⊕'); 39 | str = str.replace(/⊗/g, '⊗'); 40 | str = str.replace(/⊥/g, '⊥'); 41 | str = str.replace(/⋅/g, '⋅'); 42 | return str; 43 | } 44 | 45 | //HTML 支持的希腊字母 46 | function strGreeceDiscode(str){ 47 | str = str.replace(/Α/g, 'Α'); 48 | str = str.replace(/Β/g, 'Β'); 49 | str = str.replace(/Γ/g, 'Γ'); 50 | str = str.replace(/Δ/g, 'Δ'); 51 | str = str.replace(/Ε/g, 'Ε'); 52 | str = str.replace(/Ζ/g, 'Ζ'); 53 | str = str.replace(/Η/g, 'Η'); 54 | str = str.replace(/Θ/g, 'Θ'); 55 | str = str.replace(/Ι/g, 'Ι'); 56 | str = str.replace(/Κ/g, 'Κ'); 57 | str = str.replace(/Λ/g, 'Λ'); 58 | str = str.replace(/Μ/g, 'Μ'); 59 | str = str.replace(/Ν/g, 'Ν'); 60 | str = str.replace(/Ξ/g, 'Ν'); 61 | str = str.replace(/Ο/g, 'Ο'); 62 | str = str.replace(/Π/g, 'Π'); 63 | str = str.replace(/Ρ/g, 'Ρ'); 64 | str = str.replace(/Σ/g, 'Σ'); 65 | str = str.replace(/Τ/g, 'Τ'); 66 | str = str.replace(/Υ/g, 'Υ'); 67 | str = str.replace(/Φ/g, 'Φ'); 68 | str = str.replace(/Χ/g, 'Χ'); 69 | str = str.replace(/Ψ/g, 'Ψ'); 70 | str = str.replace(/Ω/g, 'Ω'); 71 | 72 | str = str.replace(/α/g, 'α'); 73 | str = str.replace(/β/g, 'β'); 74 | str = str.replace(/γ/g, 'γ'); 75 | str = str.replace(/δ/g, 'δ'); 76 | str = str.replace(/ε/g, 'ε'); 77 | str = str.replace(/ζ/g, 'ζ'); 78 | str = str.replace(/η/g, 'η'); 79 | str = str.replace(/θ/g, 'θ'); 80 | str = str.replace(/ι/g, 'ι'); 81 | str = str.replace(/κ/g, 'κ'); 82 | str = str.replace(/λ/g, 'λ'); 83 | str = str.replace(/μ/g, 'μ'); 84 | str = str.replace(/ν/g, 'ν'); 85 | str = str.replace(/ξ/g, 'ξ'); 86 | str = str.replace(/ο/g, 'ο'); 87 | str = str.replace(/π/g, 'π'); 88 | str = str.replace(/ρ/g, 'ρ'); 89 | str = str.replace(/ς/g, 'ς'); 90 | str = str.replace(/σ/g, 'σ'); 91 | str = str.replace(/τ/g, 'τ'); 92 | str = str.replace(/υ/g, 'υ'); 93 | str = str.replace(/φ/g, 'φ'); 94 | str = str.replace(/χ/g, 'χ'); 95 | str = str.replace(/ψ/g, 'ψ'); 96 | str = str.replace(/ω/g, 'ω'); 97 | str = str.replace(/ϑ/g, 'ϑ'); 98 | str = str.replace(/ϒ/g, 'ϒ'); 99 | str = str.replace(/ϖ/g, 'ϖ'); 100 | str = str.replace(/·/g, '·'); 101 | return str; 102 | } 103 | 104 | // 105 | 106 | function strcharacterDiscode(str){ 107 | // 加入常用解析 108 | str = str.replace(/ /g, '\xa0'); 109 | str = str.replace(/"/g, "'"); 110 | str = str.replace(/&/g, '&'); 111 | // str = str.replace(/</g, '‹'); 112 | // str = str.replace(/>/g, '›'); 113 | 114 | str = str.replace(/</g, '<'); 115 | str = str.replace(/>/g, '>'); 116 | str = str.replace(/•/g, '•'); 117 | 118 | return str; 119 | } 120 | 121 | // HTML 支持的其他实体 122 | function strOtherDiscode(str){ 123 | str = str.replace(/Œ/g, 'Œ'); 124 | str = str.replace(/œ/g, 'œ'); 125 | str = str.replace(/Š/g, 'Š'); 126 | str = str.replace(/š/g, 'š'); 127 | str = str.replace(/Ÿ/g, 'Ÿ'); 128 | str = str.replace(/ƒ/g, 'ƒ'); 129 | str = str.replace(/ˆ/g, 'ˆ'); 130 | str = str.replace(/˜/g, '˜'); 131 | str = str.replace(/ /g, ''); 132 | str = str.replace(/ /g, ''); 133 | str = str.replace(/ /g, ''); 134 | str = str.replace(/‌/g, ''); 135 | str = str.replace(/‍/g, ''); 136 | str = str.replace(/‎/g, ''); 137 | str = str.replace(/‏/g, ''); 138 | str = str.replace(/–/g, '–'); 139 | str = str.replace(/—/g, '—'); 140 | str = str.replace(/‘/g, '‘'); 141 | str = str.replace(/’/g, '’'); 142 | str = str.replace(/‚/g, '‚'); 143 | str = str.replace(/“/g, '“'); 144 | str = str.replace(/”/g, '”'); 145 | str = str.replace(/„/g, '„'); 146 | str = str.replace(/†/g, '†'); 147 | str = str.replace(/‡/g, '‡'); 148 | str = str.replace(/•/g, '•'); 149 | str = str.replace(/…/g, '…'); 150 | str = str.replace(/‰/g, '‰'); 151 | str = str.replace(/′/g, '′'); 152 | str = str.replace(/″/g, '″'); 153 | str = str.replace(/‹/g, '‹'); 154 | str = str.replace(/›/g, '›'); 155 | str = str.replace(/‾/g, '‾'); 156 | str = str.replace(/€/g, '€'); 157 | str = str.replace(/™/g, '™'); 158 | 159 | str = str.replace(/←/g, '←'); 160 | str = str.replace(/↑/g, '↑'); 161 | str = str.replace(/→/g, '→'); 162 | str = str.replace(/↓/g, '↓'); 163 | str = str.replace(/↔/g, '↔'); 164 | str = str.replace(/↵/g, '↵'); 165 | str = str.replace(/⌈/g, '⌈'); 166 | str = str.replace(/⌉/g, '⌉'); 167 | 168 | str = str.replace(/⌊/g, '⌊'); 169 | str = str.replace(/⌋/g, '⌋'); 170 | str = str.replace(/◊/g, '◊'); 171 | str = str.replace(/♠/g, '♠'); 172 | str = str.replace(/♣/g, '♣'); 173 | str = str.replace(/♥/g, '♥'); 174 | 175 | str = str.replace(/♦/g, '♦'); 176 | str = str.replace(/'/g, '\''); 177 | return str; 178 | } 179 | 180 | function strMoreDiscode(str){ 181 | str = str.replace(/\r\n/g,""); 182 | str = str.replace(/\n/g,""); 183 | 184 | // str = str.replace(/code/g,"wxxxcode-style"); 185 | return str; 186 | } 187 | 188 | function strDiscode(str){ 189 | str = strNumDiscode(str); 190 | str = strGreeceDiscode(str); 191 | str = strcharacterDiscode(str); 192 | str = strOtherDiscode(str); 193 | str = strMoreDiscode(str); 194 | return str; 195 | } 196 | function urlToHttpUrl(url,rep){ 197 | 198 | var patt1 = new RegExp("^//"); 199 | var result = patt1.test(url); 200 | if(result){ 201 | url = rep+":"+url; 202 | } 203 | return url; 204 | } 205 | 206 | module.exports = { 207 | strDiscode:strDiscode, 208 | urlToHttpUrl:urlToHttpUrl 209 | } 210 | -------------------------------------------------------------------------------- /rich-parse/render-nodes/recursion.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /rich-parse/render-nodes/render-nodes.js: -------------------------------------------------------------------------------- 1 | Component({ 2 | options: { 3 | addGlobalClass: true, 4 | }, 5 | 6 | properties: { 7 | nodes: { 8 | type: Array, 9 | value: [], 10 | }, 11 | parse_id: { 12 | type: String, 13 | value: '', 14 | } 15 | }, 16 | 17 | data: { 18 | imageWidths: {} 19 | }, 20 | 21 | methods: { 22 | onImgTap(e) { 23 | global.richParses[this.data.parse_id].onImgTap(e) 24 | }, 25 | 26 | onLinkTap(e) { 27 | global.richParses[this.data.parse_id].onLinkTap(e) 28 | }, 29 | 30 | onImgLoad(e) { 31 | this.data.imageWidths[e.target.dataset.src] = e.detail.width + 'px' 32 | this.setData({ imageWidths: this.data.imageWidths }) 33 | } 34 | } 35 | }) 36 | -------------------------------------------------------------------------------- /rich-parse/render-nodes/render-nodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": { 4 | "render-nodes": "./render-nodes" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /rich-parse/render-nodes/render-nodes.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |