vue-editify 0.1.47 → 0.1.48
Sign up to get free protection for your applications and to get access to all the features.
- package/examples/App.vue +30 -51
- package/lib/core/function.d.ts +50 -63
- package/lib/editify.es.js +18653 -18044
- package/lib/editify.umd.js +1 -1
- package/lib/index.d.ts +6 -2
- package/lib/plugins/infoBlock/index.d.ts +55 -0
- package/lib/plugins/panel/index.d.ts +48 -0
- package/lib/style.css +1 -1
- package/package.json +2 -2
- package/src/components/menu/menu.vue +14 -13
- package/src/components/toolbar/toolbar.vue +146 -111
- package/src/core/function.ts +249 -183
- package/src/core/rule.ts +78 -48
- package/src/editify/editify.less +52 -1
- package/src/editify/editify.vue +29 -29
- package/src/icon/iconfont.css +8 -0
- package/src/icon/iconfont.ttf +0 -0
- package/src/icon/iconfont.woff +0 -0
- package/src/index.ts +8 -2
- package/src/locale/en_US.ts +9 -1
- package/src/locale/zh_CN.ts +9 -1
- package/src/plugins/attachment/index.ts +10 -6
- package/src/plugins/infoBlock/index.ts +238 -0
- package/src/plugins/mathformula/index.ts +1 -3
- package/src/plugins/panel/index.ts +228 -0
package/src/core/function.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* 这里的方法都是对编辑器内容元素进行判断或者操作的方法,不涉及到格式化、dom渲染和光标渲染
|
3
3
|
*/
|
4
|
-
import { AlexElement, AlexElementsRangeType, AlexEditor } from 'alex-editor'
|
4
|
+
import { AlexElement, AlexElementsRangeType, AlexEditor, AlexElementCreateConfigType } from 'alex-editor'
|
5
5
|
import { common as DapCommon } from 'dap-util'
|
6
6
|
import { cloneData, queryHasValue, getButtonOptionsConfig, ObjectType } from './tool'
|
7
7
|
import { ButtonOptionsItemType } from '../components/button/props'
|
@@ -12,20 +12,16 @@ export type ElementMatchConfigType = {
|
|
12
12
|
styles?: ObjectType
|
13
13
|
}
|
14
14
|
|
15
|
-
export type CellMergeTypeResultType = {
|
16
|
-
crossRow: boolean
|
17
|
-
crossColumn: boolean
|
18
|
-
rowspan?: number
|
19
|
-
colspan?: number
|
20
|
-
}
|
21
|
-
|
22
15
|
/**
|
23
16
|
* 清空单元格的内容并隐藏
|
24
17
|
* @param editor
|
25
18
|
* @param cell
|
26
19
|
*/
|
27
20
|
export const setTableCellMerged = (cell: AlexElement) => {
|
28
|
-
const breakEl =
|
21
|
+
const breakEl = AlexElement.create({
|
22
|
+
type: 'closed',
|
23
|
+
parsedom: 'br'
|
24
|
+
})
|
29
25
|
cell.children = [breakEl]
|
30
26
|
breakEl.parent = cell
|
31
27
|
if (cell.hasMarks()) {
|
@@ -204,7 +200,13 @@ export const elementIsMatch = (element: AlexElement, config: ElementMatchConfigT
|
|
204
200
|
//如果存在marks判断
|
205
201
|
if (config.marks) {
|
206
202
|
const hasMarks = Object.keys(config.marks).every(key => {
|
207
|
-
|
203
|
+
if (element.hasMarks()) {
|
204
|
+
if (config.marks![key] === true) {
|
205
|
+
return element.marks!.hasOwnProperty(key)
|
206
|
+
}
|
207
|
+
return element.marks![key] == config.marks![key]
|
208
|
+
}
|
209
|
+
return false
|
208
210
|
})
|
209
211
|
//如果不是所有的mark都有
|
210
212
|
if (!hasMarks) {
|
@@ -214,7 +216,13 @@ export const elementIsMatch = (element: AlexElement, config: ElementMatchConfigT
|
|
214
216
|
//如果存在styles判断
|
215
217
|
if (config.styles) {
|
216
218
|
const hasStyles = Object.keys(config.styles).every(key => {
|
217
|
-
|
219
|
+
if (element.hasStyles()) {
|
220
|
+
if (config.styles![key] === true) {
|
221
|
+
return element.styles!.hasOwnProperty(key)
|
222
|
+
}
|
223
|
+
return element.styles![key] == config.styles![key]
|
224
|
+
}
|
225
|
+
return false
|
218
226
|
})
|
219
227
|
//如果不是所有的styles都有
|
220
228
|
if (!hasStyles) {
|
@@ -241,62 +249,47 @@ export const getMatchElementByElement = (element: AlexElement, config: ElementMa
|
|
241
249
|
}
|
242
250
|
|
243
251
|
/**
|
244
|
-
* Open API
|
252
|
+
* Open API:判断光标范围内的元素是否在同一个符合条件的元素下,如果是返回那个符合条件的元素,否则返回null
|
245
253
|
* @param editor
|
246
254
|
* @param dataRangeCaches
|
247
255
|
* @param config
|
248
256
|
* @returns
|
249
257
|
*/
|
250
|
-
export const
|
251
|
-
let elements: AlexElement[] = []
|
258
|
+
export const getMatchElementByRange = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, config: ElementMatchConfigType) => {
|
252
259
|
if (!editor.range) {
|
253
|
-
return
|
260
|
+
return null
|
254
261
|
}
|
255
262
|
if (editor.range.anchor.element.isEqual(editor.range.focus.element)) {
|
256
|
-
|
257
|
-
if (element) {
|
258
|
-
elements = [element]
|
259
|
-
}
|
260
|
-
return elements
|
263
|
+
return getMatchElementByElement(editor.range.anchor.element, config)
|
261
264
|
}
|
262
|
-
dataRangeCaches.
|
263
|
-
|
264
|
-
if (element && !elements.some(el => el.isEqual(element))) {
|
265
|
-
elements.push(element)
|
266
|
-
}
|
265
|
+
const arr = dataRangeCaches.list.map(item => {
|
266
|
+
return getMatchElementByElement(item.element, config)
|
267
267
|
})
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
}
|
286
|
-
|
287
|
-
/**
|
288
|
-
* Open API:判断元素是否在任务列表下
|
289
|
-
* @param element
|
290
|
-
* @returns
|
291
|
-
*/
|
292
|
-
export const elementIsInTask = (element: AlexElement): boolean => {
|
293
|
-
if (isTask(element)) {
|
294
|
-
return true
|
268
|
+
let hasNull = arr.some(el => {
|
269
|
+
return el == null
|
270
|
+
})
|
271
|
+
//如果存在null,则表示有的选区元素不在符合条件的元素下,返回null
|
272
|
+
if (hasNull) {
|
273
|
+
return null
|
274
|
+
}
|
275
|
+
//如果只有一个元素,则返回该元素
|
276
|
+
if (arr.length == 1) {
|
277
|
+
return arr[0]!
|
278
|
+
}
|
279
|
+
//默认数组中的元素都相等
|
280
|
+
let flag = true
|
281
|
+
for (let i = 1; i < arr.length; i++) {
|
282
|
+
if (!arr[i]!.isEqual(arr[0]!)) {
|
283
|
+
flag = false
|
284
|
+
break
|
285
|
+
}
|
295
286
|
}
|
296
|
-
|
297
|
-
|
287
|
+
//如果相等,则返回该元素
|
288
|
+
if (flag) {
|
289
|
+
return arr[0]
|
298
290
|
}
|
299
|
-
|
291
|
+
//不相等返回null
|
292
|
+
return null
|
300
293
|
}
|
301
294
|
|
302
295
|
/**
|
@@ -325,37 +318,50 @@ export const isTask = (element: AlexElement) => {
|
|
325
318
|
}
|
326
319
|
|
327
320
|
/**
|
328
|
-
* Open API
|
329
|
-
* @param
|
330
|
-
* @param
|
321
|
+
* Open API:判断元素是否在有序列表或者无序列表下
|
322
|
+
* @param element
|
323
|
+
* @param ordered
|
331
324
|
* @returns
|
332
325
|
*/
|
333
|
-
export const
|
334
|
-
if (
|
335
|
-
return
|
326
|
+
export const elementIsInList = (element: AlexElement, ordered: boolean): boolean => {
|
327
|
+
if (isList(element, ordered)) {
|
328
|
+
return true
|
336
329
|
}
|
337
|
-
if (
|
338
|
-
return
|
330
|
+
if (element.parent) {
|
331
|
+
return elementIsInList(element.parent, ordered)
|
339
332
|
}
|
340
|
-
return
|
341
|
-
|
342
|
-
|
333
|
+
return false
|
334
|
+
}
|
335
|
+
|
336
|
+
/**
|
337
|
+
* Open API:判断元素是否在任务列表下
|
338
|
+
* @param element
|
339
|
+
* @returns
|
340
|
+
*/
|
341
|
+
export const elementIsInTask = (element: AlexElement): boolean => {
|
342
|
+
if (isTask(element)) {
|
343
|
+
return true
|
344
|
+
}
|
345
|
+
if (element.parent) {
|
346
|
+
return elementIsInTask(element.parent)
|
347
|
+
}
|
348
|
+
return false
|
343
349
|
}
|
344
350
|
|
345
351
|
/**
|
346
|
-
* Open API
|
352
|
+
* Open API:选区是否含有代码块
|
347
353
|
* @param editor
|
348
354
|
* @param dataRangeCaches
|
349
355
|
* @returns
|
350
356
|
*/
|
351
|
-
export const
|
357
|
+
export const hasPreInRange = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType) => {
|
352
358
|
if (!editor.range) {
|
353
359
|
return false
|
354
360
|
}
|
355
361
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
356
362
|
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'pre' })
|
357
363
|
}
|
358
|
-
return dataRangeCaches.
|
364
|
+
return dataRangeCaches.flatList.some(item => {
|
359
365
|
return !!getMatchElementByElement(item.element, { parsedom: 'pre' })
|
360
366
|
})
|
361
367
|
}
|
@@ -379,166 +385,166 @@ export const hasQuoteInRange = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
379
385
|
}
|
380
386
|
|
381
387
|
/**
|
382
|
-
* Open API
|
388
|
+
* Open API:选区是否含有有序列表或者无序列表
|
383
389
|
* @param editor
|
384
390
|
* @param dataRangeCaches
|
391
|
+
* @param ordered
|
385
392
|
* @returns
|
386
393
|
*/
|
387
|
-
export const
|
394
|
+
export const hasListInRange = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, ordered: boolean | undefined = false) => {
|
388
395
|
if (!editor.range) {
|
389
396
|
return false
|
390
397
|
}
|
391
398
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
392
|
-
return
|
399
|
+
return elementIsInList(editor.range.anchor.element, ordered)
|
393
400
|
}
|
394
|
-
return dataRangeCaches.
|
395
|
-
return
|
401
|
+
return dataRangeCaches.flatList.some(item => {
|
402
|
+
return elementIsInList(item.element, ordered)
|
396
403
|
})
|
397
404
|
}
|
398
405
|
|
399
406
|
/**
|
400
|
-
* Open API
|
407
|
+
* Open API:选区是否含有任务列表
|
401
408
|
* @param editor
|
402
409
|
* @param dataRangeCaches
|
403
|
-
* @param ordered
|
404
410
|
* @returns
|
405
411
|
*/
|
406
|
-
export const
|
412
|
+
export const hasTaskInRange = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType) => {
|
407
413
|
if (!editor.range) {
|
408
414
|
return false
|
409
415
|
}
|
410
416
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
411
|
-
return
|
417
|
+
return elementIsInTask(editor.range.anchor.element)
|
412
418
|
}
|
413
419
|
return dataRangeCaches.flatList.some(item => {
|
414
|
-
return
|
420
|
+
return elementIsInTask(item.element)
|
415
421
|
})
|
416
422
|
}
|
417
423
|
|
418
424
|
/**
|
419
|
-
* Open API
|
425
|
+
* Open API:选区是否含有链接
|
420
426
|
* @param editor
|
421
427
|
* @param dataRangeCaches
|
422
|
-
* @param ordered
|
423
428
|
* @returns
|
424
429
|
*/
|
425
|
-
export const
|
430
|
+
export const hasLinkInRange = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType) => {
|
426
431
|
if (!editor.range) {
|
427
432
|
return false
|
428
433
|
}
|
429
434
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
430
|
-
return
|
435
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'a' })
|
431
436
|
}
|
432
|
-
return dataRangeCaches.
|
433
|
-
return
|
437
|
+
return dataRangeCaches.flatList.some(item => {
|
438
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'a' })
|
434
439
|
})
|
435
440
|
}
|
436
441
|
|
437
442
|
/**
|
438
|
-
* Open API
|
443
|
+
* Open API:选区是否含有表格
|
439
444
|
* @param editor
|
440
445
|
* @param dataRangeCaches
|
441
446
|
* @returns
|
442
447
|
*/
|
443
|
-
export const
|
448
|
+
export const hasTableInRange = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType) => {
|
444
449
|
if (!editor.range) {
|
445
450
|
return false
|
446
451
|
}
|
447
452
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
448
|
-
return
|
453
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'table' })
|
449
454
|
}
|
450
455
|
return dataRangeCaches.flatList.some(item => {
|
451
|
-
return
|
456
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'table' })
|
452
457
|
})
|
453
458
|
}
|
454
459
|
|
455
460
|
/**
|
456
|
-
* Open API
|
461
|
+
* Open API:选区是否含有图片
|
457
462
|
* @param editor
|
458
463
|
* @param dataRangeCaches
|
459
464
|
* @returns
|
460
465
|
*/
|
461
|
-
export const
|
466
|
+
export const hasImageInRange = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType) => {
|
462
467
|
if (!editor.range) {
|
463
468
|
return false
|
464
469
|
}
|
465
470
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
466
|
-
return
|
471
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'img' })
|
467
472
|
}
|
468
|
-
return dataRangeCaches.
|
469
|
-
return
|
473
|
+
return dataRangeCaches.flatList.some(item => {
|
474
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'img' })
|
470
475
|
})
|
471
476
|
}
|
472
477
|
|
473
478
|
/**
|
474
|
-
* Open API
|
479
|
+
* Open API:选区是否含有视频
|
475
480
|
* @param editor
|
476
481
|
* @param dataRangeCaches
|
477
482
|
* @returns
|
478
483
|
*/
|
479
|
-
export const
|
484
|
+
export const hasVideoInRange = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType) => {
|
480
485
|
if (!editor.range) {
|
481
486
|
return false
|
482
487
|
}
|
483
488
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
484
|
-
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: '
|
489
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'video' })
|
485
490
|
}
|
486
491
|
return dataRangeCaches.flatList.some(item => {
|
487
|
-
return !!getMatchElementByElement(item.element, { parsedom: '
|
492
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'video' })
|
488
493
|
})
|
489
494
|
}
|
490
495
|
|
491
496
|
/**
|
492
|
-
* Open API
|
497
|
+
* Open API:选区是否全部在引用内
|
493
498
|
* @param editor
|
494
499
|
* @param dataRangeCaches
|
495
500
|
* @returns
|
496
501
|
*/
|
497
|
-
export const
|
502
|
+
export const isRangeInQuote = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType) => {
|
498
503
|
if (!editor.range) {
|
499
504
|
return false
|
500
505
|
}
|
501
506
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
502
|
-
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: '
|
507
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'blockquote' })
|
503
508
|
}
|
504
|
-
return dataRangeCaches.
|
505
|
-
return !!getMatchElementByElement(item.element, { parsedom: '
|
509
|
+
return dataRangeCaches.list.every(item => {
|
510
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'blockquote' })
|
506
511
|
})
|
507
512
|
}
|
508
513
|
|
509
514
|
/**
|
510
|
-
* Open API
|
515
|
+
* Open API:选区是否全部在有序列表或者无序列表内
|
511
516
|
* @param editor
|
512
517
|
* @param dataRangeCaches
|
518
|
+
* @param ordered
|
513
519
|
* @returns
|
514
520
|
*/
|
515
|
-
export const
|
521
|
+
export const isRangeInList = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, ordered: boolean | undefined = false) => {
|
516
522
|
if (!editor.range) {
|
517
523
|
return false
|
518
524
|
}
|
519
525
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
520
|
-
return
|
526
|
+
return elementIsInList(editor.range.anchor.element, ordered)
|
521
527
|
}
|
522
|
-
return dataRangeCaches.
|
523
|
-
return
|
528
|
+
return dataRangeCaches.list.every(item => {
|
529
|
+
return elementIsInList(item.element, ordered)
|
524
530
|
})
|
525
531
|
}
|
526
532
|
|
527
533
|
/**
|
528
|
-
* Open API
|
534
|
+
* Open API:选区是否全部在任务列表里
|
529
535
|
* @param editor
|
530
536
|
* @param dataRangeCaches
|
531
537
|
* @returns
|
532
538
|
*/
|
533
|
-
export const
|
539
|
+
export const isRangeInTask = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType) => {
|
534
540
|
if (!editor.range) {
|
535
541
|
return false
|
536
542
|
}
|
537
543
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
538
|
-
return
|
544
|
+
return elementIsInTask(editor.range.anchor.element)
|
539
545
|
}
|
540
|
-
return dataRangeCaches.
|
541
|
-
return
|
546
|
+
return dataRangeCaches.list.every(item => {
|
547
|
+
return elementIsInTask(item.element)
|
542
548
|
})
|
543
549
|
}
|
544
550
|
|
@@ -931,13 +937,13 @@ export const setQuote = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeT
|
|
931
937
|
}
|
932
938
|
|
933
939
|
/**
|
934
|
-
* Open API
|
940
|
+
* Open API:设置对齐方式
|
935
941
|
* @param editor
|
936
942
|
* @param dataRangeCaches
|
937
|
-
* @param value
|
943
|
+
* @param value 取值justify/left/right/center
|
938
944
|
* @returns
|
939
945
|
*/
|
940
|
-
export const setAlign = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, value:
|
946
|
+
export const setAlign = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, value: 'justify' | 'left' | 'right' | 'center') => {
|
941
947
|
if (!editor.range) {
|
942
948
|
return
|
943
949
|
}
|
@@ -997,10 +1003,10 @@ export const setAlign = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeT
|
|
997
1003
|
}
|
998
1004
|
|
999
1005
|
/**
|
1000
|
-
* Open API:插入或者取消 有序或者无序列表
|
1006
|
+
* Open API:插入或者取消 有序或者无序列表
|
1001
1007
|
* @param editor
|
1002
1008
|
* @param dataRangeCaches
|
1003
|
-
* @param ordered
|
1009
|
+
* @param ordered 为true表示有序列表
|
1004
1010
|
* @returns
|
1005
1011
|
*/
|
1006
1012
|
export const setList = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, ordered: boolean) => {
|
@@ -1080,10 +1086,10 @@ export const setTask = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeTy
|
|
1080
1086
|
}
|
1081
1087
|
|
1082
1088
|
/**
|
1083
|
-
* Open API
|
1089
|
+
* Open API:设置文本元素的样式
|
1084
1090
|
* @param editor
|
1085
1091
|
* @param dataRangeCaches
|
1086
|
-
* @param styles
|
1092
|
+
* @param styles 值为{ 'font-weight':'bold' }这类格式
|
1087
1093
|
* @returns
|
1088
1094
|
*/
|
1089
1095
|
export const setTextStyle = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, styles: ObjectType) => {
|
@@ -1139,10 +1145,10 @@ export const setTextStyle = (editor: AlexEditor, dataRangeCaches: AlexElementsRa
|
|
1139
1145
|
}
|
1140
1146
|
|
1141
1147
|
/**
|
1142
|
-
* Open API
|
1148
|
+
* Open API:设置文本元素的标记
|
1143
1149
|
* @param editor
|
1144
1150
|
* @param dataRangeCaches
|
1145
|
-
* @param marks
|
1151
|
+
* @param marks 值为{ 'class':'a' }这类格式
|
1146
1152
|
* @returns
|
1147
1153
|
*/
|
1148
1154
|
export const setTextMark = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, marks: ObjectType) => {
|
@@ -1201,10 +1207,10 @@ export const setTextMark = (editor: AlexEditor, dataRangeCaches: AlexElementsRan
|
|
1201
1207
|
}
|
1202
1208
|
|
1203
1209
|
/**
|
1204
|
-
* Open API
|
1210
|
+
* Open API:移除文本元素的样式
|
1205
1211
|
* @param editor
|
1206
1212
|
* @param dataRangeCaches
|
1207
|
-
* @param styleNames
|
1213
|
+
* @param styleNames 样式名称数组,如果不存在则移除全部样式
|
1208
1214
|
* @returns
|
1209
1215
|
*/
|
1210
1216
|
export const removeTextStyle = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, styleNames?: string[]) => {
|
@@ -1260,10 +1266,10 @@ export const removeTextStyle = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
1260
1266
|
}
|
1261
1267
|
|
1262
1268
|
/**
|
1263
|
-
* Open API
|
1269
|
+
* Open API:移除文本元素的标记
|
1264
1270
|
* @param editor
|
1265
1271
|
* @param dataRangeCaches
|
1266
|
-
* @param markNames
|
1272
|
+
* @param markNames 标记名称数组,如果不存在则移除全部标记
|
1267
1273
|
* @returns
|
1268
1274
|
*/
|
1269
1275
|
export const removeTextMark = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, markNames?: string[]) => {
|
@@ -1387,9 +1393,9 @@ export const setLineHeight = (editor: AlexEditor, dataRangeCaches: AlexElementsR
|
|
1387
1393
|
/**
|
1388
1394
|
* Open API:插入链接
|
1389
1395
|
* @param editor
|
1390
|
-
* @param text
|
1391
|
-
* @param url
|
1392
|
-
* @param newOpen
|
1396
|
+
* @param text 链接名称
|
1397
|
+
* @param url 链接地址
|
1398
|
+
* @param newOpen 是否新窗口打开
|
1393
1399
|
* @returns
|
1394
1400
|
*/
|
1395
1401
|
export const insertLink = (editor: AlexEditor, text: string, url: string, newOpen: boolean) => {
|
@@ -1405,53 +1411,57 @@ export const insertLink = (editor: AlexEditor, text: string, url: string, newOpe
|
|
1405
1411
|
if (newOpen) {
|
1406
1412
|
marks.target = '_blank'
|
1407
1413
|
}
|
1408
|
-
const linkEle =
|
1409
|
-
|
1410
|
-
|
1414
|
+
const linkEle = AlexElement.create({
|
1415
|
+
type: 'inline',
|
1416
|
+
parsedom: 'a',
|
1417
|
+
marks,
|
1418
|
+
children: [
|
1419
|
+
{
|
1420
|
+
type: 'text',
|
1421
|
+
textcontent: text
|
1422
|
+
}
|
1423
|
+
]
|
1424
|
+
})
|
1411
1425
|
editor.insertElement(linkEle)
|
1412
1426
|
}
|
1413
1427
|
|
1414
1428
|
/**
|
1415
1429
|
* Open API:插入图片
|
1416
1430
|
* @param editor
|
1417
|
-
* @param value
|
1431
|
+
* @param value 图片地址
|
1418
1432
|
* @returns
|
1419
1433
|
*/
|
1420
1434
|
export const insertImage = (editor: AlexEditor, value: string) => {
|
1421
1435
|
if (!editor.range) {
|
1422
1436
|
return
|
1423
1437
|
}
|
1424
|
-
const image =
|
1425
|
-
'closed',
|
1426
|
-
'img',
|
1427
|
-
{
|
1438
|
+
const image = AlexElement.create({
|
1439
|
+
type: 'closed',
|
1440
|
+
parsedom: 'img',
|
1441
|
+
marks: {
|
1428
1442
|
src: value
|
1429
|
-
}
|
1430
|
-
|
1431
|
-
null
|
1432
|
-
)
|
1443
|
+
}
|
1444
|
+
})
|
1433
1445
|
editor.insertElement(image)
|
1434
1446
|
}
|
1435
1447
|
|
1436
1448
|
/**
|
1437
1449
|
* Open API:插入视频
|
1438
1450
|
* @param editor
|
1439
|
-
* @param value
|
1451
|
+
* @param value 视频地址
|
1440
1452
|
* @returns
|
1441
1453
|
*/
|
1442
1454
|
export const insertVideo = (editor: AlexEditor, value: string) => {
|
1443
1455
|
if (!editor.range) {
|
1444
1456
|
return
|
1445
1457
|
}
|
1446
|
-
const video =
|
1447
|
-
'closed',
|
1448
|
-
'video',
|
1449
|
-
{
|
1458
|
+
const video = AlexElement.create({
|
1459
|
+
type: 'closed',
|
1460
|
+
parsedom: 'video',
|
1461
|
+
marks: {
|
1450
1462
|
src: value
|
1451
|
-
}
|
1452
|
-
|
1453
|
-
null
|
1454
|
-
)
|
1463
|
+
}
|
1464
|
+
})
|
1455
1465
|
editor.insertElement(video)
|
1456
1466
|
editor.range.anchor.moveToEnd(video)
|
1457
1467
|
editor.range.focus.moveToEnd(video)
|
@@ -1460,35 +1470,61 @@ export const insertVideo = (editor: AlexEditor, value: string) => {
|
|
1460
1470
|
/**
|
1461
1471
|
* Open API:插入表格
|
1462
1472
|
* @param editor
|
1463
|
-
* @param rowLength
|
1464
|
-
* @param colLength
|
1473
|
+
* @param rowLength 表格行数
|
1474
|
+
* @param colLength 表格列数
|
1465
1475
|
* @returns
|
1466
1476
|
*/
|
1467
1477
|
export const insertTable = (editor: AlexEditor, rowLength: number, colLength: number) => {
|
1468
1478
|
if (!editor.range) {
|
1469
1479
|
return
|
1470
1480
|
}
|
1471
|
-
const
|
1472
|
-
const tbody = new AlexElement('inblock', 'tbody', null, null, null)
|
1473
|
-
editor.addElementTo(tbody, table)
|
1481
|
+
const rows: AlexElementCreateConfigType[] = []
|
1474
1482
|
for (let i = 0; i < rowLength; i++) {
|
1475
|
-
const
|
1483
|
+
const columns: AlexElementCreateConfigType[] = []
|
1476
1484
|
for (let j = 0; j < colLength; j++) {
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1485
|
+
columns.push({
|
1486
|
+
type: 'inblock',
|
1487
|
+
parsedom: 'td',
|
1488
|
+
children: [
|
1489
|
+
{
|
1490
|
+
type: 'closed',
|
1491
|
+
parsedom: 'br'
|
1492
|
+
}
|
1493
|
+
]
|
1494
|
+
})
|
1481
1495
|
}
|
1482
|
-
|
1496
|
+
rows.push({
|
1497
|
+
type: 'inblock',
|
1498
|
+
parsedom: 'tr',
|
1499
|
+
children: columns
|
1500
|
+
})
|
1483
1501
|
}
|
1502
|
+
const table = AlexElement.create({
|
1503
|
+
type: 'block',
|
1504
|
+
parsedom: 'table',
|
1505
|
+
children: [
|
1506
|
+
{
|
1507
|
+
type: 'inblock',
|
1508
|
+
parsedom: 'tbody',
|
1509
|
+
children: rows
|
1510
|
+
}
|
1511
|
+
]
|
1512
|
+
})
|
1484
1513
|
editor.insertElement(table)
|
1485
1514
|
//在表格后创建一个段落
|
1486
|
-
const paragraph =
|
1487
|
-
|
1488
|
-
|
1515
|
+
const paragraph = AlexElement.create({
|
1516
|
+
type: 'block',
|
1517
|
+
parsedom: AlexElement.BLOCK_NODE,
|
1518
|
+
children: [
|
1519
|
+
{
|
1520
|
+
type: 'closed',
|
1521
|
+
parsedom: 'br'
|
1522
|
+
}
|
1523
|
+
]
|
1524
|
+
})
|
1489
1525
|
editor.addElementAfter(paragraph, table)
|
1490
|
-
editor.range.anchor.moveToStart(
|
1491
|
-
editor.range.focus.moveToStart(
|
1526
|
+
editor.range.anchor.moveToStart(table)
|
1527
|
+
editor.range.focus.moveToStart(table)
|
1492
1528
|
}
|
1493
1529
|
|
1494
1530
|
/**
|
@@ -1501,10 +1537,10 @@ export const insertCodeBlock = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
1501
1537
|
if (!editor.range) {
|
1502
1538
|
return
|
1503
1539
|
}
|
1504
|
-
const
|
1505
|
-
if (
|
1540
|
+
const pre = getMatchElementByRange(editor, dataRangeCaches, { parsedom: 'pre' })
|
1541
|
+
if (pre) {
|
1506
1542
|
let content = ''
|
1507
|
-
AlexElement.flatElements(
|
1543
|
+
AlexElement.flatElements(pre.children!)
|
1508
1544
|
.filter(item => {
|
1509
1545
|
return item.isText()
|
1510
1546
|
})
|
@@ -1513,21 +1549,35 @@ export const insertCodeBlock = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
1513
1549
|
})
|
1514
1550
|
const splits = content.split('\n')
|
1515
1551
|
splits.forEach(item => {
|
1516
|
-
const paragraph =
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1552
|
+
const paragraph = AlexElement.create({
|
1553
|
+
type: 'block',
|
1554
|
+
parsedom: AlexElement.BLOCK_NODE,
|
1555
|
+
children: [
|
1556
|
+
{
|
1557
|
+
type: 'text',
|
1558
|
+
textcontent: item
|
1559
|
+
}
|
1560
|
+
]
|
1561
|
+
})
|
1562
|
+
editor.addElementBefore(paragraph, pre)
|
1520
1563
|
})
|
1521
|
-
|
1564
|
+
pre.toEmpty()
|
1522
1565
|
} else {
|
1523
1566
|
//起点和终点在一起
|
1524
1567
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
1525
1568
|
const block = editor.range.anchor.element.getBlock()
|
1526
1569
|
elementToParagraph(block)
|
1527
1570
|
block.parsedom = 'pre'
|
1528
|
-
const paragraph =
|
1529
|
-
|
1530
|
-
|
1571
|
+
const paragraph = AlexElement.create({
|
1572
|
+
type: 'block',
|
1573
|
+
parsedom: AlexElement.BLOCK_NODE,
|
1574
|
+
children: [
|
1575
|
+
{
|
1576
|
+
type: 'closed',
|
1577
|
+
parsedom: 'br'
|
1578
|
+
}
|
1579
|
+
]
|
1580
|
+
})
|
1531
1581
|
editor.addElementAfter(paragraph, block)
|
1532
1582
|
}
|
1533
1583
|
//起点和终点不在一起
|
@@ -1543,10 +1593,16 @@ export const insertCodeBlock = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
1543
1593
|
obj[el.element.getBlock().key] = [el.element.clone()]
|
1544
1594
|
}
|
1545
1595
|
})
|
1546
|
-
const pre =
|
1596
|
+
const pre = AlexElement.create({
|
1597
|
+
type: 'block',
|
1598
|
+
parsedom: 'pre'
|
1599
|
+
})
|
1547
1600
|
Object.keys(obj).forEach((key, index) => {
|
1548
1601
|
if (index > 0) {
|
1549
|
-
const text =
|
1602
|
+
const text = AlexElement.create({
|
1603
|
+
type: 'text',
|
1604
|
+
textcontent: '\n'
|
1605
|
+
})
|
1550
1606
|
if (pre.hasChildren()) {
|
1551
1607
|
editor.addElementTo(text, pre, pre.children!.length)
|
1552
1608
|
} else {
|
@@ -1563,9 +1619,16 @@ export const insertCodeBlock = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
1563
1619
|
})
|
1564
1620
|
editor.delete()
|
1565
1621
|
editor.insertElement(pre)
|
1566
|
-
const paragraph =
|
1567
|
-
|
1568
|
-
|
1622
|
+
const paragraph = AlexElement.create({
|
1623
|
+
type: 'block',
|
1624
|
+
parsedom: AlexElement.BLOCK_NODE,
|
1625
|
+
children: [
|
1626
|
+
{
|
1627
|
+
type: 'closed',
|
1628
|
+
parsedom: 'br'
|
1629
|
+
}
|
1630
|
+
]
|
1631
|
+
})
|
1569
1632
|
editor.addElementAfter(paragraph, pre)
|
1570
1633
|
}
|
1571
1634
|
}
|
@@ -1581,7 +1644,10 @@ export const insertSeparator = (editor: AlexEditor) => {
|
|
1581
1644
|
if (!editor.range) {
|
1582
1645
|
return
|
1583
1646
|
}
|
1584
|
-
const separator =
|
1647
|
+
const separator = AlexElement.create({
|
1648
|
+
type: 'closed',
|
1649
|
+
parsedom: 'hr'
|
1650
|
+
})
|
1585
1651
|
editor.insertElement(separator)
|
1586
1652
|
editor.range.anchor.moveToEnd(separator)
|
1587
1653
|
editor.range.focus.moveToEnd(separator)
|