From a7041b951b174741816d9ddda6f4a69675ff4c43 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Fri, 12 Jul 2019 03:24:20 +0000 Subject: [PATCH] TinyMCE: fix adding of too many undo levels for wpviews. The HTML changes several times when a wpview is added. We only want one undo level. Also fixes cases when the cursor is next to an embeddable URL in the Text tab and the user switches to the Visual tab. See #45307. git-svn-id: https://develop.svn.wordpress.org/trunk@45631 602fd350-edb4-49c9-b593-d223f7449a82 --- .../vendor/tinymce/plugins/wpview/plugin.js | 28 ++++++++++++++++--- src/js/_enqueues/wp/mce-view.js | 15 ++++++---- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/js/_enqueues/vendor/tinymce/plugins/wpview/plugin.js b/src/js/_enqueues/vendor/tinymce/plugins/wpview/plugin.js index 1e3968d2c3..573ecb4167 100644 --- a/src/js/_enqueues/vendor/tinymce/plugins/wpview/plugin.js +++ b/src/js/_enqueues/vendor/tinymce/plugins/wpview/plugin.js @@ -25,7 +25,7 @@ return '

' + window.decodeURIComponent( $1 ) + '

'; } - if ( ! content ) { + if ( ! content || content.indexOf( ' data-wpview-' ) === -1 ) { return content; } @@ -111,10 +111,30 @@ event.content = resetViews( event.content ); } ); - // Replace views with their text inside undo levels. - // This also prevents that new levels are added when there are changes inside the views. + // Prevent adding of undo levels when replacing wpview markers + // or when there are changes only in the (non-editable) previews. editor.on( 'beforeaddundo', function( event ) { - event.level.content = resetViews( event.level.content ); + var lastContent; + var newContent = event.level.content || ( event.level.fragments && event.level.fragments.join( '' ) ); + + if ( ! event.lastLevel ) { + lastContent = editor.startContent; + } else { + lastContent = event.lastLevel.content || ( event.lastLevel.fragments && event.lastLevel.fragments.join( '' ) ); + } + + if ( + ! newContent || + ! lastContent || + newContent.indexOf( ' data-wpview-' ) === -1 || + lastContent.indexOf( ' data-wpview-' ) === -1 + ) { + return; + } + + if ( resetViews( lastContent ) === resetViews( newContent ) ) { + event.preventDefault(); + } } ); // Make sure views are copied as their text. diff --git a/src/js/_enqueues/wp/mce-view.js b/src/js/_enqueues/wp/mce-view.js index e69c748a10..e0439c41c7 100644 --- a/src/js/_enqueues/wp/mce-view.js +++ b/src/js/_enqueues/wp/mce-view.js @@ -444,12 +444,16 @@ '
' ); - editor.$( node ).replaceWith( $viewNode ); + editor.undoManager.ignore( function() { + editor.$( node ).replaceWith( $viewNode ); + } ); if ( selected ) { setTimeout( function() { - editor.selection.select( $viewNode[0] ); - editor.selection.collapse(); + editor.undoManager.ignore( function() { + editor.selection.select( $viewNode[0] ); + editor.selection.collapse(); + } ); } ); } } ); @@ -961,8 +965,9 @@ views.register( 'embedURL', _.extend( {}, embed, { match: function( content ) { - var re = /(^|

)(https?:\/\/[^\s"]+?)(<\/p>\s*|$)/gi, - match = re.exec( content ); + // There may be a "bookmark" node next to the URL... + var re = /(^|

(?:]+>\s*<\/span>)?)(https?:\/\/[^\s"]+?)((?:]+>\s*<\/span>)?<\/p>\s*|$)/gi; + var match = re.exec( content ); if ( match ) { return {