@ebl-vue/editor-full 2.31.34 → 2.31.36
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/.postcssrc.yml +33 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.mjs +183 -182
- package/dist/index.mjs.map +1 -0
- package/package.json +1 -1
- package/postcss.config.js +15 -0
- package/src/components/Editor/Editor.vue +293 -0
- package/src/components/index.ts +27 -0
- package/src/constants/index.ts +1 -0
- package/src/i18n/zh-cn.ts +160 -0
- package/src/icons/index.ts +93 -0
- package/src/index.ts +21 -0
- package/src/installer.ts +21 -0
- package/src/plugins/alert/index.ts +455 -0
- package/src/plugins/block-alignment/index.ts +117 -0
- package/src/plugins/block-alignment/readme.md +1 -0
- package/src/plugins/code/LICENSE +21 -0
- package/src/plugins/code/index.ts +619 -0
- package/src/plugins/code/utils/string.ts +34 -0
- package/src/plugins/color-picker/index.ts +132 -0
- package/src/plugins/delimiter/index.ts +121 -0
- package/src/plugins/drag-drop/index.css +19 -0
- package/src/plugins/drag-drop/index.ts +151 -0
- package/src/plugins/drag-drop/readme.md +1 -0
- package/src/plugins/header/H1.ts +404 -0
- package/src/plugins/header/H2.ts +403 -0
- package/src/plugins/header/H3.ts +404 -0
- package/src/plugins/header/H4.ts +404 -0
- package/src/plugins/header/H5.ts +403 -0
- package/src/plugins/header/H6.ts +404 -0
- package/src/plugins/header/index.ts +15 -0
- package/src/plugins/header/types.d.ts +46 -0
- package/src/plugins/imageResizeCrop/ImageTune.ts +635 -0
- package/src/plugins/imageResizeCrop/index.css +230 -0
- package/src/plugins/imageResizeCrop/index.ts +5 -0
- package/src/plugins/imageResizeCrop/types.d.ts +23 -0
- package/src/plugins/imageTool/index.ts +510 -0
- package/src/plugins/imageTool/types/codexteam__ajax.d.ts +89 -0
- package/src/plugins/imageTool/types/types.ts +236 -0
- package/src/plugins/imageTool/ui.ts +313 -0
- package/src/plugins/imageTool/uploader.ts +287 -0
- package/src/plugins/imageTool/utils/dom.ts +24 -0
- package/src/plugins/imageTool/utils/index.ts +73 -0
- package/src/plugins/imageTool/utils/isPromise.ts +10 -0
- package/src/plugins/indent/index.ts +695 -0
- package/src/plugins/inline-code/index.ts +203 -0
- package/src/plugins/list/ListRenderer/ChecklistRenderer.ts +208 -0
- package/src/plugins/list/ListRenderer/ListRenderer.ts +73 -0
- package/src/plugins/list/ListRenderer/OrderedListRenderer.ts +123 -0
- package/src/plugins/list/ListRenderer/UnorderedListRenderer.ts +123 -0
- package/src/plugins/list/ListRenderer/index.ts +6 -0
- package/src/plugins/list/ListTabulator/index.ts +1179 -0
- package/src/plugins/list/index.ts +488 -0
- package/src/plugins/list/styles/CssPrefix.ts +4 -0
- package/src/plugins/list/types/Elements.ts +14 -0
- package/src/plugins/list/types/ItemMeta.ts +40 -0
- package/src/plugins/list/types/ListParams.ts +102 -0
- package/src/plugins/list/types/ListRenderer.ts +6 -0
- package/src/plugins/list/types/OlCounterType.ts +63 -0
- package/src/plugins/list/types/index.ts +14 -0
- package/src/plugins/list/utils/focusItem.ts +18 -0
- package/src/plugins/list/utils/getChildItems.ts +40 -0
- package/src/plugins/list/utils/getItemChildWrapper.ts +10 -0
- package/src/plugins/list/utils/getItemContentElement.ts +10 -0
- package/src/plugins/list/utils/getSiblings.ts +52 -0
- package/src/plugins/list/utils/isLastItem.ts +9 -0
- package/src/plugins/list/utils/itemHasSublist.ts +10 -0
- package/src/plugins/list/utils/normalizeData.ts +83 -0
- package/src/plugins/list/utils/removeChildWrapperIfEmpty.ts +31 -0
- package/src/plugins/list/utils/renderToolboxInput.ts +113 -0
- package/src/plugins/list/utils/stripNumbers.ts +7 -0
- package/src/plugins/list/utils/type-guards.ts +8 -0
- package/src/plugins/marker/index.ts +199 -0
- package/src/plugins/outline/index.ts +62 -0
- package/src/plugins/outline/outline.css +52 -0
- package/src/plugins/paragraph/index.ts +384 -0
- package/src/plugins/paragraph/types/icons.d.ts +4 -0
- package/src/plugins/paragraph/utils/makeFragment.ts +17 -0
- package/src/plugins/quote/index.ts +203 -0
- package/src/plugins/table/index.ts +4 -0
- package/src/plugins/table/plugin.ts +255 -0
- package/src/plugins/table/table.ts +1202 -0
- package/src/plugins/table/toolbox.ts +166 -0
- package/src/plugins/table/utils/dom.ts +130 -0
- package/src/plugins/table/utils/popover.ts +185 -0
- package/src/plugins/table/utils/throttled.ts +22 -0
- package/src/plugins/underline/index.ts +214 -0
- package/src/plugins/undo/index.ts +526 -0
- package/src/plugins/undo/observer.ts +101 -0
- package/src/plugins/undo/vanilla-caret-js.ts +102 -0
- package/src/style.css +139 -0
- package/src/types.ts +3 -0
- package/src/utils/AxiosService.ts +87 -0
- package/src/utils/index.ts +15 -0
- package/src/utils/install.ts +19 -0
- package/tsconfig.json +37 -0
- package/vite.config.ts +81 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { API } from '@ebl-vue/editorjs';
|
|
2
|
+
import { IconColor } from "../../icons";
|
|
3
|
+
import type {SanitizerConfig,InlineTool,InlineToolConstructorOptions} from "@ebl-vue/editorjs/types";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
import '@ebl-vue/editor-render/styles/color.css';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
export default class ColorPicker implements InlineTool {
|
|
13
|
+
private api: API;
|
|
14
|
+
|
|
15
|
+
tag = 'SPAN';
|
|
16
|
+
class = 'cdx-text-color';
|
|
17
|
+
defaultColor = '#2644FF';
|
|
18
|
+
|
|
19
|
+
lastRange: Range | null = null;
|
|
20
|
+
|
|
21
|
+
colors: string[] = [
|
|
22
|
+
'#182a4e',
|
|
23
|
+
'#0055cc',
|
|
24
|
+
'#1f6a83',
|
|
25
|
+
'#206e4e',
|
|
26
|
+
'#e56910',
|
|
27
|
+
'#ae2e24',
|
|
28
|
+
'#5e4db2',
|
|
29
|
+
'#758195',
|
|
30
|
+
'#1e7afd',
|
|
31
|
+
'#2998bd',
|
|
32
|
+
'#23a06b',
|
|
33
|
+
'#fea363',
|
|
34
|
+
'#c9372c',
|
|
35
|
+
'#8270db',
|
|
36
|
+
];
|
|
37
|
+
columns = 7;
|
|
38
|
+
|
|
39
|
+
static get title() {
|
|
40
|
+
return 'Color';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static get isInline() {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
constructor(args:InlineToolConstructorOptions) {
|
|
48
|
+
const { api, config } = args;
|
|
49
|
+
this.api = api;
|
|
50
|
+
|
|
51
|
+
if (config.colors) {
|
|
52
|
+
this.colors = config.colors;
|
|
53
|
+
}
|
|
54
|
+
if (config.columns) {
|
|
55
|
+
this.columns = config.columns;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
render() {
|
|
60
|
+
const button = document.createElement('button');
|
|
61
|
+
|
|
62
|
+
button.type = 'button';
|
|
63
|
+
button.innerHTML = IconColor;
|
|
64
|
+
button.classList.add(this.api.styles.inlineToolButton);
|
|
65
|
+
|
|
66
|
+
button.addEventListener('mousedown', (e) => {
|
|
67
|
+
// prevent text deselection when clicking the button
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return button;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
surround(range: Range | null) {
|
|
75
|
+
this.lastRange = range;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
wrapAndColor(range: Range | null, color: string) {
|
|
79
|
+
if (!range) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const selectedText = range.extractContents();
|
|
83
|
+
const span = document.createElement(this.tag);
|
|
84
|
+
span.classList.add(this.class);
|
|
85
|
+
span.appendChild(selectedText);
|
|
86
|
+
span.style.color = color;
|
|
87
|
+
span.innerHTML = span.textContent || '';
|
|
88
|
+
range.insertNode(span);
|
|
89
|
+
|
|
90
|
+
this.api.selection.expandToTag(span);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
renderActions() {
|
|
94
|
+
const container = document.createElement('div');
|
|
95
|
+
container.classList.add('editorjs__color-selector-container');
|
|
96
|
+
container.style.gridTemplateColumns = `repeat(${this.columns}, 1fr)`;
|
|
97
|
+
|
|
98
|
+
this.colors.forEach((colorValue) => {
|
|
99
|
+
const color = document.createElement('div');
|
|
100
|
+
color.classList.add('editorjs__color-selector__container-item');
|
|
101
|
+
color.style.backgroundColor = colorValue;
|
|
102
|
+
color.onclick = () => {
|
|
103
|
+
this.wrapAndColor(this.lastRange, colorValue);
|
|
104
|
+
};
|
|
105
|
+
container.append(color);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return container;
|
|
109
|
+
}
|
|
110
|
+
static get CSS() :string{
|
|
111
|
+
return ColorPicker.CSS;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Sanitizer rules
|
|
115
|
+
*
|
|
116
|
+
* @returns {object}
|
|
117
|
+
*/
|
|
118
|
+
static get sanitize(): SanitizerConfig {
|
|
119
|
+
return {
|
|
120
|
+
span: {
|
|
121
|
+
style: true,
|
|
122
|
+
class:true
|
|
123
|
+
},
|
|
124
|
+
} as SanitizerConfig;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export class ColorPickerWithoutSanitize extends ColorPicker {
|
|
129
|
+
// static override get sanitize() {
|
|
130
|
+
// return undefined;
|
|
131
|
+
// }
|
|
132
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build styles
|
|
3
|
+
*/
|
|
4
|
+
import '@ebl-vue/editor-render/styles/delimiter.css';
|
|
5
|
+
import {API, BlockTool, BlockToolConstructorOptions, BlockToolData, ToolboxConfig, PasteConfig, PasteEvent} from "@ebl-vue/editorjs";
|
|
6
|
+
|
|
7
|
+
import {IconDelimiter} from '../../icons';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
export default class Delimiter implements BlockTool {
|
|
13
|
+
|
|
14
|
+
static get isReadOnlySupported(): boolean {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
static get contentless(): boolean {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private api: API
|
|
24
|
+
|
|
25
|
+
private _CSS: {
|
|
26
|
+
block: string
|
|
27
|
+
wrapper: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
private _element: HTMLDivElement
|
|
33
|
+
private data: any;
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
constructor({data, config, api}: BlockToolConstructorOptions) {
|
|
37
|
+
this.api = api;
|
|
38
|
+
|
|
39
|
+
this._CSS = {
|
|
40
|
+
block: this.api.styles.block,
|
|
41
|
+
wrapper: 'ce-delimiter'
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
this._element = this.drawView();
|
|
45
|
+
this.data = data;
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Create Tool's view
|
|
51
|
+
* @return {HTMLDivElement}
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
drawView(): HTMLDivElement {
|
|
55
|
+
let wrapper = document.createElement('div');
|
|
56
|
+
let lineWrapper = document.createElement('div');
|
|
57
|
+
let lineDiv = document.createElement('div');
|
|
58
|
+
|
|
59
|
+
wrapper.classList.add(this._CSS.wrapper, this._CSS.block);
|
|
60
|
+
lineWrapper.classList.add('ce-delimiter__line__wrapper');
|
|
61
|
+
lineDiv.classList.add('ce-delimiter__line');
|
|
62
|
+
|
|
63
|
+
lineWrapper.appendChild(lineDiv);
|
|
64
|
+
wrapper.appendChild(lineWrapper);
|
|
65
|
+
|
|
66
|
+
return wrapper;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Return Tool's view
|
|
71
|
+
* @returns {HTMLDivElement}
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
render(): HTMLDivElement {
|
|
75
|
+
console.log(this.data);
|
|
76
|
+
return this._element;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Extract Tool's data from the view
|
|
81
|
+
* @param {HTMLDivElement} toolsContent - Paragraph tools rendered view
|
|
82
|
+
* @returns {DelimiterData} - saved data
|
|
83
|
+
* @public
|
|
84
|
+
*/
|
|
85
|
+
save(toolsContent: HTMLElement): BlockToolData {
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get Tool toolbox settings
|
|
91
|
+
* icon - Tool icon's SVG
|
|
92
|
+
* title - title to show in toolbox
|
|
93
|
+
*
|
|
94
|
+
* @return {{icon: string, title: string}}
|
|
95
|
+
*/
|
|
96
|
+
static get toolbox(): ToolboxConfig {
|
|
97
|
+
return {
|
|
98
|
+
icon: IconDelimiter,
|
|
99
|
+
title: 'Delimiter'
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Delimiter onPaste configuration
|
|
105
|
+
*
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
108
|
+
static get pasteConfig(): PasteConfig {
|
|
109
|
+
return { tags: ['HR'] };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* On paste callback that is fired from Editor
|
|
114
|
+
*
|
|
115
|
+
* @param {PasteEvent} event - event with pasted data
|
|
116
|
+
*/
|
|
117
|
+
onPaste(event: PasteEvent): void {
|
|
118
|
+
this.data = {};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.ce-block--drop-target .ce-block__content:before {
|
|
2
|
+
content: "";
|
|
3
|
+
position: absolute;
|
|
4
|
+
top: 50%;
|
|
5
|
+
left: -20px;
|
|
6
|
+
margin-top: -1px;
|
|
7
|
+
height: 8px;
|
|
8
|
+
width: 8px;
|
|
9
|
+
border: solid #a0a0a0;
|
|
10
|
+
border-width: 1px 1px 0 0;
|
|
11
|
+
-webkit-transform-origin: right;
|
|
12
|
+
transform-origin: right;
|
|
13
|
+
-webkit-transform: rotate(45deg);
|
|
14
|
+
transform: rotate(45deg);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.ce-block--drop-target .ce-block__content:after {
|
|
18
|
+
background: none;
|
|
19
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
|
|
3
|
+
import type EditorJS from '@ebl-vue/editorjs/types';
|
|
4
|
+
|
|
5
|
+
export default class DragDrop {
|
|
6
|
+
private toolbar: any;
|
|
7
|
+
private borderStyle: string;
|
|
8
|
+
private api: any;
|
|
9
|
+
private holder: HTMLElement;
|
|
10
|
+
private readOnly: boolean | undefined;
|
|
11
|
+
private startBlock: number | null;
|
|
12
|
+
private endBlock: number | null;
|
|
13
|
+
|
|
14
|
+
constructor(
|
|
15
|
+
holderId: string,
|
|
16
|
+
readonly: boolean,
|
|
17
|
+
editor: EditorJS,
|
|
18
|
+
borderStyle: string) {
|
|
19
|
+
const {
|
|
20
|
+
blocks,
|
|
21
|
+
toolbar,
|
|
22
|
+
} = editor;
|
|
23
|
+
this.toolbar = toolbar;
|
|
24
|
+
this.borderStyle = borderStyle || '1px dashed #aaa';
|
|
25
|
+
this.api = blocks;
|
|
26
|
+
this.holder = document.getElementById(holderId) as HTMLElement;
|
|
27
|
+
this.readOnly =readonly;
|
|
28
|
+
this.startBlock = null;
|
|
29
|
+
this.endBlock = null;
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
this.setDragListener();
|
|
33
|
+
this.setDropListener();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
setElementCursor(element: HTMLElement|null) {
|
|
38
|
+
if (!element) return;
|
|
39
|
+
const range = document.createRange();
|
|
40
|
+
const selection = window.getSelection();
|
|
41
|
+
|
|
42
|
+
range.setStart(element.childNodes[0], 0);
|
|
43
|
+
range.collapse(true);
|
|
44
|
+
selection?.removeAllRanges();
|
|
45
|
+
selection?.addRange(range);
|
|
46
|
+
element.focus();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
setDragListener() {
|
|
51
|
+
if (!this.readOnly) {
|
|
52
|
+
const settingsButton = this.holder?.querySelector<HTMLElement>('.ce-toolbar__settings-btn');
|
|
53
|
+
if (settingsButton) {
|
|
54
|
+
this.initializeDragListener(settingsButton);
|
|
55
|
+
} else {
|
|
56
|
+
const observer = new MutationObserver((mutations, obs) => {
|
|
57
|
+
const settingsButton = this.holder?.querySelector<HTMLElement>(
|
|
58
|
+
".ce-toolbar__settings-btn"
|
|
59
|
+
);
|
|
60
|
+
if (settingsButton) {
|
|
61
|
+
this.initializeDragListener(settingsButton);
|
|
62
|
+
obs.disconnect();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
observer.observe(this.holder, {
|
|
67
|
+
childList: true,
|
|
68
|
+
subtree: true,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
initializeDragListener(settingsButton: HTMLElement) {
|
|
75
|
+
settingsButton.setAttribute("draggable", "true");
|
|
76
|
+
settingsButton.addEventListener("dragstart", () => {
|
|
77
|
+
this.startBlock = this.api.getCurrentBlockIndex();
|
|
78
|
+
});
|
|
79
|
+
settingsButton.addEventListener('drag', () => {
|
|
80
|
+
this.toolbar.close();
|
|
81
|
+
if (!this.isTheOnlyBlock()) {
|
|
82
|
+
const allBlocks = this.holder.querySelectorAll('.ce-block') as NodeListOf<HTMLElement>;
|
|
83
|
+
const blockFocused = this.holder.querySelector<HTMLElement>('.ce-block--drop-target');
|
|
84
|
+
this.setElementCursor(blockFocused);
|
|
85
|
+
this.setBorderBlocks(allBlocks, blockFocused);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
setBorderBlocks(allBlocks: NodeListOf<HTMLElement>, blockFocused: HTMLElement|null) {
|
|
93
|
+
Object.values(allBlocks).forEach((block: HTMLElement) => {
|
|
94
|
+
const blockContent = block.querySelector<HTMLElement>('.ce-block__content');
|
|
95
|
+
if (block !== blockFocused) {
|
|
96
|
+
blockContent?.style.removeProperty('border-top');
|
|
97
|
+
blockContent?.style.removeProperty('border-bottom');
|
|
98
|
+
} else {
|
|
99
|
+
const index = Object.keys(allBlocks).find((key) => allBlocks[Number(key)] === blockFocused);
|
|
100
|
+
if (index && Number(index) > this.startBlock!) blockContent!.style.borderBottom = this.borderStyle;
|
|
101
|
+
else blockContent!.style.borderTop = this.borderStyle;
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
setDropListener() {
|
|
108
|
+
document.addEventListener('drop', (event: DragEvent) => {
|
|
109
|
+
const { target } = event;
|
|
110
|
+
if (this.holder.contains(target as HTMLElement) && this.startBlock !== null) {
|
|
111
|
+
const dropTarget = this.getDropTarget(target as HTMLElement);
|
|
112
|
+
if (dropTarget) {
|
|
113
|
+
const blockContent = dropTarget.querySelector<HTMLElement>('.ce-block__content');
|
|
114
|
+
blockContent?.style.removeProperty('border-top');
|
|
115
|
+
blockContent?.style.removeProperty('border-bottom');
|
|
116
|
+
this.endBlock = this.getTargetPosition(dropTarget as HTMLElement);
|
|
117
|
+
this.moveBlocks();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
this.startBlock = null;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
static get isReadOnlySupported() {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
getDropTarget(target: HTMLElement) {
|
|
131
|
+
return target.classList.contains('ce-block')
|
|
132
|
+
? target
|
|
133
|
+
: target.closest('.ce-block');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
getTargetPosition(target: HTMLElement) {
|
|
138
|
+
return Array.from(target.parentNode!.children).indexOf(target);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
isTheOnlyBlock() {
|
|
142
|
+
return this.api.getBlocksCount() === 1;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
moveBlocks() {
|
|
147
|
+
if (!this.isTheOnlyBlock()) {
|
|
148
|
+
this.api.move(this.endBlock, this.startBlock);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# 拖拽块插件
|