mirrored from git://git.moodle.org/moodle.git
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
/
changechecker.min.js.map
1 lines (1 loc) · 23 KB
/
changechecker.min.js.map
1
{"version":3,"sources":["../src/changechecker.js"],"names":["warningString","watchedForms","formChangeCheckerDisabled","getFormFromChild","formChild","closest","watchForm","formNode","isWatchingForm","push","unWatchForm","filter","watchedForm","contains","resetAllFormDirtyStates","forEach","dataset","formSubmitted","formDirty","resetFormDirtyState","markAllFormsAsDirty","markFormAsDirty","disableAllChecks","isAnyWatchedFormDirty","hasSubmittedForm","some","hasDirtyForm","isConnected","document","activeElement","propertyIsEnumerable","isActiveElementWatched","hasValueChanged","initialValue","value","window","tinyMCE","editors","editor","isDirty","getFormForNode","target","find","shouldIgnoreChangesForNode","markFormChangedFromNode","changedNode","formChangeCheckerOverride","markFormSubmitted","markAllFormsSubmitted","beforeUnloadHandler","e","warnBeforeUnload","M","cfg","behatsiterunning","preventDefault","returnValue","removeEventListener","startWatching","addLegacyFunctions","addEventListener","ignoredButton","ownerForm","ignoreSubmission","matches","eventTypes","editorContentRestored","then","changesMadeString","catch","getLoggedLegacyFallback","oldFunctionName","newFunctionName","newFunction","console","warn","core_formchangechecker","init","watchFormById","reset_form_dirty_state","set_form_changed","set_form_submitted","markAllFormsAsSubmitted","formId","getElementById","resetFormDirtyStateById","markFormAsDirtyById"],"mappings":"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","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 * This module provides change detection to forms, allowing a browser to warn the user before navigating away if changes\n * have been made.\n *\n * Two flags are stored for each form:\n * * a 'dirty' flag; and\n * * a 'submitted' flag.\n *\n * When the page is unloaded each watched form is checked. If the 'dirty' flag is set for any form, and the 'submitted'\n * flag is not set for any form, then a warning is shown.\n *\n * The 'dirty' flag is set when any form element is modified within a watched form.\n * The flag can also be set programatically. This may be required for custom form elements.\n *\n * It is not possible to customise the warning message in any modern browser.\n *\n * Please note that some browsers have controls on when these alerts may or may not be shown.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload} for browser-specific\n * notes and references.\n *\n * @module core_form/changechecker\n * @copyright 2021 Andrew Lyons <andrew@nicols.co.uk>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @example <caption>Usage where the FormElement is already held</caption>\n *\n * import {watchForm} from 'core_form/changechecker';\n *\n * // Fetch the form element somehow.\n * watchForm(formElement);\n *\n * @example <caption>Usage from the child of a form - i.e. an input, button, div, etc.</caption>\n *\n * import {watchForm} from 'core_form/changechecker';\n *\n * // Watch the form by using a child of it.\n * watchForm(document.querySelector('input[data-foo=\"bar\"]'););\n *\n * @example <caption>Usage from within a template</caption>\n * <form id=\"mod_example-entry-{{uniqid}}\" ...>\n * <!--\n *\n * -->\n * </form>\n * {{#js}}\n * require(['core_form/changechecker'], function(changeChecker) {\n * watchFormById('mod_example-entry-{{uniqid}}');\n * });\n * {{/js}}\n */\n\nimport {eventTypes} from 'core_editor/events';\nimport {get_string as getString} from 'core/str';\n\n/**\n * @property {Bool} initialised Whether the change checker has been initialised\n * @private\n */\nlet initialised = false;\n\n/**\n * @property {String} warningString The warning string to show on form change failure\n * @private\n */\nlet warningString;\n\n/**\n * @property {Array} watchedForms The list of watched forms\n * @private\n */\nlet watchedForms = [];\n\n/**\n * @property {Bool} formChangeCheckerDisabled Whether the form change checker has been actively disabled\n * @private\n */\nlet formChangeCheckerDisabled = false;\n\n/**\n * Get the nearest form element from a child element.\n *\n * @param {HTMLElement} formChild\n * @returns {HTMLFormElement|null}\n * @private\n */\nconst getFormFromChild = formChild => formChild.closest('form');\n\n/**\n * Watch the specified form for changes.\n *\n * @method\n * @param {HTMLElement} formNode\n */\nexport const watchForm = formNode => {\n // Normalise the formNode.\n formNode = getFormFromChild(formNode);\n\n if (!formNode) {\n // No form found.\n return;\n }\n\n if (isWatchingForm(formNode)) {\n // This form is already watched.\n return;\n }\n\n watchedForms.push(formNode);\n};\n\n/**\n * Stop watching the specified form for changes.\n *\n * If the form was not watched, then no change is made.\n *\n * A child of the form may be passed instead.\n *\n * @method\n * @param {HTMLElement} formNode\n * @example <caption>Stop watching a form for changes</caption>\n * import {unWatchForm} from 'core_form/changechecker';\n *\n * // ...\n * document.addEventListener('click', e => {\n * if (e.target.closest('[data-action=\"changePage\"]')) {\n * unWatchForm(e.target);\n * }\n * });\n */\nexport const unWatchForm = formNode => {\n watchedForms = watchedForms.filter(watchedForm => !!watchedForm.contains(formNode));\n};\n\n/**\n * Reset the 'dirty' flag for all watched forms.\n *\n * If a form was previously marked as 'dirty', then this flag will be cleared and when the page is unloaded no warning\n * will be shown.\n *\n * @method\n */\nexport const resetAllFormDirtyStates = () => {\n watchedForms.forEach(watchedForm => {\n watchedForm.dataset.formSubmitted = \"false\";\n watchedForm.dataset.formDirty = \"false\";\n });\n};\n\n/**\n * Reset the 'dirty' flag of the specified form.\n *\n * @method\n * @param {HTMLElement} formNode\n */\nexport const resetFormDirtyState = formNode => {\n formNode = getFormFromChild(formNode);\n\n if (!formNode) {\n return;\n }\n\n formNode.dataset.formSubmitted = \"false\";\n formNode.dataset.formDirty = \"false\";\n};\n\n/**\n * Mark all forms as dirty.\n *\n * This function is only for backwards-compliance with the old YUI module and should not be used in any other situation.\n * It will be removed in Moodle 4.4.\n *\n * @method\n */\nexport const markAllFormsAsDirty = () => {\n watchedForms.forEach(watchedForm => {\n watchedForm.dataset.formDirty = \"true\";\n });\n};\n\n/**\n * Mark a specific form as dirty.\n *\n * This behaviour may be required for custom form elements which are not caught by the standard change listeners.\n *\n * @method\n * @param {HTMLElement} formNode\n */\nexport const markFormAsDirty = formNode => {\n formNode = getFormFromChild(formNode);\n\n if (!formNode) {\n return;\n }\n\n // Mark it as dirty.\n formNode.dataset.formDirty = \"true\";\n};\n\n/**\n * Actively disable the form change checker.\n *\n * Please note that it cannot be re-enabled once disabled.\n *\n * @method\n */\nexport const disableAllChecks = () => {\n formChangeCheckerDisabled = true;\n};\n\n/**\n * Check whether any watched from is dirty.\n *\n * @method\n * @returns {Bool}\n * @private\n */\nconst isAnyWatchedFormDirty = () => {\n if (formChangeCheckerDisabled) {\n // The form change checker is disabled.\n return false;\n }\n\n const hasSubmittedForm = watchedForms.some(watchedForm => watchedForm.dataset.formSubmitted === \"true\");\n if (hasSubmittedForm) {\n // Do not warn about submitted forms, ever.\n return false;\n }\n\n const hasDirtyForm = watchedForms.some(watchedForm => {\n if (!watchedForm.isConnected) {\n // The watched form is not connected to the DOM.\n return false;\n }\n\n if (watchedForm.dataset.formDirty === \"true\") {\n // The form has been marked as dirty.\n return true;\n }\n\n // Elements currently holding focus will not have triggered change detection.\n // Check whether the value matches the original value upon form load.\n if (document.activeElement && document.activeElement.dataset.propertyIsEnumerable('initialValue')) {\n const isActiveElementWatched = isWatchingForm(document.activeElement);\n const hasValueChanged = document.activeElement.dataset.initialValue !== document.activeElement.value;\n\n if (isActiveElementWatched && hasValueChanged) {\n return true;\n }\n }\n\n return false;\n });\n\n if (hasDirtyForm) {\n // At least one form is dirty.\n return true;\n }\n\n // Handle TinyMCE editor instances.\n // TinyMCE forms may not have been initialised at the time that startWatching is called.\n // Check whether any tinyMCE editor is dirty.\n if (typeof window.tinyMCE !== 'undefined') {\n if (window.tinyMCE.editors.some(editor => editor.isDirty())) {\n return true;\n }\n }\n\n // No dirty forms detected.\n return false;\n};\n\n/**\n * Get the watched form for the specified target.\n *\n * @method\n * @param {HTMLNode} target\n * @returns {HTMLFormElement}\n * @private\n */\nconst getFormForNode = target => watchedForms.find(watchedForm => watchedForm.contains(target));\n\n/**\n * Whether the specified target is a watched form.\n *\n * @method\n * @param {HTMLNode} target\n * @returns {Bool}\n * @private\n */\nconst isWatchingForm = target => watchedForms.some(watchedForm => watchedForm.contains(target));\n\n/**\n * Whether the specified target should ignore changes or not.\n *\n * @method\n * @param {HTMLNode} target\n * @returns {Bool}\n * @private\n */\nconst shouldIgnoreChangesForNode = target => !!target.closest('.ignoredirty');\n\n/**\n * Mark a form as changed.\n *\n * @method\n * @param {HTMLElement} changedNode An element in the form which was changed\n */\nexport const markFormChangedFromNode = changedNode => {\n if (changedNode.dataset.formChangeCheckerOverride) {\n // Changes to this form node disable the form change checker entirely.\n // This is intended for select fields which cause an immediate redirect.\n disableAllChecks();\n return;\n }\n\n if (!isWatchingForm(changedNode)) {\n return;\n }\n\n if (shouldIgnoreChangesForNode(changedNode)) {\n return;\n }\n\n // Mark the form as dirty.\n const formNode = getFormForNode(changedNode);\n formNode.dataset.formDirty = \"true\";\n};\n\n/**\n * Mark a form as submitted.\n *\n * @method\n * @param {HTMLElement} formNode An element in the form to mark as submitted\n */\nexport const markFormSubmitted = formNode => {\n formNode = getFormFromChild(formNode);\n\n if (!formNode) {\n return;\n }\n\n formNode.dataset.formSubmitted = \"true\";\n};\n\n/**\n * Mark all forms as submitted.\n *\n * This function is only for backwards-compliance with the old YUI module and should not be used in any other situation.\n * It will be removed in Moodle 4.4.\n *\n * @method\n */\nexport const markAllFormsSubmitted = () => {\n watchedForms.forEach(watchedForm => markFormSubmitted(watchedForm));\n};\n\n/**\n * Handle the beforeunload event.\n *\n * @method\n * @param {Event} e\n * @returns {string|null}\n * @private\n */\nconst beforeUnloadHandler = e => {\n // Please note: The use of Promises in this function is forbidden.\n // This is an event handler and _cannot_ be asynchronous.\n let warnBeforeUnload = isAnyWatchedFormDirty() && !M.cfg.behatsiterunning;\n if (warnBeforeUnload) {\n // According to the specification, to show the confirmation dialog an event handler should call preventDefault()\n // on the event.\n e.preventDefault();\n\n // However note that not all browsers support this method, and some instead require the event handler to\n // implement one of two legacy methods:\n // * assigning a string to the event's returnValue property; and\n // * returning a string from the event handler.\n\n // Assigning a string to the event's returnValue property.\n e.returnValue = warningString;\n\n // Returning a string from the event handler.\n return e.returnValue;\n }\n\n // Attaching an event handler/listener to window or document's beforeunload event prevents browsers from using\n // in-memory page navigation caches, like Firefox's Back-Forward cache or WebKit's Page Cache.\n // Remove the handler.\n window.removeEventListener('beforeunload', beforeUnloadHandler);\n\n return null;\n};\n\n/**\n * Start watching for form changes.\n *\n * This function is called on module load, and should not normally be called.\n *\n * @method\n * @protected\n */\nexport const startWatching = () => {\n if (initialised) {\n return;\n }\n\n // Add legacy support to provide b/c for the old YUI version.\n addLegacyFunctions();\n\n document.addEventListener('change', e => {\n if (!isWatchingForm(e.target)) {\n return;\n }\n\n markFormChangedFromNode(e.target);\n });\n\n document.addEventListener('click', e => {\n const ignoredButton = e.target.closest('[data-formchangechecker-ignore-submit]');\n if (!ignoredButton) {\n return;\n }\n\n const ownerForm = getFormFromChild(e.target);\n if (ownerForm) {\n ownerForm.dataset.ignoreSubmission = \"true\";\n }\n });\n\n document.addEventListener('focusin', e => {\n if (e.target.matches('input, textarea, select')) {\n if (e.target.dataset.propertyIsEnumerable('initialValue')) {\n // The initial value has already been set.\n return;\n }\n e.target.dataset.initialValue = e.target.value;\n }\n });\n\n document.addEventListener('submit', e => {\n const formNode = getFormFromChild(e.target);\n if (!formNode) {\n // Weird, but watch for this anyway.\n return;\n }\n\n if (formNode.dataset.ignoreSubmission) {\n // This form was submitted by a button which requested that the form checked should not mark it as submitted.\n formNode.dataset.ignoreSubmission = \"false\";\n return;\n }\n\n markFormSubmitted(formNode);\n });\n\n document.addEventListener(eventTypes.editorContentRestored, e => {\n if (e.target != document) {\n resetFormDirtyState(e.target);\n } else {\n resetAllFormDirtyStates();\n }\n });\n\n getString('changesmadereallygoaway', 'moodle')\n .then(changesMadeString => {\n warningString = changesMadeString;\n return;\n })\n .catch();\n\n window.addEventListener('beforeunload', beforeUnloadHandler);\n};\n\n/**\n * Add legacy functions for backwards compatability.\n *\n * @method\n * @private\n */\nconst addLegacyFunctions = () => {\n // Create a curried function to log use of the old function and provide detail on its replacement.\n const getLoggedLegacyFallback = (oldFunctionName, newFunctionName, newFunction) => (...args) => {\n window.console.warn(\n `The moodle-core-formchangechecker has been deprecated ` +\n `and replaced with core_form/changechecker. ` +\n `The ${oldFunctionName} function has been replaced with ${newFunctionName}.`\n );\n newFunction(...args);\n };\n\n /* eslint-disable */\n window.M.core_formchangechecker = {\n init: getLoggedLegacyFallback('init', 'watchFormById', watchFormById),\n reset_form_dirty_state: getLoggedLegacyFallback('reset_form_dirty_state', 'resetFormDirtyState', resetAllFormDirtyStates),\n set_form_changed: getLoggedLegacyFallback('set_form_changed', 'markFormAsDirty', markAllFormsAsDirty),\n set_form_submitted: getLoggedLegacyFallback('set_form_submitted', 'markFormSubmitted', markAllFormsAsSubmitted),\n };\n /* eslint-enable */\n};\n\n/**\n * Watch the form matching the specified ID for changes.\n *\n * @method\n * @param {String} formId\n */\nexport const watchFormById = formId => {\n watchForm(document.getElementById(formId));\n};\n\n/**\n * Reset the dirty state of the form matching the specified ID..\n *\n * @method\n * @param {String} formId\n */\nexport const resetFormDirtyStateById = formId => {\n resetFormDirtyState(document.getElementById(formId));\n};\n\n/**\n * Mark the form matching the specified ID as dirty.\n *\n * @method\n * @param {String} formId\n */\nexport const markFormAsDirtyById = formId => {\n markFormAsDirty(document.getElementById(formId));\n};\n\n// Configure all event listeners.\nstartWatching();\n"],"file":"changechecker.min.js"}