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