zmt
3 years ago
30 changed files with 3084 additions and 15 deletions
-
28components/feng-parse/components/wxParseAudio.vue
-
94components/feng-parse/components/wxParseImg.vue
-
56components/feng-parse/components/wxParseTable.vue
-
116components/feng-parse/components/wxParseTemplate0.vue
-
107components/feng-parse/components/wxParseTemplate1.vue
-
107components/feng-parse/components/wxParseTemplate10.vue
-
105components/feng-parse/components/wxParseTemplate11.vue
-
107components/feng-parse/components/wxParseTemplate2.vue
-
107components/feng-parse/components/wxParseTemplate3.vue
-
107components/feng-parse/components/wxParseTemplate4.vue
-
107components/feng-parse/components/wxParseTemplate5.vue
-
107components/feng-parse/components/wxParseTemplate6.vue
-
107components/feng-parse/components/wxParseTemplate7.vue
-
107components/feng-parse/components/wxParseTemplate8.vue
-
107components/feng-parse/components/wxParseTemplate9.vue
-
55components/feng-parse/components/wxParseVideo.vue
-
25components/feng-parse/components/wxParseVideo1.vue
-
308components/feng-parse/libs/html2json.js
-
156components/feng-parse/libs/htmlparser.js
-
209components/feng-parse/libs/wxDiscode.js
-
258components/feng-parse/parse.css
-
237components/feng-parse/parse.vue
-
11nxTemp/config/index.config.js
-
294nxTemp/utils/canvas_get_image_colors.js
-
1pages.json
-
5pages/event/event_grade.vue
-
3pages/event/event_list.vue
-
30pages/index/index.vue
-
12pages/message/center_list.vue
-
26pages/message/detail.vue
@ -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="widthFix" |
|||
: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;`; |
|||
|
|||
if(!styleStr) 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,56 @@ |
|||
<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) { |
|||
console.log(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,116 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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"/> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--其他标签--> |
|||
<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,107 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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 --> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--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,107 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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"/> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--其他标签--> |
|||
<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,105 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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"> |
|||
<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'"/> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--其他标签--> |
|||
<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,107 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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"/> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--其他标签--> |
|||
<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,107 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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 --> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--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,107 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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"/> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--其他标签--> |
|||
<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,107 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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"/> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--其他标签--> |
|||
<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,107 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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"/> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--其他标签--> |
|||
<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,107 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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"/> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--其他标签--> |
|||
<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,107 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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"/> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--其他标签--> |
|||
<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,107 @@ |
|||
<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" style="display: inline; border-bottom: 1px solid #555555;"> |
|||
<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"/> |
|||
|
|||
<!--strong标签--> |
|||
<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--span标签--> |
|||
<view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
<!--em标签--> |
|||
<view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;"> |
|||
<block v-for="(node, index) of node.nodes" :key="index"> |
|||
<wx-parse-template :node="node"/> |
|||
</block> |
|||
</view> |
|||
|
|||
<!--其他标签--> |
|||
<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,55 @@ |
|||
<template> |
|||
<!-- 这个模板用来解决原生video总是浮在最上层的问题,使用view替换video,播放是再替换回,监听一个事件,用来被遮盖时做替换video --> |
|||
<!--增加video标签支持,并循环添加--> |
|||
<view @click="play"> |
|||
<view v-if="!playState" :class="node.classStr" :style="node.styleStr" style="display: inline-block;margin: auto;max-width: 100%;" class="video-video"> |
|||
<view style="display: flex;width: 100%;height:100%;flex-direction: row; justify-content: center;align-items: center;"> |
|||
<image src="https://gwbj.tongwenkeji.com/html/static/play.png" style="width: 20%;" mode="widthFix"></image> |
|||
</view> |
|||
</view> |
|||
<video |
|||
:autoplay="false" |
|||
:class="node.classStr" |
|||
:style="node.styleStr" |
|||
class="video-video" |
|||
v-if="playState" |
|||
:src="node.attr.src"></video> |
|||
|
|||
</view> |
|||
|
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'wxParseVideo', |
|||
props: { |
|||
node: {}, |
|||
}, |
|||
data(){ |
|||
return{ |
|||
playState:true, |
|||
videoStyle:'width: 100%;' |
|||
} |
|||
}, |
|||
methods:{ |
|||
play(){ |
|||
console.log('点击了video 播放') |
|||
//显示播放器并播放播放器 |
|||
this.playState = !this.playState |
|||
} |
|||
}, |
|||
mounted() { |
|||
//捕获侧滑菜单的遮盖行为,隐藏video |
|||
uni.$on('slideMenuShow',e=>{ |
|||
console.log('捕获事件:'+e) |
|||
if(e == 'show' && this.playState){ |
|||
//正在播放则停止 |
|||
this.playState = false |
|||
} |
|||
}) |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
.video-video{background: #000000;} |
|||
</style> |
@ -0,0 +1,25 @@ |
|||
<template> |
|||
<!-- 这个模板用来渲染原生video --> |
|||
<!--增加video标签支持,并循环添加--> |
|||
<view style="max-width: 100%;"> |
|||
<video |
|||
:autoplay="playState" |
|||
:class="node.classStr" |
|||
:style="node.styleStr" |
|||
class="video-video" |
|||
v-if="playState" |
|||
:src="node.attr.src"></video> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'wxParseVideo', |
|||
props: { |
|||
node: {}, |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
.video-video{z-index: 1;} |
|||
</style> |
@ -0,0 +1,308 @@ |
|||
/** |
|||
* 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 || ''; |
|||
} |
|||
|
|||
//处理table
|
|||
if (node.tag === 'table' || node.tag === 'tr' || node.tag === 'td') { |
|||
node.styleStr = "" |
|||
if (node.attr.width) { |
|||
node.styleStr += "width:" + node.attr.width + 'px;' |
|||
if (node.attr.width > node.$screen.width) { |
|||
//等比缩放height
|
|||
if (node.attr.height) { |
|||
node.attr.height = (node.$screen.width * node.attr.height) / node.attr.width |
|||
} |
|||
} |
|||
} |
|||
if (node.attr.height) { |
|||
node.styleStr += "height:" + node.attr.height + 'px;' |
|||
} |
|||
|
|||
} |
|||
//处理video
|
|||
if (node.tag === 'video') { |
|||
node.styleStr = "" |
|||
if (node.attr.width) { |
|||
node.styleStr += "width:" + node.attr.width + 'px;' |
|||
if (node.attr.width > node.$screen.width) { |
|||
//等比缩放height
|
|||
if (node.attr.height) { |
|||
node.attr.height = (node.$screen.width * node.attr.height) / node.attr.width |
|||
} |
|||
} |
|||
} |
|||
if (node.attr.height) { |
|||
node.styleStr += "height:" + node.attr.height + 'px;' |
|||
} |
|||
|
|||
} |
|||
|
|||
// 处理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; |
|||
} |
|||
//#ifndef MP-BAIDU
|
|||
if (customHandler.start) { |
|||
customHandler.start(node, results); |
|||
} |
|||
//#endif
|
|||
|
|||
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; |
|||
} |
|||
//#ifndef MP-BAIDU
|
|||
if (customHandler && customHandler.end) { |
|||
customHandler.end(node, results); |
|||
} |
|||
//#endif
|
|||
|
|||
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, |
|||
}; |
|||
//#ifndef MP-BAIDU
|
|||
if (customHandler.chars) { |
|||
customHandler.chars(node, results); |
|||
} |
|||
//#endif
|
|||
|
|||
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,237 @@ |
|||
<!--** |
|||
* forked from:https://github.com/F-loat/mpvue-wxParse |
|||
* |
|||
* github地址: https://github.com/dcloudio/uParse |
|||
* |
|||
* for: uni-app框架下 富文本解析 |
|||
* |
|||
* 优化 by zhiqiang.feng@qq.com |
|||
*/--> |
|||
|
|||
<template> |
|||
|
|||
<!--基础元素--> |
|||
<view class="wxParse" :class="className" :style="'user-select:' + userSelect"> |
|||
<block v-for="(node, index) of nodes" :key="index" v-if="!loading"> |
|||
<wxParseTemplate :node="node" /> |
|||
</block> |
|||
</view> |
|||
</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: '' |
|||
}, |
|||
startHandler: { |
|||
type: Function, |
|||
default () { |
|||
return node => { |
|||
node.attr.class = null; |
|||
node.attr.style = null; |
|||
}; |
|||
} |
|||
}, |
|||
endHandler: { |
|||
type: Function, |
|||
default() { |
|||
return node => { |
|||
node = node |
|||
}; |
|||
} |
|||
}, |
|||
charsHandler: { |
|||
type: Function, |
|||
default() { |
|||
return node => { |
|||
node = node |
|||
}; |
|||
} |
|||
}, |
|||
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(() => { |
|||
if(item.node){ |
|||
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(val){ |
|||
this.setHtml() |
|||
} |
|||
// content: { |
|||
// handler: function(newVal, oldVal) { |
|||
// if (newVal !== oldVal) { |
|||
// |
|||
// } |
|||
// }, |
|||
// deep: true |
|||
// } |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,294 @@ |
|||
export class getImgColor { //定义了一个名字为Person的类
|
|||
constructor(img) { //constructor是一个构造方法,用来接收参数
|
|||
// this代表的是实例对象
|
|||
// var that = this
|
|||
let canvasId = "testcanvasId" |
|||
let imgPath = img || "/static/images/logo_main.png" |
|||
// let imgPath = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F8c39725605bf4e80e9763c58dbfb02482f98d87711069-qXPaNI_fw658&refer=http%3A%2F%2Fhbimg.b0.upaiyun.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1650531435&t=6f1744c5f84585eaef5dd1be6f83ae24"
|
|||
const ctx = uni.createCanvasContext(canvasId) |
|||
|
|||
ctx.drawImage(imgPath, 0, 0, 300, 300) |
|||
console.log(777, ctx); |
|||
ctx.draw(false, () => { |
|||
// uni.canvasGetImageData({
|
|||
// canvasId: canvasId,
|
|||
// x: 150,
|
|||
// y: 150,
|
|||
// width: 50,
|
|||
// height: 50,
|
|||
// success: (res) => {
|
|||
// console.log(res.data[0] +' ' + res.data[1] +' ' + res.data[2])
|
|||
// console.log("canvasGetImageData return:",res.data);
|
|||
// },
|
|||
// fail: res => {
|
|||
// console.log(res)
|
|||
// },
|
|||
// }, that)
|
|||
}) |
|||
this.canvas = ctx |
|||
this.canvas.width = 300 |
|||
this.canvas.height = 300 |
|||
this.cvs = ctx |
|||
|
|||
|
|||
// this.canvas = document.createElement("canvas")
|
|||
// this.canvas.width = img.width
|
|||
// this.canvas.height = img.height
|
|||
// this.cvs = this.canvas.getContext("2d")
|
|||
// this.cvs.drawImage(img, 0, 0)
|
|||
// this.accuracy = 5
|
|||
// this.progress = ''
|
|||
} |
|||
getColorXY(x, y) { |
|||
|
|||
/** |
|||
* @param x Number x坐标起点 |
|||
* @param y Number y坐标起点 |
|||
* @return color Object 包含颜色的rgba #16进制颜色 |
|||
*/ |
|||
|
|||
let obj = this.cvs.getImageData(x, y, 1, 1) //{"data":{"0":247,"1":255,"2":254,"3":255}}
|
|||
let arr = obj.data.toString().split(",") |
|||
|
|||
let first = parseInt(arr[0]).toString(16) |
|||
first = first.length === 2 ? first : first + first |
|||
|
|||
let second = parseInt(arr[1]).toString(16) |
|||
second = second.length === 2 ? second : second + second |
|||
|
|||
let third = parseInt(arr[2]).toString(16) |
|||
third = third.length === 2 ? third : third + third |
|||
|
|||
let last = parseInt(arr.pop()) / 255 |
|||
last = last.toFixed(0) |
|||
|
|||
let color = {} |
|||
color['rgba'] = 'rgba(' + arr.join(',') + ',' + last + ')' |
|||
color['#'] = '#' + first + second + third |
|||
return color |
|||
} |
|||
getColors() { |
|||
|
|||
/** |
|||
* 避免图片过大,阻塞卡死 |
|||
* 每加载一行像素,延迟20毫秒加载下一行 |
|||
* return Promise |
|||
* promise resolve 解析完成后,返回颜色的总计数组,降序排列 |
|||
* promise reject none |
|||
*/ |
|||
|
|||
return (new Promise((resolve, reject) => { |
|||
|
|||
let arr = [] |
|||
let getY = (i) => { |
|||
for (let j = 0; j < this.canvas.height; j++) { |
|||
let obj = {} |
|||
obj = this.getColorXY(i, j) |
|||
obj.index = 1 |
|||
let is = true |
|||
|
|||
arr.forEach((item) => { |
|||
if (item['#'] === obj['#']) { |
|||
is = false |
|||
item.index += 1 |
|||
} |
|||
|
|||
let l = [] |
|||
|
|||
for (let i = 0; i < obj['#'].length; i++) { |
|||
|
|||
if (item['#'].indexOf(obj['#'][i]) > -1) { |
|||
l.push('1') |
|||
} |
|||
} |
|||
|
|||
let acc = (this.accuracy > 7) ? 7 : this.accuracy |
|||
acc = (this.accuracy < 1) ? 2 : this.accuracy |
|||
if (l.length > acc) { |
|||
is = false |
|||
item.index += 1 |
|||
} |
|||
}) |
|||
|
|||
if (is) { |
|||
arr.push(obj) |
|||
} |
|||
} |
|||
}; |
|||
|
|||
let getX = (i) => { |
|||
if (i < this.canvas.width) { |
|||
|
|||
getY(i) |
|||
this.progress = (i / this.canvas.width * 100).toFixed(2) + '%' |
|||
console.log(this.progress) |
|||
setTimeout(() => { |
|||
getX(++i) |
|||
}, 20) |
|||
|
|||
} else { |
|||
|
|||
this.progress = '100%' |
|||
console.log(this.progress) |
|||
|
|||
resolve(arr.sort(function(a, b) { |
|||
return a.index < b.index ? 1 : (a.index > b.index ? -1 : 0) |
|||
})) |
|||
} |
|||
}; |
|||
|
|||
getX(0) |
|||
|
|||
})) |
|||
} |
|||
} |
|||
|
|||
var getImgColor1 = function getImgColor(img) { |
|||
/** |
|||
* @ param 传入的图片 |
|||
* @ this.progress 解析图片的进度 实时 |
|||
* @ this.canvas canvas元素 |
|||
* @ this.cvs context对象 |
|||
* @ this.accuracy Number 解析图片颜色的精确度 1 - 7 数字选择 |
|||
* |
|||
* |
|||
* @ anther taoqun <taoquns@foxmail.com> |
|||
*/ |
|||
var that = this |
|||
let canvasId = "testcanvasId" |
|||
let imgPath = img || "/static/images/logo_main.png" |
|||
// let imgPath = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F8c39725605bf4e80e9763c58dbfb02482f98d87711069-qXPaNI_fw658&refer=http%3A%2F%2Fhbimg.b0.upaiyun.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1650531435&t=6f1744c5f84585eaef5dd1be6f83ae24"
|
|||
const ctx = uni.createCanvasContext(canvasId) |
|||
|
|||
ctx.drawImage(imgPath, 0, 0, 300, 300) |
|||
console.log(777, ctx); |
|||
ctx.draw(false, () => { |
|||
// uni.canvasGetImageData({
|
|||
// canvasId: canvasId,
|
|||
// x: 150,
|
|||
// y: 150,
|
|||
// width: 50,
|
|||
// height: 50,
|
|||
// success: (res) => {
|
|||
// console.log(res.data[0] +' ' + res.data[1] +' ' + res.data[2])
|
|||
// console.log("canvasGetImageData return:",res.data);
|
|||
// },
|
|||
// fail: res => {
|
|||
// console.log(res)
|
|||
// },
|
|||
// }, that)
|
|||
}) |
|||
|
|||
// this.canvas = document.createElement("canvas")
|
|||
// this.canvas.width = img.width
|
|||
// this.canvas.height = img.height
|
|||
// this.cvs = this.canvas.getContext("2d")
|
|||
// this.cvs.drawImage(img, 0, 0)
|
|||
// this.accuracy = 5
|
|||
// this.progress = ''
|
|||
} |
|||
getImgColor1.prototype.getColorXY = function(x, y) { |
|||
|
|||
/** |
|||
* @param x Number x坐标起点 |
|||
* @param y Number y坐标起点 |
|||
* @return color Object 包含颜色的rgba #16进制颜色 |
|||
*/ |
|||
|
|||
let obj = this.cvs.getImageData(x, y, 1, 1) |
|||
let arr = obj.data.toString().split(",") |
|||
|
|||
let first = parseInt(arr[0]).toString(16) |
|||
first = first.length === 2 ? first : first + first |
|||
|
|||
let second = parseInt(arr[1]).toString(16) |
|||
second = second.length === 2 ? second : second + second |
|||
|
|||
let third = parseInt(arr[2]).toString(16) |
|||
third = third.length === 2 ? third : third + third |
|||
|
|||
let last = parseInt(arr.pop()) / 255 |
|||
last = last.toFixed(0) |
|||
|
|||
let color = {} |
|||
color['rgba'] = 'rgba(' + arr.join(',') + ',' + last + ')' |
|||
color['#'] = '#' + first + second + third |
|||
return color |
|||
} |
|||
getImgColor1.prototype.getColors = function() { |
|||
|
|||
/** |
|||
* 避免图片过大,阻塞卡死 |
|||
* 每加载一行像素,延迟20毫秒加载下一行 |
|||
* return Promise |
|||
* promise resolve 解析完成后,返回颜色的总计数组,降序排列 |
|||
* promise reject none |
|||
*/ |
|||
|
|||
return (new Promise((resolve, reject) => { |
|||
|
|||
let arr = [] |
|||
let getY = (i) => { |
|||
for (let j = 0; j < this.canvas.height; j++) { |
|||
let obj = {} |
|||
obj = this.getColorXY(i, j) |
|||
obj.index = 1 |
|||
let is = true |
|||
|
|||
arr.forEach((item) => { |
|||
if (item['#'] === obj['#']) { |
|||
is = false |
|||
item.index += 1 |
|||
} |
|||
|
|||
let l = [] |
|||
|
|||
for (let i = 0; i < obj['#'].length; i++) { |
|||
|
|||
if (item['#'].indexOf(obj['#'][i]) > -1) { |
|||
l.push('1') |
|||
} |
|||
} |
|||
|
|||
let acc = (this.accuracy > 7) ? 7 : this.accuracy |
|||
acc = (this.accuracy < 1) ? 2 : this.accuracy |
|||
if (l.length > acc) { |
|||
is = false |
|||
item.index += 1 |
|||
} |
|||
}) |
|||
|
|||
if (is) { |
|||
arr.push(obj) |
|||
} |
|||
} |
|||
}; |
|||
|
|||
let getX = (i) => { |
|||
if (i < this.canvas.width) { |
|||
|
|||
getY(i) |
|||
this.progress = (i / this.canvas.width * 100).toFixed(2) + '%' |
|||
console.log(this.progress) |
|||
setTimeout(() => { |
|||
getX(++i) |
|||
}, 20) |
|||
|
|||
} else { |
|||
|
|||
this.progress = '100%' |
|||
console.log(this.progress) |
|||
|
|||
resolve(arr.sort(function(a, b) { |
|||
return a.index < b.index ? 1 : (a.index > b.index ? -1 : 0) |
|||
})) |
|||
} |
|||
}; |
|||
|
|||
getX(0) |
|||
|
|||
})) |
|||
} |
|||
export default { |
|||
getImgColor |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue