From dcee67b470732a1e3701c9d23ba050136822dbee Mon Sep 17 00:00:00 2001 From: godai78 Date: Mon, 29 May 2023 14:56:58 +0200 Subject: [PATCH 01/10] Docs: moving the autosave guide. --- docs/features/autosave.md | 139 ++++++++++++++++++ docs/installation/advanced/csp.md | 2 +- .../getting-and-setting-data.md | 125 +--------------- .../ckeditor5-autosave/docs/api/autosave.md | 2 +- .../docs/features/word-count.md | 2 +- 5 files changed, 148 insertions(+), 122 deletions(-) create mode 100644 docs/features/autosave.md diff --git a/docs/features/autosave.md b/docs/features/autosave.md new file mode 100644 index 00000000000..80109399e65 --- /dev/null +++ b/docs/features/autosave.md @@ -0,0 +1,139 @@ +--- +category: features +modified_at: 2023-05-29 +--- + +{@snippet installation/getting-and-setting-data/build-autosave-source} + +# Autosave + +The {@link module:autosave/autosave~Autosave} feature allows you to automatically save the data (e.g. send it to the server) when needed (when the user changed the content). + +## Demo + +{@snippet installation/getting-and-setting-data/autosave} + + + This demo only presents a limited set of features. Visit the {@link examples/builds/full-featured-editor full-featured editor example} to see more in action. + + +How to understand this demo: + +* The status indicator shows when the editor has some unsaved content or pending actions. + * If you drop a big image into this editor, you will see that it is busy during the entire period when the image is being uploaded. + * The editor is also busy when saving the content is in progress (the `save()`'s promise was not resolved). +* The autosave feature has a throttling mechanism which groups frequent changes (e.g. typing) are grouped in batches. +* The autosave itself does not check whether the data has actually changed. It bases on changes in the model which, in special cases, may not be "visible" in the data. You can add such a check yourself if you would like to avoid sending the same data to the server twice in a row. +* You will be asked whether you want to leave the page if an image is being uploaded or the data has not been saved successfully yet. You can test that by dropping a big image into the editor or changing the "HTTP server lag" to a high value (e.g. 9000ms) and typing something. These actions will make the editor "busy" for a longer time — try leaving the page then. + +## Installation + + + This plugin is unavailable in any of the builds by default so you need to {@link installation/plugins/installing-plugins install it}. + + +Assuming that you implemented a `saveData()` function that sends the data to your server and returns a promise which is resolved once the data is successfully saved, configuring the autosave feature is as simple as: + +```js +ClassicEditor + .create( document.querySelector( '#editor' ), { + plugins: [ + Autosave, + + // ... other plugins + ], + + autosave: { + save( editor ) { + return saveData( editor.getData() ); + } + }, + + // ... other configuration options + } ); +``` + +The autosave feature listens to the {@link module:engine/model/document~Document#event:change:data `editor.model.document#change:data`} event, throttles it, and executes the `config.autosave.save()` function. + +It also listens to the native [`window#beforeunload`](https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload) event and blocks it in the following cases: + +* The data has not been saved yet (the `save()` function did not resolve its promise or it was not called yet due to throttling). +* Or any of the editor features registered a {@link module:core/pendingactions~PendingActions "pending action"} (e.g. that an image is being uploaded). + +This automatically secures you from the user leaving the page before the content is saved or some ongoing actions like image upload did not finish. + +The minimum time period between two save actions can be configured using the {@link module:autosave/autosave~AutosaveConfig#waitingTime `config.waitingTime`} property to not overload the backend. 1 second is the default waiting time before the next save action if nothing has changed in the meantime after the editor data has changed. + +```js +ClassicEditor + .create( document.querySelector( '#editor' ), { + autosave: { + waitingTime: 5000, // in ms + save( editor ) {} + }, + + // ... other configuration options + } ); +``` + +### Demo + +This demo shows a simple integration of the editor with a fake HTTP server (which needs 1000ms to save the content). + +```js +ClassicEditor + .create( document.querySelector( '#editor' ), { + plugins: [ + Autosave, + + // ... other plugins + ], + + autosave: { + save( editor ) { + return saveData( editor.getData() ); + } + } + } ) + .then( editor => { + window.editor = editor; + + displayStatus( editor ); + } ) + .catch( err => { + console.error( err.stack ); + } ); + +// Save the data to a fake HTTP server (emulated here with a setTimeout()). +function saveData( data ) { + return new Promise( resolve => { + setTimeout( () => { + console.log( 'Saved', data ); + + resolve(); + }, HTTP_SERVER_LAG ); + } ); +} + +// Update the "Status: Saving..." info. +function displayStatus( editor ) { + const pendingActions = editor.plugins.get( 'PendingActions' ); + const statusIndicator = document.querySelector( '#editor-status' ); + + pendingActions.on( 'change:hasAny', ( evt, propertyName, newValue ) => { + if ( newValue ) { + statusIndicator.classList.add( 'busy' ); + } else { + statusIndicator.classList.remove( 'busy' ); + } + } ); +} +``` + +## Related features + +## Common API + +## Contribute + +The source code of the feature is available on GitHub at [https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-core](https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-core). diff --git a/docs/installation/advanced/csp.md b/docs/installation/advanced/csp.md index 7338531c4e5..861b5677452 100644 --- a/docs/installation/advanced/csp.md +++ b/docs/installation/advanced/csp.md @@ -27,7 +27,7 @@ Some CSP directives have an impact on certain rich-text editor features. Here is * `default-src 'none'`: Resets the policy and blocks everything. All successive directives work as a whitelist. By itself, as long as it is followed by other directives, it has no impact on the editor. * `connect-src 'self'` * Allows the {@link features/image-upload editor upload features} to use [`XMLHttpReqests`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) (Ajax) to upload files to the server, for instance, when an image is pasted or dropped into the editor content. The `'self`' value ensures the requests remain within the same host. - * Allows {@link installation/getting-started/getting-and-setting-data#autosave-feature auto–saving editor data} using `XMLHttpRequest`. + * Allows {@link features/autosave auto–saving editor data} using `XMLHttpRequest`. **Note**: To use [CKEditor Cloud Services](https://ckeditor.com/ckeditor-cloud-services/), include the `http://*.cke-cs.com` domain in the `connect-src` directive, for instance: `connect-src 'self' http://*.cke-cs.com`. * `script-src 'self'`: Allows the execution of JavaScript from the current host only and can be applied only if the CKEditor 5 script file (``) is also served from that host. diff --git a/docs/installation/getting-started/getting-and-setting-data.md b/docs/installation/getting-started/getting-and-setting-data.md index 2c7b16dcb1d..ad80066157b 100644 --- a/docs/installation/getting-started/getting-and-setting-data.md +++ b/docs/installation/getting-started/getting-and-setting-data.md @@ -13,7 +13,7 @@ order: 70 In the {@link installation/getting-started/editor-lifecycle previous tutorial} you have learned about lifecycle methods. Having the editor created, you can now set or get its data. -CKEditor 5 allows you to retrieve the data from and save it to your server (or to your system in general) in various ways. In this guide you can learn about the available options along with their pros and cons. +CKEditor 5 allows you to retrieve the data from and save it to your server (or to your system in general) in various ways. In this guide, you can learn about the available options along with their pros and cons. ## Automatic integration with HTML forms @@ -87,7 +87,7 @@ In your HTTP server, you can now read the editor data from the `content` variabl ``` - While simple content like mentioned above does not itself require to be encoded, encoding the data will prevent losing text like "<" or "<img>". + While simple content like that mentioned above does not itself require to be encoded, encoding the data will prevent losing text like "<" or "<img>". ## Manually retrieving the data @@ -115,7 +115,7 @@ To replace the editor content with new data, use the `setData()` method: editor.setData( '

