@ebl-vue/editor-full 1.0.11 → 1.0.13

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.
Files changed (47) hide show
  1. package/dist/index.d.ts +5 -0
  2. package/dist/index.mjs +733 -440
  3. package/dist/index.mjs.map +1 -1
  4. package/package.json +3 -1
  5. package/src/components/Editor/Editor.vue +34 -10
  6. package/src/i18n/zh-cn.ts +6 -1
  7. package/src/icons/index.ts +15 -0
  8. package/src/installer.ts +4 -3
  9. package/src/plugins/alert/index.ts +19 -27
  10. package/src/plugins/block-alignment/index.ts +4 -3
  11. package/src/plugins/code/index.ts +3 -2
  12. package/src/plugins/color-picker/index.ts +3 -11
  13. package/src/plugins/delimiter/index.ts +5 -6
  14. package/src/plugins/header/H1.ts +1 -1
  15. package/src/plugins/header/H2.ts +1 -1
  16. package/src/plugins/header/H3.ts +1 -1
  17. package/src/plugins/header/H4.ts +1 -2
  18. package/src/plugins/header/H5.ts +1 -3
  19. package/src/plugins/header/H6.ts +1 -3
  20. package/src/plugins/imageTool/index.css +145 -0
  21. package/src/plugins/imageTool/index.ts +519 -0
  22. package/src/plugins/imageTool/types/codexteam__ajax.d.ts +89 -0
  23. package/src/plugins/imageTool/types/types.ts +234 -0
  24. package/src/plugins/imageTool/ui.ts +312 -0
  25. package/src/plugins/imageTool/uploader.ts +234 -0
  26. package/src/plugins/imageTool/utils/dom.ts +24 -0
  27. package/src/plugins/imageTool/utils/isPromise.ts +10 -0
  28. package/src/plugins/indent/index.ts +5 -7
  29. package/src/plugins/inline-code/index.ts +2 -5
  30. package/src/plugins/list/ListRenderer/ChecklistRenderer.ts +1 -4
  31. package/src/plugins/list/index.ts +20 -37
  32. package/src/plugins/list/types/OlCounterType.ts +1 -1
  33. package/src/plugins/marker/index.ts +28 -16
  34. package/src/plugins/paragraph/index.ts +3 -2
  35. package/src/plugins/quote/index.ts +1 -4
  36. package/src/plugins/table/plugin.ts +1 -1
  37. package/src/plugins/table/table.ts +40 -38
  38. package/src/plugins/table/toolbox.ts +5 -4
  39. package/src/plugins/table/utils/dom.ts +15 -14
  40. package/src/plugins/table/utils/popover.ts +28 -15
  41. package/src/plugins/underline/index.ts +2 -4
  42. package/src/plugins/undo/index.ts +48 -33
  43. package/src/plugins/undo/observer.ts +3 -3
  44. package/src/style.css +6 -0
  45. package/types/index.d.ts +5 -0
  46. package/vite.config.ts +3 -1
  47. package/src/plugins/list/styles/icons/index.ts +0 -10
