@ckeditor/ckeditor5-core 35.2.1 → 35.3.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.
@@ -2,14 +2,11 @@
2
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  import { isFunction } from 'lodash-es';
7
6
  import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
8
-
9
7
  /**
10
8
  * @module core/editor/utils/attachtoform
11
9
  */
12
-
13
10
  /**
14
11
  * Checks if the editor is initialized on a `<textarea>` element that belongs to a form. If yes, it updates the editor's element
15
12
  * content before submitting the form.
@@ -18,50 +15,43 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
18
15
  *
19
16
  * @param {module:core/editor/editor~Editor} editor Editor instance.
20
17
  */
21
- export default function attachToForm( editor ) {
22
- if ( !isFunction( editor.updateSourceElement ) ) {
23
- /**
24
- * The editor passed to `attachToForm()` must implement the
25
- * {@link module:core/editor/utils/elementapimixin~ElementApi} interface.
26
- *
27
- * @error attachtoform-missing-elementapi-interface
28
- */
29
- throw new CKEditorError(
30
- 'attachtoform-missing-elementapi-interface',
31
- editor
32
- );
33
- }
34
-
35
- const sourceElement = editor.sourceElement;
36
-
37
- // Only when replacing a textarea which is inside of a form element.
38
- if ( sourceElement && sourceElement.tagName.toLowerCase() === 'textarea' && sourceElement.form ) {
39
- let originalSubmit;
40
- const form = sourceElement.form;
41
- const onSubmit = () => editor.updateSourceElement();
42
-
43
- // Replace the original form#submit() to call a custom submit function first.
44
- // Check if #submit is a function because the form might have an input named "submit".
45
- if ( isFunction( form.submit ) ) {
46
- originalSubmit = form.submit;
47
-
48
- form.submit = () => {
49
- onSubmit();
50
- originalSubmit.apply( form );
51
- };
52
- }
53
-
54
- // Update the replaced textarea with data before each form#submit event.
55
- form.addEventListener( 'submit', onSubmit );
56
-
57
- // Remove the submit listener and revert the original submit method on
58
- // editor#destroy.
59
- editor.on( 'destroy', () => {
60
- form.removeEventListener( 'submit', onSubmit );
61
-
62
- if ( originalSubmit ) {
63
- form.submit = originalSubmit;
64
- }
65
- } );
66
- }
18
+ export default function attachToForm(editor) {
19
+ if (!isFunction(editor.updateSourceElement)) {
20
+ /**
21
+ * The editor passed to `attachToForm()` must implement the
22
+ * {@link module:core/editor/utils/elementapimixin~ElementApi} interface.
23
+ *
24
+ * @error attachtoform-missing-elementapi-interface
25
+ */
26
+ throw new CKEditorError('attachtoform-missing-elementapi-interface', editor);
27
+ }
28
+ const sourceElement = editor.sourceElement;
29
+ // Only when replacing a textarea which is inside of a form element.
30
+ if (isTextArea(sourceElement) && sourceElement.form) {
31
+ let originalSubmit;
32
+ const form = sourceElement.form;
33
+ const onSubmit = () => editor.updateSourceElement();
34
+ // Replace the original form#submit() to call a custom submit function first.
35
+ // Check if #submit is a function because the form might have an input named "submit".
36
+ if (isFunction(form.submit)) {
37
+ originalSubmit = form.submit;
38
+ form.submit = () => {
39
+ onSubmit();
40
+ originalSubmit.apply(form);
41
+ };
42
+ }
43
+ // Update the replaced textarea with data before each form#submit event.
44
+ form.addEventListener('submit', onSubmit);
45
+ // Remove the submit listener and revert the original submit method on
46
+ // editor#destroy.
47
+ editor.on('destroy', () => {
48
+ form.removeEventListener('submit', onSubmit);
49
+ if (originalSubmit) {
50
+ form.submit = originalSubmit;
51
+ }
52
+ });
53
+ }
54
+ }
55
+ function isTextArea(sourceElement) {
56
+ return !!sourceElement && sourceElement.tagName.toLowerCase() === 'textarea';
67
57
  }
@@ -2,80 +2,29 @@
2
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  /**
7
6
  * @module core/editor/utils/dataapimixin
8
7
  */
9
-
10
8
  /**
11
9
  * Implementation of the {@link module:core/editor/utils/dataapimixin~DataApi}.
12
10
  *
13
11
  * @mixin DataApiMixin
14
12
  * @implements module:core/editor/utils/dataapimixin~DataApi
15
13
  */
16
- const DataApiMixin = {
17
- /**
18
- * @inheritDoc
19
- */
20
- setData( data ) {
21
- this.data.set( data );
22
- },
23
-
24
- /**
25
- * @inheritDoc
26
- */
27
- getData( options ) {
28
- return this.data.get( options );
29
- }
30
- };
31
-
32
- export default DataApiMixin;
33
-
34
- /**
35
- * Interface defining editor methods for setting and getting data to and from the editor's main root element
36
- * using the {@link module:core/editor/editor~Editor#data data pipeline}.
37
- *
38
- * This interface is not a part of the {@link module:core/editor/editor~Editor} class because one may want to implement
39
- * an editor with multiple root elements, in which case the methods for setting and getting data will need to be implemented
40
- * differently.
41
- *
42
- * @interface DataApi
43
- */
44
-
45
- /**
46
- * Sets the data in the editor.
47
- *
48
- * editor.setData( '<p>This is editor!</p>' );
49
- *
50
- * By default the editor accepts HTML. This can be controlled by injecting a different data processor.
51
- * See the {@glink features/markdown Markdown output} guide for more details.
52
- *
53
- * Note: Not only is the format of the data configurable, but the type of the `setData()`'s parameter does not
54
- * have to be a string either. You can e.g. accept an object or a DOM `DocumentFragment` if you consider this
55
- * the right format for you.
56
- *
57
- * @method #setData
58
- * @param {String} data Input data.
59
- */
60
-
61
- /**
62
- * Gets the data from the editor.
63
- *
64
- * editor.getData(); // -> '<p>This is editor!</p>'
65
- *
66
- * By default the editor outputs HTML. This can be controlled by injecting a different data processor.
67
- * See the {@glink features/markdown Markdown output} guide for more details.
68
- *
69
- * Note: Not only is the format of the data configurable, but the type of the `getData()`'s return value does not
70
- * have to be a string either. You can e.g. return an object or a DOM `DocumentFragment` if you consider this
71
- * the right format for you.
72
- *
73
- * @method #getData
74
- * @param {Object} [options] Additional configuration for the retrieved data.
75
- * Editor features may introduce more configuration options that can be set through this parameter.
76
- * @param {String} [options.rootName='main'] Root name.
77
- * @param {String} [options.trim='empty'] Whether returned data should be trimmed. This option is set to `'empty'` by default,
78
- * which means that whenever editor content is considered empty, an empty string is returned. To turn off trimming
79
- * use `'none'`. In such cases exact content will be returned (for example `'<p>&nbsp;</p>'` for an empty editor).
80
- * @returns {String} Output data.
81
- */
14
+ export default function DataApiMixin(base) {
15
+ class Mixin extends base {
16
+ setData(data) {
17
+ this.data.set(data);
18
+ }
19
+ getData(options) {
20
+ return this.data.get(options);
21
+ }
22
+ }
23
+ return Mixin;
24
+ }
25
+ // Backward compatibility with `mix`.
26
+ {
27
+ const mixin = DataApiMixin(Object);
28
+ DataApiMixin.setData = mixin.prototype.setData;
29
+ DataApiMixin.getData = mixin.prototype.getData;
30
+ }
@@ -2,81 +2,46 @@
2
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
- /* globals HTMLTextAreaElement */
7
-
5
+ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
8
6
  import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
9
7
  import setDataInElement from '@ckeditor/ckeditor5-utils/src/dom/setdatainelement';
10
-
11
8
  /**
12
9
  * @module core/editor/utils/elementapimixin
13
10
  */
14
-
15
11
  /**
16
12
  * Implementation of the {@link module:core/editor/utils/elementapimixin~ElementApi}.
17
13
  *
18
14
  * @mixin ElementApiMixin
19
15
  * @implements module:core/editor/utils/elementapimixin~ElementApi
20
16
  */
21
- const ElementApiMixin = {
22
- /**
23
- * @inheritDoc
24
- */
25
- updateSourceElement( data = this.data.get() ) {
26
- if ( !this.sourceElement ) {
27
- /**
28
- * Cannot update the source element of a detached editor.
29
- *
30
- * The {@link ~ElementApi#updateSourceElement `updateSourceElement()`} method cannot be called if you did not
31
- * pass an element to `Editor.create()`.
32
- *
33
- * @error editor-missing-sourceelement
34
- */
35
- throw new CKEditorError(
36
- 'editor-missing-sourceelement',
37
- this
38
- );
39
- }
40
-
41
- const shouldUpdateSourceElement = this.config.get( 'updateSourceElementOnDestroy' );
42
- const isSourceElementTextArea = this.sourceElement instanceof HTMLTextAreaElement;
43
-
44
- // The data returned by the editor might be unsafe, so we want to prevent rendering
45
- // unsafe content inside the source element different than <textarea>, which is considered
46
- // secure. This behaviour could be changed by setting the `updateSourceElementOnDestroy`
47
- // configuration option to `true`.
48
- if ( !shouldUpdateSourceElement && !isSourceElementTextArea ) {
49
- setDataInElement( this.sourceElement, '' );
50
-
51
- return;
52
- }
53
-
54
- setDataInElement( this.sourceElement, data );
55
- }
56
- };
57
-
58
- export default ElementApiMixin;
59
-
60
- /**
61
- * Interface describing an editor that replaced a DOM element (was "initialized on an element").
62
- *
63
- * Such an editor should provide a method to
64
- * {@link module:core/editor/utils/elementapimixin~ElementApi#updateSourceElement update the replaced element with the current data}.
65
- *
66
- * @interface ElementApi
67
- */
68
-
69
- /**
70
- * The element on which the editor has been initialized.
71
- *
72
- * @readonly
73
- * @member {HTMLElement} #sourceElement
74
- */
75
-
76
- /**
77
- * Updates the {@link #sourceElement editor source element}'s content with the data.
78
- *
79
- * @method #updateSourceElement
80
- * @param {String} data The data that should be used to update the source element.
81
- * By default, it is taken directly from the existing editor instance.
82
- */
17
+ export default function ElementApiMixin(base) {
18
+ class Mixin extends base {
19
+ updateSourceElement(data = this.data.get()) {
20
+ if (!this.sourceElement) {
21
+ /**
22
+ * Cannot update the source element of a detached editor.
23
+ *
24
+ * The {@link ~ElementApi#updateSourceElement `updateSourceElement()`} method cannot be called if you did not
25
+ * pass an element to `Editor.create()`.
26
+ *
27
+ * @error editor-missing-sourceelement
28
+ */
29
+ throw new CKEditorError('editor-missing-sourceelement', this);
30
+ }
31
+ const shouldUpdateSourceElement = this.config.get('updateSourceElementOnDestroy');
32
+ const isSourceElementTextArea = this.sourceElement instanceof HTMLTextAreaElement;
33
+ // The data returned by the editor might be unsafe, so we want to prevent rendering
34
+ // unsafe content inside the source element different than <textarea>, which is considered
35
+ // secure. This behaviour could be changed by setting the `updateSourceElementOnDestroy`
36
+ // configuration option to `true`.
37
+ if (!shouldUpdateSourceElement && !isSourceElementTextArea) {
38
+ setDataInElement(this.sourceElement, '');
39
+ return;
40
+ }
41
+ setDataInElement(this.sourceElement, data);
42
+ }
43
+ }
44
+ return Mixin;
45
+ }
46
+ // Backward compatibility with `mix`.
47
+ ElementApiMixin.updateSourceElement = ElementApiMixin(Object).prototype.updateSourceElement;
@@ -2,13 +2,10 @@
2
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
7
-
8
6
  /**
9
7
  * @module core/editor/utils/securesourceelement
10
8
  */
11
-
12
9
  /**
13
10
  * Marks the source element on which the editor was initialized. This prevents other editor instances from using this element.
14
11
  *
@@ -17,33 +14,26 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
17
14
  *
18
15
  * @param {module:core/editor/editor~Editor} editor Editor instance.
19
16
  */
20
- export default function secureSourceElement( editor ) {
21
- const sourceElement = editor.sourceElement;
22
-
23
- // If the editor was initialized without specifying an element, we don't need to secure anything.
24
- if ( !sourceElement ) {
25
- return;
26
- }
27
-
28
- if ( sourceElement.ckeditorInstance ) {
29
- /**
30
- * A DOM element used to create the editor (e.g.
31
- * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`})
32
- * has already been used to create another editor instance. Make sure each editor is
33
- * created with an unique DOM element.
34
- *
35
- * @error editor-source-element-already-used
36
- * @param {HTMLElement} element DOM element that caused the collision.
37
- */
38
- throw new CKEditorError(
39
- 'editor-source-element-already-used',
40
- editor
41
- );
42
- }
43
-
44
- sourceElement.ckeditorInstance = editor;
45
-
46
- editor.once( 'destroy', () => {
47
- delete sourceElement.ckeditorInstance;
48
- } );
17
+ export default function secureSourceElement(editor) {
18
+ const sourceElement = editor.sourceElement;
19
+ // If the editor was initialized without specifying an element, we don't need to secure anything.
20
+ if (!sourceElement) {
21
+ return;
22
+ }
23
+ if (sourceElement.ckeditorInstance) {
24
+ /**
25
+ * A DOM element used to create the editor (e.g.
26
+ * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`})
27
+ * has already been used to create another editor instance. Make sure each editor is
28
+ * created with an unique DOM element.
29
+ *
30
+ * @error editor-source-element-already-used
31
+ * @param {HTMLElement} element DOM element that caused the collision.
32
+ */
33
+ throw new CKEditorError('editor-source-element-already-used', editor);
34
+ }
35
+ sourceElement.ckeditorInstance = editor;
36
+ editor.once('destroy', () => {
37
+ delete sourceElement.ckeditorInstance;
38
+ });
49
39
  }
package/src/index.js CHANGED
@@ -2,28 +2,21 @@
2
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  /**
7
6
  * @module core
8
7
  */
9
-
10
8
  export { default as Plugin } from './plugin';
11
9
  export { default as Command } from './command';
12
10
  export { default as MultiCommand } from './multicommand';
13
-
14
11
  export { default as Context } from './context';
15
12
  export { default as ContextPlugin } from './contextplugin';
16
-
17
13
  export { default as Editor } from './editor/editor';
18
14
  export { default as EditorUI } from './editor/editorui';
19
-
20
15
  export { default as attachToForm } from './editor/utils/attachtoform';
21
16
  export { default as DataApiMixin } from './editor/utils/dataapimixin';
22
17
  export { default as ElementApiMixin } from './editor/utils/elementapimixin';
23
18
  export { default as secureSourceElement } from './editor/utils/securesourceelement';
24
-
25
19
  export { default as PendingActions } from './pendingactions';
26
-
27
20
  import cancel from './../theme/icons/cancel.svg';
28
21
  import caption from './../theme/icons/caption.svg';
29
22
  import check from './../theme/icons/check.svg';
@@ -31,7 +24,6 @@ import cog from './../theme/icons/cog.svg';
31
24
  import eraser from './../theme/icons/eraser.svg';
32
25
  import lowVision from './../theme/icons/low-vision.svg';
33
26
  import image from './../theme/icons/image.svg';
34
-
35
27
  import alignBottom from './../theme/icons/align-bottom.svg';
36
28
  import alignMiddle from './../theme/icons/align-middle.svg';
37
29
  import alignTop from './../theme/icons/align-top.svg';
@@ -39,7 +31,6 @@ import alignLeft from './../theme/icons/align-left.svg';
39
31
  import alignCenter from './../theme/icons/align-center.svg';
40
32
  import alignRight from './../theme/icons/align-right.svg';
41
33
  import alignJustify from './../theme/icons/align-justify.svg';
42
-
43
34
  import objectBlockLeft from './../theme/icons/object-left.svg';
44
35
  import objectCenter from './../theme/icons/object-center.svg';
45
36
  import objectBlockRight from './../theme/icons/object-right.svg';
@@ -47,60 +38,52 @@ import objectFullWidth from './../theme/icons/object-full-width.svg';
47
38
  import objectInline from './../theme/icons/object-inline.svg';
48
39
  import objectLeft from './../theme/icons/object-inline-left.svg';
49
40
  import objectRight from './../theme/icons/object-inline-right.svg';
50
-
51
41
  import objectSizeFull from './../theme/icons/object-size-full.svg';
52
42
  import objectSizeLarge from './../theme/icons/object-size-large.svg';
53
43
  import objectSizeSmall from './../theme/icons/object-size-small.svg';
54
44
  import objectSizeMedium from './../theme/icons/object-size-medium.svg';
55
-
56
45
  import pencil from './../theme/icons/pencil.svg';
57
46
  import pilcrow from './../theme/icons/pilcrow.svg';
58
47
  import quote from './../theme/icons/quote.svg';
59
48
  import threeVerticalDots from './../theme/icons/three-vertical-dots.svg';
60
-
61
49
  import bold from './../theme/icons/bold.svg';
62
50
  import paragraph from './../theme/icons/paragraph.svg';
63
51
  import plus from './../theme/icons/plus.svg';
64
52
  import text from './../theme/icons/text.svg';
65
53
  import importExport from './../theme/icons/importexport.svg';
66
-
67
54
  export const icons = {
68
- bold,
69
- cancel,
70
- caption,
71
- check,
72
- cog,
73
- eraser,
74
- image,
75
- lowVision,
76
- importExport,
77
- paragraph,
78
- plus,
79
- text,
80
-
81
- alignBottom,
82
- alignMiddle,
83
- alignTop,
84
- alignLeft,
85
- alignCenter,
86
- alignRight,
87
- alignJustify,
88
-
89
- objectLeft,
90
- objectCenter,
91
- objectRight,
92
- objectFullWidth,
93
- objectInline,
94
- objectBlockLeft,
95
- objectBlockRight,
96
-
97
- objectSizeFull,
98
- objectSizeLarge,
99
- objectSizeSmall,
100
- objectSizeMedium,
101
-
102
- pencil,
103
- pilcrow,
104
- quote,
105
- threeVerticalDots
55
+ bold,
56
+ cancel,
57
+ caption,
58
+ check,
59
+ cog,
60
+ eraser,
61
+ image,
62
+ lowVision,
63
+ importExport,
64
+ paragraph,
65
+ plus,
66
+ text,
67
+ alignBottom,
68
+ alignMiddle,
69
+ alignTop,
70
+ alignLeft,
71
+ alignCenter,
72
+ alignRight,
73
+ alignJustify,
74
+ objectLeft,
75
+ objectCenter,
76
+ objectRight,
77
+ objectFullWidth,
78
+ objectInline,
79
+ objectBlockLeft,
80
+ objectBlockRight,
81
+ objectSizeFull,
82
+ objectSizeLarge,
83
+ objectSizeSmall,
84
+ objectSizeMedium,
85
+ pencil,
86
+ pilcrow,
87
+ quote,
88
+ threeVerticalDots
106
89
  };