diff --git a/.babelrc b/.babelrc index 857e7ba32..c72dfe479 100644 --- a/.babelrc +++ b/.babelrc @@ -4,6 +4,7 @@ ], "plugins": [ ["@babel/plugin-proposal-decorators", { "legacy": true }], - ["@babel/plugin-proposal-class-properties", { "loose": true }] + ["@babel/plugin-proposal-class-properties", { "loose": true }], + ["@babel/transform-runtime"] ] } diff --git a/frontend/src/utils/form/navigate-away-prompt.js b/frontend/src/utils/form/navigate-away-prompt.js index 21c4f4661..b0542ef9f 100644 --- a/frontend/src/utils/form/navigate-away-prompt.js +++ b/frontend/src/utils/form/navigate-away-prompt.js @@ -2,6 +2,16 @@ import { Utility } from '../../core/utility'; import { AUTO_SUBMIT_BUTTON_UTIL_SELECTOR } from './auto-submit-button'; import { AUTO_SUBMIT_INPUT_UTIL_SELECTOR } from './auto-submit-input'; +/** + * Key generator from an arbitrary number of FormData objects. + * @param {...any} formDatas FormData objects + */ +function* generatorFromFormDatas(...formDatas) { + for (let formData of formDatas) { + yield* formData.keys(); + } +} + const NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS = 'navigate-away-prompt--initialized'; const NAVIGATE_AWAY_PROMPT_UTIL_OPTOUT = '[uw-no-navigate-away-prompt]'; @@ -12,7 +22,7 @@ export class NavigateAwayPrompt { _element; - _touched = false; + _initFormData; _unloadDueToSubmit = false; constructor(element) { @@ -21,6 +31,7 @@ export class NavigateAwayPrompt { } this._element = element; + this._initFormData = new FormData(this._element); if (this._element.classList.contains(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS)) { return false; @@ -40,10 +51,6 @@ export class NavigateAwayPrompt { this._element.addEventListener('submit', () => { this._unloadDueToSubmit = true; }); - this._element.addEventListener('change', () => { - this._touched = true; - this._unloadDueToSubmit = false; - }); // mark initialized this._element.classList.add(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS); @@ -55,9 +62,20 @@ export class NavigateAwayPrompt { } _beforeUnloadHandler = (event) => { + // compare every value of the current FormData with every corresponding value of the initial FormData and set formDataHasChanged to true if there is at least one change + const currentFormData = new FormData(this._element); + var formDataHasChanged = false; + for (let key of generatorFromFormDatas(this._initFormData, currentFormData)) { + if (currentFormData.get(key) !== this._initFormData.get(key)) { + formDataHasChanged = true; + break; + } + } + // allow the event to happen if the form was not touched by the - // user or the unload event was initiated by a form submit - if (!this._touched || this._unloadDueToSubmit) { + // user (i.e. if the current FormData is equal to the initial FormData) + // or the unload event was initiated by a form submit + if (!formDataHasChanged || this._unloadDueToSubmit) { return false; } diff --git a/package-lock.json b/package-lock.json index 0bc368ac1..52e105bab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1155,6 +1155,18 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-transform-runtime": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz", + "integrity": "sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "resolve": "^1.8.1", + "semver": "^5.5.1" + } + }, "@babel/plugin-transform-shorthand-properties": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", @@ -1285,19 +1297,17 @@ } }, "@babel/runtime": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", - "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", - "dev": true, + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", + "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==", "requires": { "regenerator-runtime": "^0.13.2" }, "dependencies": { "regenerator-runtime": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==", - "dev": true + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" } } }, diff --git a/package.json b/package.json index 9cb5d345b..d0aa6a1b6 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "@babel/core": "^7.5.5", "@babel/plugin-proposal-class-properties": "^7.5.5", "@babel/plugin-proposal-decorators": "^7.4.4", + "@babel/plugin-transform-runtime": "^7.5.5", "@babel/preset-env": "^7.5.5", "@commitlint/cli": "^8.1.0", "@commitlint/config-conventional": "^8.1.0", @@ -89,6 +90,7 @@ "webpack-cli": "^3.3.7" }, "dependencies": { + "@babel/runtime": "^7.5.5", "moment": "^2.24.0", "npm": "^6.11.2", "tail.datetime": "git+https://git@github.com/uni2work/tail.DateTime.git#update-view-on-select"