@ckeditor/ckeditor5-source-editing 41.3.0-alpha.0 → 41.3.0-alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. package/dist/translations/ar.d.ts +8 -0
  2. package/dist/translations/ar.js +5 -0
  3. package/dist/translations/bg.d.ts +8 -0
  4. package/dist/translations/bg.js +5 -0
  5. package/dist/translations/bn.d.ts +8 -0
  6. package/dist/translations/bn.js +5 -0
  7. package/dist/translations/ca.d.ts +8 -0
  8. package/dist/translations/ca.js +5 -0
  9. package/dist/translations/cs.d.ts +8 -0
  10. package/dist/translations/cs.js +5 -0
  11. package/dist/translations/da.d.ts +8 -0
  12. package/dist/translations/da.js +5 -0
  13. package/dist/translations/de.d.ts +8 -0
  14. package/dist/translations/de.js +5 -0
  15. package/dist/translations/el.d.ts +8 -0
  16. package/dist/translations/el.js +5 -0
  17. package/dist/translations/en-au.d.ts +8 -0
  18. package/dist/translations/en-au.js +5 -0
  19. package/dist/translations/en.d.ts +8 -0
  20. package/dist/translations/en.js +5 -0
  21. package/dist/translations/es.d.ts +8 -0
  22. package/dist/translations/es.js +5 -0
  23. package/dist/translations/et.d.ts +8 -0
  24. package/dist/translations/et.js +5 -0
  25. package/dist/translations/fi.d.ts +8 -0
  26. package/dist/translations/fi.js +5 -0
  27. package/dist/translations/fr.d.ts +8 -0
  28. package/dist/translations/fr.js +5 -0
  29. package/dist/translations/gl.d.ts +8 -0
  30. package/dist/translations/gl.js +5 -0
  31. package/dist/translations/he.d.ts +8 -0
  32. package/dist/translations/he.js +5 -0
  33. package/dist/translations/hi.d.ts +8 -0
  34. package/dist/translations/hi.js +5 -0
  35. package/dist/translations/hr.d.ts +8 -0
  36. package/dist/translations/hr.js +5 -0
  37. package/dist/translations/hu.d.ts +8 -0
  38. package/dist/translations/hu.js +5 -0
  39. package/dist/translations/id.d.ts +8 -0
  40. package/dist/translations/id.js +5 -0
  41. package/dist/translations/it.d.ts +8 -0
  42. package/dist/translations/it.js +5 -0
  43. package/dist/translations/ja.d.ts +8 -0
  44. package/dist/translations/ja.js +5 -0
  45. package/dist/translations/ko.d.ts +8 -0
  46. package/dist/translations/ko.js +5 -0
  47. package/dist/translations/lt.d.ts +8 -0
  48. package/dist/translations/lt.js +5 -0
  49. package/dist/translations/lv.d.ts +8 -0
  50. package/dist/translations/lv.js +5 -0
  51. package/dist/translations/ms.d.ts +8 -0
  52. package/dist/translations/ms.js +5 -0
  53. package/dist/translations/nl.d.ts +8 -0
  54. package/dist/translations/nl.js +5 -0
  55. package/dist/translations/no.d.ts +8 -0
  56. package/dist/translations/no.js +5 -0
  57. package/dist/translations/pl.d.ts +8 -0
  58. package/dist/translations/pl.js +5 -0
  59. package/dist/translations/pt-br.d.ts +8 -0
  60. package/dist/translations/pt-br.js +5 -0
  61. package/dist/translations/pt.d.ts +8 -0
  62. package/dist/translations/pt.js +5 -0
  63. package/dist/translations/ro.d.ts +8 -0
  64. package/dist/translations/ro.js +5 -0
  65. package/dist/translations/ru.d.ts +8 -0
  66. package/dist/translations/ru.js +5 -0
  67. package/dist/translations/sk.d.ts +8 -0
  68. package/dist/translations/sk.js +5 -0
  69. package/dist/translations/sr-latn.d.ts +8 -0
  70. package/dist/translations/sr-latn.js +5 -0
  71. package/dist/translations/sr.d.ts +8 -0
  72. package/dist/translations/sr.js +5 -0
  73. package/dist/translations/sv.d.ts +8 -0
  74. package/dist/translations/sv.js +5 -0
  75. package/dist/translations/th.d.ts +8 -0
  76. package/dist/translations/th.js +5 -0
  77. package/dist/translations/tr.d.ts +8 -0
  78. package/dist/translations/tr.js +5 -0
  79. package/dist/translations/ug.d.ts +8 -0
  80. package/dist/translations/ug.js +5 -0
  81. package/dist/translations/uk.d.ts +8 -0
  82. package/dist/translations/uk.js +5 -0
  83. package/dist/translations/ur.d.ts +8 -0
  84. package/dist/translations/ur.js +5 -0
  85. package/dist/translations/vi.d.ts +8 -0
  86. package/dist/translations/vi.js +5 -0
  87. package/dist/translations/zh-cn.d.ts +8 -0
  88. package/dist/translations/zh-cn.js +5 -0
  89. package/dist/translations/zh.d.ts +8 -0
  90. package/dist/translations/zh.js +5 -0
  91. package/dist/types/augmentation.d.ts +4 -0
  92. package/dist/types/index.d.ts +4 -0
  93. package/dist/types/sourceediting.d.ts +4 -0
  94. package/dist/types/sourceeditingconfig.d.ts +4 -0
  95. package/dist/types/utils/formathtml.d.ts +4 -0
  96. package/package.json +3 -3
  97. package/dist/index.js +0 -490
  98. package/dist/index.js.map +0 -1
