WordPress.org

Make WordPress Core

Ticket #28328: 28328.4.patch

File 28328.4.patch, 44.9 KB (added by iseulde, 4 years ago)
  • src/wp-admin/css/edit.css

     
    3737
    3838#titlediv {
    3939        position: relative;
    40         margin-bottom: 10px;
    4140}
    4241
    4342#titlediv label {
     
    337336        background-color: #f7f7f7;
    338337        -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    339338        box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    340         cursor: row-resize;
     339        z-index: 999;
    341340}
    342341
    343342#post-status-info td {
     
    345344}
    346345
    347346.autosave-info {
    348         padding: 2px;
     347        padding: 2px 10px;
    349348        text-align: right;
    350349}
    351350
     
    353352        border: none;
    354353}
    355354
    356 #content-resize-handle {
    357         background: transparent url(../images/resize.gif) no-repeat scroll right bottom;
    358         width: 12px;
     355#wp-word-count {
     356        display: block;
     357        padding: 2px 10px;
    359358}
    360359
    361 .rtl #content-resize-handle {
    362         background: transparent url(../images/resize-rtl.gif) no-repeat scroll left bottom;
     360#wp-content-editor-container {
     361        position: relative;
    363362}
    364363
    365 #wp-word-count {
    366         display: block;
    367         padding: 2px 10px;
     364#content {
     365        resize: none;
     366}
     367
     368#content-clone {
     369        z-index: -1;
     370        position: absolute;
     371        top: 0;
     372        visibility: hidden;
     373        overflow: hidden;
    368374}
    369375
    370376#timestampdiv select {
     
    11411147/* =Media Queries
    11421148-------------------------------------------------------------- */
    11431149
    1144 /**
    1145  * HiDPI Displays
    1146  */
    1147 @media print,
    1148   (-o-min-device-pixel-ratio: 5/4),
    1149   (-webkit-min-device-pixel-ratio: 1.25),
    1150   (min-resolution: 120dpi) {
    1151         #content-resize-handle,
    1152         #post-body .wp_themeSkin .mceStatusbar a.mceResize {
    1153                 background: transparent url(../images/resize-2x.gif) no-repeat scroll right bottom;
    1154                 -webkit-background-size: 11px 11px;
    1155                 background-size: 11px 11px;
    1156         }
    1157 
    1158         .rtl #content-resize-handle,
    1159         .rtl #post-body .wp_themeSkin .mceStatusbar a.mceResize {
    1160                 background: transparent url(../images/resize-rtl-2x.gif) no-repeat scroll right bottom;
    1161         }
    1162 }
    1163 
    11641150/* one column on the post write/edit screen */
    11651151@media only screen and (max-width: 850px) {
    11661152        #poststuff {
  • src/wp-admin/css/press-this.css

     
    1515        color: #333;
    1616}
    1717
    18 .press-this #content-resize-handle {
    19         bottom: 2px;
    20 }
    21 
    2218body.press-this {
    2319        color: #333;
    2420        margin: 0;
  • src/wp-admin/edit-form-advanced.php

     
    489489        'dfw' => true,
    490490        'drag_drop_upload' => true,
    491491        'tabfocus_elements' => 'insert-media-button-1,save-post',
    492         'editor_height' => 360,
    493492        'tinymce' => array(
    494493                'resize' => false,
    495494                'add_unload_trigger' => false,
     
    510509                echo '</span>';
    511510        } ?>
    512511        </td>
    513         <td id="content-resize-handle" class="hide-if-no-js"><br /></td>
    514512</tr></tbody></table>
    515513
    516514</div>
  • src/wp-admin/js/common.js

     
    210210                                setUserSetting('mfold', 'f');
    211211                        }
    212212                }
     213
     214                $( wp ).trigger( 'menu:collapse' );
    213215        });
    214216
    215217        if ( 'ontouchstart' in window || /IEMobile\/[1-9]/.test(navigator.userAgent) ) { // touch screen device
     
    721723        window.wpResponsive.init();
    722724});
    723725
    724 // make Windows 8 devices playing along nicely
     726// Make Windows 8 devices play along nicely.
    725727(function(){
    726728        if ( '-ms-user-select' in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/) ) {
    727729                var msViewportStyle = document.createElement( 'style' );
  • src/wp-admin/js/editor.js

     
    11/* global tinymce, tinyMCEPreInit, QTags, setUserSetting */
    22
    3 window.switchEditors = {
    4 
    5         switchto: function( el ) {
    6                 var aid = el.id,
    7                         l = aid.length,
    8                         id = aid.substr( 0, l - 5 ),
    9                         mode = aid.substr( l - 4 );
    10 
    11                 this.go( id, mode );
    12         },
    13 
    14         // mode can be 'html', 'tmce', or 'toggle'; 'html' is used for the 'Text' editor tab.
    15         go: function( id, mode ) {
    16                 var t = this, ed, wrap_id, txtarea_el, iframe, editorHeight, toolbarHeight,
    17                         DOM = tinymce.DOM; //DOMUtils outside the editor iframe
    18 
    19                 id = id || 'content';
    20                 mode = mode || 'toggle';
    21 
    22                 ed = tinymce.get( id );
    23                 wrap_id = 'wp-' + id + '-wrap';
    24                 txtarea_el = DOM.get( id );
    25 
    26                 if ( 'toggle' === mode ) {
    27                         if ( ed && ! ed.isHidden() ) {
    28                                 mode = 'html';
    29                         } else {
    30                                 mode = 'tmce';
     3( function( $ ) {
     4        'use strict';
     5       
     6        window.wp = wp || {};
     7        wp.editor = wp.editor || {};
     8
     9        wp.editor.mode = {
     10                switchto: function( el ) {
     11                        var aid = el.id,
     12                                l = aid.length,
     13                                id = aid.substr( 0, l - 5 ),
     14                                mode = aid.substr( l - 4 );
     15       
     16                        this.go( id, mode );
     17                },
     18       
     19                // mode can be 'html', 'tmce', or 'toggle'; 'html' is used for the 'Text' editor tab.
     20                go: function( id, mode ) {
     21                        var t = this, ed, wrap_id, txtarea_el, iframe, editorHeight, toolbarHeight,
     22                                DOM = tinymce.DOM; //DOMUtils outside the editor iframe
     23       
     24                        id = id || 'content';
     25                        mode = mode || 'toggle';
     26       
     27                        ed = tinymce.get( id );
     28                        wrap_id = 'wp-' + id + '-wrap';
     29                        txtarea_el = DOM.get( id );
     30       
     31                        if ( 'toggle' === mode ) {
     32                                if ( ed && ! ed.isHidden() ) {
     33                                        mode = 'html';
     34                                } else {
     35                                        mode = 'tmce';
     36                                }
    3137                        }
    32                 }
    33 
    34                 function getToolbarHeight() {
    35                         var node = DOM.select( '.mce-toolbar-grp', ed.getContainer() )[0],
    36                                 height = node && node.clientHeight;
    37 
    38                         if ( height && height > 10 && height < 200 ) {
    39                                 return parseInt( height, 10 );
     38       
     39                        function getToolbarHeight() {
     40                                var node = DOM.select( '.mce-toolbar-grp', ed.getContainer() )[0],
     41                                        height = node && node.clientHeight;
     42       
     43                                if ( height && height > 10 && height < 200 ) {
     44                                        return parseInt( height, 10 );
     45                                }
     46       
     47                                return 30;
    4048                        }
    41 
    42                         return 30;
    43                 }
    44 
    45                 if ( 'tmce' === mode || 'tinymce' === mode ) {
    46                         if ( ed && ! ed.isHidden() ) {
    47                                 return false;
     49       
     50                        if ( 'tmce' === mode || 'tinymce' === mode ) {
     51                                if ( ed && ! ed.isHidden() ) {
     52                                        return false;
     53                                }
     54       
     55                                if ( typeof( QTags ) !== 'undefined' ) {
     56                                        QTags.closeAllTags( id );
     57                                }
     58       
     59                                editorHeight = txtarea_el ? parseInt( txtarea_el.style.height, 10 ) : 0;
     60       
     61                                if ( tinyMCEPreInit.mceInit[ id ] && tinyMCEPreInit.mceInit[ id ].wpautop ) {
     62                                        txtarea_el.value = t.wpautop( txtarea_el.value );
     63                                }
     64       
     65                                if ( ed ) {
     66                                        ed.show();
     67       
     68                                        // No point resizing the iframe in iOS
     69                                        if ( ! tinymce.Env.iOS && editorHeight ) {
     70                                                toolbarHeight = getToolbarHeight();
     71                                                editorHeight = editorHeight - toolbarHeight + 14;
     72       
     73                                                // height cannot be under 50 or over 5000
     74                                                if ( editorHeight > 50 && editorHeight < 5000 ) {
     75                                                        ed.theme.resizeTo( null, editorHeight );
     76                                                }
     77                                        }
     78                                } else {
     79                                        tinymce.init( tinyMCEPreInit.mceInit[id] );
     80                                }
     81       
     82                                DOM.removeClass( wrap_id, 'html-active' );
     83                                DOM.addClass( wrap_id, 'tmce-active' );
     84                                setUserSetting( 'editor', 'tinymce' );
     85       
     86                        } else if ( 'html' === mode ) {
     87       
     88                                if ( ed && ed.isHidden() ) {
     89                                        return false;
     90                                }
     91       
     92                                if ( ed ) {
     93                                        if ( ! tinymce.Env.iOS ) {
     94                                                iframe = DOM.get( id + '_ifr' );
     95                                                editorHeight = iframe ? parseInt( iframe.style.height, 10 ) : 0;
     96       
     97                                                if ( editorHeight ) {
     98                                                        toolbarHeight = getToolbarHeight();
     99                                                        editorHeight = editorHeight + toolbarHeight - 14;
     100       
     101                                                        // height cannot be under 50 or over 5000
     102                                                        if ( editorHeight > 50 && editorHeight < 5000 ) {
     103                                                                txtarea_el.style.height = editorHeight + 'px';
     104                                                        }
     105                                                }
     106                                        }
     107       
     108                                        ed.hide();
     109                                } else {
     110                                        // The TinyMCE instance doesn't exist, run the content through 'pre_wpautop()' and show the textarea
     111                                        if ( tinyMCEPreInit.mceInit[ id ] && tinyMCEPreInit.mceInit[ id ].wpautop ) {
     112                                                txtarea_el.value = t.pre_wpautop( txtarea_el.value );
     113                                        }
     114       
     115                                        DOM.setStyles( txtarea_el, {'display': '', 'visibility': ''} );
     116                                }
     117       
     118                                DOM.removeClass( wrap_id, 'tmce-active' );
     119                                DOM.addClass( wrap_id, 'html-active' );
     120                                setUserSetting( 'editor', 'html' );
    48121                        }
    49 
    50                         if ( typeof( QTags ) !== 'undefined' ) {
    51                                 QTags.closeAllTags( id );
     122                        return false;
     123                },
     124       
     125                _wp_Nop: function( content ) {
     126                        var blocklist1, blocklist2,
     127                                preserve_linebreaks = false,
     128                                preserve_br = false;
     129       
     130                        // Protect pre|script tags
     131                        if ( content.indexOf( '<pre' ) !== -1 || content.indexOf( '<script' ) !== -1 ) {
     132                                preserve_linebreaks = true;
     133                                content = content.replace( /<(pre|script)[^>]*>[\s\S]+?<\/\1>/g, function( a ) {
     134                                        a = a.replace( /<br ?\/?>(\r\n|\n)?/g, '<wp-line-break>' );
     135                                        a = a.replace( /<\/?p( [^>]*)?>(\r\n|\n)?/g, '<wp-line-break>' );
     136                                        return a.replace( /\r?\n/g, '<wp-line-break>' );
     137                                });
    52138                        }
    53 
    54                         editorHeight = txtarea_el ? parseInt( txtarea_el.style.height, 10 ) : 0;
    55 
    56                         if ( tinyMCEPreInit.mceInit[ id ] && tinyMCEPreInit.mceInit[ id ].wpautop ) {
    57                                 txtarea_el.value = t.wpautop( txtarea_el.value );
     139       
     140                        // keep <br> tags inside captions and remove line breaks
     141                        if ( content.indexOf( '[caption' ) !== -1 ) {
     142                                preserve_br = true;
     143                                content = content.replace( /\[caption[\s\S]+?\[\/caption\]/g, function( a ) {
     144                                        return a.replace( /<br([^>]*)>/g, '<wp-temp-br$1>' ).replace( /[\r\n\t]+/, '' );
     145                                });
    58146                        }
    59 
    60                         if ( ed ) {
    61                                 ed.show();
    62 
    63                                 // No point resizing the iframe in iOS
    64                                 if ( ! tinymce.Env.iOS && editorHeight ) {
    65                                         toolbarHeight = getToolbarHeight();
    66                                         editorHeight = editorHeight - toolbarHeight + 14;
    67 
    68                                         // height cannot be under 50 or over 5000
    69                                         if ( editorHeight > 50 && editorHeight < 5000 ) {
    70                                                 ed.theme.resizeTo( null, editorHeight );
    71                                         }
     147       
     148                        // Pretty it up for the source editor
     149                        blocklist1 = 'blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|div|h[1-6]|p|fieldset';
     150                        content = content.replace( new RegExp( '\\s*</(' + blocklist1 + ')>\\s*', 'g' ), '</$1>\n' );
     151                        content = content.replace( new RegExp( '\\s*<((?:' + blocklist1 + ')(?: [^>]*)?)>', 'g' ), '\n<$1>' );
     152       
     153                        // Mark </p> if it has any attributes.
     154                        content = content.replace( /(<p [^>]+>.*?)<\/p>/g, '$1</p#>' );
     155       
     156                        // Separate <div> containing <p>
     157                        content = content.replace( /<div( [^>]*)?>\s*<p>/gi, '<div$1>\n\n' );
     158       
     159                        // Remove <p> and <br />
     160                        content = content.replace( /\s*<p>/gi, '' );
     161                        content = content.replace( /\s*<\/p>\s*/gi, '\n\n' );
     162                        content = content.replace( /\n[\s\u00a0]+\n/g, '\n\n' );
     163                        content = content.replace( /\s*<br ?\/?>\s*/gi, '\n' );
     164       
     165                        // Fix some block element newline issues
     166                        content = content.replace( /\s*<div/g, '\n<div' );
     167                        content = content.replace( /<\/div>\s*/g, '</div>\n' );
     168                        content = content.replace( /\s*\[caption([^\[]+)\[\/caption\]\s*/gi, '\n\n[caption$1[/caption]\n\n' );
     169                        content = content.replace( /caption\]\n\n+\[caption/g, 'caption]\n\n[caption' );
     170       
     171                        blocklist2 = 'blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|h[1-6]|pre|fieldset';
     172                        content = content.replace( new RegExp('\\s*<((?:' + blocklist2 + ')(?: [^>]*)?)\\s*>', 'g' ), '\n<$1>' );
     173                        content = content.replace( new RegExp('\\s*</(' + blocklist2 + ')>\\s*', 'g' ), '</$1>\n' );
     174                        content = content.replace( /<li([^>]*)>/g, '\t<li$1>' );
     175       
     176                        if ( content.indexOf( '<hr' ) !== -1 ) {
     177                                content = content.replace( /\s*<hr( [^>]*)?>\s*/g, '\n\n<hr$1>\n\n' );
     178                        }
     179       
     180                        if ( content.indexOf( '<object' ) !== -1 ) {
     181                                content = content.replace( /<object[\s\S]+?<\/object>/g, function( a ) {
     182                                        return a.replace( /[\r\n]+/g, '' );
     183                                });
     184                        }
     185       
     186                        // Unmark special paragraph closing tags
     187                        content = content.replace( /<\/p#>/g, '</p>\n' );
     188                        content = content.replace( /\s*(<p [^>]+>[\s\S]*?<\/p>)/g, '\n$1' );
     189       
     190                        // Trim whitespace
     191                        content = content.replace( /^\s+/, '' );
     192                        content = content.replace( /[\s\u00a0]+$/, '' );
     193       
     194                        // put back the line breaks in pre|script
     195                        if ( preserve_linebreaks ) {
     196                                content = content.replace( /<wp-line-break>/g, '\n' );
     197                        }
     198       
     199                        // and the <br> tags in captions
     200                        if ( preserve_br ) {
     201                                content = content.replace( /<wp-temp-br([^>]*)>/g, '<br$1>' );
     202                        }
     203       
     204                        return content;
     205                },
     206       
     207                _wp_Autop: function(pee) {
     208                        var preserve_linebreaks = false,
     209                                preserve_br = false,
     210                                blocklist = 'table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre' +
     211                                        '|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section' +
     212                                        '|article|aside|hgroup|header|footer|nav|figure|details|menu|summary';
     213       
     214                        if ( pee.indexOf( '<object' ) !== -1 ) {
     215                                pee = pee.replace( /<object[\s\S]+?<\/object>/g, function( a ) {
     216                                        return a.replace( /[\r\n]+/g, '' );
     217                                });
     218                        }
     219       
     220                        pee = pee.replace( /<[^<>]+>/g, function( a ){
     221                                return a.replace( /[\r\n]+/g, ' ' );
     222                        });
     223       
     224                        // Protect pre|script tags
     225                        if ( pee.indexOf( '<pre' ) !== -1 || pee.indexOf( '<script' ) !== -1 ) {
     226                                preserve_linebreaks = true;
     227                                pee = pee.replace( /<(pre|script)[^>]*>[\s\S]+?<\/\1>/g, function( a ) {
     228                                        return a.replace( /(\r\n|\n)/g, '<wp-line-break>' );
     229                                });
     230                        }
     231       
     232                        // keep <br> tags inside captions and convert line breaks
     233                        if ( pee.indexOf( '[caption' ) !== -1 ) {
     234                                preserve_br = true;
     235                                pee = pee.replace( /\[caption[\s\S]+?\[\/caption\]/g, function( a ) {
     236                                        // keep existing <br>
     237                                        a = a.replace( /<br([^>]*)>/g, '<wp-temp-br$1>' );
     238                                        // no line breaks inside HTML tags
     239                                        a = a.replace( /<[a-zA-Z0-9]+( [^<>]+)?>/g, function( b ) {
     240                                                return b.replace( /[\r\n\t]+/, ' ' );
     241                                        });
     242                                        // convert remaining line breaks to <br>
     243                                        return a.replace( /\s*\n\s*/g, '<wp-temp-br />' );
     244                                });
     245                        }
     246       
     247                        pee = pee + '\n\n';
     248                        pee = pee.replace( /<br \/>\s*<br \/>/gi, '\n\n' );
     249                        pee = pee.replace( new RegExp( '(<(?:' + blocklist + ')(?: [^>]*)?>)', 'gi' ), '\n$1' );
     250                        pee = pee.replace( new RegExp( '(</(?:' + blocklist + ')>)', 'gi' ), '$1\n\n' );
     251                        pee = pee.replace( /<hr( [^>]*)?>/gi, '<hr$1>\n\n' ); // hr is self closing block element
     252                        pee = pee.replace( /\r\n|\r/g, '\n' );
     253                        pee = pee.replace( /\n\s*\n+/g, '\n\n' );
     254                        pee = pee.replace( /([\s\S]+?)\n\n/g, '<p>$1</p>\n' );
     255                        pee = pee.replace( /<p>\s*?<\/p>/gi, '');
     256                        pee = pee.replace( new RegExp( '<p>\\s*(</?(?:' + blocklist + ')(?: [^>]*)?>)\\s*</p>', 'gi' ), '$1' );
     257                        pee = pee.replace( /<p>(<li.+?)<\/p>/gi, '$1');
     258                        pee = pee.replace( /<p>\s*<blockquote([^>]*)>/gi, '<blockquote$1><p>');
     259                        pee = pee.replace( /<\/blockquote>\s*<\/p>/gi, '</p></blockquote>');
     260                        pee = pee.replace( new RegExp( '<p>\\s*(</?(?:' + blocklist + ')(?: [^>]*)?>)', 'gi' ), '$1' );
     261                        pee = pee.replace( new RegExp( '(</?(?:' + blocklist + ')(?: [^>]*)?>)\\s*</p>', 'gi' ), '$1' );
     262                        pee = pee.replace( /\s*\n/gi, '<br />\n');
     263                        pee = pee.replace( new RegExp( '(</?(?:' + blocklist + ')[^>]*>)\\s*<br />', 'gi' ), '$1' );
     264                        pee = pee.replace( /<br \/>(\s*<\/?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)/gi, '$1' );
     265                        pee = pee.replace( /(?:<p>|<br ?\/?>)*\s*\[caption([^\[]+)\[\/caption\]\s*(?:<\/p>|<br ?\/?>)*/gi, '[caption$1[/caption]' );
     266       
     267                        pee = pee.replace( /(<(?:div|th|td|form|fieldset|dd)[^>]*>)(.*?)<\/p>/g, function( a, b, c ) {
     268                                if ( c.match( /<p( [^>]*)?>/ ) ) {
     269                                        return a;
    72270                                }
    73                         } else {
    74                                 tinymce.init( tinyMCEPreInit.mceInit[id] );
     271       
     272                                return b + '<p>' + c + '</p>';
     273                        });
     274       
     275                        // put back the line breaks in pre|script
     276                        if ( preserve_linebreaks ) {
     277                                pee = pee.replace( /<wp-line-break>/g, '\n' );
    75278                        }
     279       
     280                        if ( preserve_br ) {
     281                                pee = pee.replace( /<wp-temp-br([^>]*)>/g, '<br$1>' );
     282                        }
     283       
     284                        return pee;
     285                },
     286       
     287                pre_wpautop: function( content ) {
     288                        var t = this, o = { o: t, data: content, unfiltered: content },
     289                                q = typeof( jQuery ) !== 'undefined';
     290       
     291                        if ( q ) {
     292                                jQuery( 'body' ).trigger( 'beforePreWpautop', [ o ] );
     293                        }
     294       
     295                        o.data = t._wp_Nop( o.data );
     296       
     297                        if ( q ) {
     298                                jQuery('body').trigger('afterPreWpautop', [ o ] );
     299                        }
     300       
     301                        return o.data;
     302                },
     303       
     304                wpautop: function( pee ) {
     305                        var t = this, o = { o: t, data: pee, unfiltered: pee },
     306                                q = typeof( jQuery ) !== 'undefined';
     307       
     308                        if ( q ) {
     309                                jQuery( 'body' ).trigger('beforeWpautop', [ o ] );
     310                        }
     311       
     312                        o.data = t._wp_Autop( o.data );
     313       
     314                        if ( q ) {
     315                                jQuery( 'body' ).trigger('afterWpautop', [ o ] );
     316                        }
     317       
     318                        return o.data;
     319                }
     320        };
     321       
     322        window.switchEditors = wp.editor.mode;
     323
     324        $( function() {
     325                if ( ! wp.editor.fullscreen ) {
     326                        return;
     327                }
     328
     329                var $window = $( window ),
     330                        $document = $( document ),
     331                        $adminBar = $( '#wpadminbar' ),
     332                        $tools = $( '#wp-content-editor-tools' ),
     333                        $visualTop,
     334                        $visualEditor,
     335                        $textTop = $( '#ed_toolbar' ),
     336                        $textEditor = $( '#content' ),
     337                        $textEditorClone = $( '<div id="content-clone"></div>' ),
     338                        $bottom = $( '#post-status-info' ),
     339                        $statusBar,
     340                        adjust,
     341                        fullscreen = window.wp.editor.fullscreen,
     342                        editorInstance,
     343                        fixedTop = false,
     344                        fixedBottom = false;
     345
     346                $textEditorClone.insertAfter( $textEditor );
     347
     348                $textEditorClone.css( {
     349                        'font-family': $textEditor.css( 'font-family' ),
     350                        'font-size': $textEditor.css( 'font-size' ),
     351                        'line-height': $textEditor.css( 'line-height' ),
     352                        'padding': $textEditor.css( 'padding' ),
     353                        'padding-top': 37,
     354                        'white-space': 'pre-wrap',
     355                        'word-wrap': 'break-word'
     356                } );
     357
     358                $textEditor.on( 'focus input propertychange', function() {
     359                        textEditorResize();
     360                } );
     361
     362                $textEditor.on( 'keyup', function() {
     363                        var range = document.createRange(),
     364                                start = $textEditor[0].selectionStart,
     365                                end = $textEditor[0].selectionEnd,
     366                                textNode = $textEditorClone[0].firstChild,
     367                                windowHeight = $window.height(),
     368                                offset, cursorTop, cursorBottom, editorTop, editorBottom;
    76369
    77                         DOM.removeClass( wrap_id, 'html-active' );
    78                         DOM.addClass( wrap_id, 'tmce-active' );
    79                         setUserSetting( 'editor', 'tinymce' );
     370                        if ( start && end && start !== end ) {
     371                                return;
     372                        }
     373
     374                        range.setStart( textNode, start );
     375                        range.setEnd( textNode, end + 1 );
    80376
    81                 } else if ( 'html' === mode ) {
     377                        offset = range.getBoundingClientRect();
    82378
    83                         if ( ed && ed.isHidden() ) {
    84                                 return false;
     379                        if ( ! offset.height ) {
     380                                return;
    85381                        }
    86382
    87                         if ( ed ) {
    88                                 if ( ! tinymce.Env.iOS ) {
    89                                         iframe = DOM.get( id + '_ifr' );
    90                                         editorHeight = iframe ? parseInt( iframe.style.height, 10 ) : 0;
     383                        cursorTop = offset.top;
     384                        cursorBottom = cursorTop + offset.height;
     385                        editorTop = $adminBar.outerHeight() + $textTop.outerHeight();
     386                        editorBottom = windowHeight - $bottom.outerHeight();
    91387
    92                                         if ( editorHeight ) {
    93                                                 toolbarHeight = getToolbarHeight();
    94                                                 editorHeight = editorHeight + toolbarHeight - 14;
     388                        if ( cursorTop < editorTop || cursorBottom > editorBottom ) {
     389                                window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset - windowHeight / 2 );
     390                        }
     391                } );
    95392
    96                                                 // height cannot be under 50 or over 5000
    97                                                 if ( editorHeight > 50 && editorHeight < 5000 ) {
    98                                                         txtarea_el.style.height = editorHeight + 'px';
    99                                                 }
    100                                         }
    101                                 }
     393                function textEditorResize() {
     394                        if ( editorInstance && ! editorInstance.isHidden() ) {
     395                                return;
     396                        }
    102397
    103                                 ed.hide();
    104                         } else {
    105                                 // The TinyMCE instance doesn't exist, run the content through 'pre_wpautop()' and show the textarea
    106                                 if ( tinyMCEPreInit.mceInit[ id ] && tinyMCEPreInit.mceInit[ id ].wpautop ) {
    107                                         txtarea_el.value = t.pre_wpautop( txtarea_el.value );
    108                                 }
     398                        var hiddenHeight = $textEditorClone.width( $textEditor.width() ).text( $textEditor.val() + '&nbsp;' ).height(),
     399                                textEditorHeight = $textEditor.height();
    109400
    110                                 DOM.setStyles( txtarea_el, {'display': '', 'visibility': ''} );
     401                        if ( hiddenHeight < 300 ) {
     402                                hiddenHeight = 300;
    111403                        }
    112404
    113                         DOM.removeClass( wrap_id, 'tmce-active' );
    114                         DOM.addClass( wrap_id, 'html-active' );
    115                         setUserSetting( 'editor', 'html' );
    116                 }
    117                 return false;
    118         },
     405                        if ( hiddenHeight === textEditorHeight ) {
     406                                return;
     407                        }
    119408
    120         _wp_Nop: function( content ) {
    121                 var blocklist1, blocklist2,
    122                         preserve_linebreaks = false,
    123                         preserve_br = false;
    124 
    125                 // Protect pre|script tags
    126                 if ( content.indexOf( '<pre' ) !== -1 || content.indexOf( '<script' ) !== -1 ) {
    127                         preserve_linebreaks = true;
    128                         content = content.replace( /<(pre|script)[^>]*>[\s\S]+?<\/\1>/g, function( a ) {
    129                                 a = a.replace( /<br ?\/?>(\r\n|\n)?/g, '<wp-line-break>' );
    130                                 a = a.replace( /<\/?p( [^>]*)?>(\r\n|\n)?/g, '<wp-line-break>' );
    131                                 return a.replace( /\r?\n/g, '<wp-line-break>' );
    132                         });
    133                 }
     409                        $textEditor.height( hiddenHeight );
    134410
    135                 // keep <br> tags inside captions and remove line breaks
    136                 if ( content.indexOf( '[caption' ) !== -1 ) {
    137                         preserve_br = true;
    138                         content = content.replace( /\[caption[\s\S]+?\[\/caption\]/g, function( a ) {
    139                                 return a.replace( /<br([^>]*)>/g, '<wp-temp-br$1>' ).replace( /[\r\n\t]+/, '' );
    140                         });
     411                        adjust( 'resize' );
    141412                }
    142413
    143                 // Pretty it up for the source editor
    144                 blocklist1 = 'blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|div|h[1-6]|p|fieldset';
    145                 content = content.replace( new RegExp( '\\s*</(' + blocklist1 + ')>\\s*', 'g' ), '</$1>\n' );
    146                 content = content.replace( new RegExp( '\\s*<((?:' + blocklist1 + ')(?: [^>]*)?)>', 'g' ), '\n<$1>' );
    147 
    148                 // Mark </p> if it has any attributes.
    149                 content = content.replace( /(<p [^>]+>.*?)<\/p>/g, '$1</p#>' );
    150 
    151                 // Separate <div> containing <p>
    152                 content = content.replace( /<div( [^>]*)?>\s*<p>/gi, '<div$1>\n\n' );
    153 
    154                 // Remove <p> and <br />
    155                 content = content.replace( /\s*<p>/gi, '' );
    156                 content = content.replace( /\s*<\/p>\s*/gi, '\n\n' );
    157                 content = content.replace( /\n[\s\u00a0]+\n/g, '\n\n' );
    158                 content = content.replace( /\s*<br ?\/?>\s*/gi, '\n' );
    159 
    160                 // Fix some block element newline issues
    161                 content = content.replace( /\s*<div/g, '\n<div' );
    162                 content = content.replace( /<\/div>\s*/g, '</div>\n' );
    163                 content = content.replace( /\s*\[caption([^\[]+)\[\/caption\]\s*/gi, '\n\n[caption$1[/caption]\n\n' );
    164                 content = content.replace( /caption\]\n\n+\[caption/g, 'caption]\n\n[caption' );
    165 
    166                 blocklist2 = 'blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|h[1-6]|pre|fieldset';
    167                 content = content.replace( new RegExp('\\s*<((?:' + blocklist2 + ')(?: [^>]*)?)\\s*>', 'g' ), '\n<$1>' );
    168                 content = content.replace( new RegExp('\\s*</(' + blocklist2 + ')>\\s*', 'g' ), '</$1>\n' );
    169                 content = content.replace( /<li([^>]*)>/g, '\t<li$1>' );
     414                // We need to wait for TinyMCE to initialize.
     415                $document.on( 'tinymce-editor-init.editor-scroll', function( event, editor ) {
     416                        var $contentWrap;
    170417
    171                 if ( content.indexOf( '<hr' ) !== -1 ) {
    172                         content = content.replace( /\s*<hr( [^>]*)?>\s*/g, '\n\n<hr$1>\n\n' );
    173                 }
    174 
    175                 if ( content.indexOf( '<object' ) !== -1 ) {
    176                         content = content.replace( /<object[\s\S]+?<\/object>/g, function( a ) {
    177                                 return a.replace( /[\r\n]+/g, '' );
    178                         });
    179                 }
     418                        // Make sure it's the main editor.
     419                        if ( editor.id !== 'content' ) {
     420                                return;
     421                        }
    180422
    181                 // Unmark special paragraph closing tags
    182                 content = content.replace( /<\/p#>/g, '</p>\n' );
    183                 content = content.replace( /\s*(<p [^>]+>[\s\S]*?<\/p>)/g, '\n$1' );
    184 
    185                 // Trim whitespace
    186                 content = content.replace( /^\s+/, '' );
    187                 content = content.replace( /[\s\u00a0]+$/, '' );
    188 
    189                 // put back the line breaks in pre|script
    190                 if ( preserve_linebreaks ) {
    191                         content = content.replace( /<wp-line-break>/g, '\n' );
    192                 }
     423                        // Copy the editor instance.
     424                        editorInstance = editor;
    193425
    194                 // and the <br> tags in captions
    195                 if ( preserve_br ) {
    196                         content = content.replace( /<wp-temp-br([^>]*)>/g, '<br$1>' );
    197                 }
     426                        // Resizing will be handled by the autoresize plugin.
     427                        editor.theme.resizeTo = function() {};
    198428
    199                 return content;
    200         },
     429                        // Set the minimum height to the initial viewport height.
     430                        editor.settings.autoresize_min_height = 300;
    201431
    202         _wp_Autop: function(pee) {
    203                 var preserve_linebreaks = false,
    204                         preserve_br = false,
    205                         blocklist = 'table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre' +
    206                                 '|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section' +
    207                                 '|article|aside|hgroup|header|footer|nav|figure|details|menu|summary';
    208 
    209                 if ( pee.indexOf( '<object' ) !== -1 ) {
    210                         pee = pee.replace( /<object[\s\S]+?<\/object>/g, function( a ) {
    211                                 return a.replace( /[\r\n]+/g, '' );
    212                         });
    213                 }
     432                        // Get the necessary UI elements.
     433                        $contentWrap = $( '#wp-content-wrap' );
     434                        $visualTop = $contentWrap.find( '.mce-toolbar-grp' );
     435                        $visualEditor = $contentWrap.find( '.mce-edit-area' );
     436                        $statusBar = $contentWrap.find( '.mce-statusbar' ).filter( ':visible' );
     437
     438                        // Adjust when switching editor modes.
     439                        editor.on( 'show', function() {
     440                                setTimeout( function() {
     441                                        editor.execCommand( 'mceAutoResize' );
     442                                        adjust( 'resize' );
     443                                }, 200 );
     444                        } );
     445
     446                        editor.on( 'keyup', function() {
     447                                var offset = editor.wp.getCursorOffset(),
     448                                        windowHeight = $window.height(),
     449                                        cursorTop, cursorBottom, editorTop, editorBottom;
    214450
    215                 pee = pee.replace( /<[^<>]+>/g, function( a ){
    216                         return a.replace( /[\r\n]+/g, ' ' );
    217                 });
    218 
    219                 // Protect pre|script tags
    220                 if ( pee.indexOf( '<pre' ) !== -1 || pee.indexOf( '<script' ) !== -1 ) {
    221                         preserve_linebreaks = true;
    222                         pee = pee.replace( /<(pre|script)[^>]*>[\s\S]+?<\/\1>/g, function( a ) {
    223                                 return a.replace( /(\r\n|\n)/g, '<wp-line-break>' );
    224                         });
    225                 }
     451                                if ( ! offset ) {
     452                                        return;
     453                                }
    226454
    227                 // keep <br> tags inside captions and convert line breaks
    228                 if ( pee.indexOf( '[caption' ) !== -1 ) {
    229                         preserve_br = true;
    230                         pee = pee.replace( /\[caption[\s\S]+?\[\/caption\]/g, function( a ) {
    231                                 // keep existing <br>
    232                                 a = a.replace( /<br([^>]*)>/g, '<wp-temp-br$1>' );
    233                                 // no line breaks inside HTML tags
    234                                 a = a.replace( /<[a-zA-Z0-9]+( [^<>]+)?>/g, function( b ) {
    235                                         return b.replace( /[\r\n\t]+/, ' ' );
    236                                 });
    237                                 // convert remaining line breaks to <br>
    238                                 return a.replace( /\s*\n\s*/g, '<wp-temp-br />' );
    239                         });
    240                 }
     455                                cursorTop = offset.top + editor.getContentAreaContainer().getElementsByTagName( 'iframe' )[0].getBoundingClientRect().top;
     456                                cursorBottom = cursorTop + offset.height;
     457                                editorTop = $adminBar.outerHeight() + $tools.outerHeight() + $visualTop.outerHeight();
     458                                editorBottom = $window.height() - $bottom.outerHeight();
    241459
    242                 pee = pee + '\n\n';
    243                 pee = pee.replace( /<br \/>\s*<br \/>/gi, '\n\n' );
    244                 pee = pee.replace( new RegExp( '(<(?:' + blocklist + ')(?: [^>]*)?>)', 'gi' ), '\n$1' );
    245                 pee = pee.replace( new RegExp( '(</(?:' + blocklist + ')>)', 'gi' ), '$1\n\n' );
    246                 pee = pee.replace( /<hr( [^>]*)?>/gi, '<hr$1>\n\n' ); // hr is self closing block element
    247                 pee = pee.replace( /\r\n|\r/g, '\n' );
    248                 pee = pee.replace( /\n\s*\n+/g, '\n\n' );
    249                 pee = pee.replace( /([\s\S]+?)\n\n/g, '<p>$1</p>\n' );
    250                 pee = pee.replace( /<p>\s*?<\/p>/gi, '');
    251                 pee = pee.replace( new RegExp( '<p>\\s*(</?(?:' + blocklist + ')(?: [^>]*)?>)\\s*</p>', 'gi' ), '$1' );
    252                 pee = pee.replace( /<p>(<li.+?)<\/p>/gi, '$1');
    253                 pee = pee.replace( /<p>\s*<blockquote([^>]*)>/gi, '<blockquote$1><p>');
    254                 pee = pee.replace( /<\/blockquote>\s*<\/p>/gi, '</p></blockquote>');
    255                 pee = pee.replace( new RegExp( '<p>\\s*(</?(?:' + blocklist + ')(?: [^>]*)?>)', 'gi' ), '$1' );
    256                 pee = pee.replace( new RegExp( '(</?(?:' + blocklist + ')(?: [^>]*)?>)\\s*</p>', 'gi' ), '$1' );
    257                 pee = pee.replace( /\s*\n/gi, '<br />\n');
    258                 pee = pee.replace( new RegExp( '(</?(?:' + blocklist + ')[^>]*>)\\s*<br />', 'gi' ), '$1' );
    259                 pee = pee.replace( /<br \/>(\s*<\/?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)/gi, '$1' );
    260                 pee = pee.replace( /(?:<p>|<br ?\/?>)*\s*\[caption([^\[]+)\[\/caption\]\s*(?:<\/p>|<br ?\/?>)*/gi, '[caption$1[/caption]' );
    261 
    262                 pee = pee.replace( /(<(?:div|th|td|form|fieldset|dd)[^>]*>)(.*?)<\/p>/g, function( a, b, c ) {
    263                         if ( c.match( /<p( [^>]*)?>/ ) ) {
    264                                 return a;
    265                         }
    266 
    267                         return b + '<p>' + c + '</p>';
    268                 });
    269 
    270                 // put back the line breaks in pre|script
    271                 if ( preserve_linebreaks ) {
    272                         pee = pee.replace( /<wp-line-break>/g, '\n' );
    273                 }
     460                                if ( cursorTop < editorTop || cursorBottom > editorBottom ) {
     461                                        window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset - windowHeight / 2 );
     462                                }
     463                        } );
    274464
    275                 if ( preserve_br ) {
    276                         pee = pee.replace( /<wp-temp-br([^>]*)>/g, '<br$1>' );
    277                 }
     465                        editor.wp = editor.wp || {};
    278466
    279                 return pee;
    280         },
     467                        editor.wp.getCursorOffset = function() {
     468                                var selection = editor.selection,
     469                                        node = selection.getNode(),
     470                                        range = selection.getRng(),
     471                                        view, clone, right, offset;
    281472
    282         pre_wpautop: function( content ) {
    283                 var t = this, o = { o: t, data: content, unfiltered: content },
    284                         q = typeof( jQuery ) !== 'undefined';
     473                                if ( tinymce.Env.ie && tinymce.Env.ie < 9 ) {
     474                                        return;
     475                                }
    285476
    286                 if ( q ) {
    287                         jQuery( 'body' ).trigger( 'beforePreWpautop', [ o ] );
    288                 }
     477                                if ( view = editor.wp.getView( node ) ) {
     478                                        offset = view.getBoundingClientRect();
     479                                } else if ( selection.isCollapsed() ) {
     480                                        clone = range.cloneRange();
     481
     482                                        if ( clone.startContainer.length > 1 ) {
     483                                                if ( clone.startContainer.length > clone.endOffset ) {
     484                                                        clone.setEnd( clone.startContainer, clone.endOffset + 1 );
     485                                                        right = true;
     486                                                } else {
     487                                                        clone.setStart( clone.startContainer, clone.endOffset - 1 );
     488                                                }
    289489
    290                 o.data = t._wp_Nop( o.data );
     490                                                selection.setRng( clone );
     491                                                offset = selection.getRng().getBoundingClientRect();
     492                                                selection.setRng( range );
     493                                        } else {
     494                                                offset = node.getBoundingClientRect();
     495                                        }
     496                                } else {
     497                                        offset = range.getBoundingClientRect();
     498                                }
    291499
    292                 if ( q ) {
    293                         jQuery('body').trigger('afterPreWpautop', [ o ] );
    294                 }
     500                                if ( ! offset.height ) {
     501                                        return false;
     502                                }
    295503
    296                 return o.data;
    297         },
     504                                return offset;
     505                        };
    298506
    299         wpautop: function( pee ) {
    300                 var t = this, o = { o: t, data: pee, unfiltered: pee },
    301                         q = typeof( jQuery ) !== 'undefined';
     507                        editor.on( 'hide', function() {
     508                                textEditorResize();
     509                                adjust( 'resize' );
     510                        } );
     511
     512                        // Adjust when the editor resizes.
     513                        editor.on( 'nodechange setcontent keyup FullscreenStateChanged', function() {
     514                                adjust( 'resize' );
     515                        } );
     516
     517                        // And adjust "immediately".
     518                        // Allow some time to load CSS etc.
     519                        setTimeout( function() {
     520                                adjust( 'resize' );
     521                        }, 500 );
     522                } );
     523
     524                // Adjust when the window is scrolled or resized.
     525                $window.on( 'scroll resize', function( event ) {
     526                        adjust( event.type );
     527                } );
     528
     529                // Adjust when exiting fullscreen mode.
     530                fullscreen.pubsub.subscribe( 'hidden', function() {
     531                        adjust( 'resize' );
     532                } );
     533
     534                // Adjust when collapsing the menu.
     535                $( wp ).on( 'menu:collapse.editor-scroll', function() {
     536                        adjust( 'resize' );
     537                } )
     538
     539                // Adjust when changing the columns.
     540                .on( 'postboxes:columnchange.editor-scroll', function() {
     541                        adjust( 'resize' );
     542                } )
     543
     544                // Adjust when changing the body class.
     545                .on( 'editor:classchange.editor-scroll', function() {
     546                        adjust( 'resize' );
     547                } );
     548
     549                // Adjust the toolbars based on the active editor mode.
     550                adjust = wp.editor.adjustToolbarPosition = function( eventType ) {
     551                        // Make sure we're not in fullscreen mode.
     552                        if ( fullscreen.settings.visible ) {
     553                                return;
     554                        }
    302555
    303                 if ( q ) {
    304                         jQuery( 'body' ).trigger('beforeWpautop', [ o ] );
    305                 }
     556                        var adminBarHeight = $adminBar.height(),
     557                                bottomHeight = $bottom.outerHeight(),
     558                                windowPos = $window.scrollTop(),
     559                                windowHeight = $window.height(),
     560                                windowWidth = $window.width(),
     561                                $top, $editor, visual,
     562                                toolsHeight, topPos, topHeight, editorPos, editorHeight, editorWidth, statusBarHeight;
     563
     564                        // Visual editor.
     565                        if ( editorInstance && ! editorInstance.isHidden() ) {
     566                                $top = $visualTop;
     567                                $editor = $visualEditor;
     568                                visual = true;
     569
     570                                // Doesn't hide the panel of 'styleselect'. :(
     571                                tinymce.each( editorInstance.controlManager.buttons, function( button ) {
     572                                        if ( button._active && ( button.type === 'colorbutton' || button.type === 'panelbutton' || button.type === 'menubutton' ) ) {
     573                                                button.hidePanel();
     574                                        }
     575                                } );
     576                        // Text editor.
     577                        } else {
     578                                $top = $textTop;
     579                                $editor = $textEditor;
     580                        }
    306581
    307                 o.data = t._wp_Autop( o.data );
     582                        toolsHeight = $tools.outerHeight();
     583                        topPos = $top.parent().offset().top;
     584                        topHeight = $top.outerHeight();
     585                        editorPos = $editor.offset().top;
     586                        editorHeight = $editor.outerHeight();
     587                        editorWidth = $editor.outerWidth();
     588                        statusBarHeight = visual ? $statusBar.outerHeight() : 0;
     589
     590                        // Maybe pin the top.
     591                        if ( ( ! fixedTop || eventType === 'resize' ) &&
     592                                        // Handle scrolling down.
     593                                        ( windowPos >= ( topPos - toolsHeight - adminBarHeight ) &&
     594                                        // Handle scrolling up.
     595                                        windowPos <= ( topPos - toolsHeight - adminBarHeight + editorHeight - 100 ) ) ) {
     596                                fixedTop = true;
     597
     598                                $top.css( {
     599                                        position: 'fixed',
     600                                        top: ( windowWidth > 600 ? adminBarHeight : 0 ) + toolsHeight,
     601                                        width: editorWidth - ( visual ? 0 : 38 ),
     602                                        borderTop: '1px solid #e5e5e5'
     603                                } );
     604
     605                                $tools.css( {
     606                                        position: 'fixed',
     607                                        top: ( windowWidth > 600 ? adminBarHeight : 0 ),
     608                                        width: editorWidth + 2
     609                                } );
     610
     611                                if ( visual ) {
     612                                        $editor.css( {
     613                                                paddingTop: topHeight + toolsHeight
     614                                        } );
     615                                } else {
     616                                        $top.parent().css( {
     617                                                paddingTop: topHeight + toolsHeight
     618                                        } );
     619                                }
     620                        // Maybe unpin the top.
     621                        } else if ( fixedTop &&
     622                                        // Handle scrolling up.
     623                                        ( windowPos <= ( topPos - adminBarHeight ) ||
     624                                        // Handle scrolling down.
     625                                        // The topHeight is added to the editorHeight (padding), so we'll have to subtract it again.
     626                                        windowPos >= ( topPos - adminBarHeight + editorHeight - ( visual ? topHeight + toolsHeight : 0 ) - 100 ) ) ) {
     627                                fixedTop = false;
     628
     629                                $top.add( $tools ).css( {
     630                                        position: 'relative',
     631                                        top: 'auto',
     632                                        width: 'auto',
     633                                        borderTop: 'none'
     634                                } );
     635
     636                                if ( visual ) {
     637                                        $editor.css( {
     638                                                paddingTop: 0
     639                                        } );
     640                                } else {
     641                                        $top.parent().css( {
     642                                                paddingTop: 0
     643                                        } );
     644                                }
     645                        }
    308646
    309                 if ( q ) {
    310                         jQuery( 'body' ).trigger('afterWpautop', [ o ] );
    311                 }
     647                        // Maybe adjust the bottom bar.
     648                        if ( ( ! fixedBottom || eventType === 'resize' ) &&
     649                                        // + 1 for the border around the .wp-editor-container.
     650                                        ( windowPos + windowHeight ) <= ( editorPos + editorHeight + bottomHeight + statusBarHeight + 1 ) ) {
     651                                fixedBottom = true;
     652                                $bottom.css( {
     653                                        position: 'fixed',
     654                                        bottom: 0,
     655                                        width: editorWidth + 2,
     656                                        borderTop: '1px solid #dedede'
     657                                } );
     658                        } else if ( fixedBottom &&
     659                                        ( windowPos + windowHeight ) > ( editorPos + editorHeight + bottomHeight + statusBarHeight - 1 ) ) {
     660                                fixedBottom = false;
     661                                $bottom.css( {
     662                                        position: 'relative',
     663                                        bottom: 'auto',
     664                                        width: '100%',
     665                                        borderTop: 'none'
     666                                } );
     667                        }
     668                };
    312669
    313                 return o.data;
    314         }
    315 };
     670                textEditorResize();
     671        } );
     672} )( jQuery );
  • src/wp-admin/js/post.js

     
    10001000
    10011001        wptitlehint();
    10021002
    1003         // Resize the visual and text editors
    1004         ( function() {
    1005                 var editor, offset, mce,
    1006                         $textarea = $('textarea#content'),
    1007                         $handle = $('#post-status-info');
    1008 
    1009                 // No point for touch devices
    1010                 if ( ! $textarea.length || 'ontouchstart' in window ) {
    1011                         return;
    1012                 }
    1013 
    1014                 function dragging( event ) {
    1015                         if ( mce ) {
    1016                                 editor.theme.resizeTo( null, offset + event.pageY );
    1017                         } else {
    1018                                 $textarea.height( Math.max( 50, offset + event.pageY ) );
    1019                         }
    1020 
    1021                         event.preventDefault();
    1022                 }
    1023 
    1024                 function endDrag() {
    1025                         var height, toolbarHeight;
    1026 
    1027                         if ( mce ) {
    1028                                 editor.focus();
    1029                                 toolbarHeight = parseInt( $( '#wp-content-editor-container .mce-toolbar-grp' ).height(), 10 );
    1030 
    1031                                 if ( toolbarHeight < 10 || toolbarHeight > 200 ) {
    1032                                         toolbarHeight = 30;
    1033                                 }
    1034 
    1035                                 height = parseInt( $('#content_ifr').css('height'), 10 ) + toolbarHeight - 28;
    1036                         } else {
    1037                                 $textarea.focus();
    1038                                 height = parseInt( $textarea.css('height'), 10 );
    1039                         }
    1040 
    1041                         $document.off( '.wp-editor-resize' );
    1042 
    1043                         // sanity check
    1044                         if ( height && height > 50 && height < 5000 ) {
    1045                                 setUserSetting( 'ed_size', height );
    1046                         }
    1047                 }
    1048 
    1049                 $textarea.css( 'resize', 'none' );
    1050 
    1051                 $handle.on( 'mousedown.wp-editor-resize', function( event ) {
    1052                         if ( typeof tinymce !== 'undefined' ) {
    1053                                 editor = tinymce.get('content');
    1054                         }
    1055 
    1056                         if ( editor && ! editor.isHidden() ) {
    1057                                 mce = true;
    1058                                 offset = $('#content_ifr').height() - event.pageY;
    1059                         } else {
    1060                                 mce = false;
    1061                                 offset = $textarea.height() - event.pageY;
    1062                                 $textarea.blur();
    1063                         }
    1064 
    1065                         $document.on( 'mousemove.wp-editor-resize', dragging )
    1066                                 .on( 'mouseup.wp-editor-resize mouseleave.wp-editor-resize', endDrag );
    1067 
    1068                         event.preventDefault();
    1069                 }).on( 'mouseup.wp-editor-resize', endDrag );
    1070         })();
    1071 
    10721003        if ( typeof tinymce !== 'undefined' ) {
    10731004                // When changing post formats, change the editor body class
    10741005                $( '#post-formats-select input.post-format' ).on( 'change.set-editor-class', function() {
    10751006                        var editor, body, format = this.id;
    10761007
    1077                         if ( format && $( this ).prop('checked') ) {
    1078                                 editor = tinymce.get( 'content' );
    1079 
    1080                                 if ( editor ) {
    1081                                         body = editor.getBody();
    1082                                         body.className = body.className.replace( /\bpost-format-[^ ]+/, '' );
    1083                                         editor.dom.addClass( body, format == 'post-format-0' ? 'post-format-standard' : format );
    1084                                 }
     1008                        if ( format && $( this ).prop( 'checked' ) && ( editor = tinymce.get( 'content' ) ) ) {
     1009                                body = editor.getBody();
     1010                                body.className = body.className.replace( /\bpost-format-[^ ]+/, '' );
     1011                                editor.dom.addClass( body, format == 'post-format-0' ? 'post-format-standard' : format );
     1012                                $( wp ).trigger( 'editor:classchange' );
    10851013                        }
    10861014                });
    10871015        }
  • src/wp-admin/js/postbox.js

     
    11/* global ajaxurl */
    22
    3 var postboxes;
    4 
    53(function($) {
    6         postboxes = {
     4        window.wp = wp || {};
     5
     6        wp.postboxes = window.postboxes = {
    77                add_postbox_toggles : function(page, args) {
    88                        var self = this;
    99
     
    2121                                        self.save_state(page);
    2222
    2323                                if ( id ) {
    24                                         if ( !p.hasClass('closed') && $.isFunction(postboxes.pbshow) )
     24                                        if ( !p.hasClass('closed') && $.isFunction( self.pbshow ) )
    2525                                                self.pbshow(id);
    26                                         else if ( p.hasClass('closed') && $.isFunction(postboxes.pbhide) )
     26                                        else if ( p.hasClass('closed') && $.isFunction( self.pbhide ) )
    2727                                                self.pbhide(id);
    2828                                }
    2929                        });
     
    4343
    4444                                if ( $(this).prop('checked') ) {
    4545                                        $('#' + box).show();
    46                                         if ( $.isFunction( postboxes.pbshow ) )
     46                                        if ( $.isFunction( self.pbshow ) )
    4747                                                self.pbshow( box );
    4848                                } else {
    4949                                        $('#' + box).hide();
    50                                         if ( $.isFunction( postboxes.pbhide ) )
     50                                        if ( $.isFunction( self.pbhide ) )
    5151                                                self.pbhide( box );
    5252                                }
    5353                                self.save_state(page);
     
    6565                },
    6666
    6767                init : function(page, args) {
    68                         var isMobile = $(document.body).hasClass('mobile');
     68                        var self = this,
     69                                isMobile = $(document.body).hasClass('mobile');
    6970
    7071                        $.extend( this, args || {} );
    7172                        $('#wpbody-content').css('overflow','hidden');
     
    8788                                                return;
    8889                                        }
    8990
    90                                         postboxes.save_order(page);
     91                                        self.save_order(page);
    9192                                },
    9293                                receive: function(e,ui) {
    9394                                        if ( 'dashboard_browser_nag' == ui.item[0].id )
    9495                                                $(ui.sender).sortable('cancel');
    9596
    96                                         postboxes._mark_area();
     97                                        self._mark_area();
    9798                                }
    9899                        });
    99100
    100101                        if ( isMobile ) {
    101                                 $(document.body).bind('orientationchange.postboxes', function(){ postboxes._pb_change(); });
     102                                $(document.body).bind('orientationchange.postboxes', function(){ self._pb_change(); });
    102103                                this._pb_change();
    103104                        }
    104105
     
    159160                        if ( el ) {
    160161                                el.className = el.className.replace(/columns-\d+/, 'columns-' + n);
    161162                        }
     163                       
     164                        $( wp ).trigger( 'postboxes:columnchange' );
    162165                },
    163166
    164167                _pb_change : function() {
  • src/wp-includes/class-wp-editor.php

     
    109109                if ( self::$this_quicktags )
    110110                        self::$has_quicktags = true;
    111111
    112                 if ( empty( $set['editor_height'] ) )
    113                         return $set;
    114 
    115                 if ( 'content' === $editor_id ) {
    116                         // A cookie (set when a user resizes the editor) overrides the height.
    117                         $cookie = (int) get_user_setting( 'ed_size' );
    118 
    119                         // Upgrade an old TinyMCE cookie if it is still around, and the new one isn't.
    120                         if ( ! $cookie && isset( $_COOKIE['TinyMCE_content_size'] ) ) {
    121                                 parse_str( $_COOKIE['TinyMCE_content_size'], $cookie );
    122                                 $cookie = $cookie['ch'];
    123                         }
    124 
    125                         if ( $cookie )
    126                                 $set['editor_height'] = $cookie;
    127                 }
    128 
    129                 if ( $set['editor_height'] < 50 )
    130                         $set['editor_height'] = 50;
    131                 elseif ( $set['editor_height'] > 5000 )
    132                         $set['editor_height'] = 5000;
    133 
    134112                return $set;
    135113        }
    136114
     
    153131                        self::$drag_drop_upload = true;
    154132                }
    155133
    156                 if ( ! empty( $set['editor_height'] ) )
    157                         $height = ' style="height: ' . $set['editor_height'] . 'px"';
    158                 else
    159                         $height = ' rows="' . $set['textarea_rows'] . '"';
    160 
    161134                if ( !current_user_can( 'upload_files' ) )
    162135                        $set['media_buttons'] = false;
    163136
     
    231204                 * @param string $output Editor's HTML markup.
    232205                 */
    233206                $the_editor = apply_filters( 'the_editor', '<div id="wp-' . $editor_id . '-editor-container" class="wp-editor-container">' .
    234                         '<textarea' . $editor_class . $height . $tabindex . $autocomplete . ' cols="40" name="' . $set['textarea_name'] . '" ' .
     207                        '<textarea' . $editor_class . $tabindex . $autocomplete . ' cols="40" name="' . $set['textarea_name'] . '" ' .
    235208                        'id="' . $editor_id . '">%s</textarea></div>' );
    236209
    237210                /**
     
    316289                                         * @param array  $plugins   An array of teenyMCE plugins.
    317290                                         * @param string $editor_id Unique editor identifier, e.g. 'content'.
    318291                                         */
    319                                         self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array( 'fullscreen', 'image', 'wordpress', 'wpeditimage', 'wplink' ), $editor_id );
     292                                        self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array( 'autoresize', 'fullscreen', 'image', 'wordpress', 'wpeditimage', 'wplink' ), $editor_id );
    320293                                } else {
    321294
    322295                                        /**
     
    339312                                        $mce_external_plugins = apply_filters( 'mce_external_plugins', array() );
    340313
    341314                                        $plugins = array(
     315                                                'autoresize',
    342316                                                'charmap',
    343317                                                'hr',
    344318                                                'media',
  • src/wp-includes/css/editor.css

     
    148148div.mce-toolbar-grp {
    149149        border-bottom: 1px solid #dedede;
    150150        background: #f5f5f5;
    151         padding: 3px;
     151        padding: 0;
    152152        position: relative;
     153        z-index: 999;
     154}
     155
     156div.mce-toolbar-grp > div {
     157        padding: 3px;
    153158}
    154159
    155160.has-dfw div.mce-toolbar-grp .mce-toolbar.mce-first {
     
    161166}
    162167
    163168div.mce-statusbar {
    164         border-top: 1px solid #eee;
     169        border-top: 1px solid #e5e5e5;
    165170}
    166171
    167172div.mce-path {
    168         padding: 0 8px 2px;
     173        padding: 2px 10px;
    169174        margin: 0;
    170175}
    171176
     177.mce-path,
     178.mce-path-item,
     179.mce-path .mce-divider {
     180        font-size: 12px;
     181        line-height: 18px;
     182}
     183
     184.mce-path-item:focus {
     185        background: none;
     186        color: inherit;
     187}
     188
    172189.mce-toolbar .mce-btn,
    173190.qt-fullscreen {
    174191        border-color: transparent;
     
    731748}
    732749
    733750.mce-i-wp_code:before {
    734         content: '\e017';
     751        content: '\f475';
    735752}
    736753
    737754/* Editors */
     
    740757}
    741758
    742759.wp-editor-tools {
     760        background-color: #f1f1f1;
     761        padding-top: 20px;
    743762        position: relative;
    744         z-index: 1;
     763        z-index: 1000;
     764}
     765
     766.wp-editor-tools:after {
     767        clear: both;
     768        content: '';
     769        display: table;
    745770}
    746771
    747772.wp-editor-container {
     
    763788        box-sizing: border-box;
    764789}
    765790
    766 .wp-editor-tools {
    767         padding: 0;
    768 }
    769 
    770791.wp-editor-container textarea.wp-editor-area {
    771792        width: 100%;
    772793        margin: 0;
  • src/wp-includes/js/tinymce/plugins/wpview/plugin.js

     
    99                TreeWalker = tinymce.dom.TreeWalker,
    1010                toRemove = false,
    1111                firstFocus = true,
    12                 cursorInterval, lastKeyDownNode, setViewCursorTries, focus;
     12                cursorInterval, lastKeyDownNode, setViewCursorTries, focus, getView;
    1313
    14         function getView( node ) {
     14        editor.wp = editor.wp || {};
     15
     16        editor.wp.getView = getView = function( node ) {
    1517                // Doing this directly is about 40% faster
    1618                while ( node && node.parentNode ) {
    17                         if ( node.className && (' ' + node.className + ' ').indexOf(' wpview-wrap ') !== -1 ) {
     19                        if ( node.className && ( ' ' + node.className + ' ' ).indexOf( ' wpview-wrap ' ) !== -1 ) {
    1820                                return node;
    1921                        }
    2022
     
    2224                }
    2325
    2426                return false;
    25         }
     27        };
    2628
    2729        /**
    2830         * Get the text/shortcode string for a view.
     
    508510                        } else {
    509511                                setViewCursor( true, view );
    510512                        }
    511                        
    512513                } else if ( keyCode === VK.RIGHT ) {
    513514                        setViewCursor( false, view );
    514515                } else if ( keyCode === VK.DOWN ) {
     
    564565
    565566        editor.on( 'focus', function() {
    566567                var view;
    567                
     568
    568569                focus = true;
    569570                editor.dom.addClass( editor.getBody(), 'has-focus' );
    570571