oxy-uni-ui 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/attributes.json +1 -1
  2. package/components/common/abstracts/variable.scss +396 -321
  3. package/components/common/path.ts +9 -0
  4. package/components/common/util.ts +200 -5
  5. package/components/composables/index.ts +1 -0
  6. package/components/composables/useGlobalLoading.ts +42 -0
  7. package/components/composables/useGlobalMessage.ts +48 -0
  8. package/components/composables/useGlobalToast.ts +84 -0
  9. package/components/composables/usePopover.ts +24 -20
  10. package/components/composables/useVirtualScroll.ts +13 -11
  11. package/components/composables/useWindowResize.ts +35 -0
  12. package/components/oxy-action-sheet/index.scss +24 -11
  13. package/components/oxy-action-sheet/oxy-action-sheet.vue +27 -19
  14. package/components/oxy-action-sheet/types.ts +7 -0
  15. package/components/oxy-backtop/index.scss +3 -3
  16. package/components/oxy-backtop/oxy-backtop.vue +9 -6
  17. package/components/oxy-backtop/types.ts +7 -7
  18. package/components/oxy-badge/index.scss +4 -4
  19. package/components/oxy-badge/oxy-badge.vue +3 -3
  20. package/components/oxy-badge/types.ts +2 -2
  21. package/components/oxy-button/index.scss +5 -5
  22. package/components/oxy-button/oxy-button.vue +5 -1
  23. package/components/oxy-calendar/index.scss +11 -11
  24. package/components/oxy-calendar/oxy-calendar.vue +1 -0
  25. package/components/oxy-calendar/types.ts +5 -0
  26. package/components/oxy-calendar-view/month/index.scss +4 -4
  27. package/components/oxy-calendar-view/month/types.ts +36 -0
  28. package/components/oxy-calendar-view/monthPanel/index.scss +7 -7
  29. package/components/oxy-calendar-view/monthPanel/month-panel.vue +14 -8
  30. package/components/oxy-calendar-view/year/index.scss +4 -4
  31. package/components/oxy-calendar-view/yearPanel/index.scss +4 -4
  32. package/components/oxy-calendar-view/yearPanel/year-panel.vue +21 -5
  33. package/components/oxy-card/index.scss +2 -2
  34. package/components/oxy-cell/index.scss +8 -8
  35. package/components/oxy-cell/oxy-cell.vue +15 -2
  36. package/components/oxy-cell/types.ts +4 -0
  37. package/components/oxy-checkbox/index.scss +8 -8
  38. package/components/oxy-checkbox/oxy-checkbox.vue +2 -2
  39. package/components/oxy-checkbox-group/index.scss +2 -2
  40. package/components/oxy-circle/oxy-circle.vue +10 -7
  41. package/components/oxy-circle/types.ts +5 -5
  42. package/components/oxy-col/oxy-col.vue +2 -2
  43. package/components/oxy-col-picker/index.scss +4 -4
  44. package/components/oxy-col-picker/oxy-col-picker.vue +9 -5
  45. package/components/oxy-col-picker/types.ts +12 -3
  46. package/components/oxy-collapse/index.scss +2 -2
  47. package/components/oxy-collapse-item/oxy-collapse-item.vue +3 -3
  48. package/components/oxy-corner/index.scss +32 -32
  49. package/components/oxy-corner/oxy-corner.vue +15 -3
  50. package/components/oxy-corner/types.ts +15 -1
  51. package/components/oxy-count-to/oxy-count-to.vue +3 -3
  52. package/components/oxy-curtain/index.scss +15 -15
  53. package/components/oxy-curtain/oxy-curtain.vue +4 -2
  54. package/components/oxy-curtain/types.ts +6 -1
  55. package/components/oxy-date-strip/index.scss +10 -0
  56. package/components/oxy-date-strip/oxy-date-strip.vue +198 -0
  57. package/components/oxy-date-strip/types.ts +98 -0
  58. package/components/oxy-date-strip/utils.ts +67 -0
  59. package/components/oxy-date-strip-item/index.scss +94 -0
  60. package/components/oxy-date-strip-item/oxy-date-strip-item.vue +102 -0
  61. package/components/oxy-date-strip-item/types.ts +53 -0
  62. package/components/oxy-datetime-picker/index.scss +11 -11
  63. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +4 -1
  64. package/components/oxy-datetime-picker/types.ts +10 -1
  65. package/components/oxy-drop-menu/index.scss +3 -3
  66. package/components/oxy-drop-menu/oxy-drop-menu.vue +3 -3
  67. package/components/oxy-drop-menu-item/index.scss +1 -1
  68. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +4 -3
  69. package/components/oxy-drop-menu-item/types.ts +5 -0
  70. package/components/oxy-echarts/index.scss +17 -0
  71. package/components/oxy-echarts/index.ts +1 -0
  72. package/components/oxy-echarts/oxy-echarts.vue +32 -0
  73. package/components/oxy-echarts/types.ts +18 -0
  74. package/components/oxy-fab/index.scss +8 -8
  75. package/components/oxy-fab/oxy-fab.vue +22 -3
  76. package/components/oxy-file-list/index.scss +42 -15
  77. package/components/oxy-file-list/oxy-file-list.vue +208 -34
  78. package/components/oxy-file-list/types.ts +58 -2
  79. package/components/oxy-floating-panel/oxy-floating-panel.vue +13 -9
  80. package/components/oxy-floating-panel/{type.ts → types.ts} +8 -8
  81. package/components/oxy-footer/index.scss +19 -0
  82. package/components/oxy-footer/oxy-footer.vue +78 -0
  83. package/components/oxy-footer/types.ts +17 -0
  84. package/components/oxy-form-item/types.ts +22 -1
  85. package/components/oxy-gap/oxy-gap.vue +2 -2
  86. package/components/oxy-gap/types.ts +2 -2
  87. package/components/oxy-global-loading/oxy-global-loading.vue +53 -0
  88. package/components/oxy-global-message/oxy-global-message.vue +64 -0
  89. package/components/oxy-global-toast/oxy-global-toast.vue +53 -0
  90. package/components/oxy-grid/oxy-grid.vue +1 -1
  91. package/components/oxy-grid/types.ts +1 -1
  92. package/components/oxy-grid-item/index.scss +1 -1
  93. package/components/oxy-grid-item/oxy-grid-item.vue +7 -5
  94. package/components/oxy-grid-item/types.ts +1 -1
  95. package/components/oxy-guidance/index.scss +75 -0
  96. package/components/oxy-guidance/oxy-guidance.vue +201 -0
  97. package/components/oxy-guidance/types.ts +33 -0
  98. package/components/oxy-icon/oxy-icon.vue +2 -2
  99. package/components/oxy-icon/types.ts +1 -1
  100. package/components/oxy-img/oxy-img.vue +4 -4
  101. package/components/oxy-img/types.ts +3 -3
  102. package/components/oxy-img-cropper/index.scss +12 -12
  103. package/components/oxy-img-cropper/oxy-img-cropper.vue +97 -52
  104. package/components/oxy-img-cropper/types.ts +2 -2
  105. package/components/oxy-img-lazy/index.scss +17 -0
  106. package/components/oxy-img-lazy/oxy-img-lazy.vue +332 -0
  107. package/components/oxy-img-lazy/types.ts +69 -0
  108. package/components/oxy-index-anchor/index.scss +2 -2
  109. package/components/oxy-index-anchor/oxy-index-anchor.vue +2 -2
  110. package/components/oxy-index-anchor/{type.ts → types.ts} +3 -0
  111. package/components/oxy-index-bar/index.scss +3 -3
  112. package/components/oxy-index-bar/oxy-index-bar.vue +3 -3
  113. package/components/oxy-index-bar/{type.ts → types.ts} +2 -2
  114. package/components/oxy-input/index.scss +1 -1
  115. package/components/oxy-input-number/index.scss +5 -5
  116. package/components/oxy-input-number/oxy-input-number.vue +2 -2
  117. package/components/oxy-input-number/types.ts +3 -2
  118. package/components/oxy-keyboard/index.scss +5 -5
  119. package/components/oxy-keyboard/key/index.scss +3 -3
  120. package/components/oxy-keyboard/key/index.vue +2 -2
  121. package/components/oxy-keyboard/key/types.ts +15 -0
  122. package/components/oxy-keyboard/oxy-keyboard.vue +1 -0
  123. package/components/oxy-keyboard/types.ts +5 -0
  124. package/components/oxy-link/index.scss +57 -0
  125. package/components/oxy-link/oxy-link.vue +130 -0
  126. package/components/oxy-link/types.ts +81 -0
  127. package/components/oxy-list/index.scss +7 -1
  128. package/components/oxy-list/oxy-list.vue +4 -3
  129. package/components/oxy-list/types.ts +1 -1
  130. package/components/oxy-loading/oxy-loading.vue +8 -4
  131. package/components/oxy-loading/types.ts +1 -1
  132. package/components/oxy-loadmore/index.scss +3 -3
  133. package/components/oxy-long-press-menu/index.scss +93 -0
  134. package/components/oxy-long-press-menu/oxy-long-press-menu.vue +338 -0
  135. package/components/oxy-long-press-menu/types.ts +34 -0
  136. package/components/oxy-message-box/index.scss +12 -11
  137. package/components/oxy-message-box/oxy-message-box.vue +11 -3
  138. package/components/oxy-message-box/types.ts +14 -0
  139. package/components/oxy-navbar/index.scss +2 -2
  140. package/components/oxy-navbar/oxy-navbar.vue +58 -13
  141. package/components/oxy-navbar/types.ts +8 -1
  142. package/components/oxy-navbar-capsule/types.ts +3 -0
  143. package/components/oxy-notice-bar/index.scss +3 -3
  144. package/components/oxy-notice-bar/oxy-notice-bar.vue +9 -5
  145. package/components/oxy-notice-bar/types.ts +3 -3
  146. package/components/oxy-notify/index.ts +1 -0
  147. package/components/oxy-notify/oxy-notify.vue +3 -2
  148. package/components/oxy-notify/types.ts +7 -0
  149. package/components/oxy-pagination/index.scss +1 -1
  150. package/components/oxy-password-input/oxy-password-input.vue +2 -2
  151. package/components/oxy-password-input/types.ts +1 -1
  152. package/components/oxy-picker/index.scss +45 -2
  153. package/components/oxy-picker/oxy-picker.vue +103 -14
  154. package/components/oxy-picker/types.ts +33 -1
  155. package/components/oxy-picker-view/index.scss +3 -3
  156. package/components/oxy-picker-view/oxy-picker-view.vue +4 -4
  157. package/components/oxy-popover/index.scss +9 -9
  158. package/components/oxy-popup/index.scss +2 -2
  159. package/components/oxy-popup/oxy-popup.vue +35 -2
  160. package/components/oxy-popup/types.ts +8 -1
  161. package/components/oxy-progress/index.scss +3 -3
  162. package/components/oxy-qrcode/draw.ts +398 -0
  163. package/components/oxy-qrcode/index.scss +2 -0
  164. package/components/oxy-qrcode/oxy-qrcode.vue +124 -0
  165. package/components/oxy-qrcode/qrcode.ts +936 -0
  166. package/components/oxy-qrcode/types.ts +42 -0
  167. package/components/oxy-radio/index.scss +13 -13
  168. package/components/oxy-radio/oxy-radio.vue +1 -1
  169. package/components/oxy-radio-group/index.scss +2 -2
  170. package/components/oxy-rate/types.ts +4 -4
  171. package/components/oxy-resize/index.scss +2 -2
  172. package/components/oxy-resize/oxy-resize.vue +4 -4
  173. package/components/oxy-resize/types.ts +3 -0
  174. package/components/oxy-rich-text/icon/emjio.svg +1 -0
  175. package/components/oxy-rich-text/icon/quote.svg +1 -0
  176. package/components/oxy-rich-text/icon/text.svg +1 -0
  177. package/components/oxy-rich-text/icon/title.svg +1 -0
  178. package/components/oxy-rich-text/index.scss +160 -0
  179. package/components/oxy-rich-text/mp-html/card/card.vue +122 -0
  180. package/components/oxy-rich-text/mp-html/card/index.js +7 -0
  181. package/components/oxy-rich-text/mp-html/editable/config.js +15 -0
  182. package/components/oxy-rich-text/mp-html/editable/index.js +553 -0
  183. package/components/oxy-rich-text/mp-html/emoji/index.js +203 -0
  184. package/components/oxy-rich-text/mp-html/highlight/config.js +5 -0
  185. package/components/oxy-rich-text/mp-html/highlight/index.js +96 -0
  186. package/components/oxy-rich-text/mp-html/highlight/prism.css +1 -0
  187. package/components/oxy-rich-text/mp-html/highlight/prism.min.js +7 -0
  188. package/components/oxy-rich-text/mp-html/img-cache/index.js +138 -0
  189. package/components/oxy-rich-text/mp-html/latex/index.js +80 -0
  190. package/components/oxy-rich-text/mp-html/latex/katex.css +1 -0
  191. package/components/oxy-rich-text/mp-html/latex/katex.min.js +1 -0
  192. package/components/oxy-rich-text/mp-html/markdown/index.js +50 -0
  193. package/components/oxy-rich-text/mp-html/markdown/marked.min.js +71 -0
  194. package/components/oxy-rich-text/mp-html/mp-html.d.ts +184 -0
  195. package/components/oxy-rich-text/mp-html/mp-html.vue +684 -0
  196. package/components/oxy-rich-text/mp-html/node/node.vue +1172 -0
  197. package/components/oxy-rich-text/mp-html/parser.js +1428 -0
  198. package/components/oxy-rich-text/mp-html/search/index.js +132 -0
  199. package/components/oxy-rich-text/mp-html/style/index.js +129 -0
  200. package/components/oxy-rich-text/mp-html/style/parser.js +175 -0
  201. package/components/oxy-rich-text/mp-html/template/index.js +67 -0
  202. package/components/oxy-rich-text/mp-html/txv-video/index.js +46 -0
  203. package/components/oxy-rich-text/oxy-rich-text.vue +642 -0
  204. package/components/oxy-rich-text/types.ts +76 -0
  205. package/components/oxy-row/oxy-row.vue +3 -3
  206. package/components/oxy-row/types.ts +1 -1
  207. package/components/oxy-search/index.scss +3 -3
  208. package/components/oxy-segmented/index.scss +16 -16
  209. package/components/oxy-segmented/oxy-segmented.vue +23 -3
  210. package/components/oxy-select/index.scss +331 -0
  211. package/components/oxy-select/oxy-select.vue +456 -0
  212. package/components/oxy-select/types.ts +83 -0
  213. package/components/oxy-select-picker/index.scss +7 -7
  214. package/components/oxy-select-picker/oxy-select-picker.vue +4 -0
  215. package/components/oxy-select-picker/types.ts +7 -1
  216. package/components/oxy-sidebar-item/index.scss +1 -1
  217. package/components/oxy-signature/oxy-signature.vue +18 -10
  218. package/components/oxy-signature/types.ts +106 -13
  219. package/components/oxy-skeleton/oxy-skeleton.vue +6 -6
  220. package/components/oxy-skeleton/types.ts +1 -1
  221. package/components/oxy-slider/index.scss +3 -3
  222. package/components/oxy-sort-button/index.scss +8 -8
  223. package/components/oxy-status-tip/index.scss +4 -4
  224. package/components/oxy-status-tip/oxy-status-tip.vue +5 -5
  225. package/components/oxy-status-tip/types.ts +3 -3
  226. package/components/oxy-step/index.scss +14 -14
  227. package/components/oxy-sticky/oxy-sticky.vue +6 -6
  228. package/components/oxy-stream-render/index.scss +6 -0
  229. package/components/oxy-stream-render/oxy-stream-render.vue +204 -0
  230. package/components/oxy-stream-render/types.ts +8 -0
  231. package/components/oxy-swipe-action/oxy-swipe-action.vue +27 -2
  232. package/components/oxy-swiper/oxy-swiper.vue +6 -6
  233. package/components/oxy-swiper/types.ts +5 -5
  234. package/components/oxy-switch/index.scss +8 -8
  235. package/components/oxy-switch/oxy-switch.vue +2 -2
  236. package/components/oxy-switch/types.ts +1 -1
  237. package/components/oxy-tab/index.scss +11 -1
  238. package/components/oxy-tabbar/index.scss +1 -1
  239. package/components/oxy-tabbar/oxy-tabbar.vue +39 -10
  240. package/components/oxy-table/index.scss +5 -5
  241. package/components/oxy-table/oxy-table.vue +8 -6
  242. package/components/oxy-table/types.ts +2 -2
  243. package/components/oxy-table-col/oxy-table-col.vue +3 -3
  244. package/components/oxy-table-col/types.ts +2 -2
  245. package/components/oxy-tabs/index.scss +43 -15
  246. package/components/oxy-tabs/oxy-tabs.vue +53 -19
  247. package/components/oxy-tabs/types.ts +15 -3
  248. package/components/oxy-tag/index.scss +15 -15
  249. package/components/oxy-text/index.scss +5 -1
  250. package/components/oxy-text/oxy-text.vue +76 -7
  251. package/components/oxy-text/types.ts +12 -0
  252. package/components/oxy-textarea/index.scss +6 -6
  253. package/components/oxy-toast/oxy-toast.vue +24 -8
  254. package/components/oxy-tooltip/index.scss +9 -9
  255. package/components/oxy-tree/index.scss +61 -9
  256. package/components/oxy-tree/oxy-tree.vue +102 -17
  257. package/components/oxy-tree/types.ts +23 -10
  258. package/components/oxy-upload/index.scss +21 -21
  259. package/components/oxy-upload/types.ts +2 -2
  260. package/components/oxy-verification-code/index.scss +6 -0
  261. package/components/oxy-verification-code/oxy-verification-code.vue +187 -0
  262. package/components/oxy-verification-code/types.ts +82 -0
  263. package/components/oxy-video-preview/index.scss +4 -4
  264. package/components/oxy-virtual-scroll/index.scss +4 -4
  265. package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +11 -7
  266. package/components/oxy-virtual-scroll/types.ts +14 -14
  267. package/components/oxy-voice-player/index.scss +908 -0
  268. package/components/oxy-voice-player/oxy-voice-player.vue +821 -0
  269. package/components/oxy-voice-player/types.ts +567 -0
  270. package/components/oxy-waterfall/index.scss +18 -0
  271. package/components/oxy-waterfall/oxy-waterfall.vue +218 -0
  272. package/components/oxy-waterfall/types.ts +90 -0
  273. package/components/oxy-waterfall-item/index.scss +8 -0
  274. package/components/oxy-waterfall-item/oxy-waterfall-item.vue +89 -0
  275. package/components/oxy-waterfall-item/types.ts +16 -0
  276. package/components/oxy-watermark/oxy-watermark.vue +35 -13
  277. package/components/oxy-watermark/types.ts +14 -14
  278. package/global.d.ts +9 -0
  279. package/index.ts +3 -0
  280. package/locale/lang/ar-SA.ts +3 -0
  281. package/locale/lang/en-US.ts +29 -0
  282. package/locale/lang/zh-CN.ts +29 -0
  283. package/package.json +97 -1
  284. package/tags.json +1 -1
  285. package/uni-echarts/changelog.md +2 -0
  286. package/uni-echarts/components/index.js +1 -0
  287. package/uni-echarts/components/uni-echarts/events.js +95 -0
  288. package/uni-echarts/components/uni-echarts/types.d.ts +183 -0
  289. package/uni-echarts/components/uni-echarts/types.js +1 -0
  290. package/uni-echarts/components/uni-echarts/uni-echarts.vue +530 -0
  291. package/uni-echarts/components/uni-echarts/uni-echarts.vue.d.ts +19 -0
  292. package/uni-echarts/global.d.ts +7 -0
  293. package/uni-echarts/index.d.ts +440 -0
  294. package/uni-echarts/index.js +2 -0
  295. package/uni-echarts/package.json +105 -0
  296. package/uni-echarts/shared-core.d.ts +269 -0
  297. package/uni-echarts/shared-core.js +900 -0
  298. package/web-types.json +1 -1
  299. package/components/oxy-number-keyboard/index.scss +0 -78
  300. package/components/oxy-number-keyboard/key/index.scss +0 -81
  301. package/components/oxy-number-keyboard/key/index.vue +0 -78
  302. package/components/oxy-number-keyboard/key/types.ts +0 -11
  303. package/components/oxy-number-keyboard/oxy-number-keyboard.vue +0 -151
  304. package/components/oxy-number-keyboard/types.ts +0 -83
  305. package/components/oxy-tree/components/tree-node-content.vue +0 -72
  306. package/components/oxy-tree/index.ts +0 -51
