@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,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build styles
|
|
3
|
+
*/
|
|
4
|
+
import './index.css';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import { API, PasteEvent } from '@ebl-vue/editorjs';
|
|
8
|
+
import type { HeaderData, HeaderConfig, Level } from './types';
|
|
9
|
+
import type { BlockTool, BlockToolConstructorOptions } from '@ebl-vue/editorjs';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const IconH5: string = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12"/><path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="M16 15.9C16 15.9 16.3768 17 17.8 17C19.5 17 20 15.6199 20 14.7C20 12.7323 17.6745 12.0486 16.1635 12.9894C16.094 13.0327 16 12.9846 16 12.9027V10.1C16 10.0448 16.0448 10 16.1 10H19.8"/></svg>`;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Header block for the Editor.js.
|
|
18
|
+
*
|
|
19
|
+
* @author CodeX (team@ifmo.su)
|
|
20
|
+
* @copyright CodeX 2018
|
|
21
|
+
* @license MIT
|
|
22
|
+
* @version 2.0.0
|
|
23
|
+
*/
|
|
24
|
+
export default class H5 implements BlockTool {
|
|
25
|
+
/**
|
|
26
|
+
* Render plugin`s main Element and fill it with saved data
|
|
27
|
+
*
|
|
28
|
+
* @param {{data: HeaderData, config: HeaderConfig, api: object}}
|
|
29
|
+
* data — previously saved data
|
|
30
|
+
* config - user config for Tool
|
|
31
|
+
* api - Editor.js API
|
|
32
|
+
* readOnly - read only mode flag
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Editor.js API
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
private api: API;
|
|
39
|
+
/**
|
|
40
|
+
* Read-only mode flag
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
43
|
+
private readOnly: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Tool's settings passed from Editor
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
private _settings: HeaderConfig;
|
|
49
|
+
/**
|
|
50
|
+
* Block's data
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
private _data: HeaderData;
|
|
54
|
+
/**
|
|
55
|
+
* Main Block wrapper
|
|
56
|
+
* @private
|
|
57
|
+
*/
|
|
58
|
+
private _element: HTMLHeadingElement;
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
constructor({ data, config, api, readOnly }: BlockToolConstructorOptions) {
|
|
63
|
+
this.api = api;
|
|
64
|
+
this.readOnly = readOnly;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Tool's settings passed from Editor
|
|
68
|
+
*
|
|
69
|
+
* @type {HeaderConfig}
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
this._settings={placeholder:"H5"};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Block's data
|
|
76
|
+
*
|
|
77
|
+
* @type {HeaderData}
|
|
78
|
+
* @private
|
|
79
|
+
*/
|
|
80
|
+
this._data = this.normalizeData(data);
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Main Block wrapper
|
|
84
|
+
*
|
|
85
|
+
* @type {HTMLElement}
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
this._element = this.getTag();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Styles
|
|
92
|
+
*/
|
|
93
|
+
private get _CSS() {
|
|
94
|
+
return {
|
|
95
|
+
block: this.api.styles.block,
|
|
96
|
+
wrapper: 'ce-header',
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Check if data is valid
|
|
102
|
+
*
|
|
103
|
+
* @param {any} data - data to check
|
|
104
|
+
* @returns {data is HeaderData}
|
|
105
|
+
* @private
|
|
106
|
+
*/
|
|
107
|
+
isHeaderData(data: any): data is HeaderData {
|
|
108
|
+
return (data as HeaderData).text !== undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Normalize input data
|
|
113
|
+
*
|
|
114
|
+
* @param {HeaderData} data - saved data to process
|
|
115
|
+
*
|
|
116
|
+
* @returns {HeaderData}
|
|
117
|
+
* @private
|
|
118
|
+
*/
|
|
119
|
+
normalizeData(data: HeaderData | {}): HeaderData {
|
|
120
|
+
const newData: HeaderData = { text: '', level: this.defaultLevel.number };
|
|
121
|
+
|
|
122
|
+
if (this.isHeaderData(data)) {
|
|
123
|
+
newData.text = data.text || '';
|
|
124
|
+
|
|
125
|
+
if (data.level !== undefined && !isNaN(parseInt(data.level.toString()))) {
|
|
126
|
+
newData.level = parseInt(data.level.toString());
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return newData;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Return Tool's view
|
|
135
|
+
*
|
|
136
|
+
* @returns {HTMLHeadingElement}
|
|
137
|
+
* @public
|
|
138
|
+
*/
|
|
139
|
+
render(): HTMLHeadingElement {
|
|
140
|
+
return this._element;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Callback for Block's settings buttons
|
|
146
|
+
*
|
|
147
|
+
* @param {number} level - level to set
|
|
148
|
+
*/
|
|
149
|
+
setLevel(level: number): void {
|
|
150
|
+
this.data = {
|
|
151
|
+
level: level,
|
|
152
|
+
text: this.data.text,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Method that specified how to merge two Text blocks.
|
|
158
|
+
* Called by Editor.js by backspace at the beginning of the Block
|
|
159
|
+
*
|
|
160
|
+
* @param {HeaderData} data - saved data to merger with current block
|
|
161
|
+
* @public
|
|
162
|
+
*/
|
|
163
|
+
merge(data: HeaderData): void {
|
|
164
|
+
this._element.insertAdjacentHTML('beforeend', data.text)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Validate Text block data:
|
|
169
|
+
* - check for emptiness
|
|
170
|
+
*
|
|
171
|
+
* @param {HeaderData} blockData — data received after saving
|
|
172
|
+
* @returns {boolean} false if saved data is not correct, otherwise true
|
|
173
|
+
* @public
|
|
174
|
+
*/
|
|
175
|
+
validate(blockData: HeaderData): boolean {
|
|
176
|
+
return blockData.text.trim() !== '';
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Extract Tool's data from the view
|
|
181
|
+
*
|
|
182
|
+
* @param {HTMLHeadingElement} toolsContent - Text tools rendered view
|
|
183
|
+
* @returns {HeaderData} - saved data
|
|
184
|
+
* @public
|
|
185
|
+
*/
|
|
186
|
+
save(toolsContent: HTMLHeadingElement): HeaderData {
|
|
187
|
+
return {
|
|
188
|
+
text: toolsContent.innerHTML,
|
|
189
|
+
level: this.defaultLevel.number,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Allow Header to be converted to/from other blocks
|
|
195
|
+
*/
|
|
196
|
+
static get conversionConfig() {
|
|
197
|
+
return {
|
|
198
|
+
export: 'text', // use 'text' property for other blocks
|
|
199
|
+
import: 'text', // fill 'text' property from other block's export string
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Sanitizer Rules
|
|
205
|
+
*/
|
|
206
|
+
static get sanitize() {
|
|
207
|
+
return {
|
|
208
|
+
level: false,
|
|
209
|
+
text: {},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Returns true to notify core that read-only is supported
|
|
215
|
+
*
|
|
216
|
+
* @returns {boolean}
|
|
217
|
+
*/
|
|
218
|
+
static get isReadOnlySupported() {
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Get current Tools`s data
|
|
224
|
+
*
|
|
225
|
+
* @returns {HeaderData} Current data
|
|
226
|
+
* @private
|
|
227
|
+
*/
|
|
228
|
+
get data(): HeaderData {
|
|
229
|
+
this._data.text = this._element.innerHTML;
|
|
230
|
+
this._data.level = this.defaultLevel.number;
|
|
231
|
+
|
|
232
|
+
return this._data;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Store data in plugin:
|
|
237
|
+
* - at the this._data property
|
|
238
|
+
* - at the HTML
|
|
239
|
+
*
|
|
240
|
+
* @param {HeaderData} data — data to set
|
|
241
|
+
* @private
|
|
242
|
+
*/
|
|
243
|
+
set data(data: HeaderData) {
|
|
244
|
+
this._data = this.normalizeData(data);
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* If level is set and block in DOM
|
|
248
|
+
* then replace it to a new block
|
|
249
|
+
*/
|
|
250
|
+
if (data.level !== undefined && this._element.parentNode) {
|
|
251
|
+
/**
|
|
252
|
+
* Create a new tag
|
|
253
|
+
*
|
|
254
|
+
* @type {HTMLHeadingElement}
|
|
255
|
+
*/
|
|
256
|
+
const newHeader = this.getTag();
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Save Block's content
|
|
260
|
+
*/
|
|
261
|
+
newHeader.innerHTML = this._element.innerHTML;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Replace blocks
|
|
265
|
+
*/
|
|
266
|
+
this._element.parentNode.replaceChild(newHeader, this._element);
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Save new block to private variable
|
|
270
|
+
*
|
|
271
|
+
* @type {HTMLHeadingElement}
|
|
272
|
+
* @private
|
|
273
|
+
*/
|
|
274
|
+
this._element = newHeader;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* If data.text was passed then update block's content
|
|
279
|
+
*/
|
|
280
|
+
if (data.text !== undefined) {
|
|
281
|
+
this._element.innerHTML = this._data.text || '';
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Get tag for target level
|
|
287
|
+
* By default returns second-leveled header
|
|
288
|
+
*
|
|
289
|
+
* @returns {HTMLElement}
|
|
290
|
+
*/
|
|
291
|
+
getTag(): HTMLHeadingElement {
|
|
292
|
+
const tag = this.createHeadingElement();
|
|
293
|
+
this.setElementContent(tag);
|
|
294
|
+
this.addStylesToElement(tag);
|
|
295
|
+
this.setEditability(tag);
|
|
296
|
+
this.addPlaceholder(tag);
|
|
297
|
+
return tag;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* 创建标题元素
|
|
302
|
+
* @returns {HTMLHeadingElement} 创建的HTML标题元素
|
|
303
|
+
* @private
|
|
304
|
+
*/
|
|
305
|
+
private createHeadingElement(): HTMLHeadingElement {
|
|
306
|
+
return document.createElement(this.defaultLevel.tag) as HTMLHeadingElement;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* 设置元素内容
|
|
311
|
+
* @param {HTMLHeadingElement} element - 要设置内容的HTML标题元素
|
|
312
|
+
* @private
|
|
313
|
+
*/
|
|
314
|
+
private setElementContent(element: HTMLHeadingElement): void {
|
|
315
|
+
element.innerHTML = this._data.text || '';
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* 为元素添加样式类
|
|
320
|
+
* @param {HTMLHeadingElement} element - 要添加样式的HTML标题元素
|
|
321
|
+
* @private
|
|
322
|
+
*/
|
|
323
|
+
private addStylesToElement(element: HTMLHeadingElement): void {
|
|
324
|
+
element.classList.add(this._CSS.wrapper);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* 设置元素可编辑属性
|
|
329
|
+
* @param {HTMLHeadingElement} element - 要设置编辑属性的HTML标题元素
|
|
330
|
+
* @private
|
|
331
|
+
*/
|
|
332
|
+
private setEditability(element: HTMLHeadingElement): void {
|
|
333
|
+
element.contentEditable = this.readOnly ? 'false' : 'true';
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* 为元素添加占位符文本
|
|
338
|
+
* @param {HTMLHeadingElement} element - 要添加占位符的HTML标题元素
|
|
339
|
+
* @private
|
|
340
|
+
*/
|
|
341
|
+
private addPlaceholder(element: HTMLHeadingElement): void {
|
|
342
|
+
element.dataset.placeholder = this.api.i18n.t(this._settings.placeholder || '');
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Return default level
|
|
349
|
+
*
|
|
350
|
+
* @returns {level}
|
|
351
|
+
*/
|
|
352
|
+
get defaultLevel(): Level {
|
|
353
|
+
return {
|
|
354
|
+
number: 5,
|
|
355
|
+
tag: 'H5',
|
|
356
|
+
svg: IconH5,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Handle H1-H6 tags on paste to substitute it with header Tool
|
|
365
|
+
*
|
|
366
|
+
* @param {PasteEvent} event - event with pasted content
|
|
367
|
+
*/
|
|
368
|
+
onPaste(event: PasteEvent): void {
|
|
369
|
+
const detail = event.detail;
|
|
370
|
+
|
|
371
|
+
if ('data' in detail) {
|
|
372
|
+
const content = detail.data as HTMLElement;
|
|
373
|
+
this.data = {
|
|
374
|
+
level: 5,
|
|
375
|
+
text: content.innerHTML,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Used by Editor.js paste handling API.
|
|
382
|
+
* Provides configuration to handle H1-H6 tags.
|
|
383
|
+
*
|
|
384
|
+
* @returns {{handler: (function(HTMLElement): {text: string}), tags: string[]}}
|
|
385
|
+
*/
|
|
386
|
+
static get pasteConfig() {
|
|
387
|
+
return {
|
|
388
|
+
tags: ['H5'],
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Get Tool toolbox settings
|
|
394
|
+
* icon - Tool icon's SVG
|
|
395
|
+
* title - title to show in toolbox
|
|
396
|
+
*
|
|
397
|
+
* @returns {{icon: string, title: string}}
|
|
398
|
+
*/
|
|
399
|
+
static get toolbox() {
|
|
400
|
+
return {
|
|
401
|
+
icon: IconH5,
|
|
402
|
+
title: 'H5',
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
}
|