From bbd3e0174edaa0b855a2f3af044ca2272d9c7a2a Mon Sep 17 00:00:00 2001 From: Ella van Dorpe Date: Thu, 17 Nov 2016 20:31:12 +0000 Subject: [PATCH] TinyMCE views: fix Firefox issues. * Set focus before rendering to prevent reload in Firefox. * Rerender views if they are unloaded. * Remove timeout added in [29513]. * Fix argument in wp.mce.views.render. * Empty views on hide. Missed in #36434. Props gitlost, azaozz, iseulde. Fixes #38511. git-svn-id: https://develop.svn.wordpress.org/trunk@39282 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/js/mce-view.js | 227 +++++++++--------- .../js/tinymce/plugins/wpview/plugin.js | 5 +- 2 files changed, 123 insertions(+), 109 deletions(-) diff --git a/src/wp-includes/js/mce-view.js b/src/wp-includes/js/mce-view.js index a2dca4272b..8c8de56a0e 100644 --- a/src/wp-includes/js/mce-view.js +++ b/src/wp-includes/js/mce-view.js @@ -157,6 +157,14 @@ text = tinymce.DOM.decode( text ); + if ( text.indexOf( '[' ) !== -1 && text.indexOf( ']' ) !== -1 ) { + // Looks like a shortcode? Remove any line breaks from inside of shortcodes + // or autop will replace them with

