@ckeditor/ckeditor5-autosave 29.2.0 → 32.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE.md +2 -2
- package/build/autosave.js +3 -3
- package/build/translations/bs.js +1 -0
- package/lang/translations/af.po +1 -1
- package/lang/translations/ar.po +1 -1
- package/lang/translations/az.po +1 -1
- package/lang/translations/bs.po +21 -0
- package/lang/translations/cs.po +1 -1
- package/lang/translations/da.po +1 -1
- package/lang/translations/de-ch.po +1 -1
- package/lang/translations/de.po +1 -1
- package/lang/translations/en-au.po +1 -1
- package/lang/translations/en-gb.po +1 -1
- package/lang/translations/en.po +1 -1
- package/lang/translations/es.po +1 -1
- package/lang/translations/et.po +1 -1
- package/lang/translations/fa.po +1 -1
- package/lang/translations/fi.po +1 -1
- package/lang/translations/fr.po +1 -1
- package/lang/translations/gl.po +1 -1
- package/lang/translations/he.po +1 -1
- package/lang/translations/hi.po +1 -1
- package/lang/translations/hr.po +1 -1
- package/lang/translations/hu.po +1 -1
- package/lang/translations/id.po +1 -1
- package/lang/translations/it.po +1 -1
- package/lang/translations/ja.po +1 -1
- package/lang/translations/km.po +1 -1
- package/lang/translations/ko.po +1 -1
- package/lang/translations/ku.po +1 -1
- package/lang/translations/lt.po +1 -1
- package/lang/translations/lv.po +1 -1
- package/lang/translations/ne.po +1 -1
- package/lang/translations/nl.po +1 -1
- package/lang/translations/no.po +1 -1
- package/lang/translations/pl.po +1 -1
- package/lang/translations/pt-br.po +1 -1
- package/lang/translations/ro.po +1 -1
- package/lang/translations/ru.po +1 -1
- package/lang/translations/sk.po +1 -1
- package/lang/translations/sl.po +1 -1
- package/lang/translations/sq.po +1 -1
- package/lang/translations/sr-latn.po +1 -1
- package/lang/translations/sr.po +1 -1
- package/lang/translations/sv.po +1 -1
- package/lang/translations/th.po +1 -1
- package/lang/translations/tk.po +1 -1
- package/lang/translations/tr.po +1 -1
- package/lang/translations/ug.po +1 -1
- package/lang/translations/uk.po +1 -1
- package/lang/translations/vi.po +1 -1
- package/lang/translations/zh-cn.po +1 -1
- package/lang/translations/zh.po +1 -1
- package/package.json +11 -10
- package/src/autosave.js +109 -33
- package/src/index.js +1 -1
- package/CHANGELOG.md +0 -107
package/LICENSE.md
CHANGED
@@ -2,7 +2,7 @@ Software License Agreement
|
|
2
2
|
==========================
|
3
3
|
|
4
4
|
**CKEditor 5 autosave feature** – https://github.com/ckeditor/ckeditor5-autosave <br>
|
5
|
-
Copyright (c) 2003-
|
5
|
+
Copyright (c) 2003-2022, [CKSource](http://cksource.com) Holding sp. z o.o. All rights reserved.
|
6
6
|
|
7
7
|
Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
|
8
8
|
|
@@ -14,4 +14,4 @@ Where not otherwise indicated, all CKEditor content is authored by CKSource engi
|
|
14
14
|
Trademarks
|
15
15
|
----------
|
16
16
|
|
17
|
-
**CKEditor** is a trademark of [CKSource](http://cksource.com)
|
17
|
+
**CKEditor** is a trademark of [CKSource](http://cksource.com) Holding sp. z o.o. All other brand and product names are trademarks, registered trademarks or service marks of their respective holders.
|
package/build/autosave.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
+
!function(t){const e=t.en=t.en||{};e.dictionary=Object.assign(e.dictionary||{},{"Saving changes":"Saving changes"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={})),
|
1
2
|
/*!
|
2
|
-
* @license Copyright (c) 2003-
|
3
|
+
* @license Copyright (c) 2003-2022, CKSource - Frederico Knabben. All rights reserved.
|
3
4
|
* For licensing, see LICENSE.md.
|
4
|
-
*/
|
5
|
-
!function(t){const e=t.en=t.en||{};e.dictionary=Object.assign(e.dictionary||{},{"Saving changes":"Saving changes"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={})),window.CKEditor5=window.CKEditor5||{},window.CKEditor5.autosave=function(t){var e={};function n(i){if(e[i])return e[i].exports;var r=e[i]={i:i,l:!1,exports:{}};return t[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(i,r,function(e){return t[e]}.bind(null,r));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=5)}([function(t,e,n){t.exports=n(2)("./src/core.js")},function(t,e,n){t.exports=n(2)("./src/utils.js")},function(t,e){t.exports=CKEditor5.dll},function(t,e,n){"use strict";(function(t){var n="object"==typeof t&&t&&t.Object===Object&&t;e.a=n}).call(this,n(4))},function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){"use strict";n.r(e),n.d(e,"Autosave",(function(){return K}));var i=n(0),r=n(1);var o=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)},s=n(3),a="object"==typeof self&&self&&self.Object===Object&&self,u=s.a||a||Function("return this")(),c=function(){return u.Date.now()},d=/\s/;var l=function(t){for(var e=t.length;e--&&d.test(t.charAt(e)););return e},f=/^\s+/;var h=function(t){return t?t.slice(0,l(t)+1).replace(f,""):t},v=u.Symbol,p=Object.prototype,g=p.hasOwnProperty,b=p.toString,m=v?v.toStringTag:void 0;var y=function(t){var e=g.call(t,m),n=t[m];try{t[m]=void 0;var i=!0}catch(t){}var r=b.call(t);return i&&(e?t[m]=n:delete t[m]),r},_=Object.prototype.toString;var j=function(t){return _.call(t)},w=v?v.toStringTag:void 0;var O=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":w&&w in Object(t)?y(t):j(t)};var S=function(t){return null!=t&&"object"==typeof t};var T=function(t){return"symbol"==typeof t||S(t)&&"[object Symbol]"==O(t)},x=/^[-+]0x[0-9a-f]+$/i,A=/^0b[01]+$/i,E=/^0o[0-7]+$/i,P=parseInt;var N=function(t){if("number"==typeof t)return t;if(T(t))return NaN;if(o(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=o(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=h(t);var n=A.test(t);return n||E.test(t)?P(t.slice(2),n?2:8):x.test(t)?NaN:+t},C=Math.max,M=Math.min;var D=function(t,e,n){var i,r,s,a,u,d,l=0,f=!1,h=!1,v=!0;if("function"!=typeof t)throw new TypeError("Expected a function");function p(e){var n=i,o=r;return i=r=void 0,l=e,a=t.apply(o,n)}function g(t){return l=t,u=setTimeout(m,e),f?p(t):a}function b(t){var n=t-d;return void 0===d||n>=e||n<0||h&&t-l>=s}function m(){var t=c();if(b(t))return y(t);u=setTimeout(m,function(t){var n=e-(t-d);return h?M(n,s-(t-l)):n}(t))}function y(t){return u=void 0,v&&i?p(t):(i=r=void 0,a)}function _(){var t=c(),n=b(t);if(i=arguments,r=this,d=t,n){if(void 0===u)return g(d);if(h)return clearTimeout(u),u=setTimeout(m,e),p(d)}return void 0===u&&(u=setTimeout(m,e)),a}return e=N(e)||0,o(n)&&(f=!!n.leading,s=(h="maxWait"in n)?C(N(n.maxWait)||0,e):s,v="trailing"in n?!!n.trailing:v),_.cancel=function(){void 0!==u&&clearTimeout(u),l=0,i=d=r=u=void 0},_.flush=function(){return void 0===u?a:y(c())},_};class K extends i.Plugin{static get pluginName(){return"Autosave"}static get requires(){return[i.PendingActions]}constructor(t){super(t);const e=t.config.get("autosave")||{},n=e.waitingTime||1e3;this.set("state","synchronized"),this._debouncedSave=D(this._save.bind(this),n),this._lastDocumentVersion=t.model.document.version,this._domEmitter=Object.create(r.DomEmitterMixin),this._config=e}init(){const t=this.editor,e=t.model.document,n=t.t;this._pendingActions=t.plugins.get(i.PendingActions),this.listenTo(t,"ready",()=>{this.listenTo(e,"change:data",()=>{this._saveCallbacks.length&&("synchronized"==this.state?(this._action=this._pendingActions.add(n("Saving changes")),this.state="waiting",this._debouncedSave()):"waiting"==this.state&&this._debouncedSave())})}),this.listenTo(t,"destroy",()=>this._flush(),{priority:"highest"}),this._domEmitter.listenTo(window,"beforeunload",(t,e)=>{this._pendingActions.hasAny&&(e.returnValue=this._pendingActions.first.message)})}destroy(){this._domEmitter.stopListening(),super.destroy()}save(){this._debouncedSave.cancel(),this._save()}_flush(){this._debouncedSave.flush()}_save(){this.state="saving",this._lastDocumentVersion=this.editor.model.document.version,Promise.resolve().then(()=>Promise.all(this._saveCallbacks.map(t=>t(this.editor)))).catch(t=>{throw this.state="error",this.state="saving",this._debouncedSave(),t}).then(()=>{this.editor.model.document.version>this._lastDocumentVersion?(this.state="waiting",this._debouncedSave()):(this.state="synchronized",this._pendingActions.remove(this._action),this._action=null)})}get _saveCallbacks(){const t=[];return this.adapter&&this.adapter.save&&t.push(this.adapter.save),this._config.save&&t.push(this._config.save),t}}Object(r.mix)(K,r.ObservableMixin)}]);
|
5
|
+
*/(()=>{var t={704:(t,e,i)=>{t.exports=i(79)("./src/core.js")},209:(t,e,i)=>{t.exports=i(79)("./src/utils.js")},79:t=>{"use strict";t.exports=CKEditor5.dll}},e={};function i(n){var s=e[n];if(void 0!==s)return s.exports;var o=e[n]={exports:{}};return t[n](o,o.exports,i),o.exports}i.d=(t,e)=>{for(var n in e)i.o(e,n)&&!i.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var n={};(()=>{"use strict";i.r(n),i.d(n,{Autosave:()=>D});var t=i(704),e=i(209);const s=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)};const o="object"==typeof global&&global&&global.Object===Object&&global;var r="object"==typeof self&&self&&self.Object===Object&&self;const a=o||r||Function("return this")();const c=function(){return a.Date.now()};var u=/\s/;const d=function(t){for(var e=t.length;e--&&u.test(t.charAt(e)););return e};var l=/^\s+/;const h=function(t){return t?t.slice(0,d(t)+1).replace(l,""):t};const v=a.Symbol;var f=Object.prototype,m=f.hasOwnProperty,g=f.toString,p=v?v.toStringTag:void 0;const _=function(t){var e=m.call(t,p),i=t[p];try{t[p]=void 0;var n=!0}catch(t){}var s=g.call(t);return n&&(e?t[p]=i:delete t[p]),s};var b=Object.prototype.toString;const y=function(t){return b.call(t)};var S=v?v.toStringTag:void 0;const j=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":S&&S in Object(t)?_(t):y(t)};const O=function(t){return null!=t&&"object"==typeof t};const T=function(t){return"symbol"==typeof t||O(t)&&"[object Symbol]"==j(t)};var w=/^[-+]0x[0-9a-f]+$/i,P=/^0b[01]+$/i,A=/^0o[0-7]+$/i,x=parseInt;const E=function(t){if("number"==typeof t)return t;if(T(t))return NaN;if(s(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=s(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=h(t);var i=P.test(t);return i||A.test(t)?x(t.slice(2),i?2:8):w.test(t)?NaN:+t};var N=Math.max,I=Math.min;const C=function(t,e,i){var n,o,r,a,u,d,l=0,h=!1,v=!1,f=!0;if("function"!=typeof t)throw new TypeError("Expected a function");function m(e){var i=n,s=o;return n=o=void 0,l=e,a=t.apply(s,i)}function g(t){return l=t,u=setTimeout(_,e),h?m(t):a}function p(t){var i=t-d;return void 0===d||i>=e||i<0||v&&t-l>=r}function _(){var t=c();if(p(t))return b(t);u=setTimeout(_,function(t){var i=e-(t-d);return v?I(i,r-(t-l)):i}(t))}function b(t){return u=void 0,f&&n?m(t):(n=o=void 0,a)}function y(){var t=c(),i=p(t);if(n=arguments,o=this,d=t,i){if(void 0===u)return g(d);if(v)return clearTimeout(u),u=setTimeout(_,e),m(d)}return void 0===u&&(u=setTimeout(_,e)),a}return e=E(e)||0,s(i)&&(h=!!i.leading,r=(v="maxWait"in i)?N(E(i.maxWait)||0,e):r,f="trailing"in i?!!i.trailing:f),y.cancel=function(){void 0!==u&&clearTimeout(u),l=0,n=d=o=u=void 0},y.flush=function(){return void 0===u?a:b(c())},y};class D extends t.Plugin{static get pluginName(){return"Autosave"}static get requires(){return[t.PendingActions]}constructor(i){super(i);const n=i.config.get("autosave")||{},s=n.waitingTime||1e3;this.set("state","synchronized"),this._debouncedSave=C(this._save.bind(this),s),this._lastDocumentVersion=i.model.document.version,this._savePromise=null,this._domEmitter=Object.create(e.DomEmitterMixin),this._config=n,this._pendingActions=i.plugins.get(t.PendingActions),this._makeImmediateSave=!1}init(){const t=this.editor,e=t.model.document;this.listenTo(t,"ready",(()=>{this.listenTo(e,"change:data",((t,e)=>{this._saveCallbacks.length&&e.isLocal&&("synchronized"===this.state&&(this.state="waiting",this._setPendingAction()),"waiting"===this.state&&this._debouncedSave())}))})),this.listenTo(t,"destroy",(()=>this._flush()),{priority:"highest"}),this._domEmitter.listenTo(window,"beforeunload",((t,e)=>{this._pendingActions.hasAny&&(e.returnValue=this._pendingActions.first.message)}))}destroy(){this._domEmitter.stopListening(),super.destroy()}save(){return this._debouncedSave.cancel(),this._save()}_flush(){this._debouncedSave.flush()}_save(){return this._savePromise?(this._makeImmediateSave=this.editor.model.document.version>this._lastDocumentVersion,this._savePromise):(this._setPendingAction(),this.state="saving",this._lastDocumentVersion=this.editor.model.document.version,this._savePromise=Promise.resolve().then((()=>Promise.all(this._saveCallbacks.map((t=>t(this.editor)))))).finally((()=>{this._savePromise=null})).then((()=>{if(this._makeImmediateSave)return this._makeImmediateSave=!1,this._save();this.editor.model.document.version>this._lastDocumentVersion?(this.state="waiting",this._debouncedSave()):(this.state="synchronized",this._pendingActions.remove(this._action),this._action=null)})).catch((t=>{throw this.state="error",this.state="saving",this._debouncedSave(),t})),this._savePromise)}_setPendingAction(){const t=this.editor.t;this._action||(this._action=this._pendingActions.add(t("Saving changes")))}get _saveCallbacks(){const t=[];return this.adapter&&this.adapter.save&&t.push(this.adapter.save),this._config.save&&t.push(this._config.save),t}}(0,e.mix)(D,e.ObservableMixin)})(),(window.CKEditor5=window.CKEditor5||{}).autosave=n})();
|
@@ -0,0 +1 @@
|
|
1
|
+
!function(n){const i=n.bs=n.bs||{};i.dictionary=Object.assign(i.dictionary||{},{"Saving changes":"Spremanje izmjena"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
package/lang/translations/af.po
CHANGED
package/lang/translations/ar.po
CHANGED
package/lang/translations/az.po
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
2
|
+
#
|
3
|
+
# !!! IMPORTANT !!!
|
4
|
+
#
|
5
|
+
# Before you edit this file, please keep in mind that contributing to the project
|
6
|
+
# translations is possible ONLY via the Transifex online service.
|
7
|
+
#
|
8
|
+
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
|
9
|
+
#
|
10
|
+
# To learn more, check out the official contributor's guide:
|
11
|
+
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
|
12
|
+
#
|
13
|
+
msgid ""
|
14
|
+
msgstr ""
|
15
|
+
"Language-Team: Bosnian (https://www.transifex.com/ckeditor/teams/11143/bs/)\n"
|
16
|
+
"Language: bs\n"
|
17
|
+
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
18
|
+
|
19
|
+
msgctxt "A message that the data is being saved."
|
20
|
+
msgid "Saving changes"
|
21
|
+
msgstr "Spremanje izmjena"
|
package/lang/translations/cs.po
CHANGED
package/lang/translations/da.po
CHANGED
package/lang/translations/de.po
CHANGED
package/lang/translations/en.po
CHANGED
package/lang/translations/es.po
CHANGED
package/lang/translations/et.po
CHANGED
package/lang/translations/fa.po
CHANGED
package/lang/translations/fi.po
CHANGED
package/lang/translations/fr.po
CHANGED
package/lang/translations/gl.po
CHANGED
package/lang/translations/he.po
CHANGED
package/lang/translations/hi.po
CHANGED
package/lang/translations/hr.po
CHANGED
package/lang/translations/hu.po
CHANGED
package/lang/translations/id.po
CHANGED
package/lang/translations/it.po
CHANGED
package/lang/translations/ja.po
CHANGED
package/lang/translations/km.po
CHANGED
package/lang/translations/ko.po
CHANGED
package/lang/translations/ku.po
CHANGED
package/lang/translations/lt.po
CHANGED
package/lang/translations/lv.po
CHANGED
package/lang/translations/ne.po
CHANGED
package/lang/translations/nl.po
CHANGED
package/lang/translations/no.po
CHANGED
package/lang/translations/pl.po
CHANGED
package/lang/translations/ro.po
CHANGED
package/lang/translations/ru.po
CHANGED
package/lang/translations/sk.po
CHANGED
package/lang/translations/sl.po
CHANGED
package/lang/translations/sq.po
CHANGED
package/lang/translations/sr.po
CHANGED
package/lang/translations/sv.po
CHANGED
package/lang/translations/th.po
CHANGED
package/lang/translations/tk.po
CHANGED
package/lang/translations/tr.po
CHANGED
package/lang/translations/ug.po
CHANGED
package/lang/translations/uk.po
CHANGED
package/lang/translations/vi.po
CHANGED
package/lang/translations/zh.po
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ckeditor/ckeditor5-autosave",
|
3
|
-
"version": "
|
3
|
+
"version": "32.0.0",
|
4
4
|
"description": "Autosave feature for CKEditor 5.",
|
5
5
|
"keywords": [
|
6
6
|
"ckeditor",
|
@@ -12,20 +12,21 @@
|
|
12
12
|
],
|
13
13
|
"main": "src/index.js",
|
14
14
|
"dependencies": {
|
15
|
-
"ckeditor5": "^
|
15
|
+
"ckeditor5": "^32.0.0",
|
16
16
|
"lodash-es": "^4.17.15"
|
17
17
|
},
|
18
18
|
"devDependencies": {
|
19
|
-
"@ckeditor/ckeditor5-core": "^
|
20
|
-
"@ckeditor/ckeditor5-dev-utils": "^
|
21
|
-
"@ckeditor/ckeditor5-editor-classic": "^
|
22
|
-
"@ckeditor/ckeditor5-paragraph": "^
|
23
|
-
"@ckeditor/ckeditor5-
|
24
|
-
"
|
25
|
-
"webpack
|
19
|
+
"@ckeditor/ckeditor5-core": "^32.0.0",
|
20
|
+
"@ckeditor/ckeditor5-dev-utils": "^27.1.0",
|
21
|
+
"@ckeditor/ckeditor5-editor-classic": "^32.0.0",
|
22
|
+
"@ckeditor/ckeditor5-paragraph": "^32.0.0",
|
23
|
+
"@ckeditor/ckeditor5-source-editing": "^32.0.0",
|
24
|
+
"@ckeditor/ckeditor5-theme-lark": "^32.0.0",
|
25
|
+
"webpack": "^5.58.1",
|
26
|
+
"webpack-cli": "^4.9.0"
|
26
27
|
},
|
27
28
|
"engines": {
|
28
|
-
"node": ">=
|
29
|
+
"node": ">=14.0.0",
|
29
30
|
"npm": ">=5.7.1"
|
30
31
|
},
|
31
32
|
"author": "CKSource (http://cksource.com/)",
|
package/src/autosave.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Copyright (c) 2003-
|
2
|
+
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4
4
|
*/
|
5
5
|
|
@@ -88,6 +88,7 @@ export default class Autosave extends Plugin {
|
|
88
88
|
* * error &ndash When the provided save method will throw an error. This state immediately changes to the `saving` state and
|
89
89
|
* the save method will be called again in the short period of time.
|
90
90
|
*
|
91
|
+
* @readonly
|
91
92
|
* @member {'synchronized'|'waiting'|'saving'} #state
|
92
93
|
*/
|
93
94
|
this.set( 'state', 'synchronized' );
|
@@ -109,6 +110,17 @@ export default class Autosave extends Plugin {
|
|
109
110
|
*/
|
110
111
|
this._lastDocumentVersion = editor.model.document.version;
|
111
112
|
|
113
|
+
/**
|
114
|
+
* Promise used for asynchronous save calls.
|
115
|
+
*
|
116
|
+
* Created to handle the autosave call to an external data source. It resolves when that call is finished. It is re-used if
|
117
|
+
* save is called before the promise has resolved. It is set to `null` if there is no call in progress.
|
118
|
+
*
|
119
|
+
* @type {Promise|null}
|
120
|
+
* @private
|
121
|
+
*/
|
122
|
+
this._savePromise = null;
|
123
|
+
|
112
124
|
/**
|
113
125
|
* DOM emitter.
|
114
126
|
*
|
@@ -126,17 +138,29 @@ export default class Autosave extends Plugin {
|
|
126
138
|
this._config = config;
|
127
139
|
|
128
140
|
/**
|
129
|
-
*
|
141
|
+
* Editor's pending actions manager.
|
130
142
|
*
|
131
143
|
* @private
|
132
|
-
* @member {
|
144
|
+
* @member {module:core/pendingactions~PendingActions} #_pendingActions
|
133
145
|
*/
|
146
|
+
this._pendingActions = editor.plugins.get( PendingActions );
|
134
147
|
|
135
148
|
/**
|
136
|
-
*
|
149
|
+
* Informs whether there should be another autosave callback performed, immediately after current autosave callback finishes.
|
150
|
+
*
|
151
|
+
* This is set to `true` when there's a save request while autosave callback is already being processed and the model has changed
|
152
|
+
* since the last save.
|
137
153
|
*
|
138
154
|
* @private
|
139
|
-
* @
|
155
|
+
* @type {Boolean}
|
156
|
+
*/
|
157
|
+
this._makeImmediateSave = false;
|
158
|
+
|
159
|
+
/**
|
160
|
+
* An action that will be added to pending action manager for actions happening in that plugin.
|
161
|
+
*
|
162
|
+
* @private
|
163
|
+
* @member {Object} #_action
|
140
164
|
*/
|
141
165
|
}
|
142
166
|
|
@@ -146,25 +170,25 @@ export default class Autosave extends Plugin {
|
|
146
170
|
init() {
|
147
171
|
const editor = this.editor;
|
148
172
|
const doc = editor.model.document;
|
149
|
-
const t = editor.t;
|
150
|
-
|
151
|
-
this._pendingActions = editor.plugins.get( PendingActions );
|
152
173
|
|
153
174
|
// Add the listener only after the editor is initialized to prevent firing save callback on data init.
|
154
175
|
this.listenTo( editor, 'ready', () => {
|
155
|
-
this.listenTo( doc, 'change:data', () => {
|
176
|
+
this.listenTo( doc, 'change:data', ( evt, batch ) => {
|
156
177
|
if ( !this._saveCallbacks.length ) {
|
157
178
|
return;
|
158
179
|
}
|
159
180
|
|
160
|
-
if (
|
161
|
-
|
162
|
-
|
181
|
+
if ( !batch.isLocal ) {
|
182
|
+
return;
|
183
|
+
}
|
163
184
|
|
164
|
-
|
185
|
+
if ( this.state === 'synchronized' ) {
|
186
|
+
this.state = 'waiting';
|
187
|
+
// Set pending action already when we are waiting for the autosave callback.
|
188
|
+
this._setPendingAction();
|
165
189
|
}
|
166
190
|
|
167
|
-
|
191
|
+
if ( this.state === 'waiting' ) {
|
168
192
|
this._debouncedSave();
|
169
193
|
}
|
170
194
|
|
@@ -200,11 +224,15 @@ export default class Autosave extends Plugin {
|
|
200
224
|
}
|
201
225
|
|
202
226
|
/**
|
203
|
-
*
|
227
|
+
* Immediately calls autosave callback. All previously queued (debounced) callbacks are cleared. If there is already an autosave
|
228
|
+
* callback in progress, then the requested save will be performed immediately after the current callback finishes.
|
229
|
+
*
|
230
|
+
* @returns {Promise} A promise that will be resolved when the autosave callback is finished.
|
204
231
|
*/
|
205
232
|
save() {
|
206
233
|
this._debouncedSave.cancel();
|
207
|
-
|
234
|
+
|
235
|
+
return this._save();
|
208
236
|
}
|
209
237
|
|
210
238
|
/**
|
@@ -222,39 +250,87 @@ export default class Autosave extends Plugin {
|
|
222
250
|
* It waits for the result and then removes the created pending action.
|
223
251
|
*
|
224
252
|
* @private
|
253
|
+
* @returns {Promise} A promise that will be resolved when the autosave callback is finished.
|
225
254
|
*/
|
226
255
|
_save() {
|
256
|
+
if ( this._savePromise ) {
|
257
|
+
this._makeImmediateSave = this.editor.model.document.version > this._lastDocumentVersion;
|
258
|
+
|
259
|
+
return this._savePromise;
|
260
|
+
}
|
261
|
+
|
262
|
+
// Make sure there is a pending action (in case if `_save()` was called through manual `save()` call).
|
263
|
+
this._setPendingAction();
|
264
|
+
|
227
265
|
this.state = 'saving';
|
228
266
|
this._lastDocumentVersion = this.editor.model.document.version;
|
229
267
|
|
230
|
-
// Wait one promise cycle to be sure that save callbacks are not called
|
231
|
-
|
232
|
-
|
268
|
+
// Wait one promise cycle to be sure that save callbacks are not called inside a conversion or when the editor's state changes.
|
269
|
+
this._savePromise = Promise.resolve()
|
270
|
+
// Make autosave callback.
|
233
271
|
.then( () => Promise.all(
|
234
272
|
this._saveCallbacks.map( cb => cb( this.editor ) )
|
235
273
|
) )
|
236
|
-
//
|
237
|
-
|
238
|
-
|
274
|
+
// When the autosave callback is finished, always clear `this._savePromise`, no matter if it was successful or not.
|
275
|
+
.finally( () => {
|
276
|
+
this._savePromise = null;
|
277
|
+
} )
|
278
|
+
// If the save was successful we have three scenarios:
|
279
|
+
//
|
280
|
+
// 1. If a save was requested when an autosave callback was already processed, we need to immediately call
|
281
|
+
// another autosave callback. In this case, `this._savePromise` won't be resolved until the next callback is done.
|
282
|
+
// 2. Otherwise, if changes happened to the model, make a delayed autosave callback (like the change just happened).
|
283
|
+
// 3. If no changes happened to the model, return to the `synchronized` state.
|
284
|
+
.then( () => {
|
285
|
+
if ( this._makeImmediateSave ) {
|
286
|
+
this._makeImmediateSave = false;
|
287
|
+
|
288
|
+
// Start another autosave callback. Return a promise that will be resolved after the new autosave callback.
|
289
|
+
// This way promises returned by `_save()` won't be resolved until all changes are saved.
|
290
|
+
//
|
291
|
+
// If `save()` was called when another (most often automatic) autosave callback was already processed,
|
292
|
+
// the promise returned by `save()` call will be resolved only after new changes has been saved.
|
293
|
+
//
|
294
|
+
// Note that it would not work correctly if `this._savePromise` is not cleared.
|
295
|
+
return this._save();
|
296
|
+
} else {
|
297
|
+
if ( this.editor.model.document.version > this._lastDocumentVersion ) {
|
298
|
+
this.state = 'waiting';
|
299
|
+
this._debouncedSave();
|
300
|
+
} else {
|
301
|
+
this.state = 'synchronized';
|
302
|
+
this._pendingActions.remove( this._action );
|
303
|
+
this._action = null;
|
304
|
+
}
|
305
|
+
}
|
306
|
+
} )
|
307
|
+
// In case of an error retry the autosave callback after a delay (and also throw the original error).
|
239
308
|
.catch( err => {
|
309
|
+
// Change state to `error` so that listeners handling autosave error can be called.
|
240
310
|
this.state = 'error';
|
241
|
-
//
|
311
|
+
// Then, immediately change to the `saving` state as described above.
|
312
|
+
// Being in the `saving` state ensures that the autosave callback won't be delayed further by the `change:data` listener.
|
242
313
|
this.state = 'saving';
|
243
314
|
|
244
315
|
this._debouncedSave();
|
245
316
|
|
246
317
|
throw err;
|
247
|
-
} )
|
248
|
-
.then( () => {
|
249
|
-
if ( this.editor.model.document.version > this._lastDocumentVersion ) {
|
250
|
-
this.state = 'waiting';
|
251
|
-
this._debouncedSave();
|
252
|
-
} else {
|
253
|
-
this.state = 'synchronized';
|
254
|
-
this._pendingActions.remove( this._action );
|
255
|
-
this._action = null;
|
256
|
-
}
|
257
318
|
} );
|
319
|
+
|
320
|
+
return this._savePromise;
|
321
|
+
}
|
322
|
+
|
323
|
+
/**
|
324
|
+
* Creates a pending action if it is not set already.
|
325
|
+
*
|
326
|
+
* @private
|
327
|
+
*/
|
328
|
+
_setPendingAction() {
|
329
|
+
const t = this.editor.t;
|
330
|
+
|
331
|
+
if ( !this._action ) {
|
332
|
+
this._action = this._pendingActions.add( t( 'Saving changes' ) );
|
333
|
+
}
|
258
334
|
}
|
259
335
|
|
260
336
|
/**
|
package/src/index.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Copyright (c) 2003-
|
2
|
+
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4
4
|
*/
|
5
5
|
|
package/CHANGELOG.md
DELETED
@@ -1,107 +0,0 @@
|
|
1
|
-
Changelog
|
2
|
-
=========
|
3
|
-
|
4
|
-
All changes in the package are documented in the main repository. See: https://github.com/ckeditor/ckeditor5/blob/master/CHANGELOG.md.
|
5
|
-
|
6
|
-
Changes for the past releases are available below.
|
7
|
-
|
8
|
-
## [19.0.0](https://github.com/ckeditor/ckeditor5-autosave/compare/v18.0.0...v19.0.0) (2020-04-29)
|
9
|
-
|
10
|
-
Internal changes only (updated dependencies, documentation, etc.).
|
11
|
-
|
12
|
-
|
13
|
-
## [18.0.0](https://github.com/ckeditor/ckeditor5-autosave/compare/v17.0.0...v18.0.0) (2020-03-19)
|
14
|
-
|
15
|
-
Internal changes only (updated dependencies, documentation, etc.).
|
16
|
-
|
17
|
-
|
18
|
-
## [17.0.0](https://github.com/ckeditor/ckeditor5-autosave/compare/v16.0.0...v17.0.0) (2020-02-18)
|
19
|
-
|
20
|
-
### Other changes
|
21
|
-
|
22
|
-
* Updated translations. ([d0042f4](https://github.com/ckeditor/ckeditor5-autosave/commit/d0042f4))
|
23
|
-
|
24
|
-
|
25
|
-
## [16.0.0](https://github.com/ckeditor/ckeditor5-autosave/compare/v15.0.0...v16.0.0) (2019-12-04)
|
26
|
-
|
27
|
-
### Other changes
|
28
|
-
|
29
|
-
* Updated translations. ([b99249d](https://github.com/ckeditor/ckeditor5-autosave/commit/b99249d))
|
30
|
-
|
31
|
-
|
32
|
-
## [15.0.0](https://github.com/ckeditor/ckeditor5-autosave/compare/v11.0.5...v15.0.0) (2019-10-23)
|
33
|
-
|
34
|
-
### Features
|
35
|
-
|
36
|
-
* Provided error handling for save actions. Closes [ckeditor/ckeditor5#1546](https://github.com/ckeditor/ckeditor5/issues/1546). ([d6079bf](https://github.com/ckeditor/ckeditor5-autosave/commit/d6079bf))
|
37
|
-
|
38
|
-
### Other changes
|
39
|
-
|
40
|
-
* Updated translations. ([115bf18](https://github.com/ckeditor/ckeditor5-autosave/commit/115bf18))
|
41
|
-
|
42
|
-
|
43
|
-
## [11.0.5](https://github.com/ckeditor/ckeditor5-autosave/compare/v11.0.4...v11.0.5) (2019-08-26)
|
44
|
-
|
45
|
-
### Other changes
|
46
|
-
|
47
|
-
* The issue tracker for this package was moved to https://github.com/ckeditor/ckeditor5/issues. See [ckeditor/ckeditor5#1988](https://github.com/ckeditor/ckeditor5/issues/1988). ([0072e70](https://github.com/ckeditor/ckeditor5-autosave/commit/0072e70))
|
48
|
-
* Updated translations. ([2de7f77](https://github.com/ckeditor/ckeditor5-autosave/commit/2de7f77))
|
49
|
-
|
50
|
-
|
51
|
-
## [11.0.4](https://github.com/ckeditor/ckeditor5-autosave/compare/v11.0.3...v11.0.4) (2019-07-10)
|
52
|
-
|
53
|
-
Internal changes only (updated dependencies, documentation, etc.).
|
54
|
-
|
55
|
-
|
56
|
-
## [11.0.3](https://github.com/ckeditor/ckeditor5-autosave/compare/v11.0.2...v11.0.3) (2019-07-04)
|
57
|
-
|
58
|
-
### Other changes
|
59
|
-
|
60
|
-
* Updated translations. ([28230c2](https://github.com/ckeditor/ckeditor5-autosave/commit/28230c2)) ([3a16129](https://github.com/ckeditor/ckeditor5-autosave/commit/3a16129))
|
61
|
-
|
62
|
-
|
63
|
-
## [11.0.2](https://github.com/ckeditor/ckeditor5-autosave/compare/v11.0.1...v11.0.2) (2019-06-05)
|
64
|
-
|
65
|
-
### Other changes
|
66
|
-
|
67
|
-
* Updated translations. ([5541f00](https://github.com/ckeditor/ckeditor5-autosave/commit/5541f00))
|
68
|
-
|
69
|
-
|
70
|
-
## [11.0.1](https://github.com/ckeditor/ckeditor5-autosave/compare/v11.0.0...v11.0.1) (2019-04-10)
|
71
|
-
|
72
|
-
### Other changes
|
73
|
-
|
74
|
-
* Updated translations. ([e38aed3](https://github.com/ckeditor/ckeditor5-autosave/commit/e38aed3))
|
75
|
-
|
76
|
-
|
77
|
-
## [11.0.0](https://github.com/ckeditor/ckeditor5-autosave/compare/v10.0.2...v11.0.0) (2019-02-28)
|
78
|
-
|
79
|
-
### Other changes
|
80
|
-
|
81
|
-
* Updated translations. ([436d064](https://github.com/ckeditor/ckeditor5-autosave/commit/436d064)) ([b24b0aa](https://github.com/ckeditor/ckeditor5-autosave/commit/b24b0aa))
|
82
|
-
|
83
|
-
### BREAKING CHANGES
|
84
|
-
|
85
|
-
* Upgraded minimal versions of Node to `8.0.0` and npm to `5.7.1`. See: [ckeditor/ckeditor5#1507](https://github.com/ckeditor/ckeditor5/issues/1507). ([612ea3c](https://github.com/ckeditor/ckeditor5-cloud-services/commit/612ea3c))
|
86
|
-
|
87
|
-
|
88
|
-
## [10.0.2](https://github.com/ckeditor/ckeditor5-autosave/compare/v10.0.1...v10.0.2) (2018-12-05)
|
89
|
-
|
90
|
-
### Other changes
|
91
|
-
|
92
|
-
* Updated translations. ([5a423f6](https://github.com/ckeditor/ckeditor5-autosave/commit/5a423f6)) ([c5bb743](https://github.com/ckeditor/ckeditor5-autosave/commit/c5bb743))
|
93
|
-
|
94
|
-
|
95
|
-
## [10.0.1](https://github.com/ckeditor/ckeditor5-autosave/compare/v10.0.0...v10.0.1) (2018-10-08)
|
96
|
-
|
97
|
-
### Other changes
|
98
|
-
|
99
|
-
* 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))
|
100
|
-
* Updated translations. ([3f52ebc](https://github.com/ckeditor/ckeditor5-autosave/commit/3f52ebc)) ([8c702ee](https://github.com/ckeditor/ckeditor5-autosave/commit/8c702ee))
|
101
|
-
|
102
|
-
|
103
|
-
## [10.0.0](https://github.com/ckeditor/ckeditor5-autosave/tree/v10.0.0) (2018-07-18)
|
104
|
-
|
105
|
-
### Other changes
|
106
|
-
|
107
|
-
* 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).
|