PageSourceSearch

https://novinlib.com/assets/admincp/tinymce/plugins/autosave/plugin.js

js novinlib.com collected 2026-09-24 13:15:01 UTC 7,474 bytes, 230 lines download raw bytes

1/**
2 * Copyright (c) Tiny Technologies, Inc. All rights reserved.
3 * Licensed under the LGPL or a commercial license.
4 * For LGPL see License.txt in the project root for license information.
5 * For commercial licenses see https://www.tiny.cloud/
6 *
7 * Version: 5.0.15 (2019-09-02)
8 */
9(function (domGlobals) {
10    'use strict';
11
12    var Cell = function (initial) {
13      var value = initial;
14      var get = function () {
15        return value;
16      };
17      var set = function (v) {
18        value = v;
19      };
20      var clone = function () {
21        return Cell(get());
22      };
23      return {
24        get: get,
25        set: set,
26        clone: clone
27      };
28    };
29
30    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
31
32    var global$1 = tinymce.util.Tools.resolve('tinymce.util.Delay');
33
34    var global$2 = tinymce.util.Tools.resolve('tinymce.util.LocalStorage');
35
36    var global$3 = tinymce.util.Tools.resolve('tinymce.util.Tools');
37
38    var fireRestoreDraft = function (editor) {
39      return editor.fire('RestoreDraft');
40    };
41    var fireStoreDraft = function (editor) {
42      return editor.fire('StoreDraft');
43    };
44    var fireRemoveDraft = function (editor) {
45      return editor.fire('RemoveDraft');
46    };
47
48    var parse = function (timeString, defaultTime) {
49      var multiples = {
50        s: 1000,
51        m: 60000
52      };
53      var toParse = timeString || defaultTime;
54      var parsedTime = /^(\d+)([ms]?)$/.exec('' + toParse);
55      return (parsedTime[2] ? multiples[parsedTime[2]] : 1) * parseInt(toParse, 10);
56    };
57
58    var shouldAskBeforeUnload = function (editor) {
59      return editor.getParam('autosave_ask_before_unload', true);
60    };
61    var getAutoSavePrefix = function (editor) {
62      var prefix = editor.getParam('autosave_prefix', 'tinymce-autosave-{path}{query}{hash}-{id}-');
63      prefix = prefix.replace(/\{path\}/g, domGlobals.document.location.pathname);
64      prefix = prefix.replace(/\{query\}/g, domGlobals.document.location.search);
65      prefix = prefix.replace(/\{hash\}/g, domGlobals.document.location.hash);
66      prefix = prefix.replace(/\{id\}/g, editor.id);
67      return prefix;
68    };
69    var shouldRestoreWhenEmpty = function (editor) {
70      return editor.getParam('autosave_restore_when_empty', false);
71    };
72    var getAutoSaveInterval = function (editor) {
73      return parse(editor.settings.autosave_interval, '30s');
74    };
75    var getAutoSaveRetention = function (editor) {
76      return parse(editor.settings.autosave_retention, '20m');
77    };
78
79    var isEmpty = function (editor, html) {
80      var forcedRootBlockName = editor.settings.forced_root_block;
81      html = global$3.trim(typeof html === 'undefined' ? editor.getBody().innerHTML : html);
82      return html === '' || new RegExp('^<' + forcedRootBlockName + '[^>]*>((\xA0|&nbsp;|[ \t]|<br[^>]*>)+?|)</' + forcedRootBlockName + '>|<br>$', 'i').test(html);
83    };
84    var hasDraft = function (editor) {
85      var time = parseInt(global$2.getItem(getAutoSavePrefix(editor) + 'time'), 10) || 0;
86      if (new Date().getTime() - time > getAutoSaveRetention(editor)) {
87        removeDraft(editor, false);
88        return false;
89      }
90      return true;
91    };
92    var removeDraft = function (editor, fire) {
93      var prefix = getAutoSavePrefix(editor);
94      global$2.removeItem(prefix + 'draft');
95      global$2.removeItem(prefix + 'time');
96      if (fire !== false) {
97        fireRemoveDraft(editor);
98      }
99    };
100    var storeDraft = function (editor) {
101      var prefix = getAutoSavePrefix(editor);
102      if (!isEmpty(editor) && editor.isDirty()) {
103        global$2.setItem(prefix + 'draft', editor.getContent({
104          format: 'raw',
105          no_events: true
106        }));
107        global$2.setItem(prefix + 'time', new Date().getTime().toString());
108        fireStoreDraft(editor);
109      }
110    };
111    var restoreDraft = function (editor) {
112      var prefix = getAutoSavePrefix(editor);
113      if (hasDraft(editor)) {
114        editor.setContent(global$2.getItem(prefix + 'draft'), { format: 'raw' });
115        fireRestoreDraft(editor);
116      }
117    };
118    var startStoreDraft = function (editor, started) {
119      var interval = getAutoSaveInterval(editor);
120      if (!started.get()) {
121        global$1.setInterval(function () {
122          if (!editor.removed) {
123            storeDraft(editor);
124          }
125        }, interval);
126        started.set(true);
127      }
128    };
129    var restoreLastDraft = function (editor) {
130      editor.undoManager.transact(function () {
131        restoreDraft(editor);
132        removeDraft(editor);
133      });
134      editor.focus();
135    };
136
137    function curry(fn) {
138      var initialArgs = [];
139      for (var _i = 1; _i < arguments.length; _i++) {
140        initialArgs[_i - 1] = arguments[_i];
141      }
142      return function () {
143        var restArgs = [];
144        for (var _i = 0; _i < arguments.length; _i++) {
145          restArgs[_i] = arguments[_i];
146        }
147        var all = initialArgs.concat(restArgs);
148        return fn.apply(null, all);
149      };
150    }
151
152    var get = function (editor) {
153      return {
154        hasDraft: curry(hasDraft, editor),
155        storeDraft: curry(storeDraft, editor),
156        restoreDraft: curry(restoreDraft, editor),
157        removeDraft: curry(removeDraft, editor),
158        isEmpty: curry(isEmpty, editor)
159      };
160    };
161
162    var global$4 = tinymce.util.Tools.resolve('tinymce.EditorManager');
163
164    var setup = function (editor) {
165      editor.editorManager.on('BeforeUnload', function (e) {
166        var msg;
167        global$3.each(global$4.get(), function (editor) {
168          if (editor.plugins.autosave) {
169            editor.plugins.autosave.storeDraft();
170          }
171          if (!msg && editor.isDirty() && shouldAskBeforeUnload(editor)) {
172            msg = editor.translate('You have unsaved changes are you sure you want to navigate away?');
173          }
174        });
175        if (msg) {
176          e.preventDefault();
177          e.returnValue = msg;
178        }
179      });
180    };
181
182    var makeSetupHandler = function (editor, started) {
183      return function (api) {
184        api.setDisabled(!hasDraft(editor));
185        var editorEventCallback = function () {
186          return api.setDisabled(!hasDraft(editor));
187        };
188        editor.on('StoreDraft RestoreDraft RemoveDraft', editorEventCallback);
189        return function () {
190          return editor.off('StoreDraft RestoreDraft RemoveDraft', editorEventCallback);
191        };
192      };
193    };
194    var register = function (editor, started) {
195      startStoreDraft(editor, started);
196      editor.ui.registry.addButton('restoredraft', {
197        tooltip: 'Restore last draft',
198        icon: 'restore-draft',
199        onAction: function () {
200          restoreLastDraft(editor);
201        },
202        onSetup: makeSetupHandler(editor)
203      });
204      editor.ui.registry.addMenuItem('restoredraft', {
205        text: 'Restore last draft',
206        icon: 'restore-draft',
207        onAction: function () {
208          restoreLastDraft(editor);
209        },
210        onSetup: makeSetupHandler(editor)
211      });
212    };
213
214    function Plugin () {
215      global.add('autosave', function (editor) {
216        var started = Cell(false);
217        setup(editor);
218        register(editor, started);
219        editor.on('init', function () {
220          if (shouldRestoreWhenEmpty(editor) && editor.dom.isEmpty(editor.getBody())) {
221            restoreDraft(editor);
222          }
223        });
224        return get(editor);
225      });
226    }
227
228    Plugin();
229
230}(window));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.