MDL-72507 Quiz: Quiz auto-save does not detect uploaded files

This commit is contained in:
Thong Bui 2021-09-30 12:17:40 +07:00
parent c71b2db9a3
commit 392e57b6a0
8 changed files with 48 additions and 3 deletions

View file

@ -1,2 +1,2 @@
define ("core_form/events",["exports","core/str"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.triggerUploadCompleted=a.triggerUploadStarted=a.types=void 0;var c;(0,b.get_string)("changesmadereallygoaway","moodle").then(function(a){c=a;return a}).catch();var d=function(a){if(a){a.returnValue=c}},e={uploadStarted:"core_form/uploadStarted",uploadCompleted:"core_form/uploadCompleted"};a.types=e;a.triggerUploadStarted=function triggerUploadStarted(a){window.addEventListener("beforeunload",d);var b=new CustomEvent(e.uploadStarted,{bubbles:!0,cancellable:!1}),c=document.getElementById(a);c.dispatchEvent(b);return b};a.triggerUploadCompleted=function triggerUploadCompleted(a){window.removeEventListener("beforeunload",d);var b=new CustomEvent(e.uploadCompleted,{bubbles:!0,cancellable:!1}),c=document.getElementById(a);c.dispatchEvent(b);return b}});
define ("core_form/events",["exports","core/str"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.notifyUploadChanged=a.triggerUploadCompleted=a.triggerUploadStarted=a.types=void 0;var c;(0,b.get_string)("changesmadereallygoaway","moodle").then(function(a){c=a;return a}).catch();var d=function(a){if(a){a.returnValue=c}},e={uploadStarted:"core_form/uploadStarted",uploadCompleted:"core_form/uploadCompleted",uploadChanged:"core_form/uploadChanged"};a.types=e;a.triggerUploadStarted=function triggerUploadStarted(a){window.addEventListener("beforeunload",d);var b=new CustomEvent(e.uploadStarted,{bubbles:!0,cancellable:!1}),c=document.getElementById(a);c.dispatchEvent(b);return b};a.triggerUploadCompleted=function triggerUploadCompleted(a){window.removeEventListener("beforeunload",d);var b=new CustomEvent(e.uploadCompleted,{bubbles:!0,cancellable:!1}),c=document.getElementById(a);c.dispatchEvent(b);return b};a.notifyUploadChanged=function notifyUploadChanged(a){var b=new CustomEvent(e.uploadChanged,{bubbles:!0,cancellable:!1}),c=document.getElementById(a);c.dispatchEvent(b);return b}});
//# sourceMappingURL=events.min.js.map

View file