@@ -0,0 +1,234 @@
1
+ import ajax from '@codexteam/ajax';
2
+ import type { AjaxResponse } from '@codexteam/ajax';
3
+ import isPromise from './utils/isPromise';
4
+ import type { IUploadResponseFormat, UploadOptions } from './types/types';
5
+ import type { UploadResponseFormat, ImageConfig } from './types/types';
6
+ import axios, { AxiosInstance, InternalAxiosRequestConfig } from "axios";
7
+ /**
8
+ * Params interface for Uploader constructor
9
+ */
10
+ interface UploaderParams {
11
+ /**
12
+ * Configuration for the uploader
13
+ */
14
+ config: ImageConfig;
15
+
16
+ /**
17
+ * Handles the upload response.
18
+ * @param {UploadResponseFormat} response - Response format expected from the backend on file uploading.
19
+ * @returns {void}
20
+ */
21
+ onUpload: (response: UploadResponseFormat) => void;
22
+
23
+ /**
24
+ *
25
+ * @param error : error type
26
+ * @returns void
27
+ */
28
+ onError: (error: string) => void;
29
+ }
30
+
31
+ /**
32
+ * Module for file uploading. Handle 3 scenarios:
33
+ * 1. Select file from device and upload
34
+ * 2. Upload by pasting URL
35
+ * 3. Upload by pasting file from Clipboard or by Drag'n'Drop
36
+ */
37
+ export default class Uploader {
38
+ private config: ImageConfig;
39
+ private onUpload: (response: UploadResponseFormat) => void;
40
+ private onError: (error: string) => void;
41
+ /**
42
+ * @param params - uploader module params
43
+ * @param params.config - image tool config
44
+ * @param params.onUpload - one callback for all uploading (file, url, d-n-d, pasting)
45
+ * @param params.onError - callback for uploading errors
46
+ */
47
+ constructor({ config, onUpload, onError }: UploaderParams) {
48
+ this.config = config;
49
+ this.onUpload = onUpload;
50
+ this.onError = onError;
51
+ }
52
+
53
+ /**
54
+ * Handle clicks on the upload file button
55
+ * Fires ajax.transport()
56
+ * @param onPreview - callback fired when preview is ready
57
+ */
58
+ public async uploadSelectedFile({ onPreview }: UploadOptions) {
59
+
60
+ const preparePreview = function (file: File): void {
61
+ const reader = new FileReader();
62
+
63
+ reader.readAsDataURL(file);
64
+ reader.onload = (e) => {
65
+ onPreview((e.target as FileReader).result as string);
66
+ };
67
+ };
68
+
69
+ /**
70
+ * Custom uploading
71
+ * or default uploading
72
+ */
73
+ let upload: Promise<UploadResponseFormat>;
74
+ let cdn: string = "";
75
+ let objectKey: string = "";
76
+
77
+ // custom uploading
78
+ if (this.config.uploader && typeof this.config.uploader.uploadByFile === 'function') {
79
+ const uploadByFile = this.config.uploader.uploadByFile;
80
+
81
+ upload = ajax.selectFiles({ accept: this.config.types ?? 'image/*' }).then((files: File[]) => {
82
+ preparePreview(files[0]);
83
+
84
+ const customUpload = uploadByFile(files[0]);
85
+
86
+ if (!isPromise(customUpload)) {
87
+ console.warn('Custom uploader method uploadByFile should return a Promise');
88
+ }
89
+
90
+ return customUpload;
91
+ });
92
+
93
+ // default uploading
94
+ } else {
95
+ //选获取上传文件的地址
96
+ const files = await ajax.selectFiles({ accept: this.config.types ?? 'image/*' });
97
+ if (files && files.length > 0) {
98
+ preparePreview(files[0]);
99
+ }
100
+ const file = files[0];
101
+ const uploadBodyRes = await ajax.post({
102
+ url: this.config.endpoints.byFile,
103
+ data: Object.assign({
104
+ "fileName": file.name,
105
+ "contentType": file.type
106
+ }, this.config.additionalRequestData),
107
+ type: ajax.contentType.JSON,
108
+
109
+ });
110
+ const uploadRes = uploadBodyRes.body as IUploadResponseFormat;
111
+ if (!uploadRes.success) {
112
+ this.onError(uploadRes.message!);
113
+ return;
114
+ }
115
+ console.log(uploadRes);
116
+ cdn = uploadRes.data.cdn;
117
+ objectKey = uploadRes.data.objectKey;
118
+ const axiosInstance: AxiosInstance = axios.create({
119
+ timeout: 1800000,
120
+ headers: { "Content-Type": file.type },
121
+ });
122
+ upload = axiosInstance.put(uploadRes.data.presignedUrl, file);
123
+
124
+
125
+ }
126
+
127
+ upload.then((response) => {
128
+ if (response.status === 200) {
129
+ response = {
130
+ success: 1,
131
+ file: { url: cdn + objectKey }
132
+ }
133
+ }
134
+ this.onUpload(response);
135
+ }).catch((error: string) => {
136
+ this.onError(error);
137
+ });
138
+ }
139
+
140
+ /**
141
+ * Handle clicks on the upload file button
142
+ * Fires ajax.post()
143
+ * @param url - image source url
144
+ */
145
+ public uploadByUrl(url: string): void {
146
+ let upload;
147
+
148
+ /**
149
+ * Custom uploading
150
+ */
151
+ if (this.config.uploader && typeof this.config.uploader.uploadByUrl === 'function') {
152
+ upload = this.config.uploader.uploadByUrl(url);
153
+
154
+ if (!isPromise(upload)) {
155
+ console.warn('Custom uploader method uploadByUrl should return a Promise');
156
+ }
157
+ } else {
158
+ /**
159
+ * Default uploading
160
+ */
161
+ upload = ajax.post({
162
+ url: this.config.endpoints.byUrl,
163
+ data: Object.assign({
164
+ url: url,
165
+ }, this.config.additionalRequestData),
166
+ type: ajax.contentType.JSON,
167
+ headers: this.config.additionalRequestHeaders as Record<string, string>,
168
+ }).then((response: AjaxResponse) => response.body as UploadResponseFormat);
169
+ }
170
+
171
+ upload.then((response: UploadResponseFormat) => {
172
+ this.onUpload(response);
173
+ }).catch((error: string) => {
174
+ this.onError(error);
175
+ });
176
+ }
177
+
178
+ /**
179
+ * Handle clicks on the upload file button
180
+ * Fires ajax.post()
181
+ * @param file - file pasted by drag-n-drop
182
+ * @param onPreview - file pasted by drag-n-drop
183
+ */
184
+ public uploadByFile(file: Blob, { onPreview }: UploadOptions): void {
185
+ /**
186
+ * Load file for preview
187
+ */
188
+ const reader = new FileReader();
189
+
190
+ reader.readAsDataURL(file);
191
+ reader.onload = (e) => {
192
+ onPreview((e.target as FileReader).result as string);
193
+ };
194
+
195
+ let upload: Promise<UploadResponseFormat>;
196
+
197
+ /**
198
+ * Custom uploading
199
+ */
200
+ if (this.config.uploader && typeof this.config.uploader.uploadByFile === 'function') {
201
+ upload = this.config.uploader.uploadByFile(file);
202
+
203
+ if (!isPromise(upload)) {
204
+ console.warn('Custom uploader method uploadByFile should return a Promise');
205
+ }
206
+ } else {
207
+ /**
208
+ * Default uploading
209
+ */
210
+ const formData = new FormData();
211
+
212
+ formData.append(this.config.field ?? 'image', file);
213
+
214
+ if (this.config.additionalRequestData && Object.keys(this.config.additionalRequestData).length) {
215
+ Object.entries(this.config.additionalRequestData).forEach(([name, value]: [string, string | Blob]) => {
216
+ formData.append(name, value);
217
+ });
218
+ }
219
+
220
+ upload = ajax.post({
221
+ url: this.config.endpoints.byFile,
222
+ data: formData,
223
+ type: ajax.contentType.JSON,
224
+ headers: this.config.additionalRequestHeaders as Record<string, string>,
225
+ }).then((response: AjaxResponse) => response.body as UploadResponseFormat);
226
+ }
227
+
228
+ upload.then((response) => {
229
+ this.onUpload(response);
230
+ }).catch((error: string) => {
231
+ this.onError(error);
232
+ });
233
+ }
234
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Helper for making Elements with attributes
3
+ * @param tagName - new Element tag name
4
+ * @param classNames - list or name of CSS class
5
+ * @param attributes - any attributes
6
+ * @returns
7
+ */
8
+ export function make(tagName: string, classNames: string[] | string | null = null, attributes: { [key: string]: string | boolean } = {}): HTMLElement {
9
+ const el = document.createElement(tagName);
10
+
11
+ if (Array.isArray(classNames)) {
12
+ el.classList.add(...classNames);
13
+ } else if (classNames !== null) {
14
+ el.classList.add(classNames);
15
+ }
16
+
17
+ for (const attrName in attributes) {
18
+ if (attributes.hasOwnProperty(attrName)) {
19
+ (el as unknown as { [key: string]: string | boolean })[attrName] = attributes[attrName];
20
+ }
21
+ }
22
+
23
+ return el;
24
+ }
@@ -0,0 +1,10 @@
1
+ import type { UploadResponseFormat } from '../types/types';
2
+
3
+ /**
4
+ * Check if passed object is a Promise
5
+ * @param object - object to check
6
+ * @returns
7
+ */
8
+ export default function isPromise(object: Promise<UploadResponseFormat>): object is Promise<UploadResponseFormat> {
9
+ return object !== undefined && typeof object.then === 'function';
10
+ }
@@ -1,13 +1,11 @@
1
1
  import type { BlockTune, API, BlockAPI, BlockAddedEvent,ToolConfig } from '@ebl-vue/editorjs/types'
2
2
 
3
3
  import type { MenuConfig } from '@ebl-vue/editorjs/types/tools'
4
-
4
+ import { IconIndentLeft,IconIndentRight } from '../../icons';
5
5
 
6
6
  import './index.css'
7
7
 
8
- const IconChevronLeft = `<svg t="1763708081701" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2604" width="24" height="24"><path d="M469.3330000000001 725.333H896V640H469.3330000000001v85.333zM128 512l170.667 170.667V341.3330000000001L128 512z m0 384h768v-85.333H128V896z m0-768v85.333h768V128H128z m341.333 256H896v-85.333H469.3330000000001V384z m0 170.667H896v-85.334H469.3330000000001v85.334z" p-id="2605" fill="#000000"></path></svg>`;
9
8
 
10
- const IconChevronRight = `<svg t="1763708124227" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2788" width="24" height="24"><path d="M128 896h768v-85.333H128V896z m0-554.667v341.334L298.667 512 128 341.333z m341.333 384H896V640H469.333v85.333zM128 128v85.333h768V128H128z m341.333 256H896v-85.333H469.333V384z m0 170.667H896v-85.334H469.333v85.334z" p-id="2789" fill="#000000"></path></svg>`;
11
9
 
12
10
  interface ConstructorArgs {
13
11
  data: IndentData;
@@ -196,7 +194,7 @@ export default class IndentTune implements BlockTune {
196
194
  //@ts-ignore
197
195
  item.title = this.rightText;
198
196
  },
199
- icon: IconChevronRight,
197
+ icon: IconIndentRight,
200
198
  name: rightElementName,
201
199
  },
202
200
  {
@@ -209,7 +207,7 @@ export default class IndentTune implements BlockTune {
209
207
  //@ts-ignore
210
208
  item.title = this.leftText;
211
209
  },
212
- icon: IconChevronLeft,
210
+ icon: IconIndentLeft,
213
211
  name: leftElementName,
214
212
  },
215
213
  ]
