dragon-editor 2.0.0-beta.1.4 → 2.0.0-beta.2.1
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 +94 -147
- package/README_en.md +14 -62
- package/dist/module.json +1 -1
- package/dist/module.mjs +8 -0
- package/dist/runtime/core/components/SvgIcon.vue +30 -21
- package/dist/runtime/core/components/editor/ImageBlock.vue +175 -0
- package/dist/runtime/core/components/editor/OlBlock.vue +135 -0
- package/dist/runtime/core/components/editor/TextBlock.vue +77 -31
- package/dist/runtime/core/components/icon/Accept.vue +5 -0
- package/dist/runtime/core/components/icon/ArrowDown.vue +3 -0
- package/dist/runtime/core/components/icon/ArrowUp.vue +3 -0
- package/dist/runtime/core/components/icon/Cancel.vue +5 -0
- package/dist/runtime/core/components/icon/Delete.vue +3 -0
- package/dist/runtime/core/style/common.css +320 -31
- package/dist/runtime/core/style/viewer.css +191 -0
- package/dist/runtime/core/utils/cursor.d.ts +1 -1
- package/dist/runtime/core/utils/cursor.mjs +16 -4
- package/dist/runtime/core/utils/element.d.ts +2 -1
- package/dist/runtime/core/utils/element.mjs +19 -4
- package/dist/runtime/core/utils/index.d.ts +2 -3
- package/dist/runtime/core/utils/index.mjs +62 -5
- package/dist/runtime/core/utils/keyboard.d.ts +1 -1
- package/dist/runtime/core/utils/keyboard.mjs +500 -41
- package/dist/runtime/core/utils/style.d.ts +6 -2
- package/dist/runtime/core/utils/style.mjs +140 -30
- package/dist/runtime/shared/components/DragonEditor.vue +488 -159
- package/dist/runtime/shared/components/DragonEditorComment.vue +42 -32
- package/dist/runtime/shared/components/DragonEditorViewer.vue +30 -2
- package/package.json +1 -1
- package/dist/runtime/core/style/main.d.ts +0 -1
- package/dist/runtime/core/style/main.mjs +0 -24
|
@@ -1,23 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="dragon-editor">
|
|
3
|
-
<p class="d-text-block" :class="data.classList" contenteditable v-html="data.content" @keydown="textKeyboardEvent"
|
|
4
|
-
@paste="pasteEvent" ref="$block"></p>
|
|
2
|
+
<div class="dragon-editor --comment">
|
|
3
|
+
<p class="d-text-block" :class="data.classList" contenteditable v-html="data.content" @keydown="textKeyboardEvent" @paste="pasteEvent" ref="$block"></p>
|
|
5
4
|
</div>
|
|
6
5
|
</template>
|
|
7
6
|
|
|
8
7
|
<script setup lang="ts">
|
|
8
|
+
// @ts-ignore
|
|
9
9
|
import { ref, unref } from "#imports";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
setCursor,
|
|
13
|
-
pasteText,
|
|
14
|
-
styleSettings,
|
|
15
|
-
getArrangementCursorData,
|
|
16
|
-
getClipboardData,
|
|
17
|
-
getCursor,
|
|
18
|
-
findEditableElement
|
|
19
|
-
} from "../../core/utils/index";
|
|
20
|
-
import { commentBlock } from "../../../types/index";
|
|
10
|
+
import { keyboardEvent, setCursor, pasteText, styleSettings, getArrangementCursorData, getClipboardData, getCursor, findEditableElement } from "../../core/utils/index";
|
|
11
|
+
import { commentBlock, cursorSelection } from "../../../types/index";
|
|
21
12
|
|
|
22
13
|
const $block = ref();
|
|
23
14
|
const data = ref<commentBlock>({
|
|
@@ -29,11 +20,18 @@ const props = defineProps<{ modelValue: commentBlock }>();
|
|
|
29
20
|
const emit = defineEmits<{
|
|
30
21
|
(e: "update:modelValue", modelValue: commentBlock): void;
|
|
31
22
|
}>();
|
|
23
|
+
const blockCursorData = ref<cursorSelection>({
|
|
24
|
+
type: "",
|
|
25
|
+
startNode: null,
|
|
26
|
+
startOffset: null,
|
|
27
|
+
endNode: null,
|
|
28
|
+
endOffset: null,
|
|
29
|
+
});
|
|
32
30
|
|
|
33
31
|
data.value = unref(props.modelValue) as commentBlock;
|
|
34
32
|
|
|
35
33
|
function textKeyboardEvent(e: KeyboardEvent) {
|
|
36
|
-
keyboardEvent("comment", e, emit);
|
|
34
|
+
keyboardEvent("comment", e, emit, updateBlockData);
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
function pasteEvent(e: ClipboardEvent) {
|
|
@@ -50,32 +48,37 @@ function updateBlockData() {
|
|
|
50
48
|
// 데이터 정규화 및 검수
|
|
51
49
|
const blockClassList = [...$block.value.classList];
|
|
52
50
|
blockClassList.splice(0, 1);
|
|
53
|
-
const pushList = blockClassList.filter(
|
|
54
|
-
(item) => data.value.classList.indexOf(item) === -1
|
|
55
|
-
);
|
|
51
|
+
const pushList = blockClassList.filter((item) => data.value.classList.indexOf(item) === -1);
|
|
56
52
|
|
|
57
53
|
data.value.classList = data.value.classList.concat(pushList);
|
|
58
54
|
|
|
59
55
|
// 커서위치 재지정
|
|
60
56
|
if ($block.value.innerHTML.length > 0) {
|
|
61
|
-
const cursorData = getArrangementCursorData();
|
|
57
|
+
const cursorData = getArrangementCursorData(blockCursorData.value);
|
|
62
58
|
|
|
63
59
|
data.value.content = $block.value.innerHTML;
|
|
64
60
|
emit("update:modelValue", data.value);
|
|
65
61
|
|
|
66
62
|
setTimeout(() => {
|
|
67
|
-
setCursor(
|
|
68
|
-
$block.value.childNodes[cursorData.childCount],
|
|
69
|
-
cursorData.length
|
|
70
|
-
);
|
|
63
|
+
setCursor($block.value.childNodes[cursorData.childCount], cursorData.length);
|
|
71
64
|
|
|
72
|
-
//
|
|
65
|
+
// 구조 검수
|
|
73
66
|
$block.value.childNodes.forEach((child: ChildNode) => {
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
child.
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
if (child.constructor.name !== "Text") {
|
|
68
|
+
// 텍스트가 아닐경우
|
|
69
|
+
if (child.constructor.name !== "HTMLBRElement") {
|
|
70
|
+
// br 태그 유지
|
|
71
|
+
if (child.textContent === "") {
|
|
72
|
+
// 빈 태그 삭제
|
|
73
|
+
child.remove();
|
|
74
|
+
} else if ((child as HTMLElement).classList.length === 0) {
|
|
75
|
+
// 클레스 없는 엘리먼트 처리
|
|
76
|
+
(child as HTMLElement).insertAdjacentHTML("afterend", child.textContent as string);
|
|
77
|
+
child.remove();
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
(child as HTMLElement).removeAttribute("class");
|
|
81
|
+
}
|
|
79
82
|
}
|
|
80
83
|
});
|
|
81
84
|
}, 100);
|
|
@@ -86,10 +89,17 @@ function updateBlockData() {
|
|
|
86
89
|
|
|
87
90
|
function focus() {
|
|
88
91
|
setCursor($block.value, 0);
|
|
92
|
+
blockCursorData.value = getCursor();
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
function setStyles(kind: string) {
|
|
92
|
-
data.value = styleSettings(
|
|
95
|
+
function setStyles(kind: string, url?: string) {
|
|
96
|
+
data.value = styleSettings({
|
|
97
|
+
kind: kind,
|
|
98
|
+
blockData: data.value,
|
|
99
|
+
$target: $block.value,
|
|
100
|
+
url: url,
|
|
101
|
+
cursorData: blockCursorData.value,
|
|
102
|
+
});
|
|
93
103
|
setTimeout(() => {
|
|
94
104
|
updateBlockData();
|
|
95
105
|
}, 250);
|
|
@@ -120,7 +130,7 @@ defineExpose({
|
|
|
120
130
|
updateBlockData,
|
|
121
131
|
focus,
|
|
122
132
|
setStyles,
|
|
123
|
-
getCursorClassList
|
|
133
|
+
getCursorClassList,
|
|
124
134
|
});
|
|
125
135
|
</script>
|
|
126
136
|
|
|
@@ -1,3 +1,31 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="editor-viewer"
|
|
3
|
-
|
|
2
|
+
<div class="dragon-editor-viewer">
|
|
3
|
+
<template v-for="(row, count) in props.content">
|
|
4
|
+
<p class="d-text-block" v-if="row.type === 'text'" :class="row.classList" v-html="row.content"></p>
|
|
5
|
+
|
|
6
|
+
<template v-if="row.type === 'image'">
|
|
7
|
+
<template v-if="row.webp"> </template>
|
|
8
|
+
<template v-else>
|
|
9
|
+
<div class="d-image-block" :class="row.classList">
|
|
10
|
+
<div class="d-image-area">
|
|
11
|
+
<img class="d-img" :src="row.src" :width="row.width" :height="row.height" :alt="row.caption" loading="lazy" />
|
|
12
|
+
</div>
|
|
13
|
+
<p class="d-caption" v-if="row.caption" v-html="row.caption"></p>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
</template>
|
|
17
|
+
</template>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import { editorContentType } from "../../../types";
|
|
23
|
+
|
|
24
|
+
const props = defineProps<{
|
|
25
|
+
content: editorContentType;
|
|
26
|
+
}>();
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<style>
|
|
30
|
+
@import "../../core/style/viewer.css";
|
|
31
|
+
</style>
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const __esModule: boolean;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/******/ (() => { // webpackBootstrap
|
|
2
|
-
/******/ "use strict";
|
|
3
|
-
/******/ // The require scope
|
|
4
|
-
/******/ var __webpack_require__ = {};
|
|
5
|
-
/******/
|
|
6
|
-
/************************************************************************/
|
|
7
|
-
/******/ /* webpack/runtime/make namespace object */
|
|
8
|
-
/******/ (() => {
|
|
9
|
-
/******/ // define __esModule on exports
|
|
10
|
-
/******/ __webpack_require__.r = (exports) => {
|
|
11
|
-
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
12
|
-
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
13
|
-
/******/ }
|
|
14
|
-
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
15
|
-
/******/ };
|
|
16
|
-
/******/ })();
|
|
17
|
-
/******/
|
|
18
|
-
/************************************************************************/
|
|
19
|
-
var __webpack_exports__ = {};
|
|
20
|
-
__webpack_require__.r(__webpack_exports__);
|
|
21
|
-
// extracted by mini-css-extract-plugin
|
|
22
|
-
|
|
23
|
-
/******/ })()
|
|
24
|
-
;
|