%PDF- %PDF-
Direktori : /home/vacivi36/ava/lib/editor/atto/yui/src/editor/js/ |
Current File : /home/vacivi36/ava/lib/editor/atto/yui/src/editor/js/autosave.js |
// This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /* eslint-disable no-unused-vars */ /** * A autosave function for the Atto editor. * * @module moodle-editor_atto-autosave * @submodule autosave-base * @package editor_atto * @copyright 2014 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ var SUCCESS_MESSAGE_TIMEOUT = 5000, RECOVER_MESSAGE_TIMEOUT = 60000, LOGNAME_AUTOSAVE = 'moodle-editor_atto-editor-autosave'; function EditorAutosave() {} EditorAutosave.ATTRS = { /** * Enable/Disable auto save for this instance. * * @attribute autosaveEnabled * @type Boolean * @writeOnce */ autosaveEnabled: { value: true, writeOnce: true }, /** * The time between autosaves (in seconds). * * @attribute autosaveFrequency * @type Number * @default 60 * @writeOnce */ autosaveFrequency: { value: 60, writeOnce: true }, /** * Unique hash for this page instance. Calculated from $PAGE->url in php. * * @attribute pageHash * @type String * @writeOnce */ pageHash: { value: '', writeOnce: true } }; EditorAutosave.prototype = { /** * The text that was auto saved in the last request. * * @property lastText * @type string */ lastText: "", /** * Autosave instance. * * @property autosaveInstance * @type string */ autosaveInstance: null, /** * Autosave Timer. * * @property autosaveTimer * @type object */ autosaveTimer: null, /** * Initialize the autosave process * * @method setupAutosave * @chainable */ setupAutosave: function() { var draftid = -1, form, optiontype = null, options = this.get('filepickeroptions'), params; if (!this.get('autosaveEnabled')) { // Autosave disabled for this instance. return; } this.autosaveInstance = Y.stamp(this); for (optiontype in options) { if (typeof options[optiontype].itemid !== "undefined") { draftid = options[optiontype].itemid; } } // First see if there are any saved drafts. // Make an ajax request. params = { contextid: this.get('contextid'), action: 'resume', draftid: draftid, elementid: this.get('elementid'), pageinstance: this.autosaveInstance, pagehash: this.get('pageHash') }; this.autosaveIo(params, this, { success: function(response) { if (response === null) { // This can happen when there is nothing to resume from. return; } else if (!response) { Y.log('Invalid response received.', 'debug', LOGNAME_AUTOSAVE); return; } // Revert untouched editor contents to an empty string. var emptyContents = [ // For FF and Chrome. '<p></p>', '<p><br></p>', '<br>', '<p dir="rtl" style="text-align: right;"></p>', '<p dir="rtl" style="text-align: right;"><br></p>', '<p dir="ltr" style="text-align: left;"></p>', '<p dir="ltr" style="text-align: left;"><br></p>', // For IE 9 and 10. '<p> </p>', '<p><br> </p>', '<p dir="rtl" style="text-align: right;"> </p>', '<p dir="rtl" style="text-align: right;"><br> </p>', '<p dir="ltr" style="text-align: left;"> </p>', '<p dir="ltr" style="text-align: left;"><br> </p>' ]; if (emptyContents.includes(response.result)) { response.result = ''; } if (response.error || typeof response.result === 'undefined') { Y.log('Error occurred recovering draft text: ' + response.error, 'debug', LOGNAME_AUTOSAVE); this.showMessage(M.util.get_string('errortextrecovery', 'editor_atto'), NOTIFY_WARNING, RECOVER_MESSAGE_TIMEOUT); } else if (response.result !== this.textarea.get('value') && response.result !== '') { Y.log('Autosave text found - recover it.', 'debug', LOGNAME_AUTOSAVE); this.recoverText(response.result); } this._fireSelectionChanged(); }, failure: function() { this.showMessage(M.util.get_string('errortextrecovery', 'editor_atto'), NOTIFY_WARNING, RECOVER_MESSAGE_TIMEOUT); } }); // Now setup the timer for periodic saves. var delay = parseInt(this.get('autosaveFrequency'), 10) * 1000; this.autosaveTimer = Y.later(delay, this, this.saveDraft, false, true); // Now setup the listener for form submission. form = this.textarea.ancestor('form'); if (form) { this.autosaveIoOnSubmit(form, { action: 'reset', contextid: this.get('contextid'), elementid: this.get('elementid'), pageinstance: this.autosaveInstance, pagehash: this.get('pageHash') }); } return this; }, /** * Recover a previous version of this text and show a message. * * @method recoverText * @param {String} text * @chainable */ recoverText: function(text) { this.editor.setHTML(text); this.saveSelection(); this.updateOriginal(); this.lastText = text; this.showMessage(M.util.get_string('textrecovered', 'editor_atto'), NOTIFY_INFO, RECOVER_MESSAGE_TIMEOUT); // Fire an event that the editor content has changed. require(['core_editor/events'], function(editorEvents) { editorEvents.notifyEditorContentRestored(this.editor.getDOMNode()); }.bind(this)); return this; }, /** * Save a single draft via ajax. * * @method saveDraft * @chainable */ saveDraft: function() { var url, params; if (!this.editor.getDOMNode()) { // Stop autosaving if the editor was removed from the page. this.autosaveTimer.cancel(); return; } // Only copy the text from the div to the textarea if the textarea is not currently visible. if (!this.editor.get('hidden')) { this.updateOriginal(); } var newText = this.textarea.get('value'); if (newText !== this.lastText) { Y.log('Autosave text', 'debug', LOGNAME_AUTOSAVE); // Make an ajax request. url = M.cfg.wwwroot + this.get('autosaveAjaxScript'); params = { sesskey: M.cfg.sesskey, contextid: this.get('contextid'), action: 'save', drafttext: newText, elementid: this.get('elementid'), pagehash: this.get('pageHash'), pageinstance: this.autosaveInstance }; // Reusable error handler - must be passed the correct context. var ajaxErrorFunction = function(response) { var errorDuration = parseInt(this.get('autosaveFrequency'), 10) * 1000; Y.log('Error while autosaving text', 'warn', LOGNAME_AUTOSAVE); Y.log(response, 'warn', LOGNAME_AUTOSAVE); this.showMessage(M.util.get_string('autosavefailed', 'editor_atto'), NOTIFY_WARNING, errorDuration); }; this.autosaveIo(params, this, { failure: ajaxErrorFunction, success: function(response) { if (response && response.error) { Y.soon(Y.bind(ajaxErrorFunction, this, [response])); } else { // All working. this.lastText = newText; this.showMessage(M.util.get_string('autosavesucceeded', 'editor_atto'), NOTIFY_INFO, SUCCESS_MESSAGE_TIMEOUT); } } }); } return this; } }; Y.Base.mix(Y.M.editor_atto.Editor, [EditorAutosave]);