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,553 @@
1
+ /**
2
+ * @fileoverview editable 插件
3
+ */
4
+ import config from './config'
5
+ import Parser from '../parser'
6
+
7
+ function Editable (vm) {
8
+ this.vm = vm
9
+ this.editHistory = [] // 历史记录
10
+ this.editI = -1 // 历史记录指针
11
+ vm._mask = [] // 蒙版被点击时进行的操作
12
+
13
+ vm._setData = function (path, val) {
14
+ const paths = path.split('.')
15
+ let target = vm
16
+ for (let i = 0; i < paths.length - 1; i++) {
17
+ target = target[paths[i]]
18
+ }
19
+ vm.$set(target, paths.pop(), val)
20
+ }
21
+
22
+ /**
23
+ * @description 移动历史记录指针
24
+ * @param {Number} num 移动距离
25
+ */
26
+ const move = num => {
27
+ setTimeout(() => {
28
+ const item = this.editHistory[this.editI + num]
29
+ if (item) {
30
+ this.editI += num
31
+ vm._setData(item.key, item.value)
32
+ }
33
+ }, 200)
34
+ }
35
+ vm.undo = () => move(-1) // 撤销
36
+ vm.redo = () => move(1) // 重做
37
+
38
+ /**
39
+ * @description 更新记录
40
+ * @param {String} path 更新内容路径
41
+ * @param {*} oldVal 旧值
42
+ * @param {*} newVal 新值
43
+ * @param {Boolean} set 是否更新到视图
44
+ * @private
45
+ */
46
+ vm._editVal = (path, oldVal, newVal, set) => {
47
+ // 当前指针后的内容去除
48
+ while (this.editI < this.editHistory.length - 1) {
49
+ this.editHistory.pop()
50
+ }
51
+
52
+ // 最多存储 30 条操作记录
53
+ while (this.editHistory.length > 30) {
54
+ this.editHistory.pop()
55
+ this.editI--
56
+ }
57
+
58
+ const last = this.editHistory[this.editHistory.length - 1]
59
+ if (!last || last.key !== path) {
60
+ if (last) {
61
+ // 去掉上一次的新值
62
+ this.editHistory.pop()
63
+ this.editI--
64
+ }
65
+ // 存入这一次的旧值
66
+ this.editHistory.push({
67
+ key: path,
68
+ value: oldVal
69
+ })
70
+ this.editI++
71
+ }
72
+
73
+ // 存入本次的新值
74
+ this.editHistory.push({
75
+ key: path,
76
+ value: newVal
77
+ })
78
+ this.editI++
79
+
80
+ // 更新到视图
81
+ if (set) {
82
+ vm._setData(path, newVal)
83
+ }
84
+ }
85
+
86
+ /**
87
+ * @description 获取菜单项
88
+ * @private
89
+ */
90
+ vm._getItem = function (node, up, down) {
91
+ let items
92
+ let i
93
+ if (node === 'color') {
94
+ return config.color
95
+ }
96
+ if (node.name === 'img') {
97
+ items = config.img.slice(0)
98
+ if (!vm.getSrc) {
99
+ i = items.indexOf('换图')
100
+ if (i !== -1) {
101
+ items.splice(i, 1)
102
+ }
103
+ i = items.indexOf('超链接')
104
+ if (i !== -1) {
105
+ items.splice(i, 1)
106
+ }
107
+ i = items.indexOf('预览图')
108
+ if (i !== -1) {
109
+ items.splice(i, 1)
110
+ }
111
+ }
112
+ i = items.indexOf('禁用预览')
113
+ if (i !== -1 && node.attrs.ignore) {
114
+ items[i] = '启用预览'
115
+ }
116
+ } else if (node.name === 'a') {
117
+ items = config.link.slice(0)
118
+ if (!vm.getSrc) {
119
+ i = items.indexOf('更换链接')
120
+ if (i !== -1) {
121
+ items.splice(i, 1)
122
+ }
123
+ }
124
+ } else if (node.name === 'video' || node.name === 'audio') {
125
+ items = config.media.slice(0)
126
+ i = items.indexOf('封面')
127
+ if (!vm.getSrc && i !== -1) {
128
+ items.splice(i, 1)
129
+ }
130
+ i = items.indexOf('循环')
131
+ if (node.attrs.loop && i !== -1) {
132
+ items[i] = '不循环'
133
+ }
134
+ i = items.indexOf('自动播放')
135
+ if (node.attrs.autoplay && i !== -1) {
136
+ items[i] = '不自动播放'
137
+ }
138
+ } else if (node.name === 'card') {
139
+ items = config.card.slice(0)
140
+ } else {
141
+ items = config.node.slice(0)
142
+ }
143
+ if (!up) {
144
+ i = items.indexOf('上移')
145
+ if (i !== -1) {
146
+ items.splice(i, 1)
147
+ }
148
+ }
149
+ if (!down) {
150
+ i = items.indexOf('下移')
151
+ if (i !== -1) {
152
+ items.splice(i, 1)
153
+ }
154
+ }
155
+ return items
156
+ }
157
+
158
+ /**
159
+ * @description 显示 tooltip
160
+ * @param {object} obj
161
+ * @private
162
+ */
163
+ vm._tooltip = function (obj) {
164
+ vm.$set(vm, 'tooltip', {
165
+ top: obj.top,
166
+ items: obj.items
167
+ })
168
+ vm._tooltipcb = obj.success
169
+ }
170
+
171
+ /**
172
+ * @description 显示滚动条
173
+ * @param {object} obj
174
+ * @private
175
+ */
176
+ vm._slider = function (obj) {
177
+ vm.$set(vm, 'slider', {
178
+ min: obj.min,
179
+ max: obj.max,
180
+ value: obj.value,
181
+ top: obj.top
182
+ })
183
+ vm._slideringcb = obj.changing
184
+ vm._slidercb = obj.change
185
+ }
186
+
187
+ /**
188
+ * @description 显示颜色选择
189
+ * @param {object} obj
190
+ * @private
191
+ */
192
+ vm._color = function (obj) {
193
+ vm.$set(vm, 'color', {
194
+ items: obj.items,
195
+ top: obj.top
196
+ })
197
+ vm._colorcb = obj.success
198
+ }
199
+
200
+ /**
201
+ * @description 点击蒙版
202
+ * @private
203
+ */
204
+ vm._maskTap = function () {
205
+ // 隐藏所有悬浮窗
206
+ while (vm._mask.length) {
207
+ (vm._mask.pop())()
208
+ }
209
+ if (vm.tooltip) {
210
+ vm.$set(vm, 'tooltip', null)
211
+ }
212
+ if (vm.slider) {
213
+ vm.$set(vm, 'slider', null)
214
+ }
215
+ if (vm.color) {
216
+ vm.$set(vm, 'color', null)
217
+ }
218
+ }
219
+
220
+ /**
221
+ * @description 插入节点
222
+ * @param {Object} node
223
+ */
224
+ function insert (node) {
225
+ if (vm._edit) {
226
+ vm._edit.insert(node)
227
+ } else {
228
+ const nodes = vm.nodes.slice(0)
229
+ nodes.push(node)
230
+ vm._editVal('nodes', vm.nodes, nodes, true)
231
+ }
232
+ }
233
+
234
+ /**
235
+ * @description 在光标处插入指定 html 内容
236
+ * @param {String} html 内容
237
+ */
238
+ vm.insertHtml = html => {
239
+ this.inserting = true
240
+ const arr = new Parser(vm).parse(html)
241
+ this.inserting = undefined
242
+ for (let i = 0; i < arr.length; i++) {
243
+ insert(arr[i])
244
+ }
245
+ }
246
+
247
+ /**
248
+ * @description 在光标处插入图片
249
+ */
250
+ vm.insertImg = function () {
251
+ vm.getSrc && vm.getSrc('img').then(src => {
252
+ if (typeof src === 'string') {
253
+ src = [src]
254
+ }
255
+ const parser = new Parser(vm)
256
+ for (let i = 0; i < src.length; i++) {
257
+ insert({
258
+ name: 'img',
259
+ attrs: {
260
+ src: parser.getUrl(src[i])
261
+ }
262
+ })
263
+ }
264
+ }).catch(() => { })
265
+ }
266
+
267
+ /**
268
+ * @description 在光标处插入一个链接
269
+ */
270
+ vm.insertLink = function () {
271
+ vm.getSrc && vm.getSrc('link').then(url => {
272
+ insert({
273
+ name: 'a',
274
+ attrs: {
275
+ href: url
276
+ },
277
+ children: [{
278
+ type: 'text',
279
+ text: url
280
+ }]
281
+ })
282
+ }).catch(() => { })
283
+ }
284
+
285
+ /**
286
+ * @description 在光标处插入一个表格
287
+ * @param {Number} rows 行数
288
+ * @param {Number} cols 列数
289
+ */
290
+ vm.insertTable = function (rows, cols) {
291
+ const table = {
292
+ name: 'table',
293
+ attrs: {
294
+ style: 'display:table;width:100%;margin:10px 0;text-align:center;border-spacing:0;border-collapse:collapse;border:1px solid gray'
295
+ },
296
+ children: []
297
+ }
298
+ for (let i = 0; i < rows; i++) {
299
+ const tr = {
300
+ name: 'tr',
301
+ attrs: {},
302
+ children: []
303
+ }
304
+ for (let j = 0; j < cols; j++) {
305
+ tr.children.push({
306
+ name: 'td',
307
+ attrs: {
308
+ style: 'padding:2px;border:1px solid gray'
309
+ },
310
+ children: [{
311
+ type: 'text',
312
+ text: ''
313
+ }]
314
+ })
315
+ }
316
+ table.children.push(tr)
317
+ }
318
+ insert(table)
319
+ }
320
+
321
+ /**
322
+ * @description 插入视频/音频
323
+ * @param {Object} node
324
+ */
325
+ function insertMedia (node) {
326
+ if (typeof node.src === 'string') {
327
+ node.src = [node.src]
328
+ }
329
+ const parser = new Parser(vm)
330
+ // 拼接主域名
331
+ for (let i = 0; i < node.src.length; i++) {
332
+ node.src[i] = parser.getUrl(node.src[i])
333
+ }
334
+ insert({
335
+ name: 'div',
336
+ attrs: {
337
+ style: 'text-align:center'
338
+ },
339
+ children: [node]
340
+ })
341
+ }
342
+
343
+ /**
344
+ * @description 在光标处插入一个视频
345
+ */
346
+ vm.insertVideo = function () {
347
+ vm.getSrc && vm.getSrc('video').then(src => {
348
+ insertMedia({
349
+ name: 'video',
350
+ attrs: {
351
+ controls: 'T'
352
+ },
353
+ children: [],
354
+ src,
355
+ // #ifdef APP-PLUS
356
+ html: `<video src="${src}" style="width:100%;height:100%"></video>`
357
+ // #endif
358
+ })
359
+ }).catch(() => { })
360
+ }
361
+
362
+ /**
363
+ * @description 在光标处插入一个音频
364
+ */
365
+ vm.insertAudio = function () {
366
+ vm.getSrc && vm.getSrc('audio').then(attrs => {
367
+ let src
368
+ if (attrs.src) {
369
+ src = attrs.src
370
+ attrs.src = undefined
371
+ } else {
372
+ src = attrs
373
+ attrs = {}
374
+ }
375
+ attrs.controls = 'T'
376
+ insertMedia({
377
+ name: 'audio',
378
+ attrs,
379
+ children: [],
380
+ src
381
+ })
382
+ }).catch(() => { })
383
+ }
384
+
385
+ /**
386
+ * @description 在光标处插入一段文本
387
+ */
388
+ vm.insertText = function () {
389
+ insert({
390
+ name: 'p',
391
+ attrs: {},
392
+ children: [{
393
+ type: 'text',
394
+ text: ''
395
+ }]
396
+ })
397
+ }
398
+
399
+ /**
400
+ * @description 清空内容
401
+ */
402
+ vm.clear = function () {
403
+ vm._maskTap()
404
+ vm._edit = undefined
405
+ vm.$set(vm, 'nodes', [{
406
+ name: 'p',
407
+ attrs: {},
408
+ children: [{
409
+ type: 'text',
410
+ text: ''
411
+ }]
412
+ }])
413
+ }
414
+
415
+ /**
416
+ * @description 获取编辑后的 html
417
+ */
418
+ vm.getContent = function () {
419
+ let html = '';
420
+ // 递归遍历获取
421
+ (function traversal (nodes, table) {
422
+ for (let i = 0; i < nodes.length; i++) {
423
+ let item = nodes[i]
424
+ if (item.type === 'text') {
425
+ html += item.text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br>').replace(/\xa0/g, '&nbsp;') // 编码实体
426
+ } else {
427
+ if (item.name === 'img') {
428
+ item.attrs.i = ''
429
+ // 还原被转换的 svg
430
+ if ((item.attrs.src || '').includes('data:image/svg+xml;utf8,')) {
431
+ html += item.attrs.src.substr(24).replace(/%23/g, '#').replace('<svg', '<svg style="' + (item.attrs.style || '') + '"')
432
+ continue
433
+ }
434
+ } else if (item.name === 'video' || item.name === 'audio') {
435
+ // 还原 video 和 audio 的 source
436
+ item = JSON.parse(JSON.stringify(item))
437
+ if (item.src.length > 1) {
438
+ item.children = []
439
+ for (let j = 0; j < item.src.length; j++) {
440
+ item.children.push({
441
+ name: 'source',
442
+ attrs: {
443
+ src: item.src[j]
444
+ }
445
+ })
446
+ }
447
+ } else {
448
+ item.attrs.src = item.src[0]
449
+ }
450
+ } else if (item.name === 'div' && (item.attrs.style || '').includes('overflow:auto') && (item.children[0] || {}).name === 'table') {
451
+ // 还原滚动层
452
+ item = item.children[0]
453
+ }
454
+ // 还原 table
455
+ if (item.name === 'table') {
456
+ item = JSON.parse(JSON.stringify(item))
457
+ table = item.attrs
458
+ if ((item.attrs.style || '').includes('display:grid')) {
459
+ item.attrs.style = item.attrs.style.split('display:grid')[0]
460
+ const children = [{
461
+ name: 'tr',
462
+ attrs: {},
463
+ children: []
464
+ }]
465
+ for (let j = 0; j < item.children.length; j++) {
466
+ item.children[j].attrs.style = item.children[j].attrs.style.replace(/grid-[^;]+;*/g, '')
467
+ if (item.children[j].r !== children.length) {
468
+ children.push({
469
+ name: 'tr',
470
+ attrs: {},
471
+ children: [item.children[j]]
472
+ })
473
+ } else {
474
+ children[children.length - 1].children.push(item.children[j])
475
+ }
476
+ }
477
+ item.children = children
478
+ }
479
+ }
480
+ html += '<' + item.name
481
+ for (const attr in item.attrs) {
482
+ let val = item.attrs[attr]
483
+ if (!val) continue
484
+ if (val === 'T' || val === true) {
485
+ // bool 型省略值
486
+ html += ' ' + attr
487
+ continue
488
+ } else if (item.name[0] === 't' && attr === 'style' && table) {
489
+ // 取消为了显示 table 添加的 style
490
+ val = val.replace(/;*display:table[^;]*/, '')
491
+ if (table.border) {
492
+ val = val.replace(/border[^;]+;*/g, $ => $.includes('collapse') ? $ : '')
493
+ }
494
+ if (table.cellpadding) {
495
+ val = val.replace(/padding[^;]+;*/g, '')
496
+ }
497
+ if (!val) continue
498
+ }
499
+ html += ' ' + attr + '="' + val.replace(/"/g, '&quot;') + '"'
500
+ }
501
+ html += '>'
502
+ if (item.children) {
503
+ traversal(item.children, table)
504
+ html += '</' + item.name + '>'
505
+ }
506
+ }
507
+ }
508
+ })(vm.nodes)
509
+
510
+ // 其他插件处理
511
+ for (let i = vm.plugins.length; i--;) {
512
+ if (vm.plugins[i].onGetContent) {
513
+ html = vm.plugins[i].onGetContent(html) || html
514
+ }
515
+ }
516
+
517
+ return html
518
+ }
519
+ }
520
+
521
+ Editable.prototype.onUpdate = function (content, config) {
522
+ if (this.vm.editable) {
523
+ this.vm._maskTap()
524
+ config.entities.amp = '&'
525
+ if (!this.inserting) {
526
+ this.vm._edit = undefined
527
+ if (!content) {
528
+ setTimeout(() => {
529
+ this.vm.$set(this.vm, 'nodes', [{
530
+ name: 'p',
531
+ attrs: {},
532
+ children: [{
533
+ type: 'text',
534
+ text: ''
535
+ }]
536
+ }])
537
+ }, 0)
538
+ }
539
+ }
540
+ }
541
+ }
542
+
543
+ Editable.prototype.onParse = function (node) {
544
+ // 空白单元格可编辑
545
+ if (this.vm.editable && (node.name === 'td' || node.name === 'th') && !this.vm.getText(node.children)) {
546
+ node.children.push({
547
+ type: 'text',
548
+ text: ''
549
+ })
550
+ }
551
+ }
552
+
553
+ export default Editable