WordPress.org

Make WordPress Core

Ticket #30619: 30619.5.patch

File 30619.5.patch, 27.2 KB (added by iseulde, 6 years ago)
  • src/wp-includes/class-wp-editor.php

     
    358358                                                'textcolor',
    359359                                                'fullscreen',
    360360                                                'wordpress',
     361                                                'wptoolbar',
    361362                                                'wpautoresize',
    362363                                                'wpeditimage',
    363364                                                'wpgallery',
  • src/wp-includes/css/editor.css

     
    170170        box-sizing: border-box;
    171171        margin-bottom: 8px;
    172172        position: absolute;
    173         visibility: hidden;
    174173        -moz-user-select: none;
    175174        -webkit-user-select: none;
    176175        -ms-user-select: none;
     
    178177        z-index: 100100; /* Same as the other TinyMCE "panels" */
    179178}
    180179
    181 div.mce-wp-image-toolbar > div.mce-stack-layout {
     180div.mce-inline-toolbar-grp > div.mce-stack-layout {
    182181        padding: 1px;
    183182}
    184183
     
    262261        overflow-x: auto;
    263262}
    264263
    265 div.mce-inline-toolbar-grp-active {
    266         visibility: visible;
    267 }
    268 
    269264div.mce-toolbar-grp > div {
    270265        padding: 3px;
    271266}
  • src/wp-includes/js/mce-view.js

     
    400400                                                '<div class="wpview-wrap" data-wpview-text="' + this.encodedText + '" data-wpview-type="' + this.type + '">' +
    401401                                                        '<p class="wpview-selection-before">\u00a0</p>' +
    402402                                                        '<div class="wpview-body" contenteditable="false">' +
    403                                                                 '<div class="toolbar mce-arrow-down">' +
    404                                                                         ( this.edit ? '<div class="dashicons dashicons-edit edit"></div>' : '' ) +
    405                                                                         '<div class="dashicons dashicons-no remove"></div>' +
    406                                                                 '</div>' +
    407403                                                                '<div class="wpview-content wpview-type-' + this.type + '"></div>' +
    408404                                                        '</div>' +
    409405                                                        '<p class="wpview-selection-after">\u00a0</p>' +
  • src/wp-includes/js/tinymce/plugins/wpeditimage/plugin.js

     
    11/* global tinymce */
    22tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
    33        var floatingToolbar, serializer,
    4                 DOM = tinymce.DOM,
    5                 settings = editor.settings,
    6                 Factory = tinymce.ui.Factory,
    74                each = tinymce.each,
    8                 iOS = tinymce.Env.iOS,
    9                 toolbarIsHidden = true,
    10                 editorWrapParent = tinymce.$( '#postdivrich' );
     5                iOS = tinymce.Env.iOS;
    116
    127        function isPlaceholder( node ) {
    138                return !! ( editor.dom.getAttrib( node, 'data-mce-placeholder' ) || editor.dom.getAttrib( node, 'data-mce-object' ) );
     
    6459                } );
    6560        } );
    6661
    67         function toolbarConfig() {
    68                 var toolbarItems = [],
    69                         buttonGroup;
    70 
    71                 each( [ 'wp_img_alignleft', 'wp_img_aligncenter', 'wp_img_alignright', 'wp_img_alignnone', 'wp_img_edit', 'wp_img_remove' ], function( item ) {
    72                         var itemName;
    73 
    74                         function bindSelectorChanged() {
    75                                 var selection = editor.selection;
    76 
    77                                 if ( item.settings.stateSelector ) {
    78                                         selection.selectorChanged( item.settings.stateSelector, function( state ) {
    79                                                 item.active( state );
    80                                         }, true );
    81                                 }
    82 
    83                                 if ( item.settings.disabledStateSelector ) {
    84                                         selection.selectorChanged( item.settings.disabledStateSelector, function( state ) {
    85                                                 item.disabled( state );
    86                                         } );
    87                                 }
    88                         }
    89 
    90                         if ( item === '|' ) {
    91                                 buttonGroup = null;
    92                         } else {
    93                                 if ( Factory.has( item ) ) {
    94                                         item = {
    95                                                 type: item
    96                                         };
    97 
    98                                         if ( settings.toolbar_items_size ) {
    99                                                 item.size = settings.toolbar_items_size;
    100                                         }
    101 
    102                                         toolbarItems.push( item );
    103 
    104                                         buttonGroup = null;
    105                                 } else {
    106                                         if ( ! buttonGroup ) {
    107                                                 buttonGroup = {
    108                                                         type: 'buttongroup',
    109                                                         items: []
    110                                                 };
    111 
    112                                                 toolbarItems.push( buttonGroup );
    113                                         }
    114 
    115                                         if ( editor.buttons[ item ] ) {
    116                                                 itemName = item;
    117                                                 item = editor.buttons[ itemName ];
    118 
    119                                                 if ( typeof item === 'function' ) {
    120                                                         item = item();
    121                                                 }
    122 
    123                                                 item.type = item.type || 'button';
    124 
    125                                                 if ( settings.toolbar_items_size ) {
    126                                                         item.size = settings.toolbar_items_size;
    127                                                 }
    128 
    129                                                 item = Factory.create( item );
    130                                                 buttonGroup.items.push( item );
    131 
    132                                                 if ( editor.initialized ) {
    133                                                         bindSelectorChanged();
    134                                                 } else {
    135                                                         editor.on( 'init', bindSelectorChanged );
    136                                                 }
    137                                         }
    138                                 }
    139                         }
    140                 } );
    141 
    142                 return {
    143                         type: 'panel',
    144                         layout: 'stack',
    145                         classes: 'toolbar-grp inline-toolbar-grp wp-image-toolbar',
    146                         ariaRoot: true,
    147                         ariaRemember: true,
    148                         items: [
    149                                 {
    150                                         type: 'toolbar',
    151                                         layout: 'flow',
    152                                         items: toolbarItems
    153                                 }
    154                         ]
    155                 };
    156         }
    157 
    158         floatingToolbar = Factory.create( toolbarConfig() ).renderTo( document.body ).hide();
    159 
    160         floatingToolbar.reposition = function() {
    161                 var top, left, minTop, className,
    162                         windowPos, adminbar, mceToolbar, boundary,
    163                         boundaryMiddle, boundaryVerticalMiddle, spaceTop,
    164                         spaceBottom, windowWidth, toolbarWidth, toolbarHalf,
    165                         iframe, iframePos, iframeWidth, iframeHeigth,
    166                         toolbarNodeHeight, verticalSpaceNeeded,
    167                         toolbarNode = this.getEl(),
    168                         buffer = 5,
    169                         margin = 8,
    170                         adminbarHeight = 0,
    171                         imageNode = editor.selection.getNode();
    172 
    173                 if ( ! imageNode || imageNode.nodeName !== 'IMG' ) {
    174                         return this;
    175                 }
    176 
    177                 windowPos = window.pageYOffset || document.documentElement.scrollTop;
    178                 adminbar = tinymce.$( '#wpadminbar' )[0];
    179                 mceToolbar = tinymce.$( '.mce-toolbar-grp', editor.getContainer() )[0];
    180                 boundary = imageNode.getBoundingClientRect();
    181                 boundaryMiddle = ( boundary.left + boundary.right ) / 2;
    182                 boundaryVerticalMiddle = ( boundary.top + boundary.bottom ) / 2;
    183                 spaceTop = boundary.top;
    184                 spaceBottom = iframeHeigth - boundary.bottom;
    185                 windowWidth = window.innerWidth;
    186                 toolbarWidth = toolbarNode.offsetWidth;
    187                 toolbarHalf = toolbarWidth / 2;
    188                 iframe = document.getElementById( editor.id + '_ifr' );
    189                 iframePos = DOM.getPos( iframe );
    190                 iframeWidth = iframe.offsetWidth;
    191                 iframeHeigth = iframe.offsetHeight;
    192                 toolbarNodeHeight = toolbarNode.offsetHeight;
    193                 verticalSpaceNeeded = toolbarNodeHeight + margin + buffer;
    194 
    195                 if ( iOS ) {
    196                         top = boundary.top + iframePos.y + margin;
    197                 } else {
    198                         if ( spaceTop >= verticalSpaceNeeded ) {
    199                                 className = ' mce-arrow-down';
    200                                 top = boundary.top + iframePos.y - toolbarNodeHeight - margin;
    201                         } else if ( spaceBottom >= verticalSpaceNeeded ) {
    202                                 className = ' mce-arrow-up';
    203                                 top = boundary.bottom + iframePos.y;
    204                         } else {
    205                                 top = buffer;
    206 
    207                                 if ( boundaryVerticalMiddle >= verticalSpaceNeeded ) {
    208                                         className = ' mce-arrow-down';
    209                                 } else {
    210                                         className = ' mce-arrow-up';
    211                                 }
    212                         }
    213                 }
    214 
    215                 // Make sure the image toolbar is below the main toolbar.
    216                 if ( mceToolbar ) {
    217                         minTop = DOM.getPos( mceToolbar ).y + mceToolbar.clientHeight;
    218                 } else {
    219                         minTop = iframePos.y;
    220                 }
    221 
    222                 // Make sure the image toolbar is below the adminbar (if visible) or below the top of the window.
    223                 if ( windowPos ) {
    224                         if ( adminbar && adminbar.getBoundingClientRect().top === 0 ) {
    225                                 adminbarHeight = adminbar.clientHeight;
    226                         }
    227 
    228                         if ( windowPos + adminbarHeight > minTop ) {
    229                                 minTop = windowPos + adminbarHeight;
    230                         }
    231                 }
    232 
    233                 if ( top && minTop && ( minTop + buffer > top ) ) {
    234                         top = minTop + buffer;
    235                         className = '';
    236                 }
    237 
    238                 left = boundaryMiddle - toolbarHalf;
    239                 left += iframePos.x;
    240 
    241                 if ( boundary.left < 0 || boundary.right > iframeWidth ) {
    242                         left = iframePos.x + ( iframeWidth - toolbarWidth ) / 2;
    243                 } else if ( toolbarWidth >= windowWidth ) {
    244                         className += ' mce-arrow-full';
    245                         left = 0;
    246                 } else if ( ( left < 0 && boundary.left + toolbarWidth > windowWidth ) ||
    247                         ( left + toolbarWidth > windowWidth && boundary.right - toolbarWidth < 0 ) ) {
    248 
    249                         left = ( windowWidth - toolbarWidth ) / 2;
    250                 } else if ( left < iframePos.x ) {
    251                         className += ' mce-arrow-left';
    252                         left = boundary.left + iframePos.x;
    253                 } else if ( left + toolbarWidth > iframeWidth + iframePos.x ) {
    254                         className += ' mce-arrow-right';
    255                         left = boundary.right - toolbarWidth + iframePos.x;
    256                 }
    257 
    258                 if ( ! iOS ) {
    259                         toolbarNode.className = toolbarNode.className.replace( / ?mce-arrow-[\w]+/g, '' );
    260                         toolbarNode.className += className;
     62        floatingToolbar = editor.plugins.wptoolbar( [
     63                'wp_img_alignleft',
     64                'wp_img_aligncenter',
     65                'wp_img_alignright',
     66                'wp_img_alignnone',
     67                'wp_img_edit',
     68                'wp_img_remove'
     69        ] );
     70
     71        editor.on( 'wptoolbar', function( event ) {
     72                if ( event.element.nodeName === 'IMG' && ! isPlaceholder( event.element ) ) {
     73                        event.toolbar = floatingToolbar;
    26174                }
     75        } );
    26276
    263                 DOM.setStyles( toolbarNode, { 'left': left, 'top': top } );
    264 
    265                 return this;
    266         };
    267 
     77        // Safari on iOS fails to select image nodes in contentEditoble mode on touch/click.
     78        // Select them again.
    26879        if ( iOS ) {
    269                 // Safari on iOS fails to select image nodes in contentEditoble mode on touch/click.
    270                 // Select them again.
    27180                editor.on( 'click', function( event ) {
    27281                        if ( event.target.nodeName === 'IMG' ) {
    27382                                var node = event.target;
    27483
    27584                                window.setTimeout( function() {
    27685                                        editor.selection.select( node );
     86                                        editor.nodeChanged();
    27787                                }, 200 );
    27888                        } else {
    27989                                floatingToolbar.hide();
    28090                        }
    281                 });
    282         }
    283 
    284         editor.on( 'nodechange', function( event ) {
    285                 var delay = iOS ? 350 : 100;
    286 
    287                 if ( event.element.nodeName !== 'IMG' || isPlaceholder( event.element ) ) {
    288                         floatingToolbar.hide();
    289                         return;
    290                 }
    291 
    292                 setTimeout( function() {
    293                         var element = editor.selection.getNode();
    294 
    295                         if ( element.nodeName === 'IMG' && ! isPlaceholder( element ) ) {
    296                                 if ( floatingToolbar._visible ) {
    297                                         floatingToolbar.reposition();
    298                                 } else {
    299                                         floatingToolbar.show();
    300                                 }
    301                         } else {
    302                                 floatingToolbar.hide();
    303                         }
    304                 }, delay );
    305         } );
    306 
    307         function hide() {
    308                 if ( ! toolbarIsHidden ) {
    309                         floatingToolbar.hide();
    310                 }
     91                } );
    31192        }
    31293
    313         floatingToolbar.on( 'show', function() {
    314                 toolbarIsHidden = false;
    315 
    316                 if ( this._visible ) {
    317                         this.reposition();
    318                         DOM.addClass( this.getEl(), 'mce-inline-toolbar-grp-active' );
    319                 }
    320         } );
    321 
    322         floatingToolbar.on( 'hide', function() {
    323                 toolbarIsHidden = true;
    324                 DOM.removeClass( this.getEl(), 'mce-inline-toolbar-grp-active' );
    325         } );
    326 
    327         floatingToolbar.on( 'keydown', function( event ) {
    328                 if ( event.keyCode === 27 ) {
    329                         hide();
    330                         editor.focus();
    331                 }
    332         } );
    333 
    334         DOM.bind( window, 'resize scroll', function() {
    335                 if ( ! toolbarIsHidden && editorWrapParent.hasClass( 'wp-editor-expand' ) ) {
    336                         hide();
    337                 }
    338         });
    339 
    340         editor.on( 'init', function() {
    341                 editor.dom.bind( editor.getWin(), 'scroll', hide );
    342         });
    343 
    344         editor.on( 'blur hide', hide );
    345 
    346         // 119 = F8
    347         editor.shortcuts.add( 'Alt+119', '', function() {
    348                 var node = floatingToolbar.find( 'toolbar' )[0];
    349 
    350                 if ( node ) {
    351                         node.focus( true );
    352                 }
    353         });
    354 
    35594        function parseShortcode( content ) {
    35695                return content.replace( /(?:<p>)?\[(?:wp_)?caption([^\]]+)\]([\s\S]+?)\[\/(?:wp_)?caption\](?:<\/p>)?/g, function( a, b, c ) {
    35796                        var id, align, classes, caption, img, width,
  • src/wp-includes/js/tinymce/plugins/wptoolbar/plugin.js

     
     1( function( tinymce ) {
     2        tinymce.PluginManager.add( 'wptoolbar', function( editor ) {
     3                var DOM = tinymce.DOM,
     4                        each = tinymce.each,
     5                        Factory = tinymce.ui.Factory,
     6                        settings = editor.settings,
     7                        currentToolbar,
     8                        currentSelection;
     9
     10                function create( buttons ) {
     11                        var toolbar,
     12                                toolbarItems = [],
     13                                buttonGroup;
     14
     15                        each( buttons, function( item ) {
     16                                var itemName;
     17
     18                                function bindSelectorChanged() {
     19                                        var selection = editor.selection;
     20
     21                                        if ( itemName === 'bullist' ) {
     22                                                selection.selectorChanged( 'ul > li', function( state, args ) {
     23                                                        var i = args.parents.length,
     24                                                                nodeName;
     25
     26                                                        while ( i-- ) {
     27                                                                nodeName = args.parents[ i ].nodeName;
     28
     29                                                                if ( nodeName === 'OL' || nodeName == 'UL' ) {
     30                                                                        break;
     31                                                                }
     32                                                        }
     33
     34                                                        item.active( state && nodeName === 'UL' );
     35                                                } );
     36                                        }
     37
     38                                        if ( itemName === 'numlist' ) {
     39                                                selection.selectorChanged( 'ol > li', function( state, args ) {
     40                                                        var i = args.parents.length,
     41                                                                nodeName;
     42
     43                                                        while ( i-- ) {
     44                                                                nodeName = args.parents[ i ].nodeName;
     45
     46                                                                if ( nodeName === 'OL' || nodeName === 'UL' ) {
     47                                                                        break;
     48                                                                }
     49                                                        }
     50
     51                                                        item.active( state && nodeName === 'OL' );
     52                                                } );
     53                                        }
     54
     55                                        if ( item.settings.stateSelector ) {
     56                                                selection.selectorChanged( item.settings.stateSelector, function( state ) {
     57                                                        item.active( state );
     58                                                }, true );
     59                                        }
     60
     61                                        if ( item.settings.disabledStateSelector ) {
     62                                                selection.selectorChanged( item.settings.disabledStateSelector, function( state ) {
     63                                                        item.disabled( state );
     64                                                } );
     65                                        }
     66                                }
     67
     68                                if ( item === '|' ) {
     69                                        buttonGroup = null;
     70                                } else {
     71                                        if ( Factory.has( item ) ) {
     72                                                item = {
     73                                                        type: item
     74                                                };
     75
     76                                                if ( settings.toolbar_items_size ) {
     77                                                        item.size = settings.toolbar_items_size;
     78                                                }
     79
     80                                                toolbarItems.push( item );
     81
     82                                                buttonGroup = null;
     83                                        } else {
     84                                                if ( ! buttonGroup ) {
     85                                                        buttonGroup = {
     86                                                                type: 'buttongroup',
     87                                                                items: []
     88                                                        };
     89
     90                                                        toolbarItems.push( buttonGroup );
     91                                                }
     92
     93                                                if ( editor.buttons[ item ] ) {
     94                                                        itemName = item;
     95                                                        item = editor.buttons[ itemName ];
     96
     97                                                        if ( typeof item === 'function' ) {
     98                                                                item = item();
     99                                                        }
     100
     101                                                        item.type = item.type || 'button';
     102
     103                                                        if ( settings.toolbar_items_size ) {
     104                                                                item.size = settings.toolbar_items_size;
     105                                                        }
     106
     107                                                        item = Factory.create( item );
     108
     109                                                        buttonGroup.items.push( item );
     110
     111                                                        if ( editor.initialized ) {
     112                                                                bindSelectorChanged();
     113                                                        } else {
     114                                                                editor.on( 'init', bindSelectorChanged );
     115                                                        }
     116                                                }
     117                                        }
     118                                }
     119                        } );
     120
     121                        toolbar = Factory.create( {
     122                                type: 'panel',
     123                                layout: 'stack',
     124                                classes: 'toolbar-grp inline-toolbar-grp',
     125                                ariaRoot: true,
     126                                ariaRemember: true,
     127                                items: [ {
     128                                        type: 'toolbar',
     129                                        layout: 'flow',
     130                                        items: toolbarItems
     131                                } ]
     132                        } );
     133
     134                        function hide() {
     135                                toolbar.hide();
     136                        }
     137
     138                        function reposition() {
     139                                var top, left, minTop, className,
     140                                        windowPos, adminbar, mceToolbar, boundary,
     141                                        boundaryMiddle, boundaryVerticalMiddle, spaceTop,
     142                                        spaceBottom, windowWidth, toolbarWidth, toolbarHalf,
     143                                        iframe, iframePos, iframeWidth, iframeHeigth,
     144                                        toolbarNodeHeight, verticalSpaceNeeded,
     145                                        toolbarNode = this.getEl(),
     146                                        buffer = 5,
     147                                        margin = 8,
     148                                        adminbarHeight = 0;
     149
     150                                windowPos = window.pageYOffset || document.documentElement.scrollTop;
     151                                adminbar = tinymce.$( '#wpadminbar' )[0];
     152                                mceToolbar = tinymce.$( '.mce-toolbar-grp', editor.getContainer() )[0];
     153                                boundary = currentSelection.getBoundingClientRect();
     154                                boundaryMiddle = ( boundary.left + boundary.right ) / 2;
     155                                boundaryVerticalMiddle = ( boundary.top + boundary.bottom ) / 2;
     156                                spaceTop = boundary.top;
     157                                spaceBottom = iframeHeigth - boundary.bottom;
     158                                windowWidth = window.innerWidth;
     159                                toolbarWidth = toolbarNode.offsetWidth;
     160                                toolbarHalf = toolbarWidth / 2;
     161                                iframe = document.getElementById( editor.id + '_ifr' );
     162                                iframePos = DOM.getPos( iframe );
     163                                iframeWidth = iframe.offsetWidth;
     164                                iframeHeigth = iframe.offsetHeight;
     165                                toolbarNodeHeight = toolbarNode.offsetHeight;
     166                                verticalSpaceNeeded = toolbarNodeHeight + margin + buffer;
     167
     168                                if ( spaceTop >= verticalSpaceNeeded ) {
     169                                        className = ' mce-arrow-down';
     170                                        top = boundary.top + iframePos.y - toolbarNodeHeight - margin;
     171                                } else if ( spaceBottom >= verticalSpaceNeeded ) {
     172                                        className = ' mce-arrow-up';
     173                                        top = boundary.bottom + iframePos.y;
     174                                } else {
     175                                        top = buffer;
     176
     177                                        if ( boundaryVerticalMiddle >= verticalSpaceNeeded ) {
     178                                                className = ' mce-arrow-down';
     179                                        } else {
     180                                                className = ' mce-arrow-up';
     181                                        }
     182                                }
     183
     184                                // Make sure the image toolbar is below the main toolbar.
     185                                if ( mceToolbar ) {
     186                                        minTop = DOM.getPos( mceToolbar ).y + mceToolbar.clientHeight;
     187                                } else {
     188                                        minTop = iframePos.y;
     189                                }
     190
     191                                // Make sure the image toolbar is below the adminbar (if visible) or below the top of the window.
     192                                if ( windowPos ) {
     193                                        if ( adminbar && adminbar.getBoundingClientRect().top === 0 ) {
     194                                                adminbarHeight = adminbar.clientHeight;
     195                                        }
     196
     197                                        if ( windowPos + adminbarHeight > minTop ) {
     198                                                minTop = windowPos + adminbarHeight;
     199                                        }
     200                                }
     201
     202                                if ( top && minTop && ( minTop + buffer > top ) ) {
     203                                        top = minTop + buffer;
     204                                        className = '';
     205                                }
     206
     207                                left = boundaryMiddle - toolbarHalf;
     208                                left += iframePos.x;
     209
     210                                if ( boundary.left < 0 || boundary.right > iframeWidth ) {
     211                                        left = iframePos.x + ( iframeWidth - toolbarWidth ) / 2;
     212                                } else if ( toolbarWidth >= windowWidth ) {
     213                                        className += ' mce-arrow-full';
     214                                        left = 0;
     215                                } else if ( ( left < 0 && boundary.left + toolbarWidth > windowWidth ) ||
     216                                        ( left + toolbarWidth > windowWidth && boundary.right - toolbarWidth < 0 ) ) {
     217
     218                                        left = ( windowWidth - toolbarWidth ) / 2;
     219                                } else if ( left < iframePos.x ) {
     220                                        className += ' mce-arrow-left';
     221                                        left = boundary.left + iframePos.x;
     222                                } else if ( left + toolbarWidth > iframeWidth + iframePos.x ) {
     223                                        className += ' mce-arrow-right';
     224                                        left = boundary.right - toolbarWidth + iframePos.x;
     225                                }
     226
     227                                toolbarNode.className = toolbarNode.className.replace( / ?mce-arrow-[\w]+/g, '' );
     228                                toolbarNode.className += className;
     229
     230                                DOM.setStyles( toolbarNode, { 'left': left, 'top': top } );
     231
     232                                return this;
     233                        }
     234
     235                        toolbar.on( 'show', function() {
     236                                currentToolbar = this;
     237                                this.reposition();
     238                        } );
     239
     240                        toolbar.on( 'hide', function() {
     241                                currentToolbar = false;
     242                        } );
     243
     244                        toolbar.on( 'keydown', function( event ) {
     245                                if ( event.keyCode === 27 ) {
     246                                        this.hide();
     247                                        editor.focus();
     248                                }
     249                        } );
     250
     251                        toolbar.on( 'remove', function() {
     252                                DOM.unbind( window, 'resize scroll', hide );
     253                                editor.dom.unbind( editor.getWin(), 'resize scroll', hide );
     254                                editor.off( 'blur hide', hide );
     255                        } );
     256
     257                        editor.once( 'init', function() {
     258                                DOM.bind( window, 'resize scroll', hide );
     259                                editor.dom.bind( editor.getWin(), 'resize scroll', hide );
     260                                editor.on( 'blur hide', hide );
     261                        } );
     262
     263                        toolbar.reposition = reposition;
     264                        toolbar.hide().renderTo( document.body );
     265
     266                        return toolbar;
     267                }
     268
     269                editor.shortcuts.add( 'alt+119', '', function() {
     270                        var node;
     271
     272                        if ( currentToolbar ) {
     273                                node = currentToolbar.find( 'toolbar' )[0];
     274                                node && node.focus( true );
     275                        }
     276                } );
     277
     278                editor.on( 'nodechange', function( event ) {
     279                        var collapsed = editor.selection.isCollapsed();
     280
     281                        var args = {
     282                                element: event.element,
     283                                parents: event.parents,
     284                                collapsed: collapsed
     285                        };
     286
     287                        editor.fire( 'wptoolbar', args );
     288
     289                        currentSelection = args.selection || args.element;
     290
     291                        currentToolbar && currentToolbar.hide();
     292                        args.toolbar && args.toolbar.show();
     293                } );
     294
     295                return create;
     296        } );
     297} )( window.tinymce );
  • src/wp-includes/js/tinymce/plugins/wpview/plugin.js

     
    1212                firstFocus = true,
    1313                _noop = function() { return false; },
    1414                isios = /iPad|iPod|iPhone/.test( navigator.userAgent ),
    15                 cursorInterval, lastKeyDownNode, setViewCursorTries, focus, execCommandView, execCommandBefore;
     15                cursorInterval,
     16                lastKeyDownNode,
     17                setViewCursorTries,
     18                focus,
     19                execCommandView,
     20                execCommandBefore,
     21                toolbar;
    1622
    1723        function getView( node ) {
    1824                return getParent( node, 'wpview-wrap' );
     
    8692                        return;
    8793                }
    8894
    89                 // Adjust the toolbar position and bail if node is already selected.
    90                 if ( viewNode === selected ) {
    91                         adjustToolbarPosition( viewNode );
    92                         return;
    93                 }
     95                if ( viewNode !== selected ) {
     96                        // Make sure that the editor is focused.
     97                        // It is possible that the editor is not focused when the mouse event fires
     98                        // without focus, the selection will not work properly.
     99                        editor.getBody().focus();
    94100
    95                 // Make sure that the editor is focused.
    96                 // It is possible that the editor is not focused when the mouse event fires
    97                 // without focus, the selection will not work properly.
    98                 editor.getBody().focus();
     101                        deselect();
     102                        selected = viewNode;
     103                        dom.setAttrib( viewNode, 'data-mce-selected', 1 );
    99104
    100                 deselect();
    101                 selected = viewNode;
    102                 dom.setAttrib( viewNode, 'data-mce-selected', 1 );
    103                 adjustToolbarPosition( viewNode );
    104 
    105                 clipboard = dom.create( 'div', {
    106                         'class': 'wpview-clipboard',
    107                         'contenteditable': 'true'
    108                 }, wp.mce.views.getText( viewNode ) );
    109 
    110                 editor.dom.select( '.wpview-body', viewNode )[0].appendChild( clipboard );
    111 
    112                 // Both of the following are necessary to prevent manipulating the selection/focus
    113                 dom.bind( clipboard, 'beforedeactivate focusin focusout', _stop );
    114                 dom.bind( selected, 'beforedeactivate focusin focusout', _stop );
    115 
    116                 // select the hidden div
    117                 if ( isios ) {
    118                         editor.selection.select( clipboard );
    119                 } else {
    120                         editor.selection.select( clipboard, true );
     105                        clipboard = dom.create( 'div', {
     106                                'class': 'wpview-clipboard',
     107                                'contenteditable': 'true'
     108                        }, wp.mce.views.getText( viewNode ) );
     109
     110                        editor.dom.select( '.wpview-body', viewNode )[0].appendChild( clipboard );
     111
     112                        // Both of the following are necessary to prevent manipulating the selection/focus
     113                        dom.bind( clipboard, 'beforedeactivate focusin focusout', _stop );
     114                        dom.bind( selected, 'beforedeactivate focusin focusout', _stop );
     115
     116                        // select the hidden div
     117                        if ( isios ) {
     118                                editor.selection.select( clipboard );
     119                        } else {
     120                                editor.selection.select( clipboard, true );
     121                        }
    121122                }
    122123
    123124                editor.nodeChanged();
    124125                editor.fire( 'wpview-selected', viewNode );
    125126        }
    126127
    127         function adjustToolbarPosition( viewNode ) {
    128                 var delta = 0,
    129                         toolbar = editor.$( viewNode ).find( '.toolbar' ),
    130                         editorToolbar = tinymce.$( editor.editorContainer ).find( '.mce-toolbar-grp' )[0],
    131                         editorToolbarBottom = ( editorToolbar && editorToolbar.getBoundingClientRect().bottom ) || 0;
    132 
    133                 if ( toolbar.length && editor.iframeElement ) {
    134                         // 48 = 43 for the toolbar + 5 buffer
    135                         delta = viewNode.getBoundingClientRect().top + editor.iframeElement.getBoundingClientRect().top - editorToolbarBottom - 48;
    136                 }
    137 
    138                 if ( delta < 0 ) {
    139                         toolbar.removeClass( 'mce-arrow-down' ).css({ top: ( -43 + delta * -1 ) });
    140                 } else if ( delta > 0 && ! toolbar.hasClass( 'mce-arrow-down' ) ) {
    141                         toolbar.addClass( 'mce-arrow-down' ).css({ top: '' });
    142                 }
    143         }
    144 
    145128        /**
    146129         * Deselect a selected view and remove clipboard
    147130         */
     
    298281                                event.stopImmediatePropagation();
    299282                                event.preventDefault();
    300283
    301                                 if ( ( event.type === 'touchend' || event.type === 'mousedown' ) && ! event.metaKey && ! event.ctrlKey ) {
    302                                         if ( editor.dom.hasClass( event.target, 'edit' ) ) {
    303 
    304                                                 // In IE need to transfer focus from the non-editable view back to the editor.
    305                                                 if ( Env.ie ) {
    306                                                         editor.focus();
    307                                                 }
    308 
    309                                                 wp.mce.views.edit( editor, view );
    310                                                 return false;
    311                                         } else if ( editor.dom.hasClass( event.target, 'remove' ) ) {
    312                                                 removeView( view );
    313                                                 return false;
    314                                         }
    315                                 }
    316 
    317284                                if ( event.type === 'touchend' && scrolled ) {
    318285                                        scrolled = false;
    319286                                } else {
     
    685652                }
    686653        });
    687654
     655        editor.addButton( 'wp_view_edit', {
     656                tooltip: 'Edit ', // trailing space is needed, used for context
     657                icon: 'dashicon dashicons-edit',
     658                onclick: function() {
     659                        selected && wp.mce.views.edit( editor, selected );
     660                }
     661        } );
     662
     663        editor.addButton( 'wp_view_remove', {
     664                tooltip: 'Remove',
     665                icon: 'dashicon dashicons-no',
     666                onclick: function() {
     667                        selected && removeView( selected );
     668                }
     669        } );
     670
     671        toolbar = editor.plugins.wptoolbar( [
     672                'wp_view_edit',
     673                'wp_view_remove'
     674        ] );
     675
     676        editor.on( 'wptoolbar', function( event ) {
     677                if ( selected ) {
     678                        event.element = selected;
     679                        event.toolbar = toolbar;
     680                }
     681        } );
     682
    688683        return {
    689684                getView: getView
    690685        };
  • src/wp-includes/js/tinymce/skins/wordpress/wp-content.css

     
    319319        display: none;
    320320}
    321321
    322 .wpview-wrap .toolbar {
    323         position: absolute;
    324         top: -43px;
    325         left: 45%;
    326         left: calc(50% - 32px);
    327         display: none;
    328         z-index: 100;
    329         background-color: #f5f5f5;
    330         border: 1px solid #aaa;
    331         padding: 1px;
    332         cursor: default;
    333         -webkit-border-radius: 2px;
    334         border-radius: 2px;
    335         -webkit-box-shadow: 0 1px 4px rgba( 0, 0, 0, 0.2 );
    336         box-shadow: 0 1px 4px rgba( 0, 0, 0, 0.2 );
    337         -webkit-box-sizing: border-box;
    338         -moz-box-sizing: border-box;
    339         box-sizing: border-box;
    340         margin-bottom: 8px;
    341 }
    342 
    343 .wpview-wrap[data-mce-selected] .toolbar {
    344         display: block;
    345 }
    346 
    347 .wpview-wrap .toolbar:before,
    348 .wpview-wrap .toolbar:after {
    349         position: absolute;
    350         left: 50%;
    351         display: block;
    352         width: 0;
    353         height: 0;
    354         border-style: solid;
    355         border-color: transparent;
    356         border-width: 9px;
    357         margin-left: -9px;
    358         content: '';
    359 }
    360 
    361 .wpview-wrap .toolbar:after {
    362         border-width: 8px;
    363         margin-left: -8px;
    364 }
    365 
    366 .wpview-wrap .toolbar.mce-arrow-down:before {
    367         bottom: -18px;
    368         border-top-color: #aaa;
    369 }
    370 
    371 .wpview-wrap .toolbar.mce-arrow-down:after {
    372         bottom: -16px;
    373         border-top-color: #f5f5f5;
    374 }
    375 
    376 .wpview-wrap .toolbar.mce-arrow-up:before {
    377         top: -18px;
    378         border-bottom-color: #aaa;
    379 }
    380 
    381 .wpview-wrap .toolbar.mce-arrow-up:after {
    382         top: -16px;
    383         border-bottom-color: #f5f5f5;
    384 }
    385 
    386 .wpview-wrap .toolbar div {
    387         margin: 2px;
    388         padding: 2px 3px;
    389         width: 20px;
    390         height: 20px;
    391         color: #777;
    392         cursor: pointer;
    393         font-size: 20px;
    394         border: 1px solid transparent;
    395         border-radius: 2px;
    396 }
    397 
    398 .wpview-wrap .toolbar div:hover {
    399         background-color: #fafafa;
    400         border-color: #999;
    401         color: #222;
    402         -webkit-box-shadow: inset 0 1px 0 #fff, 0 1px 0 rgba( 0, 0, 0, 0.08 );
    403         box-shadow: inset 0 1px 0 #fff, 0 1px 0 rgba( 0, 0, 0, 0.08 );
    404         outline: none;
    405 }
    406 
    407322.wpview-wrap .loading-placeholder {
    408323        border: 1px dashed #ccc;
    409324        padding: 10px;
     
    455370        background: transparent;
    456371}
    457372
    458 .ie8 .wpview-wrap .toolbar div,
    459 .ie7 .wpview-wrap .toolbar div {
    460         display: inline;
    461         padding: 4px;
    462 }
    463 
    464 .ie8 .dashicons-edit,
    465 .ie7 .dashicons-edit {
    466         background-image: url(images/dashicon-edit.png);
    467 }
    468 
    469 .ie8 .dashicons-no,
    470 .ie7 .dashicons-no {
    471         background-image: url(images/dashicon-no.png);
    472 }
    473 
    474373.wpview-error {
    475374        border: 1px solid #dedede;
    476375        padding: 1em 0;
     
    497396        font-family: 'Open Sans', sans-serif;
    498397}
    499398
    500 .wont-play {
    501         padding: 4px 0;
    502 }
    503 
    504 .wont-play p {
    505         font-size: 13px;
    506         line-height: 1.3;
    507         display: block;
    508         width: 70%;
    509         margin: 0 15%;
    510         text-align: center;
    511 }
    512 
    513399.wpview-type-gallery:after {
    514400    content: '';
    515401        display: table;
     
    536422        margin: auto;
    537423}
    538424
    539 
    540425.gallery .gallery-item {
    541426        float: left;
    542427        margin: 0;