From 4799701cd35f55eaec71b9a6eb036285fd136f9f Mon Sep 17 00:00:00 2001 From: Jake Spurlock Date: Wed, 27 Jan 2021 19:50:30 +0000 Subject: [PATCH] Editor: Fix improper triggering of the "Are you sure" prompt when navigating away from the old, "classic" Edit Post screen and there are no changes. Was triggered when there is an instance of TinyMCE in the Excerpt postbox. This brings the changes from [49807] to the 5.6 branch. Props rodrigosprimo, jonathanstegall, kevin940726, azaozz, metalandcoffee, ifnoob. Fixes #52038. git-svn-id: https://develop.svn.wordpress.org/branches/5.6@50031 602fd350-edb4-49c9-b593-d223f7449a82 --- src/js/_enqueues/admin/post.js | 16 +++++++--- src/js/_enqueues/wp/autosave.js | 54 +++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/js/_enqueues/admin/post.js b/src/js/_enqueues/admin/post.js index 17445df17e..0c95258348 100644 --- a/src/js/_enqueues/admin/post.js +++ b/src/js/_enqueues/admin/post.js @@ -488,12 +488,20 @@ jQuery(document).ready( function($) { * When the user is trying to load another page, or reloads current page * show a confirmation dialog when there are unsaved changes. */ - $(window).on( 'beforeunload.edit-post', function() { - var editor = typeof tinymce !== 'undefined' && tinymce.get('content'); + $( window ).on( 'beforeunload.edit-post', function( event ) { + var editor = window.tinymce && window.tinymce.get( 'content' ); + var changed = false; - if ( ( editor && ! editor.isHidden() && editor.isDirty() ) || - ( wp.autosave && wp.autosave.server.postChanged() ) ) { + if ( wp.autosave ) { + changed = wp.autosave.server.postChanged(); + } else if ( editor ) { + changed = ( ! editor.isHidden() && editor.isDirty() ); + } + if ( changed ) { + event.preventDefault(); + // The return string is needed for browser compat. + // See https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event. return __( 'The changes you made will be lost if you navigate away from this page.' ); } }).on( 'unload.edit-post', function( event ) { diff --git a/src/js/_enqueues/wp/autosave.js b/src/js/_enqueues/wp/autosave.js index d2f06b8046..a1bd570c68 100644 --- a/src/js/_enqueues/wp/autosave.js +++ b/src/js/_enqueues/wp/autosave.js @@ -36,8 +36,24 @@ window.autosave = function() { */ function autosave() { var initialCompareString, - lastTriggerSave = 0, - $document = $(document); + initialCompareData = {}, + lastTriggerSave = 0, + $document = $( document ); + + /** + * Sets the initial compare data. + * + * @since 5.6.1 + */ + function setInitialCompare() { + initialCompareData = { + post_title: $( '#title' ).val() || '', + content: $( '#content' ).val() || '', + excerpt: $( '#excerpt' ).val() || '' + }; + + initialCompareString = getCompareString( initialCompareData ); + } /** * Returns the data saved in both local and remote autosave. @@ -686,6 +702,32 @@ window.autosave = function() { * @return {boolean} True if the post has been changed. */ function postChanged() { + var changed = false; + + // If there are TinyMCE instances, loop through them. + if ( window.tinymce ) { + window.tinymce.each( [ 'content', 'excerpt' ], function( field ) { + var editor = window.tinymce.get( field ); + + if ( ! editor || editor.isHidden() ) { + if ( $( '#' + field ).val() !== initialCompareData[ field ] ) { + changed = true; + // Break. + return false; + } + } else if ( editor.isDirty() ) { + changed = true; + return false; + } + } ); + + if ( $( '#title' ).val() !== initialCompareData.post_title ) { + changed = true; + } + + return changed; + } + return getCompareString() !== initialCompareString; } @@ -832,16 +874,16 @@ window.autosave = function() { * @return {void} */ $document.on( 'tinymce-editor-init.autosave', function( event, editor ) { - if ( editor.id === 'content' ) { + // Reset the initialCompare data after the TinyMCE instances have been initialized. + if ( 'content' === editor.id || 'excerpt' === editor.id ) { window.setTimeout( function() { editor.save(); - initialCompareString = getCompareString(); + setInitialCompare(); }, 1000 ); } }).ready( function() { - // Set the initial compare string in case TinyMCE is not used or not loaded first. - initialCompareString = getCompareString(); + setInitialCompare(); }); return {