WordPress.org

Make WordPress Core

Ticket #28328: 28328.3.patch

File 28328.3.patch, 52.0 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

     
    1 /* global tinymce, tinyMCEPreInit, QTags, setUserSetting */
     1/* global tinymce, tinyMCEPreInit, QTags, setUserSetting, console */
    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                        adjust,
     340                        fullscreen = window.wp.editor.fullscreen,
     341                        editorInstance,
     342                        statusBarHeight = 0,
     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' );
    80 
    81                 } else if ( 'html' === mode ) {
    82 
    83                         if ( ed && ed.isHidden() ) {
    84                                 return false;
     370                        if ( start && end && start !== end ) {
     371                                return;
    85372                        }
    86373
    87                         if ( ed ) {
    88                                 if ( ! tinymce.Env.iOS ) {
    89                                         iframe = DOM.get( id + '_ifr' );
    90                                         editorHeight = iframe ? parseInt( iframe.style.height, 10 ) : 0;
     374                        range.setStart( textNode, start );
     375                        range.setEnd( textNode, end + 1 );
    91376
    92                                         if ( editorHeight ) {
    93                                                 toolbarHeight = getToolbarHeight();
    94                                                 editorHeight = editorHeight + toolbarHeight - 14;
     377                        offset = range.getBoundingClientRect();
    95378
    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                                 }
     379                        if ( ! offset.height ) {
     380                                return;
     381                        }
    102382
    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                                 }
     383                        cursorTop = offset.top;
     384                        cursorBottom = cursorTop + offset.height;
     385                        editorTop = $adminBar.outerHeight() + $textTop.outerHeight();
     386                        editorBottom = windowHeight - $bottom.outerHeight();
    109387
    110                                 DOM.setStyles( txtarea_el, {'display': '', 'visibility': ''} );
     388                        if ( cursorTop < editorTop || cursorBottom > editorBottom ) {
     389                                window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset - windowHeight / 2 );
    111390                        }
     391                } );
    112392
    113                         DOM.removeClass( wrap_id, 'tmce-active' );
    114                         DOM.addClass( wrap_id, 'html-active' );
    115                         setUserSetting( 'editor', 'html' );
    116                 }
    117                 return false;
    118         },
     393                function textEditorResize() {
     394                        if ( editorInstance && ! editorInstance.isHidden() ) {
     395                                return;
     396                        }
    119397
    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                 }
     398                        var hiddenHeight = $textEditorClone.width( $textEditor.width() ).text( $textEditor.val() + '&nbsp;' ).height(),
     399                                textEditorHeight = $textEditor.height();
    134400
    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                         });
    141                 }
     401                        if ( hiddenHeight === textEditorHeight ) {
     402                                return;
     403                        } else if ( hiddenHeight < 300 ) {
     404                                hiddenHeight = 300;
     405                        }
    142406
    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>' );
     407                        $textEditor.height( hiddenHeight );
    170408
    171                 if ( content.indexOf( '<hr' ) !== -1 ) {
    172                         content = content.replace( /\s*<hr( [^>]*)?>\s*/g, '\n\n<hr$1>\n\n' );
     409                        adjust( 'resize' );
    173410                }
    174411
    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                 }
     412                // We need to wait for TinyMCE to initialize.
     413                $document.on( 'tinymce-editor-init.editor-scroll', function( event, editor ) {
     414                        var $contentWrap;
    180415
    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                 }
     416                        // Make sure it's the main editor.
     417                        if ( editor.id !== 'content' ) {
     418                                return;
     419                        }
    193420
    194                 // and the <br> tags in captions
    195                 if ( preserve_br ) {
    196                         content = content.replace( /<wp-temp-br([^>]*)>/g, '<br$1>' );
    197                 }
     421                        // Copy the editor instance.
     422                        editorInstance = editor;
    198423
    199                 return content;
    200         },
     424                        // Resizing will be handled by the autoresize plugin.
     425                        editor.theme.resizeTo = function() {};
    201426
    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                 }
     427                        // Set the minimum height to the initial viewport height.
     428                        editor.settings.autoresize_min_height = 300;
    214429
    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                 }
     430                        // Get the necessary UI elements.
     431                        $contentWrap = $( '#wp-content-wrap' );
     432                        statusBarHeight = $contentWrap.find( '.mce-statusbar' ).filter( ':visible' ).outerHeight();
     433                        $visualTop = $contentWrap.find( '.mce-toolbar-grp' );
     434                        $visualEditor = $contentWrap.find( '.mce-edit-area' );
     435
     436                        // Adjust when switching editor modes.
     437                        editor.on( 'show', function() {
     438                                setTimeout( function() {
     439                                        editor.execCommand( 'mceAutoResize' );
     440                                        adjust( 'resize' );
     441                                }, 200 );
     442                        } );
     443
     444                        editor.on( 'keyup', function() {
     445                                var offset = editor.wp.getCursorOffset(),
     446                                        windowHeight = $window.height(),
     447                                        cursorTop, cursorBottom, editorTop, editorBottom;
    226448
    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                 }
     449                                if ( ! offset ) {
     450                                        return;
     451                                }
    241452
    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                 }
     453                                cursorTop = offset.top + editor.getContentAreaContainer().getElementsByTagName( 'iframe' )[0].getBoundingClientRect().top;
     454                                cursorBottom = cursorTop + offset.height;
     455                                editorTop = $adminBar.outerHeight() + $tools.outerHeight() + $visualTop.outerHeight();
     456                                editorBottom = $window.height() - $bottom.outerHeight();
    274457
    275                 if ( preserve_br ) {
    276                         pee = pee.replace( /<wp-temp-br([^>]*)>/g, '<br$1>' );
    277                 }
     458                                if ( cursorTop < editorTop || cursorBottom > editorBottom ) {
     459                                        window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset - windowHeight / 2 );
     460                                }
     461                        } );
    278462
    279                 return pee;
    280         },
     463                        editor.wp = editor.wp || {};
    281464
    282         pre_wpautop: function( content ) {
    283                 var t = this, o = { o: t, data: content, unfiltered: content },
    284                         q = typeof( jQuery ) !== 'undefined';
     465                        editor.wp.getCursorOffset = function() {
     466                                var selection = editor.selection,
     467                                        node = selection.getNode(),
     468                                        range = selection.getRng(),
     469                                        view, clone, right, offset;
    285470
    286                 if ( q ) {
    287                         jQuery( 'body' ).trigger( 'beforePreWpautop', [ o ] );
    288                 }
     471                                if ( tinymce.Env.ie && tinymce.Env.ie < 9 ) {
     472                                        return;
     473                                }
    289474
    290                 o.data = t._wp_Nop( o.data );
     475                                if ( view = editor.wp.isView( node ) ) {
     476                                        offset = view.getBoundingClientRect();
     477                                } else if ( selection.isCollapsed() ) {
     478                                        clone = range.cloneRange();
     479
     480                                        if ( clone.startContainer.length > 1 ) {
     481                                                if ( clone.startContainer.length > clone.endOffset ) {
     482                                                        try {
     483                                                                clone.setEnd( clone.startContainer, clone.endOffset + 1 );
     484                                                                right = true;
     485                                                        } catch ( e ) {
     486                                                                console.log( e );
     487                                                        }
     488                                                } else {
     489                                                        try {
     490                                                                clone.setStart( clone.startContainer, clone.endOffset - 1 );
     491                                                        } catch ( e ) {
     492                                                                console.log( e );
     493                                                        }
     494                                                }
    291495
    292                 if ( q ) {
    293                         jQuery('body').trigger('afterPreWpautop', [ o ] );
    294                 }
     496                                                selection.setRng( clone );
     497                                                offset = selection.getRng().getBoundingClientRect();
     498                                                selection.setRng( range );
     499                                        } else {
     500                                                offset = node.getBoundingClientRect();
     501                                        }
     502                                } else {
     503                                        offset = range.getBoundingClientRect();
     504                                }
    295505
    296                 return o.data;
    297         },
     506                                if ( ! offset.height ) {
     507                                        return false;
     508                                }
    298509
    299         wpautop: function( pee ) {
    300                 var t = this, o = { o: t, data: pee, unfiltered: pee },
    301                         q = typeof( jQuery ) !== 'undefined';
     510                                return offset;
     511                        };
    302512
    303                 if ( q ) {
    304                         jQuery( 'body' ).trigger('beforeWpautop', [ o ] );
    305                 }
     513                        editor.wp.isView = function( node ) {
     514                                return editor.dom.getParent( node, function( node ) {
     515                                        return editor.dom.hasClass( node, 'wpview-wrap' );
     516                                } );
     517                        };
     518
     519                        editor.on( 'hide', function() {
     520                                textEditorResize();
     521                                adjust( 'resize' );
     522                        } );
     523
     524                        // Adjust when the editor resizes.
     525                        editor.on( 'nodechange setcontent keyup FullscreenStateChanged', function() {
     526                                adjust( 'resize' );
     527                        } );
     528
     529                        // And adjust "immediately".
     530                        // Allow some time to load CSS etc.
     531                        setTimeout( function() {
     532                                adjust( 'resize' );
     533                        }, 500 );
     534                } );
     535
     536                // Adjust when the window is scrolled or resized.
     537                $window.on( 'scroll resize', function( event ) {
     538                        adjust( event.type );
     539                } );
     540
     541                // Adjust when exiting fullscreen mode.
     542                fullscreen.pubsub.subscribe( 'hidden', function() {
     543                        adjust( 'resize' );
     544                } );
     545
     546                // Adjust when collapsing the menu.
     547                $( wp ).on( 'menu:collapse.editor-scroll', function() {
     548                        adjust( 'resize' );
     549                } )
     550
     551                // Adjust when changing the columns.
     552                .on( 'postboxes:columnchange.editor-scroll', function() {
     553                        adjust( 'resize' );
     554                } )
     555
     556                // Adjust when changing the body class.
     557                .on( 'editor:classchange.editor-scroll', function() {
     558                        adjust( 'resize' );
     559                } );
     560
     561                // Adjust the toolbars based on the active editor mode.
     562                adjust = wp.editor.adjustToolbarPosition = function( eventType ) {
     563                        // Make sure we're not in fullscreen mode.
     564                        if ( fullscreen.settings.visible ) {
     565                                return;
     566                        }
    306567
    307                 o.data = t._wp_Autop( o.data );
     568                        var adminBarHeight = $adminBar.height(),
     569                                bottomHeight = $bottom.outerHeight(),
     570                                windowPos = $window.scrollTop(),
     571                                windowHeight = $window.height(),
     572                                windowWidth = $window.width(),
     573                                $top, $editor, visual,
     574                                toolsHeight, topPos, topHeight, editorPos, editorHeight, editorWidth;
     575
     576                        // Visual editor.
     577                        if ( editorInstance && ! editorInstance.isHidden() ) {
     578                                $top = $visualTop;
     579                                $editor = $visualEditor;
     580                                visual = true;
     581
     582                                // Not sure if this is a bit too intensive. Doesn't hide the panel of 'styleselect'.
     583                                tinymce.each( editorInstance.controlManager.buttons, function( button ) {
     584                                        if ( button._active && ( button.type === 'colorbutton' || button.type === 'panelbutton' || button.type === 'menubutton' ) ) {
     585                                                button.hidePanel();
     586                                        }
     587                                } );
     588                        // Text editor.
     589                        } else {
     590                                $top = $textTop;
     591                                $editor = $textEditor;
     592                        }
    308593
    309                 if ( q ) {
    310                         jQuery( 'body' ).trigger('afterWpautop', [ o ] );
    311                 }
     594                        toolsHeight = $tools.outerHeight();
     595                        topPos = $top.parent().offset().top;
     596                        topHeight = $top.outerHeight();
     597                        editorPos = $editor.offset().top;
     598                        editorHeight = $editor.outerHeight();
     599                        editorWidth = $editor.outerWidth();
     600
     601                        // Maybe pin the top.
     602                        if ( ( ! fixedTop || eventType === 'resize' ) &&
     603                                        // Handle scrolling down.
     604                                        ( windowPos >= ( topPos - toolsHeight - adminBarHeight ) &&
     605                                        // Handle scrolling up.
     606                                        windowPos <= ( topPos - toolsHeight - adminBarHeight + editorHeight - 100 ) ) ) {
     607                                fixedTop = true;
     608
     609                                $top.css( {
     610                                        position: 'fixed',
     611                                        top: ( windowWidth > 600 ? adminBarHeight : 0 ) + toolsHeight,
     612                                        width: editorWidth - ( visual ? 0 : 38 ),
     613                                        borderTop: '1px solid #e5e5e5'
     614                                } );
     615
     616                                $tools.css( {
     617                                        position: 'fixed',
     618                                        top: ( windowWidth > 600 ? adminBarHeight : 0 ),
     619                                        width: editorWidth + 2
     620                                } );
     621
     622                                if ( visual ) {
     623                                        $editor.css( {
     624                                                paddingTop: topHeight + toolsHeight
     625                                        } );
     626                                } else {
     627                                        $top.parent().css( {
     628                                                paddingTop: topHeight + toolsHeight
     629                                        } );
     630                                }
     631                        // Maybe unpin the top.
     632                        } else if ( fixedTop &&
     633                                        // Handle scrolling up.
     634                                        ( windowPos <= ( topPos - adminBarHeight ) ||
     635                                        // Handle scrolling down.
     636                                        // The topHeight is added to the editorHeight (padding), so we'll have to subtract it again.
     637                                        windowPos >= ( topPos - adminBarHeight + editorHeight - ( visual ? topHeight + toolsHeight : 0 ) - 100 ) ) ) {
     638                                fixedTop = false;
     639
     640                                $top.add( $tools ).css( {
     641                                        position: 'relative',
     642                                        top: 'auto',
     643                                        width: 'auto',
     644                                        borderTop: 'none'
     645                                } );
     646
     647                                if ( visual ) {
     648                                        $editor.css( {
     649                                                paddingTop: 0
     650                                        } );
     651                                } else {
     652                                        $top.parent().css( {
     653                                                paddingTop: 0
     654                                        } );
     655                                }
     656                        }
     657
     658                        // Maybe adjust the bottom bar.
     659                        if ( ( ! fixedBottom || eventType === 'resize' ) &&
     660                                        // + 1 for the border around the .wp-editor-container.
     661                                        ( windowPos + windowHeight ) <= ( editorPos + editorHeight + bottomHeight + statusBarHeight + 1 ) ) {
     662                                fixedBottom = true;
     663                                $bottom.css( {
     664                                        position: 'fixed',
     665                                        bottom: 0,
     666                                        width: editorWidth + 2,
     667                                        borderTop: '1px solid #dedede'
     668                                } );
     669                        } else if ( fixedBottom &&
     670                                        ( windowPos + windowHeight ) > ( editorPos + editorHeight + bottomHeight + statusBarHeight - 1 ) ) {
     671                                fixedBottom = false;
     672                                $bottom.css( {
     673                                        position: 'relative',
     674                                        bottom: 'auto',
     675                                        width: '100%',
     676                                        borderTop: 'none'
     677                                } );
     678                        }
     679                };
    312680
    313                 return o.data;
    314         }
    315 };
     681                textEditorResize();
     682        } );
     683} )( 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/autoresize/plugin.js

     
     1/**
     2 * plugin.js
     3 *
     4 * Copyright, Moxiecode Systems AB
     5 * Released under LGPL License.
     6 *
     7 * License: http://www.tinymce.com/license
     8 * Contributing: http://www.tinymce.com/contributing
     9 */
     10
     11/*global tinymce:true */
     12/*eslint no-nested-ternary:0 */
     13
     14/**
     15 * Auto Resize
     16 *
     17 * This plugin automatically resizes the content area to fit its content height.
     18 * It will retain a minimum height, which is the height of the content area when
     19 * it's initialized.
     20 */
     21tinymce.PluginManager.add('autoresize', function(editor) {
     22        var settings = editor.settings, oldSize = 0;
     23
     24        function isFullscreen() {
     25                return editor.plugins.fullscreen && editor.plugins.fullscreen.isFullscreen();
     26        }
     27
     28        if (editor.settings.inline) {
     29                return;
     30        }
     31
     32        /**
     33         * This method gets executed each time the editor needs to resize.
     34         */
     35        function resize(e) {
     36                var deltaSize, doc, body, docElm, DOM = tinymce.DOM, resizeHeight, myHeight, marginTop, marginBottom;
     37
     38                doc = editor.getDoc();
     39                if (!doc) {
     40                        return;
     41                }
     42
     43                body = doc.body;
     44                docElm = doc.documentElement;
     45                resizeHeight = settings.autoresize_min_height;
     46
     47                if (!body || (e && e.type === "setcontent" && e.initial) || isFullscreen()) {
     48                        if (body && docElm) {
     49                                body.style.overflowY = "auto";
     50                                docElm.style.overflowY = "auto"; // Old IE
     51                        }
     52
     53                        return;
     54                }
     55
     56                // Calculate outer height of the body element using CSS styles
     57                marginTop = editor.dom.getStyle(body, 'margin-top', true);
     58                marginBottom = editor.dom.getStyle(body, 'margin-bottom', true);
     59                myHeight = body.offsetHeight + parseInt(marginTop, 10) + parseInt(marginBottom, 10);
     60
     61                // Make sure we have a valid height
     62                if (isNaN(myHeight) || myHeight <= 0) {
     63                        // Get height differently depending on the browser used
     64                        myHeight = tinymce.Env.ie ? body.scrollHeight : (tinymce.Env.webkit && body.clientHeight === 0 ? 0 : body.offsetHeight);
     65                }
     66
     67                // Don't make it smaller than the minimum height
     68                if (myHeight > settings.autoresize_min_height) {
     69                        resizeHeight = myHeight;
     70                }
     71
     72                // If a maximum height has been defined don't exceed this height
     73                if (settings.autoresize_max_height && myHeight > settings.autoresize_max_height) {
     74                        resizeHeight = settings.autoresize_max_height;
     75                        body.style.overflowY = "auto";
     76                        docElm.style.overflowY = "auto"; // Old IE
     77                } else {
     78                        body.style.overflowY = "hidden";
     79                        docElm.style.overflowY = "hidden"; // Old IE
     80                        body.scrollTop = 0;
     81                }
     82
     83                // Resize content element
     84                if (resizeHeight !== oldSize) {
     85                        deltaSize = resizeHeight - oldSize;
     86                        DOM.setStyle(DOM.get(editor.id + '_ifr'), 'height', resizeHeight + 'px');
     87                        oldSize = resizeHeight;
     88
     89                        // WebKit doesn't decrease the size of the body element until the iframe gets resized
     90                        // So we need to continue to resize the iframe down until the size gets fixed
     91                        if (tinymce.isWebKit && deltaSize < 0) {
     92                                resize(e);
     93                        }
     94                }
     95        }
     96
     97        /**
     98         * Calls the resize x times in 100ms intervals. We can't wait for load events since
     99         * the CSS files might load async.
     100         */
     101        function wait(times, interval, callback) {
     102                setTimeout(function() {
     103                        resize({});
     104
     105                        if (times--) {
     106                                wait(times, interval, callback);
     107                        } else if (callback) {
     108                                callback();
     109                        }
     110                }, interval);
     111        }
     112
     113        // Define minimum height
     114        settings.autoresize_min_height = parseInt(editor.getParam('autoresize_min_height', editor.getElement().offsetHeight), 10);
     115
     116        // Define maximum height
     117        settings.autoresize_max_height = parseInt(editor.getParam('autoresize_max_height', 0), 10);
     118
     119        // Add padding at the bottom for better UX
     120        editor.on("init", function() {
     121                var overflowPadding = editor.getParam('autoresize_overflow_padding', 1);
     122
     123                editor.dom.setStyles(editor.getBody(), {
     124                        paddingBottom: editor.getParam('autoresize_bottom_margin', 50),
     125                        paddingLeft: overflowPadding,
     126                        paddingRight: overflowPadding
     127                });
     128        });
     129
     130        // Add appropriate listeners for resizing content area
     131        editor.on("nodechange setcontent keyup FullscreenStateChanged", resize);
     132
     133        if (editor.getParam('autoresize_on_init', true)) {
     134                editor.on('init', function() {
     135                        // Hit it 20 times in 100 ms intervals
     136                        wait(20, 100, function() {
     137                                // Hit it 5 times in 1 sec intervals
     138                                wait(5, 1000);
     139                        });
     140                });
     141        }
     142
     143        // Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample');
     144        editor.addCommand('mceAutoResize', resize);
     145});
  • src/wp-includes/js/tinymce/plugins/autoresize/plugin.min.js

    Property changes on: src/wp-includes/js/tinymce/plugins/autoresize/plugin.js
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
     1tinymce.PluginManager.add("autoresize",function(e){function t(){return e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen()}function i(n){var s,r,g,u,l,m,h,d,f=tinymce.DOM;if(r=e.getDoc()){if(g=r.body,u=r.documentElement,l=o.autoresize_min_height,!g||n&&"setcontent"===n.type&&n.initial||t())return void(g&&u&&(g.style.overflowY="auto",u.style.overflowY="auto"));h=e.dom.getStyle(g,"margin-top",!0),d=e.dom.getStyle(g,"margin-bottom",!0),m=g.offsetHeight+parseInt(h,10)+parseInt(d,10),(isNaN(m)||0>=m)&&(m=tinymce.Env.ie?g.scrollHeight:tinymce.Env.webkit&&0===g.clientHeight?0:g.offsetHeight),m>o.autoresize_min_height&&(l=m),o.autoresize_max_height&&m>o.autoresize_max_height?(l=o.autoresize_max_height,g.style.overflowY="auto",u.style.overflowY="auto"):(g.style.overflowY="hidden",u.style.overflowY="hidden",g.scrollTop=0),l!==a&&(s=l-a,f.setStyle(f.get(e.id+"_ifr"),"height",l+"px"),a=l,tinymce.isWebKit&&0>s&&i(n))}}function n(e,t,o){setTimeout(function(){i({}),e--?n(e,t,o):o&&o()},t)}var o=e.settings,a=0;e.settings.inline||(o.autoresize_min_height=parseInt(e.getParam("autoresize_min_height",e.getElement().offsetHeight),10),o.autoresize_max_height=parseInt(e.getParam("autoresize_max_height",0),10),e.on("init",function(){var t=e.getParam("autoresize_overflow_padding",1);e.dom.setStyles(e.getBody(),{paddingBottom:e.getParam("autoresize_bottom_margin",50),paddingLeft:t,paddingRight:t})}),e.on("nodechange setcontent keyup FullscreenStateChanged",i),e.getParam("autoresize_on_init",!0)&&e.on("init",function(){n(20,100,function(){n(5,1e3)})}),e.addCommand("mceAutoResize",i))});
     2 No newline at end of file
  • src/wp-includes/js/tinymce/skins/wordpress/wp-content.css

    Property changes on: src/wp-includes/js/tinymce/plugins/autoresize/plugin.min.js
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
    11/* Additional default styles for the editor */
    22
     3html {
     4        margin: 0 40px;
     5}
     6
    37html.ios {
    48        height: 100%;
    59}
     
    1418        font-size: 13px;
    1519        line-height: 19px;
    1620        color: #333;
    17         margin: 10px;
     21        margin: 9px auto;
     22        max-width: 100%;
     23        overflow: visible !important;
     24        /* The padding ensures margins of the children are contained in the body. */
     25        padding-top: 1px !important;
     26        padding-bottom: 1px !important;
     27        padding-left: 0 !important;
     28        padding-right: 0 !important;
    1829}
    1930
    2031/* When font-weight is different than the default browser style,
     
    100111        margin: 8px;
    101112}
    102113
     114img {
     115        height: auto;
     116        max-width: 100%;
     117}
     118
    103119/* Remove blue highlighting of selected images in WebKit */
    104120img::selection {
    105121        background-color: transparent;