@ebl-vue/editor-full 1.0.8
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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +2565 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +55 -0
- package/postcss.config.js +15 -0
- package/src/components/Editor/Editor.vue +209 -0
- package/src/components/index.ts +27 -0
- package/src/constants/index.ts +1 -0
- package/src/i18n/zh-cn.ts +151 -0
- package/src/icons/index.ts +78 -0
- package/src/index.ts +11 -0
- package/src/installer.ts +22 -0
- package/src/plugins/alert/index.css +150 -0
- package/src/plugins/alert/index.ts +463 -0
- package/src/plugins/block-alignment/index.css +9 -0
- package/src/plugins/block-alignment/index.ts +116 -0
- package/src/plugins/block-alignment/readme.md +1 -0
- package/src/plugins/code/LICENSE +21 -0
- package/src/plugins/code/index.css +120 -0
- package/src/plugins/code/index.ts +530 -0
- package/src/plugins/code/utils/string.ts +34 -0
- package/src/plugins/color-picker/index.ts +138 -0
- package/src/plugins/color-picker/styles.css +27 -0
- package/src/plugins/delimiter/index.css +14 -0
- package/src/plugins/delimiter/index.ts +122 -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 +405 -0
- package/src/plugins/header/H2.ts +403 -0
- package/src/plugins/header/H3.ts +404 -0
- package/src/plugins/header/H4.ts +405 -0
- package/src/plugins/header/H5.ts +405 -0
- package/src/plugins/header/H6.ts +406 -0
- package/src/plugins/header/index.css +20 -0
- package/src/plugins/header/index.ts +15 -0
- package/src/plugins/header/types.d.ts +46 -0
- package/src/plugins/indent/index.css +86 -0
- package/src/plugins/indent/index.ts +697 -0
- package/src/plugins/inline-code/index.css +11 -0
- package/src/plugins/inline-code/index.ts +205 -0
- package/src/plugins/list/ListRenderer/ChecklistRenderer.ts +211 -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 +502 -0
- package/src/plugins/list/styles/CssPrefix.ts +4 -0
- package/src/plugins/list/styles/icons/index.ts +10 -0
- package/src/plugins/list/styles/input.css +36 -0
- package/src/plugins/list/styles/list.css +165 -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 +84 -0
- package/src/plugins/list/utils/removeChildWrapperIfEmpty.ts +31 -0
- package/src/plugins/list/utils/renderToolboxInput.ts +105 -0
- package/src/plugins/list/utils/stripNumbers.ts +7 -0
- package/src/plugins/list/utils/type-guards.ts +8 -0
- package/src/plugins/list.md +15 -0
- package/src/plugins/marker/index.css +4 -0
- package/src/plugins/marker/index.ts +187 -0
- package/src/plugins/paragraph/index.css +23 -0
- package/src/plugins/paragraph/index.ts +380 -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.css +26 -0
- package/src/plugins/quote/index.ts +206 -0
- package/src/plugins/table/index.ts +4 -0
- package/src/plugins/table/plugin.ts +254 -0
- package/src/plugins/table/style.css +388 -0
- package/src/plugins/table/table.ts +1192 -0
- package/src/plugins/table/toolbox.ts +165 -0
- package/src/plugins/table/utils/dom.ts +128 -0
- package/src/plugins/table/utils/popover.ts +172 -0
- package/src/plugins/table/utils/throttled.ts +22 -0
- package/src/plugins/underline/index.css +3 -0
- package/src/plugins/underline/index.ts +216 -0
- package/src/plugins/undo/index.ts +509 -0
- package/src/plugins/undo/observer.ts +101 -0
- package/src/style.css +89 -0
- package/src/utils/index.ts +15 -0
- package/src/utils/install.ts +19 -0
- package/tsconfig.json +37 -0
- package/types/index.d.ts +13 -0
- package/types/plugins/index.d.ts +0 -0
- package/vite.config.ts +79 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import * as Dom from '@editorjs/dom';
|
|
2
|
+
import { CssPrefix } from '../styles/CssPrefix';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Options used in input rendering
|
|
6
|
+
*/
|
|
7
|
+
interface InputOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Placeholder, that will be displayed in input
|
|
10
|
+
*/
|
|
11
|
+
placeholder: string;
|
|
12
|
+
/**
|
|
13
|
+
* Input will be rendered with this value inside
|
|
14
|
+
*/
|
|
15
|
+
value?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Html attributes, that would be added to the input element
|
|
18
|
+
*/
|
|
19
|
+
attributes?: {
|
|
20
|
+
[key: string]: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Flag that represents special behavior that prevents you from entering anything other than numbers
|
|
24
|
+
*/
|
|
25
|
+
sanitize?: (value: string) => string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const css = {
|
|
29
|
+
wrapper: `${CssPrefix}-start-with-field`,
|
|
30
|
+
input: `${CssPrefix}-start-with-field__input`,
|
|
31
|
+
startWithElementWrapperInvalid: `${CssPrefix}-start-with-field--invalid`,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Method that renders html element for popover start with item
|
|
36
|
+
* @param inputCallback - callback method that could change list attributes on input
|
|
37
|
+
* @param inputOptions - options used in input rendering
|
|
38
|
+
* @param inputOptions.value - input will be rendered with this value inside
|
|
39
|
+
* @param inputOptions.placeholder - placeholder, that will be displayed in input
|
|
40
|
+
* @param inputOptions.attributes - html attributes, that would be added to the input element
|
|
41
|
+
* @returns - rendered html element
|
|
42
|
+
*/
|
|
43
|
+
export function renderToolboxInput(inputCallback: (index: string) => void,
|
|
44
|
+
{ value, placeholder, attributes, sanitize }: InputOptions): HTMLElement {
|
|
45
|
+
const startWithElementWrapper = Dom.make('div', css.wrapper);
|
|
46
|
+
|
|
47
|
+
const input = Dom.make('input', css.input, {
|
|
48
|
+
placeholder,
|
|
49
|
+
/**
|
|
50
|
+
* Used to prevent focusing on the input by Tab key
|
|
51
|
+
* (Popover in the Toolbar lays below the blocks,
|
|
52
|
+
* so Tab in the last block will focus this hidden input if this property is not set)
|
|
53
|
+
*/
|
|
54
|
+
tabIndex: -1,
|
|
55
|
+
/**
|
|
56
|
+
* Value of the start property, if it is not specified, then it is set to one
|
|
57
|
+
*/
|
|
58
|
+
value,
|
|
59
|
+
}) as HTMLInputElement;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Add passed attributes to the input
|
|
63
|
+
*/
|
|
64
|
+
for (const attribute in attributes) {
|
|
65
|
+
input.setAttribute(attribute, attributes[attribute]);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
startWithElementWrapper.appendChild(input);
|
|
69
|
+
|
|
70
|
+
input.addEventListener('input', () => {
|
|
71
|
+
/**
|
|
72
|
+
* If input sanitizer specified, then sanitize input value
|
|
73
|
+
*/
|
|
74
|
+
if (sanitize !== undefined) {
|
|
75
|
+
input.value = sanitize(input.value);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const validInput = input.checkValidity();
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* If input is invalid and classlist does not contain invalid class, add it
|
|
82
|
+
*/
|
|
83
|
+
if (!validInput && !startWithElementWrapper.classList.contains(css.startWithElementWrapperInvalid)) {
|
|
84
|
+
startWithElementWrapper.classList.add(css.startWithElementWrapperInvalid);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* If input is valid and classlist contains invalid class, remove it
|
|
89
|
+
*/
|
|
90
|
+
if (validInput && startWithElementWrapper.classList.contains(css.startWithElementWrapperInvalid)) {
|
|
91
|
+
startWithElementWrapper.classList.remove(css.startWithElementWrapperInvalid);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* If input is invalid, than do not change start with attribute
|
|
96
|
+
*/
|
|
97
|
+
if (!validInput) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
inputCallback(input.value);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return startWithElementWrapper;
|
|
105
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type guard to check if a node is an HTMLElement, then we can safely use it as an HTMLElement
|
|
3
|
+
* @param node - Node to be checked, wherever it is an HTMLElement
|
|
4
|
+
*/
|
|
5
|
+
export function isHtmlElement(node: Node): node is HTMLElement {
|
|
6
|
+
// node is an HTMLElement if it is an element node
|
|
7
|
+
return node.nodeType === Node.ELEMENT_NODE;
|
|
8
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 插件清单
|
|
2
|
+
- 标题
|
|
3
|
+
- 通用对齐
|
|
4
|
+
- 拖拽排序
|
|
5
|
+
- 代码
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## 待实现
|
|
9
|
+
- 引用
|
|
10
|
+
- 表格
|
|
11
|
+
- media
|
|
12
|
+
- editorjs-toggle-block https://github.com/kommitters/editorjs-toggle-block
|
|
13
|
+
- 字体颜色 https://github.com/Matergi/editorjs-color-picker
|
|
14
|
+
- 字体样式 https://github.com/skchawala/editorjs-text-style
|
|
15
|
+
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build styles
|
|
3
|
+
*/
|
|
4
|
+
import './index.css';
|
|
5
|
+
|
|
6
|
+
const IconMarker = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11.3535 9.31802L12.7678 7.90381C13.5488 7.12276 14.8151 7.12276 15.5962 7.90381C16.3772 8.68486 16.3772 9.95119 15.5962 10.7322L14.182 12.1464M11.3535 9.31802L7.96729 12.7043C7.40889 13.2627 7.02826 13.9739 6.87339 14.7482L6.69798 15.6253C6.55803 16.325 7.17495 16.942 7.87467 16.802L8.75175 16.6266C9.52612 16.4717 10.2373 16.0911 10.7957 15.5327L14.182 12.1464M11.3535 9.31802L14.182 12.1464" stroke="black" stroke-width="2"/><line x1="15" y1="17" x2="19" y2="17" stroke="black" stroke-width="2" stroke-linecap="round"/></svg>`;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Marker Tool for the Editor.js
|
|
10
|
+
*
|
|
11
|
+
* Allows to wrap inline fragment and style it somehow.
|
|
12
|
+
*/
|
|
13
|
+
export default class Marker {
|
|
14
|
+
/**
|
|
15
|
+
* Class name for term-tag
|
|
16
|
+
*
|
|
17
|
+
* @type {string}
|
|
18
|
+
*/
|
|
19
|
+
static get CSS() {
|
|
20
|
+
return 'cdx-marker';
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {{api: object}} - Editor.js API
|
|
25
|
+
*/
|
|
26
|
+
constructor({api}) {
|
|
27
|
+
this.api = api;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Toolbar Button
|
|
31
|
+
*
|
|
32
|
+
* @type {HTMLElement|null}
|
|
33
|
+
*/
|
|
34
|
+
this.button = null;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Tag represented the term
|
|
38
|
+
*
|
|
39
|
+
* @type {string}
|
|
40
|
+
*/
|
|
41
|
+
this.tag = 'MARK';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* CSS classes
|
|
45
|
+
*/
|
|
46
|
+
this.iconClasses = {
|
|
47
|
+
base: this.api.styles.inlineToolButton,
|
|
48
|
+
active: this.api.styles.inlineToolButtonActive
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Specifies Tool as Inline Toolbar Tool
|
|
54
|
+
*
|
|
55
|
+
* @return {boolean}
|
|
56
|
+
*/
|
|
57
|
+
static get isInline() {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Create button element for Toolbar
|
|
63
|
+
*
|
|
64
|
+
* @return {HTMLElement}
|
|
65
|
+
*/
|
|
66
|
+
render() {
|
|
67
|
+
this.button = document.createElement('button');
|
|
68
|
+
this.button.type = 'button';
|
|
69
|
+
this.button.classList.add(this.iconClasses.base);
|
|
70
|
+
this.button.innerHTML = this.toolboxIcon;
|
|
71
|
+
|
|
72
|
+
return this.button;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Wrap/Unwrap selected fragment
|
|
77
|
+
*
|
|
78
|
+
* @param {Range} range - selected fragment
|
|
79
|
+
*/
|
|
80
|
+
surround(range) {
|
|
81
|
+
if (!range) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let termWrapper = this.api.selection.findParentTag(this.tag, Marker.CSS);
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* If start or end of selection is in the highlighted block
|
|
89
|
+
*/
|
|
90
|
+
if (termWrapper) {
|
|
91
|
+
this.unwrap(termWrapper);
|
|
92
|
+
} else {
|
|
93
|
+
this.wrap(range);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Wrap selection with term-tag
|
|
99
|
+
*
|
|
100
|
+
* @param {Range} range - selected fragment
|
|
101
|
+
*/
|
|
102
|
+
wrap(range) {
|
|
103
|
+
/**
|
|
104
|
+
* Create a wrapper for highlighting
|
|
105
|
+
*/
|
|
106
|
+
let marker = document.createElement(this.tag);
|
|
107
|
+
|
|
108
|
+
marker.classList.add(Marker.CSS);
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* SurroundContent throws an error if the Range splits a non-Text node with only one of its boundary points
|
|
112
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Range/surroundContents}
|
|
113
|
+
*
|
|
114
|
+
* // range.surroundContents(span);
|
|
115
|
+
*/
|
|
116
|
+
marker.appendChild(range.extractContents());
|
|
117
|
+
range.insertNode(marker);
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Expand (add) selection to highlighted block
|
|
121
|
+
*/
|
|
122
|
+
this.api.selection.expandToTag(marker);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Unwrap term-tag
|
|
127
|
+
*
|
|
128
|
+
* @param {HTMLElement} termWrapper - term wrapper tag
|
|
129
|
+
*/
|
|
130
|
+
unwrap(termWrapper) {
|
|
131
|
+
/**
|
|
132
|
+
* Expand selection to all term-tag
|
|
133
|
+
*/
|
|
134
|
+
this.api.selection.expandToTag(termWrapper);
|
|
135
|
+
|
|
136
|
+
let sel = window.getSelection();
|
|
137
|
+
let range = sel.getRangeAt(0);
|
|
138
|
+
|
|
139
|
+
let unwrappedContent = range.extractContents();
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Remove empty term-tag
|
|
143
|
+
*/
|
|
144
|
+
termWrapper.parentNode.removeChild(termWrapper);
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Insert extracted content
|
|
148
|
+
*/
|
|
149
|
+
range.insertNode(unwrappedContent);
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Restore selection
|
|
153
|
+
*/
|
|
154
|
+
sel.removeAllRanges();
|
|
155
|
+
sel.addRange(range);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Check and change Term's state for current selection
|
|
160
|
+
*/
|
|
161
|
+
checkState() {
|
|
162
|
+
const termTag = this.api.selection.findParentTag(this.tag, Marker.CSS);
|
|
163
|
+
|
|
164
|
+
this.button.classList.toggle(this.iconClasses.active, !!termTag);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get Tool icon's SVG
|
|
169
|
+
* @return {string}
|
|
170
|
+
*/
|
|
171
|
+
get toolboxIcon() {
|
|
172
|
+
return IconMarker;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Sanitizer rule
|
|
177
|
+
* @return {{mark: {class: string}}}
|
|
178
|
+
*/
|
|
179
|
+
static get sanitize() {
|
|
180
|
+
return {
|
|
181
|
+
mark: {
|
|
182
|
+
class: Marker.CSS
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
.ce-paragraph {
|
|
2
|
+
line-height: 1.6em;
|
|
3
|
+
outline: none;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Normally paragraph placeholder is shown only for the focused block (thanks to "data-placeholder-active").
|
|
8
|
+
*
|
|
9
|
+
* But there is a special case when the paragraph is the only block in the empty editor.
|
|
10
|
+
* When editor autofocus=false, there will be no focus. We need to show the placeholder anyway.
|
|
11
|
+
*/
|
|
12
|
+
.ce-block:only-of-type .ce-paragraph[data-placeholder-active]:empty::before,
|
|
13
|
+
.ce-block:only-of-type .ce-paragraph[data-placeholder-active][data-empty="true"]::before {
|
|
14
|
+
content: attr(data-placeholder-active);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.ce-paragraph p:first-of-type{
|
|
18
|
+
margin-top: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.ce-paragraph p:last-of-type{
|
|
22
|
+
margin-bottom: 0;
|
|
23
|
+
}
|