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| |[ \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.