| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | /** |
| | | * 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; |
| New file |
| | |
| | | /** |
| | | * |
| | | * 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; |
| New file |
| | |
| | | // 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, |
| | | }; |
| New file |
| | |
| | | /** |
| | | * 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; |
| | | } |
| New file |
| | |
| | | <!--** |
| | | * 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> |
| New file |
| | |
| | | <template> |
| | | <view class="advisory-big"> |
| | | |
| | | <view v-for="i in data" class="advisory-model" @click="goDetail(i)"> |
| | | <view class="advisory-left"> |
| | | <view class="advisory-title-top"> |
| | | <view class="advisory-title">{{i.title}}</view> |
| | | </view> |
| | | <view class="advisory-title-down"> |
| | | <view class="advisory-title-name">{{i.sourceName}}</view> |
| | | <view class="advisory-title-time">{{i.createTime}}</view> |
| | | </view> |
| | | </view> |
| | | <view class="advisory-right"> |
| | | <image :src="i.url"></image> |
| | | </view> |
| | | </view> |
| | | |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default{ |
| | | data(){ |
| | | return { |
| | | // pathUrl:"http://localhost:89/", |
| | | pathUrl:"http://s16s652780.51mypc.cn/api/blade-jfpts", |
| | | data:[] |
| | | } |
| | | }, |
| | | mounted(){ |
| | | this.getArtcilePageList(); |
| | | }, |
| | | methods:{ |
| | | //去跳转详情页面 |
| | | goDetail(e){ |
| | | |
| | | //内容传值容易报错,所以直传id,然后调用接口去查询 |
| | | // let detail = { |
| | | // title: e.title, |
| | | // content: e.content, |
| | | // id: e.id, |
| | | // createTime: e.createTime, |
| | | // sourceName: e.sourceName, |
| | | // imgUrl: e.url, |
| | | // videoUrl:e.videoUrl |
| | | // }; |
| | | |
| | | let detail = { |
| | | id: e.id |
| | | }; |
| | | //去跳转 |
| | | uni.navigateTo({ |
| | | url: './article_detail?detailData=' + encodeURIComponent(JSON.stringify(detail)) |
| | | }); |
| | | }, |
| | | |
| | | //获取资讯信息 |
| | | getArtcilePageList(){ |
| | | var that = this; |
| | | uni.request({ |
| | | url: that.pathUrl+'/article/article/page', |
| | | method:'GET', |
| | | success: (res) => { |
| | | that.data = res.data.data.records; |
| | | } |
| | | }); |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .advisory-big{ |
| | | width: 100%; |
| | | height: 70%; |
| | | position: absolute; |
| | | top: 2%; |
| | | // background-color: #0078A8; |
| | | |
| | | .advisory-model{ |
| | | width: 100%; |
| | | height: 20%; |
| | | // background-color: #00FF00; |
| | | |
| | | |
| | | .advisory-left{ |
| | | width: 61%; |
| | | height: 80%; |
| | | float: left; |
| | | position: relative; |
| | | // background-color: #00FFFF; |
| | | position: relative; |
| | | left: 4%; |
| | | top: 10%; |
| | | |
| | | |
| | | .advisory-title-top{ |
| | | // background-color: #2692FD; |
| | | width: 100%; |
| | | height: 75%; |
| | | |
| | | .advisory-title{ |
| | | width: 92%; |
| | | font-size: 15px; |
| | | font-weight: 550; |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | .advisory-title-down{ |
| | | // background-color: #0078A8; |
| | | width: 100%; |
| | | height: 25%; |
| | | font-size: 12px; |
| | | font-weight: 550; |
| | | color: #808080; |
| | | |
| | | .advisory-title-name{ |
| | | float: left; |
| | | letter-spacing: 1px; |
| | | } |
| | | |
| | | .advisory-title-time{ |
| | | position: relative; |
| | | left: 6%; |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | .advisory-right{ |
| | | // background-color: #222222; |
| | | width: 32%; |
| | | height: 80%; |
| | | left: 63%; |
| | | position: relative; |
| | | top: 10%; |
| | | |
| | | image{ |
| | | position: relative; |
| | | left: 0px; |
| | | top: -100%; |
| | | width: 100%; |
| | | height: 100%; |
| | | border-radius: 5px; |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <view> |
| | | <view class="banner"> |
| | | <image class="banner-img" :src="article.url"></image> |
| | | <view class="banner-title">{{article.title}}</view> |
| | | </view> |
| | | |
| | | |
| | | <view class="article-content"> |
| | | <!-- <rich-text type="text" :nodes="demoHtml"></rich-text> --> |
| | | <video id="myVideo" v-if="video" :src="article.videoUrl"></video> |
| | | <view class="content-placeholder"> </view> |
| | | <u-parse :content="content" @navigate="navigate"></u-parse> |
| | | </view> |
| | | |
| | | <view class="article-meta"> |
| | | <text class="article-author">{{article.sourceName}}</text> |
| | | <text class="article-text">发表于</text> |
| | | <text class="article-time">{{article.createTime}}</text> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import uParse from "@/components/feng-parse/parse.vue" |
| | | // import uParse from '@/components/gaoyia-parse/parse.vue' |
| | | // var graceRichText = require("../../components/richText/richText.js"); |
| | | |
| | | export default { |
| | | components:{ |
| | | uParse |
| | | }, |
| | | data() { |
| | | return { |
| | | content:"", |
| | | article:{}, |
| | | video:false, |
| | | pathUrl:"http://s16s652780.51mypc.cn/api/blade-jfpts", |
| | | } |
| | | }, |
| | | onLoad(event) { |
| | | var that = this; |
| | | this.article = JSON.parse(decodeURIComponent(event.detailData)); |
| | | uni.request({ |
| | | url: that.pathUrl+'/article/article/detail?id='+this.article.id, |
| | | method:'GET', |
| | | success: (res) => { |
| | | that.article = res.data.data; |
| | | that.content = that.article.content; |
| | | if(that.article.videoUrl){ |
| | | that.video = true; |
| | | } |
| | | //详情标题 |
| | | uni.setNavigationBarTitle({ |
| | | title: that.article.title |
| | | }); |
| | | } |
| | | }); |
| | | |
| | | }, |
| | | onReady: function (res) { |
| | | this.videoContext = uni.createVideoContext('myVideo') |
| | | }, |
| | | methods: { |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .banner { |
| | | height: 360upx; |
| | | overflow: hidden; |
| | | position: relative; |
| | | background-color: #ccc; |
| | | } |
| | | .banner-img { |
| | | width: 100%; |
| | | } |
| | | .banner-title { |
| | | max-height: 84upx; |
| | | overflow: hidden; |
| | | position: absolute; |
| | | left: 30upx; |
| | | bottom: 30upx; |
| | | width: 90%; |
| | | font-size: 32upx; |
| | | font-weight: 400; |
| | | line-height: 42upx; |
| | | color: white; |
| | | z-index: 11; |
| | | } |
| | | |
| | | .article-meta{ |
| | | // background-color: #007AFF; |
| | | width: 100%; |
| | | height: 80rpx; |
| | | position: relative; |
| | | top: 40rpx; |
| | | font-size: 24rpx; |
| | | color: #808080; |
| | | // font-weight: 550; |
| | | |
| | | |
| | | .article-author{ |
| | | position: relative; |
| | | left: 20rpx; |
| | | letter-spacing: 1px; |
| | | } |
| | | |
| | | .article-text{ |
| | | position: relative; |
| | | left: 40rpx; |
| | | } |
| | | |
| | | .article-time{ |
| | | position: relative; |
| | | left: 50rpx; |
| | | } |
| | | } |
| | | |
| | | .article-content{ |
| | | position: relative; |
| | | top: 20rpx; |
| | | left: 3%; |
| | | width: 94%; |
| | | border-bottom: 1px solid rgba(128,128,128,0.1); |
| | | |
| | | .content-placeholder{ |
| | | position: relative; |
| | | left: 30%; |
| | | background-color: #0078A8; |
| | | width: 30%; |
| | | height: 20%; |
| | | |
| | | } |
| | | } |
| | | </style> |