"+e)})};e.exports=f},{"./baas":6,"./constants":10,"./promise":14,"./storage":16,"./utils":19,"node.extend":2}],16:[function(t,e,n){"use strict";e.exports={set:function(t,e){try{wx.setStorageSync("ifx_baas_"+t,e)}catch(t){throw new Error(t)}},get:function(t){try{return wx.getStorageSync("ifx_baas_"+t)}catch(t){throw new Error(t)}}}},{}],17:[function(t,e,n){"use strict";var r=t("./utils"),o=t("./baas"),i=o._config.API_HOST,u=o._config.API,a=t("./constants"),s=t("./promise"),c=function(t){return new s(function(e,n){o._config.CLIENT_ID||n("未初始化客户端");var s=o.getAuthToken();s||n("未认证,请先完成用户登录"),wx.uploadFile({url:i+u.UPLOAD,filePath:t.filePath,name:a.UPLOAD.UPLOAD_FILE_KEY,formData:t.formData,header:{Authorization:a.UPLOAD.HEADER_AUTH_VALUE+s,"X-Hydrogen-Client-Version":o._config.VERSION,"X-Hydrogen-Client-Platform":r.getSysPlatform(),"X-Hydrogen-Client-ID":o._config.CLIENT_ID,"User-Agent":a.UPLOAD.UA},success:function(t){e(t)},fail:function(t){n(t)}})},function(t){throw new Error(t)})};e.exports=c},{"./baas":6,"./constants":10,"./promise":14,"./utils":19}],18:[function(t,e,n){"use strict";var r=t("./request"),o=t("./baas"),i=t("./constants"),u=(t("./utils"),t("./storage")),a=t("./promise"),s=o._config.API,c=function(t,e,n){return r({url:s.INIT,method:"POST",data:{code:t}}).then(function(t){t.statusCode==i.STATUS_CODE.CREATED?(u.set(i.STORAGE_KEY.UID,t.data.user_id),u.set(i.STORAGE_KEY.AUTH_TOKEN,t.data.token),e(t)):n(i.MSG.STATUS_CODE_ERROR)},function(t){n(t)})},f=function(){return new a(function(t,e){wx.login({success:function(n){return c(n.code,t,e)},fail:function(t){e(t)}})})},l=function(t,e,n){return r({url:s.LOGIN,method:"POST",data:t}).then(function(t){t.statusCode==i.STATUS_CODE.CREATED?(u.set(i.STORAGE_KEY.IS_LOGINED_BAAS,"1"),e(t)):n(i.MSG.STATUS_CODE_ERROR)},function(t){n(t)})},d=function(){if(!o.getAuthToken())throw new Error("未认证客户端");return new a(function(t,e){wx.getUserInfo({success:function(n){var r={rawData:n.rawData,signature:n.signature,encryptedData:n.encryptedData,iv:n.iv};return u.set(i.STORAGE_KEY.USERINFO,n.userInfo),l(r,t,e)},fail:function(e){t("")}})})},h=function(){return o.check(),r({url:s.LOGOUT,method:"POST"}).then(function(t){if(t.statusCode!=i.STATUS_CODE.CREATED)throw new Error(i.MSG.STATUS_CODE_ERROR);o.clearSession()},function(t){throw new Error(t)})};e.exports={auth:f,login:d,logout:h}},{"./baas":6,"./constants":10,"./promise":14,"./request":15,"./storage":16,"./utils":19}],19:[function(t,e,n){"use strict";var r=t("node.extend"),o=void 0;try{o=t("./config.js")}catch(e){o=t("./config.dev")}var i=function(){return o},u=function(){var t="UNKNOWN";try{t=wx.getSystemInfoSync().platform}catch(t){}return t},a=function(t){"undefined"!=typeof BaaS&&BaaS.test||!i().DEBUG||console.log("BaaS LOG: "+t)},s=function(t,e){e=e||{};for(var n in e){var r=new RegExp(":"+n,"g");t=t.replace(r,e[n])}return t.replace(/([^:])\/\//g,function(t,e){return e+"/"})},c=function(t,e){return t.replace(/:(\w*)/g,function(t,n){void 0!==e[n]&&delete e[n]}),e},f=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n={contentGroupID:"content_group_id",categoryID:"category_id",recordID:"id"},o=r({},e);return Object.keys(e).map(function(t){Object.keys(n).map(function(r){if(t.startsWith(r)){var i=t.replace(r,n[r]);delete o[t],o[i]=e[t]}})}),o};e.exports={log:a,format:s,excludeParams:c,getConfig:i,
2 | getSysPlatform:u,replaceQueryParams:f}},{"./config.dev":8,"./config.js":9,"node.extend":2}],20:[function(t,e,n){"use strict";e.exports="v1.0.9"},{}]},{},[11]);
--------------------------------------------------------------------------------
/wxParser/codeTransformation.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 特殊字符映射表
3 | * @type {Object}
4 | */
5 | const codeMap = {
6 | // HTML 支持的数学符号
7 | '∀': '∀',
8 | '∂': '∂',
9 | '&exists;': '∃',
10 | '∅': '∅',
11 | '∇': '∇',
12 | '∈': '∈',
13 | '∉': '∉',
14 | '∋': '∋',
15 | '∏': '∏',
16 | '∑': '∑',
17 | '−': '−',
18 | '∗': '∗',
19 | '√': '√',
20 | '∝': '∝',
21 | '∞': '∞',
22 | '∠': '∠',
23 | '∧': '∧',
24 | '∨': '∨',
25 | '∩': '∩',
26 | '∩': '∪',
27 | '∫': '∫',
28 | '∴': '∴',
29 | '∼': '∼',
30 | '≅': '≅',
31 | '≈': '≈',
32 | '≠': '≠',
33 | '≤': '≤',
34 | '≥': '≥',
35 | '⊂': '⊂',
36 | '⊃': '⊃',
37 | '⊄': '⊄',
38 | '⊆': '⊆',
39 | '⊇': '⊇',
40 | '⊕': '⊕',
41 | '⊗': '⊗',
42 | '⊥': '⊥',
43 | '⋅': '⋅',
44 |
45 | // HTML 支持的希腊字母
46 | 'Α': 'Α',
47 | 'Β': 'Β',
48 | 'Γ': 'Γ',
49 | 'Δ': 'Δ',
50 | 'Ε': 'Ε',
51 | 'Ζ': 'Ζ',
52 | 'Η': 'Η',
53 | 'Θ': 'Θ',
54 | 'Ι': 'Ι',
55 | 'Κ': 'Κ',
56 | 'Λ': 'Λ',
57 | 'Μ': 'Μ',
58 | 'Ν': 'Ν',
59 | 'Ξ': 'Ν',
60 | 'Ο': 'Ο',
61 | 'Π': 'Π',
62 | 'Ρ': 'Ρ',
63 | 'Σ': 'Σ',
64 | 'Τ': 'Τ',
65 | 'Υ': 'Υ',
66 | 'Φ': 'Φ',
67 | 'Χ': 'Χ',
68 | 'Ψ': 'Ψ',
69 | 'Ω': 'Ω',
70 | 'α': 'α',
71 | 'β': 'β',
72 | 'γ': 'γ',
73 | 'δ': 'δ',
74 | 'ε': 'ε',
75 | 'ζ': 'ζ',
76 | 'η': 'η',
77 | 'θ': 'θ',
78 | 'ι': 'ι',
79 | 'κ': 'κ',
80 | 'λ': 'λ',
81 | 'μ': 'μ',
82 | 'ν': 'ν',
83 | 'ξ': 'ξ',
84 | 'ο': 'ο',
85 | 'π': 'π',
86 | 'ρ': 'ρ',
87 | 'ς': 'ς',
88 | 'σ': 'σ',
89 | 'τ': 'τ',
90 | 'υ': 'υ',
91 | 'φ': 'φ',
92 | 'χ': 'χ',
93 | 'ψ': 'ψ',
94 | 'ω': 'ω',
95 | 'ϑ': 'ϑ',
96 | 'ϒ': 'ϒ',
97 | 'ϖ': 'ϖ',
98 | '·': '·',
99 |
100 | // 常用解析
101 | ' ': ' ',
102 | '"': "'",
103 | '&': '&',
104 | '<': '<',
105 | '>': '>',
106 |
107 | // HTML 支持的其他实体
108 | 'Œ': 'Œ',
109 | 'œ': 'œ',
110 | 'Š': 'Š',
111 | 'š': 'š',
112 | 'Ÿ': 'Ÿ',
113 | 'ƒ': 'ƒ',
114 | 'ˆ': 'ˆ',
115 | '˜': '˜',
116 | ' ': '',
117 | ' ': '',
118 | ' ': '',
119 | '': '',
120 | '': '',
121 | '': '',
122 | '': '',
123 | '–': '–',
124 | '—': '—',
125 | '‘': '‘',
126 | '’': '’',
127 | '‚': '‚',
128 | '“': '“',
129 | '”': '”',
130 | '„': '„',
131 | '†': '†',
132 | '‡': '‡',
133 | '•': '•',
134 | '…': '…',
135 | '‰': '‰',
136 | '′': '′',
137 | '″': '″',
138 | '‹': '‹',
139 | '›': '›',
140 | '‾': '‾',
141 | '€': '€',
142 | '™': '™',
143 | '←': '←',
144 | '↑': '↑',
145 | '→': '→',
146 | '↓': '↓',
147 | '↔': '↔',
148 | '↵': '↵',
149 | '⌈': '⌈',
150 | '⌉': '⌉',
151 | '⌊': '⌊',
152 | '⌋': '⌋',
153 | '◊': '◊',
154 | '♠': '♠',
155 | '♣': '♣',
156 | '♥': '♥',
157 | '♦': '♦',
158 | };
159 |
160 | /**
161 | * 转换特殊字符
162 | * @param {String} str 待转换字符串
163 | * @return {String} 转换后的字符串
164 | */
165 | const transform = (str) => {
166 | for (let code in codeMap) {
167 | str = str.replace(new RegExp(code, 'g'), codeMap[code]);
168 | }
169 | return str;
170 | };
171 |
172 | module.exports = {
173 | transform
174 | }
175 |
--------------------------------------------------------------------------------
/wxParser/elements.js:
--------------------------------------------------------------------------------
1 | const utils = require('./utils');
2 | const makeMap = utils.makeMap;
3 |
4 | module.exports = {
5 | empty: makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'),
6 | 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'),
7 | 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'),
8 | closeSelf: makeMap('br,hr'),
9 | fillAttrs: makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'),
10 | special: makeMap('script,style')
11 | };
12 |
--------------------------------------------------------------------------------
/wxParser/html2json.js:
--------------------------------------------------------------------------------
1 | const utils = require('./utils');
2 | const elements = require('./elements');
3 | const codeTransformation = require('./codeTransformation');
4 | const htmlParser = require('./htmlparser');
5 |
6 | /**
7 | * 移除文档头信息
8 | * @param {String} str HTML 内容
9 | * @return {String}
10 | */
11 | const removeDOCTYPE = (str) => {
12 | return str.replace(/<\?xml.*\?>\n/, '').replace(/<.*!doctype.*\>\n/, '').replace(/<.*!DOCTYPE.*\>\n/, '');
13 | };
14 |
15 | /**
16 | * HTML 内容转化为 JSON 格式的对象
17 | * @param {String} html HTML 内容
18 | * @param {String} bindName 绑定的数据名
19 | * @return {Object}
20 | */
21 | const html2json = (html, bindName) => {
22 | html = removeDOCTYPE(html);
23 | html = codeTransformation.transform(html);
24 |
25 | // 节点缓冲区,与 htmlparser.js 中的 stack 对应,只存储非自闭和标签
26 | // 比如 ,而非
等
27 | let bufferNodes = [];
28 | let nodeStyles = [];
29 | // html2json 结果
30 | let results = {
31 | nodes: [],
32 | images: [],
33 | imageUrls: []
34 | };
35 |
36 | /**
37 | * 把节点放到父节点的 nodes 列表
38 | * @param {Object} node 节点对象
39 | */
40 | const putNode2ParentNodeList = (node) => {
41 | if (bufferNodes.length === 0) { // 表明关闭此 node 时,不存在任何未关闭标签,也就是不存在父元素,所以直接挂到根节点即可
42 | results.nodes.push(node);
43 | } else {
44 | // 如果节点缓冲区还有节点,子节点会不断的被放到该子节点的父节点下,形成一个嵌套引用的节点对象。
45 | // 直到缓冲区没有节点,此时组装起来的整个嵌套引用节点对象会被放到根节点的 results.nodes 下
46 | let parent = bufferNodes[0]; // 取该 node 的父级节点
47 | if (parent.nodes === undefined) {
48 | parent.nodes = [];
49 | }
50 | parent.nodes.push(node);
51 | }
52 | };
53 |
54 | // 开始解析 HTML
55 | // 核心思路:
56 | // 1、遇到开始标签时,如果该标签是非自闭合标签,就把该节点存到缓存区(入栈),
57 | // 如果是自闭合标签、空标签等就直接存到根节点下(因为这种几点没有子节点)。
58 | // 2、当遇到文本时(文本也是节点),判断缓冲区是否还有节点,如果有,证明该节点有父节点,
59 | // 需要把此节点放到父节点的 nodes 列表,如果没有,则证明该节点没有父节点了,放到根节点即可。
60 | // 3、当遇到结束标签时,就从缓存区取出第一个节点(出栈),比较是否与该结束标签对应,
61 | // 如果不对应,证明逻辑出错。如果对应,则判断缓冲区是否还有节点,如果有,证明该节点有父节点,
62 | // 需要把此节点放到父节点的 nodes 列表,如果没有,则证明该节点没有父节点了,放到根节点即可。
63 | //
64 | // 总体来说,就是一个进栈出栈(节点缓冲区)的算法问题。
65 | htmlParser.parseHtml(html, {
66 | /**
67 | * 处理开始标签
68 | * @param {String} tag 标签名称
69 | * @param {Array} attrs 属性
70 | * @param {Boolean} isUnary 是否是自闭合标签
71 | */
72 | start: function (tag, attrs, isUnary) {
73 | let node = {
74 | node: 'element',
75 | tag: tag
76 | };
77 |
78 | if (elements.block[tag]) {
79 | node.tagType = 'block';
80 | } else if (elements.inline[tag]) {
81 | node.tagType = 'inline';
82 | } else if (elements.closeSelf[tag]) {
83 | node.tagType = 'closeSelf';
84 | }
85 |
86 | nodeStyles = [];
87 |
88 | if (attrs.length) {
89 | node.attr = {};
90 | attrs.map((item) => {
91 | if (item.name === 'style') { // 对 style 做单独处理,因为后面会根据 tag 添加更多的 style
92 | if (nodeStyles.indexOf(item.value) === -1) {
93 | nodeStyles.push(item.value);
94 | }
95 | }
96 | if (item.name === 'color') {
97 | nodeStyles.push('color: ' + item.value);
98 | }
99 | if (node.tag === 'font' && item.name === 'size') {
100 | nodeStyles.push('font-size: ' + utils.getFontSizeByAttribsSize(item.value));
101 | }
102 |
103 | // 特殊属性做转换
104 | if (item.name === 'class') {
105 | node.classStr = item.value;
106 | }
107 |
108 | node.attr[item.name] = item.value; // 重复的属性,后面的会覆盖前面的
109 | });
110 |
111 | node.styleStr = nodeStyles.join(' ');
112 | }
113 |
114 | // img 标签 添加额外数据
115 | if (node.tag === 'img') {
116 | node.imgIndex = results.images.length;
117 | node.from = bindName;
118 |
119 | results.images.push(node);
120 | results.imageUrls.push(node.attr.src);
121 | }
122 |
123 | if (isUnary) {
124 | // 自闭合标签,比如
125 | // 这种类型不会进入 end 函数或者 text 函数处理,在 start 函数放入到父元素的 nodes 列表即可
126 | putNode2ParentNodeList(node);
127 | } else {
128 | // 只要有非自闭&标签就往缓冲区保存节点,等待关闭
129 | bufferNodes.unshift(node);
130 | }
131 | },
132 | /**
133 | * 处理关闭标签
134 | * @param {String} tag 标签名称
135 | */
136 | end: function (tag) {
137 | let node = bufferNodes.shift(); // 取出缓冲区的第一个的未关闭标签,也就是与该结束标签对应的标签
138 |
139 | if (node.tag !== tag) {
140 | throw new Error('不匹配的关闭标签');
141 | }
142 |
143 | putNode2ParentNodeList(node);
144 | },
145 | /**
146 | * 处理文本内容
147 | * @param {String} text 文本字符串
148 | */
149 | text: function (text) {
150 | let node = {
151 | node: 'text',
152 | text: text,
153 | };
154 |
155 | putNode2ParentNodeList(node);
156 | },
157 | /**
158 | * 处理评论内容
159 | * @param {String} content 注释内容
160 | */
161 | comment: function (content) {},
162 | });
163 |
164 | return results;
165 |
166 | };
167 |
168 | module.exports = {
169 | html2json
170 | };
171 |
--------------------------------------------------------------------------------
/wxParser/htmlparser.js:
--------------------------------------------------------------------------------
1 | const elements = require('./elements');
2 |
3 | const startTagReg = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
4 | const endTagReg = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
5 | const attrReg = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
6 |
7 | /**
8 | * 解析 HTML
9 | * @param {String} html HTML 内容
10 | * @param {Object} handler 处理器
11 | */
12 | const parseHtml = (html, handler) => {
13 | let index;
14 | let isText;
15 | let match;
16 | let stack = [];
17 | let last = html;
18 | // 只存放非自闭合普通标签,不存放空标签、特殊标签和自闭合标签
19 | stack.last = function () {
20 | return this[this.length - 1];
21 | };
22 |
23 | while (html) {
24 | isText = true;
25 |
26 | if (!stack.length || !elements.special[stack.last()]) {
27 | if (html.indexOf(''); // indexOf 会匹配到第一个满足条件的字符位置
29 | if (index !== -1) {
30 | if (handler.comment) {
31 | // 因为注释信息不会像其他标签那样包含内部标签,所以可以直接传注释内容给 handler 处理
32 | handler.comment(html.substring(4, index));
33 | }
34 | html = html.substring(index + 3);
35 | isText = false;
36 | }
37 | } else if (html.indexOf('') === 0) { // end tag
38 | match = html.match(endTagReg);
39 | if (match) {
40 | html = html.substring(match[0].length);
41 | match[0].replace(endTagReg, parseEndTag);
42 | isText = false;
43 | }
44 | } else if (html.indexOf('<') === 0) { // start tag
45 | match = html.match(startTagReg);
46 | if (match) {
47 | html = html.substring(match[0].length);
48 | match[0].replace(startTagReg, parseStartTag);
49 | isText = false;
50 | }
51 | }
52 |
53 | // 处理文本内容
54 | if (isText) {
55 | index = html.indexOf('<');
56 | let text = ''
57 | while (index === 0 && !html.match(startTagReg)) { // 处理以 < 开头,但是却不满足 startTagReg 的情况
58 | text += '<';
59 | html = html.substring(1);
60 | index = html.indexOf('<');
61 | }
62 | text += index < 0 ? html : html.substring(0, index);
63 | html = index < 0 ? '' : html.substring(index);
64 |
65 | if (handler.text) {
66 | handler.text(text);
67 | }
68 | }
69 |
70 | } else {
71 | html = html.replace(new RegExp("([\\s\\S]*?)<\/" + stack.last() + "[^>]*>"), function (all, text) {
72 | // 丢弃 special tag 内部的所有内容,包括该 special tag 的闭合标签
73 | return '';
74 | });
75 | }
76 |
77 | if (html === last) {
78 | throw new Error('解析 html 内容时出席异常');
79 | }
80 |
81 | last = html;
82 | }
83 |
84 | if (stack.length) {
85 | throw new Error('HTML 内容存在未关闭的标签,会导致未关闭标签的内容无法被解析');
86 | }
87 |
88 | /**
89 | * 解析开始标签
90 | * @param {String} match 匹配结果
91 | * @param {String} tagName 标签名称
92 | * @param {String} attrsStr 属性信息
93 | * @param {String} unary
94 | */
95 | function parseStartTag(match, tagName, attrsStr, unary) {
96 | // 举例:
97 | // match:
98 | // tagName: p
99 | // attrsStr: style="text-align: center; " width="100"
100 |
101 | tagName = tagName.toLowerCase();
102 |
103 | let isUnary = elements.empty[tagName] || unary;
104 |
105 | // 空标签、自闭和标签、特殊标签不需要进 stack
106 | if (!isUnary && !elements.closeSelf[tagName] && !elements.special[tagName]) {
107 | stack.push(tagName);
108 | }
109 |
110 | if (handler.start && !elements.special[tagName]) {
111 | let attrs = [];
112 |
113 | attrsStr.replace(attrReg, function (match, name, value) {
114 |
115 | if (elements.fillAttrs[name]) {
116 | value = name;
117 | }
118 |
119 | attrs.push({
120 | name: name,
121 | value: value || '',
122 | });
123 | });
124 |
125 | handler.start(tagName, attrs, isUnary);
126 |
127 | }
128 | }
129 |
130 | /**
131 | * 解析结束标签
132 | * @param {String} match 匹配结果
133 | * @param {String} tagName 标签名称
134 | */
135 | function parseEndTag(match, tagName) {
136 | if (!tagName) {
137 | return;
138 | }
139 |
140 | // 找到最近同种类型的未关闭标签的位置
141 | tagName = tagName.toLowerCase();
142 | let closestOpenedTagPos = -1;
143 | for (let pos = stack.length - 1; pos >= 0; pos--) {
144 | if (stack[pos] == tagName) {
145 | closestOpenedTagPos = pos;
146 | break;
147 | }
148 | }
149 |
150 | if (closestOpenedTagPos >= 0) {
151 | if (handler.end) {
152 | handler.end(stack[closestOpenedTagPos]);
153 | }
154 | // 处理后从 stack 中移除该标签
155 | stack.length = closestOpenedTagPos;
156 | }
157 | }
158 | };
159 |
160 | module.exports = {
161 | parseHtml
162 | };
163 |
--------------------------------------------------------------------------------
/wxParser/index.js:
--------------------------------------------------------------------------------
1 | const html2Json = require('./html2json');
2 |
3 | /**
4 | * 主解析函数
5 | * @param {Object} options 配置参数
6 | * @param {String} [options.bind=wxParserData] 绑定的变量名
7 | * @param {String} options.html HTML 内容
8 | * @param {Object} options.target 要绑定的模块对象
9 | * @param {Boolean} [options.enablePreviewImage=true] 是否启用预览图片功能
10 | * @param {Function} [options.tapLink] 点击超链接后的回调函数
11 | */
12 | const parse = ({ bind = 'wxParserData', html, target, enablePreviewImage = true, tapLink }) => {
13 | if (Object.prototype.toString.call(html) !== '[object String]') {
14 | throw new Error('HTML 内容必须是字符串');
15 | }
16 | let that = target;
17 | let transData = {}; // 存放转化后的数据
18 | transData = html2Json.html2json(html, bind);
19 |
20 | let bindData = {};
21 | bindData[bind] = transData;
22 |
23 | that.setData(bindData)
24 |
25 | // 加载图片后回调函数
26 | that.loadedWxParserImg = (e) => {
27 |
28 | };
29 |
30 | // 点击图片
31 | that.tapWxParserImg = (e) => {
32 | if (!enablePreviewImage) {
33 | return;
34 | }
35 | let src = e.target.dataset.src;
36 | let tagFrom = e.target.dataset.from;
37 | if (typeof (tagFrom) !== 'undefined' && tagFrom.length > 0) {
38 | wx.previewImage({
39 | current: src, // 当前显示图片的 http 链接
40 | urls: that.data[tagFrom].imageUrls // 需要预览的图片 http 链接列表
41 | })
42 | }
43 | };
44 |
45 | // 点击超链接
46 | if (Object.prototype.toString.call(tapLink) === '[object Function]') {
47 | that.tapWxParserA = (e) => {
48 | let href = e.currentTarget.dataset.href;
49 | tapLink(href);
50 | };
51 | }
52 |
53 | };
54 |
55 | module.exports = {
56 | parse
57 | }
58 |
--------------------------------------------------------------------------------
/wxParser/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{item.text}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
--------------------------------------------------------------------------------
/wxParser/index.wxss:
--------------------------------------------------------------------------------
1 | /**
2 | * wxParser 基础样式
3 | */
4 |
5 | .wxParser-div,
6 | .wxParser-p,
7 | {
8 | word-break: break-all;
9 | overflow: auto;
10 | max-width: 100%;
11 | }
12 |
13 | .wxParser-inline {
14 | display: inline;
15 | margin: 0;
16 | padding: 0;
17 | }
18 |
19 | .wxParser-div {
20 | margin: 0;
21 | padding: 0;
22 | }
23 |
24 | .wxParser-p {
25 | margin: 5rpx 0;
26 | }
27 |
28 | .wxParser-br {
29 | height: 1em;
30 | }
31 |
32 | .wxParser-h1 {
33 | font-size: 2em;
34 | margin: .67em 0;
35 | }
36 |
37 | .wxParser-h2 {
38 | font-size: 1.5em;
39 | margin: .75em 0;
40 | }
41 |
42 | .wxParser-h3 {
43 | font-size: 1.17em;
44 | margin: .83em 0;
45 | }
46 |
47 | .wxParser-h4 {
48 | margin: 1.12em 0;
49 | }
50 |
51 | .wxParser-h5 {
52 | font-size: .83em;
53 | margin: 1.5em 0;
54 | }
55 |
56 | .wxParser-h6 {
57 | font-size: .75em;
58 | margin: 1.67em 0;
59 | }
60 |
61 | .wxParser-h1,
62 | .wxParser-h2,
63 | .wxParser-h3,
64 | .wxParser-h4,
65 | .wxParser-h5,
66 | .wxParser-h6,
67 | .wxParser-b,
68 | .wxParser-strong {
69 | font-weight: bolder;
70 | }
71 |
72 | .wxParser-i,
73 | .wxParser-cite,
74 | .wxParser-em,
75 | .wxParser-var,
76 | .wxParser-address {
77 | font-style: italic;
78 | }
79 |
80 | .wxParser-pre,
81 | .wxParser-tt,
82 | .wxParser-code,
83 | .wxParser-kbd,
84 | .wxParser-samp {
85 | font-family: monospace;
86 | }
87 |
88 | .wxParser-pre {
89 | white-space: pre;
90 | }
91 |
92 | .wxParser-big {
93 | font-size: 1.17em
94 | }
95 |
96 | .wxParser-small,
97 | .wxParser-sub,
98 | .wxParser-sup {
99 | font-size: .83em
100 | }
101 |
102 | .wxParser-sub {
103 | vertical-align: sub;
104 | }
105 |
106 | .wxParser-sup {
107 | vertical-align: super;
108 | }
109 |
110 | .wxParser-s,
111 | .wxParser-strike,
112 | .wxParser-del {
113 | text-decoration: line-through;
114 | }
115 |
116 | .wxParser-strong,
117 | .wxParser-s {
118 | display: inline;
119 | }
120 |
121 | .wxParser-u {
122 | text-decoration: underline;
123 | }
124 |
125 | .wxParser-u {
126 | text-decoration: underline;
127 | }
128 |
129 | .wxParser-a {
130 | color: deepskyblue;
131 | word-break: break-all;
132 | overflow: auto;
133 | }
134 |
135 | .wxParser-video {
136 | text-align: center;
137 | margin: 10rpx 0;
138 | }
139 |
140 | .wxParser-video-video {
141 | width: 100%;
142 | }
143 |
144 | .wxParser-img {
145 | overflow: hidden;
146 | max-width: 100%;
147 | }
148 |
149 | .wxParser-blockquote {
150 | margin: 0;
151 | padding: 10rpx 0 10rpx 5rpx;
152 | font-family: Courier, Calibri, "宋体";
153 | background: #f5f5f5;
154 | border-left: 3rpx solid #dbdbdb;
155 | }
156 |
157 | .wxParser-ul {
158 | margin: 20rpx 10rpx;
159 | }
160 |
161 | .wxParser-li {
162 | margin: 10rpx 0;
163 | }
164 |
165 | .wxParser-li,
166 | .wxParser-li-inner {
167 | display: flex;
168 | align-items: baseline;
169 | }
170 |
171 | .wxParser-li-text {
172 | align-items: center;
173 | line-height: 1em;
174 | }
175 |
176 | .wxParser-li-circle {
177 | display: inline-flex;
178 | width: 10rpx;
179 | height: 10rpx;
180 | background-color: #333;
181 | margin-right: 12rpx;
182 | border-radius: 50%;
183 | }
184 |
185 | .wxParser-li-square {
186 | display: inline-flex;
187 | width: 10rpx;
188 | height: 10rpx;
189 | background-color: #333;
190 | margin-right: 5rpx;
191 | }
192 |
193 | .wxParser-li-ring {
194 | display: inline-flex;
195 | width: 10rpx;
196 | height: 10rpx;
197 | border: 2rpx solid #333;
198 | border-radius: 50%;
199 | background-color: #fff;
200 | margin-right: 5rpx;
201 | }
202 |
203 | .wxParser-hidden {
204 | display: none;
205 | }
206 |
207 | .wxParser-tr {
208 | display: flex;
209 | border-right: 1rpx solid #e0e0e0;
210 | border-bottom: 1rpx solid #e0e0e0;
211 | }
212 |
213 | .wxParser-th,
214 | .wxParser-td {
215 | flex: 1;
216 | padding: 5rpx;
217 | font-size: 28rpx;
218 | border-left: 1rpx solid #e0e0e0;
219 | word-break: break-all;
220 | }
221 |
222 | .wxParser-td:last {
223 | border-top: 1rpx solid #e0e0e0;
224 | }
225 |
226 | .wxParser-th {
227 | background: #f0f0f0;
228 | border-top: 1rpx solid #e0e0e0;
229 | }
230 |
--------------------------------------------------------------------------------
/wxParser/utils.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | /**
3 | * 生成 Map
4 | * @param {String} str 以逗号分隔的字符串
5 | * @return {Object} 映射表
6 | */
7 | makeMap: (str) => {
8 | let map = {};
9 | let items = str.split(',');
10 | for (let i = 0, len = items.length; i < len; i++) {
11 | map[items[i]] = true;
12 | }
13 | return map;
14 | },
15 | /**
16 | * 根据 size 属性得到字体大小
17 | * @param {Number|String} size
18 | * @return {String}
19 | */
20 | getFontSizeByAttribsSize: function (size) {
21 | var fontSize;
22 | size = parseInt(size, 10);
23 | switch (size) {
24 | case 2:
25 | fontSize = 0.75;
26 | break;
27 | case 3:
28 | fontSize = 1;
29 | break;
30 | case 4:
31 | fontSize = 1.17;
32 | break;
33 | case 5:
34 | fontSize = 1.5;
35 | break;
36 | case 6:
37 | fontSize = 2;
38 | break;
39 | case 7:
40 | fontSize = 3;
41 | break;
42 | default:
43 | fontSize = 1;
44 | }
45 | return fontSize + 'em';
46 | },
47 | }
48 |
--------------------------------------------------------------------------------