oxy-uni-ui 1.2.0 → 1.2.3

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 (116) hide show
  1. package/attributes.json +1 -1
  2. package/components/common/abstracts/variable.scss +51 -1
  3. package/components/common/path.ts +9 -0
  4. package/components/common/util.ts +42 -0
  5. package/components/composables/useGlobalLoading.ts +42 -0
  6. package/components/composables/useGlobalMessage.ts +48 -0
  7. package/components/composables/useGlobalToast.ts +84 -0
  8. package/components/composables/useVirtualScroll.ts +3 -2
  9. package/components/oxy-cell/oxy-cell.vue +15 -2
  10. package/components/oxy-cell/types.ts +4 -0
  11. package/components/oxy-checkbox/index.scss +1 -1
  12. package/components/oxy-checkbox/oxy-checkbox.vue +2 -2
  13. package/components/oxy-col-picker/oxy-col-picker.vue +3 -0
  14. package/components/oxy-col-picker/types.ts +5 -1
  15. package/components/oxy-corner/oxy-corner.vue +15 -3
  16. package/components/oxy-corner/types.ts +15 -1
  17. package/components/oxy-date-strip/index.scss +10 -0
  18. package/components/oxy-date-strip/oxy-date-strip.vue +198 -0
  19. package/components/oxy-date-strip/types.ts +98 -0
  20. package/components/oxy-date-strip/utils.ts +67 -0
  21. package/components/oxy-date-strip-item/index.scss +94 -0
  22. package/components/oxy-date-strip-item/oxy-date-strip-item.vue +102 -0
  23. package/components/oxy-date-strip-item/types.ts +53 -0
  24. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +3 -1
  25. package/components/oxy-datetime-picker/types.ts +5 -1
  26. package/components/oxy-echarts/index.scss +17 -0
  27. package/components/oxy-echarts/index.ts +1 -0
  28. package/components/oxy-echarts/oxy-echarts.vue +32 -0
  29. package/components/oxy-echarts/types.ts +12 -0
  30. package/components/oxy-file-list/index.scss +26 -0
  31. package/components/oxy-file-list/oxy-file-list.vue +208 -34
  32. package/components/oxy-file-list/types.ts +58 -2
  33. package/components/oxy-global-loading/oxy-global-loading.vue +53 -0
  34. package/components/oxy-global-message/oxy-global-message.vue +64 -0
  35. package/components/oxy-global-toast/oxy-global-toast.vue +53 -0
  36. package/components/oxy-img-lazy/index.scss +17 -0
  37. package/components/oxy-img-lazy/oxy-img-lazy.vue +332 -0
  38. package/components/oxy-img-lazy/types.ts +69 -0
  39. package/components/oxy-link/index.scss +57 -0
  40. package/components/oxy-link/oxy-link.vue +130 -0
  41. package/components/oxy-link/types.ts +81 -0
  42. package/components/oxy-list/index.scss +7 -1
  43. package/components/oxy-list/types.ts +1 -1
  44. package/components/oxy-picker/oxy-picker.vue +3 -0
  45. package/components/oxy-picker/types.ts +5 -1
  46. package/components/oxy-radio/index.scss +3 -3
  47. package/components/oxy-radio/oxy-radio.vue +1 -1
  48. package/components/oxy-rich-text/icon/emjio.svg +1 -0
  49. package/components/oxy-rich-text/icon/quote.svg +1 -0
  50. package/components/oxy-rich-text/icon/text.svg +1 -0
  51. package/components/oxy-rich-text/icon/title.svg +1 -0
  52. package/components/oxy-rich-text/index.scss +159 -0
  53. package/components/oxy-rich-text/mp-html/card/card.vue +122 -0
  54. package/components/oxy-rich-text/mp-html/card/index.js +7 -0
  55. package/components/oxy-rich-text/mp-html/editable/config.js +15 -0
  56. package/components/oxy-rich-text/mp-html/editable/index.js +553 -0
  57. package/components/oxy-rich-text/mp-html/emoji/index.js +203 -0
  58. package/components/oxy-rich-text/mp-html/highlight/config.js +5 -0
  59. package/components/oxy-rich-text/mp-html/highlight/index.js +96 -0
  60. package/components/oxy-rich-text/mp-html/highlight/prism.css +1 -0
  61. package/components/oxy-rich-text/mp-html/highlight/prism.min.js +7 -0
  62. package/components/oxy-rich-text/mp-html/img-cache/index.js +138 -0
  63. package/components/oxy-rich-text/mp-html/latex/index.js +80 -0
  64. package/components/oxy-rich-text/mp-html/latex/katex.css +1 -0
  65. package/components/oxy-rich-text/mp-html/latex/katex.min.js +1 -0
  66. package/components/oxy-rich-text/mp-html/markdown/index.js +50 -0
  67. package/components/oxy-rich-text/mp-html/markdown/marked.min.js +71 -0
  68. package/components/oxy-rich-text/mp-html/mp-html.d.ts +184 -0
  69. package/components/oxy-rich-text/mp-html/mp-html.vue +675 -0
  70. package/components/oxy-rich-text/mp-html/node/node.vue +1161 -0
  71. package/components/oxy-rich-text/mp-html/parser.js +1428 -0
  72. package/components/oxy-rich-text/mp-html/search/index.js +132 -0
  73. package/components/oxy-rich-text/mp-html/style/index.js +129 -0
  74. package/components/oxy-rich-text/mp-html/style/parser.js +175 -0
  75. package/components/oxy-rich-text/mp-html/template/index.js +67 -0
  76. package/components/oxy-rich-text/mp-html/txv-video/index.js +46 -0
  77. package/components/oxy-rich-text/oxy-rich-text.vue +642 -0
  78. package/components/oxy-rich-text/types.ts +71 -0
  79. package/components/oxy-select/index.scss +255 -0
  80. package/components/oxy-select/oxy-select.vue +421 -0
  81. package/components/oxy-select/types.ts +71 -0
  82. package/components/oxy-select-picker/oxy-select-picker.vue +3 -0
  83. package/components/oxy-select-picker/types.ts +5 -1
  84. package/components/oxy-stream-render/index.scss +6 -0
  85. package/components/oxy-stream-render/oxy-stream-render.vue +204 -0
  86. package/components/oxy-stream-render/types.ts +5 -0
  87. package/components/oxy-tree/index.scss +17 -1
  88. package/components/oxy-tree/oxy-tree.vue +89 -8
  89. package/components/oxy-tree/types.ts +11 -1
  90. package/components/oxy-waterfall/index.scss +18 -0
  91. package/components/oxy-waterfall/oxy-waterfall.vue +218 -0
  92. package/components/oxy-waterfall/types.ts +90 -0
  93. package/components/oxy-waterfall-item/index.scss +8 -0
  94. package/components/oxy-waterfall-item/oxy-waterfall-item.vue +89 -0
  95. package/components/oxy-waterfall-item/types.ts +16 -0
  96. package/global.d.ts +7 -0
  97. package/index.ts +3 -0
  98. package/locale/lang/en-US.ts +26 -0
  99. package/locale/lang/zh-CN.ts +26 -0
  100. package/oxy-uni-ui.zip +0 -0
  101. package/package.json +1 -1
  102. package/tags.json +1 -1
  103. package/uni-echarts/changelog.md +2 -0
  104. package/uni-echarts/components/index.js +1 -0
  105. package/uni-echarts/components/uni-echarts/events.js +95 -0
  106. package/uni-echarts/components/uni-echarts/types.d.ts +183 -0
  107. package/uni-echarts/components/uni-echarts/types.js +1 -0
  108. package/uni-echarts/components/uni-echarts/uni-echarts.vue +530 -0
  109. package/uni-echarts/components/uni-echarts/uni-echarts.vue.d.ts +19 -0
  110. package/uni-echarts/global.d.ts +7 -0
  111. package/uni-echarts/index.d.ts +440 -0
  112. package/uni-echarts/index.js +2 -0
  113. package/uni-echarts/package.json +105 -0
  114. package/uni-echarts/shared-core.d.ts +269 -0
  115. package/uni-echarts/shared-core.js +900 -0
  116. package/web-types.json +1 -1