@ -1 +1 @@
{"version":3,"sources":["../src/events.js"],"names":["changesMadeString","then","string","catch","changesMadeCheck","e","returnValue","types","uploadStarted","uploadCompleted","triggerUploadStarted","elementId","window","addEventListener","customEvent","CustomEvent","bubbles","cancellable","element","document","getElementById","dispatchEvent","triggerUploadCompleted","removeEventListener"],"mappings":"6LA0BA,GAAIA,CAAAA,CAAJ,CACA,iBAAU,yBAAV,CAAqC,QAArC,EAA+CC,IAA/C,CAAoD,SAAAC,CAAM,CAAI,CAC1DF,CAAiB,CAAGE,CAApB,CACA,MAAOA,CAAAA,CACV,CAHD,EAGGC,KAHH,G,GASMC,CAAAA,CAAgB,CAAG,SAAAC,CAAC,CAAI,CAC1B,GAAIA,CAAJ,CAAO,CACHA,CAAC,CAACC,WAAF,CAAgBN,CACnB,CACJ,C,CAKYO,CAAK,CAAG,CACjBC,aAAa,CAAE,yBADE,CAEjBC,eAAe,CAAE,2BAFA,C,kCAWe,QAAvBC,CAAAA,oBAAuB,CAAAC,CAAS,CAAI,CAE7CC,MAAM,CAACC,gBAAP,CAAwB,cAAxB,CAAwCT,CAAxC,EAF6C,GAGvCU,CAAAA,CAAW,CAAG,GAAIC,CAAAA,WAAJ,CAAgBR,CAAK,CAACC,aAAtB,CAAqC,CACrDQ,OAAO,GAD8C,CAErDC,WAAW,GAF0C,CAArC,CAHyB,CAOvCC,CAAO,CAAGC,QAAQ,CAACC,cAAT,CAAwBT,CAAxB,CAP6B,CAQ7CO,CAAO,CAACG,aAAR,CAAsBP,CAAtB,EAEA,MAAOA,CAAAA,CACV,C,0BAQqC,QAAzBQ,CAAAA,sBAAyB,CAAAX,CAAS,CAAI,CAE/CC,MAAM,CAACW,mBAAP,CAA2B,cAA3B,CAA2CnB,CAA3C,EAF+C,GAGzCU,CAAAA,CAAW,CAAG,GAAIC,CAAAA,WAAJ,CAAgBR,CAAK,CAACE,eAAtB,CAAuC,CACvDO,OAAO,GADgD,CAEvDC,WAAW,GAF4C,CAAvC,CAH2B,CAOzCC,CAAO,CAAGC,QAAQ,CAACC,cAAT,CAAwBT,CAAxB,CAP+B,CAQ/CO,CAAO,CAACG,aAAR,CAAsBP,CAAtB,EAEA,MAAOA,CAAAA,CACV,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Contain the events the form component can trigger.\n *\n * @module core_form/events\n * @copyright 2021 Huong Nguyen <huongnv13@gmail.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.10\n */\n\nimport {get_string as getString} from 'core/str';\n\nlet changesMadeString;\ngetString('changesmadereallygoaway', 'moodle').then(string => {\n changesMadeString = string;\n return string;\n}).catch();\n\n/**\n * Prevent user navigate away when upload progress still running.\n * @param {Event} e The event\n */\nconst changesMadeCheck = e => {\n if (e) {\n e.returnValue = changesMadeString;\n }\n};\n\n/**\n * List of the events.\n **/\nexport const types = {\n uploadStarted: 'core_form/uploadStarted',\n uploadCompleted: 'core_form/uploadCompleted',\n};\n\n/**\n * Trigger upload start event.\n *\n * @param {String} elementId\n * @returns {CustomEvent<unknown>}\n */\nexport const triggerUploadStarted = elementId => {\n // Add an additional check for changes made.\n window.addEventListener('beforeunload', changesMadeCheck);\n const customEvent = new CustomEvent(types.uploadStarted, {\n bubbles: true,\n cancellable: false\n });\n const element = document.getElementById(elementId);\n element.dispatchEvent(customEvent);\n\n return customEvent;\n};\n\n/**\n * Trigger upload complete event.\n *\n * @param {String} elementId\n * @returns {CustomEvent<unknown>}\n */\nexport const triggerUploadCompleted = elementId => {\n // Remove the additional check for changes made.\n window.removeEventListener('beforeunload', changesMadeCheck);\n const customEvent = new CustomEvent(types.uploadCompleted, {\n bubbles: true,\n cancellable: false\n });\n const element = document.getElementById(elementId);\n element.dispatchEvent(customEvent);\n\n return customEvent;\n};\n"],"file":"events.min.js"}
{"version":3,"sources":["../src/events.js"],"names":["changesMadeString","then","string","catch","changesMadeCheck","e","returnValue","types","uploadStarted","uploadCompleted","uploadChanged","triggerUploadStarted","elementId","window","addEventListener","customEvent","CustomEvent","bubbles","cancellable","element","document","getElementById","dispatchEvent","triggerUploadCompleted","removeEventListener","notifyUploadChanged"],"mappings":"mNA0BA,GAAIA,CAAAA,CAAJ,CACA,iBAAU,yBAAV,CAAqC,QAArC,EAA+CC,IAA/C,CAAoD,SAAAC,CAAM,CAAI,CAC1DF,CAAiB,CAAGE,CAApB,CACA,MAAOA,CAAAA,CACV,CAHD,EAGGC,KAHH,G,GASMC,CAAAA,CAAgB,CAAG,SAAAC,CAAC,CAAI,CAC1B,GAAIA,CAAJ,CAAO,CACHA,CAAC,CAACC,WAAF,CAAgBN,CACnB,CACJ,C,CAKYO,CAAK,CAAG,CACjBC,aAAa,CAAE,yBADE,CAEjBC,eAAe,CAAE,2BAFA,CAGjBC,aAAa,CAAE,yBAHE,C,kCAYe,QAAvBC,CAAAA,oBAAuB,CAAAC,CAAS,CAAI,CAE7CC,MAAM,CAACC,gBAAP,CAAwB,cAAxB,CAAwCV,CAAxC,EAF6C,GAGvCW,CAAAA,CAAW,CAAG,GAAIC,CAAAA,WAAJ,CAAgBT,CAAK,CAACC,aAAtB,CAAqC,CACrDS,OAAO,GAD8C,CAErDC,WAAW,GAF0C,CAArC,CAHyB,CAOvCC,CAAO,CAAGC,QAAQ,CAACC,cAAT,CAAwBT,CAAxB,CAP6B,CAQ7CO,CAAO,CAACG,aAAR,CAAsBP,CAAtB,EAEA,MAAOA,CAAAA,CACV,C,0BAQqC,QAAzBQ,CAAAA,sBAAyB,CAAAX,CAAS,CAAI,CAE/CC,MAAM,CAACW,mBAAP,CAA2B,cAA3B,CAA2CpB,CAA3C,EAF+C,GAGzCW,CAAAA,CAAW,CAAG,GAAIC,CAAAA,WAAJ,CAAgBT,CAAK,CAACE,eAAtB,CAAuC,CACvDQ,OAAO,GADgD,CAEvDC,WAAW,GAF4C,CAAvC,CAH2B,CAOzCC,CAAO,CAAGC,QAAQ,CAACC,cAAT,CAAwBT,CAAxB,CAP+B,CAQ/CO,CAAO,CAACG,aAAR,CAAsBP,CAAtB,EAEA,MAAOA,CAAAA,CACV,C,uBASmC,QAAtBU,CAAAA,mBAAsB,CAAAb,CAAS,CAAI,IAEvCG,CAAAA,CAAW,CAAG,GAAIC,CAAAA,WAAJ,CAAgBT,CAAK,CAACG,aAAtB,CAAqC,CACrDO,OAAO,GAD8C,CAErDC,WAAW,GAF0C,CAArC,CAFyB,CAOvCC,CAAO,CAAGC,QAAQ,CAACC,cAAT,CAAwBT,CAAxB,CAP6B,CAQ7CO,CAAO,CAACG,aAAR,CAAsBP,CAAtB,EAEA,MAAOA,CAAAA,CACV,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Contain the events the form component can trigger.\n *\n * @module core_form/events\n * @copyright 2021 Huong Nguyen <huongnv13@gmail.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.10\n */\n\nimport {get_string as getString} from 'core/str';\n\nlet changesMadeString;\ngetString('changesmadereallygoaway', 'moodle').then(string => {\n changesMadeString = string;\n return string;\n}).catch();\n\n/**\n * Prevent user navigate away when upload progress still running.\n * @param {Event} e The event\n */\nconst changesMadeCheck = e => {\n if (e) {\n e.returnValue = changesMadeString;\n }\n};\n\n/**\n * List of the events.\n **/\nexport const types = {\n uploadStarted: 'core_form/uploadStarted',\n uploadCompleted: 'core_form/uploadCompleted',\n uploadChanged: 'core_form/uploadChanged'\n};\n\n/**\n * Trigger upload start event.\n *\n * @param {String} elementId\n * @returns {CustomEvent<unknown>}\n */\nexport const triggerUploadStarted = elementId => {\n // Add an additional check for changes made.\n window.addEventListener('beforeunload', changesMadeCheck);\n const customEvent = new CustomEvent(types.uploadStarted, {\n bubbles: true,\n cancellable: false\n });\n const element = document.getElementById(elementId);\n element.dispatchEvent(customEvent);\n\n return customEvent;\n};\n\n/**\n * Trigger upload complete event.\n *\n * @param {String} elementId\n * @returns {CustomEvent<unknown>}\n */\nexport const triggerUploadCompleted = elementId => {\n // Remove the additional check for changes made.\n window.removeEventListener('beforeunload', changesMadeCheck);\n const customEvent = new CustomEvent(types.uploadCompleted, {\n bubbles: true,\n cancellable: false\n });\n const element = document.getElementById(elementId);\n element.dispatchEvent(customEvent);\n\n return customEvent;\n};\n\n/**\n * Trigger an event to notify the file upload field has been changed.\n *\n * @method\n * @param {String} elementId The element which was changed\n * @returns {CustomEvent}\n */\n export const notifyUploadChanged = elementId => {\n\n const customEvent = new CustomEvent(types.uploadChanged, {\n bubbles: true,\n cancellable: false\n });\n\n const element = document.getElementById(elementId);\n element.dispatchEvent(customEvent);\n\n return customEvent;\n};\n"],"file":"events.min.js"}

