Skip to content

Commit bbe30ba

Browse files
authored
Release v0.2.0
1 parent 764c6cd commit bbe30ba

File tree

9 files changed

+110
-106
lines changed

9 files changed

+110
-106
lines changed

CHANGELOG.md

+12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
## 0.2.0 (December 2, 2024)
4+
5+
We are happy to announce the release of CKEditor 5 Official Integration v0.2.0.
6+
7+
### Release highlights
8+
9+
In this release, we updated the CKEditor 5 version to [v44.0.0](https://github.com/ckeditor/ckeditor5/blob/master/CHANGELOG.md#4400-december-2-2024), which introduces high impact updates. Starting from the plugin version 0.2.0, the custom field will require passing a valid license key.
10+
11+
### BREAKING CHANGES ℹ️
12+
13+
* **CKEditor 5 custom field now requires the license key**. CKEditor 5 now requires a valid license key, which can be retrieved from [Customer Portal](https://portal.ckeditor.com/). You can sign up for a [commitment-free trial](https://portal.ckeditor.com/checkout?plan=free) and get instant access to your key.
14+
315
## 0.1.0 (September 19, 2024)
416

517
We are happy to announce the release of CKEditor 5 Official Integration v0.1.0.

README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ This is an official plugin, provided to you by the [CKEditor team](https://ckedi
2222

2323
## <a id="installation"></a>🔧 Installation
2424

25+
> [!IMPORTANT]
26+
> Before installation, make sure that you own a **valid CKEditor 5 license key**. Start a [commitment-free trial](https://portal.ckeditor.com/checkout?plan=free) to get instant access to the license key. You can also refer to our [license key and activation guide](https://ckeditor.com/docs//ckeditor5/latest/getting-started/licensing/license-key-and-activation.html) to learn more.
27+
2528
Inside your Strapi app, add the package:
2629

2730
With `npm`:
@@ -36,7 +39,7 @@ With `yarn`:
3639
yarn add @ckeditor/strapi-plugin-ckeditor
3740
```
3841

39-
Then, add the Content Security Policy configuration to allow loading CKEditor 5 from https://cdn.ckeditor.com origin, by adding the rule to `config/middlewares.ts` in your Strapi project root:
42+
Then, add the Content Security Policy configuration to allow loading CKEditor 5 from https://cdn.ckeditor.com origin and sending the editor usage information to https://proxy-event.ckeditor.com, by adding the rule to `config/middlewares.ts` in your Strapi project root:
4043

4144
```js
4245
export default [
@@ -47,7 +50,8 @@ export default [
4750
contentSecurityPolicy: {
4851
useDefaults: true,
4952
directives: {
50-
'script-src': ['https://cdn.ckeditor.com']
53+
'script-src': ['https://cdn.ckeditor.com'],
54+
'connect-src': ['https://proxy-event.ckeditor.com']
5155
},
5256
},
5357
},

admin/src/components/CKEditorInput/Configurator.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { StrapiMediaLib } from "./plugins/StrapiMediaLib";
2+
import { StrapiEditorUsageDataPlugin } from "./plugins/StrapiEditorUsageData.js";
23

34
import MaximumLength from "../../vendor/ckeditor5-maximum-length/index";
45
import "../../vendor/ckeditor5-maximum-length/index-editor.css";
@@ -77,7 +78,8 @@ const CKEDITOR_BASE_CONFIG_FOR_PRESETS = {
7778
TableColumnResize,
7879
TableCaption,
7980
WordCount,
80-
StrapiMediaLib
81+
StrapiMediaLib,
82+
StrapiEditorUsageDataPlugin
8183
],
8284
toolbar: [
8385
'undo', 'redo',
@@ -146,7 +148,8 @@ const CKEDITOR_BASE_CONFIG_FOR_PRESETS = {
146148
TableColumnResize,
147149
TableCaption,
148150
WordCount,
149-
StrapiMediaLib
151+
StrapiMediaLib,
152+
StrapiEditorUsageDataPlugin
150153
],
151154
toolbar: [
152155
'undo', 'redo',
@@ -240,7 +243,8 @@ const CKEDITOR_BASE_CONFIG_FOR_PRESETS = {
240243
TableCaption,
241244
WordCount,
242245
Highlight,
243-
StrapiMediaLib
246+
StrapiMediaLib,
247+
StrapiEditorUsageDataPlugin
244248
],
245249
toolbar: {
246250
items: [
@@ -372,6 +376,9 @@ export default class Configurator {
372376

373377
const maxLength = this.fieldConfig.maxLength;
374378
const outputOption = this.fieldConfig.options.output;
379+
const licenseKey = this.fieldConfig.licenseKey;
380+
381+
config.licenseKey = licenseKey;
375382

376383
if ( outputOption === 'Markdown' ) {
377384
config.plugins.push( Markdown );

admin/src/components/CKEditorInput/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ const CKEditorInput = ( props ) => {
2929
} = props;
3030
const [ editorInstance, setEditorInstance ] = useState(false);
3131
const { formatMessage } = useIntl();
32-
const { maxLengthCharacters:maxLength , ...options } = attribute.options;
33-
const configurator = new Configurator( { options, maxLength } );
32+
const { maxLengthCharacters:maxLength, licenseKey, ...options } = attribute.options;
33+
const configurator = new Configurator( { options, maxLength, licenseKey } );
3434
const editorConfig = configurator.getEditorConfig();
3535

3636
const wordCounter = useRef( null );
@@ -132,4 +132,4 @@ CKEditorInput.propTypes = {
132132
value: PropTypes.string,
133133
};
134134

135-
export default CKEditorInput;
135+
export { CKEditorInput };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { createIntegrationUsageDataPlugin } from '@ckeditor/ckeditor5-integrations-common';
2+
import * as pkg from '../../../../../package.json'
3+
4+
export const StrapiEditorUsageDataPlugin = createIntegrationUsageDataPlugin(
5+
'strapi',
6+
{
7+
version: pkg.version,
8+
}
9+
);
+42-86
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,54 @@
1-
import { useState, useEffect } from 'react';
1+
import { memo, useEffect } from 'react';
2+
import { useCKEditorCloud } from '@ckeditor/ckeditor5-react';
23

34
const CKEditorProvider = ( {
4-
attribute,
5-
onChange,
6-
name,
7-
value,
8-
disabled = false,
9-
labelAction = null,
10-
intlLabel,
11-
required = false,
12-
description = null,
13-
error = null
14-
} ) => {
15-
const [ importedEditor, setImportedEditor ] = useState( null );
16-
5+
attribute,
6+
onChange,
7+
name,
8+
value,
9+
disabled = false,
10+
labelAction = null,
11+
intlLabel,
12+
required = false,
13+
description = null,
14+
error = null } ) => {
15+
16+
// Clean up CDN scripts after unmounting the component.
1717
useEffect( () => {
18-
const importEditor = async () => {
19-
const module = await import( '../CKEditorInput' );
20-
const CKEditorInput = module.default;
21-
22-
setImportedEditor(<CKEditorInput
23-
attribute={ attribute }
24-
onChange={ onChange }
25-
name={ name }
26-
value={ value }
27-
disabled={ disabled }
28-
labelAction={ labelAction }
29-
required={ required }
30-
description={ description }
31-
error={ error }
32-
intlLabel={ intlLabel }
33-
/> );
34-
};
35-
36-
const injectAssetsFromCDN = setInterval( () => {
37-
const CDNScript = document.querySelector( '#ckeditor5-cdn-script' );
38-
const CDNStyles = document.querySelector( '#ckeditor5-cdn-styles' );
39-
40-
if ( !CDNStyles ) {
41-
_injectStylesFromCDN();
42-
}
43-
44-
if ( window.CKEDITOR ) {
45-
window.CKEditorCDNLoaded = true;
46-
47-
importEditor();
48-
49-
clearInterval( injectAssetsFromCDN );
50-
51-
return;
52-
}
53-
54-
if ( !CDNScript ) {
55-
_injectScriptFromCDN();
56-
57-
}
58-
}, 100 )
59-
6018
return () => {
61-
const CDNScript = document.querySelector( '#ckeditor5-cdn-script' );
19+
const assets = document.querySelectorAll( '[data-injected-by="ckeditor-integration"]' );
6220

63-
if ( CDNScript ) {
64-
CDNScript.remove();
65-
}
21+
assets.forEach( asset => asset.remove() );
6622

67-
window.CKEditorCDNLoaded = false;
23+
window.CKEDITOR_VERSION = null;
6824
}
69-
}, [] );
25+
}, [] )
7026

71-
return (
72-
<>
73-
{ window.CKEditorCDNLoaded && importedEditor }
74-
</>
75-
)
76-
}
77-
78-
function _injectStylesFromCDN() {
79-
const link = document.createElement( 'link' );
80-
81-
link.rel = 'stylesheet';
82-
link.href = 'https://cdn.ckeditor.com/ckeditor5/43.0.0/ckeditor5.css';
83-
link.id = 'ckeditor5-cdn-styles';
84-
85-
document.head.appendChild( link );
86-
}
87-
88-
function _injectScriptFromCDN() {
89-
const script = document.createElement( 'script' );
27+
const cloud = useCKEditorCloud( {
28+
version: '44.0.0',
29+
plugins: {
30+
CKEditorInput: async () => ( await import('../CKEditorInput') ).CKEditorInput
31+
}
32+
} );
9033

91-
script.src = "https://cdn.ckeditor.com/ckeditor5/43.0.0/ckeditor5.umd.js";
92-
script.async = true;
93-
script.id = 'ckeditor5-cdn-script'
34+
if ( cloud.status !== 'success' ) {
35+
return null;
36+
}
9437

95-
document.body.appendChild( script );
38+
return (
39+
<cloud.loadedPlugins.CKEditorInput
40+
attribute={ attribute }
41+
onChange={ onChange }
42+
name={ name }
43+
value={ value }
44+
disabled={ disabled }
45+
labelAction={ labelAction }
46+
required={ required }
47+
description={ description }
48+
error={ error }
49+
intlLabel={ intlLabel }
50+
/>
51+
)
9652
}
9753

98-
export default CKEditorProvider;
54+
export default memo( CKEditorProvider );

admin/src/index.js

+16
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ export default {
4141
},
4242
options: {
4343
base: [
44+
{
45+
intlLabel: {
46+
id: 'ckeditor.licenseKey.label',
47+
defaultMessage: 'License key',
48+
},
49+
description: {
50+
id: 'ckeditor.licenseKey.description',
51+
defaultMessage: "Don't have a license key? Visit https://portal.ckeditor.com/checkout?plan=free to receive it.",
52+
},
53+
name: 'options.licenseKey',
54+
type: 'text',
55+
},
4456
{
4557
intlLabel: {
4658
id: 'ckeditor.preset.label',
@@ -157,6 +169,10 @@ export default {
157169
id: 'ckeditor.preset.error.required',
158170
defaultMessage: 'Editor preset is required',
159171
} ),
172+
licenseKey: yup.string().required( {
173+
id: 'ckeditor.licenseKey.error.required',
174+
defaultMessage: 'Editor license key is required. Visit https://portal.ckeditor.com/checkout?plan=free to receive it.',
175+
} ),
160176
} ),
161177
},
162178
} );

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ckeditor/strapi-plugin-ckeditor",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"description": "CKEditor 5 - Official Integration for Strapi.",
55
"strapi": {
66
"name": "ckeditor",
@@ -24,7 +24,7 @@
2424
"strapi-server.js"
2525
],
2626
"dependencies": {
27-
"@ckeditor/ckeditor5-react": "^9.1.0"
27+
"@ckeditor/ckeditor5-react": "^9.3.0"
2828
},
2929
"peerDependencies": {
3030
"@strapi/strapi": "^4.4.0"

yarn.lock

+10-10
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
# yarn lockfile v1
33

44

5-
"@ckeditor/ckeditor5-integrations-common@^1.0.0":
6-
version "1.0.0"
7-
resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-integrations-common/-/ckeditor5-integrations-common-1.0.0.tgz#f2f73509d029398929ee30da3ae23329de5a796a"
8-
integrity sha512-HLToIJ7FAtKX0tu9GaGb1d39Kx0i0TFelAj2pQPiwPU/6DLgM5gi+m0WCZub+syruSonmZPONtWrrZZdUoDB/g==
9-
10-
"@ckeditor/ckeditor5-react@^9.1.0":
11-
version "9.1.0"
12-
resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-react/-/ckeditor5-react-9.1.0.tgz#fc645a055a5c84acb41c55f0c4bffab45221d2ca"
13-
integrity sha512-48Y8Ffe21H3+3GOvjTtSITYJdeX4BINxCHyXp5zNvhTtyAyahMwG6jCgdZl1D3lwXxSq9R0/yCDHPWeMk9KOHQ==
5+
"@ckeditor/ckeditor5-integrations-common@^2.2.2":
6+
version "2.2.2"
7+
resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-integrations-common/-/ckeditor5-integrations-common-2.2.2.tgz#c494b51ad0736d087a7bc13ec634e2d66db42d5b"
8+
integrity sha512-SKGBBrwFFmSEZawR8P9tHGRq/l2OoqoJxy9f7j0HbDGEwIpSOsCSgH0xudD6lcEbWG4QWrCS28p5n8lgPA5elQ==
9+
10+
"@ckeditor/ckeditor5-react@^9.3.0":
11+
version "9.4.0"
12+
resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-react/-/ckeditor5-react-9.4.0.tgz#2d750ed585a4668931be089da7a02e823c706f16"
13+
integrity sha512-8PU7YUV0ZKYP10akKgarT8nq5QxEDPmuj6Wn5dl/DJ7qroDx6VuC/ysCYcgljseimbDNYDjPQKhatNEcsMd7Ew==
1414
dependencies:
15-
"@ckeditor/ckeditor5-integrations-common" "^1.0.0"
15+
"@ckeditor/ckeditor5-integrations-common" "^2.2.2"
1616
prop-types "^15.7.2"
1717

1818
"js-tokens@^3.0.0 || ^4.0.0":

0 commit comments

Comments
 (0)