diff --git a/Gruntfile.js b/Gruntfile.js index 5f9109fac3cb0..540eb06aabc94 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -453,6 +453,7 @@ module.exports = function(grunt) { [ WORKING_DIR + 'wp-admin/js/theme-plugin-editor.js' ]: [ './src/js/_enqueues/wp/theme-plugin-editor.js' ], [ WORKING_DIR + 'wp-admin/js/theme.js' ]: [ './src/js/_enqueues/wp/theme.js' ], [ WORKING_DIR + 'wp-admin/js/updates.js' ]: [ './src/js/_enqueues/wp/updates.js' ], + [ WORKING_DIR + 'wp-admin/js/wp-options-unsaved-changes-confirmation.js' ]: [ './src/js/_enqueues/admin/wp-options-unsaved-changes-confirmation.js' ], [ WORKING_DIR + 'wp-admin/js/user-profile.js' ]: [ './src/js/_enqueues/admin/user-profile.js' ], [ WORKING_DIR + 'wp-admin/js/user-suggest.js' ]: [ './src/js/_enqueues/lib/user-suggest.js' ], [ WORKING_DIR + 'wp-admin/js/widgets/custom-html-widgets.js' ]: [ './src/js/_enqueues/wp/widgets/custom-html.js' ], @@ -1192,6 +1193,7 @@ module.exports = function(grunt) { 'src/wp-admin/js/theme-plugin-editor.js': 'src/js/_enqueues/wp/theme-plugin-editor.js', 'src/wp-admin/js/theme.js': 'src/js/_enqueues/wp/theme.js', 'src/wp-admin/js/updates.js': 'src/js/_enqueues/wp/updates.js', + 'src/wp-admin/js/wp-options-unsaved-changes-confirmation.js': 'src/js/_enqueues/admin/wp-options-unsaved-changes-confirmation.js', 'src/wp-admin/js/user-profile.js': 'src/js/_enqueues/admin/user-profile.js', 'src/wp-admin/js/user-suggest.js': 'src/js/_enqueues/lib/user-suggest.js', 'src/wp-admin/js/widgets/custom-html-widgets.js': 'src/js/_enqueues/wp/widgets/custom-html.js', diff --git a/src/js/_enqueues/admin/wp-options-unsaved-changes-confirmation.js b/src/js/_enqueues/admin/wp-options-unsaved-changes-confirmation.js new file mode 100644 index 0000000000000..8dd4017889253 --- /dev/null +++ b/src/js/_enqueues/admin/wp-options-unsaved-changes-confirmation.js @@ -0,0 +1,31 @@ +/* global wp */ +( function () { + var form = document.querySelector( 'form[action="options.php"]' ); + + if ( ! form ) { + return; + } + + var originalFormContent = new URLSearchParams( new FormData( form ) ).toString(); + var __ = wp.i18n.__; + + function beforeUnloadHandler( event ) { + var currentContent = new URLSearchParams( new FormData( form ) ).toString(); + if ( originalFormContent !== currentContent ) { + event.preventDefault(); + return __( + 'The changes you made will be lost if you navigate away from this page.' + ); + } + } + + // Add the beforeunload listener only once a field is modified, to avoid + // breaking bfcache. + document.addEventListener( 'change', function () { + window.addEventListener( 'beforeunload', beforeUnloadHandler ); + }, { once: true } ); + + form.addEventListener( 'submit', function () { + window.removeEventListener( 'beforeunload', beforeUnloadHandler ); + } ); +} )(); diff --git a/src/wp-admin/options-discussion.php b/src/wp-admin/options-discussion.php index 0c350475fe176..2f9fa4226c1a4 100644 --- a/src/wp-admin/options-discussion.php +++ b/src/wp-admin/options-discussion.php @@ -33,6 +33,8 @@ '
' . __( 'Support forums' ) . '
' ); +wp_enqueue_script( 'wp-admin-unsaved-changes-confirmation' ); + require_once ABSPATH . 'wp-admin/admin-header.php'; ?> diff --git a/src/wp-admin/options-general.php b/src/wp-admin/options-general.php index 969065b7008f4..4c167f27b89d2 100644 --- a/src/wp-admin/options-general.php +++ b/src/wp-admin/options-general.php @@ -61,6 +61,8 @@ '' . __( 'Support forums' ) . '
' ); +wp_enqueue_script( 'wp-admin-unsaved-changes-confirmation' ); + require_once ABSPATH . 'wp-admin/admin-header.php'; ?> diff --git a/src/wp-admin/options-media.php b/src/wp-admin/options-media.php index 81ebc9223f543..4172c77eb289d 100644 --- a/src/wp-admin/options-media.php +++ b/src/wp-admin/options-media.php @@ -42,6 +42,8 @@ '' . __( 'Support forums' ) . '
' ); +wp_enqueue_script( 'wp-admin-unsaved-changes-confirmation' ); + require_once ABSPATH . 'wp-admin/admin-header.php'; ?> diff --git a/src/wp-admin/options-permalink.php b/src/wp-admin/options-permalink.php index 046c237b6a948..2e551276a12a5 100644 --- a/src/wp-admin/options-permalink.php +++ b/src/wp-admin/options-permalink.php @@ -69,6 +69,8 @@ get_current_screen()->set_help_sidebar( $help_sidebar_content ); unset( $help_sidebar_content ); +wp_enqueue_script( 'wp-admin-unsaved-changes-confirmation' ); + $home_path = get_home_path(); $iis7_permalinks = iis7_supports_permalinks(); $permalink_structure = get_option( 'permalink_structure' ); diff --git a/src/wp-admin/options-reading.php b/src/wp-admin/options-reading.php index 31facac7edcca..95f61733d7ec7 100644 --- a/src/wp-admin/options-reading.php +++ b/src/wp-admin/options-reading.php @@ -54,6 +54,8 @@ '' . __( 'Support forums' ) . '
' ); +wp_enqueue_script( 'wp-admin-unsaved-changes-confirmation' ); + require_once ABSPATH . 'wp-admin/admin-header.php'; ?> diff --git a/src/wp-admin/options-writing.php b/src/wp-admin/options-writing.php index d40dc0578b315..ac3441c664f6c 100644 --- a/src/wp-admin/options-writing.php +++ b/src/wp-admin/options-writing.php @@ -55,6 +55,7 @@ ); wp_enqueue_script( 'user-profile' ); +wp_enqueue_script( 'wp-admin-unsaved-changes-confirmation' ); require_once ABSPATH . 'wp-admin/admin-header.php'; ?> diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 42d42b3f8781d..e8b09a98ad92b 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -1260,6 +1260,9 @@ function wp_default_scripts( $scripts ) { $scripts->add( 'language-chooser', "/wp-admin/js/language-chooser$suffix.js", array( 'jquery' ), false, 1 ); + $scripts->add( 'wp-admin-unsaved-changes-confirmation', "/wp-admin/js/wp-options-unsaved-changes-confirmation$suffix.js", array( 'wp-i18n' ), false, 1 ); + $scripts->set_translations( 'wp-admin-unsaved-changes-confirmation' ); + $scripts->add( 'user-suggest', "/wp-admin/js/user-suggest$suffix.js", array( 'jquery-ui-autocomplete' ), false, 1 ); $scripts->add( 'admin-bar', "/wp-includes/js/admin-bar$suffix.js", array( 'hoverintent-js' ), false, 1 );