package/dist/index.js DELETED
@@ -1,490 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
- */
5
- import { Plugin, PendingActions } from '@ckeditor/ckeditor5-core/dist/index.js';
6
- import { ButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';
7
- import { ElementReplacer, CKEditorError, createElement } from '@ckeditor/ckeditor5-utils/dist/index.js';
8
-
9
- /**
10
- * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
11
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
12
- */
13
- /**
14
- * @module source-editing/utils/formathtml
15
- */
16
- /**
17
- * A simple (and naive) HTML code formatter that returns a formatted HTML markup that can be easily
18
- * parsed by human eyes. It beautifies the HTML code by adding new lines between elements that behave like block elements
19
- * (https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
20
- * and a few more like `tr`, `td`, and similar ones) and inserting indents for nested content.
21
- *
22
- * WARNING: This function works only on a text that does not contain any indentations or new lines.
23
- * Calling this function on the already formatted text will damage the formatting.
24
- *
25
- * @param input An HTML string to format.
26
- */
27
- function formatHtml(input) {
28
- // A list of block-like elements around which the new lines should be inserted, and within which
29
- // the indentation of their children should be increased.
30
- // The list is partially based on https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements that contains
31
- // a full list of HTML block-level elements.
32
- // A void element is an element that cannot have any child - https://html.spec.whatwg.org/multipage/syntax.html#void-elements.
33
- // Note that <pre> element is not listed on this list to avoid breaking whitespace formatting.
34
- // Note that <br> element is not listed and handled separately so no additional white spaces are injected.
35
- const elementsToFormat = [
36
- { name: 'address', isVoid: false },
37
- { name: 'article', isVoid: false },
38
- { name: 'aside', isVoid: false },
39
- { name: 'blockquote', isVoid: false },
40
- { name: 'details', isVoid: false },
41
- { name: 'dialog', isVoid: false },
42
- { name: 'dd', isVoid: false },
43
- { name: 'div', isVoid: false },
44
- { name: 'dl', isVoid: false },
45
- { name: 'dt', isVoid: false },
46
- { name: 'fieldset', isVoid: false },
47
- { name: 'figcaption', isVoid: false },
48
- { name: 'figure', isVoid: false },
49
- { name: 'footer', isVoid: false },
50
- { name: 'form', isVoid: false },
51
- { name: 'h1', isVoid: false },
52
- { name: 'h2', isVoid: false },
53
- { name: 'h3', isVoid: false },
54
- { name: 'h4', isVoid: false },
55
- { name: 'h5', isVoid: false },
56
- { name: 'h6', isVoid: false },
57
- { name: 'header', isVoid: false },
58
- { name: 'hgroup', isVoid: false },
59
- { name: 'hr', isVoid: true },
60
- { name: 'li', isVoid: false },
61
- { name: 'main', isVoid: false },
62
- { name: 'nav', isVoid: false },
63
- { name: 'ol', isVoid: false },
64
- { name: 'p', isVoid: false },
65
- { name: 'section', isVoid: false },
66
- { name: 'table', isVoid: false },
67
- { name: 'tbody', isVoid: false },
68
- { name: 'td', isVoid: false },
69
- { name: 'th', isVoid: false },
70
- { name: 'thead', isVoid: false },
71
- { name: 'tr', isVoid: false },
72
- { name: 'ul', isVoid: false }
73
- ];
74
- const elementNamesToFormat = elementsToFormat.map(element => element.name).join('|');
75
- // It is not the fastest way to format the HTML markup but the performance should be good enough.
76
- const lines = input
77
- // Add new line before and after `<tag>` and `</tag>`.
78
- // It may separate individual elements with two new lines, but this will be fixed below.
79
- .replace(new RegExp(`</?(${elementNamesToFormat})( .*?)?>`, 'g'), '\n$&\n')
80
- // Keep `<br>`s at the end of line to avoid adding additional whitespaces before `<br>`.
81
- .replace(/<br[^>]*>/g, '$&\n')
82
- // Divide input string into lines, which start with either an opening tag, a closing tag, or just a text.
83
- .split('\n');
84
- let indentCount = 0;
85
- let isPreformattedLine = false;
86
- return lines
87
- .filter(line => line.length)
88
- .map(line => {
89
- isPreformattedLine = isPreformattedBlockLine(line, isPreformattedLine);
90
- if (isNonVoidOpeningTag(line, elementsToFormat)) {
91
- return indentLine(line, indentCount++);
92
- }
93
- if (isClosingTag(line, elementsToFormat)) {
94
- return indentLine(line, --indentCount);
95
- }
96
- if (isPreformattedLine === 'middle' || isPreformattedLine === 'last') {
97
- return line;
98
- }
99
- return indentLine(line, indentCount);
100
- })
101
- .join('\n');
102
- }
103
- /**
104
- * Checks, if an argument is an opening tag of a non-void element to be formatted.
105
- *
106
- * @param line String to check.
107
- * @param elementsToFormat Elements to be formatted.
108
- */
109
- function isNonVoidOpeningTag(line, elementsToFormat) {
110
- return elementsToFormat.some(element => {
111
- if (element.isVoid) {
112
- return false;
113
- }
114
- if (!new RegExp(`<${element.name}( .*?)?>`).test(line)) {
115
- return false;
116
- }
117
- return true;
118
- });
119
- }
120
- /**
121
- * Checks, if an argument is a closing tag.
122
- *
123
- * @param line String to check.
124
- * @param elementsToFormat Elements to be formatted.
125
- */
126
- function isClosingTag(line, elementsToFormat) {
127
- return elementsToFormat.some(element => {
128
- return new RegExp(`</${element.name}>`).test(line);
129
- });
130
- }
131
- /**
132
- * Indents a line by a specified number of characters.
133
- *
134
- * @param line Line to indent.
135
- * @param indentCount Number of characters to use for indentation.
136
- * @param indentChar Indentation character(s). 4 spaces by default.
137
- */
138
- function indentLine(line, indentCount, indentChar = ' ') {
139
- // More about Math.max() here in https://github.com/ckeditor/ckeditor5/issues/10698.
140
- return `${indentChar.repeat(Math.max(0, indentCount))}${line}`;
141
- }
142
- /**
143
- * Checks whether a line belongs to a preformatted (`<pre>`) block.
144
- *
145
- * @param line Line to check.
146
- * @param isPreviousLinePreFormatted Information on whether the previous line was preformatted (and how).
147
- */
148
- function isPreformattedBlockLine(line, isPreviousLinePreFormatted) {
149
- if (new RegExp('<pre( .*?)?>').test(line)) {
150
- return 'first';
151
- }
152
- else if (new RegExp('</pre>').test(line)) {
153
- return 'last';
154
- }
155
- else if (isPreviousLinePreFormatted === 'first' || isPreviousLinePreFormatted === 'middle') {
156
- return 'middle';
157
- }
158
- else {
159
- return false;
160
- }
161
- }
162
-
163
- var sourceEditingIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m12.5 0 5 4.5v15.003h-16V0h11zM3 1.5v3.25l-1.497 1-.003 8 1.5 1v3.254L7.685 18l-.001 1.504H17.5V8.002L16 9.428l-.004-4.22-4.222-3.692L3 1.5z\"/><path d=\"M4.06 6.64a.75.75 0 0 1 .958 1.15l-.085.07L2.29 9.75l2.646 1.89c.302.216.4.62.232.951l-.058.095a.75.75 0 0 1-.951.232l-.095-.058-3.5-2.5V9.14l3.496-2.5zm4.194 6.22a.75.75 0 0 1-.958-1.149l.085-.07 2.643-1.89-2.646-1.89a.75.75 0 0 1-.232-.952l.058-.095a.75.75 0 0 1 .95-.232l.096.058 3.5 2.5v1.22l-3.496 2.5zm7.644-.836 2.122 2.122-5.825 5.809-2.125-.005.003-2.116zm2.539-1.847 1.414 1.414a.5.5 0 0 1 0 .707l-1.06 1.06-2.122-2.12 1.061-1.061a.5.5 0 0 1 .707 0z\"/></svg>";
164
-
165
- /**
166
- * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
167
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
168
- */
169
- /**
170
- * @module source-editing/sourceediting
171
- */
172
- /* global console */
173
- const COMMAND_FORCE_DISABLE_ID = 'SourceEditingMode';
174
- /**
175
- * The source editing feature.
176
- *
177
- * It provides the possibility to view and edit the source of the document.
178
- *
179
- * For a detailed overview, check the {@glink features/source-editing source editing feature documentation} and the
180
- * {@glink api/source-editing package page}.
181
- */
182
- class SourceEditing extends Plugin {
183
- /**
184
- * @inheritDoc
185
- */
186
- static get pluginName() {
187
- return 'SourceEditing';
188
- }
189
- /**
190
- * @inheritDoc
191
- */
192
- static get requires() {
193
- return [PendingActions];
194
- }
195
- /**
196
- * @inheritDoc
197
- */
198
- constructor(editor) {
199
- super(editor);
200
- this.set('isSourceEditingMode', false);
201
- this._elementReplacer = new ElementReplacer();
202
- this._replacedRoots = new Map();
203
- this._dataFromRoots = new Map();
204
- editor.config.define('sourceEditing.allowCollaborationFeatures', false);
205
- }
206
- /**
207
- * @inheritDoc
208
- */
209
- init() {
210
- this._checkCompatibility();
211
- const editor = this.editor;
212
- const t = editor.t;
213
- editor.ui.componentFactory.add('sourceEditing', locale => {
214
- const buttonView = new ButtonView(locale);
215
- buttonView.set({
216
- label: t('Source'),
217
- icon: sourceEditingIcon,
218
- tooltip: true,
219
- withText: true,
220
- class: 'ck-source-editing-button'
221
- });
222
- buttonView.bind('isOn').to(this, 'isSourceEditingMode');
223
- // The button should be disabled if one of the following conditions is met:
224
- buttonView.bind('isEnabled').to(this, 'isEnabled', editor, 'isReadOnly', editor.plugins.get(PendingActions), 'hasAny', (isEnabled, isEditorReadOnly, hasAnyPendingActions) => {
225
- // (1) The plugin itself is disabled.
226
- if (!isEnabled) {
227
- return false;
228
- }
229
- // (2) The editor is in read-only mode.
230
- if (isEditorReadOnly) {
231
- return false;
232
- }
233
- // (3) Any pending action is scheduled. It may change the model, so modifying the document source should be prevented
234
- // until the model is finally set.
235
- if (hasAnyPendingActions) {
236
- return false;
237
- }
238
- return true;
239
- });
240
- this.listenTo(buttonView, 'execute', () => {
241
- this.isSourceEditingMode = !this.isSourceEditingMode;
242
- });
243
- return buttonView;
244
- });
245
- // Currently, the plugin handles the source editing mode by itself only for the classic editor. To use this plugin with other
246
- // integrations, listen to the `change:isSourceEditingMode` event and act accordingly.
247
- if (this._isAllowedToHandleSourceEditingMode()) {
248
- this.on('change:isSourceEditingMode', (evt, name, isSourceEditingMode) => {
249
- if (isSourceEditingMode) {
250
- this._hideVisibleDialog();
251
- this._showSourceEditing();
252
- this._disableCommands();
253
- }
254
- else {
255
- this._hideSourceEditing();
256
- this._enableCommands();
257
- }
258
- });
259
- this.on('change:isEnabled', (evt, name, isEnabled) => this._handleReadOnlyMode(!isEnabled));
260
- this.listenTo(editor, 'change:isReadOnly', (evt, name, isReadOnly) => this._handleReadOnlyMode(isReadOnly));
261
- }
262
- // Update the editor data while calling editor.getData() in the source editing mode.
263
- editor.data.on('get', () => {
264
- if (this.isSourceEditingMode) {
265
- this.updateEditorData();
266
- }
267
- }, { priority: 'high' });
268
- }
269
- /**
270
- * Updates the source data in all hidden editing roots.
271
- */
272
- updateEditorData() {
273
- const editor = this.editor;
274
- const data = {};
275
- for (const [rootName, domSourceEditingElementWrapper] of this._replacedRoots) {
276
- const oldData = this._dataFromRoots.get(rootName);
277
- const newData = domSourceEditingElementWrapper.dataset.value;
278
- // Do not set the data unless some changes have been made in the meantime.
279
- // This prevents empty undo steps after switching to the normal editor.
280
- if (oldData !== newData) {
281
- data[rootName] = newData;
282
- this._dataFromRoots.set(rootName, newData);
283
- }
284
- }
285
- if (Object.keys(data).length) {
286
- editor.data.set(data, { batchType: { isUndoable: true }, suppressErrorInCollaboration: true });
287
- }
288
- }
289
- _checkCompatibility() {
290
- const editor = this.editor;
291
- const allowCollaboration = editor.config.get('sourceEditing.allowCollaborationFeatures');
292
- if (!allowCollaboration && editor.plugins.has('RealTimeCollaborativeEditing')) {
293
- /**
294
- * Source editing feature is not fully compatible with real-time collaboration,
295
- * and using it may lead to data loss. Please read
296
- * {@glink features/source-editing#limitations-and-incompatibilities source editing feature guide} to learn more.
297
- *
298
- * If you understand the possible risk of data loss, you can enable the source editing
299
- * by setting the
300
- * {@link module:source-editing/sourceeditingconfig~SourceEditingConfig#allowCollaborationFeatures}
301
- * configuration flag to `true`.
302
- *
303
- * @error source-editing-incompatible-with-real-time-collaboration
304
- */
305
- throw new CKEditorError('source-editing-incompatible-with-real-time-collaboration', null);
306
- }
307
- const collaborationPluginNamesToWarn = [
308
- 'CommentsEditing',
309
- 'TrackChangesEditing',
310
- 'RevisionHistory'
311
- ];
312
- // Currently, the basic integration with Collaboration Features is to display a warning in the console.
313
- //
314
- // If `allowCollaboration` flag is set, do not show these warnings. If the flag is set, we assume that the integrator read
315
- // appropriate section of the guide so there's no use to spam the console with warnings.
316
- //
317
- if (!allowCollaboration && collaborationPluginNamesToWarn.some(pluginName => editor.plugins.has(pluginName))) {
318
- console.warn('You initialized the editor with the source editing feature and at least one of the collaboration features. ' +
319
- 'Please be advised that the source editing feature may not work, and be careful when editing document source ' +
320
- 'that contains markers created by the collaboration features.');
321
- }
322
- // Restricted Editing integration can also lead to problems. Warn the user accordingly.
323
- if (editor.plugins.has('RestrictedEditingModeEditing')) {
324
- console.warn('You initialized the editor with the source editing feature and restricted editing feature. ' +
325
- 'Please be advised that the source editing feature may not work, and be careful when editing document source ' +
326
- 'that contains markers created by the restricted editing feature.');
327
- }
328
- }
329
- /**
330
- * Creates source editing wrappers that replace each editing root. Each wrapper contains the document source from the corresponding
331
- * root.
332
- *
333
- * The wrapper element contains a textarea and it solves the problem, that the textarea element cannot auto expand its height based on
334
- * the content it contains. The solution is to make the textarea more like a plain div element, which expands in height as much as it
335
- * needs to, in order to display the whole document source without scrolling. The wrapper element is a parent for the textarea and for
336
- * the pseudo-element `::after`, that replicates the look, content, and position of the textarea. The pseudo-element replica is hidden,
337
- * but it is styled to be an identical visual copy of the textarea with the same content. Then, the wrapper is a grid container and both
338
- * of its children (the textarea and the `::after` pseudo-element) are positioned within a CSS grid to occupy the same grid cell. The
339
- * content in the pseudo-element `::after` is set in CSS and it stretches the grid to the appropriate size based on the textarea value.
340
- * Since both children occupy the same grid cell, both have always the same height.
341
- */
342
- _showSourceEditing() {
343
- const editor = this.editor;
344
- const editingView = editor.editing.view;
345
- const model = editor.model;
346
- model.change(writer => {
347
- writer.setSelection(null);
348
- writer.removeSelectionAttribute(model.document.selection.getAttributeKeys());
349
- });
350
- // It is not needed to iterate through all editing roots, as currently the plugin supports only the Classic Editor with a single
351
- // main root, but this code may help understand and use this feature in external integrations.
352
- for (const [rootName, domRootElement] of editingView.domRoots) {
353
- const data = formatSource(editor.data.get({ rootName }));
354
- const domSourceEditingElementTextarea = createElement(domRootElement.ownerDocument, 'textarea', {
355
- rows: '1',
356
- 'aria-label': 'Source code editing area'
357
- });
358
- const domSourceEditingElementWrapper = createElement(domRootElement.ownerDocument, 'div', {
359
- class: 'ck-source-editing-area',
360
- 'data-value': data
361
- }, [domSourceEditingElementTextarea]);
362
- domSourceEditingElementTextarea.value = data;
363
- // Setting a value to textarea moves the input cursor to the end. We want the selection at the beginning.
364
- domSourceEditingElementTextarea.setSelectionRange(0, 0);
365
- // Bind the textarea's value to the wrapper's `data-value` property. Each change of the textarea's value updates the
366
- // wrapper's `data-value` property.
367
- domSourceEditingElementTextarea.addEventListener('input', () => {
368
- domSourceEditingElementWrapper.dataset.value = domSourceEditingElementTextarea.value;
369
- editor.ui.update();
370
- });
371
- editingView.change(writer => {
372
- const viewRoot = editingView.document.getRoot(rootName);
373
- writer.addClass('ck-hidden', viewRoot);
374
- });
375
- // Register the element so it becomes available for Alt+F10 and Esc navigation.
376
- editor.ui.setEditableElement('sourceEditing:' + rootName, domSourceEditingElementTextarea);
377
- this._replacedRoots.set(rootName, domSourceEditingElementWrapper);
378
- this._elementReplacer.replace(domRootElement, domSourceEditingElementWrapper);
379
- this._dataFromRoots.set(rootName, data);
380
- }
381
- this._focusSourceEditing();
382
- }
383
- /**
384
- * Restores all hidden editing roots and sets the source data in them.
385
- */
386
- _hideSourceEditing() {
387
- const editor = this.editor;
388
- const editingView = editor.editing.view;
389
- this.updateEditorData();
390
- editingView.change(writer => {
391
- for (const [rootName] of this._replacedRoots) {
392
- writer.removeClass('ck-hidden', editingView.document.getRoot(rootName));
393
- }
394
- });
395
- this._elementReplacer.restore();
396
- this._replacedRoots.clear();
397
- this._dataFromRoots.clear();
398
- editingView.focus();
399
- }
400
- /**
401
- * Focuses the textarea containing document source from the first editing root.
402
- */
403
- _focusSourceEditing() {
404
- const editor = this.editor;
405
- const [domSourceEditingElementWrapper] = this._replacedRoots.values();
406
- const textarea = domSourceEditingElementWrapper.querySelector('textarea');
407
- // The FocusObserver was disabled by View.render() while the DOM root was getting hidden and the replacer
408
- // revealed the textarea. So it couldn't notice that the DOM root got blurred in the process.
409
- // Let's sync this state manually here because otherwise Renderer will attempt to render selection
410
- // in an invisible DOM root.
411
- editor.editing.view.document.isFocused = false;
412
- textarea.focus();
413
- }
414
- /**
415
- * Disables all commands.
416
- */
417
- _disableCommands() {
418
- const editor = this.editor;
419
- for (const command of editor.commands.commands()) {
420
- command.forceDisabled(COMMAND_FORCE_DISABLE_ID);
421
- }
422
- }
423
- /**
424
- * Clears forced disable for all commands, that was previously set through {@link #_disableCommands}.
425
- */
426
- _enableCommands() {
427
- const editor = this.editor;
428
- for (const command of editor.commands.commands()) {
429
- command.clearForceDisabled(COMMAND_FORCE_DISABLE_ID);
430
- }
431
- }
432
- /**
433
- * Adds or removes the `readonly` attribute from the textarea from all roots, if document source mode is active.
434
- *
435
- * @param isReadOnly Indicates whether all textarea elements should be read-only.
436
- */
437
- _handleReadOnlyMode(isReadOnly) {
438
- if (!this.isSourceEditingMode) {
439
- return;
440
- }
441
- for (const [, domSourceEditingElementWrapper] of this._replacedRoots) {
442
- domSourceEditingElementWrapper.querySelector('textarea').readOnly = isReadOnly;
443
- }
444
- }
445
- /**
446
- * Checks, if the plugin is allowed to handle the source editing mode by itself. Currently, the source editing mode is supported only
447
- * for the {@link module:editor-classic/classiceditor~ClassicEditor classic editor}.
448
- */
449
- _isAllowedToHandleSourceEditingMode() {
450
- const editor = this.editor;
451
- const editable = editor.ui.view.editable;
452
- // Checks, if the editor's editable belongs to the editor's DOM tree.
453
- return editable && !editable.hasExternalElement;
454
- }
455
- /**
456
- * If any {@link module:ui/dialog/dialogview~DialogView editor dialog} is currently visible, hide it.
457
- */
458
- _hideVisibleDialog() {
459
- if (this.editor.plugins.has('Dialog')) {
460
- const dialogPlugin = this.editor.plugins.get('Dialog');
461
- if (dialogPlugin.isOpen) {
462
- dialogPlugin.hide();
463
- }
464
- }
465
- }
466
- }
467
- /**
468
- * Formats the content for a better readability.
469
- *
470
- * For a non-HTML source the unchanged input string is returned.
471
- *
472
- * @param input Input string to check.
473
- */
474
- function formatSource(input) {
475
- if (!isHtml(input)) {
476
- return input;
477
- }
478
- return formatHtml(input);
479
- }
480
- /**
481
- * Checks, if the document source is HTML. It is sufficient to just check the first character from the document data.
482
- *
483
- * @param input Input string to check.
484
- */
485
- function isHtml(input) {
486
- return input.startsWith('<');
487
- }
488
-
489
- export { SourceEditing };
490
- //# sourceMappingURL=index.js.map