From d8b41fff43a2cee6a8f714ffa807623b15803786 Mon Sep 17 00:00:00 2001
From: quanyawei <401863037@qq.com>
Date: Fri, 20 Oct 2023 15:21:35 +0800
Subject: [PATCH] fix:立行立改Uniapp小程序新建项目
---
uni_modules/uview-ui/components/u-parse/u-parse.vue | 366 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 366 insertions(+), 0 deletions(-)
diff --git a/uni_modules/uview-ui/components/u-parse/u-parse.vue b/uni_modules/uview-ui/components/u-parse/u-parse.vue
new file mode 100644
index 0000000..7bc8b3d
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-parse/u-parse.vue
@@ -0,0 +1,366 @@
+<template>
+ <view id="_root" :class="(selectable?'_select ':'')+'_root'">
+ <slot v-if="!nodes[0]" />
+ <!-- #ifndef APP-PLUS-NVUE -->
+ <node v-else :childs="nodes" :opts="[lazyLoad,loadingImg,errorImg,showImgMenu]" />
+ <!-- #endif -->
+ <!-- #ifdef APP-PLUS-NVUE -->
+ <web-view ref="web" src="/static/app-plus/mp-html/local.html" :style="'margin-top:-2px;height:' + height + 'px'" @onPostMessage="_onMessage" />
+ <!-- #endif -->
+ </view>
+</template>
+
+<script>
+ import props from './props.js';
+/**
+ * mp-html v2.0.4
+ * @description ���������������
+ * @tutorial https://github.com/jin-yufeng/mp-html
+ * @property {String} bgColor ���������������������������APP-PLUS-NVUE
+ * @property {String} content ������������������������������������������ true ���
+ * @property {Boolean} copyLink ������������������������������������������������
+ * @property {String} domain ������������������������������
+ * @property {String} errorImg ���������������������������������
+ * @property {Boolean} lazyLoad ������������������������������������ true ���
+ * @property {string} loadingImg ���������������������������������������
+ * @property {Boolean} pauseVideo ��������������������������������������������������������������� true ���
+ * @property {Boolean} previewImg ��������������������������������������������������� true ���
+ * @property {Boolean} scrollTable ���������������������������������������������������������������������
+ * @property {Boolean} selectable ������������������������
+ * @property {Boolean} setTitle ��������� title ��������������������������������������������� true ���
+ * @property {Boolean} showImgMenu ��������������������������������������������������� true ���
+ * @property {Object} tagStyle ���������������������
+ * @property {Boolean | Number} useAnchor ������������������������
+ *
+ * @event {Function} load dom ���������������������������
+ * @event {Function} ready ���������������������������������
+ * @event {Function} imgTap ������������������������
+ * @event {Function} linkTap ������������������������
+ * @event {Function} error ���������������������������
+ */
+const plugins=[]
+const parser = require('./parser')
+// #ifndef APP-PLUS-NVUE
+import node from './node/node'
+// #endif
+// #ifdef APP-PLUS-NVUE
+const dom = weex.requireModule('dom')
+// #endif
+export default {
+ name: 'mp-html',
+ data() {
+ return {
+ nodes: [],
+ // #ifdef APP-PLUS-NVUE
+ height: 0
+ // #endif
+ }
+ },
+ mixins:[props],
+ // #ifndef APP-PLUS-NVUE
+ components: {
+ node
+ },
+ // #endif
+ watch: {
+ content(content) {
+ this.setContent(content)
+ }
+ },
+ created() {
+ this.plugins = []
+ for (let i = plugins.length; i--;)
+ this.plugins.push(new plugins[i](this))
+ },
+ mounted() {
+ if (this.content && !this.nodes.length)
+ this.setContent(this.content)
+ },
+ beforeDestroy() {
+ this._hook('onDetached')
+ clearInterval(this._timer)
+ },
+ methods: {
+ /**
+ * @description ��������������������������������������� scroll-view ���
+ * @param {Object} page scroll-view ���������������������
+ * @param {String} selector scroll-view ������������
+ * @param {String} scrollTop scroll-view scroll-top ������������������������
+ */
+ in(page, selector, scrollTop) {
+ // #ifndef APP-PLUS-NVUE
+ if (page && selector && scrollTop)
+ this._in = {
+ page,
+ selector,
+ scrollTop
+ }
+ // #endif
+ },
+
+ /**
+ * @description ������������
+ * @param {String} id ������������������ id
+ * @param {Number} offset ������������������������
+ * @returns {Promise}
+ */
+ navigateTo(id, offset) {
+ return new Promise((resolve, reject) => {
+ if (!this.useAnchor)
+ return reject('Anchor is disabled')
+ offset = offset || parseInt(this.useAnchor) || 0
+ // #ifdef APP-PLUS-NVUE
+ if (!id) {
+ dom.scrollToElement(this.$refs.web, {
+ offset
+ })
+ resolve()
+ } else {
+ this._navigateTo = {
+ resolve,
+ reject,
+ offset
+ }
+ this.$refs.web.evalJs('uni.postMessage({data:{action:"getOffset",offset:(document.getElementById(' + id + ')||{}).offsetTop}})')
+ }
+ // #endif
+ // #ifndef APP-PLUS-NVUE
+ let deep = ' '
+ // #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
+ deep = '>>>'
+ // #endif
+ const selector = uni.createSelectorQuery()
+ // #ifndef MP-ALIPAY
+ .in(this._in ? this._in.page : this)
+ // #endif
+ .select((this._in ? this._in.selector : '._root') + (id ? `${deep}#${id}` : '')).boundingClientRect()
+ if (this._in)
+ selector.select(this._in.selector).scrollOffset()
+ .select(this._in.selector).boundingClientRect() // ������ scroll-view ������������������������
+ else
+ selector.selectViewport().scrollOffset() // ���������������������������
+ selector.exec(res => {
+ if (!res[0])
+ return reject('Label not found')
+ const scrollTop = res[1].scrollTop + res[0].top - (res[2] ? res[2].top : 0) + offset
+ if (this._in)
+ // scroll-view ������
+ this._in.page[this._in.scrollTop] = scrollTop
+ else
+ // ������������
+ uni.pageScrollTo({
+ scrollTop,
+ duration: 300
+ })
+ resolve()
+ })
+ // #endif
+ })
+ },
+
+ /**
+ * @description ������������������
+ * @return {String}
+ */
+ getText() {
+ let text = '';
+ (function traversal(nodes) {
+ for (let i = 0; i < nodes.length; i++) {
+ const node = nodes[i]
+ if (node.type == 'text')
+ text += node.text.replace(/&/g, '&')
+ else if (node.name == 'br')
+ text += '\n'
+ else {
+ // ���������������������������
+ const isBlock = node.name == 'p' || node.name == 'div' || node.name == 'tr' || node.name == 'li' || (node.name[0] == 'h' && node.name[1] > '0' && node.name[1] < '7')
+ if (isBlock && text && text[text.length - 1] != '\n')
+ text += '\n'
+ // ������������������������������
+ if (node.children)
+ traversal(node.children)
+ if (isBlock && text[text.length - 1] != '\n')
+ text += '\n'
+ else if (node.name == 'td' || node.name == 'th')
+ text += '\t'
+ }
+ }
+ })(this.nodes)
+ return text
+ },
+
+ /**
+ * @description ���������������������������
+ * @return {Promise}
+ */
+ getRect() {
+ return new Promise((resolve, reject) => {
+ uni.createSelectorQuery()
+ // #ifndef MP-ALIPAY
+ .in(this)
+ // #endif
+ .select('#_root').boundingClientRect().exec(res => res[0] ? resolve(res[0]) : reject('Root label not found'))
+ })
+ },
+
+ /**
+ * @description ������������
+ * @param {String} content html ������
+ * @param {Boolean} append ���������������������
+ */
+ setContent(content, append) {
+ if (!append || !this.imgList)
+ this.imgList = []
+ const nodes = new parser(this).parse(content)
+ // #ifdef APP-PLUS-NVUE
+ if (this._ready)
+ this._set(nodes, append)
+ // #endif
+ this.$set(this, 'nodes', append ? (this.nodes || []).concat(nodes) : nodes)
+
+ // #ifndef APP-PLUS-NVUE
+ this._videos = []
+ this.$nextTick(() => {
+ this._hook('onLoad')
+ this.$emit('load')
+ })
+
+ // ������������������������
+ let height
+ clearInterval(this._timer)
+ this._timer = setInterval(() => {
+ this.getRect().then(rect => {
+ // 350ms ��������������������������� ready ������
+ if (rect.height == height) {
+ this.$emit('ready', rect)
+ clearInterval(this._timer)
+ }
+ height = rect.height
+ }).catch(() => { })
+ }, 350)
+ // #endif
+ },
+
+ /**
+ * @description ������������������������
+ */
+ _hook(name) {
+ for (let i = plugins.length; i--;)
+ if (this.plugins[i][name])
+ this.plugins[i][name]()
+ },
+
+ // #ifdef APP-PLUS-NVUE
+ /**
+ * @description ������������
+ */
+ _set(nodes, append) {
+ this.$refs.web.evalJs('setContent(' + JSON.stringify(nodes) + ',' + JSON.stringify([this.bgColor, this.errorImg, this.loadingImg, this.pauseVideo, this.scrollTable, this.selectable]) + ',' + append + ')')
+ },
+
+ /**
+ * @description ��������� web-view ������
+ */
+ _onMessage(e) {
+ const message = e.detail.data[0]
+ switch (message.action) {
+ // web-view ���������������
+ case 'onJSBridgeReady':
+ this._ready = true
+ if (this.nodes)
+ this._set(this.nodes)
+ break
+ // ������ dom ������������
+ case 'onLoad':
+ this.height = message.height
+ this._hook('onLoad')
+ this.$emit('load')
+ break
+ // ������������������������
+ case 'onReady':
+ this.getRect().then(res => {
+ this.$emit('ready', res)
+ }).catch(() => { })
+ break
+ // ���������������������
+ case 'onHeightChange':
+ this.height = message.height
+ break
+ // ������������
+ case 'onImgTap':
+ this.$emit('imgTap', message.attrs)
+ if (this.previewImg)
+ uni.previewImage({
+ current: parseInt(message.attrs.i),
+ urls: this.imgList
+ })
+ break
+ // ������������
+ case 'onLinkTap':
+ const href = message.attrs.href
+ this.$emit('linkTap', message.attrs)
+ if (href) {
+ // ������������
+ if (href[0] == '#') {
+ if (this.useAnchor)
+ dom.scrollToElement(this.$refs.web, {
+ offset: message.offset
+ })
+ }
+ // ������������
+ else if (href.includes('://')) {
+ if (this.copyLink)
+ plus.runtime.openWeb(href)
+ }
+ else
+ uni.navigateTo({
+ url: href,
+ fail() {
+ wx.switchTab({
+ url: href
+ })
+ }
+ })
+ }
+ break
+ // ���������������������������
+ case 'getOffset':
+ if (typeof message.offset == 'number') {
+ dom.scrollToElement(this.$refs.web, {
+ offset: message.offset + this._navigateTo.offset
+ })
+ this._navigateTo.resolve()
+ } else
+ this._navigateTo.reject('Label not found')
+ break
+ // ������
+ case 'onClick':
+ this.$emit('tap')
+ break
+ // ������
+ case 'onError':
+ this.$emit('error', {
+ source: message.source,
+ attrs: message.attrs
+ })
+ }
+ }
+ // #endif
+ }
+}
+</script>
+
+<style>
+/* #ifndef APP-PLUS-NVUE */
+/* ��������������� */
+._root {
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+/* ������������ */
+._select {
+ user-select: text;
+}
+/* #endif */
+</style>
--
Gitblit v1.8.0