mirror of
https://github.com/moodle/moodle.git
synced 2025-07-27 01:10:51 +02:00
The window.tinyMCE.editors API was present in version 3 of TinyMCE, but is not present in later versions. As a result, this check tries to loop over a variable which does not exist and throws an error in the process. We should check that window.tinyMCE *and* window.tinyMCE.editors both exist before attempting to loop over them.
53 lines
7.6 KiB
JavaScript
53 lines
7.6 KiB
JavaScript
define("core_form/changechecker",["exports","core_editor/events","core/str"],(function(_exports,_events,_str){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.watchFormById=_exports.watchForm=_exports.unWatchForm=_exports.startWatching=_exports.resetFormDirtyStateById=_exports.resetFormDirtyState=_exports.resetAllFormDirtyStates=_exports.markFormSubmitted=_exports.markFormChangedFromNode=_exports.markFormAsDirtyById=_exports.markFormAsDirty=_exports.markAllFormsSubmitted=_exports.markAllFormsAsDirty=_exports.isAnyWatchedFormDirty=_exports.disableAllChecks=void 0;
|
|
/**
|
|
* This module provides change detection to forms, allowing a browser to warn the user before navigating away if changes
|
|
* have been made.
|
|
*
|
|
* Two flags are stored for each form:
|
|
* * a 'dirty' flag; and
|
|
* * a 'submitted' flag.
|
|
*
|
|
* When the page is unloaded each watched form is checked. If the 'dirty' flag is set for any form, and the 'submitted'
|
|
* flag is not set for any form, then a warning is shown.
|
|
*
|
|
* The 'dirty' flag is set when any form element is modified within a watched form.
|
|
* The flag can also be set programatically. This may be required for custom form elements.
|
|
*
|
|
* It is not possible to customise the warning message in any modern browser.
|
|
*
|
|
* Please note that some browsers have controls on when these alerts may or may not be shown.
|
|
* See {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload} for browser-specific
|
|
* notes and references.
|
|
*
|
|
* @module core_form/changechecker
|
|
* @copyright 2021 Andrew Lyons <andrew@nicols.co.uk>
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
* @example <caption>Usage where the FormElement is already held</caption>
|
|
*
|
|
* import {watchForm} from 'core_form/changechecker';
|
|
*
|
|
* // Fetch the form element somehow.
|
|
* watchForm(formElement);
|
|
*
|
|
* @example <caption>Usage from the child of a form - i.e. an input, button, div, etc.</caption>
|
|
*
|
|
* import {watchForm} from 'core_form/changechecker';
|
|
*
|
|
* // Watch the form by using a child of it.
|
|
* watchForm(document.querySelector('input[data-foo="bar"]'););
|
|
*
|
|
* @example <caption>Usage from within a template</caption>
|
|
* <form id="mod_example-entry-{{uniqid}}" ...>
|
|
* <!--
|
|
*
|
|
* -->
|
|
* </form>
|
|
* {{#js}}
|
|
* require(['core_form/changechecker'], function(changeChecker) {
|
|
* watchFormById('mod_example-entry-{{uniqid}}');
|
|
* });
|
|
* {{/js}}
|
|
*/
|
|
let warningString,watchedForms=[],formChangeCheckerDisabled=!1;const getFormFromChild=formChild=>formChild.closest("form"),watchForm=formNode=>{(formNode=getFormFromChild(formNode))&&(isWatchingForm(formNode)||watchedForms.push(formNode))};_exports.watchForm=watchForm;_exports.unWatchForm=formNode=>{watchedForms=watchedForms.filter((watchedForm=>!!watchedForm.contains(formNode)))};const resetAllFormDirtyStates=()=>{watchedForms.forEach((watchedForm=>{watchedForm.dataset.formSubmitted="false",watchedForm.dataset.formDirty="false"}))};_exports.resetAllFormDirtyStates=resetAllFormDirtyStates;const resetFormDirtyState=formNode=>{(formNode=getFormFromChild(formNode))&&(formNode.dataset.formSubmitted="false",formNode.dataset.formDirty="false")};_exports.resetFormDirtyState=resetFormDirtyState;const markAllFormsAsDirty=()=>{watchedForms.forEach((watchedForm=>{watchedForm.dataset.formDirty="true"}))};_exports.markAllFormsAsDirty=markAllFormsAsDirty;const markFormAsDirty=formNode=>{(formNode=getFormFromChild(formNode))&&(formNode.dataset.formDirty="true")};_exports.markFormAsDirty=markFormAsDirty;const disableAllChecks=()=>{formChangeCheckerDisabled=!0};_exports.disableAllChecks=disableAllChecks;const isAnyWatchedFormDirty=()=>{if(formChangeCheckerDisabled)return!1;if(watchedForms.some((watchedForm=>"true"===watchedForm.dataset.formSubmitted)))return!1;return!!watchedForms.some((watchedForm=>{if(!watchedForm.isConnected)return!1;if("true"===watchedForm.dataset.formDirty)return!0;if(document.activeElement&&document.activeElement.dataset.propertyIsEnumerable("initialValue")){const isActiveElementWatched=isWatchingForm(document.activeElement),hasValueChanged=document.activeElement.dataset.initialValue!==document.activeElement.value;if(isActiveElementWatched&&hasValueChanged)return!0}return!1}))||!(void 0===window.tinyMCE||!window.tinyMCE.editors||!window.tinyMCE.editors.some((editor=>editor.isDirty())))};_exports.isAnyWatchedFormDirty=isAnyWatchedFormDirty;const isWatchingForm=target=>watchedForms.some((watchedForm=>watchedForm.contains(target))),markFormChangedFromNode=changedNode=>{if(changedNode.dataset.formChangeCheckerOverride)return void disableAllChecks();if(!isWatchingForm(changedNode))return;if(changedNode.closest(".ignoredirty"))return;const formNode=(target=>watchedForms.find((watchedForm=>watchedForm.contains(target))))(changedNode);formNode.dataset.formDirty="true"};_exports.markFormChangedFromNode=markFormChangedFromNode;const markFormSubmitted=formNode=>{(formNode=getFormFromChild(formNode))&&(formNode.dataset.formSubmitted="true")};_exports.markFormSubmitted=markFormSubmitted;const markAllFormsSubmitted=()=>{watchedForms.forEach((watchedForm=>markFormSubmitted(watchedForm)))};_exports.markAllFormsSubmitted=markAllFormsSubmitted;const beforeUnloadHandler=e=>isAnyWatchedFormDirty()&&!M.cfg.behatsiterunning?(e.preventDefault(),e.returnValue=warningString,e.returnValue):(window.removeEventListener("beforeunload",beforeUnloadHandler),null),startWatching=()=>{addLegacyFunctions(),document.addEventListener("change",(e=>{isWatchingForm(e.target)&&markFormChangedFromNode(e.target)})),document.addEventListener("click",(e=>{if(!e.target.closest("[data-formchangechecker-ignore-submit]"))return;const ownerForm=getFormFromChild(e.target);ownerForm&&(ownerForm.dataset.ignoreSubmission="true")})),document.addEventListener("focusin",(e=>{if(e.target.matches("input, textarea, select")){if(e.target.dataset.propertyIsEnumerable("initialValue"))return;e.target.dataset.initialValue=e.target.value}})),document.addEventListener("submit",(e=>{const formNode=getFormFromChild(e.target);formNode&&(formNode.dataset.ignoreSubmission?formNode.dataset.ignoreSubmission="false":markFormSubmitted(formNode))})),document.addEventListener(_events.eventTypes.editorContentRestored,(e=>{e.target!=document?resetFormDirtyState(e.target):resetAllFormDirtyStates()})),(0,_str.get_string)("changesmadereallygoaway","moodle").then((changesMadeString=>{warningString=changesMadeString})).catch(),window.addEventListener("beforeunload",beforeUnloadHandler)};_exports.startWatching=startWatching;const addLegacyFunctions=()=>{const getLoggedLegacyFallback=(oldFunctionName,newFunctionName,newFunction)=>function(){window.console.warn("The moodle-core-formchangechecker has been deprecated and replaced with core_form/changechecker. "+"The ".concat(oldFunctionName," function has been replaced with ").concat(newFunctionName,".")),newFunction(...arguments)};window.M.core_formchangechecker={init:getLoggedLegacyFallback("init","watchFormById",watchFormById),reset_form_dirty_state:getLoggedLegacyFallback("reset_form_dirty_state","resetFormDirtyState",resetAllFormDirtyStates),set_form_changed:getLoggedLegacyFallback("set_form_changed","markFormAsDirty",markAllFormsAsDirty),set_form_submitted:getLoggedLegacyFallback("set_form_submitted","markFormSubmitted",markAllFormsSubmitted)}},watchFormById=formId=>{watchForm(document.getElementById(formId))};_exports.watchFormById=watchFormById;_exports.resetFormDirtyStateById=formId=>{resetFormDirtyState(document.getElementById(formId))};_exports.markFormAsDirtyById=formId=>{markFormAsDirty(document.getElementById(formId))},startWatching()}));
|
|
|
|
//# sourceMappingURL=changechecker.min.js.map
|