View file

@ -46,6 +46,7 @@ const changesMadeCheck = e => {
export const types = {
uploadStarted: 'core_form/uploadStarted',
uploadCompleted: 'core_form/uploadCompleted',
uploadChanged: 'core_form/uploadChanged'
};
/**
@ -85,3 +86,23 @@ export const triggerUploadCompleted = elementId => {
return customEvent;
};
/**
* Trigger an event to notify the file upload field has been changed.
*
* @method
* @param {String} elementId The element which was changed
* @returns {CustomEvent}
*/
export const notifyUploadChanged = elementId => {
const customEvent = new CustomEvent(types.uploadChanged, {
bubbles: true,
cancellable: false
});
const element = document.getElementById(elementId);
element.dispatchEvent(customEvent);
return customEvent;
};

View file

@ -202,6 +202,10 @@ M.form_filemanager.init = function(Y, options) {
if (typeof M.core_formchangechecker != 'undefined') {
M.core_formchangechecker.set_form_changed();
}
require(['core_form/events'], function(FormEvent) {
FormEvent.notifyUploadChanged(this.filemanager.get('id'));
}.bind(this));
},
check_buttons: function() {
if (this.filecount>0) {
@ -463,6 +467,10 @@ M.form_filemanager.init = function(Y, options) {
if (typeof M.core_formchangechecker != 'undefined') {
M.core_formchangechecker.set_form_changed();
}
require(['core_form/events'], function(FormEvent) {
FormEvent.notifyUploadChanged(this.scope.filemanager.get('id'));
}.bind(this));
}
});
};
@ -1002,6 +1010,10 @@ M.form_filemanager.init = function(Y, options) {
if (typeof M.core_formchangechecker != 'undefined') {
M.core_formchangechecker.set_form_changed();
}
require(['core_form/events'], function(FormEvent) {
FormEvent.notifyUploadChanged(this.scope.filemanager.get('id'));
}.bind(this));
}
});
};