@@ -0,0 +1,684 @@
1
+ <template>
2
+ <view
3
+ id="_root"
4
+ class="mp-html"
5
+ :class="(selectable ? '_select ' : '') + '_root'"
6
+ :style="(editable ? 'min-height:400rpx;' : '') + containerStyle"
7
+ @tap="_containTap"
8
+ >
9
+ <slot v-if="!nodes[0]" />
10
+ <!-- #ifndef APP-PLUS-NVUE -->
11
+ <node v-else :childs="nodes" :opts="[lazyLoad, loadingImg, errorImg, showImgMenu, selectable, editable, placeholder, 'nodes']" name="span" />
12
+ <!-- #endif -->
13
+ <!-- #ifdef APP-PLUS-NVUE -->
14
+ <web-view
15
+ ref="web"
16
+ src="/static/app-plus/mp-html/local.html"
17
+ :style="'margin-top:' + toPx(-2) + ';height:' + toPx(height)"
18
+ @onPostMessage="_onMessage"
19
+ />
20
+ <!-- #endif -->
21
+ <view v-if="tooltip" class="_tooltip_contain" :style="'top:' + toPx(tooltip.top)">
22
+ <view class="_tooltip">
23
+ <view v-for="(item, index) in tooltip.items" v-bind:key="index" class="_tooltip_item" :data-i="index" @tap="_tooltipTap">{{ item }}</view>
24
+ </view>
25
+ </view>
26
+ <view v-if="slider" class="_slider" :style="'top:' + toPx(slider.top)">
27
+ <slider
28
+ :value="slider.value"
29
+ :min="slider.min"
30
+ :max="slider.max"
31
+ handle-size="14"
32
+ block-size="14"
33
+ show-value
34
+ activeColor="white"
35
+ style="padding: 6rpx"
36
+ @changing="_sliderChanging"
37
+ @change="_sliderChange"
38
+ />
39
+ </view>
40
+ <view v-if="color" class="_tooltip_contain" :style="'top:' + toPx(color.top)">
41
+ <view class="_tooltip" style="overflow-y: hidden">
42
+ <view
43
+ v-for="(item, index) in color.items"
44
+ v-bind:key="index"
45
+ class="_color_item"
46
+ :style="'background-color:' + item"
47
+ :data-i="index"
48
+ @tap="_colorTap"
49
+ ></view>
50
+ </view>
51
+ </view>
52
+ </view>
53
+ </template>
54
+
55
+ <script>
56
+ /**
57
+ * mp-html v2.5.2
58
+ * @description 富文本组件
59
+ * @tutorial https://github.com/jin-yufeng/mp-html
60
+ * @property {String} container-style 容器的样式
61
+ * @property {String} content 用于渲染的 html 字符串
62
+ * @property {Boolean} copy-link 是否允许外部链接被点击时自动复制
63
+ * @property {String} domain 主域名,用于拼接链接
64
+ * @property {String} error-img 图片出错时的占位图链接
65
+ * @property {Boolean} lazy-load 是否开启图片懒加载
66
+ * @property {string} loading-img 图片加载过程中的占位图链接
67
+ * @property {Boolean} pause-video 是否在播放一个视频时自动暂停其他视频
68
+ * @property {Boolean} preview-img 是否允许图片被点击时自动预览
69
+ * @property {Boolean} scroll-table 是否给每个表格添加一个滚动层使其能单独横向滚动
70
+ * @property {Boolean | String} selectable 是否开启长按复制
71
+ * @property {Boolean} set-title 是否将 title 标签的内容设置到页面标题
72
+ * @property {Boolean} show-img-menu 是否允许图片被长按时显示菜单
73
+ * @property {Object} tag-style 标签的默认样式
74
+ * @property {Boolean | Number} use-anchor 是否使用锚点链接
75
+ * @event {Function} load dom 结构加载完毕时触发
76
+ * @event {Function} ready 所有图片加载完毕时触发
77
+ * @event {Function} imgtap 图片被点击时触发
78
+ * @event {Function} linktap 链接被点击时触发
79
+ * @event {Function} play 音视频播放时触发
80
+ * @event {Function} error 媒体加载出错时触发
81
+ * @event {Function} pause 音视频暂停时触发
82
+ * @event {Function} fullscreenchange 视频全屏状态变化时触发
83
+ */
84
+ // #ifndef APP-PLUS-NVUE
85
+ import node from './node/node'
86
+ // #endif
87
+ import Parser from './parser'
88
+ import markdown from './markdown/index.js'
89
+ import highlight from './highlight/index.js'
90
+ import latex from './latex/index.js'
91
+ import style from './style/index.js'
92
+ import editable from './editable/index.js'
93
+ import { unitConvert } from '../../common/util'
94
+ const plugins = [markdown, highlight, latex, style, editable]
95
+ // #ifdef APP-PLUS-NVUE
96
+ const dom = weex.requireModule('dom')
97
+ // #endif
98
+ export default {
99
+ name: 'mp-html',
100
+ data() {
101
+ return {
102
+ tooltip: null,
103
+ slider: null,
104
+ color: null,
105
+ nodes: [],
106
+ // #ifdef APP-PLUS-NVUE
107
+ height: 3
108
+ // #endif
109
+ }
110
+ },
111
+ props: {
112
+ editable: [Boolean, String],
113
+ placeholder: String,
114
+ markdown: Boolean,
115
+ containerStyle: {
116
+ type: String,
117
+ default: ''
118
+ },
119
+ content: {
120
+ type: String,
121
+ default: ''
122
+ },
123
+ copyLink: {
124
+ type: [Boolean, String],
125
+ default: true
126
+ },
127
+ domain: String,
128
+ errorImg: {
129
+ type: String,
130
+ default: ''
131
+ },
132
+ lazyLoad: {
133
+ type: [Boolean, String],
134
+ default: false
135
+ },
136
+ loadingImg: {
137
+ type: String,
138
+ default: ''
139
+ },
140
+ pauseVideo: {
141
+ type: [Boolean, String],
142
+ default: true
143
+ },
144
+ previewImg: {
145
+ type: [Boolean, String],
146
+ default: true
147
+ },
148
+ scrollTable: [Boolean, String],
149
+ selectable: [Boolean, String],
150
+ setTitle: {
151
+ type: [Boolean, String],
152
+ default: true
153
+ },
154
+ showImgMenu: {
155
+ type: [Boolean, String],
156
+ default: true
157
+ },
158
+ tagStyle: Object,
159
+ useAnchor: [Boolean, Number]
160
+ },
161
+ // #ifdef VUE3
162
+ emits: ['load', 'ready', 'imgtap', 'linktap', 'play', 'error'],
163
+ // #endif
164
+ // #ifndef APP-PLUS-NVUE
165
+ components: {
166
+ node
167
+ },
168
+ // #endif
169
+ watch: {
170
+ editable(val) {
171
+ this.setContent(val ? this.content : this.getContent())
172
+ if (!val) this._maskTap()
173
+ },
174
+ content(content) {
175
+ this.setContent(content)
176
+ }
177
+ },
178
+ created() {
179
+ this.plugins = []
180
+ for (let i = plugins.length; i--; ) {
181
+ this.plugins.push(new plugins[i](this))
182
+ }
183
+ },
184
+ mounted() {
185
+ if ((this.content || this.editable) && !this.nodes.length) {
186
+ this.setContent(this.content)
187
+ }
188
+ },
189
+ beforeDestroy() {
190
+ this._hook('onDetached')
191
+ },
192
+ methods: {
193
+ toPx(value) {
194
+ return unitConvert(value, 0, { output: 'px' })
195
+ },
196
+ _containTap() {
197
+ if (!this._lock && !this.slider && !this.color) {
198
+ this._edit = undefined
199
+ this._maskTap()
200
+ }
201
+ },
202
+ _tooltipTap(e) {
203
+ this._tooltipcb(e.currentTarget.dataset.i)
204
+ this.$set(this, 'tooltip', null)
205
+ },
206
+ _sliderChanging(e) {
207
+ this._slideringcb(e.detail.value)
208
+ },
209
+ _sliderChange(e) {
210
+ this._slidercb(e.detail.value)
211
+ },
212
+ _colorTap(e) {
213
+ this._colorcb(e.currentTarget.dataset.i)
214
+ this.$set(this, 'color', null)
215
+ },
216
+ /**
217
+ * @description 将锚点跳转的范围限定在一个 scroll-view 内
218
+ * @param {Object} page scroll-view 所在页面的示例
219
+ * @param {String} selector scroll-view 的选择器
220
+ * @param {String} scrollTop scroll-view scroll-top 属性绑定的变量名
221
+ */
222
+ in(page, selector, scrollTop) {
223
+ // #ifndef APP-PLUS-NVUE
224
+ if (page && selector && scrollTop) {
225
+ this._in = {
226
+ page,
227
+ selector,
228
+ scrollTop
229
+ }
230
+ }
231
+ // #endif
232
+ },
233
+
234
+ /**
235
+ * @description 锚点跳转
236
+ * @param {String} id 要跳转的锚点 id
237
+ * @param {Number} offset 跳转位置的偏移量
238
+ * @returns {Promise}
239
+ */
240
+ navigateTo(id, offset) {
241
+ id = this._ids[decodeURI(id)] || id
242
+ return new Promise((resolve, reject) => {
243
+ if (!this.useAnchor) {
244
+ reject(Error('Anchor is disabled'))
245
+ return
246
+ }
247
+ offset = offset || parseInt(this.useAnchor) || 0
248
+ // #ifdef APP-PLUS-NVUE
249
+ if (!id) {
250
+ dom.scrollToElement(this.$refs.web, {
251
+ offset
252
+ })
253
+ resolve()
254
+ } else {
255
+ this._navigateTo = {
256
+ resolve,
257
+ reject,
258
+ offset
259
+ }
260
+ this.$refs.web.evalJs('uni.postMessage({data:{action:"getOffset",offset:(document.getElementById(' + id + ')||{}).offsetTop}})')
261
+ }
262
+ // #endif
263
+ // #ifndef APP-PLUS-NVUE
264
+ let deep = ' '
265
+ // #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
266
+ deep = '>>>'
267
+ // #endif
268
+ const selector = uni
269
+ .createSelectorQuery()
270
+ // #ifndef MP-ALIPAY
271
+ .in(this._in ? this._in.page : this)
272
+ // #endif
273
+ .select((this._in ? this._in.selector : '._root') + (id ? `${deep}#${id}` : ''))
274
+ .boundingClientRect()
275
+ if (this._in) {
276
+ selector.select(this._in.selector).scrollOffset().select(this._in.selector).boundingClientRect()
277
+ } else {
278
+ // 获取 scroll-view 的位置和滚动距离
279
+ selector.selectViewport().scrollOffset() // 获取窗口的滚动距离
280
+ }
281
+ selector.exec((res) => {
282
+ if (!res[0]) {
283
+ reject(Error('Label not found'))
284
+ return
285
+ }
286
+ const scrollTop = res[1].scrollTop + res[0].top - (res[2] ? res[2].top : 0) + offset
287
+ if (this._in) {
288
+ // scroll-view 跳转
289
+ this._in.page[this._in.scrollTop] = scrollTop
290
+ } else {
291
+ // 页面跳转
292
+ uni.pageScrollTo({
293
+ scrollTop,
294
+ duration: 300
295
+ })
296
+ }
297
+ resolve()
298
+ })
299
+ // #endif
300
+ })
301
+ },
302
+
303
+ /**
304
+ * @description 获取文本内容
305
+ * @return {String}
306
+ */
307
+ getText(nodes) {
308
+ let text = ''
309
+ ;(function traversal(nodes) {
310
+ for (let i = 0; i < nodes.length; i++) {
311
+ const node = nodes[i]
312
+ if (node.type === 'text') {
313
+ text += node.text.replace(/&amp;/g, '&')
314
+ } else if (node.name === 'br') {
315
+ text += '\n'
316
+ } else {
317
+ // 块级标签前后加换行
318
+ const isBlock =
319
+ node.name === 'p' ||
320
+ node.name === 'div' ||
321
+ node.name === 'tr' ||
322
+ node.name === 'li' ||
323
+ (node.name[0] === 'h' && node.name[1] > '0' && node.name[1] < '7')
324
+ if (isBlock && text && text[text.length - 1] !== '\n') {
325
+ text += '\n'
326
+ }
327
+ // 递归获取子节点的文本
328
+ if (node.children) {
329
+ traversal(node.children)
330
+ }
331
+ if (isBlock && text[text.length - 1] !== '\n') {
332
+ text += '\n'
333
+ } else if (node.name === 'td' || node.name === 'th') {
334
+ text += '\t'
335
+ }
336
+ }
337
+ }
338
+ })(nodes || this.nodes)
339
+ return text
340
+ },
341
+
342
+ /**
343
+ * @description 获取内容大小和位置
344
+ * @return {Promise}
345
+ */
346
+ getRect() {
347
+ return new Promise((resolve, reject) => {
348
+ uni
349
+ .createSelectorQuery()
350
+ // #ifndef MP-ALIPAY
351
+ .in(this)
352
+ // #endif
353
+ .select('#_root')
354
+ .boundingClientRect()
355
+ .exec((res) => (res[0] ? resolve(res[0]) : reject(Error('Root label not found'))))
356
+ })
357
+ },
358
+
359
+ /**
360
+ * @description 暂停播放媒体
361
+ */
362
+ pauseMedia() {
363
+ for (let i = (this._videos || []).length; i--; ) {
364
+ this._videos[i].pause()
365
+ }
366
+ // #ifdef APP-PLUS
367
+ const command = 'for(var e=document.getElementsByTagName("video"),i=e.length;i--;)e[i].pause()'
368
+ // #ifndef APP-PLUS-NVUE
369
+ let page = this.$parent
370
+ while (!page.$scope) page = page.$parent
371
+ page.$scope.$getAppWebview().evalJS(command)
372
+ // #endif
373
+ // #ifdef APP-PLUS-NVUE
374
+ this.$refs.web.evalJs(command)
375
+ // #endif
376
+ // #endif
377
+ },
378
+
379
+ /**
380
+ * @description 设置媒体播放速率
381
+ * @param {Number} rate 播放速率
382
+ */
383
+ setPlaybackRate(rate) {
384
+ this.playbackRate = rate
385
+ for (let i = (this._videos || []).length; i--; ) {
386
+ this._videos[i].playbackRate(rate)
387
+ }
388
+ // #ifdef APP-PLUS
389
+ const command = 'for(var e=document.getElementsByTagName("video"),i=e.length;i--;)e[i].playbackRate=' + rate
390
+ // #ifndef APP-PLUS-NVUE
391
+ let page = this.$parent
392
+ while (!page.$scope) page = page.$parent
393
+ page.$scope.$getAppWebview().evalJS(command)
394
+ // #endif
395
+ // #ifdef APP-PLUS-NVUE
396
+ this.$refs.web.evalJs(command)
397
+ // #endif
398
+ // #endif
399
+ },
400
+
401
+ /**
402
+ * @description 设置内容
403
+ * @param {String} content html 内容
404
+ * @param {Boolean} append 是否在尾部追加
405
+ */
406
+ setContent(content, append) {
407
+ if (!append || !this.imgList) {
408
+ this.imgList = []
409
+ }
410
+ const nodes = new Parser(this).parse(content)
411
+ // #ifdef APP-PLUS-NVUE
412
+ if (this._ready) {
413
+ this._set(nodes, append)
414
+ }
415
+ // #endif
416
+ this.$set(this, 'nodes', append ? (this.nodes || []).concat(nodes) : nodes)
417
+
418
+ // #ifndef APP-PLUS-NVUE
419
+ this._videos = []
420
+ this.$nextTick(() => {
421
+ this._hook('onLoad')
422
+ this.$emit('load')
423
+ })
424
+
425
+ if (this.lazyLoad || this.imgList._unloadimgs < this.imgList.length / 2) {
426
+ // 设置懒加载,每 350ms 获取高度,不变则认为加载完毕
427
+ let height = 0
428
+ const callback = (rect) => {
429
+ if (!rect || !rect.height) rect = {}
430
+ // 350ms 总高度无变化就触发 ready 事件
431
+ if (rect.height === height) {
432
+ this.$emit('ready', rect)
433
+ } else {
434
+ height = rect.height
435
+ setTimeout(() => {
436
+ this.getRect().then(callback).catch(callback)
437
+ }, 350)
438
+ }
439
+ }
440
+ this.getRect().then(callback).catch(callback)
441
+ } else {
442
+ // 未设置懒加载,等待所有图片加载完毕
443
+ if (!this.imgList._unloadimgs) {
444
+ this.getRect()
445
+ .then((rect) => {
446
+ this.$emit('ready', rect)
447
+ })
448
+ .catch(() => {
449
+ this.$emit('ready', {})
450
+ })
451
+ }
452
+ }
453
+ // #endif
454
+ },
455
+
456
+ /**
457
+ * @description 调用插件钩子函数
458
+ */
459
+ _hook(name) {
460
+ for (let i = plugins.length; i--; ) {
461
+ if (this.plugins[i][name]) {
462
+ this.plugins[i][name]()
463
+ }
464
+ }
465
+ },
466
+
467
+ // #ifdef APP-PLUS-NVUE
468
+ /**
469
+ * @description 设置内容
470
+ */
471
+ _set(nodes, append) {
472
+ this.$refs.web.evalJs(
473
+ 'setContent(' +
474
+ JSON.stringify(nodes).replace(/%22/g, '') +
475
+ ',' +
476
+ JSON.stringify([
477
+ this.containerStyle.replace(/(?:margin|padding)[^;]+/g, ''),
478
+ this.errorImg,
479
+ this.loadingImg,
480
+ this.pauseVideo,
481
+ this.scrollTable,
482
+ this.selectable
483
+ ]) +
484
+ ',' +
485
+ append +
486
+ ')'
487
+ )
488
+ },
489
+
490
+ /**
491
+ * @description 接收到 web-view 消息
492
+ */
493
+ _onMessage(e) {
494
+ const message = e.detail.data[0]
495
+ switch (message.action) {
496
+ // web-view 初始化完毕
497
+ case 'onJSBridgeReady':
498
+ this._ready = true
499
+ if (this.nodes) {
500
+ this._set(this.nodes)
501
+ }
502
+ break
503
+ // 内容 dom 加载完毕
504
+ case 'onLoad':
505
+ this.height = message.height
506
+ this._hook('onLoad')
507
+ this.$emit('load')
508
+ break
509
+ // 所有图片加载完毕
510
+ case 'onReady':
511
+ this.getRect()
512
+ .then((res) => {
513
+ this.$emit('ready', res)
514
+ })
515
+ .catch(() => {
516
+ this.$emit('ready', {})
517
+ })
518
+ break
519
+ // 总高度发生变化
520
+ case 'onHeightChange':
521
+ this.height = message.height
522
+ break
523
+ // 图片点击
524
+ case 'onImgTap':
525
+ this.$emit('imgtap', message.attrs)
526
+ if (this.previewImg) {
527
+ uni.previewImage({
528
+ current: parseInt(message.attrs.i),
529
+ urls: this.imgList
530
+ })
531
+ }
532
+ break
533
+ // 链接点击
534
+ case 'onLinkTap': {
535
+ const href = message.attrs.href
536
+ this.$emit('linktap', message.attrs)
537
+ if (href) {
538
+ // 锚点跳转
539
+ if (href[0] === '#') {
540
+ if (this.useAnchor) {
541
+ dom.scrollToElement(this.$refs.web, {
542
+ offset: message.offset
543
+ })
544
+ }
545
+ } else if (href.includes('://')) {
546
+ // 打开外链
547
+ if (this.copyLink) {
548
+ plus.runtime.openWeb(href)
549
+ }
550
+ } else {
551
+ uni.navigateTo({
552
+ url: href,
553
+ fail() {
554
+ uni.switchTab({
555
+ url: href
556
+ })
557
+ }
558
+ })
559
+ }
560
+ }
561
+ break
562
+ }
563
+ case 'onPlay':
564
+ this.$emit('play')
565
+ break
566
+ // 获取到锚点的偏移量
567
+ case 'getOffset':
568
+ if (typeof message.offset === 'number') {
569
+ dom.scrollToElement(this.$refs.web, {
570
+ offset: message.offset + this._navigateTo.offset
571
+ })
572
+ this._navigateTo.resolve()
573
+ } else {
574
+ this._navigateTo.reject(Error('Label not found'))
575
+ }
576
+ break
577
+ // 点击
578
+ case 'onClick':
579
+ this.$emit('tap')
580
+ this.$emit('click')
581
+ break
582
+ // 出错
583
+ case 'onError':
584
+ this.$emit('error', {
585
+ source: message.source,
586
+ attrs: message.attrs
587
+ })
588
+ }
589
+ }
590
+ // #endif
591
+ }
592
+ }
593
+ </script>
594
+
595
+ <style>
596
+ /* #ifndef APP-PLUS-NVUE */
597
+ /* 根节点样式 */
598
+ ._root {
599
+ padding: 2rpx 0;
600
+ overflow-x: auto;
601
+ overflow-y: hidden;
602
+ -webkit-overflow-scrolling: touch;
603
+ }
604
+
605
+ /* 长按复制 */
606
+ ._select {
607
+ user-select: text;
608
+ }
609
+ /* #endif */
610
+
611
+ /* 提示条 */
612
+ ._tooltip_contain {
613
+ position: absolute;
614
+ right: 40rpx;
615
+ left: 40rpx;
616
+ text-align: center;
617
+ }
618
+
619
+ ._tooltip {
620
+ box-sizing: border-box;
621
+ display: inline-block;
622
+ width: auto;
623
+ max-width: 100%;
624
+ height: 60rpx;
625
+ padding: 0 6rpx;
626
+ overflow-x: auto;
627
+ overflow-y: hidden;
628
+ font-size: 28rpx;
629
+ line-height: 60rpx;
630
+ white-space: nowrap;
631
+ padding-bottom: 4rpx;
632
+ border: 1px solid transparent;
633
+ }
634
+
635
+ ._tooltip::-webkit-scrollbar {
636
+ height: 8rpx;
637
+ }
638
+
639
+ ._tooltip::-webkit-scrollbar-track {
640
+ background: rgba(255, 255, 255, 0.1);
641
+ border-radius: 4rpx;
642
+ }
643
+
644
+ ._tooltip::-webkit-scrollbar-thumb {
645
+ background: rgba(255, 255, 255, 1);
646
+ border-radius: 4rpx;
647
+ }
648
+
649
+ ._tooltip::-webkit-scrollbar-thumb:hover {
650
+ background: rgba(255, 255, 255, 0.7);
651
+ }
652
+
653
+ ._tooltip_item {
654
+ display: inline-block;
655
+ width: auto;
656
+ padding: 0 2vw;
657
+ line-height: 60rpx;
658
+ background-color: black;
659
+ color: white;
660
+ }
661
+
662
+ ._color_item {
663
+ display: inline-block;
664
+ width: 36rpx;
665
+ height: 36rpx;
666
+ margin: 10rpx 2vw;
667
+ border: 1px solid #dfe2e5;
668
+ border-radius: 50%;
669
+ }
670
+
671
+ /* 图片宽度滚动条 */
672
+ ._slider {
673
+ position: absolute;
674
+ left: 40rpx;
675
+ width: 440rpx;
676
+ }
677
+
678
+ ._tooltip,
679
+ ._slider {
680
+ background-color: black;
681
+ border-radius: 6rpx;
682
+ opacity: 0.75;
683
+ }
684
+ </style>