diff --git a/apps/miniprogram/package.json b/apps/miniprogram/package.json index f8279ab..f12c2c6 100644 --- a/apps/miniprogram/package.json +++ b/apps/miniprogram/package.json @@ -34,6 +34,7 @@ "@tarojs/runtime": "4.2.0", "@tarojs/shared": "4.2.0", "@tarojs/taro": "4.2.0", + "mp-html": "^2.5.2", "react": "^18.3.0", "react-dom": "18.3.1", "zustand": "^5.0.0" diff --git a/apps/miniprogram/pnpm-lock.yaml b/apps/miniprogram/pnpm-lock.yaml index 19bcf03..b96514b 100644 --- a/apps/miniprogram/pnpm-lock.yaml +++ b/apps/miniprogram/pnpm-lock.yaml @@ -38,6 +38,9 @@ importers: '@tarojs/taro': specifier: 4.2.0 version: 4.2.0(@tarojs/components@4.2.0(@tarojs/helper@4.2.0)(@types/react@18.3.28)(html-webpack-plugin@5.6.7(webpack@5.95.0(@swc/core@1.3.96)(esbuild@0.27.7)))(postcss@8.5.12)(rollup@3.30.0)(webpack-chain@6.5.1)(webpack-dev-server@4.15.2(webpack@5.95.0(@swc/core@1.3.96)(esbuild@0.27.7)))(webpack@5.95.0(@swc/core@1.3.96)(esbuild@0.27.7)))(@tarojs/helper@4.2.0)(@tarojs/shared@4.2.0)(@types/react@18.3.28)(html-webpack-plugin@5.6.7(webpack@5.95.0(@swc/core@1.3.96)(esbuild@0.27.7)))(postcss@8.5.12)(rollup@3.30.0)(webpack-chain@6.5.1)(webpack-dev-server@4.15.2(webpack@5.95.0(@swc/core@1.3.96)(esbuild@0.27.7)))(webpack@5.95.0(@swc/core@1.3.96)(esbuild@0.27.7)) + mp-html: + specifier: ^2.5.2 + version: 2.5.2 react: specifier: ^18.3.0 version: 18.3.1 @@ -4435,6 +4438,9 @@ packages: mobile-detect@1.4.5: resolution: {integrity: sha512-yc0LhH6tItlvfLBugVUEtgawwFU2sIe+cSdmRJJCTMZ5GEJyLxNyC/NIOAOGk67Fa8GNpOttO3Xz/1bHpXFD/g==} + mp-html@2.5.2: + resolution: {integrity: sha512-45e8c32Qgux4YU4iC3qCSFsOh3y+RwPwZ+iz/vvLkDgSGWk+1zsL4WUzWWQc9w3AsAfkaD/QR0oIufIDngBmXA==} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -11011,6 +11017,8 @@ snapshots: mobile-detect@1.4.5: {} + mp-html@2.5.2: {} + ms@2.0.0: {} ms@2.1.3: {} diff --git a/apps/miniprogram/src/components/RichArticle/index.tsx b/apps/miniprogram/src/components/RichArticle/index.tsx new file mode 100644 index 0000000..95a2542 --- /dev/null +++ b/apps/miniprogram/src/components/RichArticle/index.tsx @@ -0,0 +1,32 @@ +import { memo, useMemo } from 'react'; +import { View } from '@tarojs/components'; +import { sanitizeHtml } from '@/utils/sanitize-html'; + +interface RichArticleProps { + html: string; + className?: string; +} + +function prepareHtml(raw: string): string { + return sanitizeHtml(raw); +} + +function RichArticle({ html, className }: RichArticleProps) { + const content = useMemo(() => prepareHtml(html), [html]); + + if (!content) return null; + + return ( + + + + ); +} + +export default memo(RichArticle); diff --git a/apps/miniprogram/src/native-components/mp-html/index.js b/apps/miniprogram/src/native-components/mp-html/index.js new file mode 100644 index 0000000..6ad17c0 --- /dev/null +++ b/apps/miniprogram/src/native-components/mp-html/index.js @@ -0,0 +1,8 @@ +"use strict";function e(t){"@babel/helpers - typeof";return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}function t(e,t,o){return(t=n(t))in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function n(t){var n=o(t,"string");return"symbol"==e(n)?n:n+""}function o(t,n){if("object"!=e(t)||!t)return t;var o=t[Symbol.toPrimitive];if(void 0!==o){var i=o.call(t,n||"default");if("object"!=e(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===n?String:Number)(t)}/*! + * mp-html v2.5.2 + * https://github.com/jin-yufeng/mp-html + * + * Released under the MIT license + * Author: Jin Yufeng + */ +var i=require("./parser"),r=[];Component({data:{nodes:[]},properties:{containerStyle:String,content:{type:String,value:"",observer:function(e){this.setContent(e)}},copyLink:{type:Boolean,value:!0},domain:String,errorImg:String,lazyLoad:Boolean,loadingImg:String,pauseVideo:{type:Boolean,value:!0},previewImg:{type:null,value:!0},scrollTable:Boolean,selectable:null,setTitle:{type:Boolean,value:!0},showImgMenu:{type:Boolean,value:!0},tagStyle:Object,useAnchor:null},created:function(){this.plugins=[];for(var e=r.length;e--;)this.plugins.push(new r[e](this))},detached:function(){this._hook("onDetached")},methods:{in:function(e,t,n){e&&t&&n&&(this._in={page:e,selector:t,scrollTop:n})},navigateTo:function(e,n){var o=this;return new Promise(function(i,r){if(!o.data.useAnchor)return void r(Error("Anchor is disabled"));var a=wx.createSelectorQuery().in(o._in?o._in.page:o).select((o._in?o._in.selector:"._root")+(e?"".concat(">>>","#").concat(e):"")).boundingClientRect();o._in?a.select(o._in.selector).scrollOffset().select(o._in.selector).boundingClientRect():a.selectViewport().scrollOffset(),a.exec(function(e){if(!e[0])return void r(Error("Label not found"));var a=e[1].scrollTop+e[0].top-(e[2]?e[2].top:0)+(n||parseInt(o.data.useAnchor)||0);o._in?o._in.page.setData(t({},o._in.scrollTop,a)):wx.pageScrollTo({scrollTop:a,duration:300}),i()})})},getText:function(e){var t="";return function e(n){for(var o=0;o"0"&&i.name[1]<"7";r&&t&&"\n"!==t[t.length-1]&&(t+="\n"),i.children&&e(i.children),r&&"\n"!==t[t.length-1]?t+="\n":"td"!==i.name&&"th"!==i.name||(t+="\t")}}}(e||this.data.nodes),t},getRect:function(){var e=this;return new Promise(function(t,n){wx.createSelectorQuery().in(e).select("._root").boundingClientRect().exec(function(e){return e[0]?t(e[0]):n(Error("Root label not found"))})})},pauseMedia:function(){for(var e=(this._videos||[]).length;e--;)this._videos[e].pause()},setPlaybackRate:function(e){this.playbackRate=e;for(var t=(this._videos||[]).length;t--;)this._videos[t].playbackRate(e)},setContent:function(e,t){var n=this;this.imgList&&t||(this.imgList=[]),this._videos=[];var o={},r=new i(this).parse(e);if(t)for(var a=this.data.nodes.length,s=r.length;s--;)o["nodes[".concat(a+s,"]")]=r[s];else o.nodes=r;if(this.setData(o,function(){n._hook("onLoad"),n.triggerEvent("load")}),this.data.lazyLoad||this.imgList._unloadimgs \ No newline at end of file diff --git a/apps/miniprogram/src/native-components/mp-html/index.wxss b/apps/miniprogram/src/native-components/mp-html/index.wxss new file mode 100644 index 0000000..5f74d06 --- /dev/null +++ b/apps/miniprogram/src/native-components/mp-html/index.wxss @@ -0,0 +1 @@ +._root{padding:1px 0;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch}._select{-webkit-user-select:text;user-select:text} \ No newline at end of file diff --git a/apps/miniprogram/src/native-components/mp-html/node/node.js b/apps/miniprogram/src/native-components/mp-html/node/node.js new file mode 100644 index 0000000..4257f3c --- /dev/null +++ b/apps/miniprogram/src/native-components/mp-html/node/node.js @@ -0,0 +1 @@ +"use strict";function t(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,o)}return r}function e(e){for(var o=1;o=t.length?{done:!0}:{done:!1,value:t[o++]}},e:function(t){throw t},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var n,a=!0,c=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return a=t.done,t},e:function(t){c=!0,n=t},f:function(){try{a||null==r.return||r.return()}finally{if(c)throw n}}}}function s(t,e){if(t){if("string"==typeof t)return c(t,e);var r={}.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?c(t,e):void 0}}function c(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,o=Array(e);ro.length;)0!==Object.keys(t[s-1]).length&&(r[i+"["+(s-1)+"]"]={}),s-=1;for(;so.src.length&&(i=0),ivar e={abbr:!0,b:!0,big:!0,code:!0,del:!0,em:!0,i:!0,ins:!0,label:!0,q:!0,small:!0,span:!0,strong:!0,sub:!0,sup:!0};module.exports=function(n,i){return e[n]||-1!==(i||"").indexOf("inline")};