and
later and the string won't match. + text = text.replace( /\[[^\]]+\]/g, function( match ) { + return match.replace( /[\r\n]/g, '' ); + }); + } + if ( ! force ) { instance = this.getInstance( text ); @@ -208,7 +216,7 @@ */ render: function( force ) { _.each( instances, function( instance ) { - instance.render( force ); + instance.render( null, force ); } ); }, @@ -490,7 +498,8 @@ var dom = editor.dom, styles = '', bodyClasses = editor.getBody().className || '', - editorHead = editor.getDoc().getElementsByTagName( 'head' )[0]; + editorHead = editor.getDoc().getElementsByTagName( 'head' )[0], + iframe, iframeWin, iframeDoc, MutationObserver, observer, i, block; tinymce.each( dom.$( 'link[rel="stylesheet"]', editorHead ), function( link ) { if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 && @@ -511,125 +520,127 @@ }, '\u200B' ); } - // Seems the browsers need a bit of time to insert/set the view nodes, - // or the iframe will fail especially when switching Text => Visual. - setTimeout( function() { - var iframe, iframeWin, iframeDoc, MutationObserver, observer, i, block; + editor.undoManager.transact( function() { + node.innerHTML = ''; - editor.undoManager.transact( function() { - node.innerHTML = ''; - - iframe = dom.add( node, 'iframe', { - /* jshint scripturl: true */ - src: tinymce.Env.ie ? 'javascript:""' : '', - frameBorder: '0', - allowTransparency: 'true', - scrolling: 'no', - 'class': 'wpview-sandbox', - style: { - width: '100%', - display: 'block' - }, - height: self.iframeHeight - } ); - - dom.add( node, 'span', { 'class': 'mce-shim' } ); - dom.add( node, 'span', { 'class': 'wpview-end' } ); + iframe = dom.add( node, 'iframe', { + /* jshint scripturl: true */ + src: tinymce.Env.ie ? 'javascript:""' : '', + frameBorder: '0', + allowTransparency: 'true', + scrolling: 'no', + 'class': 'wpview-sandbox', + style: { + width: '100%', + display: 'block' + }, + height: self.iframeHeight } ); - // Bail if the iframe node is not attached to the DOM. - // Happens when the view is dragged in the editor. - // There is a browser restriction when iframes are moved in the DOM. They get emptied. - // The iframe will be rerendered after dropping the view node at the new location. - if ( ! iframe.contentWindow ) { + dom.add( node, 'span', { 'class': 'mce-shim' } ); + dom.add( node, 'span', { 'class': 'wpview-end' } ); + } ); + + // Bail if the iframe node is not attached to the DOM. + // Happens when the view is dragged in the editor. + // There is a browser restriction when iframes are moved in the DOM. They get emptied. + // The iframe will be rerendered after dropping the view node at the new location. + if ( ! iframe.contentWindow ) { + return; + } + + iframeWin = iframe.contentWindow; + iframeDoc = iframeWin.document; + iframeDoc.open(); + + iframeDoc.write( + '' + + '' + + '' + + '' + + head + + styles + + '' + + '' + + '' + + body + + '' + + '' + ); + + iframeDoc.close(); + + function resize() { + var $iframe; + + if ( block ) { return; } - iframeWin = iframe.contentWindow; - iframeDoc = iframeWin.document; - iframeDoc.open(); + // Make sure the iframe still exists. + if ( iframe.contentWindow ) { + $iframe = $( iframe ); + self.iframeHeight = $( iframeDoc.body ).height(); - iframeDoc.write( - '' + - '' + - '' + - '' + - head + - styles + - '' + - '' + - '' + - body + - '' + - '' - ); - - iframeDoc.close(); - - function resize() { - var $iframe; - - if ( block ) { - return; - } - - // Make sure the iframe still exists. - if ( iframe.contentWindow ) { - $iframe = $( iframe ); - self.iframeHeight = $( iframeDoc.body ).height(); - - if ( $iframe.height() !== self.iframeHeight ) { - $iframe.height( self.iframeHeight ); - editor.nodeChanged(); - } + if ( $iframe.height() !== self.iframeHeight ) { + $iframe.height( self.iframeHeight ); + editor.nodeChanged(); } } + } - if ( self.iframeHeight ) { - block = true; + if ( self.iframeHeight ) { + block = true; - setTimeout( function() { - block = false; - resize(); - }, 3000 ); + setTimeout( function() { + block = false; + resize(); + }, 3000 ); + } + + function reload() { + $( node ).data( 'rendered', null ); + + setTimeout( function() { + wp.mce.views.render(); + } ); + } + + $( iframeWin ).on( 'load', resize ).on( 'unload', reload ); + + MutationObserver = iframeWin.MutationObserver || iframeWin.WebKitMutationObserver || iframeWin.MozMutationObserver; + + if ( MutationObserver ) { + observer = new MutationObserver( _.debounce( resize, 100 ) ); + + observer.observe( iframeDoc.body, { + attributes: true, + childList: true, + subtree: true + } ); + } else { + for ( i = 1; i < 6; i++ ) { + setTimeout( resize, i * 700 ); } + } - $( iframeWin ).on( 'load', resize ); - - MutationObserver = iframeWin.MutationObserver || iframeWin.WebKitMutationObserver || iframeWin.MozMutationObserver; - - if ( MutationObserver ) { - observer = new MutationObserver( _.debounce( resize, 100 ) ); - - observer.observe( iframeDoc.body, { - attributes: true, - childList: true, - subtree: true - } ); - } else { - for ( i = 1; i < 6; i++ ) { - setTimeout( resize, i * 700 ); - } - } - - callback && callback.call( self, editor, node ); - }, 50 ); + callback && callback.call( self, editor, node ); }, rendered ); }, diff --git a/src/wp-includes/js/tinymce/plugins/wpview/plugin.js b/src/wp-includes/js/tinymce/plugins/wpview/plugin.js index 2fc0e4b3d8..3b9e7ef6de 100644 --- a/src/wp-includes/js/tinymce/plugins/wpview/plugin.js +++ b/src/wp-includes/js/tinymce/plugins/wpview/plugin.js @@ -93,11 +93,14 @@ // Replace any new markers nodes with views. editor.on( 'setcontent', function() { + // Make sure that the editor is focussed. + // May refresh the content internally which resets the iframes. + editor.focus(); wp.mce.views.render(); } ); // Empty view nodes for easier processing. - editor.on( 'preprocess', function( event ) { + editor.on( 'preprocess hide', function( event ) { editor.$( 'div[data-wpview-text], p[data-wpview-marker]', event.node ).each( function( i, node ) { node.innerHTML = '.'; } );