Make WordPress Core

Ticket #24409: 24409-07.patch

File 24409-07.patch, 22.1 KB (added by gcorne, 11 years ago)
  • src/wp-includes/class-wp-editor.php

    diff --git src/wp-includes/class-wp-editor.php src/wp-includes/class-wp-editor.php
    index bcbc631..a829945 100644
    final class _WP_Editors { 
    207207                                $ext_plugins = '';
    208208
    209209                                if ( $set['teeny'] ) {
    210                                         self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array( 'fullscreen', 'link', 'image', 'wordpress', 'wplink' ), $editor_id );
     210                                        self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array( 'fullscreen', 'link', 'image', 'wordpress', 'wpeditimage', 'wplink' ), $editor_id );
    211211                                } else {
    212212                                        /**
    213213                                         * TinyMCE external plugins filter
    final class _WP_Editors { 
    335335                                        self::$first_init['external_plugins'] = json_encode( $mce_external_plugins );
    336336                                }
    337337
    338                                 // WordPress default stylesheet
    339                                 $mce_css = array( self::$baseurl . '/skins/wordpress/wp-content.css' );
     338                                $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
     339                                $version = 'ver=' . $GLOBALS['wp_version'];
     340                                $dashicons = includes_url( "css/dashicons$suffix.css?$version" );
     341
     342                                // WordPress default stylesheet and dashicons
     343                                $mce_css = array( $dashicons, self::$baseurl . '/skins/wordpress/wp-content.css' );
    340344
    341345                                // load editor_style.css if the current theme supports it
    342346                                if ( ! empty( $GLOBALS['editor_styles'] ) && is_array( $GLOBALS['editor_styles'] ) ) {
  • src/wp-includes/js/tinymce/plugins/wpeditimage/plugin.js

    diff --git src/wp-includes/js/tinymce/plugins/wpeditimage/plugin.js src/wp-includes/js/tinymce/plugins/wpeditimage/plugin.js
    index 6681eda..f625097 100644
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    4242
    4343                        width = parseInt( w, 10 ) + 10;
    4444
    45                         return '<div class="mceTemp" draggable="true"><dl id="'+ id +'" class="wp-caption '+ cls +'" style="width: '+ width +'px">' +
     45                        return '<div class="mceTemp"><dl id="'+ id +'" class="wp-caption '+ cls +'" style="width: '+ width +'px">' +
    4646                                '<dt class="wp-caption-dt">'+ img +'</dt><dd class="wp-caption-dd">'+ cap +'</dd></dl></div>';
    4747                });
    4848        }
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    102102        }
    103103
    104104        function extractImageData( imageNode ) {
    105                 var classes, metadata, captionBlock, caption;
     105                var classes, metadata, captionBlock, caption,
     106                        dom = editor.dom;
    106107
    107108                // default attributes
    108109                metadata = {
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    118119                        linkUrl: ''
    119120                };
    120121
    121                 metadata.url = editor.dom.getAttrib( imageNode, 'src' );
    122                 metadata.alt = editor.dom.getAttrib( imageNode, 'alt' );
    123                 metadata.width = parseInt( editor.dom.getAttrib( imageNode, 'width' ), 10 );
    124                 metadata.height = parseInt( editor.dom.getAttrib( imageNode, 'height' ), 10 );
     122                metadata.url = dom.getAttrib( imageNode, 'src' );
     123                metadata.alt = dom.getAttrib( imageNode, 'alt' );
     124                metadata.width = parseInt( dom.getAttrib( imageNode, 'width' ), 10 );
     125                metadata.height = parseInt( dom.getAttrib( imageNode, 'height' ), 10 );
    125126
    126                 //TODO: probably should capture attributes on both the <img /> and the <a /> so that they can be restored when the image and/or caption are updated
     127                //TODO: probably should capture attributes on both the <img /> and the <a /> so that they can be restored
     128                // when the image and/or caption are updated
    127129                // maybe use getAttribs()
    128130
    129131                // extract meta data from classes (candidate for turning into a method)
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    144146                } );
    145147
    146148                // extract caption
    147                 captionBlock = editor.dom.getParents( imageNode, '.wp-caption' );
     149                captionBlock = dom.getParents( imageNode, '.wp-caption' );
    148150
    149151                if ( captionBlock.length ) {
    150152                        captionBlock = captionBlock[0];
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    155157                                        metadata.align = name.replace( 'align', '' );
    156158                                }
    157159                        } );
    158                         caption = editor.dom.select( 'dd.wp-caption-dd', captionBlock );
     160
     161                        caption = dom.select( 'dd.wp-caption-dd', captionBlock );
    159162                        if ( caption.length ) {
    160163                                caption = caption[0];
    161164                                // need to do some more thinking about this
    162165                                metadata.caption = editor.serializer.serialize( caption )
    163166                                        .replace( /<br[^>]*>/g, '$&\n' ).replace( /^<p>/, '' ).replace( /<\/p>$/, '' );
    164 
    165167                        }
    166168                }
    167169
    168170                // extract linkTo
    169                 if ( imageNode.parentNode.nodeName === 'A' ) {
    170                         metadata.linkUrl = editor.dom.getAttrib( imageNode.parentNode, 'href' );
     171                if ( imageNode.parentNode && imageNode.parentNode.nodeName === 'A' ) {
     172                        metadata.linkUrl = dom.getAttrib( imageNode.parentNode, 'href' );
    171173                }
    172174
    173175                return metadata;
    174176        }
    175177
    176178        function updateImage( imageNode, imageData ) {
    177                 var className, width, node, html, captionNode, nodeToReplace, uid;
     179                var className, width, node, html, captionNode, nodeToReplace, uid, editedImg;
    178180
    179181                if ( imageData.caption ) {
    180182
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    185187
    186188                        //TODO: shouldn't add the id attribute if it isn't an attachment
    187189
    188                         // should create a new function for genrating the caption markup
     190                        // should create a new function for generating the caption markup
    189191                        html =  '<dl id="'+ imageData.attachment_id +'" class="wp-caption '+ className +'" style="width: '+ width +'px">' +
    190192                                '<dt class="wp-caption-dt">'+ html + '</dt><dd class="wp-caption-dd">'+ imageData.caption +'</dd></dl>';
    191193
    192                         node = editor.dom.create( 'div', { 'class': 'mceTemp', draggable: 'true' }, html );
     194                        node = editor.dom.create( 'div', { 'class': 'mceTemp' }, html );
    193195                } else {
    194196                        node = createImageAndLink( imageData, 'node' );
    195197                }
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    215217
    216218                editor.dom.setAttrib( node, 'data-wp-replace-id', '' );
    217219
    218                 if ( node.nodeName === 'IMG' ) {
    219                         editor.selection.select( node );
    220                 } else {
    221                         editor.selection.select( editor.dom.select( 'img', node )[0] );
    222                 }
    223220                editor.nodeChanged();
     221
     222                editedImg = node.nodeName === 'IMG' ? node : editor.dom.select( 'img', node )[0];
     223
     224                if ( editedImg ) {
     225                        editor.selection.select( editedImg );
     226                        // refresh toolbar
     227                        addToolbar( editedImg );
     228                }
    224229        }
    225230
    226231        function createImageAndLink( imageData, mode ) {
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    264269                }
    265270        }
    266271
     272        function editImage( img ) {
     273                var frame, callback;
     274
     275                if ( typeof wp === 'undefined' || ! wp.media ) {
     276                        editor.execCommand( 'mceImage' );
     277                        return;
     278                }
     279
     280                editor.undoManager.add();
     281
     282                frame = wp.media({
     283                        frame: 'image',
     284                        state: 'image-details',
     285                        metadata: extractImageData( img )
     286                } );
     287
     288                callback = function( imageData ) {
     289                        updateImage( img, imageData );
     290                        editor.focus();
     291                };
     292
     293                frame.state('image-details').on( 'update', callback );
     294                frame.state('replace-image').on( 'replace', callback );
     295                frame.on( 'close', function() {
     296                        editor.focus();
     297        //              editor.selection.select( img );
     298        //              editor.nodeChanged();
     299                });
     300
     301                frame.open();
     302        }
     303
     304        function removeImage( node ) {
     305                var wrap;
     306
     307                if ( node.nodeName === 'DIV' && editor.dom.hasClass( node, 'mceTemp' ) ) {
     308                        wrap = node;
     309                } else if ( node.nodeName === 'IMG' || node.nodeName === 'DT' || node.nodeName === 'A' ) {
     310                        wrap = editor.dom.getParent( node, 'div.mceTemp' );
     311                }
     312
     313                if ( wrap ) {
     314                        if ( wrap.nextSibling ) {
     315                                editor.selection.select( wrap.nextSibling );
     316                        } else if ( wrap.previousSibling ) {
     317                                editor.selection.select( wrap.previousSibling );
     318                        } else {
     319                                editor.selection.select( wrap.parentNode );
     320                        }
     321
     322                        editor.selection.collapse( true );
     323                        editor.nodeChanged();
     324                        editor.dom.remove( wrap );
     325                } else {
     326                        editor.dom.remove( node );
     327                }
     328        }
     329
     330        function addToolbar( node ) {
     331                var position, toolbarHtml, toolbar,
     332                        dom = editor.dom;
     333
     334                removeToolbar();
     335
     336                // Don't add to placeholders
     337                if ( ! node || node.nodeName !== 'IMG' || isPlaceholder( node ) ) {
     338                        return;
     339                }
     340
     341                dom.setAttrib( node, 'data-wp-imgselect', 1 );
     342                position = dom.getPos( node, editor.getBody() );
     343
     344                toolbarHtml = '<div class="wrapper" data-mce-bogus="1">' +
     345                        '<div class="dashicons dashicons-format-image edit" data-mce-bogus="1"></div> ' +
     346                        '<div class="dashicons dashicons-no-alt remove" data-mce-bogus="1"></div></div>';
     347
     348                toolbar = dom.create( 'div', {
     349                        'id': 'wp-image-toolbar',
     350                        'data-mce-bogus': '1',
     351                        'contenteditable': false
     352                }, toolbarHtml );
     353
     354                editor.getBody().appendChild( toolbar );
     355
     356                dom.setStyles( toolbar, {
     357                        top: position.y,
     358                        left: position.x,
     359                        width: node.width
     360                });
     361        }
     362
     363        function removeToolbar() {
     364                var toolbar = editor.dom.get( 'wp-image-toolbar' );
     365
     366                if ( toolbar ) {
     367                        editor.dom.remove( toolbar );
     368                }
     369
     370                editor.dom.setAttrib( editor.dom.select( 'img[data-wp-imgselect]' ), 'data-wp-imgselect', null );
     371        }
     372
     373        function isPlaceholder( node ) {
     374                var dom = editor.dom;
     375
     376                if ( dom.hasClass( node, 'mceItem' ) || dom.getAttrib( node, 'data-mce-placeholder' ) ||
     377                        dom.getAttrib( node, 'data-mce-object' ) ) {
     378
     379                        return true;
     380                }
     381
     382                return false;
     383        }
     384
    267385        editor.on( 'init', function() {
    268386                var dom = editor.dom;
    269387
    270388                // Add caption field to the default image dialog
    271                 editor.on( 'wpLoadImageForm', function( e ) {
     389                editor.on( 'wpLoadImageForm', function( event ) {
    272390                        if ( editor.getParam( 'wpeditimage_disable_captions' ) ) {
    273391                                return;
    274392                        }
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    283401                                label: 'Image caption'
    284402                        };
    285403
    286                         e.data.splice( e.data.length - 1, 0, captionField );
     404                        event.data.splice( event.data.length - 1, 0, captionField );
    287405                });
    288406
    289407                // Fix caption parent width for images added from URL
    290                 editor.on( 'wpNewImageRefresh', function( e ) {
     408                editor.on( 'wpNewImageRefresh', function( event ) {
    291409                        var parent, captionWidth;
    292410
    293                         if ( parent = dom.getParent( e.node, 'dl.wp-caption' ) ) {
     411                        if ( parent = dom.getParent( event.node, 'dl.wp-caption' ) ) {
    294412                                if ( ! parent.style.width ) {
    295                                         captionWidth = parseInt( e.node.clientWidth, 10 ) + 10;
     413                                        captionWidth = parseInt( event.node.clientWidth, 10 ) + 10;
    296414                                        captionWidth = captionWidth ? captionWidth + 'px' : '50%';
    297415                                        dom.setStyle( parent, 'width', captionWidth );
    298416                                }
    299417                        }
    300418                });
    301419
    302                 editor.on( 'wpImageFormSubmit', function( e ) {
    303                         var data = e.imgData.data,
    304                                 imgNode = e.imgData.node,
    305                                 caption = e.imgData.caption,
     420                editor.on( 'wpImageFormSubmit', function( event ) {
     421                        var data = event.imgData.data,
     422                                imgNode = event.imgData.node,
     423                                caption = event.imgData.caption,
    306424                                captionId = '',
    307425                                captionAlign = '',
    308426                                captionWidth = '',
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    311429                        // Temp image id so we can find the node later
    312430                        data.id = '__wp-temp-img-id';
    313431                        // Cancel the original callback
    314                         e.imgData.cancel = true;
     432                        event.imgData.cancel = true;
    315433
    316434                        if ( ! data.style ) {
    317435                                data.style = null;
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    365483                                        }
    366484
    367485                                        if ( parent && parent.nodeName === 'P' ) {
    368                                                 wrap = dom.create( 'div', { 'class': 'mceTemp', 'draggable': 'true' }, html );
     486                                                wrap = dom.create( 'div', { 'class': 'mceTemp' }, html );
    369487                                                dom.insertAfter( wrap, parent );
    370488                                                editor.selection.select( wrap );
    371489                                                editor.nodeChanged();
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    374492                                                        dom.remove( parent );
    375493                                                }
    376494                                        } else {
    377                                                 editor.selection.setContent( '<div class="mceTemp" draggable="true">' + html + '</div>' );
     495                                                editor.selection.setContent( '<div class="mceTemp">' + html + '</div>' );
    378496                                        }
    379497                                } else {
    380498                                        editor.selection.setContent( html );
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    431549                                                        '<dt class="wp-caption-dt">'+ html +'</dt><dd class="wp-caption-dd">'+ caption +'</dd></dl>';
    432550
    433551                                                if ( parent = dom.getParent( imgNode, 'p' ) ) {
    434                                                         wrap = dom.create( 'div', { 'class': 'mceTemp', 'draggable': 'true' }, html );
     552                                                        wrap = dom.create( 'div', { 'class': 'mceTemp' }, html );
    435553                                                        dom.insertAfter( wrap, parent );
    436554                                                        editor.selection.select( wrap );
    437555                                                        editor.nodeChanged();
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    443561                                                                dom.remove( parent );
    444562                                                        }
    445563                                                } else {
    446                                                         editor.selection.setContent( '<div class="mceTemp" draggable="true">' + html + '</div>' );
     564                                                        editor.selection.setContent( '<div class="mceTemp">' + html + '</div>' );
    447565                                                }
    448566                                        }
    449567                                } else {
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    466584
    467585                        imgNode = dom.get('__wp-temp-img-id');
    468586                        dom.setAttrib( imgNode, 'id', imgId );
    469                         e.imgData.node = imgNode;
     587                        event.imgData.node = imgNode;
    470588                });
    471589
    472                 editor.on( 'wpLoadImageData', function( e ) {
     590                editor.on( 'wpLoadImageData', function( event ) {
    473591                        var parent,
    474                                 data = e.imgData.data,
    475                                 imgNode = e.imgData.node;
     592                                data = event.imgData.data,
     593                                imgNode = event.imgData.node;
    476594
    477595                        if ( parent = dom.getParent( imgNode, 'dl.wp-caption' ) ) {
    478596                                parent = dom.select( 'dd.wp-caption-dd', parent )[0];
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    484602                        }
    485603                });
    486604
    487                 // Prevent dragging images out of the caption elements
    488605                dom.bind( editor.getDoc(), 'dragstart', function( event ) {
    489606                        var node = editor.selection.getNode();
    490607
     608                        // Prevent dragging images out of the caption elements
    491609                        if ( node.nodeName === 'IMG' && dom.getParent( node, '.wp-caption' ) ) {
    492610                                event.preventDefault();
    493611                        }
     612
     613                        // Remove toolbar to avoid an orphaned toolbar when dragging an image to a new location
     614                        removeToolbar();
     615
    494616                });
     617
     618                // Prevent IE11 from making dl.wp-caption resizable
     619                if ( tinymce.Env.ie && tinymce.Env.ie > 10 ) {
     620                        // The 'mscontrolselect' event is supported only in IE11+
     621                        dom.bind( editor.getBody(), 'mscontrolselect', function( event ) {
     622                                if ( event.target.nodeName === 'IMG' && dom.getParent( event.target, '.wp-caption' ) ) {
     623                                        // Hide the thick border with resize handles around dl.wp-caption
     624                                        editor.getBody().focus(); // :(
     625                                } else if ( event.target.nodeName === 'DL' && dom.hasClass( event.target, 'wp-caption' ) ) {
     626                                        // Trigger the thick border with resize handles...
     627                                        // This will make the caption text editable.
     628                                        event.target.focus();
     629                                }
     630                        });
     631
     632                        editor.on( 'click', function( event ) {
     633                                if ( event.target.nodeName === 'IMG' && dom.getAttrib( event.target, 'data-wp-imgselect' ) &&
     634                                        dom.getParent( event.target, 'dl.wp-caption' ) ) {
     635
     636                                        editor.getBody().focus();
     637                                }
     638                        });
     639                }
    495640        });
    496641
    497642        editor.on( 'ObjectResized', function( event ) {
    498643        var parent, width,
    499644                        node = event.target;
    500645
    501                 if ( node.nodeName === 'IMG' && ( parent = editor.dom.getParent( node, '.wp-caption' ) ) ) {
    502                         width = event.width || editor.dom.getAttrib( node, 'width' );
     646                if ( node.nodeName === 'IMG' ) {
     647                        if ( parent = editor.dom.getParent( node, '.wp-caption' ) ) {
     648                                width = event.width || editor.dom.getAttrib( node, 'width' );
    503649
    504                         if ( width ) {
    505                                 width = parseInt( width, 10 ) + 10;
    506                                 editor.dom.setStyle( parent, 'width', width + 'px' );
     650                                if ( width ) {
     651                                        width = parseInt( width, 10 ) + 10;
     652                                        editor.dom.setStyle( parent, 'width', width + 'px' );
     653                                }
    507654                        }
     655                        // refresh toolbar
     656                        addToolbar( node );
    508657                }
    509658    });
    510659
    511         editor.on( 'BeforeExecCommand', function( e ) {
     660        editor.on( 'BeforeExecCommand', function( event ) {
    512661                var node, p, DL, align,
    513                         cmd = e.command,
     662                        cmd = event.command,
    514663                        dom = editor.dom;
    515664
    516665                if ( cmd === 'mceInsertContent' ) {
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    525674                                if ( tinymce.Env.ie > 8 ) {
    526675                                        setTimeout( function() {
    527676                                                editor.selection.setCursorLocation( p, 0 );
    528                                                 editor.selection.setContent( e.value );
     677                                                editor.selection.setContent( event.value );
    529678                                        }, 500 );
    530679
    531680                                        return false;
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    536685                        align = cmd.substr(7).toLowerCase();
    537686                        align = 'align' + align;
    538687
     688                        removeToolbar();
     689
    539690                        if ( dom.is( node, 'dl.wp-caption' ) ) {
    540691                                DL = node;
    541692                        } else {
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    566717                }
    567718        });
    568719
    569         editor.on( 'keydown', function( e ) {
     720        editor.on( 'keydown', function( event ) {
    570721                var node, wrap, P, spacer,
    571722                        selection = editor.selection,
    572723                        dom = editor.dom;
    573724
    574                 if ( e.keyCode === tinymce.util.VK.ENTER ) {
     725                if ( event.keyCode === tinymce.util.VK.ENTER ) {
    575726                        // When pressing Enter inside a caption move the caret to a new parapraph under it
    576                         wrap = dom.getParent( editor.selection.getNode(), 'div.mceTemp' );
     727                        node = selection.getNode();
     728                        wrap = dom.getParent( node, 'div.mceTemp' );
    577729
    578730                        if ( wrap ) {
    579                                 dom.events.cancel(e); // Doesn't cancel all :(
     731                                dom.events.cancel( event ); // Doesn't cancel all :(
    580732
    581733                                // Remove any extra dt and dd cleated on pressing Enter...
    582734                                tinymce.each( dom.select( 'dt, dd', wrap ), function( element ) {
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    585737                                        }
    586738                                });
    587739
    588                                 spacer = tinymce.Env.ie ? '' : '<br data-mce-bogus="1" />';
     740                                spacer = tinymce.Env.ie && tinymce.Env.ie < 11 ? '' : '<br data-mce-bogus="1" />';
    589741                                P = dom.create( 'p', null, spacer );
    590                                 dom.insertAfter( P, wrap );
    591                                 selection.setCursorLocation( P, 0 );
     742
     743                                if ( node.nodeName === 'DD' ) {
     744                                        dom.insertAfter( P, wrap );
     745                                } else {
     746                                        wrap.parentNode.insertBefore( P, wrap );
     747                                }
     748
    592749                                editor.nodeChanged();
     750                                selection.setCursorLocation( P, 0 );
    593751                        }
    594                 } else if ( e.keyCode === tinymce.util.VK.DELETE || e.keyCode === tinymce.util.VK.BACKSPACE ) {
     752                } else if ( event.keyCode === tinymce.util.VK.DELETE || event.keyCode === tinymce.util.VK.BACKSPACE ) {
    595753                        node = selection.getNode();
    596754
    597755                        if ( node.nodeName === 'DIV' && dom.hasClass( node, 'mceTemp' ) ) {
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    601759                        }
    602760
    603761                        if ( wrap ) {
    604                                 dom.events.cancel(e);
    605 
    606                                 if ( wrap.nextSibling ) {
    607                                         selection.select( wrap.nextSibling );
    608                                 } else if ( wrap.previousSibling ) {
    609                                         selection.select( wrap.previousSibling );
    610                                 } else {
    611                                         selection.select( wrap.parentNode );
    612                                 }
    613 
    614                                 selection.collapse( true );
    615                                 editor.nodeChanged();
    616                                 dom.remove( wrap );
    617                                 wrap = null;
     762                                dom.events.cancel( event );
     763                                removeImage( node );
    618764                                return false;
    619765                        }
    620766                }
    621767        });
    622768
    623         editor.on( 'mousedown', function( e ) {
    624                 var imageNode, frame, callback;
    625                 if ( e.target.nodeName === 'IMG' && editor.selection.getNode() === e.target ) {
    626                         // Don't trigger on right-click
    627                         if ( e.button !== 2 ) {
     769        editor.on( 'mousedown', function( event ) {
     770                var node = event.target;
    628771
    629                                 // Don't attempt to edit placeholders
    630                                 if ( editor.dom.hasClass( e.target, 'mceItem' ) || '1' === editor.dom.getAttrib( e.target, 'data-mce-placeholder' ) ) {
    631                                         return;
    632                                 }
     772                if ( tinymce.Env.ie && editor.dom.getParent( node, '#wp-image-toolbar' ) ) {
     773                        // Stop IE > 8 from making the wrapper resizable on mousedown
     774                        event.preventDefault();
     775                }
    633776
    634                                 imageNode = e.target;
     777                if ( node.nodeName === 'IMG' && ! editor.dom.getAttrib( node, 'data-wp-imgselect' ) && ! isPlaceholder( node ) ) {
     778                        addToolbar( node );
     779                }
     780        });
    635781
    636                                 frame = wp.media({
    637                                         frame: 'image',
    638                                         state: 'image-details',
    639                                         metadata: extractImageData( imageNode )
    640                                 } );
     782        editor.on( 'mouseup', function( event ) {
     783                var image,
     784                        node = event.target,
     785                        dom = editor.dom;
    641786
    642                                 callback = function( imageData ) {
    643                                         updateImage( imageNode, imageData );
    644                                         editor.focus();
    645                                 };
     787                // Don't trigger on right-click
     788                if ( event.button && event.button > 1 ) {
     789                        return;
     790                }
    646791
    647                                 frame.state('image-details').on( 'update', callback );
    648                                 frame.state('replace-image').on( 'replace', callback );
     792                if ( node.nodeName === 'DIV' && dom.getParent( node, '#wp-image-toolbar' ) ) {
     793                        image = dom.select( 'img[data-wp-imgselect]' )[0];
    649794
    650                                 frame.open();
     795                        if ( image ) {
     796                                editor.selection.select( image );
     797
     798                                if ( dom.hasClass( node, 'remove' ) ) {
     799                                        removeImage( image );
     800                                        removeToolbar();
     801                                } else if ( dom.hasClass( node, 'edit' ) ) {
     802                                        editImage( image );
     803                                }
    651804                        }
     805                } else if ( node.nodeName !== 'IMG' ) {
     806                        removeToolbar();
    652807                }
    653         } );
     808        });
     809
     810        editor.on( 'cut', function() {
     811                removeToolbar();
     812        });
    654813
    655814        editor.wpSetImgCaption = function( content ) {
    656815                return parseShortcode( content );
    tinymce.PluginManager.add( 'wpeditimage', function( editor ) { 
    660819                return getShortcode( content );
    661820        };
    662821
    663         editor.on( 'BeforeSetContent', function( e ) {
    664                 e.content = editor.wpSetImgCaption( e.content );
     822        editor.on( 'BeforeSetContent', function( event ) {
     823                event.content = editor.wpSetImgCaption( event.content );
    665824        });
    666825
    667         editor.on( 'PostProcess', function( e ) {
    668                 if ( e.get ) {
    669                         e.content = editor.wpGetImgCaption( e.content );
     826        editor.on( 'PostProcess', function( event ) {
     827                if ( event.get ) {
     828                        event.content = editor.wpGetImgCaption( event.content );
     829                        event.content = event.content.replace( / data-wp-imgselect="1"/g, '' );
    670830                }
    671831        });
    672832
  • src/wp-includes/js/tinymce/skins/wordpress/wp-content.css

    diff --git src/wp-includes/js/tinymce/skins/wordpress/wp-content.css src/wp-includes/js/tinymce/skins/wordpress/wp-content.css
    index 92e1f35..f9537a2 100644
    img::selection { 
    117117        cursor: pointer;
    118118}
    119119
     120#wp-image-toolbar {
     121        position: absolute;
     122}
     123
     124#wp-image-toolbar .wrapper {
     125        position: relative;
     126        height: 33px;
     127        background-color: rgba(0,0,0,0.3);
     128}
     129
     130#wp-image-toolbar .dashicons {
     131        position: absolute;
     132        color: white;
     133        width: 36px;
     134        height: 32px;
     135        line-height: 32px;
     136        cursor: pointer;
     137}
     138
     139#wp-image-toolbar div.dashicons-no-alt {
     140        top: 0;
     141        right: 0;
     142}
     143
     144#wp-image-toolbar div.dashicons-format-image {
     145        top: 0;
     146        left: 0;
     147}
     148
     149/* Image resize handles */
     150.mce-content-body div.mce-resizehandle {
     151        border-color: #777;
     152        width: 7px;
     153        height: 7px;
     154}
     155
     156.mce-content-body img[data-mce-selected] {
     157        outline: 1px solid #777;
     158}
     159
    120160.mce-content-body img.wp-gallery:hover {
    121161        background-color: #ededed;
    122162        border-style: solid;