vue-editify 0.1.47 → 0.1.48
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.
- 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)
|