vue-editify 0.1.44 → 0.1.46
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 +1 -1
- package/lib/editify/props.d.ts +1 -1
- package/lib/editify.es.js +130 -61
- package/lib/editify.umd.js +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/style.css +1 -1
- package/package.json +2 -2
- package/src/editify/editify.less +4 -2
- package/src/editify/editify.vue +136 -57
- package/src/editify/props.ts +1 -1
- package/src/icon/iconfont.ttf +0 -0
- package/src/icon/iconfont.woff +0 -0
- package/src/index.ts +1 -1
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "vue-editify",
|
3
|
-
"version": "0.1.
|
3
|
+
"version": "0.1.46",
|
4
4
|
"private": false,
|
5
5
|
"sideEffects": [
|
6
6
|
"*.css"
|
@@ -17,7 +17,7 @@
|
|
17
17
|
"lib": "vue-tsc && vite build"
|
18
18
|
},
|
19
19
|
"dependencies": {
|
20
|
-
"alex-editor": "^1.4.
|
20
|
+
"alex-editor": "^1.4.8",
|
21
21
|
"dap-util": "^1.5.4",
|
22
22
|
"highlight.js": "^11.8.0",
|
23
23
|
"katex": "^0.16.10",
|
package/src/editify/editify.less
CHANGED
@@ -263,8 +263,9 @@
|
|
263
263
|
height: auto;
|
264
264
|
border-radius: 2px;
|
265
265
|
vertical-align: text-bottom;
|
266
|
-
margin: 0
|
266
|
+
margin: 0;
|
267
267
|
max-width: 100%;
|
268
|
+
min-width: 100px;
|
268
269
|
}
|
269
270
|
//视频样式
|
270
271
|
:deep(video) {
|
@@ -275,8 +276,9 @@
|
|
275
276
|
vertical-align: text-bottom;
|
276
277
|
background-color: #000;
|
277
278
|
object-fit: contain;
|
278
|
-
margin: 0
|
279
|
+
margin: 0;
|
279
280
|
max-width: 100%;
|
281
|
+
min-width: 100px;
|
280
282
|
}
|
281
283
|
//引用样式
|
282
284
|
:deep(blockquote) {
|
package/src/editify/editify.vue
CHANGED
@@ -28,7 +28,7 @@ import { isTask, elementToParagraph, getMatchElementsByRange, hasTableInRange, h
|
|
28
28
|
import Toolbar from '../components/toolbar/toolbar.vue'
|
29
29
|
import Menu from '../components/menu/menu.vue'
|
30
30
|
import Layer from '../components/layer/layer.vue'
|
31
|
-
import { EditifyProps,
|
31
|
+
import { EditifyProps, EditifyResizeParamsType, EditifyToolbarOptionsType } from './props'
|
32
32
|
import { trans } from '../locale'
|
33
33
|
import { LanguagesItemType } from '../hljs'
|
34
34
|
|
@@ -52,8 +52,8 @@ const isModelChange = ref<boolean>(false)
|
|
52
52
|
const isInputChinese = ref<boolean>(false)
|
53
53
|
//工具条和菜单栏判定延时器
|
54
54
|
const rangeUpdateTimer = ref<any>(null)
|
55
|
-
|
56
|
-
const
|
55
|
+
//拖拽记录数据
|
56
|
+
const resizeParams = ref<EditifyResizeParamsType>({
|
57
57
|
element: null, //被拖拽的td
|
58
58
|
start: 0 //水平方向起点位置
|
59
59
|
})
|
@@ -344,96 +344,163 @@ const setVideoHeight = () => {
|
|
344
344
|
video.style.height = video.offsetWidth / props.videoRatio + 'px'
|
345
345
|
})
|
346
346
|
}
|
347
|
-
|
347
|
+
//鼠标在页面按下:处理表格拖拽改变列宽、拖拽改变图片视频宽度和菜单栏是否使用判断
|
348
348
|
const documentMouseDown = (e: Event) => {
|
349
349
|
if (props.disabled) {
|
350
350
|
return
|
351
351
|
}
|
352
|
+
const elm = e.target as HTMLElement
|
353
|
+
const event = e as MouseEvent
|
352
354
|
//鼠标在编辑器内按下
|
353
|
-
if (DapElement.isContains(contentRef.value!,
|
354
|
-
const elm = <HTMLElement>e.target
|
355
|
+
if (DapElement.isContains(contentRef.value!, elm)) {
|
355
356
|
const key = DapData.get(elm, 'data-alex-editor-key')
|
356
357
|
if (key) {
|
357
358
|
const element = editor.value!.getElementByKey(key)
|
358
|
-
if (element
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
359
|
+
if (element) {
|
360
|
+
//如果是td则表示拖拽改变列宽
|
361
|
+
if (element.parsedom == 'td') {
|
362
|
+
const length = element.parent!.children!.length
|
363
|
+
//最后一个td不设置
|
364
|
+
if (element.parent!.children![length - 1].isEqual(element)) {
|
365
|
+
return
|
366
|
+
}
|
367
|
+
const rect = DapElement.getElementBounding(elm)
|
368
|
+
//在可拖拽范围内
|
369
|
+
if (event.pageX >= Math.abs(rect.left + elm.offsetWidth - 5) && event.pageX <= Math.abs(rect.left + elm.offsetWidth + 5)) {
|
370
|
+
resizeParams.value.element = element
|
371
|
+
resizeParams.value.start = event.pageX
|
372
|
+
}
|
363
373
|
}
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
374
|
+
//如果是img或者video则表示拖拽改变图片视频宽度
|
375
|
+
else if (['img', 'video'].includes(element.parsedom!)) {
|
376
|
+
const rect = DapElement.getElementBounding(elm)
|
377
|
+
//在可拖拽范围内
|
378
|
+
if (event.pageX >= Math.abs(rect.left + elm.offsetWidth - 10) && event.pageX <= Math.abs(rect.left + elm.offsetWidth)) {
|
379
|
+
resizeParams.value.element = element
|
380
|
+
resizeParams.value.start = event.pageX
|
381
|
+
}
|
369
382
|
}
|
370
383
|
}
|
371
384
|
}
|
372
385
|
}
|
373
386
|
//如果点击了除编辑器外的地方,菜单栏不可使用
|
374
|
-
if (!DapElement.isContains(elRef.value!,
|
387
|
+
if (!DapElement.isContains(elRef.value!, elm) && !isSourceView.value) {
|
375
388
|
canUseMenu.value = false
|
376
389
|
}
|
377
390
|
}
|
378
|
-
|
391
|
+
//鼠标在页面移动:处理表格拖拽改变列宽、拖拽改变图片视频宽度
|
379
392
|
const documentMouseMove = (e: Event) => {
|
380
393
|
if (props.disabled) {
|
381
394
|
return
|
382
395
|
}
|
383
|
-
|
384
|
-
|
396
|
+
const event = e as MouseEvent
|
397
|
+
const elm = e.target as HTMLElement
|
398
|
+
//如果鼠标在图片和视频上
|
399
|
+
if (DapElement.isContains(contentRef.value!, elm) && ['img', 'video'].includes(elm.tagName.toLocaleLowerCase())) {
|
400
|
+
const rect = DapElement.getElementBounding(elm)
|
401
|
+
//在可拖拽范围内改变鼠标样式
|
402
|
+
if (event.pageX >= Math.abs(rect.left + elm.offsetWidth - 10) && event.pageX <= Math.abs(rect.left + elm.offsetWidth)) {
|
403
|
+
elm.style.cursor = 'col-resize'
|
404
|
+
} else {
|
405
|
+
elm.style.cursor = ''
|
406
|
+
}
|
385
407
|
}
|
386
|
-
|
387
|
-
if (tables.length != 1) {
|
408
|
+
if (!resizeParams.value.element) {
|
388
409
|
return
|
389
410
|
}
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
411
|
+
//表格列宽拖拽
|
412
|
+
if (resizeParams.value.element.parsedom == 'td') {
|
413
|
+
const tables = getMatchElementsByRange(editor.value!, dataRangeCaches.value, { parsedom: 'table' })
|
414
|
+
if (tables.length != 1) {
|
415
|
+
return
|
416
|
+
}
|
417
|
+
const colgroup = tables[0].children!.find(item => {
|
418
|
+
return item.parsedom == 'colgroup'
|
419
|
+
})!
|
420
|
+
const index = resizeParams.value.element.parent!.children!.findIndex(el => {
|
421
|
+
return el.isEqual(resizeParams.value.element!)
|
422
|
+
})
|
423
|
+
const width = `${resizeParams.value.element.elm!.offsetWidth + event.pageX - resizeParams.value.start}`
|
424
|
+
colgroup.children![index].marks!['width'] = width
|
425
|
+
colgroup.children![index].elm!.setAttribute('width', width)
|
426
|
+
resizeParams.value.start = event.pageX
|
427
|
+
}
|
428
|
+
//图片视频拖拽改变宽度
|
429
|
+
else if (['img', 'video'].includes(resizeParams.value.element.parsedom!)) {
|
430
|
+
const width = `${resizeParams.value.element.elm!.offsetWidth + event.pageX - resizeParams.value.start}px`
|
431
|
+
if (resizeParams.value.element.hasStyles()) {
|
432
|
+
resizeParams.value.element.styles!['width'] = width
|
433
|
+
} else {
|
434
|
+
resizeParams.value.element.styles = {
|
435
|
+
width: width
|
436
|
+
}
|
437
|
+
}
|
438
|
+
resizeParams.value.element.elm!.style.width = width
|
439
|
+
//视频宽度改变的同时需要设置高度
|
440
|
+
if (resizeParams.value.element.parsedom == 'video') {
|
441
|
+
setVideoHeight()
|
442
|
+
}
|
443
|
+
resizeParams.value.start = event.pageX
|
444
|
+
}
|
400
445
|
}
|
401
|
-
|
446
|
+
//鼠标在页面松开:处理表格拖拽改变列宽、拖拽改变图片视频宽度
|
402
447
|
const documentMouseUp = () => {
|
403
448
|
if (props.disabled) {
|
404
449
|
return
|
405
450
|
}
|
406
|
-
if (!
|
451
|
+
if (!resizeParams.value.element) {
|
407
452
|
return
|
408
453
|
}
|
409
|
-
|
410
|
-
if (
|
411
|
-
|
454
|
+
//表格列宽拖拽
|
455
|
+
if (resizeParams.value.element.parsedom == 'td') {
|
456
|
+
const tables = getMatchElementsByRange(editor.value!, dataRangeCaches.value, { parsedom: 'table' })
|
457
|
+
if (tables.length != 1) {
|
458
|
+
return
|
459
|
+
}
|
460
|
+
const colgroup = tables[0].children!.find(item => {
|
461
|
+
return item.parsedom == 'colgroup'
|
462
|
+
})!
|
463
|
+
const index = resizeParams.value.element.parent!.children!.findIndex(el => {
|
464
|
+
return el.isEqual(resizeParams.value.element!)
|
465
|
+
})
|
466
|
+
const width = parseFloat(colgroup.children![index].marks!['width'])
|
467
|
+
if (!isNaN(width)) {
|
468
|
+
colgroup.children![index].marks!['width'] = `${Number(((width / resizeParams.value.element.parent!.elm!.offsetWidth) * 100).toFixed(2))}%`
|
469
|
+
editor.value!.formatElementStack()
|
470
|
+
editor.value!.domRender()
|
471
|
+
editor.value!.rangeRender()
|
472
|
+
}
|
473
|
+
resizeParams.value.element = null
|
474
|
+
resizeParams.value.start = 0
|
412
475
|
}
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
476
|
+
//图片视频拖拽改变宽度
|
477
|
+
else if (['img', 'video'].includes(resizeParams.value.element.parsedom!)) {
|
478
|
+
const width = parseFloat(resizeParams.value.element.styles!['width'])
|
479
|
+
if (!isNaN(width)) {
|
480
|
+
if (resizeParams.value.element.hasStyles()) {
|
481
|
+
resizeParams.value.element.styles!['width'] = `${Number(((width / DapElement.width(contentRef.value!)) * 100).toFixed(2))}%`
|
482
|
+
} else {
|
483
|
+
resizeParams.value.element.styles = {
|
484
|
+
width: `${Number(((width / DapElement.width(contentRef.value!)) * 100).toFixed(2))}%`
|
485
|
+
}
|
486
|
+
}
|
487
|
+
editor.value!.formatElementStack()
|
488
|
+
editor.value!.domRender()
|
489
|
+
editor.value!.rangeRender()
|
490
|
+
}
|
491
|
+
resizeParams.value.element = null
|
492
|
+
resizeParams.value.start = 0
|
425
493
|
}
|
426
|
-
tableColumnResizeParams.value.element = null
|
427
|
-
tableColumnResizeParams.value.start = 0
|
428
494
|
}
|
429
495
|
//鼠标点击页面:处理任务列表复选框勾选
|
430
496
|
const documentClick = (e: Event) => {
|
431
497
|
if (props.disabled) {
|
432
498
|
return
|
433
499
|
}
|
500
|
+
const elm = e.target as HTMLElement
|
501
|
+
const event = e as MouseEvent
|
434
502
|
//鼠标在编辑器内点击
|
435
|
-
if (DapElement.isContains(contentRef.value!,
|
436
|
-
const elm = <HTMLElement>e.target
|
503
|
+
if (DapElement.isContains(contentRef.value!, elm)) {
|
437
504
|
const key = DapData.get(elm, 'data-alex-editor-key')
|
438
505
|
if (key) {
|
439
506
|
const element = editor.value!.getElementByKey(key)!
|
@@ -441,7 +508,7 @@ const documentClick = (e: Event) => {
|
|
441
508
|
if (isTask(element)) {
|
442
509
|
const rect = DapElement.getElementBounding(elm)
|
443
510
|
//在复选框范围内
|
444
|
-
if (
|
511
|
+
if (event.pageX >= Math.abs(rect.left) && event.pageX <= Math.abs(rect.left + 16) && event.pageY >= Math.abs(rect.top + elm.offsetHeight / 2 - 8) && event.pageY <= Math.abs(rect.top + elm.offsetHeight / 2 + 8)) {
|
445
512
|
//取消勾选
|
446
513
|
if (element.marks!['data-editify-task'] == 'checked') {
|
447
514
|
element.marks!['data-editify-task'] = 'uncheck'
|
@@ -483,6 +550,10 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
|
|
483
550
|
if (el.marks!['disabled']) {
|
484
551
|
marks['disabled'] = el.marks!['disabled']
|
485
552
|
}
|
553
|
+
//图片的alt属性保留
|
554
|
+
if (el.parsedom == 'img' && el.marks!['alt']) {
|
555
|
+
marks['alt'] = el.marks!['alt']
|
556
|
+
}
|
486
557
|
//图片和视频的src属性保留
|
487
558
|
if (['img', 'video'].includes(el.parsedom!) && el.marks!['src']) {
|
488
559
|
marks['src'] = el.marks!['src']
|
@@ -527,6 +598,10 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
|
|
527
598
|
if (el.parsedom == 'div' && el.marks!['data-editify-task']) {
|
528
599
|
marks['data-editify-task'] = el.marks!['data-editify-task']
|
529
600
|
}
|
601
|
+
//表格列宽属性保留
|
602
|
+
if (el.parsedom == 'col' && el.marks!['width']) {
|
603
|
+
marks['width'] = el.marks!['width']
|
604
|
+
}
|
530
605
|
//表格单元格colspan属性保留
|
531
606
|
if (['td', 'th'].includes(el.parsedom!) && el.marks!['colspan']) {
|
532
607
|
marks['colspan'] = el.marks!['colspan']
|
@@ -542,6 +617,10 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
|
|
542
617
|
}
|
543
618
|
//处理需要保留的样式
|
544
619
|
if (el.hasStyles()) {
|
620
|
+
//图片和视频保留width样式
|
621
|
+
if (['img', 'video'].includes(el.parsedom!) && el.styles!['width']) {
|
622
|
+
styles['width'] = el.styles!['width']
|
623
|
+
}
|
545
624
|
//块元素保留text-indent样式
|
546
625
|
if ((el.isBlock() || el.isInblock()) && el.styles!['text-indent']) {
|
547
626
|
styles['text-indent'] = el.styles!['text-indent']
|
@@ -649,10 +728,10 @@ const handleEditorClick = (e: Event) => {
|
|
649
728
|
if (props.disabled || isSourceView.value) {
|
650
729
|
return
|
651
730
|
}
|
652
|
-
const
|
731
|
+
const elm = e.target as HTMLElement
|
653
732
|
//点击的是图片或者视频
|
654
|
-
if (
|
655
|
-
const key = Number(
|
733
|
+
if (elm.nodeName.toLocaleLowerCase() == 'img' || elm.nodeName.toLocaleLowerCase() == 'video') {
|
734
|
+
const key = Number(elm.getAttribute('data-editify-element'))
|
656
735
|
if (DapNumber.isNumber(key)) {
|
657
736
|
const element = editor.value!.getElementByKey(key)!
|
658
737
|
if (!editor.value!.range) {
|
package/src/editify/props.ts
CHANGED
@@ -4,7 +4,7 @@ import { PluginType, MenuConfigType, ObjectType, ToolbarConfigType } from '../co
|
|
4
4
|
import { AlexElement } from 'alex-editor'
|
5
5
|
import { LocaleType } from '../locale'
|
6
6
|
|
7
|
-
export type
|
7
|
+
export type EditifyResizeParamsType = {
|
8
8
|
element: AlexElement | null
|
9
9
|
start: number
|
10
10
|
}
|
package/src/icon/iconfont.ttf
CHANGED
Binary file
|
package/src/icon/iconfont.woff
CHANGED
Binary file
|