| 1 |
efrain |
1 |
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;
|
|
|
2 |
/**
|
|
|
3 |
* This module provides change detection to forms, allowing a browser to warn the user before navigating away if changes
|
|
|
4 |
* have been made.
|
|
|
5 |
*
|
|
|
6 |
* Two flags are stored for each form:
|
|
|
7 |
* * a 'dirty' flag; and
|
|
|
8 |
* * a 'submitted' flag.
|
|
|
9 |
*
|
|
|
10 |
* When the page is unloaded each watched form is checked. If the 'dirty' flag is set for any form, and the 'submitted'
|
|
|
11 |
* flag is not set for any form, then a warning is shown.
|
|
|
12 |
*
|
|
|
13 |
* The 'dirty' flag is set when any form element is modified within a watched form.
|
|
|
14 |
* The flag can also be set programatically. This may be required for custom form elements.
|
|
|
15 |
*
|
|
|
16 |
* It is not possible to customise the warning message in any modern browser.
|
|
|
17 |
*
|
|
|
18 |
* Please note that some browsers have controls on when these alerts may or may not be shown.
|
|
|
19 |
* See {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload} for browser-specific
|
|
|
20 |
* notes and references.
|
|
|
21 |
*
|
|
|
22 |
* @module core_form/changechecker
|
|
|
23 |
* @copyright 2021 Andrew Lyons <andrew@nicols.co.uk>
|
|
|
24 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
|
25 |
* @example <caption>Usage where the FormElement is already held</caption>
|
|
|
26 |
*
|
|
|
27 |
* import {watchForm} from 'core_form/changechecker';
|
|
|
28 |
*
|
|
|
29 |
* // Fetch the form element somehow.
|
|
|
30 |
* watchForm(formElement);
|
|
|
31 |
*
|
|
|
32 |
* @example <caption>Usage from the child of a form - i.e. an input, button, div, etc.</caption>
|
|
|
33 |
*
|
|
|
34 |
* import {watchForm} from 'core_form/changechecker';
|
|
|
35 |
*
|
|
|
36 |
* // Watch the form by using a child of it.
|
|
|
37 |
* watchForm(document.querySelector('input[data-foo="bar"]'););
|
|
|
38 |
*
|
|
|
39 |
* @example <caption>Usage from within a template</caption>
|
|
|
40 |
* <form id="mod_example-entry-{{uniqid}}" ...>
|
|
|
41 |
* <!--
|
|
|
42 |
*
|
|
|
43 |
* -->
|
|
|
44 |
* </form>
|
|
|
45 |
* {{#js}}
|
|
|
46 |
* require(['core_form/changechecker'], function(changeChecker) {
|
|
|
47 |
* watchFormById('mod_example-entry-{{uniqid}}');
|
|
|
48 |
* });
|
|
|
49 |
* {{/js}}
|
|
|
50 |
*/
|
| 1441 |
ariadna |
51 |
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;_exports.markAllFormsAsDirty=()=>{watchedForms.forEach((watchedForm=>{watchedForm.dataset.formDirty="true"}))};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)&&!shouldIgnoreChangesForNode(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))),shouldIgnoreChangesForNode=target=>!!target.closest(".ignoredirty"),markFormChangedFromNode=changedNode=>{if(changedNode.dataset.formChangeCheckerOverride)return void disableAllChecks();if(!isWatchingForm(changedNode))return;if(shouldIgnoreChangesForNode(changedNode))return;var target;(target=changedNode,watchedForms.find((watchedForm=>watchedForm.contains(target)))).dataset.formDirty="true"};_exports.markFormChangedFromNode=markFormChangedFromNode;const markFormSubmitted=formNode=>{(formNode=getFormFromChild(formNode))&&(formNode.dataset.formSubmitted="true")};_exports.markFormSubmitted=markFormSubmitted;_exports.markAllFormsSubmitted=()=>{watchedForms.forEach((watchedForm=>markFormSubmitted(watchedForm)))};const beforeUnloadHandler=e=>isAnyWatchedFormDirty()&&!M.cfg.behatsiterunning?(e.preventDefault(),e.returnValue=warningString,e.returnValue):(window.removeEventListener("beforeunload",beforeUnloadHandler),null),startWatching=()=>{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.getString)("changesmadereallygoaway","moodle").then((changesMadeString=>{warningString=changesMadeString})).catch(),window.addEventListener("beforeunload",beforeUnloadHandler)};_exports.startWatching=startWatching;_exports.watchFormById=formId=>{watchForm(document.getElementById(formId))};_exports.resetFormDirtyStateById=formId=>{resetFormDirtyState(document.getElementById(formId))};_exports.markFormAsDirtyById=formId=>{markFormAsDirty(document.getElementById(formId))},startWatching()}));
|
| 1 |
efrain |
52 |
|
|
|
53 |
//# sourceMappingURL=changechecker.min.js.map
|