@puresnake/snake-ui 0.0.0-stage → 0.0.2

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 (279) hide show
  1. package/LICENSE +21 -0
  2. package/changelog.md +83 -0
  3. package/components/snake-activity-list/snake-activity-list.vue +365 -0
  4. package/components/snake-activity-list/types.ts +29 -0
  5. package/components/snake-auxiliary-segmentation/snake-auxiliary-segmentation.vue +44 -0
  6. package/components/snake-auxiliary-segmentation/types.ts +5 -0
  7. package/components/snake-button/snake-button.vue +357 -0
  8. package/components/snake-button/types.ts +103 -0
  9. package/components/snake-button-sort/snake-button-sort.vue +72 -0
  10. package/components/snake-button-sort/types.ts +22 -0
  11. package/components/snake-calendar/snake-calendar.vue +998 -0
  12. package/components/snake-calendar/types.ts +189 -0
  13. package/components/snake-cell-group/snake-cell-group.vue +55 -0
  14. package/components/snake-cell-group/types.ts +19 -0
  15. package/components/snake-cell-item/snake-cell-item.vue +159 -0
  16. package/components/snake-cell-item/types.ts +66 -0
  17. package/components/snake-checkbox/snake-checkbox.vue +264 -0
  18. package/components/snake-checkbox/types.ts +70 -0
  19. package/components/snake-checkbox-group/snake-checkbox-group.vue +154 -0
  20. package/components/snake-checkbox-group/types.ts +52 -0
  21. package/components/snake-cms/blocks/v2/cms-v2-carousel.vue +87 -0
  22. package/components/snake-cms/blocks/v2/cms-v2-coupon.vue +25 -0
  23. package/components/snake-cms/blocks/v2/cms-v2-custom.vue +12 -0
  24. package/components/snake-cms/blocks/v2/cms-v2-divider.vue +33 -0
  25. package/components/snake-cms/blocks/v2/cms-v2-floatbutton.vue +28 -0
  26. package/components/snake-cms/blocks/v2/cms-v2-goods-list.vue +150 -0
  27. package/components/snake-cms/blocks/v2/cms-v2-hotzone.vue +41 -0
  28. package/components/snake-cms/blocks/v2/cms-v2-images.vue +41 -0
  29. package/components/snake-cms/blocks/v2/cms-v2-magiccube.vue +93 -0
  30. package/components/snake-cms/blocks/v2/cms-v2-notice.vue +80 -0
  31. package/components/snake-cms/blocks/v2/cms-v2-popup.vue +46 -0
  32. package/components/snake-cms/blocks/v2/cms-v2-richtext.vue +18 -0
  33. package/components/snake-cms/blocks/v2/cms-v2-search.vue +115 -0
  34. package/components/snake-cms/blocks/v2/cms-v2-video.vue +25 -0
  35. package/components/snake-cms/blocks/v2/shared.ts +84 -0
  36. package/components/snake-cms/snake-cms.vue +409 -0
  37. package/components/snake-cms/types.ts +50 -0
  38. package/components/snake-commodity-search/snake-commodity-search.vue +234 -0
  39. package/components/snake-commodity-search/types.ts +11 -0
  40. package/components/snake-config-provider/snake-config-provider.vue +61 -0
  41. package/components/snake-config-provider/types.ts +22 -0
  42. package/components/snake-count-down/snake-count-down.vue +231 -0
  43. package/components/snake-count-down/types.ts +103 -0
  44. package/components/snake-coupon/snake-coupon.vue +209 -0
  45. package/components/snake-coupon/types.ts +21 -0
  46. package/components/snake-custom-module/snake-custom-module.vue +25 -0
  47. package/components/snake-custom-module/types.ts +11 -0
  48. package/components/snake-drop-menu/snake-drop-menu.vue +123 -0
  49. package/components/snake-drop-menu/types.ts +95 -0
  50. package/components/snake-drop-menu-item/snake-drop-menu-item.vue +181 -0
  51. package/components/snake-drop-menu-item/types.ts +48 -0
  52. package/components/snake-empty/snake-empty.vue +100 -0
  53. package/components/snake-empty/types.ts +48 -0
  54. package/components/snake-filter-sorts/filter-page.vue +695 -0
  55. package/components/snake-filter-sorts/snake-filter-sorts.vue +185 -0
  56. package/components/snake-filter-sorts/types.ts +57 -0
  57. package/components/snake-floating-bubble/snake-floating-bubble.vue +157 -0
  58. package/components/snake-floating-bubble/types.ts +43 -0
  59. package/components/snake-follow/snake-follow.vue +18 -0
  60. package/components/snake-follow/types.ts +2 -0
  61. package/components/snake-form/snake-form.vue +124 -0
  62. package/components/snake-form/types.ts +96 -0
  63. package/components/snake-form-item/snake-form-item.vue +331 -0
  64. package/components/snake-form-item/types.ts +70 -0
  65. package/components/snake-goods-list/snake-goods-list.vue +792 -0
  66. package/components/snake-goods-list/types.ts +55 -0
  67. package/components/snake-graphic-navigation/snake-graphic-navigation.vue +198 -0
  68. package/components/snake-graphic-navigation/types.ts +43 -0
  69. package/components/snake-icon/icon-names.ts +222 -0
  70. package/components/snake-icon/snake-icon.vue +220 -0
  71. package/components/snake-icon/types.ts +45 -0
  72. package/components/snake-image/snake-image.vue +230 -0
  73. package/components/snake-image/types.ts +70 -0
  74. package/components/snake-images/snake-images.vue +80 -0
  75. package/components/snake-images/types.ts +5 -0
  76. package/components/snake-index-anchor/snake-index-anchor.vue +83 -0
  77. package/components/snake-index-anchor/types.ts +14 -0
  78. package/components/snake-index-list/anchor-registry.ts +80 -0
  79. package/components/snake-index-list/snake-index-list.vue +259 -0
  80. package/components/snake-index-list/types.ts +115 -0
  81. package/components/snake-index-list-panel/snake-index-list-panel.vue +277 -0
  82. package/components/snake-index-list-panel/types.ts +10 -0
  83. package/components/snake-input/snake-input.vue +225 -0
  84. package/components/snake-input/types.ts +99 -0
  85. package/components/snake-jump-applet/snake-jump-applet.vue +99 -0
  86. package/components/snake-jump-applet/types.ts +17 -0
  87. package/components/snake-line/snake-line.vue +42 -0
  88. package/components/snake-line/types.ts +30 -0
  89. package/components/snake-line-progress/snake-line-progress.vue +105 -0
  90. package/components/snake-line-progress/types.ts +26 -0
  91. package/components/snake-link/snake-link.vue +74 -0
  92. package/components/snake-link/types.ts +30 -0
  93. package/components/snake-list-switching/components/tree-select/index.vue +156 -0
  94. package/components/snake-list-switching/snake-list-switching.vue +1285 -0
  95. package/components/snake-list-switching/types.ts +11 -0
  96. package/components/snake-loading/snake-loading.vue +241 -0
  97. package/components/snake-loading/types.ts +34 -0
  98. package/components/snake-loadmore/snake-loadmore.vue +103 -0
  99. package/components/snake-loadmore/types.ts +56 -0
  100. package/components/snake-magic-cube/snake-magic-cube.vue +622 -0
  101. package/components/snake-magic-cube/types.ts +5 -0
  102. package/components/snake-modal/snake-modal.vue +434 -0
  103. package/components/snake-modal/types.ts +71 -0
  104. package/components/snake-navbar/snake-navbar.vue +194 -0
  105. package/components/snake-navbar/types.ts +54 -0
  106. package/components/snake-no-network/snake-no-network.vue +125 -0
  107. package/components/snake-no-network/types.ts +27 -0
  108. package/components/snake-notice/snake-notice.vue +44 -0
  109. package/components/snake-notice/types.ts +5 -0
  110. package/components/snake-notice-bar/snake-notice-bar.vue +336 -0
  111. package/components/snake-notice-bar/types.ts +82 -0
  112. package/components/snake-overlay/snake-overlay.vue +73 -0
  113. package/components/snake-overlay/types.ts +35 -0
  114. package/components/snake-page-popup/snake-page-popup.vue +146 -0
  115. package/components/snake-page-popup/types.ts +28 -0
  116. package/components/snake-parse/audio/audio.vue +286 -0
  117. package/components/snake-parse/audio/context.js +11 -0
  118. package/components/snake-parse/audio/index.js +34 -0
  119. package/components/snake-parse/node/node.vue +830 -0
  120. package/components/snake-parse/parser.js +1480 -0
  121. package/components/snake-parse/snake-parse.vue +548 -0
  122. package/components/snake-parse/static/app-plus/snake-parse/js/handler.js +109 -0
  123. package/components/snake-parse/static/app-plus/snake-parse/js/uni.webview.js +0 -0
  124. package/components/snake-parse/static/app-plus/snake-parse/js/uni.webview.min.js +1 -0
  125. package/components/snake-parse/static/app-plus/snake-parse/local.html +3 -0
  126. package/components/snake-parse/style/index.js +132 -0
  127. package/components/snake-parse/style/parser.js +175 -0
  128. package/components/snake-parse/types.ts +49 -0
  129. package/components/snake-picture-ads/snake-picture-ads.vue +292 -0
  130. package/components/snake-picture-ads/types.ts +5 -0
  131. package/components/snake-popup/snake-popup.vue +348 -0
  132. package/components/snake-popup/types.ts +88 -0
  133. package/components/snake-qr-code/qrcode.ts +1214 -0
  134. package/components/snake-qr-code/snake-qr-code.vue +408 -0
  135. package/components/snake-qr-code/types.ts +78 -0
  136. package/components/snake-radio/snake-radio.vue +271 -0
  137. package/components/snake-radio/types.ts +64 -0
  138. package/components/snake-radio-group/snake-radio-group.vue +98 -0
  139. package/components/snake-radio-group/types.ts +48 -0
  140. package/components/snake-read-more/snake-read-more.vue +140 -0
  141. package/components/snake-read-more/types.ts +53 -0
  142. package/components/snake-rich-text/snake-rich-text.vue +24 -0
  143. package/components/snake-rich-text/types.ts +5 -0
  144. package/components/snake-root-portal/snake-root-portal.vue +92 -0
  145. package/components/snake-root-portal/types.ts +9 -0
  146. package/components/snake-search/snake-search.vue +202 -0
  147. package/components/snake-search/types.ts +84 -0
  148. package/components/snake-select/snake-select.vue +371 -0
  149. package/components/snake-select/types.ts +75 -0
  150. package/components/snake-skeleton/snake-skeleton.vue +104 -0
  151. package/components/snake-skeleton/types.ts +32 -0
  152. package/components/snake-skeleton-item/snake-skeleton-item.vue +90 -0
  153. package/components/snake-skeleton-item/types.ts +30 -0
  154. package/components/snake-slider/snake-slider.vue +249 -0
  155. package/components/snake-slider/types.ts +59 -0
  156. package/components/snake-sticky/snake-sticky.vue +178 -0
  157. package/components/snake-sticky/types.ts +48 -0
  158. package/components/snake-subsection/snake-subsection.vue +188 -0
  159. package/components/snake-subsection/types.ts +54 -0
  160. package/components/snake-swiper/snake-swiper.vue +229 -0
  161. package/components/snake-swiper/types.ts +79 -0
  162. package/components/snake-switch/snake-switch.vue +100 -0
  163. package/components/snake-switch/types.ts +41 -0
  164. package/components/snake-tabbar/snake-tabbar.vue +306 -0
  165. package/components/snake-tabbar/types.ts +93 -0
  166. package/components/snake-tabs/snake-tabs.vue +305 -0
  167. package/components/snake-tabs/types.ts +79 -0
  168. package/components/snake-text/snake-text.vue +292 -0
  169. package/components/snake-text/types.ts +100 -0
  170. package/components/snake-textarea/snake-textarea.vue +171 -0
  171. package/components/snake-textarea/types.ts +79 -0
  172. package/components/snake-toast/snake-toast.vue +330 -0
  173. package/components/snake-toast/types.ts +55 -0
  174. package/components/snake-tooltip/position.ts +33 -0
  175. package/components/snake-tooltip/snake-tooltip.vue +339 -0
  176. package/components/snake-tooltip/types.ts +80 -0
  177. package/components/snake-transition/snake-transition.vue +315 -0
  178. package/components/snake-transition/types.ts +65 -0
  179. package/components/snake-upload/snake-upload.vue +1801 -0
  180. package/components/snake-upload/types.ts +256 -0
  181. package/components/snake-videos/snake-videos.vue +122 -0
  182. package/components/snake-videos/types.ts +7 -0
  183. package/iconfont.css +881 -0
  184. package/index.d.ts +7 -0
  185. package/index.scss +26 -0
  186. package/index.ts +94 -0
  187. package/libs/cms/blocks.ts +103 -0
  188. package/libs/cms/config.ts +25 -0
  189. package/libs/cms/index.ts +7 -0
  190. package/libs/cms/normalize.ts +135 -0
  191. package/libs/cms/resolve.ts +12 -0
  192. package/libs/cms/types.ts +164 -0
  193. package/libs/cms/use-commerce.ts +385 -0
  194. package/libs/cms/v2.ts +193 -0
  195. package/libs/config/index.ts +4 -0
  196. package/libs/config/modal.ts +93 -0
  197. package/libs/config/state.ts +33 -0
  198. package/libs/config/theme.ts +351 -0
  199. package/libs/config/toast.ts +71 -0
  200. package/libs/config/types.ts +135 -0
  201. package/libs/config/zIndex.ts +44 -0
  202. package/libs/css/color.scss +105 -0
  203. package/libs/css/common.scss +171 -0
  204. package/libs/css/style.h5.scss +7 -0
  205. package/libs/css/style.mp.scss +7 -0
  206. package/libs/css/style.theme.scss +70 -0
  207. package/libs/css/style.vue.scss +140 -0
  208. package/libs/form/async-validator.min.d.ts +75 -0
  209. package/libs/form/async-validator.min.js +3 -0
  210. package/libs/form/index.ts +3 -0
  211. package/libs/form/path.ts +40 -0
  212. package/libs/form/types.ts +51 -0
  213. package/libs/form/validate.ts +149 -0
  214. package/libs/foundation.ts +96 -0
  215. package/libs/function/$parent.ts +33 -0
  216. package/libs/function/clipboard.ts +13 -0
  217. package/libs/function/color.ts +55 -0
  218. package/libs/function/debounce.ts +34 -0
  219. package/libs/function/deepClone.ts +30 -0
  220. package/libs/function/deepMerge.ts +25 -0
  221. package/libs/function/emitter.ts +30 -0
  222. package/libs/function/format.ts +27 -0
  223. package/libs/function/getParent.ts +53 -0
  224. package/libs/function/getRect.ts +29 -0
  225. package/libs/function/guid.ts +11 -0
  226. package/libs/function/index.ts +31 -0
  227. package/libs/function/queryParams.ts +73 -0
  228. package/libs/function/random.ts +6 -0
  229. package/libs/function/randomArray.ts +14 -0
  230. package/libs/function/route.ts +155 -0
  231. package/libs/function/sleep.ts +7 -0
  232. package/libs/function/style.ts +58 -0
  233. package/libs/function/styleUtils.ts +83 -0
  234. package/libs/function/system.ts +14 -0
  235. package/libs/function/test.ts +202 -0
  236. package/libs/function/throttle.ts +36 -0
  237. package/libs/function/timeFormat.ts +27 -0
  238. package/libs/function/timeFrom.ts +27 -0
  239. package/libs/function/toast.ts +10 -0
  240. package/libs/function/trim.ts +11 -0
  241. package/libs/function/type2icon.ts +11 -0
  242. package/libs/function/unit.ts +45 -0
  243. package/libs/hooks/index.ts +11 -0
  244. package/libs/hooks/useChildren.ts +125 -0
  245. package/libs/hooks/useColor.ts +5 -0
  246. package/libs/hooks/useDebounce.ts +5 -0
  247. package/libs/hooks/useLocale.ts +13 -0
  248. package/libs/hooks/useModal.ts +131 -0
  249. package/libs/hooks/useParent.ts +62 -0
  250. package/libs/hooks/useRect.ts +44 -0
  251. package/libs/hooks/useRouter.ts +5 -0
  252. package/libs/hooks/useTheme.ts +31 -0
  253. package/libs/hooks/useThrottle.ts +5 -0
  254. package/libs/hooks/useToast.ts +116 -0
  255. package/libs/index.ts +18 -0
  256. package/libs/request/auto-http.ts +1 -0
  257. package/libs/request/index.ts +343 -0
  258. package/libs/runtime/accessors.ts +55 -0
  259. package/libs/runtime/context.ts +40 -0
  260. package/libs/runtime/index.ts +18 -0
  261. package/libs/runtime/types.ts +49 -0
  262. package/libs/util/calendar.ts +6 -0
  263. package/locale/index.ts +130 -0
  264. package/locale/lang/en-US.ts +67 -0
  265. package/locale/lang/zh-CN.ts +67 -0
  266. package/package.json +134 -5
  267. package/plugins/index.ts +1 -0
  268. package/plugins/root/README.md +86 -0
  269. package/plugins/root/index.ts +123 -0
  270. package/plugins/root/page.ts +77 -0
  271. package/plugins/root/root.ts +53 -0
  272. package/plugins/root/utils.ts +137 -0
  273. package/readme.md +79 -0
  274. package/theme.scss +118 -0
  275. package/types/components.d.ts +236 -0
  276. package/types/global.d.ts +21 -0
  277. package/types/index.d.ts +6 -0
  278. package/types/uni-app.d.ts +16 -0
  279. package/README.md +0 -3