@@ -0,0 +1,132 @@
1
+ /**
2
+ * @fileoverview search 插件
3
+ */
4
+ function Search (vm) {
5
+ /**
6
+ * @description 关键词搜索
7
+ * @param {regexp|string} key 要搜索的关键词
8
+ * @param {boolean} anchor 是否将搜索结果设置为锚点
9
+ * @param {string} style 搜索结果的样式
10
+ */
11
+ vm.search = function (key, anchor, style = 'background-color:yellow') {
12
+ const res = []
13
+ const stack = [];
14
+
15
+ // 遍历搜索
16
+ (function traversal (nodes) {
17
+ for (let i = 0; i < nodes.length; i++) {
18
+ let node = nodes[i]
19
+ if (node.type === 'text' && key) {
20
+ const text = node.text
21
+ const arr = text.split(key)
22
+ if (arr.length > 1) {
23
+ node = {
24
+ name: 'span',
25
+ attrs: {},
26
+ type: 'node',
27
+ c: 1,
28
+ s: 1,
29
+ children: []
30
+ }
31
+ vm.$set(nodes, i, node)
32
+ for (let j = 0; j < arr.length; j++) {
33
+ if (arr[j]) {
34
+ node.children.push({
35
+ type: 'text',
36
+ text: arr[j]
37
+ })
38
+ }
39
+ if (j !== arr.length - 1) {
40
+ // 关键词转为一个 span
41
+ node.children.push({
42
+ name: 'span',
43
+ attrs: {
44
+ id: anchor ? 'search' + (res.length + 1) : undefined, // 用于锚点的 id
45
+ style: style
46
+ },
47
+ // #ifdef VUE3
48
+ c: 1,
49
+ // #endif
50
+ children: [{
51
+ type: 'text',
52
+ text: key instanceof RegExp ? key.exec(text)[0] : key
53
+ }]
54
+ })
55
+ res.push(node.children[node.children.length - 1].attrs)
56
+ }
57
+ }
58
+ if (key instanceof RegExp) {
59
+ key.exec(text)
60
+ }
61
+ if (anchor) {
62
+ for (let l = stack.length; l--;) {
63
+ if (stack[l].c) {
64
+ break
65
+ } else {
66
+ vm.$set(stack[l], 'c', 1)
67
+ }
68
+ }
69
+ }
70
+ }
71
+ } else if (node.s) {
72
+ let text = ''
73
+ // 复原上一次的结果
74
+ for (let k = 0; k < node.children.length; k++) {
75
+ const child = node.children[k]
76
+ if (child.text) {
77
+ text += child.text
78
+ } else {
79
+ text += child.children[0].text
80
+ }
81
+ }
82
+ vm.$set(nodes, i, {
83
+ type: 'text',
84
+ text
85
+ })
86
+ if (key && (key instanceof RegExp ? key.test(text) : text.includes(key))) {
87
+ i--
88
+ }
89
+ } else if (node.children) {
90
+ stack.push(node)
91
+ traversal(node.children)
92
+ stack.pop()
93
+ }
94
+ }
95
+ })(vm.nodes)
96
+
97
+ return new Promise(function (resolve) {
98
+ setTimeout(() => {
99
+ resolve({
100
+ num: res.length, // 结果数量
101
+ /**
102
+ * @description 高亮某一个结果
103
+ * @param {number} i 第几个
104
+ * @param {string} hlstyle 高亮的样式
105
+ */
106
+ highlight (i, hlstyle = 'background-color:#FF9632') {
107
+ if (i < 1 || i > res.length) return
108
+ if (this.last) {
109
+ res[this.last - 1].style = style
110
+ }
111
+ this.last = i
112
+ res[i - 1].style = hlstyle
113
+ },
114
+ /**
115
+ * @description 跳转到搜索结果
116
+ * @param {number} i 第几个
117
+ * @param {number} offset 偏移量
118
+ */
119
+ jump: anchor
120
+ ? (i, offset) => {
121
+ if (i > 0 && i <= res.length) {
122
+ vm.navigateTo('search' + i, offset)
123
+ }
124
+ }
125
+ : undefined
126
+ })
127
+ }, 200)
128
+ })
129
+ }
130
+ }
131
+
132
+ export default Search
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @fileoverview style 插件
3
+ */
4
+ // #ifndef APP-PLUS-NVUE
5
+ import Parser from './parser'
6
+ // #endif
7
+
8
+ function Style () {
9
+ this.styles = []
10
+ }
11
+
12
+ // #ifndef APP-PLUS-NVUE
13
+ Style.prototype.onParse = function (node, vm) {
14
+ // 获取样式
15
+ if (node.name === 'style' && node.children.length && node.children[0].type === 'text') {
16
+ this.styles = this.styles.concat(new Parser().parse(node.children[0].text))
17
+ } else if (node.name) {
18
+ // 匹配样式(对非文本标签)
19
+ // 存储不同优先级的样式 name < class < id < 后代
20
+ let matched = ['', '', '', '']
21
+ for (let i = 0, len = this.styles.length; i < len; i++) {
22
+ const item = this.styles[i]
23
+ let res = match(node, item.key || item.list[item.list.length - 1])
24
+ let j
25
+ if (res) {
26
+ // 后代选择器
27
+ if (!item.key) {
28
+ j = item.list.length - 2
29
+ for (let k = vm.stack.length; j >= 0 && k--;) {
30
+ // 子选择器
31
+ if (item.list[j] === '>') {
32
+ // 错误情况
33
+ if (j < 1 || j > item.list.length - 2) break
34
+ if (match(vm.stack[k], item.list[j - 1])) {
35
+ j -= 2
36
+ } else {
37
+ j++
38
+ }
39
+ } else if (match(vm.stack[k], item.list[j])) {
40
+ j--
41
+ }
42
+ }
43
+ res = 4
44
+ }
45
+ if (item.key || j < 0) {
46
+ // 添加伪类
47
+ if (item.pseudo && node.children) {
48
+ let text
49
+ item.style = item.style.replace(/content:([^;]+)/, (_, $1) => {
50
+ text = $1.replace(/['"]/g, '')
51
+ // 处理 attr 函数
52
+ .replace(/attr\((.+?)\)/, (_, $1) => node.attrs[$1.trim()] || '')
53
+ // 编码 \xxx
54
+ .replace(/\\(\w{4})/, (_, $1) => String.fromCharCode(parseInt($1, 16)))
55
+ return ''
56
+ })
57
+ const pseudo = {
58
+ name: 'span',
59
+ attrs: {
60
+ style: item.style
61
+ },
62
+ children: [{
63
+ type: 'text',
64
+ text
65
+ }]
66
+ }
67
+ if (item.pseudo === 'before') {
68
+ node.children.unshift(pseudo)
69
+ } else {
70
+ node.children.push(pseudo)
71
+ }
72
+ } else {
73
+ matched[res - 1] += item.style + (item.style[item.style.length - 1] === ';' ? '' : ';')
74
+ }
75
+ }
76
+ }
77
+ }
78
+ matched = matched.join('')
79
+ if (matched.length > 2) {
80
+ node.attrs.style = matched + (node.attrs.style || '')
81
+ }
82
+ }
83
+ }
84
+
85
+ /**
86
+ * @description 匹配样式
87
+ * @param {object} node 要匹配的标签
88
+ * @param {string|string[]} keys 选择器
89
+ * @returns {number} 0:不匹配;1:name 匹配;2:class 匹配;3:id 匹配
90
+ */
91
+ function match (node, keys) {
92
+ function matchItem (key) {
93
+ if (key[0] === '#') {
94
+ // 匹配 id
95
+ if (node.attrs.id && node.attrs.id.trim() === key.substr(1)) return 3
96
+ } else if (key[0] === '.') {
97
+ // 匹配 class
98
+ key = key.substr(1)
99
+ const selectors = (node.attrs.class || '').split(' ')
100
+ for (let i = 0; i < selectors.length; i++) {
101
+ if (selectors[i].trim() === key) return 2
102
+ }
103
+ } else if (node.name === key) {
104
+ // 匹配 name
105
+ return 1
106
+ }
107
+ return 0
108
+ }
109
+
110
+ // 多选择器交集
111
+ if (keys instanceof Array) {
112
+ let res = 0
113
+ for (let j = 0; j < keys.length; j++) {
114
+ const tmp = matchItem(keys[j])
115
+ // 任意一个不匹配就失败
116
+ if (!tmp) return 0
117
+ // 优先级最大的一个作为最终优先级
118
+ if (tmp > res) {
119
+ res = tmp
120
+ }
121
+ }
122
+ return res
123
+ }
124
+
125
+ return matchItem(keys)
126
+ }
127
+ // #endif
128
+
129
+ export default Style
@@ -0,0 +1,175 @@
1
+ const blank = {
2
+ ' ': true,
3
+ '\n': true,
4
+ '\t': true,
5
+ '\r': true,
6
+ '\f': true
7
+ }
8
+
9
+ function Parser () {
10
+ this.styles = []
11
+ this.selectors = []
12
+ }
13
+
14
+ /**
15
+ * @description 解析 css 字符串
16
+ * @param {string} content css 内容
17
+ */
18
+ Parser.prototype.parse = function (content) {
19
+ new Lexer(this).parse(content)
20
+ return this.styles
21
+ }
22
+
23
+ /**
24
+ * @description 解析到一个选择器
25
+ * @param {string} name 名称
26
+ */
27
+ Parser.prototype.onSelector = function (name) {
28
+ // 不支持的选择器
29
+ if (name.includes('[') || name.includes('*') || name.includes('@')) return
30
+ const selector = {}
31
+ // 伪类
32
+ if (name.includes(':')) {
33
+ const info = name.split(':')
34
+ const pseudo = info.pop()
35
+ if (pseudo === 'before' || pseudo === 'after') {
36
+ selector.pseudo = pseudo
37
+ name = info[0]
38
+ } else return
39
+ }
40
+
41
+ // 分割交集选择器
42
+ function splitItem (str) {
43
+ const arr = []
44
+ let i, start
45
+ for (i = 1, start = 0; i < str.length; i++) {
46
+ if (str[i] === '.' || str[i] === '#') {
47
+ arr.push(str.substring(start, i))
48
+ start = i
49
+ }
50
+ }
51
+ if (!arr.length) {
52
+ return str
53
+ } else {
54
+ arr.push(str.substring(start, i))
55
+ return arr
56
+ }
57
+ }
58
+
59
+ // 后代选择器
60
+ if (name.includes(' ')) {
61
+ selector.list = []
62
+ const list = name.split(' ')
63
+ for (let i = 0; i < list.length; i++) {
64
+ if (list[i].length) {
65
+ // 拆分子选择器
66
+ const arr = list[i].split('>')
67
+ for (let j = 0; j < arr.length; j++) {
68
+ selector.list.push(splitItem(arr[j]))
69
+ if (j < arr.length - 1) {
70
+ selector.list.push('>')
71
+ }
72
+ }
73
+ }
74
+ }
75
+ } else {
76
+ selector.key = splitItem(name)
77
+ }
78
+
79
+ this.selectors.push(selector)
80
+ }
81
+
82
+ /**
83
+ * @description 解析到选择器内容
84
+ * @param {string} content 内容
85
+ */
86
+ Parser.prototype.onContent = function (content) {
87
+ // 并集选择器
88
+ for (let i = 0; i < this.selectors.length; i++) {
89
+ this.selectors[i].style = content
90
+ }
91
+ this.styles = this.styles.concat(this.selectors)
92
+ this.selectors = []
93
+ }
94
+
95
+ /**
96
+ * @description css 词法分析器
97
+ * @param {object} handler 高层处理器
98
+ */
99
+ function Lexer (handler) {
100
+ this.selector = ''
101
+ this.style = ''
102
+ this.handler = handler
103
+ }
104
+
105
+ Lexer.prototype.parse = function (content) {
106
+ this.i = 0
107
+ this.content = content
108
+ this.state = this.blank
109
+ for (let len = content.length; this.i < len; this.i++) {
110
+ this.state(content[this.i])
111
+ }
112
+ }
113
+
114
+ Lexer.prototype.comment = function () {
115
+ this.i = this.content.indexOf('*/', this.i) + 1
116
+ if (!this.i) {
117
+ this.i = this.content.length
118
+ }
119
+ }
120
+
121
+ Lexer.prototype.blank = function (c) {
122
+ if (!blank[c]) {
123
+ if (c === '/' && this.content[this.i + 1] === '*') {
124
+ this.comment()
125
+ return
126
+ }
127
+ this.selector += c
128
+ this.state = this.name
129
+ }
130
+ }
131
+
132
+ Lexer.prototype.name = function (c) {
133
+ if (c === '/' && this.content[this.i + 1] === '*') {
134
+ this.comment()
135
+ return
136
+ }
137
+ if (c === '{' || c === ',' || c === ';') {
138
+ this.handler.onSelector(this.selector.trimEnd())
139
+ this.selector = ''
140
+ if (c !== '{') {
141
+ while (blank[this.content[++this.i]]);
142
+ }
143
+ if (this.content[this.i] === '{') {
144
+ this.floor = 1
145
+ this.state = this.val
146
+ } else {
147
+ this.selector += this.content[this.i]
148
+ }
149
+ } else if (blank[c]) {
150
+ this.selector += ' '
151
+ } else {
152
+ this.selector += c
153
+ }
154
+ }
155
+
156
+ Lexer.prototype.val = function (c) {
157
+ if (c === '/' && this.content[this.i + 1] === '*') {
158
+ this.comment()
159
+ return
160
+ }
161
+ if (c === '{') {
162
+ this.floor++
163
+ } else if (c === '}') {
164
+ this.floor--
165
+ if (!this.floor) {
166
+ this.handler.onContent(this.style)
167
+ this.style = ''
168
+ this.state = this.blank
169
+ return
170
+ }
171
+ }
172
+ this.style += c
173
+ }
174
+
175
+ export default Parser
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @fileoverview 插件入口文件模板
3
+ */
4
+
5
+ const data = {} // 全局数据
6
+
7
+ /**
8
+ * @description 组件被创建时将实例化插件
9
+ * @param {Component} vm 组件实例
10
+ */
11
+ function Plugin (vm) {
12
+ this.vm = vm // 保存实例在其他周期使用
13
+ this.compData = {} // 仅在单个组件中使用的数据
14
+ data.xxx = 'xxx' // 记录全局数据
15
+ }
16
+
17
+ /**
18
+ * @description html 数据更新时触发
19
+ * @param {string} content 要更新的 html 字符串
20
+ * @param {object} config 解析配置
21
+ * @returns {string|void} 如果要对 html 字符串进行一些预处理,则返回处理后的字符串
22
+ */
23
+ Plugin.prototype.onUpdate = function (content, config) {
24
+ config.ignoreTags.xxx = true // 移除 xxx 标签
25
+ // 对 html 内容进行预处理并返回修改,没有修改则不需要返回
26
+ return content
27
+ }
28
+
29
+ /**
30
+ * @description 解析到一个标签时触发
31
+ * @param {object} node 标签
32
+ * @param {object} parser 解析器实例
33
+ * @returns {boolean|void} 如果返回 false 将移除该标签
34
+ */
35
+ Plugin.prototype.onParse = function (node, parser) {
36
+ // 处理文本标签
37
+ if (node.type === 'text') {
38
+ // node.text 文本内容
39
+ } else {
40
+ // 处理元素标签
41
+ // node.name 标签名
42
+ // node.attrs 属性列表
43
+ // node.children 子节点(非自闭合标签有)
44
+
45
+ if (node.name === 'xxx') {
46
+ parser.expose() // 如果该标签不能被 rich-text 包含,需要调用此方法暴露出来
47
+ // parser.options 组件传入的一些解析属性
48
+ // parser.stack 可以从栈中获取祖先节点
49
+ }
50
+ }
51
+ }
52
+
53
+ /**
54
+ * @description dom 树加载完毕时触发(load 事件)
55
+ */
56
+ Plugin.prototype.onLoad = function () {
57
+ // 可以获取媒体 context 对象等
58
+ }
59
+
60
+ /**
61
+ * @description 组件被移除时触发
62
+ */
63
+ Plugin.prototype.onDetached = function () {
64
+ // 可以释放一些必要的资源(计时器等)
65
+ }
66
+
67
+ export default Plugin
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @fileoverview txv-video 插件
3
+ * Include txv-video (https://github.com/tvfe/txv-miniprogram-plugin)
4
+ */
5
+ const TxvVideo = function (vm) {
6
+ this.vm = vm
7
+ }
8
+
9
+ // #ifdef MP-WEIXIN || MP-QQ
10
+ try {
11
+ const TxvContext = requirePlugin('tencentvideo')
12
+
13
+ TxvVideo.prototype.onLoad = function () {
14
+ setTimeout(() => {
15
+ for (let i = 0; i < this.videos.length; i++) {
16
+ const ctx = TxvContext.getTxvContext(this.videos[i])
17
+ ctx.id = this.videos[i]
18
+ this.vm._videos.push(ctx)
19
+ }
20
+ }, 50)
21
+ }
22
+ } catch (e) {
23
+ console.error('使用txv-video扩展需注册腾讯视频插件')
24
+ }
25
+
26
+ TxvVideo.prototype.onUpdate = function (_, config) {
27
+ config.trustTags['txv-video'] = true
28
+ this.videos = []
29
+ }
30
+
31
+ TxvVideo.prototype.onParse = function (node, parser) {
32
+ if (node.name === 'iframe' && (node.attrs.src || '').includes('vid')) {
33
+ const vid = node.attrs.src.match(/vid=([^&\s]+)/)
34
+ if (vid) {
35
+ node.name = 'txv-video'
36
+ node.attrs.vid = vid[1]
37
+ this.videos.push(vid[1])
38
+ node.attrs.src = undefined
39
+ parser.expose()
40
+ }
41
+ }
42
+ }
43
+
44
+ // #endif
45
+
46
+ export default TxvVideo