@ebl-vue/editor-full 2.31.24 → 2.31.28
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/dist/index.d.ts +1 -28
- package/dist/index.mjs +540 -702
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/types/index.d.ts +5 -1
- package/.postcssrc.yml +0 -33
- package/postcss.config.js +0 -15
- package/src/components/Editor/Editor.vue +0 -293
- package/src/components/Editor/EditorRender.vue +0 -274
- package/src/components/index.ts +0 -29
- package/src/constants/index.ts +0 -1
- package/src/i18n/zh-cn.ts +0 -158
- package/src/icons/index.ts +0 -93
- package/src/index.ts +0 -22
- package/src/installer.ts +0 -21
- package/src/plugins/alert/index.css +0 -150
- package/src/plugins/alert/index.ts +0 -456
- package/src/plugins/block-alignment/index.css +0 -9
- package/src/plugins/block-alignment/index.ts +0 -117
- package/src/plugins/block-alignment/readme.md +0 -1
- package/src/plugins/code/LICENSE +0 -21
- package/src/plugins/code/index.css +0 -158
- package/src/plugins/code/index.ts +0 -573
- package/src/plugins/code/utils/string.ts +0 -34
- package/src/plugins/color-picker/index.ts +0 -130
- package/src/plugins/color-picker/styles.css +0 -27
- package/src/plugins/delimiter/index.css +0 -14
- package/src/plugins/delimiter/index.ts +0 -121
- package/src/plugins/drag-drop/index.css +0 -19
- package/src/plugins/drag-drop/index.ts +0 -151
- package/src/plugins/drag-drop/readme.md +0 -1
- package/src/plugins/header/H1.ts +0 -404
- package/src/plugins/header/H2.ts +0 -403
- package/src/plugins/header/H3.ts +0 -404
- package/src/plugins/header/H4.ts +0 -404
- package/src/plugins/header/H5.ts +0 -403
- package/src/plugins/header/H6.ts +0 -404
- package/src/plugins/header/index.css +0 -20
- package/src/plugins/header/index.ts +0 -15
- package/src/plugins/header/types.d.ts +0 -46
- package/src/plugins/imageResizeCrop/ImageTune.ts +0 -916
- package/src/plugins/imageResizeCrop/index.css +0 -230
- package/src/plugins/imageResizeCrop/index.ts +0 -5
- package/src/plugins/imageResizeCrop/types.d.ts +0 -23
- package/src/plugins/imageTool/index.css +0 -156
- package/src/plugins/imageTool/index.ts +0 -538
- package/src/plugins/imageTool/types/codexteam__ajax.d.ts +0 -89
- package/src/plugins/imageTool/types/types.ts +0 -236
- package/src/plugins/imageTool/ui.ts +0 -313
- package/src/plugins/imageTool/uploader.ts +0 -272
- package/src/plugins/imageTool/utils/dom.ts +0 -24
- package/src/plugins/imageTool/utils/index.ts +0 -73
- package/src/plugins/imageTool/utils/isPromise.ts +0 -10
- package/src/plugins/indent/index.css +0 -86
- package/src/plugins/indent/index.ts +0 -695
- package/src/plugins/inline-code/index.css +0 -11
- package/src/plugins/inline-code/index.ts +0 -202
- package/src/plugins/list/ListRenderer/ChecklistRenderer.ts +0 -208
- package/src/plugins/list/ListRenderer/ListRenderer.ts +0 -73
- package/src/plugins/list/ListRenderer/OrderedListRenderer.ts +0 -123
- package/src/plugins/list/ListRenderer/UnorderedListRenderer.ts +0 -123
- package/src/plugins/list/ListRenderer/index.ts +0 -6
- package/src/plugins/list/ListTabulator/index.ts +0 -1179
- package/src/plugins/list/index.ts +0 -480
- package/src/plugins/list/styles/CssPrefix.ts +0 -4
- package/src/plugins/list/styles/input.css +0 -36
- package/src/plugins/list/styles/list.css +0 -165
- package/src/plugins/list/types/Elements.ts +0 -14
- package/src/plugins/list/types/ItemMeta.ts +0 -40
- package/src/plugins/list/types/ListParams.ts +0 -102
- package/src/plugins/list/types/ListRenderer.ts +0 -6
- package/src/plugins/list/types/OlCounterType.ts +0 -63
- package/src/plugins/list/types/index.ts +0 -14
- package/src/plugins/list/utils/focusItem.ts +0 -18
- package/src/plugins/list/utils/getChildItems.ts +0 -40
- package/src/plugins/list/utils/getItemChildWrapper.ts +0 -10
- package/src/plugins/list/utils/getItemContentElement.ts +0 -10
- package/src/plugins/list/utils/getSiblings.ts +0 -52
- package/src/plugins/list/utils/isLastItem.ts +0 -9
- package/src/plugins/list/utils/itemHasSublist.ts +0 -10
- package/src/plugins/list/utils/normalizeData.ts +0 -83
- package/src/plugins/list/utils/removeChildWrapperIfEmpty.ts +0 -31
- package/src/plugins/list/utils/renderToolboxInput.ts +0 -105
- package/src/plugins/list/utils/stripNumbers.ts +0 -7
- package/src/plugins/list/utils/type-guards.ts +0 -8
- package/src/plugins/marker/index.css +0 -4
- package/src/plugins/marker/index.ts +0 -199
- package/src/plugins/outline/index.css +0 -52
- package/src/plugins/outline/index.ts +0 -63
- package/src/plugins/paragraph/index.css +0 -23
- package/src/plugins/paragraph/index.ts +0 -381
- package/src/plugins/paragraph/types/icons.d.ts +0 -4
- package/src/plugins/paragraph/utils/makeFragment.ts +0 -17
- package/src/plugins/quote/index.css +0 -26
- package/src/plugins/quote/index.ts +0 -203
- package/src/plugins/table/index.ts +0 -4
- package/src/plugins/table/plugin.ts +0 -254
- package/src/plugins/table/style.css +0 -388
- package/src/plugins/table/table.ts +0 -1195
- package/src/plugins/table/toolbox.ts +0 -166
- package/src/plugins/table/utils/dom.ts +0 -130
- package/src/plugins/table/utils/popover.ts +0 -185
- package/src/plugins/table/utils/throttled.ts +0 -22
- package/src/plugins/underline/index.css +0 -3
- package/src/plugins/underline/index.ts +0 -214
- package/src/plugins/undo/index.ts +0 -524
- package/src/plugins/undo/observer.ts +0 -101
- package/src/style.css +0 -114
- package/src/types.ts +0 -3
- package/src/utils/AxiosService.ts +0 -87
- package/src/utils/index.ts +0 -15
- package/src/utils/install.ts +0 -19
- package/tsconfig.json +0 -37
- package/vite.config.ts +0 -81
|
@@ -1,573 +0,0 @@
|
|
|
1
|
-
//https://github.com/yudaapratama/editorjs-shiki
|
|
2
|
-
import './index.css';
|
|
3
|
-
import type { API, BlockTool, BlockToolConstructorOptions, BlockToolData, PasteConfig, PasteEvent, SanitizerConfig, ToolboxConfig } from '@ebl-vue/editorjs';
|
|
4
|
-
import { codeToHtml, bundledLanguagesInfo as languages } from 'shiki'
|
|
5
|
-
import { getLineStartPosition } from './utils/string';
|
|
6
|
-
import { IconCode ,IconCopy} from "../../icons";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* CodeTool for Editor.js
|
|
10
|
-
* @version 1.0.0
|
|
11
|
-
* @license MIT
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Data structure for CodeTool's data
|
|
16
|
-
*/
|
|
17
|
-
export type CodeData = BlockToolData<{
|
|
18
|
-
/**
|
|
19
|
-
* The code content input by the user
|
|
20
|
-
*/
|
|
21
|
-
code: string;
|
|
22
|
-
lang: string;
|
|
23
|
-
theme: string;
|
|
24
|
-
}>;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Configuration options for the CodeTool provided by the user
|
|
28
|
-
*/
|
|
29
|
-
export interface CodeConfig {
|
|
30
|
-
/**
|
|
31
|
-
* Placeholder text to display in the input field when it's empty
|
|
32
|
-
*/
|
|
33
|
-
placeholder: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Defines the CSS class names used by CodeTool for styling its elements
|
|
38
|
-
*/
|
|
39
|
-
interface CodeToolCSS {
|
|
40
|
-
/** Block Styling from Editor.js API */
|
|
41
|
-
baseClass: string;
|
|
42
|
-
/** Input Styling from Editor.js API */
|
|
43
|
-
input: string;
|
|
44
|
-
/** Wrapper styling */
|
|
45
|
-
wrapper: string;
|
|
46
|
-
/** Textarea styling */
|
|
47
|
-
textarea: string;
|
|
48
|
-
/** Span styling */
|
|
49
|
-
span: string;
|
|
50
|
-
/** Selector Language styling */
|
|
51
|
-
selectorLanguage: string;
|
|
52
|
-
/** Selector Theme styling */
|
|
53
|
-
selectorTheme: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Holds references to the DOM elements used by CodeTool
|
|
58
|
-
*/
|
|
59
|
-
interface CodeToolNodes {
|
|
60
|
-
/** Main container or Wrapper for CodeTool */
|
|
61
|
-
holder: HTMLDivElement | null;
|
|
62
|
-
/** Textarea where user inputs their code */
|
|
63
|
-
textarea: HTMLTextAreaElement | null;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Options passed to the constructor of a block tool
|
|
68
|
-
*/
|
|
69
|
-
export type CodeToolConstructorOptions = BlockToolConstructorOptions<CodeData>;
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Code Tool for the Editor.js allows to include code examples in your articles.
|
|
73
|
-
*/
|
|
74
|
-
export default class CodeTool implements BlockTool {
|
|
75
|
-
/**
|
|
76
|
-
* API provided by Editor.js for interacting with the editor's core functionality
|
|
77
|
-
*/
|
|
78
|
-
private api: API;
|
|
79
|
-
/**
|
|
80
|
-
* Indicates whether the editor is in read-only mode, preventing modifications
|
|
81
|
-
*/
|
|
82
|
-
private readOnly: boolean;
|
|
83
|
-
/**
|
|
84
|
-
* Placeholder text displayed when there is no code content
|
|
85
|
-
*/
|
|
86
|
-
private placeholder: string;
|
|
87
|
-
/**
|
|
88
|
-
* Collection of CSS class names used by CodeTool for styling its elements
|
|
89
|
-
*/
|
|
90
|
-
private CSS: CodeToolCSS;
|
|
91
|
-
/**
|
|
92
|
-
* DOM nodes related to the CodeTool, including containers and other elements
|
|
93
|
-
*/
|
|
94
|
-
private nodes: CodeToolNodes;
|
|
95
|
-
/**
|
|
96
|
-
* Stores the current data (code and other related properties) for the CodeTool
|
|
97
|
-
*/
|
|
98
|
-
private _data!: CodeData;
|
|
99
|
-
/**
|
|
100
|
-
* Default language for the CodeTool
|
|
101
|
-
*/
|
|
102
|
-
private _selectorLanguage: string = '';
|
|
103
|
-
/**
|
|
104
|
-
* Default theme for the CodeTool
|
|
105
|
-
*/
|
|
106
|
-
private _selectorTheme: string = '';
|
|
107
|
-
/**
|
|
108
|
-
* Notify core that read-only mode is supported
|
|
109
|
-
* @returns true if read-only mode is supported
|
|
110
|
-
*/
|
|
111
|
-
public static get isReadOnlySupported(): boolean {
|
|
112
|
-
return true;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Allows pressing Enter key to create line breaks inside the CodeTool textarea
|
|
117
|
-
* This enables multi-line input within the code editor.
|
|
118
|
-
* @returns true if line breaks are allowed in the textarea
|
|
119
|
-
*/
|
|
120
|
-
public static get enableLineBreaks(): boolean {
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Render plugin`s main Element and fill it with saved data
|
|
126
|
-
* @param options - tool constricting options
|
|
127
|
-
* @param options.data — previously saved plugin code
|
|
128
|
-
* @param options.config - user config for Tool
|
|
129
|
-
* @param options.api - Editor.js API
|
|
130
|
-
* @param options.readOnly - read only mode flag
|
|
131
|
-
*/
|
|
132
|
-
constructor({ data, config, api, readOnly }: CodeToolConstructorOptions) {
|
|
133
|
-
this.api = api;
|
|
134
|
-
this.readOnly = readOnly;
|
|
135
|
-
|
|
136
|
-
this.placeholder = this.api.i18n.t(config.placeholder as string || CodeTool.DEFAULT_PLACEHOLDER);
|
|
137
|
-
|
|
138
|
-
this._selectorLanguage = data.lang || config.lang || CodeTool.DEFAULT_LANGUAGE
|
|
139
|
-
this._selectorTheme = data.theme || config.theme || CodeTool.DEFAULT_THEME
|
|
140
|
-
|
|
141
|
-
this.CSS = {
|
|
142
|
-
baseClass: this.api.styles.block,
|
|
143
|
-
input: this.api.styles.input,
|
|
144
|
-
wrapper: 'ce-editorjs-x-shiki',
|
|
145
|
-
textarea: 'ce-editorjs-x-shiki__textarea',
|
|
146
|
-
span: 'ce-editorjs-x-shiki__span',
|
|
147
|
-
selectorLanguage: 'ce-editorjs-x-shiki__selector-language',
|
|
148
|
-
selectorTheme: 'ce-editorjs-x-shiki__selector-theme',
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
this.nodes = {
|
|
152
|
-
holder: null,
|
|
153
|
-
textarea: null,
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
this.data = {
|
|
157
|
-
code: data.code ?? '',
|
|
158
|
-
lang: this._selectorLanguage,
|
|
159
|
-
theme: this._selectorTheme,
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
this.nodes.holder = this.drawView()
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Return Tool's view
|
|
167
|
-
* @returns this.nodes.holder - Code's wrapper
|
|
168
|
-
*/
|
|
169
|
-
public render(): HTMLDivElement {
|
|
170
|
-
return this.nodes.holder!;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Extract Tool's data from the view
|
|
175
|
-
* @param codeWrapper - CodeTool's wrapper, containing textarea with code
|
|
176
|
-
* @returns - saved plugin code
|
|
177
|
-
*/
|
|
178
|
-
public save(codeWrapper: HTMLDivElement): CodeData {
|
|
179
|
-
return {
|
|
180
|
-
code: codeWrapper.querySelector('textarea')!.value,
|
|
181
|
-
lang: this._selectorLanguage,
|
|
182
|
-
theme: this._selectorTheme
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* onPaste callback fired from Editor`s core
|
|
188
|
-
* @param event - event with pasted content
|
|
189
|
-
*/
|
|
190
|
-
public onPaste(event: PasteEvent): void {
|
|
191
|
-
const detail = event.detail;
|
|
192
|
-
|
|
193
|
-
if ('data' in detail) {
|
|
194
|
-
const content = detail.data as string;
|
|
195
|
-
|
|
196
|
-
this.data = {
|
|
197
|
-
code: content || '',
|
|
198
|
-
lang: this._selectorLanguage,
|
|
199
|
-
theme: this._selectorTheme
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Returns Tool`s data from private property
|
|
206
|
-
* @returns
|
|
207
|
-
*/
|
|
208
|
-
public get data(): CodeData {
|
|
209
|
-
return this._data;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Set Tool`s data to private property and update view
|
|
214
|
-
* @param data - saved tool data
|
|
215
|
-
*/
|
|
216
|
-
public set data(data: CodeData) {
|
|
217
|
-
this._data = data;
|
|
218
|
-
|
|
219
|
-
if (this.nodes.textarea) {
|
|
220
|
-
this.nodes.textarea.value = data.code;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Get Tool toolbox settings.
|
|
226
|
-
* Provides the icon and title to display in the toolbox for the CodeTool.
|
|
227
|
-
* @returns An object containing:
|
|
228
|
-
* - icon: SVG representation of the Tool's icon
|
|
229
|
-
* - title: Title to show in the toolbox
|
|
230
|
-
*/
|
|
231
|
-
public static get toolbox(): ToolboxConfig {
|
|
232
|
-
return {
|
|
233
|
-
icon: IconCode,
|
|
234
|
-
title: 'Code',
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Default placeholder for CodeTool's textarea
|
|
240
|
-
* @returns
|
|
241
|
-
*/
|
|
242
|
-
public static get DEFAULT_PLACEHOLDER(): string {
|
|
243
|
-
return 'Enter your code';
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Default language for CodeTool's textarea
|
|
248
|
-
* @returns
|
|
249
|
-
*/
|
|
250
|
-
public static get DEFAULT_LANGUAGE(): string {
|
|
251
|
-
return 'javascript';
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Default theme for CodeTool's textarea
|
|
256
|
-
* @returns
|
|
257
|
-
*/
|
|
258
|
-
public static get DEFAULT_THEME(): string {
|
|
259
|
-
return 'vitesse-dark';
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Used by Editor.js paste handling API.
|
|
264
|
-
* Provides configuration to handle CODE tag.
|
|
265
|
-
* @returns
|
|
266
|
-
*/
|
|
267
|
-
public static get pasteConfig(): PasteConfig {
|
|
268
|
-
return {
|
|
269
|
-
tags: ['pre'],
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Automatic sanitize config
|
|
275
|
-
* @returns
|
|
276
|
-
*/
|
|
277
|
-
public static get sanitize(): SanitizerConfig {
|
|
278
|
-
return {
|
|
279
|
-
code: true, // Allow HTML tags
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Handles Tab key pressing (adds/removes indentations)
|
|
285
|
-
* @param event - keydown
|
|
286
|
-
*/
|
|
287
|
-
private tabHandler(event: KeyboardEvent): void {
|
|
288
|
-
/**
|
|
289
|
-
* Prevent editor.js tab handler
|
|
290
|
-
*/
|
|
291
|
-
event.stopPropagation();
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* Prevent native tab behaviour
|
|
295
|
-
*/
|
|
296
|
-
event.preventDefault();
|
|
297
|
-
|
|
298
|
-
const textarea = event.target as HTMLTextAreaElement;
|
|
299
|
-
const isShiftPressed = event.shiftKey;
|
|
300
|
-
const caretPosition = textarea.selectionStart;
|
|
301
|
-
const value = textarea.value;
|
|
302
|
-
const indentation = ' ';
|
|
303
|
-
|
|
304
|
-
let newCaretPosition;
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* For Tab pressing, just add an indentation to the caret position
|
|
308
|
-
*/
|
|
309
|
-
if (!isShiftPressed) {
|
|
310
|
-
newCaretPosition = caretPosition + indentation.length;
|
|
311
|
-
|
|
312
|
-
textarea.value = value.substring(0, caretPosition) + indentation + value.substring(caretPosition);
|
|
313
|
-
} else {
|
|
314
|
-
/**
|
|
315
|
-
* For Shift+Tab pressing, remove an indentation from the start of line
|
|
316
|
-
*/
|
|
317
|
-
const currentLineStart = getLineStartPosition(value, caretPosition);
|
|
318
|
-
const firstLineChars = value.substr(currentLineStart, indentation.length);
|
|
319
|
-
|
|
320
|
-
if (firstLineChars !== indentation) {
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Trim the first two chars from the start of line
|
|
326
|
-
*/
|
|
327
|
-
textarea.value = value.substring(0, currentLineStart) + value.substring(currentLineStart + indentation.length);
|
|
328
|
-
newCaretPosition = caretPosition - indentation.length;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Restore the caret
|
|
333
|
-
*/
|
|
334
|
-
textarea.setSelectionRange(newCaretPosition, newCaretPosition);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Create Tool's view
|
|
339
|
-
* @returns
|
|
340
|
-
*/
|
|
341
|
-
private drawView(): HTMLDivElement {
|
|
342
|
-
const wrapper = document.createElement('div');
|
|
343
|
-
const wrapperHolder = document.createElement('div');
|
|
344
|
-
const wrapperSelectorHolder = document.createElement('div');
|
|
345
|
-
const wrapperLang = document.createElement('div');
|
|
346
|
-
const wrapperCopy = document.createElement('div');
|
|
347
|
-
const wrapperCopyTip = document.createElement('div');
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
const selectorLanguage = document.createElement('select');
|
|
351
|
-
const selectorTheme = document.createElement('select');
|
|
352
|
-
const span = document.createElement('span');
|
|
353
|
-
const textarea = document.createElement('textarea');
|
|
354
|
-
|
|
355
|
-
wrapper.classList.add(this.CSS.baseClass, this.CSS.wrapper);
|
|
356
|
-
wrapperHolder.classList.add('ce-editorjs-x-shiki__code');
|
|
357
|
-
wrapperSelectorHolder.classList.add('ce-editorjs-x-shiki__selector');
|
|
358
|
-
wrapperLang.classList.add('ce-editorjs-x-shiki__lang');
|
|
359
|
-
wrapperCopy.classList.add('ce-editorjs-x-shiki__copy');
|
|
360
|
-
wrapperCopyTip.classList.add('ce-editorjs-x-shiki__copy_tip');
|
|
361
|
-
|
|
362
|
-
selectorLanguage.classList.add(this.CSS.selectorLanguage);
|
|
363
|
-
//selectorTheme.classList.add(this.CSS.selectorTheme);
|
|
364
|
-
textarea.classList.add(this.CSS.textarea, this.CSS.input);
|
|
365
|
-
|
|
366
|
-
wrapperLang.innerHTML = this.data.lang
|
|
367
|
-
wrapperCopy.innerHTML = IconCopy;
|
|
368
|
-
wrapperCopyTip.innerText = this.api.i18n.t('Copied');
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
languages.forEach((lang) => {
|
|
373
|
-
const option = document.createElement('option');
|
|
374
|
-
option.value = lang.id;
|
|
375
|
-
option.text = lang.name;
|
|
376
|
-
selectorLanguage.appendChild(option);
|
|
377
|
-
});
|
|
378
|
-
selectorLanguage.value = this.data.lang
|
|
379
|
-
|
|
380
|
-
// themes.forEach((theme) => {
|
|
381
|
-
// const option = document.createElement('option');
|
|
382
|
-
// option.value = theme.id;
|
|
383
|
-
// option.text = theme.displayName;
|
|
384
|
-
// selectorTheme.appendChild(option);
|
|
385
|
-
// });
|
|
386
|
-
// selectorTheme.value = this.data.theme
|
|
387
|
-
|
|
388
|
-
textarea.value = this.data.code;
|
|
389
|
-
textarea.placeholder = this.placeholder;
|
|
390
|
-
textarea.spellcheck = false;
|
|
391
|
-
textarea.autocomplete = "off"
|
|
392
|
-
textarea.autocapitalize = "off"
|
|
393
|
-
|
|
394
|
-
if (this.readOnly) {
|
|
395
|
-
textarea.disabled = true;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
wrapperHolder.appendChild(span);
|
|
399
|
-
wrapperHolder.appendChild(textarea);
|
|
400
|
-
|
|
401
|
-
if (!this.readOnly) {
|
|
402
|
-
wrapperSelectorHolder.appendChild(selectorLanguage);
|
|
403
|
-
//wrapperSelectorHolder.appendChild(selectorTheme);
|
|
404
|
-
|
|
405
|
-
} else {
|
|
406
|
-
wrapperSelectorHolder.appendChild(wrapperLang);
|
|
407
|
-
|
|
408
|
-
}
|
|
409
|
-
wrapperCopy.appendChild(wrapperCopyTip);
|
|
410
|
-
|
|
411
|
-
wrapperSelectorHolder.appendChild(wrapperCopy);
|
|
412
|
-
wrapper.appendChild(wrapperSelectorHolder);
|
|
413
|
-
|
|
414
|
-
wrapper.appendChild(wrapperHolder);
|
|
415
|
-
//wrapper.appendChild(wrapperLang);
|
|
416
|
-
|
|
417
|
-
this.runShiki().then(({ html, preStyle }) => {
|
|
418
|
-
|
|
419
|
-
span.innerHTML = html
|
|
420
|
-
wrapper?.setAttribute('style', preStyle)
|
|
421
|
-
selectorLanguage.setAttribute('style', preStyle)
|
|
422
|
-
selectorTheme.setAttribute('style', preStyle)
|
|
423
|
-
})
|
|
424
|
-
|
|
425
|
-
selectorLanguage.addEventListener('change', (event: Event) => {
|
|
426
|
-
const lang = (event.target as HTMLSelectElement).value
|
|
427
|
-
this._selectorLanguage = lang
|
|
428
|
-
this.runShiki().then(({ html, preStyle }) => {
|
|
429
|
-
span.innerHTML = html
|
|
430
|
-
wrapperLang.innerHTML = lang
|
|
431
|
-
})
|
|
432
|
-
})
|
|
433
|
-
|
|
434
|
-
selectorTheme.addEventListener('change', (event: Event) => {
|
|
435
|
-
const theme = (event.target as HTMLSelectElement).value
|
|
436
|
-
this._selectorTheme = theme
|
|
437
|
-
this.runShiki().then(({ html, preStyle }) => {
|
|
438
|
-
span.innerHTML = html
|
|
439
|
-
wrapper?.setAttribute('style', preStyle)
|
|
440
|
-
selectorLanguage.setAttribute('style', preStyle)
|
|
441
|
-
selectorTheme.setAttribute('style', preStyle)
|
|
442
|
-
})
|
|
443
|
-
})
|
|
444
|
-
|
|
445
|
-
textarea.addEventListener('input', () => {
|
|
446
|
-
this.data.code = textarea.value
|
|
447
|
-
this.runShiki().then(({ html, preStyle }) => {
|
|
448
|
-
span.innerHTML = html
|
|
449
|
-
wrapper?.setAttribute('style', preStyle)
|
|
450
|
-
selectorLanguage.setAttribute('style', preStyle)
|
|
451
|
-
selectorTheme.setAttribute('style', preStyle)
|
|
452
|
-
})
|
|
453
|
-
})
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* Enable keydown handlers
|
|
457
|
-
*/
|
|
458
|
-
textarea.addEventListener('keydown', (event) => {
|
|
459
|
-
switch (event.code) {
|
|
460
|
-
case 'Tab':
|
|
461
|
-
this.tabHandler(event);
|
|
462
|
-
this.data.code = textarea.value
|
|
463
|
-
this.runShiki().then(({ html, preStyle }) => {
|
|
464
|
-
span.innerHTML = html
|
|
465
|
-
})
|
|
466
|
-
break;
|
|
467
|
-
}
|
|
468
|
-
});
|
|
469
|
-
wrapperCopy.addEventListener('click', (event: MouseEvent) => {
|
|
470
|
-
this.copyCode(this.data.code, event);
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
this.nodes.textarea = textarea;
|
|
474
|
-
|
|
475
|
-
return wrapper;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
private async runShiki(): Promise<{ html: string, preStyle: string }> {
|
|
479
|
-
let preStyle = ''
|
|
480
|
-
|
|
481
|
-
const html = await codeToHtml(this.data.code, {
|
|
482
|
-
lang: this._selectorLanguage,
|
|
483
|
-
theme: this._selectorTheme,
|
|
484
|
-
|
|
485
|
-
transformers: [
|
|
486
|
-
{
|
|
487
|
-
preprocess(code) {
|
|
488
|
-
// if (code.endsWith('\n'))
|
|
489
|
-
return `${code}\n`
|
|
490
|
-
},
|
|
491
|
-
pre(node) {
|
|
492
|
-
this.addClassToHast(node, 'ce-editorjs-x-shiki__span')
|
|
493
|
-
preStyle = node.properties?.style as string || ''
|
|
494
|
-
},
|
|
495
|
-
line(node, line) {
|
|
496
|
-
node.properties = node.properties || {};
|
|
497
|
-
node.properties['data-line'] = line;
|
|
498
|
-
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
}
|
|
502
|
-
]
|
|
503
|
-
})
|
|
504
|
-
|
|
505
|
-
return {
|
|
506
|
-
html,
|
|
507
|
-
preStyle
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
}
|
|
511
|
-
private showCopyTip(msg: string,event: MouseEvent) {
|
|
512
|
-
const tip = this.api.i18n.t(msg);
|
|
513
|
-
if (event.target) {
|
|
514
|
-
const parentEle = (event.target as HTMLElement).parentElement;
|
|
515
|
-
if (parentEle) {
|
|
516
|
-
const tooltip = parentEle.lastChild as HTMLElement;
|
|
517
|
-
if (tooltip) {
|
|
518
|
-
tooltip.innerHTML = tip;
|
|
519
|
-
tooltip.classList.add('visible');
|
|
520
|
-
setTimeout(() => {
|
|
521
|
-
tooltip.classList.remove('visible');
|
|
522
|
-
|
|
523
|
-
}, 2000);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
private copyCode(code: string, event: MouseEvent) {
|
|
529
|
-
if (this.data.code) {
|
|
530
|
-
if (navigator.clipboard && window.isSecureContext) {
|
|
531
|
-
try {
|
|
532
|
-
navigator.clipboard.writeText(code).then(() => {
|
|
533
|
-
this.showCopyTip('Copied',event);
|
|
534
|
-
}).catch((err) => {
|
|
535
|
-
console.error(err);
|
|
536
|
-
this.showCopyTip('Unable to copy',event);
|
|
537
|
-
});
|
|
538
|
-
|
|
539
|
-
} catch (err) {
|
|
540
|
-
this.showCopyTip('Unable to copy',event);
|
|
541
|
-
}
|
|
542
|
-
} else {
|
|
543
|
-
// 传统方法:使用 textarea 和 execCommand
|
|
544
|
-
|
|
545
|
-
const textArea = document.createElement('textarea');
|
|
546
|
-
textArea.value = code;
|
|
547
|
-
|
|
548
|
-
// 避免滚动到底部
|
|
549
|
-
textArea.style.top = '0';
|
|
550
|
-
textArea.style.left = '0';
|
|
551
|
-
textArea.style.position = 'fixed';
|
|
552
|
-
textArea.style.opacity = '0';
|
|
553
|
-
textArea.style.pointerEvents = 'none';
|
|
554
|
-
textArea.style.zIndex = '-1000';
|
|
555
|
-
|
|
556
|
-
document.body.appendChild(textArea);
|
|
557
|
-
textArea.focus();
|
|
558
|
-
textArea.select();
|
|
559
|
-
try {
|
|
560
|
-
document.execCommand('copy');
|
|
561
|
-
document.body.removeChild(textArea);
|
|
562
|
-
this.showCopyTip('Copied',event);
|
|
563
|
-
} catch (err) {
|
|
564
|
-
this.showCopyTip('Unable to copy',event);
|
|
565
|
-
document.body.removeChild(textArea);
|
|
566
|
-
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
}
|
|
573
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Return the position of line starting from passed point
|
|
3
|
-
*
|
|
4
|
-
* ┌───────────────┐
|
|
5
|
-
* │1234\n │
|
|
6
|
-
* │2eda | dadd\n │ <-- returns 5
|
|
7
|
-
* └───────────────┘
|
|
8
|
-
* @param string - string to process
|
|
9
|
-
* @param position - search starting position
|
|
10
|
-
* @returns
|
|
11
|
-
*/
|
|
12
|
-
export function getLineStartPosition(string: string, position: number): number {
|
|
13
|
-
const charLength = 1;
|
|
14
|
-
let char = '';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Iterate through all the chars before the position till the
|
|
18
|
-
* - end of line (\n)
|
|
19
|
-
* - or start of string (position === 0)
|
|
20
|
-
*/
|
|
21
|
-
while (char !== '\n' && position > 0) {
|
|
22
|
-
position = position - charLength;
|
|
23
|
-
char = string.substr(position, charLength);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Do not count the linebreak symbol because it is related to the previous line
|
|
28
|
-
*/
|
|
29
|
-
if (char === '\n') {
|
|
30
|
-
position += 1;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return position;
|
|
34
|
-
}
|