@@ -217,9 +215,9 @@ export default class IndentTune implements BlockTune {
217
215
 
218
216
  const html = /*html*/ `
219
217
  <div class="${this.CSS.popoverItem} ${this.CSS.customPopoverItem}" data-item-name='indent' version=${this.config.version}>
220
- <button type="button" class="${this.CSS.popoverItemIcon}" data-${this.TuneNames.indentLeft}>${IconChevronLeft}</button>
218
+ <button type="button" class="${this.CSS.popoverItemIcon}" data-${this.TuneNames.indentLeft}>${IconIndentLeft}</button>
221
219
  <span class="${this.CSS.popoverItemTitle}">${this.api.sanitizer.clean(this.api.i18n.t('Indent'), {})}</span>
222
- <button type="button" class="${this.CSS.popoverItemIcon}" data-${this.TuneNames.indentRight} style="margin-left:10px;">${IconChevronRight}</button>
220
+ <button type="button" class="${this.CSS.popoverItemIcon}" data-${this.TuneNames.indentRight} style="margin-left:10px;">${IconIndentRight}</button>
223
221
  </div>
224
222
  `
225
223
 
@@ -2,11 +2,8 @@
2
2
  * Build styles
3
3
  */
4
4
  import './index.css';
5
- const IconBrackets = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
6
- <path d="M9 8L5 12L9 16" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
7
- <path d="M15 8L19 12L15 16" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
8
- </svg>
9
- `;
5
+ import {IconBrackets} from '../../icons';
6
+
10
7
  import { API, InlineTool, InlineToolConstructorOptions, SanitizerConfig } from "@editorjs/editorjs";
11
8
 
12
9
  interface IconClasses {
@@ -4,10 +4,7 @@ import { isEmpty, make } from '@editorjs/dom';
4
4
  import { DefaultListCssClasses } from './ListRenderer';
5
5
  import type { ListCssClasses, ListRendererInterface } from './ListRenderer';
6
6
  import { CssPrefix } from '../styles/CssPrefix';
7
- const IconCheck = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
8
- <path d="M7 12L10.4884 15.8372C10.5677 15.9245 10.705 15.9245 10.7844 15.8372L17 9" stroke="black" stroke-width="2" stroke-linecap="round"/>
9
- </svg>
10
- `;
7
+ import { IconCheck } from "../../../icons";
11
8
 
12
9
  /**
13
10
  * Interface that represents all list used only in unordered list rendering
@@ -1,46 +1,28 @@
1
1
  import type { API, BlockAPI, PasteConfig, ToolboxConfig } from '@ebl-vue/editorjs';
2
2
  import type {
3
3
  BlockToolConstructorOptions,
4
- MenuConfigItem,
4
+
5
5
  ToolConfig
6
6
  } from '@editorjs/editorjs/types/tools';
7
7
 
8
- import { IconStartWith } from './styles/icons/index.js';
8
+
9
9
  import type { ListConfig, ListData, ListDataStyle, ListItem, OldListData } from './types/ListParams';
10
10
  import ListTabulator from './ListTabulator';
11
11
  import { CheckListRenderer, OrderedListRenderer, UnorderedListRenderer } from './ListRenderer';
12
12
  import type { ListRenderer } from './types/ListRenderer';
13
- import { renderToolboxInput } from './utils/renderToolboxInput';
14
- import { OlCounterIconsMap, type OlCounterType, OlCounterTypesMap } from './types/OlCounterType';
15
-
16
- const IconListBulleted = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
17
- <line x1="9" y1="7" x2="19" y2="7" stroke="black" stroke-width="2" stroke-linecap="round"/>
18
- <line x1="9" y1="12" x2="19" y2="12" stroke="black" stroke-width="2" stroke-linecap="round"/>
19
- <line x1="9" y1="17" x2="19" y2="17" stroke="black" stroke-width="2" stroke-linecap="round"/>
20
- <path d="M5.00001 17H4.99002" stroke="black" stroke-width="2" stroke-linecap="round"/>
21
- <path d="M5.00001 12H4.99002" stroke="black" stroke-width="2" stroke-linecap="round"/>
22
- <path d="M5.00001 7H4.99002" stroke="black" stroke-width="2" stroke-linecap="round"/>
23
- </svg>
24
- `;
25
- const IconListNumbered = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
26
- <line x1="12" y1="7" x2="19" y2="7" stroke="black" stroke-width="2" stroke-linecap="round"/>
27
- <line x1="12" y1="12" x2="19" y2="12" stroke="black" stroke-width="2" stroke-linecap="round"/>
28
- <line x1="12" y1="17" x2="19" y2="17" stroke="black" stroke-width="2" stroke-linecap="round"/>
29
- <path d="M7.79999 14L7.79999 7.2135C7.79999 7.12872 7.7011 7.0824 7.63597 7.13668L4.79999 9.5" stroke="black" stroke-width="2" stroke-linecap="round"/>
30
- </svg>
31
- `;
32
- const IconChecklist = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
33
- <path d="M9.2 12L11.0586 13.8586C11.1367 13.9367 11.2633 13.9367 11.3414 13.8586L14.7 10.5" stroke="black" stroke-width="2" stroke-linecap="round"/>
34
- <rect x="5" y="5" width="14" height="14" rx="4" stroke="black" stroke-width="2"/>
35
- </svg>
36
- `;
13
+
14
+ import { type OlCounterType, OlCounterTypesMap } from './types/OlCounterType';
15
+
16
+ import { IconListBulleted, IconListNumbered, IconChecklist } from "../../icons";
17
+
18
+
37
19
 
38
20
  /**
39
21
  * Build styles
40
22
  */
41
23
  import './styles/list.css';
42
24
  import './styles/input.css';
43
- import stripNumbers from './utils/stripNumbers';
25
+
44
26
  import normalizeData from './utils/normalizeData';
45
27
  import type { PasteEvent } from './types';
46
28
  import type { OrderedListItemMeta } from './types/ItemMeta';
@@ -54,6 +36,7 @@ export type ListParams = BlockToolConstructorOptions<ListData | OldListData, Lis
54
36
  * Default class of the component used in editor
55
37
  */
56
38
  export default class EditorjsList {
39
+ defaultCounterTypes: OlCounterType[];
57
40
  /**
58
41
  * Notify core that read-only mode is supported
59
42
  */
@@ -196,7 +179,7 @@ export default class EditorjsList {
196
179
  /**
197
180
  * Default Counter type of the ordered list
198
181
  */
199
- private defaultCounterTypes: OlCounterType[];
182
+ //private defaultCounterTypes: OlCounterType[];
200
183
 
201
184
  /**
202
185
  * Tool's data
@@ -438,21 +421,21 @@ export default class EditorjsList {
438
421
  * Changes ordered list counterType property value
439
422
  * @param counterType - new value of the counterType value
440
423
  */
441
- private changeCounters(counterType: OlCounterType): void {
442
- this.list?.changeCounters(counterType);
424
+ // private changeCounters(counterType: OlCounterType): void {
425
+ // this.list?.changeCounters(counterType);
443
426
 
444
- (this.data.meta as OrderedListItemMeta).counterType = counterType;
445
- }
427
+ // (this.data.meta as OrderedListItemMeta).counterType = counterType;
428
+ // }
446
429
 
447
430
  /**
448
431
  * Changes ordered list start property value
449
432
  * @param index - new value of the start property
450
- */
451
- private changeStartWith(index: number): void {
452
- this.list?.changeStartWith(index);
433
+ // */
434
+ // private changeStartWith(index: number): void {
435
+ // this.list?.changeStartWith(index);
453
436
 
454
- (this.data.meta as OrderedListItemMeta).start = index;
455
- }
437
+ // (this.data.meta as OrderedListItemMeta).start = index;
438
+ // }
456
439
 
457
440
  /**
458
441
  * This method allows changing tabulator respectfully to passed style
@@ -1,4 +1,4 @@
1
- import { IconNumber, IconLowerRoman, IconUpperRoman, IconLowerAlpha, IconUpperAlpha } from '../styles/icons/index.js';
1
+ import { IconNumber, IconLowerRoman, IconUpperRoman, IconLowerAlpha, IconUpperAlpha } from '../../../icons';
2
2
 
3
3
  export type OlCounterType = 'numeric' | 'upper-roman' | 'lower-roman' | 'upper-alpha' | 'lower-alpha';
4
4
 
@@ -2,15 +2,23 @@
2
2
  * Build styles
3
3
  */
4
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>`;
5
+ import type { API } from '@ebl-vue/editorjs';
6
+ import { IconMarker } from '../../icons';
7
7
 
8
8
  /**
9
9
  * Marker Tool for the Editor.js
10
10
  *
11
11
  * Allows to wrap inline fragment and style it somehow.
12
12
  */
13
- export default class Marker {
13
+ export default class Marker {
14
+ private api: API;
15
+ private button: HTMLElement | null;
16
+ private tag: string;
17
+ private iconClasses: {base: string; active: string};
18
+
19
+ static get toolboxIcon() {
20
+ return IconMarker;
21
+ }
14
22
  /**
15
23
  * Class name for term-tag
16
24
  *
@@ -23,7 +31,7 @@ const IconMarker = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
23
31
  /**
24
32
  * @param {{api: object}} - Editor.js API
25
33
  */
26
- constructor({api}) {
34
+ constructor({api}: {api: any}) {
27
35
  this.api = api;
28
36
 
29
37
  /**
@@ -65,7 +73,8 @@ const IconMarker = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
65
73
  */
66
74
  render() {
67
75
  this.button = document.createElement('button');
68
- this.button.type = 'button';
76
+ //this.button.type = 'button';
77
+ this.button.setAttribute("type", "button");
69
78
  this.button.classList.add(this.iconClasses.base);
70
79
  this.button.innerHTML = this.toolboxIcon;
71
80
 
@@ -77,7 +86,7 @@ const IconMarker = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
77
86
  *
78
87
  * @param {Range} range - selected fragment
79
88
  */
80
- surround(range) {
89
+ surround(range:Range) {
81
90
  if (!range) {
82
91
  return;
83
92
  }
@@ -99,7 +108,7 @@ const IconMarker = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
99
108
  *
100
109
  * @param {Range} range - selected fragment
101
110
  */
102
- wrap(range) {
111
+ wrap(range:Range) {
103
112
  /**
104
113
  * Create a wrapper for highlighting
105
114
  */
@@ -127,32 +136,35 @@ const IconMarker = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
127
136
  *
128
137
  * @param {HTMLElement} termWrapper - term wrapper tag
129
138
  */
130
- unwrap(termWrapper) {
139
+ unwrap(termWrapper: HTMLElement) {
131
140
  /**
132
141
  * Expand selection to all term-tag
133
142
  */
134
143
  this.api.selection.expandToTag(termWrapper);
135
144
 
136
145
  let sel = window.getSelection();
137
- let range = sel.getRangeAt(0);
146
+ let range = sel?.getRangeAt(0);
138
147
 
139
- let unwrappedContent = range.extractContents();
148
+ let unwrappedContent = range?.extractContents();
140
149
 
141
150
  /**
142
151
  * Remove empty term-tag
143
152
  */
144
- termWrapper.parentNode.removeChild(termWrapper);
153
+ termWrapper?.parentNode?.removeChild(termWrapper);
145
154
 
146
155
  /**
147
156
  * Insert extracted content
148
157
  */
149
- range.insertNode(unwrappedContent);
150
-
158
+ if (unwrappedContent) {
159
+ range?.insertNode(unwrappedContent);
160
+ }
151
161
  /**
152
162
  * Restore selection
153
163
  */
154
- sel.removeAllRanges();
155
- sel.addRange(range);
164
+ sel?.removeAllRanges();
165
+ if (range) {
166
+ sel?.addRange(range);
167
+ }
156
168
  }
157
169
 
158
170
  /**
@@ -161,7 +173,7 @@ const IconMarker = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
161
173
  checkState() {
162
174
  const termTag = this.api.selection.findParentTag(this.tag, Marker.CSS);
163
175
 
164
- this.button.classList.toggle(this.iconClasses.active, !!termTag);
176
+ this.button?.classList.toggle(this.iconClasses.active, !!termTag);
165
177
  }
166
178
 
167
179
  /**
@@ -4,7 +4,8 @@
4
4
  import './index.css';
5
5
 
6
6
  import makeFragment from './utils/makeFragment';
7
- import type { BlockToolConstructorOptions } from '@ebl-vue/editorjs';
7
+ import type { BlockToolConstructorOptions } from '@ebl-vue/editorjs';
8
+ import {IconText} from "../../icons";
8
9
  export type ToolConstructorOptions = BlockToolConstructorOptions<ParagraphData>;
9
10
 
10
11
 
@@ -372,7 +373,7 @@ export default class Paragraph {
372
373
  */
373
374
  static get toolbox(): ToolboxConfig {
374
375
  return {
375
- icon: `<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="M8 9V7.2C8 7.08954 8.08954 7 8.2 7L12 7M16 9V7.2C16 7.08954 15.9105 7 15.8 7L12 7M12 7L12 17M12 17H10M12 17H14"/></svg>`,
376
+ icon: IconText,
376
377
  title: 'Text',
377
378
 
378
379
  };
@@ -3,12 +3,9 @@ import "./index.css";
3
3
 
4
4
  import { make } from "@editorjs/dom";
5
5
  import type { API, BlockAPI, BlockTool } from "@ebl-vue/editorjs";
6
+ import { IconQuote } from "../../icons";
6
7
 
7
8
 
8
- const IconQuote = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
9
- <path d="M10 10.8182L9 10.8182C8.80222 10.8182 8.60888 10.7649 8.44443 10.665C8.27998 10.5651 8.15181 10.4231 8.07612 10.257C8.00043 10.0909 7.98063 9.90808 8.01922 9.73174C8.0578 9.55539 8.15304 9.39341 8.29289 9.26627C8.43275 9.13913 8.61093 9.05255 8.80491 9.01747C8.99889 8.98239 9.19996 9.00039 9.38268 9.0692C9.56541 9.13801 9.72159 9.25453 9.83147 9.40403C9.94135 9.55353 10 9.72929 10 9.90909L10 12.1818C10 12.664 9.78929 13.1265 9.41421 13.4675C9.03914 13.8084 8.53043 14 8 14" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
10
- <path d="M16 10.8182L15 10.8182C14.8022 10.8182 14.6089 10.7649 14.4444 10.665C14.28 10.5651 14.1518 10.4231 14.0761 10.257C14.0004 10.0909 13.9806 9.90808 14.0192 9.73174C14.0578 9.55539 14.153 9.39341 14.2929 9.26627C14.4327 9.13913 14.6109 9.05255 14.8049 9.01747C14.9989 8.98239 15.2 9.00039 15.3827 9.0692C15.5654 9.13801 15.7216 9.25453 15.8315 9.40403C15.9414 9.55353 16 9.72929 16 9.90909L16 12.1818C16 12.664 15.7893 13.1265 15.4142 13.4675C15.0391 13.8084 14.5304 14 14 14" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
11
- </svg>`;
12
9
 
13
10
 
14
11
 
@@ -1,7 +1,7 @@
1
1
  import Table from './table';
2
2
  import * as $ from './utils/dom';
3
3
 
4
- import { IconTable, IconTableWithHeadings, IconTableWithoutHeadings, IconStretch, IconCollapse } from '../../icons';
4
+ import { IconTable, IconTableWithHeadings, IconTableWithoutHeadings } from '../../icons';
5
5
  import type { BlockTool, BlockToolConstructorOptions,PasteEvent } from '@ebl-vue/editorjs';
6
6
 
7
7
  /**