Make WordPress Core

Changeset 32022


Ignore:
Timestamp:
04/04/2015 10:59:07 PM (9 years ago)
Author:
azaozz
Message:

TinyMCE wpView:

  • Fix editor undo levels.
  • Remove views and markers in the DOM before serialization.
  • Unbind views before removing them on hide.
  • Empty the content in the timeout, so it doesn't render iframes twice.

Props iseulde. Fixes #31669.

Location:
trunk/src/wp-includes
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/js/mce-view.js

    r31972 r32022  
    8888         *
    8989         * @param {String} content The string to scan.
     90         *
     91         * @return {String} The string with markers.
    9092         */
    9193        setMarkers: function( content ) {
     
    299301         * Renders all view nodes tied to this view instance that are not yet rendered.
    300302         *
     303         * @param {String} content The content to render. Optional.
    301304         * @param {Boolean} force Rerender all view nodes tied to this view instance.
    302305         */
    303         render: function( force ) {
     306        render: function( content, force ) {
     307            if ( content != null ) {
     308                this.content = content;
     309            }
     310
     311            content = this.getContent();
     312
    304313            // If there's nothing to render an no loader needs to be shown, stop.
    305             if ( ! this.loader && ! this.getContent() ) {
     314            if ( ! this.loader && ! content ) {
    306315                return;
    307316            }
     
    313322            this.replaceMarkers();
    314323
    315             if ( this.getContent() ) {
    316                 this.setContent( this.getContent(), function( editor, node ) {
    317                     $( node ).data( 'rendered', true ).trigger( 'wp-mce-view-bind' );
     324            if ( content ) {
     325                this.setContent( content, function( editor, node ) {
     326                    $( node ).data( 'rendered', true );
     327                    this.bindNode.call( this, editor, node );
    318328                }, force ? null : false );
    319329            } else {
     
    323333
    324334        /**
     335         * Binds a given node after its content is added to the DOM.
     336         */
     337        bindNode: function() {},
     338
     339        /**
     340         * Unbinds a given node before its content is removed from the DOM.
     341         */
     342        unbindNode: function() {},
     343
     344        /**
    325345         * Unbinds all view nodes tied to this view instance.
    326346         * Runs before their content is removed from the DOM.
     
    328348        unbind: function() {
    329349            this.getNodes( function( editor, node ) {
     350                this.unbindNode.call( this, editor, node );
    330351                $( node ).trigger( 'wp-mce-view-unbind' );
    331352            }, true );
     
    448469                    contentNode.appendChild( _.isString( content ) ? editor.dom.createFragment( content ) : content );
    449470
    450                     callback && callback.apply( this, arguments );
     471                    callback && callback.call( this, editor, node, contentNode );
    451472                }, rendered );
    452473            }
     
    462483         */
    463484        setIframes: function( head, body, callback, rendered ) {
    464             var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
     485            var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
     486                self = this;
    465487
    466488            this.getNodes( function( editor, node, content ) {
    467                 // Seems Firefox needs a bit of time to insert/set the view nodes,
     489                var dom = editor.dom,
     490                    styles = '',
     491                    bodyClasses = editor.getBody().className || '',
     492                    editorHead = editor.getDoc().getElementsByTagName( 'head' )[0],
     493                    iframe, iframeDoc, observer, i;
     494
     495                tinymce.each( dom.$( 'link[rel="stylesheet"]', editorHead ), function( link ) {
     496                    if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 &&
     497                        link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 ) {
     498
     499                        styles += dom.getOuterHTML( link );
     500                    }
     501                } );
     502
     503                // Seems the browsers need a bit of time to insert/set the view nodes,
    468504                // or the iframe will fail especially when switching Text => Visual.
    469505                setTimeout( function() {
    470                     var dom = editor.dom,
    471                         styles = '',
    472                         bodyClasses = editor.getBody().className || '',
    473                         iframe, iframeDoc, observer, i;
    474 
    475                     tinymce.each( dom.$(
    476                         'link[rel="stylesheet"]',
    477                         editor.getDoc().getElementsByTagName( 'head' )[0]
    478                     ), function( link ) {
    479                         if (
    480                             link.href &&
    481                             link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 &&
    482                             link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1
    483                         ) {
    484                             styles += dom.getOuterHTML( link );
    485                         }
    486                     } );
    487 
    488506                    content.innerHTML = '';
    489507
     
    583601                    } );
    584602
    585                     callback && callback.apply( this, arguments );
     603                    callback && callback.call( self, editor, node );
    586604                }, 50 );
    587605            }, rendered );
     
    665683         */
    666684        remove: function( editor, node ) {
     685            this.unbindNode.call( this, editor, node, $( node ).find( '.wpview-content' ).get( 0 ) );
    667686            $( node ).trigger( 'wp-mce-view-unbind' );
    668687            editor.dom.remove( node );
     
    729748                } );
    730749
    731                 self.content = self.template( {
     750                self.render( self.template( {
    732751                    attachments: attachments,
    733752                    columns: attrs.columns ? parseInt( attrs.columns, 10 ) : wp.media.galleryDefaults.columns
    734                 } );
    735 
    736                 self.render();
     753                } ) );
    737754            } )
    738755            .fail( function( jqXHR, textStatus ) {
     
    755772            }
    756773
    757             wp.ajax.send( this.action, {
    758                 data: {
    759                     post_ID: postID,
    760                     type: this.shortcode.tag,
    761                     shortcode: this.shortcode.string()
    762                 }
     774            wp.ajax.post( this.action, {
     775                post_ID: postID,
     776                type: this.shortcode.tag,
     777                shortcode: this.shortcode.string()
    763778            } )
    764779            .done( function( response ) {
    765                 self.content = response;
    766                 self.render();
     780                self.render( response );
    767781            } )
    768782            .fail( function( response ) {
  • trunk/src/wp-includes/js/tinymce/plugins/wpview/plugin.js

    r31931 r32022  
    55 */
    66tinymce.PluginManager.add( 'wpview', function( editor ) {
    7     var selected,
     7    var $ = editor.$,
     8        selected,
    89        Env = tinymce.Env,
    910        VK = tinymce.util.VK,
     
    154155    // Remove the content of view wrappers from HTML string
    155156    function emptyViews( content ) {
    156         return content.replace(/<div[^>]+data-wpview-text=\"([^"]+)"[^>]*>[\s\S]+?wpview-selection-after[^>]+>(?:&nbsp;|\u00a0)*<\/p><\/div>/g, '$1' );
     157        content = content.replace( /<div[^>]+data-wpview-text="([^"]+)"[^>]*>[\s\S]+?wpview-selection-after[^>]+>[^<>]*<\/p>\s*<\/div>/g, function( all, match ) {
     158            return '<p>' + window.decodeURIComponent( match ) + '</p>';
     159        });
     160
     161        return content.replace( / data-wpview-marker="[^"]+"/g, '' );
    157162    }
    158163
    159164    // Prevent adding undo levels on changes inside a view wrapper
    160165    editor.on( 'BeforeAddUndo', function( event ) {
    161         if ( event.lastLevel && emptyViews( event.level.content ) === emptyViews( event.lastLevel.content ) ) {
    162             event.preventDefault();
     166        if ( event.level.content ) {
     167            event.level.content = emptyViews( event.level.content );
    163168        }
    164169    });
     
    169174    editor.on( 'BeforeSetContent', function( event ) {
    170175        var node;
     176
     177        if ( ! event.selection ) {
     178            wp.mce.views.unbind();
     179        }
    171180
    172181        if ( ! event.content ) {
     
    340349    });
    341350
     351    function resetViews( rootNode ) {
     352        // Replace view nodes
     353        $( 'div[data-wpview-text]', rootNode ).each( function( i, node ) {
     354            var $node = $( node ),
     355                text = window.decodeURIComponent( $node.attr( 'data-wpview-text' ) || '' );
     356
     357            if ( text && node.parentNode ) {
     358                $node.replaceWith( $( editor.dom.create('p') ).text( text ) );
     359            }
     360        });
     361
     362        // Remove marker attributes
     363        $( 'p[data-wpview-marker]', rootNode ).attr( 'data-wpview-marker', null );
     364    }
     365
    342366    editor.on( 'PreProcess', function( event ) {
    343         // Empty the wpview wrap nodes
    344         tinymce.each( editor.dom.select( 'div[data-wpview-text]', event.node ), function( node ) {
    345             node.textContent = node.innerText = '\u00a0';
    346         });
    347     });
    348 
    349     editor.on( 'PostProcess', function( event ) {
    350         if ( event.content ) {
    351             event.content = event.content.replace( /<div [^>]*?data-wpview-text="([^"]*)"[^>]*>[\s\S]*?<\/div>/g, function( match, shortcode ) {
    352                 if ( shortcode ) {
    353                     return '<p>' + window.decodeURIComponent( shortcode ) + '</p>';
    354                 }
    355                 return ''; // If error, remove the view wrapper
    356             });
    357         }
     367        // Replace the view nodes with their text in the DOM clone.
     368        resetViews( event.node );
     369    }, true );
     370
     371    editor.on( 'hide', function() {
     372        // Replace the view nodes with their text directly in the editor body.
     373        wp.mce.views.unbind();
     374        resetViews( editor.getBody() );
    358375    });
    359376
  • trunk/src/wp-includes/version.php

    r31998 r32022  
    1919 * @global string $tinymce_version
    2020 */
    21 $tinymce_version = '4109-20150310';
     21$tinymce_version = '4109-20150404';
    2222
    2323/**
Note: See TracChangeset for help on using the changeset viewer.