From fed6b2c8e9667deb4271284658aaee6b6492bfc4 Mon Sep 17 00:00:00 2001 From: Anukasha Singh Date: Fri, 13 Feb 2026 17:36:29 +0530 Subject: [PATCH] adding a js confirmation before navigating away from settings menus --- Gruntfile.js | 2 ++ src/js/_enqueues/admin/options.js | 51 +++++++++++++++++++++++++++++ src/wp-admin/options-discussion.php | 2 ++ src/wp-admin/options-general.php | 2 ++ src/wp-admin/options-media.php | 2 ++ src/wp-admin/options-permalink.php | 2 ++ src/wp-admin/options-reading.php | 2 ++ src/wp-admin/options-writing.php | 2 +- src/wp-includes/script-loader.php | 3 ++ 9 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/js/_enqueues/admin/options.js diff --git a/Gruntfile.js b/Gruntfile.js index 9363a26a746a6..a47d82199fc91 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -438,6 +438,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/options.js' ]: [ './src/js/_enqueues/admin/options.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' ], @@ -1059,6 +1060,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/options.js': 'src/js/_enqueues/admin/options.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/options.js b/src/js/_enqueues/admin/options.js new file mode 100644 index 0000000000000..5df9c79ea5e04 --- /dev/null +++ b/src/js/_enqueues/admin/options.js @@ -0,0 +1,51 @@ +/** + * @output wp-admin/js/options.js + */ + +/** + * Detects unsaved changes on settings forms and warns users before navigating away. + * + * @since 7.0.0 + */ +( function( $ ) { + var $form, + originalFormContent, + isSubmitting = false, + __ = wp.i18n.__; + + $( function() { + // Target all settings forms on options pages. + $form = $( 'form[action="options.php"]' ); + + // Exit if no form is found. + if ( ! $form.length ) { + return; + } + + // Store the original form state. + originalFormContent = $form.serialize(); + + // Track form submission to avoid false warnings. + $form.on( 'submit', function() { + isSubmitting = true; + } ); + } ); + + /** + * Warn the user if they have unsaved changes. + * + * The browser will show a native confirmation dialog when the user + * attempts to leave the page with unsaved changes. + */ + $( window ).on( 'beforeunload', function() { + // Skip warning if form is being submitted or content hasn't changed. + if ( isSubmitting || ! $form || ! $form.length ) { + return; + } + + if ( originalFormContent !== $form.serialize() ) { + return __( 'The changes you made will be lost if you navigate away from this page.' ); + } + } ); + +}( jQuery ) ); diff --git a/src/wp-admin/options-discussion.php b/src/wp-admin/options-discussion.php index 0c350475fe176..442e922c2cd7e 100644 --- a/src/wp-admin/options-discussion.php +++ b/src/wp-admin/options-discussion.php @@ -33,6 +33,8 @@ '

' . __( 'Support forums' ) . '

' ); +wp_enqueue_script( 'options' ); + 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 214899d5a11a6..431145072f0d9 100644 --- a/src/wp-admin/options-general.php +++ b/src/wp-admin/options-general.php @@ -61,6 +61,8 @@ '

' . __( 'Support forums' ) . '

' ); +wp_enqueue_script( 'options' ); + 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..3bacbd27bd907 100644 --- a/src/wp-admin/options-media.php +++ b/src/wp-admin/options-media.php @@ -42,6 +42,8 @@ '

' . __( 'Support forums' ) . '

' ); +wp_enqueue_script( 'options' ); + 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 2a1b46fba2102..837c5226f521c 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( 'options' ); + $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 d08abc108d669..ea7835657b421 100644 --- a/src/wp-admin/options-reading.php +++ b/src/wp-admin/options-reading.php @@ -54,6 +54,8 @@ '

' . __( 'Support forums' ) . '

' ); +wp_enqueue_script( 'options' ); + 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 6f85b54679327..61443f94ee0c4 100644 --- a/src/wp-admin/options-writing.php +++ b/src/wp-admin/options-writing.php @@ -54,7 +54,7 @@ '

' . __( 'Support forums' ) . '

' ); -wp_enqueue_script( 'user-profile' ); +wp_enqueue_script( 'options' ); 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 4e9de5a0a7ed9..80f049800d249 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -1256,6 +1256,9 @@ function wp_default_scripts( $scripts ) { $scripts->add( 'language-chooser', "/wp-admin/js/language-chooser$suffix.js", array( 'jquery' ), false, 1 ); + $scripts->add( 'options', "/wp-admin/js/options$suffix.js", array( 'jquery', 'wp-i18n' ), false, 1 ); + $scripts->set_translations( 'options' ); + $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 );