@oix1987/yjd 1.0.3 → 2.0.0
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/LICENSE +15 -0
- package/README.md +146 -142
- package/core.js +77 -0
- package/dist/core.esm.js +2 -0
- package/dist/core.esm.js.map +1 -0
- package/dist/rich-editor.esm.js +1 -1
- package/dist/rich-editor.esm.js.map +1 -1
- package/dist/rich-editor.min.js +1 -1
- package/dist/rich-editor.min.js.map +1 -1
- package/index.d.ts +134 -103
- package/index.js +227 -0
- package/lib/core/editor.js +1806 -0
- package/lib/core/format.js +540 -0
- package/lib/core/module.js +81 -0
- package/lib/core/registry.js +158 -0
- package/lib/formats/background.js +213 -0
- package/lib/formats/bold.js +49 -0
- package/lib/formats/capitalization.js +579 -0
- package/lib/formats/color.js +183 -0
- package/lib/formats/emoji.js +282 -0
- package/lib/formats/font-family.js +548 -0
- package/lib/formats/heading.js +502 -0
- package/lib/formats/image.js +347 -0
- package/lib/formats/import.js +385 -0
- package/lib/formats/indent.js +297 -0
- package/lib/formats/italic.js +27 -0
- package/lib/formats/line-height.js +562 -0
- package/lib/formats/link.js +251 -0
- package/lib/formats/list.js +635 -0
- package/lib/formats/strike.js +31 -0
- package/lib/formats/subscript.js +40 -0
- package/lib/formats/superscript.js +39 -0
- package/lib/formats/table.js +293 -0
- package/lib/formats/tag.js +304 -0
- package/lib/formats/text-align.js +422 -0
- package/lib/formats/text-size.js +498 -0
- package/lib/formats/underline.js +30 -0
- package/lib/formats/video.js +381 -0
- package/lib/modules/block-toolbar.js +639 -0
- package/lib/modules/code-view.js +447 -0
- package/lib/modules/find-replace.js +273 -0
- package/lib/modules/history.js +425 -0
- package/lib/modules/resize-handles.js +701 -0
- package/lib/modules/slash-menu.js +183 -0
- package/lib/modules/table-toolbar.js +635 -0
- package/lib/modules/toolbar.js +607 -0
- package/lib/styles-loader.js +142 -0
- package/{dist → lib}/styles.css +1285 -35
- package/lib/styles.css.js +2 -0
- package/lib/styles.min.css +1 -0
- package/lib/ui/color-picker.js +296 -0
- package/lib/ui/customselect.js +351 -0
- package/lib/ui/emoji-picker.js +196 -0
- package/lib/ui/icons.js +145 -0
- package/lib/ui/image-popup.js +435 -0
- package/lib/ui/import-popup.js +288 -0
- package/lib/ui/link-popup.js +139 -0
- package/lib/ui/list-picker.js +307 -0
- package/lib/ui/select-button.js +68 -0
- package/lib/ui/table-popup.js +171 -0
- package/lib/ui/tag-popup.js +249 -0
- package/lib/ui/text-align-picker.js +278 -0
- package/lib/ui/video-popup.js +413 -0
- package/lib/utils/exec-command.js +72 -0
- package/lib/utils/history-helper.js +50 -0
- package/lib/utils/popup-helper.js +219 -0
- package/lib/utils/popup-positioning.js +234 -0
- package/lib/utils/sanitize.js +164 -0
- package/package.json +51 -32
- package/umd-entry.js +18 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import Module from '../core/module.js';
|
|
2
|
+
import { sanitizeHtml } from '../utils/sanitize.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Code View Module - Toggles between normal editor view and HTML source code view
|
|
6
|
+
*/
|
|
7
|
+
class CodeView extends Module {
|
|
8
|
+
constructor(editor, options = {}) {
|
|
9
|
+
super(editor, options);
|
|
10
|
+
|
|
11
|
+
this.isCodeView = false;
|
|
12
|
+
this.originalContent = '';
|
|
13
|
+
this.codeTextarea = null;
|
|
14
|
+
this.disabledModules = new Set(); // Track disabled modules
|
|
15
|
+
|
|
16
|
+
this.init();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
init() {
|
|
20
|
+
|
|
21
|
+
// Listen for code view toggle events
|
|
22
|
+
this.editor.on('toolbar-click', (data) => {
|
|
23
|
+
if (data.command === 'code-view') {
|
|
24
|
+
this.toggleCodeView();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Toggle between normal editor view and code view
|
|
31
|
+
*/
|
|
32
|
+
toggleCodeView() {
|
|
33
|
+
|
|
34
|
+
if (this.isCodeView) {
|
|
35
|
+
this.showNormalView();
|
|
36
|
+
} else {
|
|
37
|
+
this.showCodeView();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.updateToolbarButton();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Show code view - display HTML source
|
|
45
|
+
*/
|
|
46
|
+
showCodeView() {
|
|
47
|
+
const editorArea = this.editor.editor;
|
|
48
|
+
if (!editorArea) return;
|
|
49
|
+
|
|
50
|
+
// Store original content
|
|
51
|
+
this.originalContent = editorArea.innerHTML;
|
|
52
|
+
|
|
53
|
+
// Create textarea for code editing
|
|
54
|
+
this.codeTextarea = document.createElement('textarea');
|
|
55
|
+
this.codeTextarea.className = 'code-view-textarea';
|
|
56
|
+
this.codeTextarea.value = this.formatHTML(this.originalContent);
|
|
57
|
+
|
|
58
|
+
// Replace editor content with textarea
|
|
59
|
+
editorArea.style.display = 'none';
|
|
60
|
+
editorArea.parentNode.insertBefore(this.codeTextarea, editorArea);
|
|
61
|
+
|
|
62
|
+
// Add CSS class to wrapper for styling
|
|
63
|
+
const wrapper = this.editor.wrapper;
|
|
64
|
+
if (wrapper) {
|
|
65
|
+
wrapper.classList.add('code-view-active');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Focus on textarea
|
|
69
|
+
this.codeTextarea.focus();
|
|
70
|
+
|
|
71
|
+
// Set flag
|
|
72
|
+
this.isCodeView = true;
|
|
73
|
+
|
|
74
|
+
// Reflect the source content in the word/char counter
|
|
75
|
+
if (typeof this.editor.updateStatusbar === 'function') {
|
|
76
|
+
this.editor.updateStatusbar();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Disable other features
|
|
80
|
+
this.disableOtherFeatures();
|
|
81
|
+
|
|
82
|
+
// Add event listener for real-time updates
|
|
83
|
+
this.codeTextarea.addEventListener('input', () => {
|
|
84
|
+
this.updateOriginalContent();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Show normal editor view - restore visual editor
|
|
91
|
+
*/
|
|
92
|
+
showNormalView() {
|
|
93
|
+
const editorArea = this.editor.editor;
|
|
94
|
+
if (!editorArea || !this.codeTextarea) return;
|
|
95
|
+
|
|
96
|
+
// Get updated content from textarea
|
|
97
|
+
const updatedHTML = this.codeTextarea.value;
|
|
98
|
+
|
|
99
|
+
// Remove textarea
|
|
100
|
+
this.codeTextarea.parentNode.removeChild(this.codeTextarea);
|
|
101
|
+
this.codeTextarea = null;
|
|
102
|
+
|
|
103
|
+
// Remove CSS class from wrapper
|
|
104
|
+
const wrapper = this.editor.wrapper;
|
|
105
|
+
if (wrapper) {
|
|
106
|
+
wrapper.classList.remove('code-view-active');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Show editor area
|
|
110
|
+
editorArea.style.display = '';
|
|
111
|
+
|
|
112
|
+
// Update editor content (sanitize HTML typed in the source view to prevent XSS)
|
|
113
|
+
editorArea.innerHTML = sanitizeHtml(updatedHTML);
|
|
114
|
+
|
|
115
|
+
// Focus on editor
|
|
116
|
+
editorArea.focus();
|
|
117
|
+
|
|
118
|
+
// Set flag
|
|
119
|
+
this.isCodeView = false;
|
|
120
|
+
|
|
121
|
+
// Enable other features
|
|
122
|
+
this.enableOtherFeatures();
|
|
123
|
+
|
|
124
|
+
// Trigger content change event
|
|
125
|
+
this.editor.onContentChange();
|
|
126
|
+
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Disable other features when in code view
|
|
131
|
+
*/
|
|
132
|
+
disableOtherFeatures() {
|
|
133
|
+
// Disable toolbar buttons (except code-view and theme)
|
|
134
|
+
const toolbar = this.editor.getModule('toolbar');
|
|
135
|
+
if (toolbar) {
|
|
136
|
+
const allCommands = [
|
|
137
|
+
'bold', 'italic', 'underline', 'strike', 'subscript', 'superscript',
|
|
138
|
+
'color', 'background', 'link', 'table', 'heading',
|
|
139
|
+
'font-family', 'line-height', 'capitalization', 'text-align', 'list',
|
|
140
|
+
'indent-increase', 'indent-decrease', 'text-size', 'emoji', 'image',
|
|
141
|
+
'video', 'tag', 'import', 'undo', 'redo',
|
|
142
|
+
'clear-format', 'horizontal-rule', 'text-direction', 'find', 'more'
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
allCommands.forEach(command => {
|
|
146
|
+
toolbar.setButtonDisabled(command, true);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Keep code-view and theme enabled
|
|
150
|
+
toolbar.setButtonDisabled('code-view', false);
|
|
151
|
+
toolbar.setButtonDisabled('theme', false);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Disable editor events
|
|
155
|
+
this.disableEditorEvents();
|
|
156
|
+
|
|
157
|
+
// Disable other modules
|
|
158
|
+
this.disableOtherModules();
|
|
159
|
+
|
|
160
|
+
// Hide any open popups
|
|
161
|
+
this.hideAllPopups();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Enable other features when returning to normal view
|
|
166
|
+
*/
|
|
167
|
+
enableOtherFeatures() {
|
|
168
|
+
// Enable toolbar buttons
|
|
169
|
+
const toolbar = this.editor.getModule('toolbar');
|
|
170
|
+
if (toolbar) {
|
|
171
|
+
const allCommands = [
|
|
172
|
+
'bold', 'italic', 'underline', 'strike', 'subscript', 'superscript',
|
|
173
|
+
'color', 'background', 'link', 'table', 'heading',
|
|
174
|
+
'font-family', 'line-height', 'capitalization', 'text-align', 'list',
|
|
175
|
+
'indent-increase', 'indent-decrease', 'text-size', 'emoji', 'image',
|
|
176
|
+
'video', 'tag', 'import', 'undo', 'redo',
|
|
177
|
+
'clear-format', 'horizontal-rule', 'text-direction', 'find', 'more'
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
allCommands.forEach(command => {
|
|
181
|
+
toolbar.setButtonDisabled(command, false);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Enable editor events
|
|
186
|
+
this.enableEditorEvents();
|
|
187
|
+
|
|
188
|
+
// Enable other modules
|
|
189
|
+
this.enableOtherModules();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Disable editor events when in code view
|
|
194
|
+
*/
|
|
195
|
+
disableEditorEvents() {
|
|
196
|
+
const editorArea = this.editor.editor;
|
|
197
|
+
if (!editorArea) return;
|
|
198
|
+
|
|
199
|
+
// Make editor non-editable to disable all editing functionality
|
|
200
|
+
editorArea.contentEditable = false;
|
|
201
|
+
|
|
202
|
+
// Add a visual indicator that editor is disabled
|
|
203
|
+
editorArea.style.opacity = '0.5';
|
|
204
|
+
editorArea.style.pointerEvents = 'none';
|
|
205
|
+
editorArea.style.cursor = 'not-allowed';
|
|
206
|
+
|
|
207
|
+
// Add a title to indicate the editor is disabled
|
|
208
|
+
editorArea.title = 'Editor is disabled in code view mode. Click "Switch to Visual Editor" to return to normal editing.';
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Enable editor events when returning to normal view
|
|
213
|
+
*/
|
|
214
|
+
enableEditorEvents() {
|
|
215
|
+
const editorArea = this.editor.editor;
|
|
216
|
+
if (!editorArea) return;
|
|
217
|
+
|
|
218
|
+
// Restore editor functionality
|
|
219
|
+
editorArea.contentEditable = true;
|
|
220
|
+
editorArea.style.opacity = '';
|
|
221
|
+
editorArea.style.pointerEvents = '';
|
|
222
|
+
editorArea.style.cursor = '';
|
|
223
|
+
editorArea.title = '';
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Disable other modules when in code view
|
|
228
|
+
*/
|
|
229
|
+
disableOtherModules() {
|
|
230
|
+
const modulesToDisable = ['history', 'block-toolbar', 'table-toolbar', 'resize-handles'];
|
|
231
|
+
|
|
232
|
+
modulesToDisable.forEach(moduleName => {
|
|
233
|
+
const module = this.editor.getModule(moduleName);
|
|
234
|
+
if (module) {
|
|
235
|
+
// Try to disable module if it has disable method
|
|
236
|
+
if (typeof module.disable === 'function') {
|
|
237
|
+
module.disable();
|
|
238
|
+
this.disabledModules.add(moduleName);
|
|
239
|
+
}
|
|
240
|
+
// For modules without disable method, we can hide their UI elements
|
|
241
|
+
else if (module.getContainer && typeof module.getContainer === 'function') {
|
|
242
|
+
const container = module.getContainer();
|
|
243
|
+
if (container) {
|
|
244
|
+
container.style.display = 'none';
|
|
245
|
+
this.disabledModules.add(moduleName);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Enable other modules when returning to normal view
|
|
254
|
+
*/
|
|
255
|
+
enableOtherModules() {
|
|
256
|
+
this.disabledModules.forEach(moduleName => {
|
|
257
|
+
const module = this.editor.getModule(moduleName);
|
|
258
|
+
if (module) {
|
|
259
|
+
// Try to enable module if it has enable method
|
|
260
|
+
if (typeof module.enable === 'function') {
|
|
261
|
+
module.enable();
|
|
262
|
+
}
|
|
263
|
+
// For modules without enable method, show their UI elements
|
|
264
|
+
else if (module.getContainer && typeof module.getContainer === 'function') {
|
|
265
|
+
const container = module.getContainer();
|
|
266
|
+
if (container) {
|
|
267
|
+
container.style.display = '';
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
this.disabledModules.clear();
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Update original content when user types in textarea
|
|
278
|
+
*/
|
|
279
|
+
updateOriginalContent() {
|
|
280
|
+
if (this.codeTextarea) {
|
|
281
|
+
this.originalContent = this.codeTextarea.value;
|
|
282
|
+
|
|
283
|
+
// Trigger content change event to call onChange callback
|
|
284
|
+
// Get the HTML content from textarea
|
|
285
|
+
const content = this.codeTextarea.value;
|
|
286
|
+
|
|
287
|
+
// Call onChange callback if provided
|
|
288
|
+
if (this.editor.options.onChange && typeof this.editor.options.onChange === 'function') {
|
|
289
|
+
this.editor.options.onChange(content);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Emit text-change event
|
|
293
|
+
this.editor.emit('text-change', content);
|
|
294
|
+
|
|
295
|
+
// Keep the word/char counter in sync with the edited source
|
|
296
|
+
if (typeof this.editor.updateStatusbar === 'function') {
|
|
297
|
+
this.editor.updateStatusbar();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Format HTML for better readability
|
|
304
|
+
*/
|
|
305
|
+
formatHTML(html) {
|
|
306
|
+
let formatted = html;
|
|
307
|
+
|
|
308
|
+
// Tách thẻ mở và đóng thành dòng riêng biệt
|
|
309
|
+
formatted = formatted.replace(/></g, '>\n<');
|
|
310
|
+
|
|
311
|
+
// Tách nội dung giữa thẻ mở và đóng thành dòng riêng
|
|
312
|
+
formatted = formatted.replace(/>([^<>\s][^<]*)</g, '>\n$1\n<');
|
|
313
|
+
|
|
314
|
+
const lines = formatted.split('\n');
|
|
315
|
+
const indentSize = 4;
|
|
316
|
+
const formattedLines = [];
|
|
317
|
+
const tagStack = []; // Stack để theo dõi thẻ mở
|
|
318
|
+
|
|
319
|
+
for (let line of lines) {
|
|
320
|
+
const trimmed = line.trim();
|
|
321
|
+
if (!trimmed) continue;
|
|
322
|
+
|
|
323
|
+
// Check for closing tag - xử lý trước khi in
|
|
324
|
+
if (/^<\/(\w+)/.test(trimmed)) {
|
|
325
|
+
const closeTagMatch = trimmed.match(/^<\/(\w+)/);
|
|
326
|
+
if (closeTagMatch) {
|
|
327
|
+
const tagName = closeTagMatch[1];
|
|
328
|
+
// Tìm và loại bỏ thẻ mở tương ứng từ stack
|
|
329
|
+
for (let i = tagStack.length - 1; i >= 0; i--) {
|
|
330
|
+
if (tagStack[i] === tagName) {
|
|
331
|
+
tagStack.splice(i, 1);
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Apply indentation based on current stack level
|
|
339
|
+
let currentLevel = tagStack.length;
|
|
340
|
+
|
|
341
|
+
// Nếu là nội dung text (không phải thẻ), nó nằm bên trong thẻ cha nên cần thụt lề thêm
|
|
342
|
+
if (!trimmed.startsWith('<')) {
|
|
343
|
+
currentLevel = tagStack.length;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
formattedLines.push(' '.repeat(currentLevel * indentSize) + trimmed);
|
|
347
|
+
|
|
348
|
+
// Check for opening tag (not self-closing) - xử lý sau khi in
|
|
349
|
+
const openTagMatch = trimmed.match(/^<(\w+)/);
|
|
350
|
+
if (
|
|
351
|
+
openTagMatch &&
|
|
352
|
+
!trimmed.startsWith('</') &&
|
|
353
|
+
!trimmed.endsWith('/>') &&
|
|
354
|
+
!['area','base','br','col','embed','hr','img','input','link','meta','param','source','track','wbr'].includes(openTagMatch[1].toLowerCase())
|
|
355
|
+
) {
|
|
356
|
+
const tagName = openTagMatch[1];
|
|
357
|
+
tagStack.push(tagName);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return formattedLines.join('\n');
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Update toolbar button state
|
|
366
|
+
*/
|
|
367
|
+
updateToolbarButton() {
|
|
368
|
+
|
|
369
|
+
const toolbar = this.editor.getModule('toolbar');
|
|
370
|
+
if (toolbar) {
|
|
371
|
+
toolbar.setButtonActive('code-view', this.isCodeView);
|
|
372
|
+
|
|
373
|
+
// Update button title
|
|
374
|
+
const buttonTitle = this.isCodeView ? 'Switch to Visual Editor' : 'Switch to HTML Editor';
|
|
375
|
+
toolbar.setButtonTitle('code-view', buttonTitle);
|
|
376
|
+
|
|
377
|
+
} else {
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Check if currently in code view
|
|
383
|
+
*/
|
|
384
|
+
isInCodeView() {
|
|
385
|
+
return this.isCodeView;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Get current content (from textarea if in code view, otherwise from editor)
|
|
390
|
+
*/
|
|
391
|
+
getCurrentContent() {
|
|
392
|
+
if (this.isCodeView && this.codeTextarea) {
|
|
393
|
+
return this.codeTextarea.value;
|
|
394
|
+
}
|
|
395
|
+
return this.editor.editor.innerHTML;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Set content programmatically
|
|
400
|
+
*/
|
|
401
|
+
setContent(html) {
|
|
402
|
+
if (this.isCodeView && this.codeTextarea) {
|
|
403
|
+
this.codeTextarea.value = this.formatHTML(html);
|
|
404
|
+
this.updateOriginalContent();
|
|
405
|
+
} else {
|
|
406
|
+
this.editor.editor.innerHTML = html;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Hide all popups when entering code view
|
|
412
|
+
*/
|
|
413
|
+
hideAllPopups() {
|
|
414
|
+
// Remove all popup elements from the DOM
|
|
415
|
+
const popups = document.querySelectorAll('.rich-editor-popup, .color-picker-popup, .emoji-picker-popup, .link-popup, .image-popup, .video-popup, .table-popup, .tag-popup, .import-popup');
|
|
416
|
+
popups.forEach(popup => {
|
|
417
|
+
if (popup.parentNode) {
|
|
418
|
+
popup.parentNode.removeChild(popup);
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
// Clear any popup instances from the editor
|
|
423
|
+
if (this.editor.popupInstances) {
|
|
424
|
+
this.editor.popupInstances.clear();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Clean up when module is destroyed
|
|
430
|
+
*/
|
|
431
|
+
destroy() {
|
|
432
|
+
if (this.isCodeView) {
|
|
433
|
+
this.showNormalView();
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (this.codeTextarea && this.codeTextarea.parentNode) {
|
|
437
|
+
this.codeTextarea.parentNode.removeChild(this.codeTextarea);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
this.codeTextarea = null;
|
|
441
|
+
this.originalContent = '';
|
|
442
|
+
this.isCodeView = false;
|
|
443
|
+
this.disabledModules.clear();
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export default CodeView;
|