Some text.

' ); ``` -For that, you need to store the reference to the `editor` because — unlike in CKEditor 4 — there is no global `CKEDITOR.instances` property. You can do that in multiple ways, for example by assigning the `editor` to a variable defined outside the `then()`'s callback: +For that, you need to store the reference to the `editor` because there is no global `CKEDITOR.instances` property. You can do that in multiple ways, for example by assigning the `editor` to a variable defined outside the `then()`'s callback: ```js let editor; @@ -149,129 +149,16 @@ ClassicEditor.create( document.querySelector( '#editor' ), { ``` -Enabling the `updateSourceElementOnDestroy` option in your configuration might have some security implications, depending on plugins you use. While the editing view is secured, there might be some unsafe content in the data output, so enable this option only if you know what you are doing. Be especially careful when using the Markdown, General HTML Support and HTML embed features. +Enabling the `updateSourceElementOnDestroy` option in your configuration might have some security implications, depending on the plugins you use. While the editing view is secured, there might be some unsafe content in the data output, so enable this option only if you know what you are doing. Be especially careful when using the Markdown, General HTML Support, and HTML embed features. ## Autosave feature -The {@link module:autosave/autosave~Autosave} feature allows you to automatically save the data (e.g. send it to the server) when needed (when the user changed the content). - - - This plugin is unavailable in any of the builds by default so you need to {@link installation/plugins/installing-plugins install it}. - - -Assuming that you implemented a `saveData()` function that sends the data to your server and returns a promise which is resolved once the data is successfully saved, configuring the autosave feature is as simple as: - -```js -ClassicEditor - .create( document.querySelector( '#editor' ), { - plugins: [ - Autosave, - - // ... other plugins - ], - - autosave: { - save( editor ) { - return saveData( editor.getData() ); - } - }, - - // ... other configuration options - } ); -``` - -The autosave feature listens to the {@link module:engine/model/document~Document#event:change:data `editor.model.document#change:data`} event, throttles it and executes the `config.autosave.save()` function. - -It also listens to the native [`window#beforeunload`](https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload) event and blocks it in the following cases: - -* The data has not been saved yet (the `save()` function did not resolve its promise or it was not called yet due to throttling). -* Or any of the editor features registered a {@link module:core/pendingactions~PendingActions "pending action"} (e.g. that an image is being uploaded). - -This automatically secures you from the user leaving the page before the content is saved or some ongoing actions like image upload did not finish. - -The minimum time period between two save actions can be configured using the {@link module:autosave/autosave~AutosaveConfig#waitingTime `config.waitingTime`} property to not overload the backend. 1 second is the default waiting time before the next save action if nothing has changed in the meantime after the editor data has changed. - -```js -ClassicEditor - .create( document.querySelector( '#editor' ), { - autosave: { - waitingTime: 5000, // in ms - save( editor ) {} - }, - - // ... other configuration options - } ); -``` - -### Demo - -This demo shows a simple integration of the editor with a fake HTTP server (which needs 1000ms to save the content). - -```js -ClassicEditor - .create( document.querySelector( '#editor' ), { - plugins: [ - Autosave, - - // ... other plugins - ], - - autosave: { - save( editor ) { - return saveData( editor.getData() ); - } - } - } ) - .then( editor => { - window.editor = editor; - - displayStatus( editor ); - } ) - .catch( err => { - console.error( err.stack ); - } ); - -// Save the data to a fake HTTP server (emulated here with a setTimeout()). -function saveData( data ) { - return new Promise( resolve => { - setTimeout( () => { - console.log( 'Saved', data ); - - resolve(); - }, HTTP_SERVER_LAG ); - } ); -} - -// Update the "Status: Saving..." info. -function displayStatus( editor ) { - const pendingActions = editor.plugins.get( 'PendingActions' ); - const statusIndicator = document.querySelector( '#editor-status' ); - - pendingActions.on( 'change:hasAny', ( evt, propertyName, newValue ) => { - if ( newValue ) { - statusIndicator.classList.add( 'busy' ); - } else { - statusIndicator.classList.remove( 'busy' ); - } - } ); -} -``` - -How to understand this demo: - -* The status indicator shows when the editor has some unsaved content or pending actions. - * If you drop a big image into this editor, you will see that it is busy during the entire period when the image is being uploaded. - * The editor is also busy when saving the content is in progress (the `save()`'s promise was not resolved). -* The autosave feature has a throttling mechanism which groups frequent changes (e.g. typing) are grouped in batches. -* The autosave itself does not check whether the data has really changed. It bases on changes in the model which, in special cases, may not be "visible" in the data. You can add such a check yourself if you would like to avoid sending the same data to the server twice in a row. -* You will be asked whether you want to leave the page if an image is being uploaded or the data has not been saved successfully yet. You can test that by dropping a big image into the editor or changing the "HTTP server lag" to a high value (e.g. 9000ms) and typing something. These actions will make the editor "busy" for a longer time — try leaving the page then. - -{@snippet installation/getting-and-setting-data/autosave} +The {@link module:autosave/autosave~Autosave} feature allows you to automatically save the data (e.g. send it to the server) when needed (when the user changed the content). Please refer to the {@link features/autosave autosave} guide for details. ## Handling users exiting the page -An additional concern when integrating the editor in your website is that the user may mistakenly leave before saving the data. This problem is automatically handled by the [autosave feature](#autosave-feature) described above, but if you do not use it and instead chose different integration methods, you should consider handling these two scenarios: +An additional concern when integrating the editor in your website is that the user may mistakenly leave before saving the data. This problem is automatically handled by the {@link features/autosave autosave feature}, but if you do not use it and instead chose different integration methods, you should consider handling these two scenarios: * The user leaves the page before saving the data (e.g. mistakenly closes a tab or clicks some link). * The user saved the data, but there are some pending actions like an image upload. diff --git a/packages/ckeditor5-autosave/docs/api/autosave.md b/packages/ckeditor5-autosave/docs/api/autosave.md index 24d0d65beaf..250d457f2f4 100644 --- a/packages/ckeditor5-autosave/docs/api/autosave.md +++ b/packages/ckeditor5-autosave/docs/api/autosave.md @@ -10,7 +10,7 @@ This package implements the autosaving feature for CKEditor 5. ## Documentation -See the {@link installation/getting-started/getting-and-setting-data#autosave-feature autosave feature guide} and the {@link module:autosave/autosave~Autosave} plugin documentation. +See the {@link features/autosave autosave feature guide} and the {@link module:autosave/autosave~Autosave} plugin documentation. ## Installation diff --git a/packages/ckeditor5-word-count/docs/features/word-count.md b/packages/ckeditor5-word-count/docs/features/word-count.md index 63225cf854d..b2a0282e5c1 100644 --- a/packages/ckeditor5-word-count/docs/features/word-count.md +++ b/packages/ckeditor5-word-count/docs/features/word-count.md @@ -264,7 +264,7 @@ ClassicEditor CKEditor 5 provides other productivity-boosting features that you may find helpful: * {@link features/spelling-and-grammar-checking Proofreading, spelling and grammar checking} – Track and correct any possible errors as you type. -* {@link installation/getting-started/getting-and-setting-data#autosave-feature Autosave} – Never lose your content by accident, stay safe and automatically save. +* {@link features/autosave Autosave} – Never lose your content by accident, stay safe and automatically save. * {@link features/autoformat Autoformatting} – Employ Markdown syntax for a faster and more efficient editing process. * {@link features/text-transformation Automatic text transformation} – Automatically turn predefined snippets into their improved forms using the autocorrect feature. From 73912ea1f279452af7af006fbb60d8c8de01bd5a Mon Sep 17 00:00:00 2001 From: godai78 Date: Tue, 30 May 2023 07:52:32 +0200 Subject: [PATCH 02/10] Docs: mostly maintenance stuff. --- .../installation/getting-and-setting-data/autosave.html | 4 ++-- .../ckeditor5-autosave/docs}/features/autosave.md | 8 +++++--- packages/ckeditor5-autosave/src/autosave.ts | 5 ++--- 3 files changed, 9 insertions(+), 8 deletions(-) rename {docs => packages/ckeditor5-autosave/docs}/features/autosave.md (89%) diff --git a/docs/_snippets/installation/getting-and-setting-data/autosave.html b/docs/_snippets/installation/getting-and-setting-data/autosave.html index b6468d7cb8d..34cc11a80b9 100644 --- a/docs/_snippets/installation/getting-and-setting-data/autosave.html +++ b/docs/_snippets/installation/getting-and-setting-data/autosave.html @@ -1,5 +1,5 @@
-

Type some text to test the autosave feature.

+

Type some text or input some rich content to test the autosave feature.

@@ -19,7 +19,7 @@

Server data:

-
Type some text to test the <a href="#autosave-feature">autosave</a> feature.
+
Type some text to test the autosave feature.