@@ -0,0 +1,830 @@
1
+ <template>
2
+ <view :id="attrs.id" :class="'_block _' + name + ' ' + attrs.class" :style="attrs.style">
3
+ <block v-for="(n, i) in nodes" v-bind:key="i">
4
+ <!-- 图片 -->
5
+ <!-- 占位图 -->
6
+ <image
7
+ v-if="n.name === 'img' && !n.t && ((opts[1] && !ctrl[i]) || ctrl[i] < 0)"
8
+ class="_img"
9
+ :style="n.attrs.style"
10
+ :src="ctrl[i] < 0 ? opts[2] : opts[1]"
11
+ mode="widthFix"
12
+ />
13
+ <!-- 显示图片 -->
14
+ <!-- #ifdef H5 || (APP-PLUS && VUE2) -->
15
+ <img
16
+ v-if="n.name === 'img'"
17
+ :id="n.attrs.id"
18
+ :class="'_img ' + n.attrs.class"
19
+ :style="(ctrl[i] === -1 ? 'display:none;' : '') + n.attrs.style"
20
+ :src="n.attrs.src || (ctrl.load ? n.attrs['data-src'] : '')"
21
+ :data-i="i"
22
+ @load="imgLoad"
23
+ @error="mediaError"
24
+ @tap.stop="imgTap"
25
+ @longpress="imgLongTap"
26
+ />
27
+ <!-- #endif -->
28
+ <!-- #ifndef H5 || (APP-PLUS && VUE2) -->
29
+ <!-- 表格中的图片,使用 rich-text 防止大小不正确 -->
30
+ <rich-text
31
+ v-if="n.name === 'img' && n.t"
32
+ :style="'display:' + n.t"
33
+ :nodes="[{ attrs: { style: n.attrs.style || '', src: n.attrs.src }, name: 'img' }]"
34
+ :data-i="i"
35
+ @tap.stop="imgTap"
36
+ />
37
+ <!-- #endif -->
38
+ <!-- #ifdef APP-HARMONY -->
39
+ <image
40
+ v-else-if="n.name === 'img'"
41
+ :id="n.attrs.id"
42
+ :class="'_img ' + n.attrs.class"
43
+ :style="(ctrl[i] === -1 ? 'display:none;' : '') + 'width:' + ctrl[i] + 'px;' + n.attrs.style"
44
+ :src="n.attrs.src || (ctrl.load ? n.attrs['data-src'] : '')"
45
+ :mode="!n.h ? 'widthFix' : !n.w ? 'heightFix' : n.m || 'scaleToFill'"
46
+ :data-i="i"
47
+ @load="imgLoad"
48
+ @error="mediaError"
49
+ @tap.stop="imgTap"
50
+ @longpress="imgLongTap"
51
+ />
52
+ <!-- #endif -->
53
+ <!-- #ifndef H5 || APP-PLUS || MP-KUAISHOU -->
54
+ <image
55
+ v-else-if="n.name === 'img'"
56
+ :id="n.attrs.id"
57
+ :class="'_img ' + n.attrs.class"
58
+ :style="
59
+ (ctrl[i] === -1 ? 'display:none;' : '') +
60
+ 'width:' +
61
+ (ctrl[i] || 1) +
62
+ 'px;height:1px;' +
63
+ n.attrs.style
64
+ "
65
+ :src="n.attrs.src"
66
+ :mode="!n.h ? 'widthFix' : !n.w ? 'heightFix' : n.m || 'scaleToFill'"
67
+ :lazy-load="opts[0]"
68
+ :webp="n.webp"
69
+ :show-menu-by-longpress="opts[3] && !n.attrs.ignore"
70
+ :image-menu-prevent="!opts[3] || n.attrs.ignore"
71
+ :data-i="i"
72
+ @load="imgLoad"
73
+ @error="mediaError"
74
+ @tap.stop="imgTap"
75
+ @longpress="imgLongTap"
76
+ />
77
+ <!-- #endif -->
78
+ <!-- #ifdef MP-KUAISHOU -->
79
+ <image
80
+ v-else-if="n.name === 'img'"
81
+ :id="n.attrs.id"
82
+ :class="'_img ' + n.attrs.class"
83
+ :style="(ctrl[i] === -1 ? 'display:none;' : '') + n.attrs.style"
84
+ :src="n.attrs.src"
85
+ :lazy-load="opts[0]"
86
+ :data-i="i"
87
+ @load="imgLoad"
88
+ @error="mediaError"
89
+ @tap.stop="imgTap"
90
+ ></image>
91
+ <!-- #endif -->
92
+ <!-- #ifdef APP-PLUS && VUE3 -->
93
+ <image
94
+ v-else-if="n.name === 'img'"
95
+ :id="n.attrs.id"
96
+ :class="'_img ' + n.attrs.class"
97
+ :style="(ctrl[i] === -1 ? 'display:none;' : '') + 'width:' + (ctrl[i] || 1) + 'px;' + n.attrs.style"
98
+ :src="n.attrs.src || (ctrl.load ? n.attrs['data-src'] : '')"
99
+ :mode="!n.h ? 'widthFix' : !n.w ? 'heightFix' : n.m || ''"
100
+ :data-i="i"
101
+ @load="imgLoad"
102
+ @error="mediaError"
103
+ @tap.stop="imgTap"
104
+ @longpress="imgLongTap"
105
+ />
106
+ <!-- #endif -->
107
+ <!-- 文本 -->
108
+ <!-- #ifdef MP-WEIXIN -->
109
+ <text v-else-if="n.text" :user-select="opts[4] == 'force' && isiOS" decode>{{ n.text }}</text>
110
+ <!-- #endif -->
111
+ <!-- #ifndef MP-WEIXIN || MP-BAIDU || MP-ALIPAY || MP-TOUTIAO -->
112
+ <text v-else-if="n.text" decode>{{ n.text }}</text>
113
+ <!-- #endif -->
114
+ <text v-else-if="n.name === 'br'">{{ '\n' }}</text>
115
+ <!-- 链接 -->
116
+ <view
117
+ v-else-if="n.name === 'a'"
118
+ :id="n.attrs.id"
119
+ :class="(n.attrs.href ? '_a ' : '') + n.attrs.class"
120
+ hover-class="_hover"
121
+ :style="'display:inline;' + n.attrs.style"
122
+ :data-i="i"
123
+ @tap.stop="linkTap"
124
+ >
125
+ <node name="span" :childs="n.children" :opts="opts" style="display: inherit" />
126
+ </view>
127
+ <!-- 视频 -->
128
+ <!-- #ifdef APP-PLUS -->
129
+ <view
130
+ v-else-if="n.html"
131
+ :id="n.attrs.id"
132
+ :class="'_video ' + n.attrs.class"
133
+ :style="n.attrs.style"
134
+ v-html="n.html"
135
+ :data-i="i"
136
+ @vplay.stop="play"
137
+ />
138
+ <!-- #endif -->
139
+ <!-- #ifndef APP-PLUS -->
140
+ <video
141
+ v-else-if="n.name === 'video'"
142
+ :id="n.attrs.id"
143
+ :class="n.attrs.class"
144
+ :style="n.attrs.style"
145
+ :autoplay="n.attrs.autoplay"
146
+ :controls="n.attrs.controls"
147
+ :loop="n.attrs.loop"
148
+ :muted="n.attrs.muted"
149
+ :object-fit="n.attrs['object-fit']"
150
+ :poster="n.attrs.poster"
151
+ :src="n.src[ctrl[i] || 0]"
152
+ :data-i="i"
153
+ @play="play"
154
+ @pause="mediaEvent"
155
+ @fullscreenchange="mediaEvent"
156
+ @error="mediaError"
157
+ />
158
+ <!-- #endif -->
159
+ <!-- #ifdef H5 || APP-PLUS -->
160
+ <iframe
161
+ v-else-if="n.name === 'iframe'"
162
+ :style="n.attrs.style"
163
+ :allowfullscreen="n.attrs.allowfullscreen"
164
+ :frameborder="n.attrs.frameborder"
165
+ :src="n.attrs.src"
166
+ />
167
+ <embed v-else-if="n.name === 'embed'" :style="n.attrs.style" :src="n.attrs.src" />
168
+ <!-- #endif -->
169
+ <!-- #ifndef MP-TOUTIAO || ((H5 || APP-PLUS) && VUE3) -->
170
+ <!-- 音频 -->
171
+ <audio
172
+ v-else-if="n.name === 'audio'"
173
+ :id="n.attrs.id"
174
+ :class="n.attrs.class"
175
+ :style="n.attrs.style"
176
+ :author="n.attrs.author"
177
+ :controls="n.attrs.controls"
178
+ :loop="n.attrs.loop"
179
+ :name="n.attrs.name"
180
+ :poster="n.attrs.poster"
181
+ :src="n.src[ctrl[i] || 0]"
182
+ :data-i="i"
183
+ @play="play"
184
+ @pause="mediaEvent"
185
+ @error="mediaError"
186
+ />
187
+ <!-- #endif -->
188
+ <view
189
+ v-else-if="(n.name === 'table' && n.c) || n.name === 'li'"
190
+ :id="n.attrs.id"
191
+ :class="'_' + n.name + ' ' + n.attrs.class"
192
+ :style="n.attrs.style"
193
+ >
194
+ <node v-if="n.name === 'li'" :childs="n.children" :opts="opts" />
195
+ <view
196
+ v-else
197
+ v-for="(tbody, x) in n.children"
198
+ v-bind:key="x"
199
+ :class="'_' + tbody.name + ' ' + tbody.attrs.class"
200
+ :style="tbody.attrs.style"
201
+ >
202
+ <node v-if="tbody.name === 'td' || tbody.name === 'th'" :childs="tbody.children" :opts="opts" />
203
+ <block v-else v-for="(tr, y) in tbody.children" v-bind:key="y">
204
+ <view
205
+ v-if="tr.name === 'td' || tr.name === 'th'"
206
+ :class="'_' + tr.name + ' ' + tr.attrs.class"
207
+ :style="tr.attrs.style"
208
+ >
209
+ <node :childs="tr.children" :opts="opts" />
210
+ </view>
211
+ <view v-else :class="'_' + tr.name + ' ' + tr.attrs.class" :style="tr.attrs.style">
212
+ <view
213
+ v-for="(td, z) in tr.children"
214
+ v-bind:key="z"
215
+ :class="'_' + td.name + ' ' + td.attrs.class"
216
+ :style="td.attrs.style"
217
+ >
218
+ <node :childs="td.children" :opts="opts" />
219
+ </view>
220
+ </view>
221
+ </block>
222
+ </view>
223
+ </view>
224
+
225
+ <!-- 富文本 -->
226
+ <!-- #ifdef H5 || ((MP-WEIXIN || MP-QQ || APP-PLUS || MP-360) && VUE2) -->
227
+ <rich-text
228
+ v-else-if="!n.c && !handler.isInline(n.name, n.attrs.style)"
229
+ :id="n.attrs.id"
230
+ :style="n.f"
231
+ :user-select="opts[4]"
232
+ :nodes="[n]"
233
+ />
234
+ <!-- #endif -->
235
+ <!-- #ifndef H5 || ((MP-WEIXIN || MP-QQ || APP-PLUS || MP-360) && VUE2) -->
236
+ <rich-text
237
+ v-else-if="!n.c"
238
+ :id="n.attrs.id"
239
+ :style="'display:inline;' + n.f"
240
+ :preview="false"
241
+ :selectable="opts[4]"
242
+ :user-select="opts[4]"
243
+ :nodes="[n]"
244
+ />
245
+ <!-- #endif -->
246
+ <!-- 继续递归 -->
247
+ <view
248
+ v-else-if="n.c === 2"
249
+ :id="n.attrs.id"
250
+ :class="'_block _' + n.name + ' ' + n.attrs.class"
251
+ :style="n.f + ';' + n.attrs.style"
252
+ >
253
+ <node
254
+ v-for="(n2, j) in n.children"
255
+ v-bind:key="j"
256
+ :style="n2.f"
257
+ :name="n2.name"
258
+ :attrs="n2.attrs"
259
+ :childs="n2.children"
260
+ :opts="opts"
261
+ />
262
+ </view>
263
+ <node v-else :style="n.f" :name="n.name" :attrs="n.attrs" :childs="n.children" :opts="opts" />
264
+ </block>
265
+ </view>
266
+ </template>
267
+ <script module="handler" lang="wxs">
268
+ // 行内标签列表
269
+ var inlineTags = {
270
+ abbr: true,
271
+ b: true,
272
+ big: true,
273
+ code: true,
274
+ del: true,
275
+ em: true,
276
+ i: true,
277
+ ins: true,
278
+ label: true,
279
+ q: true,
280
+ small: true,
281
+ span: true,
282
+ strong: true,
283
+ sub: true,
284
+ sup: true
285
+ };
286
+ /**
287
+ * @description 判断是否为行内标签
288
+ */
289
+ module.exports = {
290
+ isInline: function (tagName, style) {
291
+ return inlineTags[tagName] || (style || '').indexOf('display:inline') !== -1;
292
+ }
293
+ };
294
+ </script>
295
+ <script>
296
+ import node from './node';
297
+ export default {
298
+ name: 'node',
299
+ options: {
300
+ // #ifdef MP-WEIXIN
301
+ virtualHost: true,
302
+ // #endif
303
+ // #ifdef MP-TOUTIAO
304
+ addGlobalClass: false
305
+ // #endif
306
+ },
307
+ data() {
308
+ return {
309
+ root: null,
310
+ ctrl: {},
311
+ nodes: [],
312
+ // #ifdef MP-WEIXIN
313
+ isiOS: (uni.canIUse('getDeviceInfo') ? uni.getDeviceInfo() : uni.getSystemInfoSync()).system.includes('iOS')
314
+ // #endif
315
+ };
316
+ },
317
+ props: {
318
+ name: String,
319
+ attrs: {
320
+ type: Object,
321
+ default() {
322
+ return {};
323
+ }
324
+ },
325
+ childs: Array,
326
+ opts: Array
327
+ },
328
+ inject: {
329
+ snakeParseRoot: {
330
+ default: null
331
+ }
332
+ },
333
+ watch: {
334
+ childs: {
335
+ handler(nodes) {
336
+ // 列表缩短会刷新整个列表,因此进行空填充
337
+ while (this.nodes.length > nodes.length) {
338
+ nodes.push({});
339
+ }
340
+ this.nodes = nodes;
341
+ },
342
+ immediate: true
343
+ }
344
+ },
345
+ components: {
346
+ // #ifndef ((H5 || APP-PLUS) && VUE3) || APP-HARMONY
347
+ node
348
+ // #endif
349
+ },
350
+ created() {
351
+ // The renderer is recursive, so $parent may be another node (or a
352
+ // framework wrapper in Vue 3). Receive the actual parse component
353
+ // explicitly instead of walking the component tree by name.
354
+ this.root = this.snakeParseRoot;
355
+ },
356
+ mounted() {
357
+ // #ifdef H5 || APP-PLUS
358
+ if (this.opts[0]) {
359
+ let i;
360
+ for (i = this.childs.length; i--;) {
361
+ if (this.childs[i].name === 'img') break;
362
+ }
363
+ if (i !== -1) {
364
+ this.observer = uni.createIntersectionObserver(this).relativeToViewport({
365
+ top: 500,
366
+ bottom: 500
367
+ });
368
+ this.observer.observe('._img', res => {
369
+ if (res.intersectionRatio) {
370
+ this.ctrl.load = 1;
371
+ this.observer.disconnect();
372
+ }
373
+ });
374
+ }
375
+ }
376
+ // #endif
377
+ },
378
+ beforeDestroy() {
379
+ // #ifdef H5 || APP-PLUS
380
+ if (this.observer) {
381
+ this.observer.disconnect();
382
+ }
383
+ // #endif
384
+ },
385
+ methods: {
386
+ // #ifdef MP-WEIXIN
387
+ toJSON() {
388
+ return this;
389
+ },
390
+ // #endif
391
+ /**
392
+ * @description 播放视频事件
393
+ * @param {Event} e
394
+ */
395
+ play(e) {
396
+ const i = e.currentTarget.dataset.i;
397
+ const node = this.childs[i];
398
+ this.root.$emit('play', {
399
+ source: node.name,
400
+ attrs: {
401
+ ...node.attrs,
402
+ src: node.src[this.ctrl[i] || 0]
403
+ }
404
+ });
405
+ // #ifndef APP-PLUS
406
+ if (this.root.pauseVideo) {
407
+ let flag = false;
408
+ const id = e.target.id;
409
+ for (let i = this.root._videos.length; i--;) {
410
+ if (this.root._videos[i].id === id) {
411
+ flag = true;
412
+ } else {
413
+ this.root._videos[i].pause(); // 自动暂停其他视频
414
+ }
415
+ }
416
+ // 将自己加入列表
417
+ if (!flag) {
418
+ const ctx = uni.createVideoContext(
419
+ id,
420
+ // #ifndef MP-BAIDU
421
+ this
422
+ // #endif
423
+ );
424
+ ctx.id = id;
425
+ if (this.root.playbackRate) {
426
+ ctx.playbackRate(this.root.playbackRate);
427
+ }
428
+ this.root._videos.push(ctx);
429
+ }
430
+ }
431
+ // #endif
432
+ },
433
+ /**
434
+ * @description 音视频其他事件
435
+ * @param {Event} e
436
+ */
437
+ mediaEvent(e) {
438
+ const i = e.currentTarget.dataset.i;
439
+ const node = this.childs[i];
440
+ this.root.$emit(e.type, {
441
+ ...e.detail,
442
+ source: node.name,
443
+ attrs: {
444
+ ...node.attrs,
445
+ src: node.src[this.ctrl[i] || 0]
446
+ }
447
+ });
448
+ },
449
+
450
+ /**
451
+ * @description 图片点击事件
452
+ * @param {Event} e
453
+ */
454
+ imgTap(e) {
455
+ const node = this.childs[e.currentTarget.dataset.i];
456
+ if (node.a) {
457
+ this.linkTap(node.a);
458
+ return;
459
+ }
460
+ if (node.attrs.ignore) return;
461
+ // #ifdef H5 || APP-PLUS
462
+ node.attrs.src = node.attrs.src || node.attrs['data-src'];
463
+ // #endif
464
+ // #ifndef APP-HARMONY
465
+ this.root.$emit('imgtap', node.attrs);
466
+ // #endif
467
+ // #ifdef APP-HARMONY
468
+ this.root.$emit('imgtap', {
469
+ ...node.attrs
470
+ });
471
+ // #endif
472
+ // 自动预览图片
473
+ if (this.root.previewImg) {
474
+ uni.previewImage({
475
+ // #ifdef MP-WEIXIN
476
+ showmenu: this.root.showImgMenu,
477
+ // #endif
478
+ // #ifdef MP-ALIPAY
479
+ enablesavephoto: this.root.showImgMenu,
480
+ enableShowPhotoDownload: this.root.showImgMenu,
481
+ // #endif
482
+ current: parseInt(node.attrs.i),
483
+ urls: this.root.imgList
484
+ });
485
+ }
486
+ },
487
+
488
+ /**
489
+ * @description 图片长按
490
+ */
491
+ imgLongTap(e) {
492
+ // #ifdef APP-PLUS
493
+ const attrs = this.childs[e.currentTarget.dataset.i].attrs;
494
+ if (this.opts[3] && !attrs.ignore) {
495
+ uni.showActionSheet({
496
+ itemList: ['保存图片'],
497
+ success: () => {
498
+ const save = path => {
499
+ uni.saveImageToPhotosAlbum({
500
+ filePath: path,
501
+ success() {
502
+ uni.showToast({
503
+ title: '保存成功'
504
+ });
505
+ }
506
+ });
507
+ };
508
+ if (this.root.imgList[attrs.i].startsWith('http')) {
509
+ uni.downloadFile({
510
+ url: this.root.imgList[attrs.i],
511
+ success: res => save(res.tempFilePath)
512
+ });
513
+ } else {
514
+ save(this.root.imgList[attrs.i]);
515
+ }
516
+ }
517
+ });
518
+ }
519
+ // #endif
520
+ },
521
+
522
+ /**
523
+ * @description 图片加载完成事件
524
+ * @param {Event} e
525
+ */
526
+ imgLoad(e) {
527
+ const i = e.currentTarget.dataset.i;
528
+ let hasOriginalWidth = false;
529
+ /* #ifndef H5 || (APP-PLUS && VUE2) */
530
+ if (!this.childs[i].w) {
531
+ // 设置原宽度
532
+ this.ctrl[i] = e.detail.width;
533
+ hasOriginalWidth = true;
534
+ }
535
+ /* #endif */
536
+ if (!hasOriginalWidth && ((this.opts[1] && !this.ctrl[i]) || this.ctrl[i] === -1)) {
537
+ // 加载完毕,取消加载中占位图
538
+ this.ctrl[i] = 1;
539
+ }
540
+ this.checkReady();
541
+ },
542
+
543
+ /**
544
+ * @description 检查是否所有图片加载完毕
545
+ */
546
+ checkReady() {
547
+ if (this.root && !this.root.lazyLoad) {
548
+ this.root._unloadimgs -= 1;
549
+ if (!this.root._unloadimgs) {
550
+ setTimeout(() => {
551
+ this.root
552
+ .getRect()
553
+ .then(rect => {
554
+ this.root.$emit('ready', rect);
555
+ })
556
+ .catch(() => {
557
+ this.root.$emit('ready', {});
558
+ });
559
+ }, 350);
560
+ }
561
+ }
562
+ },
563
+
564
+ /**
565
+ * @description 链接点击事件
566
+ * @param {Event} e
567
+ */
568
+ linkTap(e) {
569
+ const node = e.currentTarget ? this.childs[e.currentTarget.dataset.i] : {};
570
+ const attrs = node.attrs || e;
571
+ const href = attrs.href;
572
+ this.root.$emit(
573
+ 'linktap',
574
+ Object.assign(
575
+ {
576
+ innerText: this.root.getText(node.children || []) // 链接内的文本内容
577
+ },
578
+ attrs
579
+ )
580
+ );
581
+ if (href) {
582
+ if (href[0] === '#') {
583
+ // 跳转锚点
584
+ this.root.navigateTo(href.substring(1)).catch(() => {});
585
+ } else if (href.split('?')[0].includes('://')) {
586
+ // 复制外部链接
587
+ if (this.root.copyLink) {
588
+ // #ifdef H5
589
+ window.open(href);
590
+ // #endif
591
+ // #ifdef MP
592
+ uni.setClipboardData({
593
+ data: href,
594
+ success: () =>
595
+ uni.showToast({
596
+ title: '链接已复制'
597
+ })
598
+ });
599
+ // #endif
600
+ // #ifdef APP-PLUS
601
+ plus.runtime.openWeb(href);
602
+ // #endif
603
+ }
604
+ } else {
605
+ // 跳转页面
606
+ uni.navigateTo({
607
+ url: href,
608
+ fail() {
609
+ uni.switchTab({
610
+ url: href,
611
+ fail() {}
612
+ });
613
+ }
614
+ });
615
+ }
616
+ }
617
+ },
618
+
619
+ /**
620
+ * @description 错误事件
621
+ * @param {Event} e
622
+ */
623
+ mediaError(e) {
624
+ const i = e.currentTarget.dataset.i;
625
+ const node = this.childs[i];
626
+ // 加载其他源
627
+ if (node.name === 'video' || node.name === 'audio') {
628
+ let index = (this.ctrl[i] || 0) + 1;
629
+ if (index > node.src.length) {
630
+ index = 0;
631
+ }
632
+ if (index < node.src.length) {
633
+ this.ctrl[i] = index;
634
+ return;
635
+ }
636
+ } else if (node.name === 'img') {
637
+ // #ifdef H5 && VUE3
638
+ if (this.opts[0] && !this.ctrl.load) return;
639
+ // #endif
640
+ // 显示错误占位图
641
+ if (this.opts[2]) {
642
+ this.ctrl[i] = -1;
643
+ }
644
+ this.checkReady();
645
+ }
646
+ if (this.root) {
647
+ this.root.$emit('error', {
648
+ source: node.name,
649
+ attrs: node.attrs,
650
+ // #ifndef H5 && VUE3
651
+ errMsg: e.detail.errMsg
652
+ // #endif
653
+ });
654
+ }
655
+ }
656
+ }
657
+ };
658
+ </script>
659
+ <style>
660
+ /* a 标签默认效果 */
661
+ ._a {
662
+ padding: 1.5px 0 1.5px 0;
663
+ color: #366092;
664
+ word-break: break-all;
665
+ }
666
+
667
+ /* a 标签点击态效果 */
668
+ ._hover {
669
+ text-decoration: underline;
670
+ opacity: 0.7;
671
+ }
672
+
673
+ /* 图片默认效果 */
674
+ ._img {
675
+ max-width: 100%;
676
+ -webkit-touch-callout: none;
677
+ }
678
+
679
+ /* 内部样式 */
680
+
681
+ ._block {
682
+ display: block;
683
+ }
684
+
685
+ ._b,
686
+ ._strong {
687
+ font-weight: bold;
688
+ }
689
+
690
+ ._code {
691
+ font-family: monospace;
692
+ }
693
+
694
+ ._del {
695
+ text-decoration: line-through;
696
+ }
697
+
698
+ ._em,
699
+ ._i {
700
+ font-style: italic;
701
+ }
702
+
703
+ ._h1 {
704
+ font-size: 2em;
705
+ }
706
+
707
+ ._h2 {
708
+ font-size: 1.5em;
709
+ }
710
+
711
+ ._h3 {
712
+ font-size: 1.17em;
713
+ }
714
+
715
+ ._h5 {
716
+ font-size: 0.83em;
717
+ }
718
+
719
+ ._h6 {
720
+ font-size: 0.67em;
721
+ }
722
+
723
+ ._h1,
724
+ ._h2,
725
+ ._h3,
726
+ ._h4,
727
+ ._h5,
728
+ ._h6 {
729
+ display: block;
730
+ font-weight: bold;
731
+ }
732
+
733
+ ._image {
734
+ height: 1px;
735
+ }
736
+
737
+ ._ins {
738
+ text-decoration: underline;
739
+ }
740
+
741
+ ._li {
742
+ display: list-item;
743
+ }
744
+
745
+ ._ol {
746
+ list-style-type: decimal;
747
+ }
748
+
749
+ ._ol,
750
+ ._ul {
751
+ display: block;
752
+ padding-left: 40px;
753
+ margin: 1em 0;
754
+ }
755
+
756
+ ._q::before {
757
+ content: '"';
758
+ }
759
+
760
+ ._q::after {
761
+ content: '"';
762
+ }
763
+
764
+ ._sub {
765
+ font-size: smaller;
766
+ vertical-align: sub;
767
+ }
768
+
769
+ ._sup {
770
+ font-size: smaller;
771
+ vertical-align: super;
772
+ }
773
+
774
+ ._thead,
775
+ ._tbody,
776
+ ._tfoot {
777
+ display: table-row-group;
778
+ }
779
+
780
+ ._tr {
781
+ display: table-row;
782
+ }
783
+
784
+ ._td,
785
+ ._th {
786
+ display: table-cell;
787
+ vertical-align: middle;
788
+ }
789
+
790
+ ._th {
791
+ font-weight: bold;
792
+ text-align: center;
793
+ }
794
+
795
+ ._ul {
796
+ list-style-type: disc;
797
+ }
798
+
799
+ ._ul ._ul {
800
+ margin: 0;
801
+ list-style-type: circle;
802
+ }
803
+
804
+ ._ul ._ul ._ul {
805
+ list-style-type: square;
806
+ }
807
+
808
+ ._abbr,
809
+ ._b,
810
+ ._code,
811
+ ._del,
812
+ ._em,
813
+ ._i,
814
+ ._ins,
815
+ ._label,
816
+ ._q,
817
+ ._span,
818
+ ._strong,
819
+ ._sub,
820
+ ._sup {
821
+ display: inline;
822
+ }
823
+
824
+ /* #ifdef APP-PLUS */
825
+ ._video {
826
+ width: 300px;
827
+ height: 225px;
828
+ }
829
+ /* #endif */
830
+ </style>