@@ -0,0 +1,28 @@ | |||
<template> | |||
<!-- '<audio/>' 组件不再维护,建议使用能力更强的 'uni.createInnerAudioContext' 接口 有时间再改--> | |||
<!--增加audio标签支持--> | |||
<audio | |||
:id="node.attr.id" | |||
:class="node.classStr" | |||
:style="node.styleStr" | |||
:src="node.attr.src" | |||
:loop="node.attr.loop" | |||
:poster="node.attr.poster" | |||
:name="node.attr.name" | |||
:author="node.attr.author" | |||
controls></audio> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'wxParseAudio', | |||
props: { | |||
node: { | |||
type: Object, | |||
default() { | |||
return {}; | |||
}, | |||
}, | |||
}, | |||
}; | |||
</script> |
@@ -0,0 +1,94 @@ | |||
<template> | |||
<image | |||
:mode="node.attr.mode" | |||
:lazy-load="node.attr.lazyLoad" | |||
:class="node.classStr" | |||
:style="newStyleStr || node.styleStr" | |||
:data-src="node.attr.src" | |||
:src="node.attr.src" | |||
@tap="wxParseImgTap" | |||
@load="wxParseImgLoad" | |||
/> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'wxParseImg', | |||
data() { | |||
return { | |||
newStyleStr: '', | |||
preview: true | |||
}; | |||
}, | |||
inject: ['parseWidth'], | |||
mounted() {}, | |||
props: { | |||
node: { | |||
type: Object, | |||
default() { | |||
return {}; | |||
} | |||
} | |||
}, | |||
methods: { | |||
wxParseImgTap(e) { | |||
if (!this.preview) return; | |||
const { src } = e.currentTarget.dataset; | |||
if (!src) return; | |||
let parent = this.$parent; | |||
while (!parent.preview || typeof parent.preview !== 'function') { | |||
// TODO 遍历获取父节点执行方法 | |||
parent = parent.$parent; | |||
} | |||
parent.preview(src, e); | |||
}, | |||
// 图片视觉宽高计算函数区 | |||
wxParseImgLoad(e) { | |||
const { src } = e.currentTarget.dataset; | |||
if (!src) return; | |||
let { width, height } = e.mp.detail; | |||
const recal = this.wxAutoImageCal(width, height); | |||
const { imageheight, imageWidth } = recal; | |||
const { padding, mode } = this.node.attr;//删除padding | |||
// const { mode } = this.node.attr; | |||
const { styleStr } = this.node; | |||
const imageHeightStyle = mode === 'widthFix' ? '' : `height: ${imageheight}px;`; | |||
this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px; padding: 0 ${+padding}px;`;//删除padding | |||
// this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px;`; | |||
}, | |||
// 计算视觉优先的图片宽高 | |||
wxAutoImageCal(originalWidth, originalHeight) { | |||
// 获取图片的原始长宽 | |||
const windowWidth = this.parseWidth.value; | |||
const results = {}; | |||
if (originalWidth < 60 || originalHeight < 60) { | |||
const { src } = this.node.attr; | |||
let parent = this.$parent; | |||
while (!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.removeImageUrl(src); | |||
this.preview = false; | |||
} | |||
// 判断按照那种方式进行缩放 | |||
if (originalWidth > windowWidth) { | |||
// 在图片width大于手机屏幕width时候 | |||
results.imageWidth = windowWidth; | |||
results.imageheight = windowWidth * (originalHeight / originalWidth); | |||
} else { | |||
// 否则展示原来的数据 | |||
results.imageWidth = originalWidth; | |||
results.imageheight = originalHeight; | |||
} | |||
return results; | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,55 @@ | |||
<template> | |||
<div class='tablebox'> | |||
<rich-text :nodes="nodes" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'wxParseTable', | |||
props: { | |||
node: { | |||
type: Object, | |||
default() { | |||
return {}; | |||
}, | |||
}, | |||
}, | |||
inject: ['parseSelect'], | |||
data() { | |||
return { | |||
nodes:[] | |||
}; | |||
}, | |||
mounted() { | |||
this.nodes=this.loadNode([this.node]); | |||
}, | |||
methods: { | |||
loadNode(node) { | |||
let obj = []; | |||
for (let children of node) { | |||
if (children.node=='element') { | |||
let t = { | |||
name:children.tag, | |||
attrs: { | |||
class: children.classStr, | |||
// style: children.styleStr, | |||
}, | |||
children: children.nodes?this.loadNode(children.nodes):[] | |||
} | |||
obj.push(t) | |||
} else if(children.node=='text'){ | |||
obj.push({ | |||
type: 'text', | |||
text: children.text | |||
}) | |||
} | |||
} | |||
return obj | |||
} | |||
} | |||
}; | |||
</script> | |||
<style> | |||
@import url("../parse.css"); | |||
</style> |
@@ -0,0 +1,98 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node"/> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text'">{{node.text}}</block> | |||
</template> | |||
<script> | |||
// #ifdef APP-PLUS | H5 | |||
import wxParseTemplate from './wxParseTemplate0'; | |||
// #endif | |||
// #ifdef MP | |||
import wxParseTemplate from './wxParseTemplate1'; | |||
// #endif | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
// #ifdef APP-PLUS | H5 | |||
name: 'wxParseTemplate', | |||
// #endif | |||
// #ifdef MP | |||
name: 'wxParseTemplate0', | |||
// #endif | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset;// TODO currentTarget才有dataset | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') {// TODO 遍历获取父节点执行方法 | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text'">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate2'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate1', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate11'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate10', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,86 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate11', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text'">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate3'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate2', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate4'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate3', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate5'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate4', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate6'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate5', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate7'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate6', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate8'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate7', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate9'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate8', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate10'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate9', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,15 @@ | |||
<template> | |||
<!--增加video标签支持,并循环添加--> | |||
<view :class="node.classStr" :style="node.styleStr"> | |||
<video :class="node.classStr" :style="node.styleStr" class="video-video" :src="node.attr.src"></video> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'wxParseVideo', | |||
props: { | |||
node: {}, | |||
}, | |||
}; | |||
</script> |
@@ -0,0 +1,261 @@ | |||
/** | |||
* html2Json 改造来自: https://github.com/Jxck/html2json | |||
* | |||
* | |||
* author: Di (微信小程序开发工程师) | |||
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | |||
* 垂直微信小程序开发交流社区 | |||
* | |||
* github地址: https://github.com/icindy/wxParse | |||
* | |||
* for: 微信小程序富文本解析 | |||
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | |||
*/ | |||
import wxDiscode from './wxDiscode'; | |||
import HTMLParser from './htmlparser'; | |||
function makeMap(str) { | |||
const obj = {}; | |||
const items = str.split(','); | |||
for (let i = 0; i < items.length; i += 1) obj[items[i]] = true; | |||
return obj; | |||
} | |||
// Block Elements - HTML 5 | |||
const block = makeMap('br,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 Elements - HTML 5 | |||
const inline = makeMap('a,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'); | |||
// Elements that you can, intentionally, leave open | |||
// (and which close themselves) | |||
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); | |||
function removeDOCTYPE(html) { | |||
const isDocument = /<body.*>([^]*)<\/body>/.test(html); | |||
return isDocument ? RegExp.$1 : html; | |||
} | |||
function trimHtml(html) { | |||
return html | |||
.replace(/<!--.*?-->/gi, '') | |||
.replace(/\/\*.*?\*\//gi, '') | |||
.replace(/[ ]+</gi, '<') | |||
.replace(/<script[^]*<\/script>/gi, '') | |||
.replace(/<style[^]*<\/style>/gi, ''); | |||
} | |||
function getScreenInfo() { | |||
const screen = {}; | |||
wx.getSystemInfo({ | |||
success: (res) => { | |||
screen.width = res.windowWidth; | |||
screen.height = res.windowHeight; | |||
}, | |||
}); | |||
return screen; | |||
} | |||
function html2json(html, customHandler, imageProp, host) { | |||
// 处理字符串 | |||
html = removeDOCTYPE(html); | |||
html = trimHtml(html); | |||
html = wxDiscode.strDiscode(html); | |||
// 生成node节点 | |||
const bufArray = []; | |||
const results = { | |||
nodes: [], | |||
imageUrls: [], | |||
}; | |||
const screen = getScreenInfo(); | |||
function Node(tag) { | |||
this.node = 'element'; | |||
this.tag = tag; | |||
this.$screen = screen; | |||
} | |||
HTMLParser(html, { | |||
start(tag, attrs, unary) { | |||
// node for this element | |||
const node = new Node(tag); | |||
if (bufArray.length !== 0) { | |||
const parent = bufArray[0]; | |||
if (parent.nodes === undefined) { | |||
parent.nodes = []; | |||
} | |||
} | |||
if (block[tag]) { | |||
node.tagType = 'block'; | |||
} else if (inline[tag]) { | |||
node.tagType = 'inline'; | |||
} else if (closeSelf[tag]) { | |||
node.tagType = 'closeSelf'; | |||
} | |||
node.attr = attrs.reduce((pre, attr) => { | |||
const { name } = attr; | |||
let { value } = attr; | |||
if (name === 'class') { | |||
node.classStr = value; | |||
} | |||
// has multi attibutes | |||
// make it array of attribute | |||
if (name === 'style') { | |||
node.styleStr = value; | |||
} | |||
if (value.match(/ /)) { | |||
value = value.split(' '); | |||
} | |||
// if attr already exists | |||
// merge it | |||
if (pre[name]) { | |||
if (Array.isArray(pre[name])) { | |||
// already array, push to last | |||
pre[name].push(value); | |||
} else { | |||
// single value, make it array | |||
pre[name] = [pre[name], value]; | |||
} | |||
} else { | |||
// not exist, put it | |||
pre[name] = value; | |||
} | |||
return pre; | |||
}, {}); | |||
// 优化样式相关属性 | |||
if (node.classStr) { | |||
node.classStr += ` ${node.tag}`; | |||
} else { | |||
node.classStr = node.tag; | |||
} | |||
if (node.tagType === 'inline') { | |||
node.classStr += ' inline'; | |||
} | |||
// 对img添加额外数据 | |||
if (node.tag === 'img') { | |||
let imgUrl = node.attr.src; | |||
imgUrl = wxDiscode.urlToHttpUrl(imgUrl, imageProp.domain); | |||
Object.assign(node.attr, imageProp, { | |||
src: imgUrl || '', | |||
}); | |||
if (imgUrl) { | |||
results.imageUrls.push(imgUrl); | |||
} | |||
} | |||
// 处理a标签属性 | |||
if (node.tag === 'a') { | |||
node.attr.href = node.attr.href || ''; | |||
} | |||
// 处理font标签样式属性 | |||
if (node.tag === 'font') { | |||
const fontSize = [ | |||
'x-small', | |||
'small', | |||
'medium', | |||
'large', | |||
'x-large', | |||
'xx-large', | |||
'-webkit-xxx-large', | |||
]; | |||
const styleAttrs = { | |||
color: 'color', | |||
face: 'font-family', | |||
size: 'font-size', | |||
}; | |||
if (!node.styleStr) node.styleStr = ''; | |||
Object.keys(styleAttrs).forEach((key) => { | |||
if (node.attr[key]) { | |||
const value = key === 'size' ? fontSize[node.attr[key] - 1] : node.attr[key]; | |||
node.styleStr += `${styleAttrs[key]}: ${value};`; | |||
} | |||
}); | |||
} | |||
// 临时记录source资源 | |||
if (node.tag === 'source') { | |||
results.source = node.attr.src; | |||
} | |||
if (customHandler.start) { | |||
customHandler.start(node, results); | |||
} | |||
if (unary) { | |||
// if this tag doesn't have end tag | |||
// like <img src="hoge.png"/> | |||
// add to parents | |||
const parent = bufArray[0] || results; | |||
if (parent.nodes === undefined) { | |||
parent.nodes = []; | |||
} | |||
parent.nodes.push(node); | |||
} else { | |||
bufArray.unshift(node); | |||
} | |||
}, | |||
end(tag) { | |||
// merge into parent tag | |||
const node = bufArray.shift(); | |||
if (node.tag !== tag) { | |||
console.error('invalid state: mismatch end tag'); | |||
} | |||
// 当有缓存source资源时于于video补上src资源 | |||
if (node.tag === 'video' && results.source) { | |||
node.attr.src = results.source; | |||
delete results.source; | |||
} | |||
if (customHandler.end) { | |||
customHandler.end(node, results); | |||
} | |||
if (bufArray.length === 0) { | |||
results.nodes.push(node); | |||
} else { | |||
const parent = bufArray[0]; | |||
if (!parent.nodes) { | |||
parent.nodes = []; | |||
} | |||
parent.nodes.push(node); | |||
} | |||
}, | |||
chars(text) { | |||
if (!text.trim()) return; | |||
const node = { | |||
node: 'text', | |||
text, | |||
}; | |||
if (customHandler.chars) { | |||
customHandler.chars(node, results); | |||
} | |||
if (bufArray.length === 0) { | |||
results.nodes.push(node); | |||
} else { | |||
const parent = bufArray[0]; | |||
if (parent.nodes === undefined) { | |||
parent.nodes = []; | |||
} | |||
parent.nodes.push(node); | |||
} | |||
}, | |||
}); | |||
return results; | |||
} | |||
export default html2json; |
@@ -0,0 +1,156 @@ | |||
/** | |||
* | |||
* htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser | |||
* | |||
* author: Di (微信小程序开发工程师) | |||
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | |||
* 垂直微信小程序开发交流社区 | |||
* | |||
* github地址: https://github.com/icindy/wxParse | |||
* | |||
* for: 微信小程序富文本解析 | |||
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | |||
*/ | |||
// Regular Expressions for parsing tags and attributes | |||
const startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z0-9_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/; | |||
const endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/; | |||
const attr = /([a-zA-Z0-9_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; | |||
function makeMap(str) { | |||
const obj = {}; | |||
const items = str.split(','); | |||
for (let i = 0; i < items.length; i += 1) obj[items[i]] = true; | |||
return obj; | |||
} | |||
// Empty Elements - HTML 5 | |||
const empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); | |||
// Block Elements - HTML 5 | |||
const block = makeMap('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'); | |||
// Inline Elements - HTML 5 | |||
const inline = makeMap('a,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'); | |||
// Elements that you can, intentionally, leave open | |||
// (and which close themselves) | |||
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); | |||
// Attributes that have their values filled in disabled="disabled" | |||
const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); | |||
function HTMLParser(html, handler) { | |||
let index; | |||
let chars; | |||
let match; | |||
let last = html; | |||
const stack = []; | |||
stack.last = () => stack[stack.length - 1]; | |||
function parseEndTag(tag, tagName) { | |||
// If no tag name is provided, clean shop | |||
let pos; | |||
if (!tagName) { | |||
pos = 0; | |||
} else { | |||
// Find the closest opened tag of the same type | |||
tagName = tagName.toLowerCase(); | |||
for (pos = stack.length - 1; pos >= 0; pos -= 1) { | |||
if (stack[pos] === tagName) break; | |||
} | |||
} | |||
if (pos >= 0) { | |||
// Close all the open elements, up the stack | |||
for (let i = stack.length - 1; i >= pos; i -= 1) { | |||
if (handler.end) handler.end(stack[i]); | |||
} | |||
// Remove the open elements from the stack | |||
stack.length = pos; | |||
} | |||
} | |||
function parseStartTag(tag, tagName, rest, unary) { | |||
tagName = tagName.toLowerCase(); | |||
if (block[tagName]) { | |||
while (stack.last() && inline[stack.last()]) { | |||
parseEndTag('', stack.last()); | |||
} | |||
} | |||
if (closeSelf[tagName] && stack.last() === tagName) { | |||
parseEndTag('', tagName); | |||
} | |||
unary = empty[tagName] || !!unary; | |||
if (!unary) stack.push(tagName); | |||
if (handler.start) { | |||
const attrs = []; | |||
rest.replace(attr, function genAttr(matches, name) { | |||
const value = arguments[2] || arguments[3] || arguments[4] || (fillAttrs[name] ? name : ''); | |||
attrs.push({ | |||
name, | |||
value, | |||
escaped: value.replace(/(^|[^\\])"/g, '$1\\"'), // " | |||
}); | |||
}); | |||
if (handler.start) { | |||
handler.start(tagName, attrs, unary); | |||
} | |||
} | |||
} | |||
while (html) { | |||
chars = true; | |||
if (html.indexOf('</') === 0) { | |||
match = html.match(endTag); | |||
if (match) { | |||
html = html.substring(match[0].length); | |||
match[0].replace(endTag, parseEndTag); | |||
chars = false; | |||
} | |||
// start tag | |||
} else if (html.indexOf('<') === 0) { | |||
match = html.match(startTag); | |||
if (match) { | |||
html = html.substring(match[0].length); | |||
match[0].replace(startTag, parseStartTag); | |||
chars = false; | |||
} | |||
} | |||
if (chars) { | |||
index = html.indexOf('<'); | |||
let text = ''; | |||
while (index === 0) { | |||
text += '<'; | |||
html = html.substring(1); | |||
index = html.indexOf('<'); | |||
} | |||
text += index < 0 ? html : html.substring(0, index); | |||
html = index < 0 ? '' : html.substring(index); | |||
if (handler.chars) handler.chars(text); | |||
} | |||
if (html === last) throw new Error(`Parse Error: ${html}`); | |||
last = html; | |||
} | |||
// Clean up any remaining tags | |||
parseEndTag(); | |||
} | |||
export default HTMLParser; |
@@ -0,0 +1,209 @@ | |||
// HTML 支持的数学符号 | |||
function strNumDiscode(str) { | |||
str = str.replace(/∀|∀|∀/g, '∀'); | |||
str = str.replace(/∂|∂|∂/g, '∂'); | |||
str = str.replace(/∃|∃|∃/g, '∃'); | |||
str = str.replace(/∅|∅|∅/g, '∅'); | |||
str = str.replace(/∇|∇|∇/g, '∇'); | |||
str = str.replace(/∈|∈|∈/g, '∈'); | |||
str = str.replace(/∉|∉|∉/g, '∉'); | |||
str = str.replace(/∋|∋|∋/g, '∋'); | |||
str = str.replace(/∏|∏|∏/g, '∏'); | |||
str = str.replace(/∑|∑|∑/g, '∑'); | |||
str = str.replace(/−|−|−/g, '−'); | |||
str = str.replace(/∗|∗|∗/g, '∗'); | |||
str = str.replace(/√|√|√/g, '√'); | |||
str = str.replace(/∝|∝|∝/g, '∝'); | |||
str = str.replace(/∞|∞|∞/g, '∞'); | |||
str = str.replace(/∠|∠|∠/g, '∠'); | |||
str = str.replace(/∧|∧|∧/g, '∧'); | |||
str = str.replace(/∨|∨|∨/g, '∨'); | |||
str = str.replace(/∩|∩|∩/g, '∩'); | |||
str = str.replace(/∪|∪|∪/g, '∪'); | |||
str = str.replace(/∫|∫|∫/g, '∫'); | |||
str = str.replace(/∴|∴|∴/g, '∴'); | |||
str = str.replace(/∼|∼|∼/g, '∼'); | |||
str = str.replace(/≅|≅|≅/g, '≅'); | |||
str = str.replace(/≈|≈|≈/g, '≈'); | |||
str = str.replace(/≠|≠|≠/g, '≠'); | |||
str = str.replace(/≤|≤|≤/g, '≤'); | |||
str = str.replace(/≥|≥|≥/g, '≥'); | |||
str = str.replace(/⊂|⊂|⊂/g, '⊂'); | |||
str = str.replace(/⊃|⊃|⊃/g, '⊃'); | |||
str = str.replace(/⊄|⊄|⊄/g, '⊄'); | |||
str = str.replace(/⊆|⊆|⊆/g, '⊆'); | |||
str = str.replace(/⊇|⊇|⊇/g, '⊇'); | |||
str = str.replace(/⊕|⊕|⊕/g, '⊕'); | |||
str = str.replace(/⊗|⊗|⊗/g, '⊗'); | |||
str = str.replace(/⊥|⊥|⊥/g, '⊥'); | |||
str = str.replace(/⋅|⋅|⋅/g, '⋅'); | |||
return str; | |||
} | |||
// HTML 支持的希腊字母 | |||
function strGreeceDiscode(str) { | |||
str = str.replace(/Α|Α|Α/g, 'Α'); | |||
str = str.replace(/Β|Β|Β/g, 'Β'); | |||
str = str.replace(/Γ|Γ|Γ/g, 'Γ'); | |||
str = str.replace(/Δ|Δ|Δ/g, 'Δ'); | |||
str = str.replace(/Ε|Ε|Ε/g, 'Ε'); | |||
str = str.replace(/Ζ|Ζ|Ζ/g, 'Ζ'); | |||
str = str.replace(/Η|Η|Η/g, 'Η'); | |||
str = str.replace(/Θ|Θ|Θ/g, 'Θ'); | |||
str = str.replace(/Ι|Ι|Ι/g, 'Ι'); | |||
str = str.replace(/Κ|Κ|Κ/g, 'Κ'); | |||
str = str.replace(/Λ|Λ|Λ/g, 'Λ'); | |||
str = str.replace(/Μ|Μ|Μ/g, 'Μ'); | |||
str = str.replace(/Ν|Ν|Ν/g, 'Ν'); | |||
str = str.replace(/Ξ|Ν|Ν/g, 'Ν'); | |||
str = str.replace(/Ο|Ο|Ο/g, 'Ο'); | |||
str = str.replace(/Π|Π|Π/g, 'Π'); | |||
str = str.replace(/Ρ|Ρ|Ρ/g, 'Ρ'); | |||
str = str.replace(/Σ|Σ|Σ/g, 'Σ'); | |||
str = str.replace(/Τ|Τ|Τ/g, 'Τ'); | |||
str = str.replace(/Υ|Υ|Υ/g, 'Υ'); | |||
str = str.replace(/Φ|Φ|Φ/g, 'Φ'); | |||
str = str.replace(/Χ|Χ|Χ/g, 'Χ'); | |||
str = str.replace(/Ψ|Ψ|Ψ/g, 'Ψ'); | |||
str = str.replace(/Ω|Ω|Ω/g, 'Ω'); | |||
str = str.replace(/α|α|α/g, 'α'); | |||
str = str.replace(/β|β|β/g, 'β'); | |||
str = str.replace(/γ|γ|γ/g, 'γ'); | |||
str = str.replace(/δ|δ|δ/g, 'δ'); | |||
str = str.replace(/ε|ε|ε/g, 'ε'); | |||
str = str.replace(/ζ|ζ|ζ/g, 'ζ'); | |||
str = str.replace(/η|η|η/g, 'η'); | |||
str = str.replace(/θ|θ|θ/g, 'θ'); | |||
str = str.replace(/ι|ι|ι/g, 'ι'); | |||
str = str.replace(/κ|κ|κ/g, 'κ'); | |||
str = str.replace(/λ|λ|λ/g, 'λ'); | |||
str = str.replace(/μ|μ|μ/g, 'μ'); | |||
str = str.replace(/ν|ν|ν/g, 'ν'); | |||
str = str.replace(/ξ|ξ|ξ/g, 'ξ'); | |||
str = str.replace(/ο|ο|ο/g, 'ο'); | |||
str = str.replace(/π|π|π/g, 'π'); | |||
str = str.replace(/ρ|ρ|ρ/g, 'ρ'); | |||
str = str.replace(/ς|ς|ς/g, 'ς'); | |||
str = str.replace(/σ|σ|σ/g, 'σ'); | |||
str = str.replace(/τ|τ|τ/g, 'τ'); | |||
str = str.replace(/υ|υ|υ/g, 'υ'); | |||
str = str.replace(/φ|φ|φ/g, 'φ'); | |||
str = str.replace(/χ|χ|χ/g, 'χ'); | |||
str = str.replace(/ψ|ψ|ψ/g, 'ψ'); | |||
str = str.replace(/ω|ω|ω/g, 'ω'); | |||
str = str.replace(/ϑ|ϑ|ϑ/g, 'ϑ'); | |||
str = str.replace(/ϒ|ϒ|ϒ/g, 'ϒ'); | |||
str = str.replace(/ϖ|ϖ|ϖ/g, 'ϖ'); | |||
str = str.replace(/·|·|·/g, '·'); | |||
return str; | |||
} | |||
function strcharacterDiscode(str) { | |||
// 加入常用解析 | |||
// str = str.replace(/ | | /g, " "); | |||
// str = str.replace(/ | | /g, ' '); | |||
// str = str.replace(/ | /g, '<span class=\'spaceshow\'> </span>'); | |||
// str = str.replace(/ | | /g, ' '); | |||
// str = str.replace(/"|"|"/g, "\""); | |||
// str = str.replace(/'|'|'/g, "'"); | |||
// str = str.replace(/´|´|´/g, "´"); | |||
// str = str.replace(/×|×|×/g, "×"); | |||
// str = str.replace(/÷|÷|÷/g, "÷"); | |||
// str = str.replace(/&|&|&/g, '&'); | |||
// str = str.replace(/<|<|</g, '<'); | |||
// str = str.replace(/>|>|>/g, '>'); | |||
str = str.replace(/ | | /g, "<span class='spaceshow'> </span>"); | |||
str = str.replace(/ | | /g, '<span class=\'spaceshow\'> </span>'); | |||
str = str.replace(/ | /g, '<span class=\'spaceshow\'> </span>'); | |||
str = str.replace(/ | | /g, '<span class=\'spaceshow\'> </span>'); | |||
str = str.replace(/"|"|"/g, "\""); | |||
str = str.replace(/"|'|'/g, "'"); | |||
str = str.replace(/´|´|´/g, "´"); | |||
str = str.replace(/×|×|×/g, "×"); | |||
str = str.replace(/÷|÷|÷/g, "÷"); | |||
str = str.replace(/&|&|&/g, '&'); | |||
str = str.replace(/<|<|</g, '<'); | |||
str = str.replace(/>|>|>/g, '>'); | |||
return str; | |||
} | |||
// HTML 支持的其他实体 | |||
function strOtherDiscode(str) { | |||
str = str.replace(/Œ|Œ|Œ/g, 'Œ'); | |||
str = str.replace(/œ|œ|œ/g, 'œ'); | |||
str = str.replace(/Š|Š|Š/g, 'Š'); | |||
str = str.replace(/š|š|š/g, 'š'); | |||
str = str.replace(/Ÿ|Ÿ|Ÿ/g, 'Ÿ'); | |||
str = str.replace(/ƒ|ƒ|ƒ/g, 'ƒ'); | |||
str = str.replace(/ˆ|ˆ|ˆ/g, 'ˆ'); | |||
str = str.replace(/˜|˜|˜/g, '˜'); | |||
str = str.replace(/ |$#8201;| /g, '<span class=\'spaceshow\'> </span>'); | |||
str = str.replace(/‌|‌|‌/g, '<span class=\'spaceshow\'></span>'); | |||
str = str.replace(/‍|$#8205;|‍/g, '<span class=\'spaceshow\'></span>'); | |||
str = str.replace(/‎|$#8206;|‎/g, '<span class=\'spaceshow\'></span>'); | |||
str = str.replace(/‏|‏|‏/g, '<span class=\'spaceshow\'></span>'); | |||
str = str.replace(/–|–|–/g, '–'); | |||
str = str.replace(/—|—|—/g, '—'); | |||
str = str.replace(/‘|‘|‘/g, '‘'); | |||
str = str.replace(/’|’|’/g, '’'); | |||
str = str.replace(/‚|‚|‚/g, '‚'); | |||
str = str.replace(/“|“|“/g, '“'); | |||
str = str.replace(/”|”|”/g, '”'); | |||
str = str.replace(/„|„|„/g, '„'); | |||
str = str.replace(/†|†|†/g, '†'); | |||
str = str.replace(/‡|‡|‡/g, '‡'); | |||
str = str.replace(/•|•|•/g, '•'); | |||
str = str.replace(/…|…|…/g, '…'); | |||
str = str.replace(/‰|‰|‰/g, '‰'); | |||
str = str.replace(/′|′|′/g, '′'); | |||
str = str.replace(/″|″|″/g, '″'); | |||
str = str.replace(/‹|‹|‹/g, '‹'); | |||
str = str.replace(/›|›|›/g, '›'); | |||
str = str.replace(/‾|‾|‾/g, '‾'); | |||
str = str.replace(/€|€|€/g, '€'); | |||
str = str.replace(/™|™|™/g, '™'); | |||
str = str.replace(/←|←|←/g, '←'); | |||
str = str.replace(/↑|↑|↑/g, '↑'); | |||
str = str.replace(/→|→|→/g, '→'); | |||
str = str.replace(/↓|↓|↓/g, '↓'); | |||
str = str.replace(/↔|↔|↔/g, '↔'); | |||
str = str.replace(/↵|↵|↵/g, '↵'); | |||
str = str.replace(/⌈|⌈|⌈/g, '⌈'); | |||
str = str.replace(/⌉|⌉|⌉/g, '⌉'); | |||
str = str.replace(/⌊|⌊|⌊/g, '⌊'); | |||
str = str.replace(/⌋|⌋|⌋/g, '⌋'); | |||
str = str.replace(/◊|◊|◊/g, '◊'); | |||
str = str.replace(/♠|♠|♠/g, '♠'); | |||
str = str.replace(/♣|♣|♣/g, '♣'); | |||
str = str.replace(/♥|♥|♥/g, '♥'); | |||
str = str.replace(/♦|♦|♦/g, '♦'); | |||
return str; | |||
} | |||
function strDiscode(str) { | |||
str = strNumDiscode(str); | |||
str = strGreeceDiscode(str); | |||
str = strcharacterDiscode(str); | |||
str = strOtherDiscode(str); | |||
return str; | |||
} | |||
function urlToHttpUrl(url, domain) { | |||
if (/^\/\//.test(url)) { | |||
return `https:${url}`; | |||
} else if (/^\//.test(url)) { | |||
return `https://${domain}${url}`; | |||
} | |||
return url; | |||
} | |||
export default { | |||
strDiscode, | |||
urlToHttpUrl, | |||
}; |
@@ -0,0 +1,258 @@ | |||
/** | |||
* author: Di (微信小程序开发工程师) | |||
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | |||
* 垂直微信小程序开发交流社区 | |||
* | |||
* github地址: https://github.com/icindy/wxParse | |||
* | |||
* for: 微信小程序富文本解析 | |||
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | |||
*/ | |||
/** | |||
* 请在全局下引入该文件,@import '/static/wxParse.css'; | |||
*/ | |||
.wxParse { | |||
user-select:none; | |||
width: 100%; | |||
font-family: Helvetica, "PingFangSC", 'Microsoft Yahei', '微软雅黑', Arial, sans-serif; | |||
color: #333; | |||
line-height: 1.5; | |||
font-size: 1em; | |||
text-align:justify;/* //左右两端对齐 */ | |||
} | |||
.wxParse view ,.wxParse uni-view{ | |||
word-break: break-word; | |||
} | |||
.wxParse .p { | |||
padding-bottom: 0.5em; | |||
clear: both; | |||
/* letter-spacing: 0;//字间距 */ | |||
} | |||
.wxParse .inline { | |||
display: inline; | |||
margin: 0; | |||
padding: 0; | |||
} | |||
.wxParse .div { | |||
margin: 0; | |||
padding: 0; | |||
display: block; | |||
} | |||
.wxParse .h1{ | |||
font-size: 2em; | |||
line-height: 1.2em; | |||
margin: 0.67em 0; | |||
} | |||
.wxParse .h2{ | |||
font-size: 1.5em; | |||
margin: 0.83em 0; | |||
} | |||
.wxParse .h3{ | |||
font-size: 1.17em; | |||
margin: 1em 0; | |||
} | |||
.wxParse .h4{ | |||
margin: 1.33em 0; | |||
} | |||
.wxParse .h5{ | |||
font-size: 0.83em; | |||
margin: 1.67em 0; | |||
} | |||
.wxParse .h6{ | |||
font-size: 0.83em; | |||
margin: 1.67em 0; | |||
} | |||
.wxParse .h1, | |||
.wxParse .h2, | |||
.wxParse .h3, | |||
.wxParse .h4, | |||
.wxParse .h5, | |||
.wxParse .h6, | |||
.wxParse .b, | |||
.wxParse .strong{ | |||
font-weight: bolder; | |||
} | |||
.wxParse .i, | |||
.wxParse .cite, | |||
.wxParse .em, | |||
.wxParse .var, | |||
.wxParse .address { | |||
font-style: italic; | |||
} | |||
.wxParse .spaceshow{ | |||
white-space: pre; | |||
} | |||
.wxParse .pre, | |||
.wxParse .tt, | |||
.wxParse .code, | |||
.wxParse .kbd, | |||
.wxParse .samp { | |||
font-family: monospace; | |||
} | |||
.wxParse .pre { | |||
overflow: auto; | |||
background: #f5f5f5; | |||
padding: 16upx; | |||
white-space: pre; | |||
margin: 1em 0upx; | |||
font-size: 24upx; | |||
} | |||
.wxParse .code { | |||
overflow: auto; | |||
padding: 16upx; | |||
white-space: pre; | |||
margin: 1em 0upx; | |||
background: #f5f5f5; | |||
font-size: 24upx; | |||
} | |||
.wxParse .big { | |||
font-size: 1.17em; | |||
} | |||
.wxParse .small, | |||
.wxParse .sub, | |||
.wxParse .sup { | |||
font-size: 0.83em; | |||
} | |||
.wxParse .sub { | |||
vertical-align: sub; | |||
} | |||
.wxParse .sup { | |||
vertical-align: super; | |||
} | |||
.wxParse .s, | |||
.wxParse .strike, | |||
.wxParse .del { | |||
text-decoration: line-through; | |||
} | |||
.wxParse .strong, | |||
.wxParse .text, | |||
.wxParse .span, | |||
.wxParse .s { | |||
display: inline; | |||
} | |||
.wxParse .a { | |||
color: deepskyblue; | |||
} | |||
.wxParse .video { | |||
text-align: center; | |||
margin: 22upx 0; | |||
} | |||
.wxParse .video-video { | |||
width: 100%; | |||
} | |||
.wxParse .uni-image{ | |||
max-width: 100%; | |||
} | |||
.wxParse .img { | |||
display: block; | |||
max-width: 100%; | |||
margin-bottom: 0em;/* //与p标签底部padding同时修改 */ | |||
overflow: hidden; | |||
} | |||
.wxParse .blockquote { | |||
margin: 10upx 0; | |||
padding: 22upx 0 22upx 22upx; | |||
font-family: Courier, Calibri, "宋体"; | |||
background: #f5f5f5; | |||
border-left: 6upx solid #dbdbdb; | |||
} | |||
.wxParse .blockquote .p { | |||
margin: 0; | |||
} | |||
.wxParse .ul, .wxParse .ol { | |||
display: block; | |||
margin: 1em 0; | |||
padding-left: 2em; | |||
} | |||
.wxParse .ol { | |||
list-style-type: disc; | |||
} | |||
.wxParse .ol { | |||
list-style-type: decimal; | |||
} | |||
.wxParse .ol>weixin-parse-template,.wxParse .ul>weixin-parse-template { | |||
display: list-item; | |||
align-items: baseline; | |||
text-align: match-parent; | |||
} | |||
.wxParse .ol>.li,.wxParse .ul>.li { | |||
display: list-item; | |||
align-items: baseline; | |||
text-align: match-parent; | |||
} | |||
.wxParse .ul .ul, .wxParse .ol .ul { | |||
list-style-type: circle; | |||
} | |||
.wxParse .ol .ol .ul, .wxParse .ol .ul .ul, .wxParse .ul .ol .ul, .wxParse .ul .ul .ul { | |||
list-style-type: square; | |||
} | |||
.wxParse .u { | |||
text-decoration: underline; | |||
} | |||
.wxParse .hide { | |||
display: none; | |||
} | |||
.wxParse .del { | |||
display: inline; | |||
} | |||
.wxParse .figure { | |||
overflow: hidden; | |||
} | |||
.wxParse .tablebox{ | |||
overflow: auto; | |||
background-color: #f5f5f5; | |||
background: #f5f5f5; | |||
font-size: 13px; | |||
padding: 8px; | |||
} | |||
.wxParse .table .table,.wxParse .table{ | |||
border-collapse:collapse; | |||
box-sizing: border-box; | |||
/* 内边框 */ | |||
/* width: 100%; */ | |||
overflow: auto; | |||
white-space: pre; | |||
} | |||
.wxParse .tbody{ | |||
border-collapse:collapse; | |||
box-sizing: border-box; | |||
/* 内边框 */ | |||
border: 1px solid #dadada; | |||
} | |||
.wxParse .table .thead, .wxParse .table .tfoot, .wxParse .table .th{ | |||
border-collapse:collapse; | |||
box-sizing: border-box; | |||
background: #ececec; | |||
font-weight: 40; | |||
} | |||
.wxParse .table .tr { | |||
border-collapse:collapse; | |||
box-sizing: border-box; | |||
/* border: 2px solid #F0AD4E; */ | |||
overflow:auto; | |||
} | |||
.wxParse .table .th, | |||
.wxParse .table .td{ | |||
border-collapse:collapse; | |||
box-sizing: border-box; | |||
border: 2upx solid #dadada; | |||
overflow:auto; | |||
} | |||
.wxParse .audio, .wxParse .uni-audio-default{ | |||
display: block; | |||
} |
@@ -0,0 +1,228 @@ | |||
<!--** | |||
* forked from:https://github.com/F-loat/mpvue-wxParse | |||
* | |||
* github地址: https://github.com/dcloudio/uParse | |||
* | |||
* for: uni-app框架下 富文本解析 | |||
* | |||
* 优化 by gaoyia@qq.com https://github.com/gaoyia/parse | |||
*/--> | |||
<template> | |||
<!--基础元素--> | |||
<div class="wxParse" :class="className" :style="'user-select:' + userSelect"> | |||
<block v-for="(node, index) of nodes" :key="index" v-if="!loading"> | |||
<wxParseTemplate :node="node" /> | |||
</block> | |||
</div> | |||
</template> | |||
<script> | |||
import HtmlToJson from './libs/html2json'; | |||
import wxParseTemplate from './components/wxParseTemplate0'; | |||
export default { | |||
name: 'wxParse', | |||
props: { | |||
// user-select:none; | |||
userSelect: { | |||
type: String, | |||
default: 'text' //none |text| all | element | |||
}, | |||
imgOptions: { | |||
type: [Object, Boolean], | |||
default: function() { | |||
return { | |||
loop: false, | |||
indicator: 'number', | |||
longPressActions: false | |||
// longPressActions: { | |||
// itemList: ['发送给朋友', '保存图片', '收藏'], | |||
// success: function (res) { | |||
// console.log('选中了第' + (res.tapIndex + 1) + '个按钮'); | |||
// }, | |||
// fail: function (res) { | |||
// console.log(res.errMsg); | |||
// } | |||
// } | |||
// } | |||
} | |||
} | |||
}, | |||
loading: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
className: { | |||
type: String, | |||
default: '' | |||
}, | |||
content: { | |||
type: String, | |||
default: '' | |||
}, | |||
noData: { | |||
type: String, | |||
default: '<div style="color: red;">数据不能为空</div>' | |||
}, | |||
startHandler: { | |||
type: Function, | |||
default () { | |||
return node => { | |||
node.attr.class = null; | |||
node.attr.style = null; | |||
}; | |||
} | |||
}, | |||
endHandler: { | |||
type: Function, | |||
default: null | |||
}, | |||
charsHandler: { | |||
type: Function, | |||
default: null | |||
}, | |||
imageProp: { | |||
type: Object, | |||
default () { | |||
return { | |||
mode: 'aspectFit', | |||
padding: 0, | |||
lazyLoad: false, | |||
domain: '' | |||
}; | |||
} | |||
} | |||
}, | |||
components: { | |||
wxParseTemplate | |||
}, | |||
data() { | |||
return { | |||
nodes: {}, | |||
imageUrls: [], | |||
wxParseWidth: { | |||
value: 0 | |||
} | |||
}; | |||
}, | |||
computed: {}, | |||
mounted() { | |||
this.setHtml() | |||
}, | |||
methods: { | |||
setHtml() { | |||
this.getWidth().then((data) => { | |||
this.wxParseWidth.value = data; | |||
}) | |||
let { | |||
content, | |||
noData, | |||
imageProp, | |||
startHandler, | |||
endHandler, | |||
charsHandler | |||
} = this; | |||
let parseData = content || noData; | |||
let customHandler = { | |||
start: startHandler, | |||
end: endHandler, | |||
chars: charsHandler | |||
}; | |||
let results = HtmlToJson(parseData, customHandler, imageProp, this); | |||
this.imageUrls = results.imageUrls; | |||
// this.nodes = results.nodes; | |||
this.nodes = []; | |||
results.nodes.forEach((item) => { | |||
setTimeout(() => { | |||
this.nodes.push(item) | |||
}, 0); | |||
}) | |||
}, | |||
getWidth() { | |||
return new Promise((res, rej) => { | |||
// #ifndef MP-ALIPAY || MP-BAIDU | |||
uni.createSelectorQuery() | |||
.in(this) | |||
.select('.wxParse') | |||
.fields({ | |||
size: true, | |||
scrollOffset: true | |||
}, | |||
data => { | |||
res(data.width); | |||
} | |||
).exec(); | |||
// #endif | |||
// #ifdef MP-BAIDU | |||
const query = swan.createSelectorQuery(); | |||
query.select('.wxParse').boundingClientRect(); | |||
query.exec(obj => { | |||
const rect = obj[0] | |||
if (rect) { | |||
res(rect.width); | |||
} | |||
}); | |||
// #endif | |||
// #ifdef MP-ALIPAY | |||
my.createSelectorQuery() | |||
.select('.wxParse') | |||
.boundingClientRect().exec((ret) => { | |||
res(ret[0].width); | |||
}); | |||
// #endif | |||
}); | |||
}, | |||
navigate(href, $event, attr) { | |||
console.log(href, attr); | |||
this.$emit('navigate', href, $event); | |||
}, | |||
preview(src, $event) { | |||
if (!this.imageUrls.length || typeof this.imgOptions === 'boolean') { | |||
} else { | |||
uni.previewImage({ | |||
current: src, | |||
urls: this.imageUrls, | |||
loop: this.imgOptions.loop, | |||
indicator: this.imgOptions.indicator, | |||
longPressActions: this.imgOptions.longPressActions | |||
}); | |||
} | |||
this.$emit('preview', src, $event); | |||
}, | |||
removeImageUrl(src) { | |||
const { | |||
imageUrls | |||
} = this; | |||
imageUrls.splice(imageUrls.indexOf(src), 1); | |||
} | |||
}, | |||
// 父组件中提供 | |||
provide() { | |||
return { | |||
parseWidth: this.wxParseWidth, | |||
parseSelect: this.userSelect | |||
// 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。 | |||
}; | |||
}, | |||
watch: { | |||
content(){ | |||
this.setHtml() | |||
} | |||
// content: { | |||
// handler: function(newVal, oldVal) { | |||
// if (newVal !== oldVal) { | |||
// | |||
// } | |||
// }, | |||
// deep: true | |||
// } | |||
} | |||
}; | |||
</script> |
@@ -66,7 +66,11 @@ var config = { | |||
//取消加精 | |||
delATD:`${host}/addtodigest/delATD`, | |||
// 获取客户来源列表 | |||
sourceList: `${host}/customer/sourceList`, | |||
sourceList: `${host}/customer/sourceList`, | |||
// 升级公告 | |||
updateList: `${host}/zkMessage/messageList`, | |||
// 升级公告更新阅读 | |||
updateRead: `${host}/zkMessage/updateFlag`, | |||
} | |||
}; | |||
module.exports = config; |
@@ -280,6 +280,16 @@ | |||
"navigationBarTextStyle": "white" | |||
} | |||
} | |||
,{ | |||
"path" : "messageDetail", | |||
"style" : | |||
{ | |||
"navigationBarTitleText": "消息", | |||
"navigationBarBackgroundColor": "#2671E2", | |||
"navigationBarTextStyle": "white" | |||
} | |||
} | |||
] | |||
}, | |||
@@ -14,15 +14,15 @@ | |||
</view> | |||
</view> | |||
<view class="settingGroup box"> | |||
<!-- <navigator class="line" url="/pages/mine/messageList"> | |||
<view class="title"> | |||
<navigator class="line" url="/pages/mine/messageList"> | |||
<view class="title" style="width: 21%;"> | |||
<image src="/static/images/studyhot.png" style="width: 36rpx;height: 36rpx;" mode=""></image> | |||
消息 | |||
</view> | |||
<view class="right"> | |||
<image src="/static/images/arrow.png" style="width: 18rpx;height: 32rpx;" mode=""></image> | |||
</view> | |||
</navigator> --> | |||
</navigator> | |||
<navigator class="line" url="/pages/mine/subscribe"> | |||
<view class="title"> | |||
<image src="/static/images/studyhot.png" style="width: 36rpx;height: 36rpx;" mode=""></image> | |||
@@ -0,0 +1,444 @@ | |||
<template> | |||
<view class="main"> | |||
<!-- <u-parse :content="content" /> --> | |||
<!-- <view v-html="content"></view> --> | |||
<rich-text :nodes="content"></rich-text> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
import uParse from '../../components/gaoyia-parse/parse.vue' | |||
export default { | |||
data() { | |||
return { | |||
content:"", | |||
id:"" | |||
}; | |||
}, | |||
components: { | |||
uParse | |||
}, | |||
onLoad(e){ | |||
this.id = e.id; | |||
let link=JSON.parse(decodeURIComponent(e.content)) | |||
this.content = link | |||
this.read() | |||
}, | |||
methods:{ | |||
read(){ | |||
uni.request({ | |||
url: config.service.updateRead, | |||
method: "GET", | |||
data:{id:this.id,accountId:uni.getStorageSync('weapp_session_userInfo_data').accountId}, | |||
header: { | |||
'content-type': 'application/json', | |||
'Authorization': 'Bearer '+uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (res) => { | |||
console.log(res) | |||
} | |||
}) | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss"> | |||
.main{ | |||
padding: 20rpx; | |||
} | |||
.ql-container { | |||
box-sizing: border-box; | |||
font-family: Helvetica, Arial, sans-serif; | |||
font-size: 13px; | |||
height: 100%; | |||
margin: 0px; | |||
position: relative; | |||
} | |||
.ql-container.ql-disabled .ql-tooltip { | |||
visibility: hidden; | |||
} | |||
.ql-container.ql-disabled .ql-editor ul[data-checked] > li::before { | |||
pointer-events: none; | |||
} | |||
.ql-clipboard { | |||
left: -100000px; | |||
height: 1px; | |||
overflow-y: hidden; | |||
position: absolute; | |||
top: 50%; | |||
} | |||
.ql-clipboard p { | |||
margin: 0; | |||
padding: 0; | |||
} | |||
.ql-editor { | |||
box-sizing: border-box; | |||
line-height: 1.42; | |||
height: 100%; | |||
outline: none; | |||
overflow-y: auto; | |||
padding: 12px 15px; | |||
tab-size: 4; | |||
-moz-tab-size: 4; | |||
text-align: left; | |||
white-space: pre-wrap; | |||
word-wrap: break-word; | |||
} | |||
.ql-editor > * { | |||
cursor: text; | |||
} | |||
.ql-editor p, | |||
.ql-editor ol, | |||
.ql-editor ul, | |||
.ql-editor pre, | |||
.ql-editor blockquote, | |||
.ql-editor h1, | |||
.ql-editor h2, | |||
.ql-editor h3, | |||
.ql-editor h4, | |||
.ql-editor h5, | |||
.ql-editor h6 { | |||
margin: 0; | |||
padding: 0; | |||
counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |||
} | |||
.ql-editor ol, | |||
.ql-editor ul { | |||
padding-left: 1.5em; | |||
} | |||
.ql-editor ol > li, | |||
.ql-editor ul > li { | |||
list-style-type: none; | |||
} | |||
.ql-editor ul > li::before { | |||
content: '\2022'; | |||
} | |||
.ql-editor ul[data-checked=true], | |||
.ql-editor ul[data-checked=false] { | |||
pointer-events: none; | |||
} | |||
.ql-editor ul[data-checked=true] > li *, | |||
.ql-editor ul[data-checked=false] > li * { | |||
pointer-events: all; | |||
} | |||
.ql-editor ul[data-checked=true] > li::before, | |||
.ql-editor ul[data-checked=false] > li::before { | |||
color: #777; | |||
cursor: pointer; | |||
pointer-events: all; | |||
} | |||
.ql-editor ul[data-checked=true] > li::before { | |||
content: '\2611'; | |||
} | |||
.ql-editor ul[data-checked=false] > li::before { | |||
content: '\2610'; | |||
} | |||
.ql-editor li::before { | |||
display: inline-block; | |||
white-space: nowrap; | |||
width: 1.2em; | |||
} | |||
.ql-editor li:not(.ql-direction-rtl)::before { | |||
margin-left: -1.5em; | |||
margin-right: 0.3em; | |||
text-align: right; | |||
} | |||
.ql-editor li.ql-direction-rtl::before { | |||
margin-left: 0.3em; | |||
margin-right: -1.5em; | |||
} | |||
.ql-editor ol li:not(.ql-direction-rtl), | |||
.ql-editor ul li:not(.ql-direction-rtl) { | |||
padding-left: 1.5em; | |||
} | |||
.ql-editor ol li.ql-direction-rtl, | |||
.ql-editor ul li.ql-direction-rtl { | |||
padding-right: 1.5em; | |||
} | |||
.ql-editor ol li { | |||
counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |||
counter-increment: list-0; | |||
} | |||
.ql-editor ol li:before { | |||
content: counter(list-0, decimal) '. '; | |||
} | |||
.ql-editor ol li.ql-indent-1 { | |||
counter-increment: list-1; | |||
} | |||
.ql-editor ol li.ql-indent-1:before { | |||
content: counter(list-1, lower-alpha) '. '; | |||
} | |||
.ql-editor ol li.ql-indent-1 { | |||
counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |||
} | |||
.ql-editor ol li.ql-indent-2 { | |||
counter-increment: list-2; | |||
} | |||
.ql-editor ol li.ql-indent-2:before { | |||
content: counter(list-2, lower-roman) '. '; | |||
} | |||
.ql-editor ol li.ql-indent-2 { | |||
counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9; | |||
} | |||
.ql-editor ol li.ql-indent-3 { | |||
counter-increment: list-3; | |||
} | |||
.ql-editor ol li.ql-indent-3:before { | |||
content: counter(list-3, decimal) '. '; | |||
} | |||
.ql-editor ol li.ql-indent-3 { | |||
counter-reset: list-4 list-5 list-6 list-7 list-8 list-9; | |||
} | |||
.ql-editor ol li.ql-indent-4 { | |||
counter-increment: list-4; | |||
} | |||
.ql-editor ol li.ql-indent-4:before { | |||
content: counter(list-4, lower-alpha) '. '; | |||
} | |||
.ql-editor ol li.ql-indent-4 { | |||
counter-reset: list-5 list-6 list-7 list-8 list-9; | |||
} | |||
.ql-editor ol li.ql-indent-5 { | |||
counter-increment: list-5; | |||
} | |||
.ql-editor ol li.ql-indent-5:before { | |||
content: counter(list-5, lower-roman) '. '; | |||
} | |||
.ql-editor ol li.ql-indent-5 { | |||
counter-reset: list-6 list-7 list-8 list-9; | |||
} | |||
.ql-editor ol li.ql-indent-6 { | |||
counter-increment: list-6; | |||
} | |||
.ql-editor ol li.ql-indent-6:before { | |||
content: counter(list-6, decimal) '. '; | |||
} | |||
.ql-editor ol li.ql-indent-6 { | |||
counter-reset: list-7 list-8 list-9; | |||
} | |||
.ql-editor ol li.ql-indent-7 { | |||
counter-increment: list-7; | |||
} | |||
.ql-editor ol li.ql-indent-7:before { | |||
content: counter(list-7, lower-alpha) '. '; | |||
} | |||
.ql-editor ol li.ql-indent-7 { | |||
counter-reset: list-8 list-9; | |||
} | |||
.ql-editor ol li.ql-indent-8 { | |||
counter-increment: list-8; | |||
} | |||
.ql-editor ol li.ql-indent-8:before { | |||
content: counter(list-8, lower-roman) '. '; | |||
} | |||
.ql-editor ol li.ql-indent-8 { | |||
counter-reset: list-9; | |||
} | |||
.ql-editor ol li.ql-indent-9 { | |||
counter-increment: list-9; | |||
} | |||
.ql-editor ol li.ql-indent-9:before { | |||
content: counter(list-9, decimal) '. '; | |||
} | |||
.ql-editor .ql-indent-1:not(.ql-direction-rtl) { | |||
padding-left: 3em; | |||
} | |||
.ql-editor li.ql-indent-1:not(.ql-direction-rtl) { | |||
padding-left: 4.5em; | |||
} | |||
.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right { | |||
padding-right: 3em; | |||
} | |||
.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right { | |||
padding-right: 4.5em; | |||
} | |||
.ql-editor .ql-indent-2:not(.ql-direction-rtl) { | |||
padding-left: 6em; | |||
} | |||
.ql-editor li.ql-indent-2:not(.ql-direction-rtl) { | |||
padding-left: 7.5em; | |||
} | |||
.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right { | |||
padding-right: 6em; | |||
} | |||
.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right { | |||
padding-right: 7.5em; | |||
} | |||
.ql-editor .ql-indent-3:not(.ql-direction-rtl) { | |||
padding-left: 9em; | |||
} | |||
.ql-editor li.ql-indent-3:not(.ql-direction-rtl) { | |||
padding-left: 10.5em; | |||
} | |||
.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right { | |||
padding-right: 9em; | |||
} | |||
.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right { | |||
padding-right: 10.5em; | |||
} | |||
.ql-editor .ql-indent-4:not(.ql-direction-rtl) { | |||
padding-left: 12em; | |||
} | |||
.ql-editor li.ql-indent-4:not(.ql-direction-rtl) { | |||
padding-left: 13.5em; | |||
} | |||
.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right { | |||
padding-right: 12em; | |||
} | |||
.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right { | |||
padding-right: 13.5em; | |||
} | |||
.ql-editor .ql-indent-5:not(.ql-direction-rtl) { | |||
padding-left: 15em; | |||
} | |||
.ql-editor li.ql-indent-5:not(.ql-direction-rtl) { | |||
padding-left: 16.5em; | |||
} | |||
.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right { | |||
padding-right: 15em; | |||
} | |||
.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right { | |||
padding-right: 16.5em; | |||
} | |||
.ql-editor .ql-indent-6:not(.ql-direction-rtl) { | |||
padding-left: 18em; | |||
} | |||
.ql-editor li.ql-indent-6:not(.ql-direction-rtl) { | |||
padding-left: 19.5em; | |||
} | |||
.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right { | |||
padding-right: 18em; | |||
} | |||
.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right { | |||
padding-right: 19.5em; | |||
} | |||
.ql-editor .ql-indent-7:not(.ql-direction-rtl) { | |||
padding-left: 21em; | |||
} | |||
.ql-editor li.ql-indent-7:not(.ql-direction-rtl) { | |||
padding-left: 22.5em; | |||
} | |||
.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right { | |||
padding-right: 21em; | |||
} | |||
.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right { | |||
padding-right: 22.5em; | |||
} | |||
.ql-editor .ql-indent-8:not(.ql-direction-rtl) { | |||
padding-left: 24em; | |||
} | |||
.ql-editor li.ql-indent-8:not(.ql-direction-rtl) { | |||
padding-left: 25.5em; | |||
} | |||
.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right { | |||
padding-right: 24em; | |||
} | |||
.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right { | |||
padding-right: 25.5em; | |||
} | |||
.ql-editor .ql-indent-9:not(.ql-direction-rtl) { | |||
padding-left: 27em; | |||
} | |||
.ql-editor li.ql-indent-9:not(.ql-direction-rtl) { | |||
padding-left: 28.5em; | |||
} | |||
.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right { | |||
padding-right: 27em; | |||
} | |||
.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right { | |||
padding-right: 28.5em; | |||
} | |||
.ql-editor .ql-video { | |||
display: block; | |||
max-width: 100%; | |||
} | |||
.ql-editor .ql-video.ql-align-center { | |||
margin: 0 auto; | |||
} | |||
.ql-editor .ql-video.ql-align-right { | |||
margin: 0 0 0 auto; | |||
} | |||
.ql-editor .ql-bg-black { | |||
background-color: #000; | |||
} | |||
.ql-editor .ql-bg-red { | |||
background-color: #e60000; | |||
} | |||
.ql-editor .ql-bg-orange { | |||
background-color: #f90; | |||
} | |||
.ql-editor .ql-bg-yellow { | |||
background-color: #ff0; | |||
} | |||
.ql-editor .ql-bg-green { | |||
background-color: #008a00; | |||
} | |||
.ql-editor .ql-bg-blue { | |||
background-color: #06c; | |||
} | |||
.ql-editor .ql-bg-purple { | |||
background-color: #93f; | |||
} | |||
.ql-editor .ql-color-white { | |||
color: #fff; | |||
} | |||
.ql-editor .ql-color-red { | |||
color: #e60000; | |||
} | |||
.ql-editor .ql-color-orange { | |||
color: #f90; | |||
} | |||
.ql-editor .ql-color-yellow { | |||
color: #ff0; | |||
} | |||
.ql-editor .ql-color-green { | |||
color: #008a00; | |||
} | |||
.ql-editor .ql-color-blue { | |||
color: #06c; | |||
} | |||
.ql-editor .ql-color-purple { | |||
color: #93f; | |||
} | |||
.ql-editor .ql-font-serif { | |||
font-family: Georgia, Times New Roman, serif; | |||
} | |||
.ql-editor .ql-font-monospace { | |||
font-family: Monaco, Courier New, monospace; | |||
} | |||
.ql-editor .ql-size-small { | |||
font-size: 0.75em; | |||
} | |||
.ql-editor .ql-size-large { | |||
font-size: 1.5em; | |||
} | |||
.ql-editor .ql-size-huge { | |||
font-size: 2.5em; | |||
} | |||
.ql-editor .ql-direction-rtl { | |||
direction: rtl; | |||
text-align: inherit; | |||
} | |||
.ql-editor .ql-align-center { | |||
text-align: center; | |||
} | |||
.ql-editor .ql-align-justify { | |||
text-align: justify; | |||
} | |||
.ql-editor .ql-align-right { | |||
text-align: right; | |||
} | |||
.ql-editor.ql-blank::before { | |||
color: rgba(0,0,0,0.6); | |||
content: attr(data-placeholder); | |||
font-style: italic; | |||
left: 15px; | |||
pointer-events: none; | |||
position: absolute; | |||
right: 15px; | |||
} | |||
</style> |
@@ -95,45 +95,68 @@ | |||
</view> | |||
</view> | |||
<view class="upgradeList" v-if="current==1"> | |||
<view class="upgradeItem"> | |||
<view class="notRead"> | |||
<!-- <view class="red"></view> --> | |||
</view> | |||
<view class="right"> | |||
<view class="title">智控管家(2022-01-22)升级公告</view> | |||
<view class="time">2021-01-12 12:23:01</view> | |||
</view> | |||
</view> | |||
<view class="upgradeItem"> | |||
<view class="notRead"> | |||
<view class="red"></view> | |||
</view> | |||
<view class="right"> | |||
<view class="title">智控管家(2022-01-11)升级公告</view> | |||
<view class="time">2021-01-12 12:23:01</view> | |||
<block v-for="(item,index) in updateAnnList" :key="index"> | |||
<view class="upgradeItem" @click="goDetail(item.content,item.id)"> | |||
<view class="notRead"> | |||
<view v-if="item.readFlag==0" class="red"></view> | |||
</view> | |||
<view class="right"> | |||
<view class="title">{{item.title}}</view> | |||
<view class="time">{{item.createTime}}</view> | |||
</view> | |||
</view> | |||
</view> | |||
</block> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
export default { | |||
data() { | |||
return { | |||
return { | |||
updateAnnList:[], | |||
list: [{ | |||
name: '系统消息' | |||
},{ | |||
name: `升级公告`, | |||
count:20, | |||
count:"", | |||
}], | |||
current: 0 | |||
}; | |||
}, | |||
onShow() { | |||
this.updateInit() | |||
}, | |||
methods:{ | |||
updateInit(){ | |||
uni.request({ | |||
url: config.service.updateList, | |||
method: "GET", | |||
data:{id:uni.getStorageSync('weapp_session_userInfo_data').accountId}, | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (res) => { | |||
this.updateAnnList = res.data.data.list | |||
this.list[1].count = res.data.data.count | |||
} | |||
}) | |||
}, | |||
goDetail(text,id){ | |||
let link=encodeURIComponent(JSON.stringify(text)) | |||
uni.navigateTo({ | |||
url:"./messageDetail?content="+link+"&id="+id | |||
}) | |||
}, | |||
change(index) { | |||
this.current = index; | |||
if(this.current==1){ | |||
this.updateInit() | |||
} | |||
} | |||
} | |||
} | |||
@@ -1,15 +1,14 @@ | |||
// http.js使用域名 | |||
// const baseUrl = 'http://192.168.31.57:8080/autoSR/api';// 本地 | |||
// const baseUrl = 'http://121.42.63.138:9091/autoSR/api';// 测试站 | |||
// const baseUrl = 'http://192.168.31.92:8080/api';// sh | |||
const baseUrl = 'http://192.168.31.89:9090/api';// sh | |||
// const baseUrl = 'http://81.70.55.170:9090/autoSR/api';// 测试站 | |||
// const baseUrl = 'http://192.168.31.167:8080/autoSR/api'; // 长龙 | |||
// const baseUrl = 'http://192.168.31.134:8080/autoSR/api'; // 佳豪 | |||
// const baseUrl = 'http://10.2.1.104:8081/autoSR/api'; // 刘敏 | |||
const baseUrl = 'https://zkgj.quhouse.com/api'; // 质控正式 | |||
// const baseUrl = 'https://zkgj.quhouse.com/api'; // 质控正式 | |||
// const baseUrl = 'https://hfju.com/api'; // 数智正式 | |||
// config使用域名 | |||
/**192.168.31.167 | |||
* 小程序配置文件 | |||