@ckeditor/ckeditor5-autosave
Advanced tools
Comparing version 10.0.0 to 10.0.1
Changelog | ||
========= | ||
## [10.0.1](https://github.com/ckeditor/ckeditor5-autosave/compare/v10.0.0...v10.0.1) (2018-10-08) | ||
### Other changes | ||
* Improved heuristics for triggering the save callback. It will not be called before the previous save attempt completed. It will be called less often in when the user is in the middle of making changes. Closes [#9](https://github.com/ckeditor/ckeditor5-autosave/issues/9). Closes [#10](https://github.com/ckeditor/ckeditor5-autosave/issues/10). Closes [#12](https://github.com/ckeditor/ckeditor5-autosave/issues/12). Closes [ckeditor/ckeditor5#1158](https://github.com/ckeditor/ckeditor5/issues/1158). ([820e060](https://github.com/ckeditor/ckeditor5-autosave/commit/820e060)) | ||
* Updated translations. ([3f52ebc](https://github.com/ckeditor/ckeditor5-autosave/commit/3f52ebc)) ([8c702ee](https://github.com/ckeditor/ckeditor5-autosave/commit/8c702ee)) | ||
## [10.0.0](https://github.com/ckeditor/ckeditor5-autosave/tree/v10.0.0) (2018-07-18) | ||
@@ -8,2 +16,2 @@ | ||
* The first implementation of the autosave plugin. Check out the [demo](https://docs.ckeditor.com/ckeditor5/latest/builds/guides/integration/saving-data.html#autosave-feature). | ||
* The first implementation of the autosave plugin. Check out the [demo](https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/saving-data.html#autosave-feature). |
{ | ||
"name": "@ckeditor/ckeditor5-autosave", | ||
"version": "10.0.0", | ||
"version": "10.0.1", | ||
"description": "Autosave feature for CKEditor 5.", | ||
@@ -9,13 +9,15 @@ "keywords": [ | ||
"ckeditor 5", | ||
"ckeditor5-feature" | ||
"ckeditor5-feature", | ||
"ckeditor5-plugin" | ||
], | ||
"dependencies": { | ||
"@ckeditor/ckeditor5-utils": "^10.2.0", | ||
"@ckeditor/ckeditor5-core": "^11.0.0" | ||
"@ckeditor/ckeditor5-utils": "^11.0.0", | ||
"@ckeditor/ckeditor5-core": "^11.0.1", | ||
"lodash-es": "^4.17.10" | ||
}, | ||
"devDependencies": { | ||
"@ckeditor/ckeditor5-engine": "^10.2.0", | ||
"@ckeditor/ckeditor5-paragraph": "^10.0.2", | ||
"@ckeditor/ckeditor5-editor-classic": "^11.0.0", | ||
"eslint": "^4.15.0", | ||
"@ckeditor/ckeditor5-engine": "^11.0.0", | ||
"@ckeditor/ckeditor5-paragraph": "^10.0.3", | ||
"@ckeditor/ckeditor5-editor-classic": "^11.0.1", | ||
"eslint": "^5.5.0", | ||
"eslint-config-ckeditor5": "^1.0.7", | ||
@@ -22,0 +24,0 @@ "husky": "^0.14.3", |
@@ -17,3 +17,3 @@ CKEditor 5 autosave feature | ||
See the [`@ckeditor/ckeditor5-autosave` package](https://docs.ckeditor.com/ckeditor5/latest/api/autosave.html) page in [CKEditor 5 documentation](https://docs.ckeditor.com/ckeditor5/latest/). | ||
See the [`@ckeditor/ckeditor5-autosave` package](https://ckeditor.com/docs/ckeditor5/latest/api/autosave.html) page in [CKEditor 5 documentation](https://ckeditor.com/docs/ckeditor5/latest/). | ||
@@ -20,0 +20,0 @@ ## License |
@@ -13,3 +13,5 @@ /** | ||
import DomEmitterMixin from '@ckeditor/ckeditor5-utils/src/dom/emittermixin'; | ||
import throttle from './throttle'; | ||
import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin'; | ||
import mix from '@ckeditor/ckeditor5-utils/src/mix'; | ||
import { debounce } from 'lodash-es'; | ||
@@ -19,3 +21,3 @@ /* globals window */ | ||
/** | ||
* The {@link module:autosave/autosave~Autosave} allows you to automatically save the data (e.g. send it to the server) | ||
* The {@link module:autosave/autosave~Autosave} plugin allows you to automatically save the data (e.g. send it to the server) | ||
* when needed (when the user changed the content). | ||
@@ -43,4 +45,6 @@ * | ||
* | ||
* Read more about this feature in the {@glink builds/guides/integration/saving-data#the-autosave-feature Autosave feature} | ||
* Read more about this feature in the {@glink builds/guides/integration/saving-data#autosave-feature Autosave feature} | ||
* section of the {@glink builds/guides/integration/saving-data Saving and getting data}. | ||
* | ||
* @extends module:core/plugin~Plugin | ||
*/ | ||
@@ -68,2 +72,8 @@ export default class Autosave extends Plugin { | ||
const config = editor.config.get( 'autosave' ) || {}; | ||
// A minimum amount of time that needs to pass after the last action. | ||
// After that time the provided save callbacks are being called. | ||
const waitingTime = config.waitingTime || 1000; | ||
/** | ||
@@ -78,8 +88,22 @@ * The adapter is an object with a `save()` method. That method will be called whenever | ||
/** | ||
* Throttled save method. | ||
* The state of this plugin. | ||
* | ||
* @protected | ||
* The plugin can be in the following states: | ||
* | ||
* * synchronized - when all changes are saved | ||
* * waiting - when the plugin is waiting for other changes before calling `adapter#save()` and `config.autosave.save()` | ||
* * saving - when the provided save method is called and the plugin waits for the response | ||
* | ||
* @member {'synchronized'|'waiting'|'saving'} #state | ||
*/ | ||
this.set( 'state', 'synchronized' ); | ||
/** | ||
* Debounced save method. The `save` method is called the specified `waitingTime` after the `debouncedSave` is called, | ||
* unless new action happens in the meantime. | ||
* | ||
* @private | ||
* @type {Function} | ||
*/ | ||
this._throttledSave = throttle( this._save.bind( this ), 1000 ); | ||
this._debouncedSave = debounce( this._save.bind( this ), waitingTime ); | ||
@@ -89,3 +113,3 @@ /** | ||
* | ||
* @protected | ||
* @private | ||
* @type {Number} | ||
@@ -104,8 +128,8 @@ */ | ||
/** | ||
* Save action counter monitors number of actions. | ||
* The config of this plugins. | ||
* | ||
* @private | ||
* @type {Number} | ||
* @type {Object} | ||
*/ | ||
this._saveActionCounter = 0; | ||
this._config = config; | ||
@@ -120,10 +144,2 @@ /** | ||
/** | ||
* Plugins' config. | ||
* | ||
* @private | ||
* @type {Object} | ||
*/ | ||
this._config = editor.config.get( 'autosave' ) || {}; | ||
/** | ||
* Editor's pending actions manager. | ||
@@ -142,2 +158,3 @@ * | ||
const doc = editor.model.document; | ||
const t = editor.t; | ||
@@ -147,9 +164,20 @@ this._pendingActions = editor.plugins.get( PendingActions ); | ||
this.listenTo( doc, 'change:data', () => { | ||
this._incrementCounter(); | ||
if ( !this._saveCallbacks.length ) { | ||
return; | ||
} | ||
const willOriginalFunctionBeCalled = this._throttledSave(); | ||
if ( this.state == 'synchronized' ) { | ||
this._action = this._pendingActions.add( t( 'Saving changes' ) ); | ||
this.state = 'waiting'; | ||
if ( !willOriginalFunctionBeCalled ) { | ||
this._decrementCounter(); | ||
this._debouncedSave(); | ||
} | ||
else if ( this.state == 'waiting' ) { | ||
this._debouncedSave(); | ||
} | ||
// If the plugin is in `saving` state, it will change its state later basing on the `document.version`. | ||
// If the `document.version` will be higher than stored `#_lastDocumentVersion`, then it means, that some `change:data` | ||
// event has fired in the meantime. | ||
} ); | ||
@@ -188,3 +216,3 @@ | ||
_flush() { | ||
this._throttledSave.flush(); | ||
this._debouncedSave.flush(); | ||
} | ||
@@ -202,12 +230,2 @@ | ||
const saveCallbacks = []; | ||
if ( this.adapter && this.adapter.save ) { | ||
saveCallbacks.push( this.adapter.save ); | ||
} | ||
if ( this._config.save ) { | ||
saveCallbacks.push( this._config.save ); | ||
} | ||
// Change may not produce an operation, so the document's version | ||
@@ -217,7 +235,5 @@ // can be the same after that change. | ||
version < this._lastDocumentVersion || | ||
!saveCallbacks.length || | ||
this.editor.state === 'initializing' | ||
) { | ||
this._throttledSave.flush(); | ||
this._decrementCounter(); | ||
this._debouncedSave.cancel(); | ||
@@ -229,11 +245,19 @@ return; | ||
// Wait one promise cycle to be sure that: | ||
// 1. The save method is always asynchronous. | ||
// 2. Save callbacks are not called inside conversions or while editor's state changes. | ||
this.state = 'saving'; | ||
// Wait one promise cycle to be sure that save callbacks are not called | ||
// inside a conversion or when the editor's state changes. | ||
Promise.resolve() | ||
.then( () => Promise.all( | ||
saveCallbacks.map( cb => cb( this.editor ) ) | ||
this._saveCallbacks.map( cb => cb( this.editor ) ) | ||
) ) | ||
.then( () => { | ||
this._decrementCounter(); | ||
if ( this.editor.model.document.version > this._lastDocumentVersion ) { | ||
this.state = 'waiting'; | ||
this._debouncedSave(); | ||
} else { | ||
this.state = 'synchronized'; | ||
this._pendingActions.remove( this._action ); | ||
this._action = null; | ||
} | ||
} ); | ||
@@ -243,36 +267,28 @@ } | ||
/** | ||
* Increments counter and adds pending action if it not exists. | ||
* Save callbacks. | ||
* | ||
* @private | ||
* @type {Array.<Function>} | ||
*/ | ||
_incrementCounter() { | ||
const t = this.editor.t; | ||
get _saveCallbacks() { | ||
const saveCallbacks = []; | ||
this._saveActionCounter++; | ||
if ( this.adapter && this.adapter.save ) { | ||
saveCallbacks.push( this.adapter.save ); | ||
} | ||
if ( !this._action ) { | ||
this._action = this._pendingActions.add( t( 'Saving changes' ) ); | ||
if ( this._config.save ) { | ||
saveCallbacks.push( this._config.save ); | ||
} | ||
} | ||
/** | ||
* Decrements counter and removes pending action if counter is empty, | ||
* which means, that no new save action occurred. | ||
* | ||
* @private | ||
*/ | ||
_decrementCounter() { | ||
this._saveActionCounter--; | ||
if ( this._saveActionCounter === 0 ) { | ||
this._pendingActions.remove( this._action ); | ||
this._action = null; | ||
} | ||
return saveCallbacks; | ||
} | ||
} | ||
mix( Autosave, ObservableMixin ); | ||
/** | ||
* An interface that requires the `save()` method. | ||
* | ||
* Used by {module:autosave/autosave~Autosave#adapter} | ||
* Used by {@link module:autosave/autosave~Autosave#adapter} | ||
* | ||
@@ -342,1 +358,20 @@ * @interface module:autosave/autosave~AutosaveAdapter | ||
*/ | ||
/** | ||
* The minimum amount of time that need to pass after last action to call the provided callback. | ||
* | ||
* ClassicEditor | ||
* .create( editorElement, { | ||
* autosave: { | ||
* save( editor ) { | ||
* return saveData( editor.getData() ); | ||
* }, | ||
* waitingTime: 2000 | ||
* } | ||
* } ); | ||
* .then( ... ) | ||
* .catch( ... ); | ||
* | ||
* @property module:autosave/autosave~AutosaveConfig#waitingTime | ||
* @type {Number} | ||
*/ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
26031
34
3
319
+ Addedlodash-es@^4.17.10
- Removed@ckeditor/ckeditor5-utils@10.2.1(transitive)