@_sh/strapi-plugin-ckeditor 2.0.3 → 2.0.4
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 +20 -20
- package/README.md +448 -448
- package/admin/src/components/CKEditorIcon.js +45 -45
- package/admin/src/components/Input/CKEditor/configs/base.js +627 -627
- package/admin/src/components/Input/CKEditor/configs/blockBaloon.js +25 -25
- package/admin/src/components/Input/CKEditor/configs/index.js +11 -11
- package/admin/src/components/Input/CKEditor/configs/toolbar.js +17 -17
- package/admin/src/components/Input/CKEditor/configs/toolbarBaloon.js +17 -17
- package/admin/src/components/Input/CKEditor/configuration.js +165 -165
- package/admin/src/components/Input/CKEditor/index.js +119 -119
- package/admin/src/components/Input/CKEditor/plugins/StrapiMediaLib.js +43 -43
- package/admin/src/components/Input/CKEditor/plugins/StrapiUploadAdapter.js +204 -203
- package/admin/src/components/Input/CKEditor/plugins/index.js +1 -1
- package/admin/src/components/Input/CKEditor/styling.js +16 -16
- package/admin/src/components/Input/CKEditor/theme/additional.js +212 -212
- package/admin/src/components/Input/CKEditor/theme/common.js +232 -232
- package/admin/src/components/Input/CKEditor/theme/dark.js +144 -144
- package/admin/src/components/Input/CKEditor/theme/index.js +12 -12
- package/admin/src/components/Input/CKEditor/theme/light.js +135 -135
- package/admin/src/components/Input/MediaLib/index.js +78 -78
- package/admin/src/components/Input/index.js +47 -47
- package/admin/src/index.js +109 -109
- package/admin/src/utils/getEditorConfig.js +37 -37
- package/admin/src/utils/pluginId.js +4 -4
- package/package.json +86 -86
- package/server/controllers/config.js +16 -16
- package/server/controllers/index.js +7 -7
- package/server/index.js +13 -13
- package/server/register.js +11 -11
- package/server/routes/index.js +15 -15
- package/server/services/config.js +19 -19
- package/server/services/index.js +7 -7
- package/strapi-admin.js +3 -3
- package/strapi-server.js +3 -3
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
|
-
import styled from "styled-components";
|
|
4
|
-
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
|
5
|
-
import { Box, Loader } from '@strapi/design-system';
|
|
6
|
-
|
|
7
|
-
import {getConfiguration} from "./configuration";
|
|
8
|
-
import {getGlobalStyling} from "./styling";
|
|
9
|
-
import MediaLib from "../MediaLib";
|
|
10
|
-
|
|
11
|
-
import ckeditor5Dll from "ckeditor5/build/ckeditor5-dll.js";
|
|
12
|
-
import ckeditor5EditorClassicDll from "@ckeditor/ckeditor5-editor-classic/build/editor-classic.js";
|
|
13
|
-
|
|
14
|
-
const GlobalStyling = getGlobalStyling();
|
|
15
|
-
|
|
16
|
-
const Wrapper = styled("div")`${({ editorStyles }) => editorStyles}`;
|
|
17
|
-
|
|
18
|
-
const Editor = ({ onChange, name, value, disabled, preset, maxLength }) => {
|
|
19
|
-
|
|
20
|
-
const [ editorInstance, setEditorInstance ] = useState(false);
|
|
21
|
-
|
|
22
|
-
const [mediaLibVisible, setMediaLibVisible] = useState(false);
|
|
23
|
-
|
|
24
|
-
const [uploadPluginConfig, setUploadPluginConfig] = useState(null);
|
|
25
|
-
|
|
26
|
-
const [config, setConfig] = useState(null);
|
|
27
|
-
|
|
28
|
-
const [lengthMax, setLengthMax] = useState(false);
|
|
29
|
-
|
|
30
|
-
const wordCounter = useRef(null);
|
|
31
|
-
|
|
32
|
-
const handleToggleMediaLib = () => setMediaLibVisible(prev => !prev);
|
|
33
|
-
|
|
34
|
-
const handleCounter = (number) => number > maxLength ? setLengthMax(true) : setLengthMax(false);
|
|
35
|
-
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
(async () => {
|
|
38
|
-
const {currentConfig, uploadPluginConfig} = await getConfiguration(preset, handleToggleMediaLib);
|
|
39
|
-
setConfig(currentConfig);
|
|
40
|
-
setUploadPluginConfig(uploadPluginConfig);
|
|
41
|
-
})();
|
|
42
|
-
}, []);
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<>
|
|
46
|
-
{config && <GlobalStyling />}
|
|
47
|
-
<Wrapper editorStyles={config?.styles} >
|
|
48
|
-
{!config &&
|
|
49
|
-
<LoaderBox hasRadius background="neutral100">
|
|
50
|
-
<Loader>Loading...</Loader>
|
|
51
|
-
</LoaderBox>}
|
|
52
|
-
{config &&
|
|
53
|
-
<CKEditor
|
|
54
|
-
editor={window.CKEditor5.editorClassic.ClassicEditor}
|
|
55
|
-
config={config?.editorConfig}
|
|
56
|
-
disabled={disabled}
|
|
57
|
-
data={value}
|
|
58
|
-
onReady={(editor) => {
|
|
59
|
-
|
|
60
|
-
if(config.editorConfig.WordCountPlugin){
|
|
61
|
-
const wordCountPlugin = editor.plugins.get( 'WordCount' );
|
|
62
|
-
wordCountPlugin.on( 'update', ( evt, stats ) =>handleCounter(stats.characters));
|
|
63
|
-
const wordCountWrapper = wordCounter.current;
|
|
64
|
-
wordCountWrapper?.appendChild( wordCountPlugin.wordCountContainer );
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if(editor.plugins.has( 'ImageUploadEditing' )){
|
|
68
|
-
editor.plugins.get( 'ImageUploadEditing' ).on( 'uploadComplete', ( evt, { data, imageElement } ) =>
|
|
69
|
-
editor.model.change( writer => writer.setAttribute( 'alt', data.alt, imageElement ) ) );
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
setEditorInstance( editor );
|
|
73
|
-
}}
|
|
74
|
-
onChange={(event, editor) => {
|
|
75
|
-
const data = editor.getData();
|
|
76
|
-
onChange({ target: { name, value: data } });
|
|
77
|
-
}}
|
|
78
|
-
/>
|
|
79
|
-
}
|
|
80
|
-
{config && config.editorConfig.WordCountPlugin &&
|
|
81
|
-
<CounterLoaderBox
|
|
82
|
-
color={lengthMax?"danger500":"neutral400"}
|
|
83
|
-
ref={wordCounter}>
|
|
84
|
-
{!editorInstance && <Loader small>Loading...</Loader>}
|
|
85
|
-
</CounterLoaderBox>
|
|
86
|
-
}
|
|
87
|
-
{uploadPluginConfig && <MediaLib isOpen={mediaLibVisible} onToggle={handleToggleMediaLib} editor={editorInstance} uploadConfig={uploadPluginConfig} />}
|
|
88
|
-
</Wrapper>
|
|
89
|
-
</>
|
|
90
|
-
);
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
Editor.defaultProps = {
|
|
94
|
-
value: "",
|
|
95
|
-
disabled: false,
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
Editor.propTypes = {
|
|
99
|
-
onChange: PropTypes.func.isRequired,
|
|
100
|
-
name: PropTypes.string.isRequired,
|
|
101
|
-
value: PropTypes.string,
|
|
102
|
-
disabled: PropTypes.bool,
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const CounterLoaderBox = styled(Box)`
|
|
106
|
-
display:flex;
|
|
107
|
-
width: 100%;
|
|
108
|
-
justify-content: flex-end;
|
|
109
|
-
align-items: center;
|
|
110
|
-
`
|
|
111
|
-
const LoaderBox = styled(Box)`
|
|
112
|
-
display:flex;
|
|
113
|
-
height: 200px;
|
|
114
|
-
width: 100%;
|
|
115
|
-
justify-content: center;
|
|
116
|
-
align-items: center;
|
|
117
|
-
`
|
|
118
|
-
|
|
119
|
-
export default Editor;
|
|
1
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import styled from "styled-components";
|
|
4
|
+
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
|
5
|
+
import { Box, Loader } from '@strapi/design-system';
|
|
6
|
+
|
|
7
|
+
import {getConfiguration} from "./configuration";
|
|
8
|
+
import {getGlobalStyling} from "./styling";
|
|
9
|
+
import MediaLib from "../MediaLib";
|
|
10
|
+
|
|
11
|
+
import ckeditor5Dll from "ckeditor5/build/ckeditor5-dll.js";
|
|
12
|
+
import ckeditor5EditorClassicDll from "@ckeditor/ckeditor5-editor-classic/build/editor-classic.js";
|
|
13
|
+
|
|
14
|
+
const GlobalStyling = getGlobalStyling();
|
|
15
|
+
|
|
16
|
+
const Wrapper = styled("div")`${({ editorStyles }) => editorStyles}`;
|
|
17
|
+
|
|
18
|
+
const Editor = ({ onChange, name, value, disabled, preset, maxLength }) => {
|
|
19
|
+
|
|
20
|
+
const [ editorInstance, setEditorInstance ] = useState(false);
|
|
21
|
+
|
|
22
|
+
const [mediaLibVisible, setMediaLibVisible] = useState(false);
|
|
23
|
+
|
|
24
|
+
const [uploadPluginConfig, setUploadPluginConfig] = useState(null);
|
|
25
|
+
|
|
26
|
+
const [config, setConfig] = useState(null);
|
|
27
|
+
|
|
28
|
+
const [lengthMax, setLengthMax] = useState(false);
|
|
29
|
+
|
|
30
|
+
const wordCounter = useRef(null);
|
|
31
|
+
|
|
32
|
+
const handleToggleMediaLib = () => setMediaLibVisible(prev => !prev);
|
|
33
|
+
|
|
34
|
+
const handleCounter = (number) => number > maxLength ? setLengthMax(true) : setLengthMax(false);
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
(async () => {
|
|
38
|
+
const {currentConfig, uploadPluginConfig} = await getConfiguration(preset, handleToggleMediaLib);
|
|
39
|
+
setConfig(currentConfig);
|
|
40
|
+
setUploadPluginConfig(uploadPluginConfig);
|
|
41
|
+
})();
|
|
42
|
+
}, []);
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<>
|
|
46
|
+
{config && <GlobalStyling />}
|
|
47
|
+
<Wrapper editorStyles={config?.styles} >
|
|
48
|
+
{!config &&
|
|
49
|
+
<LoaderBox hasRadius background="neutral100">
|
|
50
|
+
<Loader>Loading...</Loader>
|
|
51
|
+
</LoaderBox>}
|
|
52
|
+
{config &&
|
|
53
|
+
<CKEditor
|
|
54
|
+
editor={window.CKEditor5.editorClassic.ClassicEditor}
|
|
55
|
+
config={config?.editorConfig}
|
|
56
|
+
disabled={disabled}
|
|
57
|
+
data={value}
|
|
58
|
+
onReady={(editor) => {
|
|
59
|
+
|
|
60
|
+
if(config.editorConfig.WordCountPlugin){
|
|
61
|
+
const wordCountPlugin = editor.plugins.get( 'WordCount' );
|
|
62
|
+
wordCountPlugin.on( 'update', ( evt, stats ) =>handleCounter(stats.characters));
|
|
63
|
+
const wordCountWrapper = wordCounter.current;
|
|
64
|
+
wordCountWrapper?.appendChild( wordCountPlugin.wordCountContainer );
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if(editor.plugins.has( 'ImageUploadEditing' )){
|
|
68
|
+
editor.plugins.get( 'ImageUploadEditing' ).on( 'uploadComplete', ( evt, { data, imageElement } ) =>
|
|
69
|
+
editor.model.change( writer => writer.setAttribute( 'alt', data.alt, imageElement ) ) );
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
setEditorInstance( editor );
|
|
73
|
+
}}
|
|
74
|
+
onChange={(event, editor) => {
|
|
75
|
+
const data = editor.getData();
|
|
76
|
+
onChange({ target: { name, value: data } });
|
|
77
|
+
}}
|
|
78
|
+
/>
|
|
79
|
+
}
|
|
80
|
+
{config && config.editorConfig.WordCountPlugin &&
|
|
81
|
+
<CounterLoaderBox
|
|
82
|
+
color={lengthMax?"danger500":"neutral400"}
|
|
83
|
+
ref={wordCounter}>
|
|
84
|
+
{!editorInstance && <Loader small>Loading...</Loader>}
|
|
85
|
+
</CounterLoaderBox>
|
|
86
|
+
}
|
|
87
|
+
{uploadPluginConfig && <MediaLib isOpen={mediaLibVisible} onToggle={handleToggleMediaLib} editor={editorInstance} uploadConfig={uploadPluginConfig} />}
|
|
88
|
+
</Wrapper>
|
|
89
|
+
</>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
Editor.defaultProps = {
|
|
94
|
+
value: "",
|
|
95
|
+
disabled: false,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
Editor.propTypes = {
|
|
99
|
+
onChange: PropTypes.func.isRequired,
|
|
100
|
+
name: PropTypes.string.isRequired,
|
|
101
|
+
value: PropTypes.string,
|
|
102
|
+
disabled: PropTypes.bool,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const CounterLoaderBox = styled(Box)`
|
|
106
|
+
display:flex;
|
|
107
|
+
width: 100%;
|
|
108
|
+
justify-content: flex-end;
|
|
109
|
+
align-items: center;
|
|
110
|
+
`
|
|
111
|
+
const LoaderBox = styled(Box)`
|
|
112
|
+
display:flex;
|
|
113
|
+
height: 200px;
|
|
114
|
+
width: 100%;
|
|
115
|
+
justify-content: center;
|
|
116
|
+
align-items: center;
|
|
117
|
+
`
|
|
118
|
+
|
|
119
|
+
export default Editor;
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
const Plugin = window.CKEditor5.core.Plugin;
|
|
2
|
-
const ButtonView = window.CKEditor5.ui.ButtonView;
|
|
3
|
-
const mediaLibIcon = '<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">' +
|
|
4
|
-
'<path fill-rule="evenodd" clip-rule="evenodd" d="M4.3.6a.9.9 0 100 1.8h15.311a.9.9 0 100-1.8H4.301zm17.1 3.7A1.6 1.6' +
|
|
5
|
-
' 0 0123 5.9v15.5a1.6 1.6 0 01-1.6 1.6H2.6A1.601 1.601 0 011 21.4V8 5.915C1 5.03 1.716 4.3 2.6' +
|
|
6
|
-
' 4.3h18.8zM5.032 19.18h14.336l-3.136-3.205-1.792 1.831-4.032-4.12-5.376 5.494zm13.44-8.697c0 ' +
|
|
7
|
-
'1.282-.985 2.289-2.24 2.289-1.254 0-2.24-1.007-2.24-2.29 0-1.281.986-2.288 2.24-2.288 1.255 0 2.24 1.007 2.24 2.289z">' +
|
|
8
|
-
'</path></svg>'
|
|
9
|
-
|
|
10
|
-
export default class StrapiMediaLib extends Plugin {
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Strapi function used to show media library modal.
|
|
14
|
-
* Should be provided via connect method before using toggle method.
|
|
15
|
-
*
|
|
16
|
-
* @type {function|null}
|
|
17
|
-
*/
|
|
18
|
-
strapiToggle = null;
|
|
19
|
-
|
|
20
|
-
static get pluginName() {
|
|
21
|
-
return 'StrapiMediaLib'
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
init() {
|
|
25
|
-
const editor = this.editor;
|
|
26
|
-
const config = editor.config.get('strapiMediaLib');
|
|
27
|
-
editor.ui.componentFactory.add('strapiMediaLib', () => {
|
|
28
|
-
|
|
29
|
-
const button = new ButtonView();
|
|
30
|
-
|
|
31
|
-
button.set({
|
|
32
|
-
label: "Media Library",
|
|
33
|
-
icon: mediaLibIcon,
|
|
34
|
-
tooltip: true
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
button.on('execute', config.toggle.bind(this));
|
|
38
|
-
|
|
39
|
-
return button;
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
}
|
|
1
|
+
const Plugin = window.CKEditor5.core.Plugin;
|
|
2
|
+
const ButtonView = window.CKEditor5.ui.ButtonView;
|
|
3
|
+
const mediaLibIcon = '<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">' +
|
|
4
|
+
'<path fill-rule="evenodd" clip-rule="evenodd" d="M4.3.6a.9.9 0 100 1.8h15.311a.9.9 0 100-1.8H4.301zm17.1 3.7A1.6 1.6' +
|
|
5
|
+
' 0 0123 5.9v15.5a1.6 1.6 0 01-1.6 1.6H2.6A1.601 1.601 0 011 21.4V8 5.915C1 5.03 1.716 4.3 2.6' +
|
|
6
|
+
' 4.3h18.8zM5.032 19.18h14.336l-3.136-3.205-1.792 1.831-4.032-4.12-5.376 5.494zm13.44-8.697c0 ' +
|
|
7
|
+
'1.282-.985 2.289-2.24 2.289-1.254 0-2.24-1.007-2.24-2.29 0-1.281.986-2.288 2.24-2.288 1.255 0 2.24 1.007 2.24 2.289z">' +
|
|
8
|
+
'</path></svg>'
|
|
9
|
+
|
|
10
|
+
export default class StrapiMediaLib extends Plugin {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Strapi function used to show media library modal.
|
|
14
|
+
* Should be provided via connect method before using toggle method.
|
|
15
|
+
*
|
|
16
|
+
* @type {function|null}
|
|
17
|
+
*/
|
|
18
|
+
strapiToggle = null;
|
|
19
|
+
|
|
20
|
+
static get pluginName() {
|
|
21
|
+
return 'StrapiMediaLib'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
init() {
|
|
25
|
+
const editor = this.editor;
|
|
26
|
+
const config = editor.config.get('strapiMediaLib');
|
|
27
|
+
editor.ui.componentFactory.add('strapiMediaLib', () => {
|
|
28
|
+
|
|
29
|
+
const button = new ButtonView();
|
|
30
|
+
|
|
31
|
+
button.set({
|
|
32
|
+
label: "Media Library",
|
|
33
|
+
icon: mediaLibIcon,
|
|
34
|
+
tooltip: true
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
button.on('execute', config.toggle.bind(this));
|
|
38
|
+
|
|
39
|
+
return button;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
}
|