View file

@ -204,6 +204,10 @@ M.mod_quiz.autosave = {
this.form.delegate('change', this.value_changed, this.SELECTORS.CHANGE_ELEMENTS, this);
this.form.on('submit', this.stop_autosaving, this);
require(['core_form/events'], function(FormEvent) {
window.addEventListener(FormEvent.types.uploadChanged, this.value_changed.bind(this));
}.bind(this));
this.init_tinymce(this.TINYMCE_DETECTION_REPEATS);
this.save_hidden_field_values();

View file

@ -1 +1 @@
YUI.add("moodle-mod_quiz-autosave",function(s,e){M.mod_quiz=M.mod_quiz||{},M.mod_quiz.autosave={TINYMCE_DETECTION_DELAY:500,TINYMCE_DETECTION_REPEATS:20,WATCH_HIDDEN_DELAY:1e3,FAILURES_BEFORE_NOTIFY:1,FIRST_SUCCESSFUL_SAVE:-1,SELECTORS:{QUIZ_FORM:"#responseform",VALUE_CHANGE_ELEMENTS:'input, textarea, [contenteditable="true"]',CHANGE_ELEMENTS:"input, select",HIDDEN_INPUTS:"input[type=hidden]",CONNECTION_ERROR:"#connection-error",CONNECTION_OK:"#connection-ok"},AUTOSAVE_HANDLER:M.cfg.wwwroot+"/mod/quiz/autosave.ajax.php",delay:12e4,form:null,dirty:!1,delay_timer:null,save_transaction:null,savefailures:0,editor_change_handler:null,hidden_field_values:{},init:function(e){this.form=s.one(this.SELECTORS.QUIZ_FORM),this.form&&(this.delay=1e3*e,this.form.delegate("valuechange",this.value_changed,this.SELECTORS.VALUE_CHANGE_ELEMENTS,this),this.form.delegate("change",this.value_changed,this.SELECTORS.CHANGE_ELEMENTS,this),this.form.on("submit",this.stop_autosaving,this),this.init_tinymce(this.TINYMCE_DETECTION_REPEATS),this.save_hidden_field_values(),this.watch_hidden_fields())},save_hidden_field_values:function(){this.form.all(this.SELECTORS.HIDDEN_INPUTS).each(function(e){var t=e.get("name");t&&(this.hidden_field_values[t]=e.get("value"))},this)},watch_hidden_fields:function(){this.detect_hidden_field_changes(),s.later(this.WATCH_HIDDEN_DELAY,this,this.watch_hidden_fields)},detect_hidden_field_changes:function(){this.form.all(this.SELECTORS.HIDDEN_INPUTS).each(function(e){var t=e.get("name"),i=e.get("value");t&&(t in this.hidden_field_values&&i===this.hidden_field_values[t]||(this.hidden_field_values[t]=i,this.value_changed({target:e})))},this)},init_tinymce:function(e){"undefined"!=typeof window.tinyMCE?(this.editor_change_handler=s.bind(this.editor_changed,this),window.tinyMCE.onAddEditor.add(s.bind(this.init_tinymce_editor,this))):0<e&&s.later(this.TINYMCE_DETECTION_DELAY,this,this.init_tinymce,[e-1])},init_tinymce_editor:function(e,t){t.onChange.add(this.editor_change_handler),t.onRedo.add(this.editor_change_handler),t.onUndo.add(this.editor_change_handler),t.onKeyDown.add(this.editor_change_handler)},value_changed:function(e){var t=e.target.getAttribute("name");"thispage"===t||"scrollpos"===t||t&&t.match(/_:flagged$/)||(t=t||"#"+e.target.getAttribute("id"),this.start_save_timer_if_necessary())},editor_changed:function(e){this.start_save_timer_if_necessary()},start_save_timer_if_necessary:function(){this.dirty=!0,this.delay_timer||this.save_transaction||this.start_save_timer()},start_save_timer:function(){this.cancel_delay(),this.delay_timer=s.later(this.delay,this,this.save_changes)},cancel_delay:function(){this.delay_timer&&!0!==this.delay_timer&&this.delay_timer.cancel(),this.delay_timer=null},save_changes:function(){if(this.cancel_delay(),this.dirty=!1,this.is_time_nearly_over())this.stop_autosaving();else{"undefined"!=typeof window.tinyMCE&&window.tinyMCE.triggerSave();var e=this.form.all("input[type=submit], button[type=submit]");e.setAttribute("type","button"),this.save_transaction=s.io(this.AUTOSAVE_HANDLER,{method:"POST",form:{id:this.form},on:{success:this.save_done,failure:this.save_failed},context:this}),e.setAttribute("type","submit")}},save_done:function(e,t){var i=JSON.parse(t.responseText);"OK"===i.status?("undefined"!=typeof i.timeleft&&M.mod_quiz.timer.updateEndTime(i.timeleft),this.save_transaction=null,this.dirty&&this.start_save_timer(),0<this.savefailures?(s.one(this.SELECTORS.CONNECTION_ERROR).hide(),s.one(this.SELECTORS.CONNECTION_OK).show(),this.savefailures=this.FIRST_SUCCESSFUL_SAVE):this.savefailures===this.FIRST_SUCCESSFUL_SAVE&&(s.one(this.SELECTORS.CONNECTION_OK).hide(),this.savefailures=0)):this.save_failed(e,t)},save_failed:function(){this.save_transaction=null,this.start_save_timer(),this.savefailures=Math.max(1,this.savefailures+1),this.savefailures===this.FAILURES_BEFORE_NOTIFY&&(s.one(this.SELECTORS.CONNECTION_ERROR).show(),s.one(this.SELECTORS.CONNECTION_OK).hide())},is_time_nearly_over:function(){return M.mod_quiz.timer&&M.mod_quiz.timer.endtime&&(new Date).getTime()+2*this.delay>M.mod_quiz.timer.endtime},stop_autosaving:function(){this.cancel_delay(),this.delay_timer=!0,this.save_transaction&&this.save_transaction.abort()}}},"@VERSION@",{requires:["base","node","event","event-valuechange","node-event-delegate","io-form"]});
YUI.add("moodle-mod_quiz-autosave",function(s,e){M.mod_quiz=M.mod_quiz||{},M.mod_quiz.autosave={TINYMCE_DETECTION_DELAY:500,TINYMCE_DETECTION_REPEATS:20,WATCH_HIDDEN_DELAY:1e3,FAILURES_BEFORE_NOTIFY:1,FIRST_SUCCESSFUL_SAVE:-1,SELECTORS:{QUIZ_FORM:"#responseform",VALUE_CHANGE_ELEMENTS:'input, textarea, [contenteditable="true"]',CHANGE_ELEMENTS:"input, select",HIDDEN_INPUTS:"input[type=hidden]",CONNECTION_ERROR:"#connection-error",CONNECTION_OK:"#connection-ok"},AUTOSAVE_HANDLER:M.cfg.wwwroot+"/mod/quiz/autosave.ajax.php",delay:12e4,form:null,dirty:!1,delay_timer:null,save_transaction:null,savefailures:0,editor_change_handler:null,hidden_field_values:{},init:function(e){this.form=s.one(this.SELECTORS.QUIZ_FORM),this.form&&(this.delay=1e3*e,this.form.delegate("valuechange",this.value_changed,this.SELECTORS.VALUE_CHANGE_ELEMENTS,this),this.form.delegate("change",this.value_changed,this.SELECTORS.CHANGE_ELEMENTS,this),this.form.on("submit",this.stop_autosaving,this),require(["core_form/events"],function(e){window.addEventListener(e.types.uploadChanged,this.value_changed.bind(this))}.bind(this)),this.init_tinymce(this.TINYMCE_DETECTION_REPEATS),this.save_hidden_field_values(),this.watch_hidden_fields())},save_hidden_field_values:function(){this.form.all(this.SELECTORS.HIDDEN_INPUTS).each(function(e){var t=e.get("name");t&&(this.hidden_field_values[t]=e.get("value"))},this)},watch_hidden_fields:function(){this.detect_hidden_field_changes(),s.later(this.WATCH_HIDDEN_DELAY,this,this.watch_hidden_fields)},detect_hidden_field_changes:function(){this.form.all(this.SELECTORS.HIDDEN_INPUTS).each(function(e){var t=e.get("name"),i=e.get("value");t&&(t in this.hidden_field_values&&i===this.hidden_field_values[t]||(this.hidden_field_values[t]=i,this.value_changed({target:e})))},this)},init_tinymce:function(e){"undefined"!=typeof window.tinyMCE?(this.editor_change_handler=s.bind(this.editor_changed,this),window.tinyMCE.onAddEditor.add(s.bind(this.init_tinymce_editor,this))):0<e&&s.later(this.TINYMCE_DETECTION_DELAY,this,this.init_tinymce,[e-1])},init_tinymce_editor:function(e,t){t.onChange.add(this.editor_change_handler),t.onRedo.add(this.editor_change_handler),t.onUndo.add(this.editor_change_handler),t.onKeyDown.add(this.editor_change_handler)},value_changed:function(e){var t=e.target.getAttribute("name");"thispage"===t||"scrollpos"===t||t&&t.match(/_:flagged$/)||(t=t||"#"+e.target.getAttribute("id"),this.start_save_timer_if_necessary())},editor_changed:function(e){this.start_save_timer_if_necessary()},start_save_timer_if_necessary:function(){this.dirty=!0,this.delay_timer||this.save_transaction||this.start_save_timer()},start_save_timer:function(){this.cancel_delay(),this.delay_timer=s.later(this.delay,this,this.save_changes)},cancel_delay:function(){this.delay_timer&&!0!==this.delay_timer&&this.delay_timer.cancel(),this.delay_timer=null},save_changes:function(){if(this.cancel_delay(),this.dirty=!1,this.is_time_nearly_over())this.stop_autosaving();else{"undefined"!=typeof window.tinyMCE&&window.tinyMCE.triggerSave();var e=this.form.all("input[type=submit], button[type=submit]");e.setAttribute("type","button"),this.save_transaction=s.io(this.AUTOSAVE_HANDLER,{method:"POST",form:{id:this.form},on:{success:this.save_done,failure:this.save_failed},context:this}),e.setAttribute("type","submit")}},save_done:function(e,t){var i=JSON.parse(t.responseText);"OK"===i.status?("undefined"!=typeof i.timeleft&&M.mod_quiz.timer.updateEndTime(i.timeleft),this.save_transaction=null,this.dirty&&this.start_save_timer(),0<this.savefailures?(s.one(this.SELECTORS.CONNECTION_ERROR).hide(),s.one(this.SELECTORS.CONNECTION_OK).show(),this.savefailures=this.FIRST_SUCCESSFUL_SAVE):this.savefailures===this.FIRST_SUCCESSFUL_SAVE&&(s.one(this.SELECTORS.CONNECTION_OK).hide(),this.savefailures=0)):this.save_failed(e,t)},save_failed:function(){this.save_transaction=null,this.start_save_timer(),this.savefailures=Math.max(1,this.savefailures+1),this.savefailures===this.FAILURES_BEFORE_NOTIFY&&(s.one(this.SELECTORS.CONNECTION_ERROR).show(),s.one(this.SELECTORS.CONNECTION_OK).hide())},is_time_nearly_over:function(){return M.mod_quiz.timer&&M.mod_quiz.timer.endtime&&(new Date).getTime()+2*this.delay>M.mod_quiz.timer.endtime},stop_autosaving:function(){this.cancel_delay(),this.delay_timer=!0,this.save_transaction&&this.save_transaction.abort()}}},"@VERSION@",{requires:["base","node","event","event-valuechange","node-event-delegate","io-form"]});

View file

@ -203,6 +203,10 @@ M.mod_quiz.autosave = {
this.form.delegate('change', this.value_changed, this.SELECTORS.CHANGE_ELEMENTS, this);
this.form.on('submit', this.stop_autosaving, this);
require(['core_form/events'], function(FormEvent) {
window.addEventListener(FormEvent.types.uploadChanged, this.value_changed.bind(this));
}.bind(this));
this.init_tinymce(this.TINYMCE_DETECTION_REPEATS);
this.save_hidden_field_values();

View file

@ -202,6 +202,10 @@ M.mod_quiz.autosave = {
this.form.delegate('change', this.value_changed, this.SELECTORS.CHANGE_ELEMENTS, this);
this.form.on('submit', this.stop_autosaving, this);
require(['core_form/events'], function(FormEvent) {
window.addEventListener(FormEvent.types.uploadChanged, this.value_changed.bind(this));
}.bind(this));
this.init_tinymce(this.TINYMCE_DETECTION_REPEATS);
this.save_hidden_field_values();