Commit 93780232 by 高淑倩

add: 商品详情页_图文详情

parent c3f5dd10
// component/html2wxml/wxHtml.js
const wxParser = require('../../wxParser/index')
Component({
/**
* 组件的属性列表
*/
properties: {
config: {
type: Object,
observer: '_configChange',
value: null
},
html: {
type: String,
value: '',
observer: '_htmlChange'
}
},
/**
* 组件的初始数据
*/
data: {
},
created () {
this.init()
},
attached: function () {
console.log(this)
},
moved: function () { },
detached: function () {
this._htmlChange = null
this._configChange = null
},
/**
* 组件的方法列表
*/
methods: {
init: function (config) {
config = config || {
bind: 'richText',
html: this.data.html || ``,
target: this,
enablePreviewImage: false, // 禁用图片预览功能
tapLink: (url) => { // 点击超链接时的回调函数
// url 就是 HTML 富文本中 a 标签的 href 属性值
// 这里可以自定义点击事件逻辑,比如页面跳转
wx.navigateTo({
url
})
}
}
this.data.config = config
},
_parse: function (config) {
wxParser.parse(config)
},
_parseHtml (html) {
let config = this.data.config
config.html = html
this._parse(config)
},
_configChange (newV, oldV) {
if (newV !== oldV) {
this._parse(newV)
}
},
_htmlChange (newV, oldV) {
if (newV !== oldV) {
this._parseHtml(newV)
}
}
}
})
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<!--component/html2wxml/wxHtml.wxml-->
<view class='wx-html'>
<import src="../../wxParser/index.wxml"/>
<view class="wxParser">
<template is="wxParser" data="{{wxParserData:richText.nodes}}"/>
</view>
</view>
/* component/html2wxml/wxHtml.wxss */
@import '../../wxParser/index.wxss';
.wxParser image {
width:100%;
}
\ No newline at end of file
......@@ -5,12 +5,12 @@ import { Integer } from '../../utils/integerDigitalConvertion'
wxService.page({
/**
* 页面的初始数据
*/
data: {
productId:'',
scrollTips: '继续拖动,查看图文详情', // 滑动文案
productInfo:'',
showHtml: false,
reachBottom: false, // 标识是否触底
......
......@@ -3,6 +3,7 @@
"usingComponents": {
"buy-image-swiper": "/component/buyImageSwiper/buyImageSwiper",
"sku-popup": "/component/skuPopup/skuPopup",
"card-modal": "/component/cardModal/cardModal"
"card-modal": "/component/cardModal/cardModal",
"x-html": "/component/html2wxml/wxHtml"
}
}
\ No newline at end of file
<!--pages/productDetail/productDetail.wxml-->
<import src="../../wxParser/index.wxml" />
<view
class="page-product-detail product-container"
bindtouchstart="pageTouchStart"
......@@ -68,9 +69,15 @@
<view class="gray-line" />
<view class="scroll-tips">
<!--<view class="scroll-tips">
继续拖动,查看图文详情
</view>
</view>-->
<view class="scroll-tips" wx:if="{{htmlContent == null}}">{{scrollTips}}</view>
<block wx:if="{{showHtml}}">
<x-html html="{{productInfo.descHtml}}" />
</block>
<view class="product-footer">
<view class="footer-icons clearfix">
......
......@@ -39,7 +39,7 @@
"list": []
},
"miniprogram": {
"current": 38,
"current": 16,
"list": [
{
"id": -1,
......@@ -141,10 +141,10 @@
"scene": null
},
{
"id": -1,
"id": 16,
"name": "商品详情页",
"pathName": "pages/productDetail/productDetail",
"query": "",
"query": "productId=1008190",
"scene": null
},
{
......@@ -297,7 +297,8 @@
{
"id": -1,
"name": "集点列表",
"pathName": "pages/pointList/pointList"
"pathName": "pages/pointList/pointList",
"query": ""
}
]
}
......
/**
* 特殊字符映射表
* @type {Object}
*/
const codeMap = {
// HTML 支持的数学符号
'&forall;': '∀',
'&part;': '∂',
'&exists;': '∃',
'&empty;': '∅',
'&nabla;': '∇',
'&isin;': '∈',
'&notin;': '∉',
'&ni;': '∋',
'&prod;': '∏',
'&sum;': '∑',
'&minus;': '−',
'&lowast;': '∗',
'&radic;': '√',
'&prop;': '∝',
'&infin;': '∞',
'&ang;': '∠',
'&and;': '∧',
'&or;': '∨',
'&cap;': '∩',
'&cap;': '∪',
'&int;': '∫',
'&there4;': '∴',
'&sim;': '∼',
'&cong;': '≅',
'&asymp;': '≈',
'&ne;': '≠',
'&le;': '≤',
'&ge;': '≥',
'&sub;': '⊂',
'&sup;': '⊃',
'&nsub;': '⊄',
'&sube;': '⊆',
'&supe;': '⊇',
'&oplus;': '⊕',
'&otimes;': '⊗',
'&perp;': '⊥',
'&sdot;': '⋅',
// HTML 支持的希腊字母
'&Alpha;': 'Α',
'&Beta;': 'Β',
'&Gamma;': 'Γ',
'&Delta;': 'Δ',
'&Epsilon;': 'Ε',
'&Zeta;': 'Ζ',
'&Eta;': 'Η',
'&Theta;': 'Θ',
'&Iota;': 'Ι',
'&Kappa;': 'Κ',
'&Lambda;': 'Λ',
'&Mu;': 'Μ',
'&Nu;': 'Ν',
'&Xi;': 'Ν',
'&Omicron;': 'Ο',
'&Pi;': 'Π',
'&Rho;': 'Ρ',
'&Sigma;': 'Σ',
'&Tau;': 'Τ',
'&Upsilon;': 'Υ',
'&Phi;': 'Φ',
'&Chi;': 'Χ',
'&Psi;': 'Ψ',
'&Omega;': 'Ω',
'&alpha;': 'α',
'&beta;': 'β',
'&gamma;': 'γ',
'&delta;': 'δ',
'&epsilon;': 'ε',
'&zeta;': 'ζ',
'&eta;': 'η',
'&theta;': 'θ',
'&iota;': 'ι',
'&kappa;': 'κ',
'&lambda;': 'λ',
'&mu;': 'μ',
'&nu;': 'ν',
'&xi;': 'ξ',
'&omicron;': 'ο',
'&pi;': 'π',
'&rho;': 'ρ',
'&sigmaf;': 'ς',
'&sigma;': 'σ',
'&tau;': 'τ',
'&upsilon;': 'υ',
'&phi;': 'φ',
'&chi;': 'χ',
'&psi;': 'ψ',
'&omega;': 'ω',
'&thetasym;': 'ϑ',
'&upsih;': 'ϒ',
'&piv;': 'ϖ',
'&middot;': '·',
// 常用解析
'&nbsp;': ' ',
'&quot;': "'",
'&amp;': '&',
'&lt;': '<',
'&gt;': '>',
// HTML 支持的其他实体
'&OElig;': 'Œ',
'&oelig;': 'œ',
'&Scaron;': 'Š',
'&scaron;': 'š',
'&Yuml;': 'Ÿ',
'&fnof;': 'ƒ',
'&circ;': 'ˆ',
'&tilde;': '˜',
'&ensp;': '',
'&emsp;': '',
'&thinsp;': '',
'&zwnj;': '',
'&zwj;': '',
'&lrm;': '',
'&rlm;': '',
'&ndash;': '–',
'&mdash;': '—',
'&lsquo;': '‘',
'&rsquo;': '’',
'&sbquo;': '‚',
'&ldquo;': '“',
'&rdquo;': '”',
'&bdquo;': '„',
'&dagger;': '†',
'&Dagger;': '‡',
'&bull;': '•',
'&hellip;': '…',
'&permil;': '‰',
'&prime;': '′',
'&Prime;': '″',
'&lsaquo;': '‹',
'&rsaquo;': '›',
'&oline;': '‾',
'&euro;': '€',
'&trade;': '™',
'&larr;': '←',
'&uarr;': '↑',
'&rarr;': '→',
'&darr;': '↓',
'&harr;': '↔',
'&crarr;': '↵',
'&lceil;': '⌈',
'&rceil;': '⌉',
'&lfloor;': '⌊',
'&rfloor;': '⌋',
'&loz;': '◊',
'&spades;': '♠',
'&clubs;': '♣',
'&hearts;': '♥',
'&diams;': '♦',
'&#39;': "'"
}
/**
* 转换特殊字符
* @param {String} str 待转换字符串
* @return {String} 转换后的字符串
*/
const transform = (str) => {
for (let code in codeMap) {
str = str.replace(new RegExp(code, 'g'), codeMap[code])
}
return str
}
module.exports = {
transform
}
const utils = require('./utils')
const makeMap = utils.makeMap
module.exports = {
empty: makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'),
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'),
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'),
closeSelf: makeMap('br,hr'),
fillAttrs: makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'),
special: makeMap('script,style')
}
const utils = require('./utils')
const elements = require('./elements')
const codeTransformation = require('./codeTransformation')
const htmlParser = require('./htmlparser')
let olTagCount = []
/**
* 移除文档头信息
* @param {String} str HTML 内容
* @return {String}
*/
const removeDOCTYPE = (str) => {
return str.replace(/<\?xml.*\?>\n/, '').replace(/<.*!doctype.*\>\n/, '').replace(/<.*!DOCTYPE.*\>\n/, '')
}
/**
* HTML 内容转化为 JSON 格式的对象
* @param {String} html HTML 内容
* @param {String} bindName 绑定的数据名
* @return {Object}
*/
const html2json = (html, bindName) => {
html = removeDOCTYPE(html)
// 节点缓冲区,与 htmlparser.js 中的 stack 对应,只存储非自闭和标签
// 比如 <span></span>,而非 <img src="#"> 等
let bufferNodes = []
let nodeStyles = []
// html2json 结果
let results = {
nodes: [],
images: [],
imageUrls: []
}
/**
* 把节点放到父节点的 nodes 列表
* @param {Object} node 节点对象
*/
const putNode2ParentNodeList = (node) => {
if (bufferNodes.length === 0) { // 表明关闭此 node 时,不存在任何未关闭标签,也就是不存在父元素,所以直接挂到根节点即可
results.nodes.push(node)
} else {
// 如果节点缓冲区还有节点,子节点会不断的被放到该子节点的父节点下,形成一个嵌套引用的节点对象。
// 直到缓冲区没有节点,此时组装起来的整个嵌套引用节点对象会被放到根节点的 results.nodes 下
let parent = bufferNodes[0] // 取该 node 的父级节点
if (parent.nodes === undefined) {
parent.nodes = []
}
node.parent = parent.tag
parent.nodes.push(node)
}
}
// 开始解析 HTML
// 核心思路:
// 1、遇到开始标签时,如果该标签是非自闭合标签,就把该节点存到缓存区(入栈),
// 如果是自闭合标签、空标签等就直接存到根节点下(因为这种几点没有子节点)。
// 2、当遇到文本时(文本也是节点),判断缓冲区是否还有节点,如果有,证明该节点有父节点,
// 需要把此节点放到父节点的 nodes 列表,如果没有,则证明该节点没有父节点了,放到根节点即可。
// 3、当遇到结束标签时,就从缓存区取出第一个节点(出栈),比较是否与该结束标签对应,
// 如果不对应,证明逻辑出错。如果对应,则判断缓冲区是否还有节点,如果有,证明该节点有父节点,
// 需要把此节点放到父节点的 nodes 列表,如果没有,则证明该节点没有父节点了,放到根节点即可。
//
// 总体来说,就是一个进栈出栈(节点缓冲区)的算法问题。
htmlParser.parseHtml(html, {
/**
* 处理开始标签
* @param {String} tag 标签名称
* @param {Array} attrs 属性
* @param {Boolean} isUnary 是否是自闭合标签
*/
start: function (tag, attrs, isUnary) {
let node = {
node: 'element',
tag: tag
}
if (elements.block[tag]) {
node.tagType = 'block'
} else if (elements.inline[tag]) {
node.tagType = 'inline'
} else if (elements.closeSelf[tag]) {
node.tagType = 'closeSelf'
}
nodeStyles = []
if (attrs.length) {
node.attr = {}
attrs.map((item) => {
if (item.name === 'style') { // 对 style 做单独处理,因为后面会根据 tag 添加更多的 style
if (nodeStyles.indexOf(item.value) === -1) {
nodeStyles.push(item.value)
}
}
if (item.name === 'color') {
nodeStyles.push('color: ' + item.value)
}
if (node.tag === 'font' && item.name === 'size') {
nodeStyles.push('font-size: ' + utils.getFontSizeByAttribsSize(item.value))
}
// 特殊属性做转换
if (item.name === 'class') {
node.classStr = item.value
}
node.attr[item.name] = item.value // 重复的属性,后面的会覆盖前面的
})
node.styleStr = nodeStyles.join(' ')
}
if (node.tag == 'ol' || node.tag == 'ul') {
olTagCount.push(0)
}
if (node.tag == 'li') {
let len = olTagCount.length - 1
olTagCount[len] = olTagCount[len] + 1
node.order = olTagCount[len]
}
// img 标签 添加额外数据
if (node.tag === 'img') {
node.imgIndex = results.images.length
node.from = bindName
results.images.push(node)
results.imageUrls.push(node.attr.src)
}
if (node.tag === 'video' || node.tag === 'audio') {
node.attr.controls = !!node.attr.controls
node.attr.autoplay = !!node.attr.autoplay
node.attr.loop = !!node.attr.loop
}
if (node.tag === 'video') {
node.attr.muted = !!node.attr.muted
}
if (node.tag === 'audio') {
let params = node.attr['data-extra']
if (params) {
params = params.replace(new RegExp('&quot;', 'g'), '"')
params = JSON.parse(params)
node.attr.poster = params.poster
node.attr.name = params.name
node.attr.author = params.author
}
}
if (isUnary) {
// 自闭合标签,比如 <img src="https://github.com/pacochan/wxParser.png"/>
// 这种类型不会进入 end 函数或者 text 函数处理,在 start 函数放入到父元素的 nodes 列表即可
putNode2ParentNodeList(node)
} else {
// 只要有非自闭&标签就往缓冲区保存节点,等待关闭
bufferNodes.unshift(node)
}
},
/**
* 处理关闭标签
* @param {String} tag 标签名称
*/
end: function (tag) {
let node = bufferNodes.shift() // 取出缓冲区的第一个的未关闭标签,也就是与该结束标签对应的标签
if (node.tag !== tag) {
throw new Error('不匹配的关闭标签')
}
if (node.tag == 'ol' || node.tag == 'ul') {
olTagCount.pop()
}
if (node.tag === 'video' || node.tag === 'audio') {
if (!node.attr.src) {
let nodes = node.nodes
let len = nodes.length
let src = ''
for (let i = 0; i < len; i++) {
if (nodes[i].tag === 'source') {
src = nodes[i].attr.src
break
}
}
node.attr.src = src
}
}
putNode2ParentNodeList(node)
},
/**
* 处理文本内容
* @param {String} text 文本字符串
*/
text: function (text) {
let node = {
node: 'text',
text: codeTransformation.transform(text)
}
putNode2ParentNodeList(node)
},
/**
* 处理评论内容
* @param {String} content 注释内容
*/
comment: function (content) {}
})
return results
}
module.exports = {
html2json
}
const elements = require('./elements')
const startTagReg = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/
const endTagReg = /^<\/([-A-Za-z0-9_]+)[^>]*>/
const attrReg = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g
/**
* 解析 HTML
* @param {String} html HTML 内容
* @param {Object} handler 处理器
*/
const parseHtml = (html, handler) => {
let index
let isText
let match
let stack = []
let last = html
// 只存放非自闭合普通标签,不存放空标签、特殊标签和自闭合标签
stack.last = function () {
return this[this.length - 1]
}
while (html) {
isText = true
if (!stack.length || !elements.special[stack.last()]) {
if (html.indexOf('<!--') === 0) { // comment
index = html.indexOf('-->') // indexOf 会匹配到第一个满足条件的字符位置
if (index !== -1) {
if (handler.comment) {
// 因为注释信息不会像其他标签那样包含内部标签,所以可以直接传注释内容给 handler 处理
handler.comment(html.substring(4, index))
}
html = html.substring(index + 3)
isText = false
}
} else if (html.indexOf('</') === 0) { // end tag
match = html.match(endTagReg)
if (match) {
html = html.substring(match[0].length)
match[0].replace(endTagReg, parseEndTag)
isText = false
}
} else if (html.indexOf('<') === 0) { // start tag
match = html.match(startTagReg)
if (match) {
html = html.substring(match[0].length)
match[0].replace(startTagReg, parseStartTag)
isText = false
}
}
// 处理文本内容
if (isText) {
index = html.indexOf('<')
let text = ''
while (index === 0 && !html.match(startTagReg)) { // 处理以 < 开头,但是却不满足 startTagReg 的情况
text += '<'
html = html.substring(1)
index = html.indexOf('<')
}
text += index < 0 ? html : html.substring(0, index)
html = index < 0 ? '' : html.substring(index)
if (handler.text) {
handler.text(text)
}
}
} else {
html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
// 丢弃 special tag 内部的所有内容,包括该 special tag 的闭合标签
return ''
})
}
if (html === last) {
throw new Error('解析 html 内容时出席异常')
}
last = html
}
if (stack.length) {
throw new Error('HTML 内容存在未关闭的标签,会导致未关闭标签的内容无法被解析')
}
/**
* 解析开始标签
* @param {String} match 匹配结果
* @param {String} tagName 标签名称
* @param {String} attrsStr 属性信息
* @param {String} unary
*/
function parseStartTag (match, tagName, attrsStr, unary) {
// 举例:
// match: <p style="text-align: center; " width="100">
// tagName: p
// attrsStr: style="text-align: center; " width="100"
tagName = tagName.toLowerCase()
let isUnary = elements.empty[tagName] || unary
// 空标签、自闭和标签、特殊标签不需要进 stack
if (!isUnary && !elements.closeSelf[tagName] && !elements.special[tagName]) {
stack.push(tagName)
}
if (handler.start && !elements.special[tagName]) {
let attrs = []
attrsStr.replace(attrReg, function (match, name, value) {
if (elements.fillAttrs[name]) {
value = name
}
attrs.push({
name: name,
value: value || ''
})
})
handler.start(tagName, attrs, isUnary)
}
}
/**
* 解析结束标签
* @param {String} match 匹配结果
* @param {String} tagName 标签名称
*/
function parseEndTag (match, tagName) {
if (!tagName) {
return
}
// 找到最近同种类型的未关闭标签的位置
tagName = tagName.toLowerCase()
let closestOpenedTagPos = -1
for (let pos = stack.length - 1; pos >= 0; pos--) {
if (stack[pos] == tagName) {
closestOpenedTagPos = pos
break
}
}
if (closestOpenedTagPos >= 0) {
if (handler.end) {
handler.end(stack[closestOpenedTagPos])
}
// 处理后从 stack 中移除该标签
stack.length = closestOpenedTagPos
}
}
}
module.exports = {
parseHtml
}
const html2Json = require('./html2json')
/**
* 主解析函数
* @param {Object} options 配置参数
* @param {String} [options.bind=wxParserData] 绑定的变量名
* @param {String} options.html HTML 内容
* @param {Object} options.target 要绑定的模块对象
* @param {Boolean} [options.enablePreviewImage=true] 是否启用预览图片功能
* @param {Function} [options.tapLink] 点击超链接后的回调函数
*/
const parse = ({ bind = 'wxParserData', html, target, enablePreviewImage = true, tapLink }) => {
if (Object.prototype.toString.call(html) !== '[object String]') {
throw new Error('HTML 内容必须是字符串')
}
let that = target
let transData = {} // 存放转化后的数据
transData = html2Json.html2json(html, bind)
let bindData = {}
bindData[bind] = transData
that.setData(bindData)
// 加载图片后回调函数
that.loadedWxParserImg = (e) => {
}
// 点击图片
that.tapWxParserImg = (e) => {
if (!enablePreviewImage) {
return
}
let src = e.target.dataset.src
let tagFrom = e.target.dataset.from
if (typeof (tagFrom) !== 'undefined' && tagFrom.length > 0) {
wx.previewImage({
current: src, // 当前显示图片的 http 链接
urls: that.data[tagFrom].imageUrls // 需要预览的图片 http 链接列表
})
}
}
// 点击超链接
if (Object.prototype.toString.call(tapLink) === '[object Function]') {
that.tapWxParserA = (e) => {
let href = e.currentTarget.dataset.href
tapLink(href)
}
}
}
module.exports = {
parse
}
This source diff could not be displayed because it is too large. You can view the blob instead.
@charset "UTF-8";
/**
* wxParser 基础样式
*/
.wxParser-div,
.wxParser-p {
word-break: break-all;
overflow: auto;
max-width: 100%; }
.wxParser-inline {
display: inline;
margin: 0;
padding: 0; }
.wxParser-div {
margin: 0;
padding: 0; }
.wxParser-p {
margin: 5rpx 0; }
.wxParser-br {
height: 0.4em; }
.wxParser-h1 {
font-size: 2em;
margin: .67em 0; }
.wxParser-h2 {
font-size: 1.5em;
margin: .75em 0; }
.wxParser-h3 {
font-size: 1.17em;
margin: .83em 0; }
.wxParser-h4 {
margin: 1.12em 0; }
.wxParser-h5 {
font-size: .83em;
margin: 1.5em 0; }
.wxParser-h6 {
font-size: .75em;
margin: 1.67em 0; }
.wxParser-h1,
.wxParser-h2,
.wxParser-h3,
.wxParser-h4,
.wxParser-h5,
.wxParser-h6,
.wxParser-b,
.wxParser-strong {
font-weight: bolder; }
.wxParser-i,
.wxParser-cite,
.wxParser-em,
.wxParser-var,
.wxParser-address {
font-style: italic; }
.wxParser-pre,
.wxParser-tt,
.wxParser-code,
.wxParser-kbd,
.wxParser-samp {
font-family: monospace; }
.wxParser-pre {
white-space: pre; }
.wxParser-big {
font-size: 1.17em; }
.wxParser-small,
.wxParser-sub,
.wxParser-sup {
font-size: .83em; }
.wxParser-sub {
vertical-align: sub; }
.wxParser-sup {
vertical-align: super; }
.wxParser-s,
.wxParser-strike,
.wxParser-del {
text-decoration: line-through; }
.wxParser-strong,
.wxParser-s {
display: inline; }
.wxParser-u {
text-decoration: underline; }
.wxParser-u {
text-decoration: underline; }
.wxParser-a {
color: deepskyblue;
word-break: break-all;
overflow: auto; }
.wxParser-video {
text-align: center;
margin: 10rpx 0; }
.wxParser-video-video {
width: 100%; }
.wxParser-audio {
text-align: center;
margin: 10rpx 0; }
.wxParser-audio-audio {
display: flex;
flex-direction: column;
text-align: left; }
.wxParser-img {
overflow: hidden;
max-width: 100%; }
.wxParser-blockquote {
margin: 0;
padding: 8rpx 20rpx 8rpx 20rpx;
font-family: Courier, Calibri, "宋体";
background: #f5f5f5;
border-left: 3rpx solid #dbdbdb; }
.wxParser-ul {
margin: 20rpx 10rpx; }
.wxParser-li {
margin: 10rpx 0; }
.wxParser-li,
.wxParser-li-inner {
display: flex;
align-items: baseline; }
.wxParser-li-text {
align-items: center;
line-height: 1em; }
.wxParser-li-circle {
display: inline-flex;
width: 10rpx;
height: 10rpx;
background-color: #333;
margin-right: 12rpx;
border-radius: 50%; }
.wxParser-li-square {
display: inline-flex;
width: 10rpx;
height: 10rpx;
background-color: #333;
margin-right: 5rpx; }
.wxParser-li-ring {
display: inline-flex;
width: 10rpx;
height: 10rpx;
border: 2rpx solid #333;
border-radius: 50%;
background-color: #fff;
margin-right: 5rpx; }
.wxParser-ol {
margin: 20rpx 10rpx; }
.wxParser-ol-li {
margin: 10rpx 0; }
.wxParser-ol-li,
.wxParser-ol-li-inner {
display: flex;
align-items: baseline; }
.wxParser-ol-li-text {
margin-right: 12rpx;
line-height: 1em; }
.wxParser-hidden {
display: none; }
.wxParser-tr {
display: flex;
border-right: 1rpx solid #e0e0e0; }
.wxParser-th,
.wxParser-td {
flex: 1;
padding: 5rpx;
font-size: 28rpx;
border-left: 1rpx solid #e0e0e0;
border-top: 1rpx solid #e0e0e0;
word-break: break-all; }
.wxParser-tr:last-child {
border-bottom: 1rpx solid #e0e0e0; }
.wxParser-th {
background: #f0f0f0; }
.wxParser-hr {
border: 1rpx solid #DDD;
margin: 20rpx 0; }
.wxParser-pre, .wxParser-code {
margin: 5rpx 0;
padding: 10rpx 10rpx;
border-radius: 8rpx;
background: #f8f8f8;
font-size: 30rpx;
line-height: 40rpx;
overflow-x: auto; }
module.exports = {
/**
* 生成 Map
* @param {String} str 以逗号分隔的字符串
* @return {Object} 映射表
*/
makeMap: (str) => {
let map = {}
let items = str.split(',')
for (let i = 0, len = items.length; i < len; i++) {
map[items[i]] = true
}
return map
},
/**
* 根据 size 属性得到字体大小
* @param {Number|String} size
* @return {String}
*/
getFontSizeByAttribsSize: function (size) {
var fontSize
size = parseInt(size, 10)
switch (size) {
case 2:
fontSize = 0.75
break
case 3:
fontSize = 1
break
case 4:
fontSize = 1.17
break
case 5:
fontSize = 1.5
break
case 6:
fontSize = 2
break
case 7:
fontSize = 3
break
default:
fontSize = 1
}
return fontSize + 'em'
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment