dragon-editor 3.0.1 → 3.1.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/README.md +4 -4
- package/dist/module.json +1 -1
- package/dist/runtime/components/DragonEditor.vue +513 -23
- package/dist/runtime/components/DragonEditorViewer.vue +308 -7
- package/dist/runtime/scss/editor.css +300 -0
- package/dist/runtime/scss/viewer.css +291 -0
- package/dist/runtime/store.d.ts +1 -0
- package/dist/runtime/store.mjs +4 -0
- package/dist/runtime/type.d.ts +74 -0
- package/dist/runtime/utils/block.d.ts +6 -4
- package/dist/runtime/utils/block.mjs +63 -22
- package/dist/runtime/utils/content.d.ts +2 -0
- package/dist/runtime/utils/content.mjs +15 -0
- package/dist/runtime/utils/convertor.d.ts +3 -2
- package/dist/runtime/utils/convertor.mjs +68 -9
- package/dist/runtime/utils/keyboardEvent.mjs +30 -19
- package/dist/runtime/utils/style.d.ts +1 -0
- package/dist/runtime/utils/style.mjs +288 -263
- package/dist/runtime/utils/ui.d.ts +0 -1
- package/dist/runtime/utils/ui.mjs +0 -35
- package/package.json +3 -2
- package/dist/runtime/plugin.d.ts +0 -2
- package/dist/runtime/plugin.mjs +0 -10
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { _createTextBlock, _createHeadingBlock, _createListBlock } from "./block.mjs";
|
|
1
|
+
import { _createTextBlock, _createHeadingBlock, _createListBlock, _createImageBlock, _createCustomBlock } from "./block.mjs";
|
|
2
|
+
import "../type.d.ts";
|
|
2
3
|
export function _getContentData($content) {
|
|
3
4
|
const childList = $content.children;
|
|
4
5
|
const data = [];
|
|
@@ -26,6 +27,7 @@ export function _getContentData($content) {
|
|
|
26
27
|
case "PRE":
|
|
27
28
|
break;
|
|
28
29
|
case "DIV":
|
|
30
|
+
data.push(converteDivToData($child));
|
|
29
31
|
break;
|
|
30
32
|
}
|
|
31
33
|
});
|
|
@@ -36,18 +38,30 @@ export function _setContentData(data, store) {
|
|
|
36
38
|
data.forEach((item) => {
|
|
37
39
|
switch (item.type) {
|
|
38
40
|
case "text":
|
|
39
|
-
childList.push(_createTextBlock(item
|
|
41
|
+
childList.push(_createTextBlock(item));
|
|
40
42
|
break;
|
|
41
43
|
case "heading":
|
|
42
|
-
childList.push(_createHeadingBlock(
|
|
44
|
+
childList.push(_createHeadingBlock(item));
|
|
43
45
|
break;
|
|
44
46
|
case "ul":
|
|
45
|
-
childList.push(_createListBlock("ul", item.child));
|
|
46
|
-
break;
|
|
47
47
|
case "ol":
|
|
48
|
-
childList.push(_createListBlock(
|
|
48
|
+
childList.push(_createListBlock(item));
|
|
49
|
+
break;
|
|
50
|
+
case "image":
|
|
51
|
+
childList.push(
|
|
52
|
+
_createImageBlock({
|
|
53
|
+
type: item.type,
|
|
54
|
+
src: item.src,
|
|
55
|
+
maxWidth: item.maxWidth,
|
|
56
|
+
width: item.width,
|
|
57
|
+
height: item.height,
|
|
58
|
+
caption: item.caption,
|
|
59
|
+
classList: item.classList
|
|
60
|
+
})
|
|
61
|
+
);
|
|
49
62
|
break;
|
|
50
|
-
case "":
|
|
63
|
+
case "custom":
|
|
64
|
+
childList.push(_createCustomBlock(item));
|
|
51
65
|
break;
|
|
52
66
|
}
|
|
53
67
|
});
|
|
@@ -56,6 +70,7 @@ export function _setContentData(data, store) {
|
|
|
56
70
|
function converteParagraphToData($child) {
|
|
57
71
|
return {
|
|
58
72
|
type: "text",
|
|
73
|
+
classList: getClassListWithoutDefaultClass($child),
|
|
59
74
|
textContent: $child.innerHTML
|
|
60
75
|
};
|
|
61
76
|
}
|
|
@@ -64,6 +79,7 @@ function converteHeadingToData($child, level) {
|
|
|
64
79
|
type: "heading",
|
|
65
80
|
level,
|
|
66
81
|
id: $child.id,
|
|
82
|
+
classList: getClassListWithoutDefaultClass($child),
|
|
67
83
|
textContent: $child.innerHTML
|
|
68
84
|
};
|
|
69
85
|
}
|
|
@@ -71,7 +87,10 @@ function converteUListToData($child) {
|
|
|
71
87
|
return {
|
|
72
88
|
type: "ul",
|
|
73
89
|
child: [...$child.children].map(($li) => {
|
|
74
|
-
return
|
|
90
|
+
return {
|
|
91
|
+
classList: getClassListWithoutDefaultClass($li),
|
|
92
|
+
textContent: $li.innerHTML
|
|
93
|
+
};
|
|
75
94
|
})
|
|
76
95
|
};
|
|
77
96
|
}
|
|
@@ -80,7 +99,47 @@ function converteOListToData($child) {
|
|
|
80
99
|
type: "ol",
|
|
81
100
|
pattern: $child.type,
|
|
82
101
|
child: [...$child.children].map(($li) => {
|
|
83
|
-
return
|
|
102
|
+
return {
|
|
103
|
+
classList: getClassListWithoutDefaultClass($li),
|
|
104
|
+
textContent: $li.innerHTML
|
|
105
|
+
};
|
|
84
106
|
})
|
|
85
107
|
};
|
|
86
108
|
}
|
|
109
|
+
function converteDivToData($child) {
|
|
110
|
+
let data;
|
|
111
|
+
switch (true) {
|
|
112
|
+
case $child.classList.contains("de-image-block"):
|
|
113
|
+
data = convertImageBlock($child);
|
|
114
|
+
break;
|
|
115
|
+
case $child.classList.contains("de-custom-block"):
|
|
116
|
+
data = convertCustomBlock($child);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
return data;
|
|
120
|
+
}
|
|
121
|
+
function convertImageBlock($imageBlock) {
|
|
122
|
+
const $imgArea = $imageBlock.querySelector(".de-image-area");
|
|
123
|
+
const $img = $imageBlock.querySelector(".de-img");
|
|
124
|
+
const $caption = $imageBlock.querySelector(".de-caption");
|
|
125
|
+
return {
|
|
126
|
+
type: "image",
|
|
127
|
+
src: $img.src,
|
|
128
|
+
maxWidth: parseInt($imgArea.dataset["maxwidth"]),
|
|
129
|
+
width: $img.width,
|
|
130
|
+
height: $img.height,
|
|
131
|
+
caption: $caption.textContent ?? "",
|
|
132
|
+
classList: getClassListWithoutDefaultClass($imageBlock)
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function convertCustomBlock($block) {
|
|
136
|
+
return {
|
|
137
|
+
type: "custom",
|
|
138
|
+
classList: getClassListWithoutDefaultClass($block),
|
|
139
|
+
textContent: $block.innerHTML
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function getClassListWithoutDefaultClass($element) {
|
|
143
|
+
const defaultClassList = ["de-block", "de-text-block", "de-heading-block", "de-list-block", "de-image-block"];
|
|
144
|
+
return [...$element.classList].filter((className) => defaultClassList.includes(className) === false);
|
|
145
|
+
}
|
|
@@ -2,13 +2,14 @@ import { _setCursor, _setCursorData, _clenupCursor, _soltingCursorDataOnElement
|
|
|
2
2
|
import { _getParentElementIfNodeIsText, _findContentEditableElement } from "./element.mjs";
|
|
3
3
|
import { _getBlockType, _createTextBlock, _createListItemBlock } from "./block.mjs";
|
|
4
4
|
import { _setNodeStyle } from "./style.mjs";
|
|
5
|
-
let
|
|
5
|
+
let keyEventCount = 0;
|
|
6
|
+
let keyEventFn;
|
|
6
7
|
export function _elementKeyEvent(event, store) {
|
|
7
8
|
_setCursorData(store);
|
|
8
9
|
switch (event.code) {
|
|
9
10
|
case "Enter":
|
|
10
11
|
event.preventDefault();
|
|
11
|
-
if (
|
|
12
|
+
if (keyEventCount === 0) {
|
|
12
13
|
_clenupCursor(store);
|
|
13
14
|
setTimeout(() => {
|
|
14
15
|
if (event.shiftKey === true) {
|
|
@@ -18,9 +19,9 @@ export function _elementKeyEvent(event, store) {
|
|
|
18
19
|
}
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
+
keyEventCount += 1;
|
|
22
23
|
setTimeout(() => {
|
|
23
|
-
|
|
24
|
+
keyEventCount = 0;
|
|
24
25
|
}, 150);
|
|
25
26
|
break;
|
|
26
27
|
case "Backspace":
|
|
@@ -28,15 +29,15 @@ export function _elementKeyEvent(event, store) {
|
|
|
28
29
|
break;
|
|
29
30
|
case "Tab":
|
|
30
31
|
event.preventDefault();
|
|
31
|
-
if (
|
|
32
|
+
if (keyEventCount === 0) {
|
|
32
33
|
_clenupCursor(store);
|
|
33
34
|
setTimeout(() => {
|
|
34
35
|
elementTabEvent(event, store);
|
|
35
36
|
});
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
keyEventCount += 1;
|
|
38
39
|
setTimeout(() => {
|
|
39
|
-
|
|
40
|
+
keyEventCount = 0;
|
|
40
41
|
}, 150);
|
|
41
42
|
break;
|
|
42
43
|
case "Space":
|
|
@@ -48,6 +49,14 @@ export function _elementKeyEvent(event, store) {
|
|
|
48
49
|
moveToBlockEvent(event, store, "down");
|
|
49
50
|
break;
|
|
50
51
|
}
|
|
52
|
+
clearTimeout(keyEventFn);
|
|
53
|
+
keyEventFn = setTimeout(() => {
|
|
54
|
+
_clenupCursor(store);
|
|
55
|
+
const $block = _findContentEditableElement(store.cursorData.startNode);
|
|
56
|
+
if ($block !== null) {
|
|
57
|
+
store.setCurrentBlock($block.closest(".de-block"));
|
|
58
|
+
}
|
|
59
|
+
}, 250);
|
|
51
60
|
}
|
|
52
61
|
function elementEnterEvent(event, store) {
|
|
53
62
|
const { $element, type } = _getBlockType(event.target);
|
|
@@ -86,7 +95,6 @@ function elementBackspaceEvent(e, store) {
|
|
|
86
95
|
listBlockBackspaceEvent(e, store, $element);
|
|
87
96
|
break;
|
|
88
97
|
default:
|
|
89
|
-
console.log("// TODO : \uB2E4\uB978 \uD0C0\uC785 \uBE14\uB7ED \uBC31\uC2A4\uD398\uC774\uC2A4 \uC774\uBCA4\uD2B8", type);
|
|
90
98
|
}
|
|
91
99
|
}
|
|
92
100
|
function elementTabEvent(e, store) {
|
|
@@ -439,9 +447,9 @@ function defaultBlockShiftEnterEvent(store, $element) {
|
|
|
439
447
|
}
|
|
440
448
|
} else {
|
|
441
449
|
const childList = $textBlock.childNodes;
|
|
442
|
-
let $target = store.cursorData.startNode;
|
|
443
450
|
let targetIdx = -1;
|
|
444
451
|
let structure = "";
|
|
452
|
+
let $target = store.cursorData.startNode;
|
|
445
453
|
if ($target.constructor.name === "Text") {
|
|
446
454
|
if ($target.parentNode !== $textBlock) {
|
|
447
455
|
$target = $target.parentNode;
|
|
@@ -479,7 +487,10 @@ function defaultBlockShiftEnterEvent(store, $element) {
|
|
|
479
487
|
if (constructorName === "HTMLBRElement") {
|
|
480
488
|
structure += `<br><br>`;
|
|
481
489
|
} else {
|
|
482
|
-
|
|
490
|
+
structure += `<span class="${[...child.classList].join(" ")}">${child.textContent.slice(0, store.cursorData.startOffset)}</span>`;
|
|
491
|
+
structure += `<br>`;
|
|
492
|
+
structure += `<span class="${[...child.classList].join(" ")}">${child.textContent.slice(store.cursorData.startOffset)}</span>`;
|
|
493
|
+
curruntIdx += 1;
|
|
483
494
|
}
|
|
484
495
|
}
|
|
485
496
|
} else {
|
|
@@ -610,7 +621,14 @@ function defaultBlockBackspaceEvent(e, store, $element) {
|
|
|
610
621
|
} else {
|
|
611
622
|
e.preventDefault();
|
|
612
623
|
if ($textBlock.tagName !== "P") {
|
|
613
|
-
$textBlock.insertAdjacentElement(
|
|
624
|
+
$textBlock.insertAdjacentElement(
|
|
625
|
+
"afterend",
|
|
626
|
+
_createTextBlock({
|
|
627
|
+
type: "text",
|
|
628
|
+
classList: [],
|
|
629
|
+
textContent: $textBlock.textContent ?? ""
|
|
630
|
+
})
|
|
631
|
+
);
|
|
614
632
|
_setCursor($textBlock.nextElementSibling, 0);
|
|
615
633
|
$textBlock.remove();
|
|
616
634
|
}
|
|
@@ -676,17 +694,9 @@ function defaultBlockBackspaceEvent(e, store, $element) {
|
|
|
676
694
|
function listBlockBackspaceEvent(e, store, $element) {
|
|
677
695
|
const $listBlock = $element;
|
|
678
696
|
const $targetItem = _findContentEditableElement(store.cursorData.startNode);
|
|
679
|
-
const childList = store.$content.querySelectorAll(".de-block");
|
|
680
697
|
const liList = $listBlock.querySelectorAll(".de-item");
|
|
681
698
|
const $target = _getParentElementIfNodeIsText(store.cursorData.startNode, $targetItem);
|
|
682
|
-
let elementIdx = -1;
|
|
683
699
|
let liIdx = -1;
|
|
684
|
-
for (let i = 0; childList.length > i; i += 1) {
|
|
685
|
-
if (childList[i] === $element) {
|
|
686
|
-
elementIdx = i;
|
|
687
|
-
break;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
700
|
for (let i = 0; liList.length > i; i += 1) {
|
|
691
701
|
if (liList[i] === $targetItem) {
|
|
692
702
|
liIdx = i;
|
|
@@ -726,6 +736,7 @@ function listBlockBackspaceEvent(e, store, $element) {
|
|
|
726
736
|
_setCursor($preBlock, 0);
|
|
727
737
|
}
|
|
728
738
|
$targetItem.remove();
|
|
739
|
+
$listBlock.remove();
|
|
729
740
|
}
|
|
730
741
|
}
|
|
731
742
|
}
|