dragon-editor 3.2.2 → 3.3.0
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/dist/module.json +1 -1
- package/dist/runtime/components/DragonEditor.vue +162 -74
- package/dist/runtime/components/DragonEditorViewer.vue +2 -1
- package/dist/runtime/scss/editor.css +14 -2
- package/dist/runtime/store.d.ts +1 -1
- package/dist/runtime/utils/convertor.d.ts +1 -1
- package/dist/runtime/utils/convertor.mjs +6 -6
- package/dist/runtime/utils/keyboardEvent.mjs +10 -7
- package/dist/runtime/utils/style.mjs +9 -6
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -1,74 +1,92 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="dragon-editor" :class="{ '--hasMenu': props.useMenuBar === true }" @mousemove="resizeEvent" @touchmove="resizeEvent" @mouseup="resizeEventEnd" @touchend="resizeEventEnd" @mouseleave="resizeEventEnd" ref="$editor">
|
|
3
3
|
<div v-if="props.useMenuBar === true" class="de-menu-bar" :style="{ top: `${menuBarTop}px` }">
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<
|
|
30
|
-
<
|
|
31
|
-
class="de-path"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
</
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
</
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
</
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
</
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</
|
|
71
|
-
|
|
4
|
+
<div class="de-menu-wrap">
|
|
5
|
+
<button class="de-menu de-menu-add" @click="isActiveAddBlockMenu = !isActiveAddBlockMenu">
|
|
6
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
7
|
+
<path class="de-path" d="M50.6667 34.6668H34.6667V50.6668H29.3334V34.6668H13.3334V29.3335H29.3334V13.3335H34.6667V29.3335H50.6667V34.6668Z"></path>
|
|
8
|
+
</svg>
|
|
9
|
+
</button>
|
|
10
|
+
|
|
11
|
+
<button class="de-menu" @click="setDecoration('bold')">
|
|
12
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
13
|
+
<path class="de-path" d="M40.6 31.4402C43.1866 29.6535 45 26.7202 45 24.0002C45 17.9735 40.3333 13.3335 34.3333 13.3335H17.6666V50.6668H36.44C42.0133 50.6668 46.3333 46.1335 46.3333 40.5602C46.3333 36.5068 44.04 33.0402 40.6 31.4402ZM25.6666 20.0002H33.6666C35.88 20.0002 37.6666 21.7868 37.6666 24.0002C37.6666 26.2135 35.88 28.0002 33.6666 28.0002H25.6666V20.0002ZM35 44.0002H25.6666V36.0002H35C37.2133 36.0002 39 37.7868 39 40.0002C39 42.2135 37.2133 44.0002 35 44.0002Z"></path>
|
|
14
|
+
</svg>
|
|
15
|
+
</button>
|
|
16
|
+
|
|
17
|
+
<button class="de-menu" @click="setDecoration('italic')">
|
|
18
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
19
|
+
<path class="de-path" d="M26.6667 13.3335V21.3335H32.56L23.44 42.6668H16V50.6668H37.3333V42.6668H31.44L40.56 21.3335H48V13.3335H26.6667Z"></path>
|
|
20
|
+
</svg>
|
|
21
|
+
</button>
|
|
22
|
+
|
|
23
|
+
<button class="de-menu" @click="setDecoration('underline')">
|
|
24
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
25
|
+
<path class="de-path" d="M32 45.3333C40.8267 45.3333 48 38.16 48 29.3333V8H41.3334V29.3333C41.3334 34.48 37.1467 38.6667 32 38.6667C26.8534 38.6667 22.6667 34.48 22.6667 29.3333V8H16V29.3333C16 38.16 23.1734 45.3333 32 45.3333ZM13.3334 50.6667V56H50.6667V50.6667H13.3334Z"></path>
|
|
26
|
+
</svg>
|
|
27
|
+
</button>
|
|
28
|
+
|
|
29
|
+
<button class="de-menu" @click="setDecoration('strikethrough')">
|
|
30
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
31
|
+
<path class="de-path" d="M26.6667 52H37.3333V44H26.6667V52ZM13.3333 12V20H26.6667V28H37.3333V20H50.6667V12H13.3333ZM8 38.6667H56V33.3333H8V38.6667Z"></path>
|
|
32
|
+
</svg>
|
|
33
|
+
</button>
|
|
34
|
+
|
|
35
|
+
<button class="de-menu" @click="setDecoration('code')">
|
|
36
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
37
|
+
<path class="de-path" d="M25.0667 44.2667L12.8 32L25.0667 19.7333L21.3334 16L5.33337 32L21.3334 48L25.0667 44.2667ZM38.9334 44.2667L51.2 32L38.9334 19.7333L42.6667 16L58.6667 32L42.6667 48L38.9334 44.2667Z"></path>
|
|
38
|
+
</svg>
|
|
39
|
+
</button>
|
|
40
|
+
|
|
41
|
+
<label class="de-menu">
|
|
42
|
+
<input type="file" hidden accept=".jpg,.jpeg,.png,.webp,.gif" @change="chooseMediaEvent" />
|
|
43
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
44
|
+
<path d="M50.6667 13.3333V50.6667H13.3333V13.3333H50.6667ZM50.6667 8H13.3333C10.4 8 8 10.4 8 13.3333V50.6667C8 53.6 10.4 56 13.3333 56H50.6667C53.6 56 56 53.6 56 50.6667V13.3333C56 10.4 53.6 8 50.6667 8ZM37.7067 31.6267L29.7067 41.9467L24 35.04L16 45.3333H48L37.7067 31.6267Z"></path>
|
|
45
|
+
</svg>
|
|
46
|
+
</label>
|
|
47
|
+
|
|
48
|
+
<button class="de-menu" @click="setTextAlign('left')">
|
|
49
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
50
|
+
<path class="de-path" d="M40 40H8V45.3333H40V40ZM40 18.6667H8V24H40V18.6667ZM8 34.6667H56V29.3333H8V34.6667ZM8 56H56V50.6667H8V56ZM8 8V13.3333H56V8H8Z"></path>
|
|
51
|
+
</svg>
|
|
52
|
+
</button>
|
|
53
|
+
|
|
54
|
+
<button class="de-menu" @click="setTextAlign('center')">
|
|
55
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
56
|
+
<path class="de-path" d="M18.6667 40V45.3333H45.3333V40H18.6667ZM8 56H56V50.6667H8V56ZM8 34.6667H56V29.3333H8V34.6667ZM18.6667 18.6667V24H45.3333V18.6667H18.6667ZM8 8V13.3333H56V8H8Z"></path>
|
|
57
|
+
</svg>
|
|
58
|
+
</button>
|
|
59
|
+
|
|
60
|
+
<button class="de-menu" @click="setTextAlign('right')">
|
|
61
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
62
|
+
<path class="de-path" d="M8 56H56V50.6667H8V56ZM24 45.3333H56V40H24V45.3333ZM8 34.6667H56V29.3333H8V34.6667ZM24 24H56V18.6667H24V24ZM8 8V13.3333H56V8H8Z"></path>
|
|
63
|
+
</svg>
|
|
64
|
+
</button>
|
|
65
|
+
|
|
66
|
+
<button class="de-menu" @click="setTextAlign('justify')">
|
|
67
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
68
|
+
<path class="de-path" d="M8 56H56V50.6667H8V56ZM8 45.3333H56V40H8V45.3333ZM8 34.6667H56V29.3333H8V34.6667ZM8 24H56V18.6667H8V24ZM8 8V13.3333H56V8H8Z"></path>
|
|
69
|
+
</svg>
|
|
70
|
+
</button>
|
|
71
|
+
|
|
72
|
+
<button class="de-menu" @click="moveBlock('up')">
|
|
73
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
74
|
+
<path d="M9.33333 35.9999C9.33333 29.4666 14.0267 24.0799 20.2133 22.9066L16.24 26.9066L20 30.6666L30.6667 19.9733L20 9.33325L16.24 13.0933L20.4533 17.3066V17.4666C11.2 18.5599 4 26.4533 4 35.9999C4 46.3199 12.3467 54.6666 22.6667 54.6666H30.6667V49.3333H22.6667C15.3067 49.3333 9.33333 43.3599 9.33333 35.9999Z M36 35.9999V54.6666H60V35.9999H36ZM54.6667 49.3333H41.3333V41.3333H54.6667V49.3333Z M60 11.9999H36V30.6666H60V11.9999Z"></path>
|
|
75
|
+
</svg>
|
|
76
|
+
</button>
|
|
77
|
+
|
|
78
|
+
<button class="de-menu" @click="moveBlock('down')">
|
|
79
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
80
|
+
<path d="M9.33333 27.9999C9.33333 34.5333 14.0267 39.9199 20.2133 41.0933L16.24 37.1199L20 33.3333L30.6667 44.0266L20 54.6666L16.24 50.9066L20.4533 46.6933V46.5333C11.2 45.4399 4 37.5466 4 27.9999C4 17.6799 12.3467 9.33325 22.6667 9.33325H30.6667V14.6666H22.6667C15.3067 14.6666 9.33333 20.6399 9.33333 27.9999Z M60 27.9999V9.33325H36V27.9999H60ZM54.6667 22.6666H41.3333V14.6666H54.6667V22.6666Z M60 33.3333H36V51.9999H60V33.3333Z"></path>
|
|
81
|
+
</svg>
|
|
82
|
+
</button>
|
|
83
|
+
|
|
84
|
+
<button class="de-menu" @click="deleteBlock">
|
|
85
|
+
<svg class="de-icon" viewBox="0 0 64 64">
|
|
86
|
+
<path class="de-path --red" fill-rule="evenodd" clip-rule="evenodd" d="M42.6667 24V50.6667H21.3334V24H42.6667ZM38.6667 8H25.3334L22.6667 10.6667H13.3334V16H50.6667V10.6667H41.3334L38.6667 8ZM48 18.6667H16V50.6667C16 53.6 18.4 56 21.3334 56H42.6667C45.6 56 48 53.6 48 50.6667V18.6667Z"></path>
|
|
87
|
+
</svg>
|
|
88
|
+
</button>
|
|
89
|
+
</div>
|
|
72
90
|
|
|
73
91
|
<div class="de-block-menu-area" :class="{ '--active': isActiveAddBlockMenu }">
|
|
74
92
|
<div class="de-list">
|
|
@@ -85,7 +103,7 @@
|
|
|
85
103
|
</div>
|
|
86
104
|
</div>
|
|
87
105
|
|
|
88
|
-
<div class="de-control-bar" :class="{ '--active': editorStore.controlBar.active === true }" :style="{ top: `${editorStore.controlBar.y}px`, left: `${editorStore.controlBar.x}px` }" ref="$controlBar">
|
|
106
|
+
<div v-if="editorStore.$currentBlock !== null" class="de-control-bar" :class="{ '--active': editorStore.controlBar.active === true }" :style="{ top: `${editorStore.controlBar.y}px`, left: `${editorStore.controlBar.x}px` }" ref="$controlBar">
|
|
89
107
|
<div v-if="['code'].includes(curruntType) === true" class="de-col">
|
|
90
108
|
<p class="de-name">Theme :</p>
|
|
91
109
|
<select class="de-selector" v-model="codeBlockTheme" @change="codeBlockThemeChangeEvent">
|
|
@@ -133,7 +151,7 @@ import { _findScrollingElement, _findContentEditableElement } from "../utils/ele
|
|
|
133
151
|
import { _elementKeyEvent, _hotKeyEvent, _copyEvent, _pasteEvent } from "../utils/keyboardEvent";
|
|
134
152
|
import { _getBlockType, _createTextBlock, _createHeadingBlock, _createListBlock, _createImageBlock, _createCustomBlock, _createCodeBlock } from "../utils/block";
|
|
135
153
|
import { _setNodeStyle, _setTextAlign } from "../utils/style";
|
|
136
|
-
import { _setCursorData, _clenupCursor } from "../utils/cursor";
|
|
154
|
+
import { _setCursor, _setCursorData, _clenupCursor } from "../utils/cursor";
|
|
137
155
|
import { _getContentData, _setContentData } from "../utils/convertor";
|
|
138
156
|
import { _addBlockToContent } from "../utils/content";
|
|
139
157
|
import "../type.d.ts";
|
|
@@ -144,9 +162,14 @@ const props = defineProps({
|
|
|
144
162
|
requiard: false,
|
|
145
163
|
default: () => true,
|
|
146
164
|
},
|
|
165
|
+
imageHostURL: {
|
|
166
|
+
type: String,
|
|
167
|
+
requiard: false,
|
|
168
|
+
default: () => "",
|
|
169
|
+
},
|
|
147
170
|
});
|
|
148
171
|
const emit = defineEmits<{
|
|
149
|
-
(e: "
|
|
172
|
+
(e: "uploadImageEvent", file: File): DEImage;
|
|
150
173
|
}>();
|
|
151
174
|
const editorStore = useEditorStore();
|
|
152
175
|
const isActiveAddBlockMenu = ref<boolean>(false);
|
|
@@ -306,7 +329,18 @@ function checkOthersideClick(event: MouseEvent) {
|
|
|
306
329
|
// 블럭 삭제
|
|
307
330
|
function deleteBlock() {
|
|
308
331
|
if (editorStore.$currentBlock !== null) {
|
|
332
|
+
const childCount: number = editorStore.$content?.childElementCount ?? 1;
|
|
333
|
+
|
|
309
334
|
editorStore.$currentBlock.remove();
|
|
335
|
+
editorStore.setCurrentBlock(null);
|
|
336
|
+
|
|
337
|
+
if (childCount < 2) {
|
|
338
|
+
// 모든 엘리먼트를 지우려는 경우
|
|
339
|
+
const $block = _createTextBlock();
|
|
340
|
+
|
|
341
|
+
editorStore.$content?.insertAdjacentElement("beforeend", $block);
|
|
342
|
+
_setCursor($block, 0);
|
|
343
|
+
}
|
|
310
344
|
}
|
|
311
345
|
}
|
|
312
346
|
|
|
@@ -374,6 +408,9 @@ function listBlockStyleChangeEvent() {
|
|
|
374
408
|
* 컨트롤 바 이벤트 관련 영역 종료
|
|
375
409
|
*/
|
|
376
410
|
|
|
411
|
+
/**
|
|
412
|
+
* 메뉴 이벤트 관련 영역
|
|
413
|
+
*/
|
|
377
414
|
function addBlock(type: string) {
|
|
378
415
|
isActiveAddBlockMenu.value = false;
|
|
379
416
|
|
|
@@ -455,6 +492,10 @@ function addCustomBlock(HTML: string, classList: string[] = []) {
|
|
|
455
492
|
}
|
|
456
493
|
|
|
457
494
|
function addImageBlock(data: DEImage) {
|
|
495
|
+
if (props.imageHostURL !== "") {
|
|
496
|
+
data.src = props.imageHostURL + data.src;
|
|
497
|
+
}
|
|
498
|
+
|
|
458
499
|
const blockStructure = _createImageBlock({
|
|
459
500
|
...data,
|
|
460
501
|
type: "image",
|
|
@@ -475,7 +516,7 @@ function setTextAlign(type: DETextalign) {
|
|
|
475
516
|
|
|
476
517
|
function getContentData(): DEContentData {
|
|
477
518
|
if (editorStore.$content !== null) {
|
|
478
|
-
return _getContentData(editorStore.$content);
|
|
519
|
+
return _getContentData(editorStore.$content, props.imageHostURL);
|
|
479
520
|
} else {
|
|
480
521
|
console.error("[DragonEditor] Con't find content Element.");
|
|
481
522
|
return [];
|
|
@@ -486,6 +527,41 @@ function setContentData(data: DEContentData) {
|
|
|
486
527
|
_setContentData(data, editorStore);
|
|
487
528
|
}
|
|
488
529
|
|
|
530
|
+
function moveBlock(type: "up" | "down") {
|
|
531
|
+
if (editorStore.$currentBlock !== null) {
|
|
532
|
+
let $target: Element | null;
|
|
533
|
+
|
|
534
|
+
if (type === "up") {
|
|
535
|
+
$target = editorStore.$currentBlock.previousElementSibling;
|
|
536
|
+
} else {
|
|
537
|
+
$target = editorStore.$currentBlock.nextElementSibling;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if ($target !== null) {
|
|
541
|
+
($target as HTMLElement).insertAdjacentHTML(type === "up" ? "beforebegin" : "afterend", editorStore.$currentBlock.outerHTML);
|
|
542
|
+
editorStore.$currentBlock.remove();
|
|
543
|
+
|
|
544
|
+
if (type === "up") {
|
|
545
|
+
editorStore.setCurrentBlock(($target as HTMLElement).previousElementSibling as HTMLElement | null);
|
|
546
|
+
} else {
|
|
547
|
+
editorStore.setCurrentBlock(($target as HTMLElement).nextElementSibling as HTMLElement | null);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function chooseMediaEvent(event: Event) {
|
|
554
|
+
const $target = event.target as HTMLInputElement;
|
|
555
|
+
const file = $target.files![0];
|
|
556
|
+
|
|
557
|
+
emit("uploadImageEvent", file);
|
|
558
|
+
$target.value = "";
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* 메뉴 이벤트 관련 영역 종료
|
|
563
|
+
*/
|
|
564
|
+
|
|
489
565
|
onMounted(() => {
|
|
490
566
|
if ($editor.value !== undefined) {
|
|
491
567
|
editorStore.setWrapElement($editor.value);
|
|
@@ -663,7 +739,8 @@ defineExpose({
|
|
|
663
739
|
padding-top: 38px;
|
|
664
740
|
}
|
|
665
741
|
.dragon-editor .de-body {
|
|
666
|
-
display:
|
|
742
|
+
display: flex;
|
|
743
|
+
flex-direction: column;
|
|
667
744
|
gap: 4px;
|
|
668
745
|
padding: 20px;
|
|
669
746
|
line-height: 1.6;
|
|
@@ -678,12 +755,23 @@ defineExpose({
|
|
|
678
755
|
border-bottom: 1px solid #ccc;
|
|
679
756
|
z-index: 10;
|
|
680
757
|
}
|
|
758
|
+
.dragon-editor .de-menu-bar .de-menu-wrap {
|
|
759
|
+
display: flex;
|
|
760
|
+
overflow-x: auto;
|
|
761
|
+
}
|
|
681
762
|
.dragon-editor .de-menu-bar .de-menu {
|
|
763
|
+
display: flex;
|
|
764
|
+
justify-content: center;
|
|
765
|
+
align-items: center;
|
|
682
766
|
min-width: 38px;
|
|
683
767
|
height: 38px;
|
|
684
|
-
padding: 0 8px;
|
|
685
768
|
border-right: 1px solid #ccc;
|
|
686
769
|
box-sizing: border-box;
|
|
770
|
+
cursor: pointer;
|
|
771
|
+
}
|
|
772
|
+
.dragon-editor .de-menu-bar .de-menu .de-icon {
|
|
773
|
+
width: 24px;
|
|
774
|
+
height: 24px;
|
|
687
775
|
}
|
|
688
776
|
.dragon-editor .de-menu-bar .de-menu.--lastchild {
|
|
689
777
|
border-right: 0;
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
<div v-if="item.type === 'image'" class="de-block de-image-block" :class="item.classList">
|
|
23
23
|
<div class="de-image-area" :data-maxwidth="item.maxWidth">
|
|
24
|
-
<img :src="item.src" alt="" class="de-img" :width="item.width" :height="item.height" loading="lazy" />
|
|
24
|
+
<img :src="props.imageHostURL === undefined ? item.src : props.imageHostURL + item.src" alt="" class="de-img" :width="item.width" :height="item.height" loading="lazy" />
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
27
|
<p v-if="item.caption" class="de-caption">{{ item.caption }}</p>
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
<script setup lang="ts">
|
|
42
42
|
const props = defineProps<{
|
|
43
43
|
content: DEContentData;
|
|
44
|
+
imageHostURL?: string;
|
|
44
45
|
}>();
|
|
45
46
|
</script>
|
|
46
47
|
|
|
@@ -140,7 +140,8 @@
|
|
|
140
140
|
padding-top: 38px;
|
|
141
141
|
}
|
|
142
142
|
.dragon-editor .de-body {
|
|
143
|
-
display:
|
|
143
|
+
display: flex;
|
|
144
|
+
flex-direction: column;
|
|
144
145
|
gap: 4px;
|
|
145
146
|
padding: 20px;
|
|
146
147
|
line-height: 1.6;
|
|
@@ -155,12 +156,23 @@
|
|
|
155
156
|
border-bottom: 1px solid #ccc;
|
|
156
157
|
z-index: 10;
|
|
157
158
|
}
|
|
159
|
+
.dragon-editor .de-menu-bar .de-menu-wrap {
|
|
160
|
+
display: flex;
|
|
161
|
+
overflow-x: auto;
|
|
162
|
+
}
|
|
158
163
|
.dragon-editor .de-menu-bar .de-menu {
|
|
164
|
+
display: flex;
|
|
165
|
+
justify-content: center;
|
|
166
|
+
align-items: center;
|
|
159
167
|
min-width: 38px;
|
|
160
168
|
height: 38px;
|
|
161
|
-
padding: 0 8px;
|
|
162
169
|
border-right: 1px solid #ccc;
|
|
163
170
|
box-sizing: border-box;
|
|
171
|
+
cursor: pointer;
|
|
172
|
+
}
|
|
173
|
+
.dragon-editor .de-menu-bar .de-menu .de-icon {
|
|
174
|
+
width: 24px;
|
|
175
|
+
height: 24px;
|
|
164
176
|
}
|
|
165
177
|
.dragon-editor .de-menu-bar .de-menu.--lastchild {
|
|
166
178
|
border-right: 0;
|
package/dist/runtime/store.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"editorStor
|
|
|
4
4
|
setContentElement(value: HTMLDivElement): void;
|
|
5
5
|
setParentWrapElement(value: HTMLElement | Window): void;
|
|
6
6
|
setCursorData(data: DEditorCursor): void;
|
|
7
|
-
setCurrentBlock(block: HTMLElement): void;
|
|
7
|
+
setCurrentBlock(block: HTMLElement | null): void;
|
|
8
8
|
setContrulBar(value: HTMLDivElement): void;
|
|
9
9
|
controlBarActive(): void;
|
|
10
10
|
controlBarDeactive(): void;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import "../type.d.ts";
|
|
2
|
-
export declare function _getContentData($content: HTMLDivElement): DEContentData;
|
|
2
|
+
export declare function _getContentData($content: HTMLDivElement, imageHostURL: string): DEContentData;
|
|
3
3
|
export declare function _setContentData(data: DEContentData, store: any): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _createTextBlock, _createHeadingBlock, _createListBlock, _createImageBlock, _createCodeBlock, _createCustomBlock } from "./block.mjs";
|
|
2
2
|
import "../type.d.ts";
|
|
3
|
-
export function _getContentData($content) {
|
|
3
|
+
export function _getContentData($content, imageHostURL) {
|
|
4
4
|
const childList = $content.children;
|
|
5
5
|
const data = [];
|
|
6
6
|
[...childList].forEach(($child) => {
|
|
@@ -23,7 +23,7 @@ export function _getContentData($content) {
|
|
|
23
23
|
data.push(converteListToData($child));
|
|
24
24
|
break;
|
|
25
25
|
case "DIV":
|
|
26
|
-
data.push(converteDivToData($child));
|
|
26
|
+
data.push(converteDivToData($child, imageHostURL));
|
|
27
27
|
break;
|
|
28
28
|
}
|
|
29
29
|
});
|
|
@@ -84,11 +84,11 @@ function converteListToData($child) {
|
|
|
84
84
|
})
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
|
-
function converteDivToData($child) {
|
|
87
|
+
function converteDivToData($child, imageHostURL) {
|
|
88
88
|
let data;
|
|
89
89
|
switch (true) {
|
|
90
90
|
case $child.classList.contains("de-image-block"):
|
|
91
|
-
data = convertImageBlock($child);
|
|
91
|
+
data = convertImageBlock($child, imageHostURL);
|
|
92
92
|
break;
|
|
93
93
|
case $child.classList.contains("de-code-block"):
|
|
94
94
|
data = convertCodeBlock($child);
|
|
@@ -99,13 +99,13 @@ function converteDivToData($child) {
|
|
|
99
99
|
}
|
|
100
100
|
return data;
|
|
101
101
|
}
|
|
102
|
-
function convertImageBlock($imageBlock) {
|
|
102
|
+
function convertImageBlock($imageBlock, imageHostURL) {
|
|
103
103
|
const $imgArea = $imageBlock.querySelector(".de-image-area");
|
|
104
104
|
const $img = $imageBlock.querySelector(".de-img");
|
|
105
105
|
const $caption = $imageBlock.querySelector(".de-caption");
|
|
106
106
|
return {
|
|
107
107
|
type: "image",
|
|
108
|
-
src: $img.src,
|
|
108
|
+
src: imageHostURL === "" ? $img.src : $img.src.replace(imageHostURL, ""),
|
|
109
109
|
maxWidth: parseInt($imgArea.dataset["maxwidth"]),
|
|
110
110
|
width: $img.width,
|
|
111
111
|
height: $img.height,
|
|
@@ -28,7 +28,7 @@ export function _elementKeyEvent(event, store) {
|
|
|
28
28
|
keyEventCount += 1;
|
|
29
29
|
setTimeout(() => {
|
|
30
30
|
keyEventCount = 0;
|
|
31
|
-
},
|
|
31
|
+
}, 200);
|
|
32
32
|
break;
|
|
33
33
|
case "Backspace":
|
|
34
34
|
elementBackspaceEvent(event, store);
|
|
@@ -44,7 +44,7 @@ export function _elementKeyEvent(event, store) {
|
|
|
44
44
|
keyEventCount += 1;
|
|
45
45
|
setTimeout(() => {
|
|
46
46
|
keyEventCount = 0;
|
|
47
|
-
},
|
|
47
|
+
}, 200);
|
|
48
48
|
break;
|
|
49
49
|
case "Space":
|
|
50
50
|
break;
|
|
@@ -187,12 +187,15 @@ function defaultBlockEnterEvent(store, $element) {
|
|
|
187
187
|
const text = node.textContent;
|
|
188
188
|
const preSpan = document.createElement("span");
|
|
189
189
|
const nextSpan = document.createElement("span");
|
|
190
|
+
const nextText = text.slice(store.cursorData.startOffset);
|
|
190
191
|
preSpan.classList.add(...originalClassList);
|
|
191
192
|
preSpan.textContent = text.slice(0, store.cursorData.startOffset);
|
|
192
193
|
preStructure.push(preSpan);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
194
|
+
if (nextText !== "") {
|
|
195
|
+
nextSpan.classList.add(...originalClassList);
|
|
196
|
+
nextSpan.textContent = nextText;
|
|
197
|
+
nextStructure.push(nextSpan);
|
|
198
|
+
}
|
|
196
199
|
}
|
|
197
200
|
}
|
|
198
201
|
});
|
|
@@ -292,7 +295,7 @@ function defaultBlockEnterEvent(store, $element) {
|
|
|
292
295
|
}
|
|
293
296
|
});
|
|
294
297
|
}
|
|
295
|
-
const $nextBlock = _createTextBlock(
|
|
298
|
+
const $nextBlock = _createTextBlock({ type: "text", classList: [], textContent: "" });
|
|
296
299
|
$textBlock.insertAdjacentElement("afterend", $nextBlock);
|
|
297
300
|
$textBlock.replaceChildren(...preStructure);
|
|
298
301
|
$nextBlock.replaceChildren(...nextStructure);
|
|
@@ -962,7 +965,7 @@ export async function _pasteEvent(event, store, emit) {
|
|
|
962
965
|
if (imageItem !== void 0) {
|
|
963
966
|
const blob = await clipboardItems[0].getType(imageItem);
|
|
964
967
|
const file = new File([blob], `${_generateId()}.${imageItem.split("/")[1]}`);
|
|
965
|
-
emit("
|
|
968
|
+
emit("uploadImageEvent", file);
|
|
966
969
|
}
|
|
967
970
|
} else {
|
|
968
971
|
const selection = window.getSelection();
|
|
@@ -40,7 +40,7 @@ export function _setNodeStyle(className, store) {
|
|
|
40
40
|
_setCursor($element.childNodes[targetIdx], cursorOffset);
|
|
41
41
|
} else {
|
|
42
42
|
if ($parentElement.tagName === "SPAN") {
|
|
43
|
-
const classList =
|
|
43
|
+
const classList = $parentElement.classList.value.split(" ");
|
|
44
44
|
const classIdx = classList.indexOf(className);
|
|
45
45
|
if (classIdx === -1) {
|
|
46
46
|
$parentElement.classList.add(className);
|
|
@@ -92,7 +92,7 @@ export function _setNodeStyle(className, store) {
|
|
|
92
92
|
} else {
|
|
93
93
|
const $target = cursorData.startNode;
|
|
94
94
|
if ($target.tagName !== "A") {
|
|
95
|
-
const classList =
|
|
95
|
+
const classList = $target.classList.value.split(" ");
|
|
96
96
|
const classIdx = classList.indexOf(className);
|
|
97
97
|
if (classIdx === -1) {
|
|
98
98
|
if (cursorData.startOffset !== 0) {
|
|
@@ -157,7 +157,7 @@ export function _setNodeStyle(className, store) {
|
|
|
157
157
|
isDuble = true;
|
|
158
158
|
}
|
|
159
159
|
} else {
|
|
160
|
-
const classList =
|
|
160
|
+
const classList = $elementNode.classList.value.split(" ");
|
|
161
161
|
const classIdx = classList.indexOf(className);
|
|
162
162
|
if ($elementNode.tagName === "SPAN") {
|
|
163
163
|
if (classIdx === -1) {
|
|
@@ -196,7 +196,7 @@ export function _setNodeStyle(className, store) {
|
|
|
196
196
|
structureArray.push(childNode.textContent);
|
|
197
197
|
}
|
|
198
198
|
} else {
|
|
199
|
-
const classList =
|
|
199
|
+
const classList = $elementNode.classList.value.split(" ");
|
|
200
200
|
const classIdx = classList.indexOf(className);
|
|
201
201
|
if ($elementNode.tagName === "SPAN") {
|
|
202
202
|
if (isWrap === true) {
|
|
@@ -236,7 +236,7 @@ export function _setNodeStyle(className, store) {
|
|
|
236
236
|
structureArray.push(childNode.textContent);
|
|
237
237
|
}
|
|
238
238
|
} else {
|
|
239
|
-
const classList =
|
|
239
|
+
const classList = $elementNode.classList.value.split(" ");
|
|
240
240
|
const classIdx = classList.indexOf(className);
|
|
241
241
|
if ($elementNode.tagName === "SPAN") {
|
|
242
242
|
if (isWrap === true) {
|
|
@@ -351,12 +351,15 @@ export function _setTextAlign(type, store) {
|
|
|
351
351
|
if ($element.classList.contains(className) === true) {
|
|
352
352
|
$element.classList.remove(className);
|
|
353
353
|
} else {
|
|
354
|
-
const curruntClassname = alignClassList.filter((text) =>
|
|
354
|
+
const curruntClassname = alignClassList.filter((text) => $element.classList.contains(text) === true)[0];
|
|
355
355
|
if (curruntClassname !== void 0) {
|
|
356
356
|
$element.classList.remove(curruntClassname);
|
|
357
357
|
}
|
|
358
358
|
$element.classList.add(className);
|
|
359
359
|
}
|
|
360
|
+
if (store.$currentBlock.classList.contains("de-image-block") !== true) {
|
|
361
|
+
_setCursor($element, 0);
|
|
362
|
+
}
|
|
360
363
|
}
|
|
361
364
|
}
|
|
362
365
|
}
|