plugin.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /**
  2. * @license Copyright (c) CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.html or http://ckeditor.com/license
  4. */
  5. (function() {
  6. if (!supportsLocalStorage()) {
  7. CKEDITOR.plugins.add("autosave", {}); //register a dummy plugin to pass CKEditor plugin initialization process
  8. return;
  9. }
  10. CKEDITOR.plugins.add("autosave", {
  11. lang: 'ca,cs,de,en,es,fr,ja,pl,pt-br,sv,zh,zh-cn', // %REMOVE_LINE_CORE%
  12. requires: 'notification',
  13. version: 0.13,
  14. init: function(editor) {
  15. CKEDITOR.document.appendStyleSheet(CKEDITOR.getUrl(CKEDITOR.plugins.getPath('autosave') + 'css/autosave.min.css'));
  16. editor.on('instanceReady', function(){
  17. if (typeof (jQuery) === 'undefined') {
  18. CKEDITOR.scriptLoader.load('//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js', function() {
  19. jQuery.noConflict();
  20. loadPlugin(editor);
  21. });
  22. } else {
  23. CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(CKEDITOR.plugins.getPath('autosave') + 'js/extensions.min.js'), function() {
  24. loadPlugin(editor);
  25. });
  26. }
  27. }, editor, null, 100);
  28. }
  29. });
  30. function loadPlugin(editorInstance) {
  31. var autoSaveKey = editorInstance.config.autosave_SaveKey != null ? editorInstance.config.autosave_SaveKey : 'autosave_' + window.location + "_" + editorInstance.id;
  32. var notOlderThen = editorInstance.config.autosave_NotOlderThen != null ? editorInstance.config.autosave_NotOlderThen : 1440;
  33. var saveOnDestroy = editorInstance.config.autosave_saveOnDestroy != null ? editorInstance.config.autosave_saveOnDestroy : false;
  34. var saveDetectionSelectors =
  35. editorInstance.config.autosave_saveDetectionSelectors != null ? editorInstance.config.autosave_saveDetectionSelectors : "a[href^='javascript:__doPostBack'][id*='Save'],a[id*='Cancel']";
  36. CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(CKEDITOR.plugins.getPath('autosave') + 'js/extensions.min.js'), function() {
  37. GenerateAutoSaveDialog(editorInstance, autoSaveKey);
  38. CheckForAutoSavedContent(editorInstance, autoSaveKey, notOlderThen);
  39. });
  40. jQuery(saveDetectionSelectors).click(function() {
  41. RemoveStorage(autoSaveKey);
  42. });
  43. editorInstance.on('change', startTimer);
  44. editorInstance.on('destroy', function() {
  45. if (saveOnDestroy) {
  46. SaveData(autoSaveKey, editorInstance);
  47. }
  48. });
  49. }
  50. var timeOutId = 0,
  51. savingActive = false;
  52. var startTimer = function(event) {
  53. if (timeOutId) {
  54. } else {
  55. var delay = CKEDITOR.config.autosave_delay != null ? CKEDITOR.config.autosave_delay : 25;
  56. timeOutId = setTimeout(onTimer, delay * 1000, event);
  57. }
  58. };
  59. var onTimer = function(event) {
  60. if (savingActive) {
  61. startTimer(event);
  62. } else if (event.editor.checkDirty() || event.editor.plugins.bbcode) {
  63. savingActive = true;
  64. var editor = event.editor,
  65. autoSaveKey = editor.config.autosave_SaveKey != null ? editor.config.autosave_SaveKey : 'autosave_' + window.location + "_" + editor.id;
  66. SaveData(autoSaveKey, editor);
  67. timeOutId = 0;
  68. savingActive = false;
  69. }
  70. };
  71. // localStorage detection
  72. function supportsLocalStorage() {
  73. if (typeof (Storage) === 'undefined') {
  74. return false;
  75. }
  76. try {
  77. localStorage.getItem("___test_key");
  78. return true;
  79. } catch (e) {
  80. return false;
  81. }
  82. }
  83. function GenerateAutoSaveDialog(editorInstance, autoSaveKey) {
  84. CKEDITOR.dialog.add('autosaveDialog', function() {
  85. return {
  86. title: editorInstance.lang.autosave.title,
  87. minHeight: 155,
  88. height: 300,
  89. width: 750,
  90. onShow: function() {
  91. RenderDiff(this, editorInstance, autoSaveKey);
  92. },
  93. onOk: function() {
  94. if (localStorage.getItem(autoSaveKey)) {
  95. var jsonSavedContent = LoadData(autoSaveKey);
  96. editorInstance.loadSnapshot(jsonSavedContent.data);
  97. RemoveStorage(autoSaveKey);
  98. }
  99. },
  100. onCancel: function() {
  101. RemoveStorage(autoSaveKey);
  102. },
  103. contents: [
  104. {
  105. label: '',
  106. id: 'general',
  107. elements: [
  108. {
  109. type: 'radio',
  110. id: 'diffType',
  111. label: editorInstance.lang.autosave.diffType,
  112. items: [[editorInstance.lang.autosave.sideBySide, 'sideBySide'], [editorInstance.lang.autosave.inline, 'inline']],
  113. 'default': 'sideBySide',
  114. onClick: function() {
  115. RenderDiff(this._.dialog, editorInstance, autoSaveKey);
  116. }
  117. }, {
  118. type: 'html',
  119. id: 'diffContent',
  120. html: ''
  121. }
  122. ]
  123. }
  124. ],
  125. buttons: [
  126. {
  127. id: 'ok',
  128. type: 'button',
  129. label: editorInstance.lang.autosave.ok,
  130. 'class': 'cke_dialog_ui_button_ok cke_dialog_autosave_ok',
  131. onClick: function(evt) {
  132. var dialog = evt.data.dialog;
  133. if (dialog.fire('ok', { hide: true }).hide !== false)
  134. dialog.hide();
  135. }
  136. },
  137. {
  138. id: 'cancel',
  139. type: 'button',
  140. label: editorInstance.lang.autosave.no,
  141. 'class': 'cke_dialog_ui_button_cancel',
  142. onClick: function(evt) {
  143. var dialog = evt.data.dialog;
  144. if (dialog.fire('cancel', { hide: true }).hide !== false)
  145. dialog.hide();
  146. }
  147. }
  148. ]
  149. };
  150. });
  151. }
  152. function CheckForAutoSavedContent(editorInstance, autoSaveKey, notOlderThen) {
  153. // Checks If there is data available and load it
  154. if (localStorage.getItem(autoSaveKey)) {
  155. var jsonSavedContent = LoadData(autoSaveKey);
  156. var autoSavedContent = jsonSavedContent.data;
  157. var autoSavedContentDate = jsonSavedContent.saveTime;
  158. var editorLoadedContent = editorInstance.getSnapshot();
  159. // check if the loaded editor content is the same as the autosaved content
  160. if (editorLoadedContent == autoSavedContent) {
  161. localStorage.removeItem(autoSaveKey);
  162. return;
  163. }
  164. // Ignore if autosaved content is older then x minutes
  165. if (moment(new Date()).diff(new Date(autoSavedContentDate), 'minutes') > notOlderThen) {
  166. RemoveStorage(autoSaveKey);
  167. return;
  168. }
  169. var confirmMessage = editorInstance.lang.autosave.loadSavedContent.replace("{0}", moment(autoSavedContentDate).locale(editorInstance.config.language).format(editorInstance.lang.autosave.dateFormat));
  170. if (confirm(confirmMessage)) {
  171. // Open DIFF Dialog
  172. editorInstance.openDialog('autosaveDialog');
  173. } else {
  174. RemoveStorage(autoSaveKey);
  175. }
  176. }
  177. }
  178. function LoadData(autoSaveKey) {
  179. console.log('LD lS');
  180. var data = localStorage.getItem(autoSaveKey);
  181. if( data ){
  182. var compressedJSON = LZString.decompressFromUTF16( data );
  183. return JSON.parse(compressedJSON);
  184. }
  185. return '';
  186. }
  187. function SaveData(autoSaveKey, editorInstance) {
  188. var compressedJSON = LZString.compressToUTF16(JSON.stringify({ data: editorInstance.getSnapshot(), saveTime: new Date() }));
  189. localStorage.setItem(autoSaveKey, compressedJSON);
  190. var notification = new CKEDITOR.plugins.notification( editorInstance, { message: editorInstance.lang.autosave.autoSaveMessage, type: 'success' } );
  191. notification.show();
  192. }
  193. function RemoveStorage(autoSaveKey) {
  194. if (timeOutId) {
  195. clearTimeout(timeOutId);
  196. }
  197. localStorage.removeItem(autoSaveKey);
  198. }
  199. function RenderDiff(dialog, editorInstance, autoSaveKey) {
  200. var jsonSavedContent = LoadData(autoSaveKey);
  201. var base = difflib.stringAsLines(editorInstance.getSnapshot());
  202. var newtxt = difflib.stringAsLines(jsonSavedContent.data);
  203. var sm = new difflib.SequenceMatcher(base, newtxt);
  204. var opcodes = sm.get_opcodes();
  205. dialog.getContentElement('general', 'diffContent').getElement().setHtml('<div class="diffContent">' + diffview.buildView({
  206. baseTextLines: base,
  207. newTextLines: newtxt,
  208. opcodes: opcodes,
  209. baseTextName: editorInstance.lang.autosave.loadedContent,
  210. newTextName: editorInstance.lang.autosave.autoSavedContent + (moment(jsonSavedContent.saveTime).locale(editorInstance.config.language).format(editorInstance.lang.autosave.dateFormat)) + '\'',
  211. contextSize: 3,
  212. viewType: dialog.getContentElement('general', 'diffType').getValue() == "inline" ? 1 : 0
  213. }).outerHTML + '</div>');
  214. }
  215. })();