@ckeditor/ckeditor5-core 30.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.md +17 -0
- package/README.md +18 -0
- package/lang/contexts.json +8 -0
- package/lang/translations/af.po +41 -0
- package/lang/translations/ar.po +41 -0
- package/lang/translations/ast.po +41 -0
- package/lang/translations/az.po +41 -0
- package/lang/translations/bg.po +41 -0
- package/lang/translations/ca.po +41 -0
- package/lang/translations/cs.po +41 -0
- package/lang/translations/da.po +41 -0
- package/lang/translations/de-ch.po +41 -0
- package/lang/translations/de.po +41 -0
- package/lang/translations/el.po +41 -0
- package/lang/translations/en-au.po +41 -0
- package/lang/translations/en-gb.po +41 -0
- package/lang/translations/en.po +41 -0
- package/lang/translations/eo.po +41 -0
- package/lang/translations/es.po +41 -0
- package/lang/translations/et.po +41 -0
- package/lang/translations/eu.po +41 -0
- package/lang/translations/fa.po +41 -0
- package/lang/translations/fi.po +41 -0
- package/lang/translations/fr.po +41 -0
- package/lang/translations/gl.po +41 -0
- package/lang/translations/he.po +41 -0
- package/lang/translations/hi.po +41 -0
- package/lang/translations/hr.po +41 -0
- package/lang/translations/hu.po +41 -0
- package/lang/translations/id.po +41 -0
- package/lang/translations/it.po +41 -0
- package/lang/translations/ja.po +41 -0
- package/lang/translations/km.po +41 -0
- package/lang/translations/kn.po +41 -0
- package/lang/translations/ko.po +41 -0
- package/lang/translations/ku.po +41 -0
- package/lang/translations/lt.po +41 -0
- package/lang/translations/lv.po +41 -0
- package/lang/translations/nb.po +41 -0
- package/lang/translations/ne.po +41 -0
- package/lang/translations/nl.po +41 -0
- package/lang/translations/no.po +41 -0
- package/lang/translations/oc.po +41 -0
- package/lang/translations/pl.po +41 -0
- package/lang/translations/pt-br.po +41 -0
- package/lang/translations/pt.po +41 -0
- package/lang/translations/ro.po +41 -0
- package/lang/translations/ru.po +41 -0
- package/lang/translations/sk.po +41 -0
- package/lang/translations/sl.po +41 -0
- package/lang/translations/sq.po +41 -0
- package/lang/translations/sr-latn.po +41 -0
- package/lang/translations/sr.po +41 -0
- package/lang/translations/sv.po +41 -0
- package/lang/translations/th.po +41 -0
- package/lang/translations/tk.po +41 -0
- package/lang/translations/tr.po +41 -0
- package/lang/translations/tt.po +41 -0
- package/lang/translations/ug.po +41 -0
- package/lang/translations/uk.po +41 -0
- package/lang/translations/vi.po +41 -0
- package/lang/translations/zh-cn.po +41 -0
- package/lang/translations/zh.po +41 -0
- package/package.json +65 -0
- package/src/command.js +244 -0
- package/src/commandcollection.js +109 -0
- package/src/context.js +355 -0
- package/src/contextplugin.js +61 -0
- package/src/editingkeystrokehandler.js +72 -0
- package/src/editor/editor.js +448 -0
- package/src/editor/editorconfig.jsdoc +325 -0
- package/src/editor/editorui.js +275 -0
- package/src/editor/editorwithui.jsdoc +29 -0
- package/src/editor/utils/attachtoform.js +67 -0
- package/src/editor/utils/dataapimixin.js +81 -0
- package/src/editor/utils/elementapimixin.js +65 -0
- package/src/editor/utils/securesourceelement.js +49 -0
- package/src/index.js +95 -0
- package/src/multicommand.js +101 -0
- package/src/pendingactions.js +155 -0
- package/src/plugin.js +292 -0
- package/src/plugincollection.js +597 -0
- package/theme/icons/align-bottom.svg +1 -0
- package/theme/icons/align-center.svg +1 -0
- package/theme/icons/align-justify.svg +1 -0
- package/theme/icons/align-left.svg +1 -0
- package/theme/icons/align-middle.svg +1 -0
- package/theme/icons/align-right.svg +1 -0
- package/theme/icons/align-top.svg +1 -0
- package/theme/icons/cancel.svg +1 -0
- package/theme/icons/caption.svg +1 -0
- package/theme/icons/check.svg +1 -0
- package/theme/icons/cog.svg +1 -0
- package/theme/icons/eraser.svg +1 -0
- package/theme/icons/image.svg +1 -0
- package/theme/icons/low-vision.svg +1 -0
- package/theme/icons/object-center.svg +1 -0
- package/theme/icons/object-full-width.svg +1 -0
- package/theme/icons/object-inline-left.svg +1 -0
- package/theme/icons/object-inline-right.svg +1 -0
- package/theme/icons/object-inline.svg +1 -0
- package/theme/icons/object-left.svg +1 -0
- package/theme/icons/object-right.svg +1 -0
- package/theme/icons/object-size-full.svg +1 -0
- package/theme/icons/object-size-large.svg +1 -0
- package/theme/icons/object-size-medium.svg +1 -0
- package/theme/icons/object-size-small.svg +1 -0
- package/theme/icons/pencil.svg +1 -0
- package/theme/icons/pilcrow.svg +1 -0
- package/theme/icons/quote.svg +1 -0
- package/theme/icons/three-vertical-dots.svg +1 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module core/editor/utils/dataapimixin
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Implementation of the {@link module:core/editor/utils/dataapimixin~DataApi}.
|
|
12
|
+
*
|
|
13
|
+
* @mixin DataApiMixin
|
|
14
|
+
* @implements module:core/editor/utils/dataapimixin~DataApi
|
|
15
|
+
*/
|
|
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> </p>'` for an empty editor).
|
|
80
|
+
* @returns {String} Output data.
|
|
81
|
+
*/
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
7
|
+
import setDataInElement from '@ckeditor/ckeditor5-utils/src/dom/setdatainelement';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @module core/editor/utils/elementapimixin
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Implementation of the {@link module:core/editor/utils/elementapimixin~ElementApi}.
|
|
15
|
+
*
|
|
16
|
+
* @mixin ElementApiMixin
|
|
17
|
+
* @implements module:core/editor/utils/elementapimixin~ElementApi
|
|
18
|
+
*/
|
|
19
|
+
const ElementApiMixin = {
|
|
20
|
+
/**
|
|
21
|
+
* @inheritDoc
|
|
22
|
+
*/
|
|
23
|
+
updateSourceElement() {
|
|
24
|
+
if ( !this.sourceElement ) {
|
|
25
|
+
/**
|
|
26
|
+
* Cannot update the source element of a detached editor.
|
|
27
|
+
*
|
|
28
|
+
* The {@link ~ElementApi#updateSourceElement `updateSourceElement()`} method cannot be called if you did not
|
|
29
|
+
* pass an element to `Editor.create()`.
|
|
30
|
+
*
|
|
31
|
+
* @error editor-missing-sourceelement
|
|
32
|
+
*/
|
|
33
|
+
throw new CKEditorError(
|
|
34
|
+
'editor-missing-sourceelement',
|
|
35
|
+
this
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
setDataInElement( this.sourceElement, this.data.get() );
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export default ElementApiMixin;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Interface describing an editor that replaced a DOM element (was "initialized on an element").
|
|
47
|
+
*
|
|
48
|
+
* Such an editor should provide a method to
|
|
49
|
+
* {@link module:core/editor/utils/elementapimixin~ElementApi#updateSourceElement update the replaced element with the current data}.
|
|
50
|
+
*
|
|
51
|
+
* @interface ElementApi
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The element on which the editor has been initialized.
|
|
56
|
+
*
|
|
57
|
+
* @readonly
|
|
58
|
+
* @member {HTMLElement} #sourceElement
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Updates the {@link #sourceElement editor source element}'s content with the data.
|
|
63
|
+
*
|
|
64
|
+
* @method #updateSourceElement
|
|
65
|
+
*/
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @module core/editor/utils/securesourceelement
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Marks the source element on which the editor was initialized. This prevents other editor instances from using this element.
|
|
14
|
+
*
|
|
15
|
+
* Running multiple editor instances on the same source element causes various issues and it is
|
|
16
|
+
* crucial this helper is called as soon as the source element is known to prevent collisions.
|
|
17
|
+
*
|
|
18
|
+
* @param {module:core/editor/editor~Editor} editor Editor instance.
|
|
19
|
+
*/
|
|
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
|
+
} );
|
|
49
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module core
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { default as Plugin } from './plugin';
|
|
11
|
+
export { default as Command } from './command';
|
|
12
|
+
export { default as MultiCommand } from './multicommand';
|
|
13
|
+
|
|
14
|
+
export { default as Context } from './context';
|
|
15
|
+
export { default as ContextPlugin } from './contextplugin';
|
|
16
|
+
|
|
17
|
+
export { default as Editor } from './editor/editor';
|
|
18
|
+
export { default as EditorUI } from './editor/editorui';
|
|
19
|
+
|
|
20
|
+
export { default as attachToForm } from './editor/utils/attachtoform';
|
|
21
|
+
export { default as DataApiMixin } from './editor/utils/dataapimixin';
|
|
22
|
+
export { default as ElementApiMixin } from './editor/utils/elementapimixin';
|
|
23
|
+
export { default as secureSourceElement } from './editor/utils/securesourceelement';
|
|
24
|
+
|
|
25
|
+
export { default as PendingActions } from './pendingactions';
|
|
26
|
+
|
|
27
|
+
import cancel from './../theme/icons/cancel.svg';
|
|
28
|
+
import caption from './../theme/icons/caption.svg';
|
|
29
|
+
import check from './../theme/icons/check.svg';
|
|
30
|
+
import cog from './../theme/icons/cog.svg';
|
|
31
|
+
import eraser from './../theme/icons/eraser.svg';
|
|
32
|
+
import lowVision from './../theme/icons/low-vision.svg';
|
|
33
|
+
import image from './../theme/icons/image.svg';
|
|
34
|
+
|
|
35
|
+
import alignBottom from './../theme/icons/align-bottom.svg';
|
|
36
|
+
import alignMiddle from './../theme/icons/align-middle.svg';
|
|
37
|
+
import alignTop from './../theme/icons/align-top.svg';
|
|
38
|
+
import alignLeft from './../theme/icons/align-left.svg';
|
|
39
|
+
import alignCenter from './../theme/icons/align-center.svg';
|
|
40
|
+
import alignRight from './../theme/icons/align-right.svg';
|
|
41
|
+
import alignJustify from './../theme/icons/align-justify.svg';
|
|
42
|
+
|
|
43
|
+
import objectBlockLeft from './../theme/icons/object-left.svg';
|
|
44
|
+
import objectCenter from './../theme/icons/object-center.svg';
|
|
45
|
+
import objectBlockRight from './../theme/icons/object-right.svg';
|
|
46
|
+
import objectFullWidth from './../theme/icons/object-full-width.svg';
|
|
47
|
+
import objectInline from './../theme/icons/object-inline.svg';
|
|
48
|
+
import objectLeft from './../theme/icons/object-inline-left.svg';
|
|
49
|
+
import objectRight from './../theme/icons/object-inline-right.svg';
|
|
50
|
+
|
|
51
|
+
import objectSizeFull from './../theme/icons/object-size-full.svg';
|
|
52
|
+
import objectSizeLarge from './../theme/icons/object-size-large.svg';
|
|
53
|
+
import objectSizeSmall from './../theme/icons/object-size-small.svg';
|
|
54
|
+
import objectSizeMedium from './../theme/icons/object-size-medium.svg';
|
|
55
|
+
|
|
56
|
+
import pencil from './../theme/icons/pencil.svg';
|
|
57
|
+
import pilcrow from './../theme/icons/pilcrow.svg';
|
|
58
|
+
import quote from './../theme/icons/quote.svg';
|
|
59
|
+
import threeVerticalDots from './../theme/icons/three-vertical-dots.svg';
|
|
60
|
+
|
|
61
|
+
export const icons = {
|
|
62
|
+
cancel,
|
|
63
|
+
caption,
|
|
64
|
+
check,
|
|
65
|
+
cog,
|
|
66
|
+
eraser,
|
|
67
|
+
lowVision,
|
|
68
|
+
image,
|
|
69
|
+
|
|
70
|
+
alignBottom,
|
|
71
|
+
alignMiddle,
|
|
72
|
+
alignTop,
|
|
73
|
+
alignLeft,
|
|
74
|
+
alignCenter,
|
|
75
|
+
alignRight,
|
|
76
|
+
alignJustify,
|
|
77
|
+
|
|
78
|
+
objectLeft,
|
|
79
|
+
objectCenter,
|
|
80
|
+
objectRight,
|
|
81
|
+
objectFullWidth,
|
|
82
|
+
objectInline,
|
|
83
|
+
objectBlockLeft,
|
|
84
|
+
objectBlockRight,
|
|
85
|
+
|
|
86
|
+
objectSizeFull,
|
|
87
|
+
objectSizeLarge,
|
|
88
|
+
objectSizeSmall,
|
|
89
|
+
objectSizeMedium,
|
|
90
|
+
|
|
91
|
+
pencil,
|
|
92
|
+
pilcrow,
|
|
93
|
+
quote,
|
|
94
|
+
threeVerticalDots
|
|
95
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import Command from './command';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @module core/multicommand
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A CKEditor command that aggregates other commands.
|
|
14
|
+
*
|
|
15
|
+
* This command is used to proxy multiple commands. The multi-command is enabled when
|
|
16
|
+
* at least one of its registered child commands is enabled.
|
|
17
|
+
* When executing a multi-command the first command that is enabled will be executed.
|
|
18
|
+
*
|
|
19
|
+
* const multiCommand = new MultiCommand( editor );
|
|
20
|
+
*
|
|
21
|
+
* const commandFoo = new Command( editor );
|
|
22
|
+
* const commandBar = new Command( editor );
|
|
23
|
+
*
|
|
24
|
+
* // Register child commands.
|
|
25
|
+
* multiCommand.registerChildCommand( commandFoo );
|
|
26
|
+
* multiCommand.registerChildCommand( commandBar );
|
|
27
|
+
*
|
|
28
|
+
* // Enable one of the commands.
|
|
29
|
+
* commandBar.isEnabled = true;
|
|
30
|
+
*
|
|
31
|
+
* multiCommand.execute(); // Will execute commandBar.
|
|
32
|
+
*
|
|
33
|
+
* @extends module:core/command~Command
|
|
34
|
+
*/
|
|
35
|
+
export default class MultiCommand extends Command {
|
|
36
|
+
/**
|
|
37
|
+
* @inheritDoc
|
|
38
|
+
*/
|
|
39
|
+
constructor( editor ) {
|
|
40
|
+
super( editor );
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Registered child commands.
|
|
44
|
+
*
|
|
45
|
+
* @type {Array.<module:core/command~Command>}
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
this._childCommands = [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @inheritDoc
|
|
53
|
+
*/
|
|
54
|
+
refresh() {
|
|
55
|
+
// Override base command refresh(): the command's state is changed when one of child commands changes states.
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Executes the first of it registered child commands.
|
|
60
|
+
*
|
|
61
|
+
* @returns {*} The value returned by the {@link module:core/command~Command#execute `command.execute()`}.
|
|
62
|
+
*/
|
|
63
|
+
execute( ...args ) {
|
|
64
|
+
const command = this._getFirstEnabledCommand();
|
|
65
|
+
|
|
66
|
+
return command != null && command.execute( args );
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Registers a child command.
|
|
71
|
+
*
|
|
72
|
+
* @param {module:core/command~Command} command
|
|
73
|
+
*/
|
|
74
|
+
registerChildCommand( command ) {
|
|
75
|
+
this._childCommands.push( command );
|
|
76
|
+
|
|
77
|
+
// Change multi command enabled state when one of registered commands changes state.
|
|
78
|
+
command.on( 'change:isEnabled', () => this._checkEnabled() );
|
|
79
|
+
|
|
80
|
+
this._checkEnabled();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Checks if any of child commands is enabled.
|
|
85
|
+
*
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
_checkEnabled() {
|
|
89
|
+
this.isEnabled = !!this._getFirstEnabledCommand();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Returns a first enabled command or undefined if none of them is enabled.
|
|
94
|
+
*
|
|
95
|
+
* @returns {module:core/command~Command|undefined}
|
|
96
|
+
* @private
|
|
97
|
+
*/
|
|
98
|
+
_getFirstEnabledCommand() {
|
|
99
|
+
return this._childCommands.find( command => command.isEnabled );
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module core/pendingactions
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import ContextPlugin from './contextplugin';
|
|
11
|
+
import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
|
|
12
|
+
import Collection from '@ckeditor/ckeditor5-utils/src/collection';
|
|
13
|
+
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The list of pending editor actions.
|
|
17
|
+
*
|
|
18
|
+
* This plugin should be used to synchronise plugins that execute long-lasting actions
|
|
19
|
+
* (e.g. file upload) with the editor integration. It gives the developer who integrates the editor
|
|
20
|
+
* an easy way to check if there are any actions pending whenever such information is needed.
|
|
21
|
+
* All plugins that register a pending action also provide a message about the action that is ongoing
|
|
22
|
+
* which can be displayed to the user. This lets them decide if they want to interrupt the action or wait.
|
|
23
|
+
*
|
|
24
|
+
* Adding and updating a pending action:
|
|
25
|
+
*
|
|
26
|
+
* const pendingActions = editor.plugins.get( 'PendingActions' );
|
|
27
|
+
* const action = pendingActions.add( 'Upload in progress: 0%.' );
|
|
28
|
+
*
|
|
29
|
+
* // You can update the message:
|
|
30
|
+
* action.message = 'Upload in progress: 10%.';
|
|
31
|
+
*
|
|
32
|
+
* Removing a pending action:
|
|
33
|
+
*
|
|
34
|
+
* const pendingActions = editor.plugins.get( 'PendingActions' );
|
|
35
|
+
* const action = pendingActions.add( 'Unsaved changes.' );
|
|
36
|
+
*
|
|
37
|
+
* pendingActions.remove( action );
|
|
38
|
+
*
|
|
39
|
+
* Getting pending actions:
|
|
40
|
+
*
|
|
41
|
+
* const pendingActions = editor.plugins.get( 'PendingActions' );
|
|
42
|
+
*
|
|
43
|
+
* const action1 = pendingActions.add( 'Action 1' );
|
|
44
|
+
* const action2 = pendingActions.add( 'Action 2' );
|
|
45
|
+
*
|
|
46
|
+
* pendingActions.first; // Returns action1
|
|
47
|
+
* Array.from( pendingActions ); // Returns [ action1, action2 ]
|
|
48
|
+
*
|
|
49
|
+
* This plugin is used by features like {@link module:upload/filerepository~FileRepository} to register their ongoing actions
|
|
50
|
+
* and by features like {@link module:autosave/autosave~Autosave} to detect whether there are any ongoing actions.
|
|
51
|
+
* Read more about saving the data in the {@glink builds/guides/integration/saving-data Saving and getting data} guide.
|
|
52
|
+
*
|
|
53
|
+
* @extends module:core/contextplugin~ContextPlugin
|
|
54
|
+
*/
|
|
55
|
+
export default class PendingActions extends ContextPlugin {
|
|
56
|
+
/**
|
|
57
|
+
* @inheritDoc
|
|
58
|
+
*/
|
|
59
|
+
static get pluginName() {
|
|
60
|
+
return 'PendingActions';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @inheritDoc
|
|
65
|
+
*/
|
|
66
|
+
init() {
|
|
67
|
+
/**
|
|
68
|
+
* Defines whether there is any registered pending action.
|
|
69
|
+
*
|
|
70
|
+
* @readonly
|
|
71
|
+
* @observable
|
|
72
|
+
* @member {Boolean} #hasAny
|
|
73
|
+
*/
|
|
74
|
+
this.set( 'hasAny', false );
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A list of pending actions.
|
|
78
|
+
*
|
|
79
|
+
* @private
|
|
80
|
+
* @type {module:utils/collection~Collection}
|
|
81
|
+
*/
|
|
82
|
+
this._actions = new Collection( { idProperty: '_id' } );
|
|
83
|
+
this._actions.delegate( 'add', 'remove' ).to( this );
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Adds an action to the list of pending actions.
|
|
88
|
+
*
|
|
89
|
+
* This method returns an action object with an observable message property.
|
|
90
|
+
* The action object can be later used in the {@link #remove} method. It also allows you to change the message.
|
|
91
|
+
*
|
|
92
|
+
* @param {String} message The action message.
|
|
93
|
+
* @returns {Object} An observable object that represents a pending action.
|
|
94
|
+
*/
|
|
95
|
+
add( message ) {
|
|
96
|
+
if ( typeof message !== 'string' ) {
|
|
97
|
+
/**
|
|
98
|
+
* The message must be a string.
|
|
99
|
+
*
|
|
100
|
+
* @error pendingactions-add-invalid-message
|
|
101
|
+
*/
|
|
102
|
+
throw new CKEditorError( 'pendingactions-add-invalid-message', this );
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const action = Object.create( ObservableMixin );
|
|
106
|
+
|
|
107
|
+
action.set( 'message', message );
|
|
108
|
+
this._actions.add( action );
|
|
109
|
+
this.hasAny = true;
|
|
110
|
+
|
|
111
|
+
return action;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Removes an action from the list of pending actions.
|
|
116
|
+
*
|
|
117
|
+
* @param {Object} action An action object.
|
|
118
|
+
*/
|
|
119
|
+
remove( action ) {
|
|
120
|
+
this._actions.remove( action );
|
|
121
|
+
this.hasAny = !!this._actions.length;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Returns the first action from the list or null when list is empty
|
|
126
|
+
*
|
|
127
|
+
* returns {Object|null} The pending action object.
|
|
128
|
+
*/
|
|
129
|
+
get first() {
|
|
130
|
+
return this._actions.get( 0 );
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Iterable interface.
|
|
135
|
+
*
|
|
136
|
+
* @returns {Iterable.<*>}
|
|
137
|
+
*/
|
|
138
|
+
[ Symbol.iterator ]() {
|
|
139
|
+
return this._actions[ Symbol.iterator ]();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Fired when an action is added to the list.
|
|
144
|
+
*
|
|
145
|
+
* @event add
|
|
146
|
+
* @param {Object} action The added action.
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Fired when an action is removed from the list.
|
|
151
|
+
*
|
|
152
|
+
* @event remove
|
|
153
|
+
* @param {Object} action The removed action.
|
|
154
|
+
*/
|
|
155
|
+
}
|