Make WordPress Core

Ticket #29806: 29806.patch

File 29806.patch, 70.0 KB (added by iseulde, 10 years ago)
  • src/wp-admin/js/editor-expand.js

     
    1 /* global tinymce */
     1( function( window, $, undefined ) {
     2        'use strict';
    23
    3 window.wp = window.wp || {};
    4 
    5 jQuery( document ).ready( function( $ ) {
    64        var $window = $( window ),
    75                $document = $( document ),
    86                $adminBar = $( '#wpadminbar' ),
    9                 $footer = $( '#wpfooter' ),
    10                 $wrap = $( '#postdivrich' ),
    11                 $contentWrap = $( '#wp-content-wrap' ),
    12                 $tools = $( '#wp-content-editor-tools' ),
    13                 $visualTop = $(),
    14                 $visualEditor = $(),
    15                 $textTop = $( '#ed_toolbar' ),
    16                 $textEditor = $( '#content' ),
    17                 $textEditorClone = $( '<div id="content-textarea-clone"></div>' ),
    18                 $bottom = $( '#post-status-info' ),
    19                 $menuBar = $(),
    20                 $statusBar = $(),
    21                 $sideSortables = $( '#side-sortables' ),
    22                 $postboxContainer = $( '#postbox-container-1' ),
    23                 $postBody = $('#post-body'),
    24                 fullscreen = window.wp.editor && window.wp.editor.fullscreen,
    25                 mceEditor,
    26                 mceBind = function(){},
    27                 mceUnbind = function(){},
    28                 fixedTop = false,
    29                 fixedBottom = false,
    30                 fixedSideTop = false,
    31                 fixedSideBottom = false,
    32                 scrollTimer,
    33                 lastScrollPosition = 0,
    34                 pageYOffsetAtTop = 130,
    35                 pinnedToolsTop = 56,
    36                 sidebarBottom = 20,
    37                 autoresizeMinHeight = 300,
    38                 initialMode = window.getUserSetting( 'editor' ),
    39                 // These are corrected when adjust() runs, except on scrolling if already set.
    40                 heights = {
    41                         windowHeight: 0,
    42                         windowWidth: 0,
    43                         adminBarHeight: 0,
    44                         toolsHeight: 0,
    45                         menuBarHeight: 0,
    46                         visualTopHeight: 0,
    47                         textTopHeight: 0,
    48                         bottomHeight: 0,
    49                         statusBarHeight: 0,
    50                         sideSortablesHeight: 0
    51                 };
    52 
    53         $textEditorClone.insertAfter( $textEditor );
    54 
    55         $textEditorClone.css( {
    56                 'font-family': $textEditor.css( 'font-family' ),
    57                 'font-size': $textEditor.css( 'font-size' ),
    58                 'line-height': $textEditor.css( 'line-height' ),
    59                 'white-space': 'pre-wrap',
    60                 'word-wrap': 'break-word'
    61         } );
    62 
    63         function getHeights() {
    64                 var windowWidth = $window.width();
    65 
    66                 heights = {
    67                         windowHeight: $window.height(),
    68                         windowWidth: windowWidth,
    69                         adminBarHeight: ( windowWidth > 600 ? $adminBar.outerHeight() : 0 ),
    70                         toolsHeight: $tools.outerHeight() || 0,
    71                         menuBarHeight: $menuBar.outerHeight() || 0,
    72                         visualTopHeight: $visualTop.outerHeight() || 0,
    73                         textTopHeight: $textTop.outerHeight() || 0,
    74                         bottomHeight: $bottom.outerHeight() || 0,
    75                         statusBarHeight: $statusBar.outerHeight() || 0,
    76                         sideSortablesHeight: $sideSortables.height() || 0
    77                 };
    78 
    79                 // Adjust for hidden
    80                 if ( heights.menuBarHeight < 3 ) {
    81                         heights.menuBarHeight = 0;
    82                 }
    83         }
    84 
    85         function textEditorKeyup( event ) {
    86                 var VK = jQuery.ui.keyCode,
    87                         key = event.keyCode,
    88                         range = document.createRange(),
    89                         selStart = $textEditor[0].selectionStart,
    90                         selEnd = $textEditor[0].selectionEnd,
    91                         textNode = $textEditorClone[0].firstChild,
    92                         buffer = 10,
    93                         offset, cursorTop, cursorBottom, editorTop, editorBottom;
     7                $footer = $( '#wpfooter' );
    948
    95                 if ( selStart && selEnd && selStart !== selEnd ) {
    96                         return;
    97                 }
    98 
    99                 // These are not TinyMCE ranges.
    100                 try {
    101                         range.setStart( textNode, selStart );
    102                         range.setEnd( textNode, selEnd + 1 );
    103                 } catch ( ex ) {}
    104 
    105                 offset = range.getBoundingClientRect();
    106 
    107                 if ( ! offset.height ) {
    108                         return;
    109                 }
    110 
    111                 cursorTop = offset.top - buffer;
    112                 cursorBottom = cursorTop + offset.height + buffer;
    113                 editorTop = heights.adminBarHeight + heights.toolsHeight + heights.textTopHeight;
    114                 editorBottom = heights.windowHeight - heights.bottomHeight;
     9        /* Autoresize editor. */
     10        $( function() {
     11                var $wrap = $( '#postdivrich' ),
     12                        $contentWrap = $( '#wp-content-wrap' ),
     13                        $tools = $( '#wp-content-editor-tools' ),
     14                        $visualTop = $(),
     15                        $visualEditor = $(),
     16                        $textTop = $( '#ed_toolbar' ),
     17                        $textEditor = $( '#content' ),
     18                        $textEditorClone = $( '<div id="content-textarea-clone"></div>' ),
     19                        $bottom = $( '#post-status-info' ),
     20                        $menuBar = $(),
     21                        $statusBar = $(),
     22                        $sideSortables = $( '#side-sortables' ),
     23                        $postboxContainer = $( '#postbox-container-1' ),
     24                        $postBody = $('#post-body'),
     25                        fullscreen = window.wp.editor && window.wp.editor.fullscreen,
     26                        mceEditor,
     27                        mceBind = function(){},
     28                        mceUnbind = function(){},
     29                        fixedTop = false,
     30                        fixedBottom = false,
     31                        fixedSideTop = false,
     32                        fixedSideBottom = false,
     33                        scrollTimer,
     34                        lastScrollPosition = 0,
     35                        pageYOffsetAtTop = 130,
     36                        pinnedToolsTop = 56,
     37                        sidebarBottom = 20,
     38                        autoresizeMinHeight = 300,
     39                        initialMode = window.getUserSetting( 'editor' ),
     40                        advanced = !! parseInt( window.getUserSetting( 'hidetb' ), 10 ),
     41                        // These are corrected when adjust() runs, except on scrolling if already set.
     42                        heights = {
     43                                windowHeight: 0,
     44                                windowWidth: 0,
     45                                adminBarHeight: 0,
     46                                toolsHeight: 0,
     47                                menuBarHeight: 0,
     48                                visualTopHeight: 0,
     49                                textTopHeight: 0,
     50                                bottomHeight: 0,
     51                                statusBarHeight: 0,
     52                                sideSortablesHeight: 0
     53                        };
     54
     55                $textEditorClone.insertAfter( $textEditor );
     56
     57                $textEditorClone.css( {
     58                        'font-family': $textEditor.css( 'font-family' ),
     59                        'font-size': $textEditor.css( 'font-size' ),
     60                        'line-height': $textEditor.css( 'line-height' ),
     61                        'white-space': 'pre-wrap',
     62                        'word-wrap': 'break-word'
     63                } );
    11564
    116                 if ( cursorTop < editorTop && ( key === VK.UP || key === VK.LEFT || key === VK.BACKSPACE ) ) {
    117                         window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset - editorTop );
    118                 } else if ( cursorBottom > editorBottom ) {
    119                         window.scrollTo( window.pageXOffset, cursorBottom + window.pageYOffset - editorBottom );
    120                 }
    121         }
     65                function getHeights() {
     66                        var windowWidth = $window.width();
    12267
    123         function textEditorResize() {
    124                 if ( ( mceEditor && ! mceEditor.isHidden() ) || ( ! mceEditor && initialMode === 'tinymce' ) ) {
    125                         return;
     68                        heights = {
     69                                windowHeight: $window.height(),
     70                                windowWidth: windowWidth,
     71                                adminBarHeight: ( windowWidth > 600 ? $adminBar.outerHeight() : 0 ),
     72                                toolsHeight: $tools.outerHeight() || 0,
     73                                menuBarHeight: $menuBar.outerHeight() || 0,
     74                                visualTopHeight: $visualTop.outerHeight() || 0,
     75                                textTopHeight: $textTop.outerHeight() || 0,
     76                                bottomHeight: $bottom.outerHeight() || 0,
     77                                statusBarHeight: $statusBar.outerHeight() || 0,
     78                                sideSortablesHeight: $sideSortables.height() || 0
     79                        };
     80
     81                        // Adjust for hidden
     82                        if ( heights.menuBarHeight < 3 ) {
     83                                heights.menuBarHeight = 0;
     84                        }
    12685                }
    12786
    128                 var textEditorHeight = $textEditor.height(),
    129                         hiddenHeight;
    130 
    131                 $textEditorClone.width( $textEditor.width() - 22 );
    132                 $textEditorClone.text( $textEditor.val() + '&nbsp;' );
    133 
    134                 hiddenHeight = $textEditorClone.height();
     87                function textEditorKeyup( event ) {
     88                        var VK = jQuery.ui.keyCode,
     89                                key = event.keyCode,
     90                                range = document.createRange(),
     91                                selStart = $textEditor[0].selectionStart,
     92                                selEnd = $textEditor[0].selectionEnd,
     93                                textNode = $textEditorClone[0].firstChild,
     94                                buffer = 10,
     95                                offset, cursorTop, cursorBottom, editorTop, editorBottom;
    13596
    136                 if ( hiddenHeight < autoresizeMinHeight ) {
    137                         hiddenHeight = autoresizeMinHeight;
    138                 }
     97                        if ( selStart && selEnd && selStart !== selEnd ) {
     98                                return;
     99                        }
    139100
    140                 if ( hiddenHeight === textEditorHeight ) {
    141                         return;
    142                 }
     101                        // These are not TinyMCE ranges.
     102                        try {
     103                                range.setStart( textNode, selStart );
     104                                range.setEnd( textNode, selEnd + 1 );
     105                        } catch ( ex ) {}
    143106
    144                 $textEditor.height( hiddenHeight );
     107                        offset = range.getBoundingClientRect();
    145108
    146                 adjust();
    147         }
     109                        if ( ! offset.height ) {
     110                                return;
     111                        }
    148112
    149         // We need to wait for TinyMCE to initialize.
    150         $document.on( 'tinymce-editor-init.editor-expand', function( event, editor ) {
    151                 var hideFloatPanels = _.debounce( function() {
    152                         ! $( '.mce-floatpanel:hover' ).length && tinymce.ui.FloatPanel.hideAll();
    153                         $( '.mce-tooltip' ).hide();
    154                 }, 1000, true );
     113                        cursorTop = offset.top - buffer;
     114                        cursorBottom = cursorTop + offset.height + buffer;
     115                        editorTop = heights.adminBarHeight + heights.toolsHeight + heights.textTopHeight;
     116                        editorBottom = heights.windowHeight - heights.bottomHeight;
    155117
    156                 // Make sure it's the main editor.
    157                 if ( editor.id !== 'content' ) {
    158                         return;
     118                        if ( cursorTop < editorTop && ( key === VK.UP || key === VK.LEFT || key === VK.BACKSPACE ) ) {
     119                                window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset - editorTop );
     120                        } else if ( cursorBottom > editorBottom ) {
     121                                window.scrollTo( window.pageXOffset, cursorBottom + window.pageYOffset - editorBottom );
     122                        }
    159123                }
    160124
    161                 // Copy the editor instance.
    162                 mceEditor = editor;
    163 
    164                 // Set the minimum height to the initial viewport height.
    165                 editor.settings.autoresize_min_height = autoresizeMinHeight;
     125                function textEditorResize() {
     126                        if ( ( mceEditor && ! mceEditor.isHidden() ) || ( ! mceEditor && initialMode === 'tinymce' ) ) {
     127                                return;
     128                        }
    166129
    167                 // Get the necessary UI elements.
    168                 $visualTop = $contentWrap.find( '.mce-toolbar-grp' );
    169                 $visualEditor = $contentWrap.find( '.mce-edit-area' );
    170                 $statusBar = $contentWrap.find( '.mce-statusbar' );
    171                 $menuBar = $contentWrap.find( '.mce-menubar' );
     130                        var textEditorHeight = $textEditor.height(),
     131                                hiddenHeight;
    172132
    173                 function mceGetCursorOffset() {
    174                         var node = editor.selection.getNode(),
    175                                 range, view, offset;
     133                        $textEditorClone.width( $textEditor.width() - 22 );
     134                        $textEditorClone.text( $textEditor.val() + '&nbsp;' );
    176135
    177                         if ( editor.plugins.wpview && ( view = editor.plugins.wpview.getView( node ) ) ) {
    178                                 offset = view.getBoundingClientRect();
    179                         } else {
    180                                 range = editor.selection.getRng();
     136                        hiddenHeight = $textEditorClone.height();
    181137
    182                                 try {
    183                                         offset = range.getClientRects()[0];
    184                                 } catch( er ) {}
     138                        if ( hiddenHeight < autoresizeMinHeight ) {
     139                                hiddenHeight = autoresizeMinHeight;
     140                        }
    185141
    186                                 if ( ! offset ) {
    187                                         offset = node.getBoundingClientRect();
    188                                 }
     142                        if ( hiddenHeight === textEditorHeight ) {
     143                                return;
    189144                        }
    190145
    191                         return offset.height ? offset : false;
    192                 }
     146                        $textEditor.height( hiddenHeight );
    193147
    194                 // Make sure the cursor is always visible.
    195                 // This is not only necessary to keep the cursor between the toolbars,
    196                 // but also to scroll the window when the cursor moves out of the viewport to a wpview.
    197                 // Setting a buffer > 0 will prevent the browser default.
    198                 // Some browsers will scroll to the middle,
    199                 // others to the top/bottom of the *window* when moving the cursor out of the viewport.
    200                 function mceKeyup( event ) {
    201                         var VK = tinymce.util.VK,
    202                                 key = event.keyCode;
     148                        adjust();
     149                }
    203150
    204                         // Bail on special keys.
    205                         if ( key <= 47 && ! ( key === VK.SPACEBAR || key === VK.ENTER || key === VK.DELETE || key === VK.BACKSPACE ||
    206                                 key === VK.UP || key === VK.RIGHT || key === VK.DOWN || key === VK.LEFT ) ) {
     151                // We need to wait for TinyMCE to initialize.
     152                $document.on( 'tinymce-editor-init.editor-expand', function( event, editor ) {
     153                        var VK = window.tinymce.util.VK,
     154                                hideFloatPanels = _.debounce( function() {
     155                                        ! $( '.mce-floatpanel:hover' ).length && window.tinymce.ui.FloatPanel.hideAll();
     156                                        $( '.mce-tooltip' ).hide();
     157                                }, 1000, true );
    207158
    208                                 return;
    209                         // OS keys, function keys, num lock, scroll lock
    210                         } else if ( ( key >= 91 && key <= 93 ) || ( key >= 112 && key <= 123 ) || key === 144 || key === 145 ) {
     159                        // Make sure it's the main editor.
     160                        if ( editor.id !== 'content' ) {
    211161                                return;
    212162                        }
    213163
    214                         mceScroll( key );
    215                 }
     164                        // Copy the editor instance.
     165                        mceEditor = editor;
    216166
    217                 function mceScroll( key ) {
    218                         var VK = tinymce.util.VK,
    219                                 offset = mceGetCursorOffset(),
    220                                 buffer = 10,
    221                                 cursorTop, cursorBottom, editorTop, editorBottom;
     167                        // Set the minimum height to the initial viewport height.
     168                        editor.settings.autoresize_min_height = autoresizeMinHeight;
    222169
    223                         if ( ! offset ) {
    224                                 return;
    225                         }
     170                        // Get the necessary UI elements.
     171                        $visualTop = $contentWrap.find( '.mce-toolbar-grp' );
     172                        $visualEditor = $contentWrap.find( '.mce-edit-area' );
     173                        $statusBar = $contentWrap.find( '.mce-statusbar' );
     174                        $menuBar = $contentWrap.find( '.mce-menubar' );
     175
     176                        function mceGetCursorOffset() {
     177                                var node = editor.selection.getNode(),
     178                                        range, view, offset;
    226179
    227                         cursorTop = offset.top + editor.iframeElement.getBoundingClientRect().top;
    228                         cursorBottom = cursorTop + offset.height + buffer;
    229                         cursorTop -= buffer;
    230                         editorTop = heights.adminBarHeight + heights.toolsHeight + heights.menuBarHeight + heights.visualTopHeight;
    231                         editorBottom = heights.windowHeight - heights.bottomHeight - heights.statusBarHeight;
     180                                if ( editor.plugins.wpview && ( view = editor.plugins.wpview.getView( node ) ) ) {
     181                                        offset = view.getBoundingClientRect();
     182                                } else {
     183                                        range = editor.selection.getRng();
    232184
    233                         // Don't scroll if the node is taller than the visible part of the editor
    234                         if ( editorBottom - editorTop < offset.height ) {
    235                                 return;
    236                         }
     185                                        try {
     186                                                offset = range.getClientRects()[0];
     187                                        } catch( er ) {}
    237188
    238                         // WebKit browsers scroll-into-view to the middle of the window but not for arrow keys/backspace.
    239                         // The others scroll to the top of the window, we need to account for the adminbar and editor toolbar(s).
    240                         if ( cursorTop < editorTop && ( ! tinymce.Env.webkit ||
    241                                 ( key === VK.UP || key === VK.RIGHT || key === VK.DOWN || key === VK.LEFT || key === VK.BACKSPACE ) ) ) {
     189                                        if ( ! offset ) {
     190                                                offset = node.getBoundingClientRect();
     191                                        }
     192                                }
    242193
    243                                 window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset - editorTop );
    244                         } else if ( cursorBottom > editorBottom ) {
    245                                 window.scrollTo( window.pageXOffset, cursorBottom + window.pageYOffset - editorBottom );
     194                                return offset.height ? offset : false;
    246195                        }
    247                 }
    248196
    249                 // Adjust when switching editor modes.
    250                 function mceShow() {
    251                         $window.on( 'scroll.mce-float-panels', hideFloatPanels );
     197                        // Make sure the cursor is always visible.
     198                        // This is not only necessary to keep the cursor between the toolbars,
     199                        // but also to scroll the window when the cursor moves out of the viewport to a wpview.
     200                        // Setting a buffer > 0 will prevent the browser default.
     201                        // Some browsers will scroll to the middle,
     202                        // others to the top/bottom of the *window* when moving the cursor out of the viewport.
     203                        function mceKeyup( event ) {
     204                                var key = event.keyCode;
     205
     206                                // Bail on special keys.
     207                                if ( key <= 47 && ! ( key === VK.SPACEBAR || key === VK.ENTER || key === VK.DELETE || key === VK.BACKSPACE || key === VK.UP || key === VK.LEFT || key === VK.DOWN || key === VK.UP ) ) {
     208                                        return;
     209                                // OS keys, function keys, num lock, scroll lock
     210                                } else if ( ( key >= 91 && key <= 93 ) || ( key >= 112 && key <= 123 ) || key === 144 || key === 145 ) {
     211                                        return;
     212                                }
    252213
    253                         setTimeout( function() {
    254                                 editor.execCommand( 'wpAutoResize' );
    255                                 adjust();
    256                         }, 300 );
    257                 }
     214                                mceScroll( key );
     215                        }
    258216
    259                 function mceHide() {
    260                         $window.off( 'scroll.mce-float-panels' );
     217                        function mceScroll( key ) {
     218                                var offset = mceGetCursorOffset(),
     219                                        buffer = 50,
     220                                        cursorTop, cursorBottom, editorTop, editorBottom;
    261221
    262                         setTimeout( function() {
    263                                 var top = $contentWrap.offset().top;
     222                                if ( ! offset ) {
     223                                        return;
     224                                }
    264225
    265                                 if ( window.pageYOffset > top ) {
    266                                         window.scrollTo( window.pageXOffset, top - heights.adminBarHeight );
     226                                cursorTop = offset.top + editor.iframeElement.getBoundingClientRect().top;
     227                                cursorBottom = cursorTop + offset.height;
     228                                cursorTop = cursorTop - buffer;
     229                                cursorBottom = cursorBottom + buffer;
     230                                editorTop = heights.adminBarHeight + heights.toolsHeight + heights.menuBarHeight + heights.visualTopHeight;
     231                                editorBottom = heights.windowHeight - ( advanced ? heights.bottomHeight + heights.statusBarHeight : 0 );
     232
     233                                // Don't scroll if the node is taller than the visible part of the editor
     234                                if ( editorBottom - editorTop < offset.height ) {
     235                                        return;
    267236                                }
    268237
    269                                 textEditorResize();
    270                                 adjust();
    271                         }, 100 );
     238                                if ( cursorTop < editorTop && ( key === VK.UP || key === VK.LEFT || key === VK.BACKSPACE ) ) {
     239                                        window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset - editorTop );
     240                                } else if ( cursorBottom > editorBottom ) {
     241                                        window.scrollTo( window.pageXOffset, cursorBottom + window.pageYOffset - editorBottom );
     242                                }
     243                        }
    272244
    273                         adjust();
    274                 }
     245                        // Adjust when switching editor modes.
     246                        function mceShow() {
     247                                $window.on( 'scroll.mce-float-panels', hideFloatPanels );
    275248
    276                 mceBind = function() {
    277                         editor.on( 'keyup', mceKeyup );
    278                         editor.on( 'show', mceShow );
    279                         editor.on( 'hide', mceHide );
    280                         // Adjust when the editor resizes.
    281                         editor.on( 'setcontent wp-autoresize wp-toolbar-toggle', adjust );
    282                         // Scroll to the caret or selection after undo/redo
    283                         editor.on( 'undo redo', mceScroll );
     249                                setTimeout( function() {
     250                                        editor.execCommand( 'wpAutoResize' );
     251                                        adjust();
     252                                }, 300 );
     253                        }
    284254
    285                         $window.off( 'scroll.mce-float-panels' ).on( 'scroll.mce-float-panels', hideFloatPanels );
    286                 };
     255                        function mceHide() {
     256                                $window.off( 'scroll.mce-float-panels' );
    287257
    288                 mceUnbind = function() {
    289                         editor.off( 'keyup', mceKeyup );
    290                         editor.off( 'show', mceShow );
    291                         editor.off( 'hide', mceHide );
    292                         editor.off( 'setcontent wp-autoresize wp-toolbar-toggle', adjust );
    293                         editor.off( 'undo redo', mceScroll );
     258                                setTimeout( function() {
     259                                        var top = $contentWrap.offset().top;
    294260
    295                         $window.off( 'scroll.mce-float-panels' );
    296                 };
     261                                        if ( window.pageYOffset > top ) {
     262                                                window.scrollTo( window.pageXOffset, top - heights.adminBarHeight );
     263                                        }
    297264
    298                 if ( $wrap.hasClass( 'wp-editor-expand' ) ) {
    299                         // Adjust "immediately"
    300                         mceBind();
    301                         initialResize( adjust );
    302                 }
    303         } );
     265                                        textEditorResize();
     266                                        adjust();
     267                                }, 100 );
    304268
    305         // Adjust the toolbars based on the active editor mode.
    306         function adjust( type ) {
    307                 // Make sure we're not in fullscreen mode.
    308                 if ( fullscreen && fullscreen.settings.visible ) {
    309                         return;
    310                 }
    311 
    312                 var windowPos = $window.scrollTop(),
    313                         resize = type !== 'scroll',
    314                         visual = ( mceEditor && ! mceEditor.isHidden() ),
    315                         buffer = autoresizeMinHeight,
    316                         postBodyTop = $postBody.offset().top,
    317                         borderWidth = 1,
    318                         contentWrapWidth = $contentWrap.width(),
    319                         $top, $editor, sidebarTop, footerTop, canPin,
    320                         topPos, topHeight, editorPos, editorHeight;
    321 
    322                 // Refresh the heights
    323                 if ( resize || ! heights.windowHeight ) {
    324                         getHeights();
    325                 }
     269                                adjust();
     270                        }
    326271
    327                 if ( ! visual && type === 'resize' ) {
    328                         textEditorResize();
    329                 }
     272                        function toggleAdvanced() {
     273                                advanced = ! advanced;
     274                        }
    330275
    331                 if ( visual ) {
    332                         $top = $visualTop;
    333                         $editor = $visualEditor;
    334                         topHeight = heights.visualTopHeight;
    335                 } else {
    336                         $top = $textTop;
    337                         $editor = $textEditor;
    338                         topHeight = heights.textTopHeight;
    339                 }
    340 
    341                 topPos = $top.parent().offset().top;
    342                 editorPos = $editor.offset().top;
    343                 editorHeight = $editor.outerHeight();
    344 
    345                 // Should we pin?
    346                 canPin = visual ? autoresizeMinHeight + topHeight : autoresizeMinHeight + 20; // 20px from textarea padding
    347                 canPin = editorHeight > ( canPin + 5 );
     276                        mceBind = function() {
     277                                editor.on( 'keyup', mceKeyup );
     278                                editor.on( 'show', mceShow );
     279                                editor.on( 'hide', mceHide );
     280                                editor.on( 'wp-toolbar-toggle', toggleAdvanced );
     281                                // Adjust when the editor resizes.
     282                                editor.on( 'setcontent wp-autoresize wp-toolbar-toggle', adjust );
     283                                // Don't hide the caret after undo/redo
     284                                editor.on( 'undo redo', mceScroll );
     285
     286                                $window.off( 'scroll.mce-float-panels' ).on( 'scroll.mce-float-panels', hideFloatPanels );
     287                        };
     288
     289                        mceUnbind = function() {
     290                                editor.off( 'keyup', mceKeyup );
     291                                editor.off( 'show', mceShow );
     292                                editor.off( 'hide', mceHide );
     293                                editor.off( 'wp-toolbar-toggle', toggleAdvanced );
     294                                editor.off( 'setcontent wp-autoresize wp-toolbar-toggle', adjust );
     295                                editor.off( 'undo redo', mceScroll );
     296
     297                                $window.off( 'scroll.mce-float-panels' );
     298                        };
     299
     300                        if ( $wrap.hasClass( 'wp-editor-expand' ) ) {
     301                                // Adjust "immediately"
     302                                mceBind();
     303                                initialResize( adjust );
     304                        }
     305                } );
    348306
    349                 if ( ! canPin ) {
    350                         if ( resize ) {
    351                                 $tools.css( {
    352                                         position: 'absolute',
    353                                         top: 0,
    354                                         width: contentWrapWidth
    355                                 } );
     307                // Adjust the toolbars based on the active editor mode.
     308                function adjust( event ) {
     309                        var type = event && event.type;
    356310
    357                                 if ( visual && $menuBar.length ) {
    358                                         $menuBar.css( {
    359                                                 position: 'absolute',
    360                                                 top: 0,
    361                                                 width: contentWrapWidth - ( borderWidth * 2 )
    362                                         } );
    363                                 }
     311                        // Make sure we're not in fullscreen mode.
     312                        if ( fullscreen && fullscreen.settings.visible ) {
     313                                return;
     314                        }
    364315
    365                                 $top.css( {
    366                                         position: 'absolute',
    367                                         top: heights.menuBarHeight,
    368                                         width: contentWrapWidth - ( borderWidth * 2 ) - ( visual ? 0 : ( $top.outerWidth() - $top.width() ) )
    369                                 } );
     316                        var windowPos = $window.scrollTop(),
     317                                resize = type !== 'scroll',
     318                                visual = ( mceEditor && ! mceEditor.isHidden() ),
     319                                buffer = autoresizeMinHeight,
     320                                postBodyTop = $postBody.offset().top,
     321                                borderWidth = 1,
     322                                contentWrapWidth = $contentWrap.width(),
     323                                $top, $editor, sidebarTop, footerTop, canPin,
     324                                topPos, topHeight, editorPos, editorHeight;
     325
     326                        // Refresh the heights
     327                        if ( resize || ! heights.windowHeight ) {
     328                                getHeights();
     329                        }
    370330
    371                                 $statusBar.add( $bottom ).attr( 'style', '' );
     331                        if ( ! visual && type === 'resize' ) {
     332                                textEditorResize();
    372333                        }
    373                 } else {
    374                         // Maybe pin the top.
    375                         if ( ( ! fixedTop || resize ) &&
    376                                 // Handle scrolling down.
    377                                 ( windowPos >= ( topPos - heights.toolsHeight - heights.adminBarHeight ) &&
    378                                 // Handle scrolling up.
    379                                 windowPos <= ( topPos - heights.toolsHeight - heights.adminBarHeight + editorHeight - buffer ) ) ) {
    380                                 fixedTop = true;
    381 
    382                                 $tools.css( {
    383                                         position: 'fixed',
    384                                         top: heights.adminBarHeight,
    385                                         width: contentWrapWidth
    386                                 } );
    387334
    388                                 if ( visual && $menuBar.length ) {
    389                                         $menuBar.css( {
    390                                                 position: 'fixed',
    391                                                 top: heights.adminBarHeight + heights.toolsHeight,
    392                                                 width: contentWrapWidth - ( borderWidth * 2 ) - ( visual ? 0 : ( $top.outerWidth() - $top.width() ) )
    393                                         } );
    394                                 }
     335                        if ( visual ) {
     336                                $top = $visualTop;
     337                                $editor = $visualEditor;
     338                                topHeight = heights.visualTopHeight;
     339                        } else {
     340                                $top = $textTop;
     341                                $editor = $textEditor;
     342                                topHeight = heights.textTopHeight;
     343                        }
    395344
    396                                 $top.css( {
    397                                         position: 'fixed',
    398                                         top: heights.adminBarHeight + heights.toolsHeight + heights.menuBarHeight,
    399                                         width: contentWrapWidth - ( borderWidth * 2 ) - ( visual ? 0 : ( $top.outerWidth() - $top.width() ) )
    400                                 } );
    401                         // Maybe unpin the top.
    402                         } else if ( fixedTop || resize ) {
    403                                 // Handle scrolling up.
    404                                 if ( windowPos <= ( topPos - heights.toolsHeight - heights.adminBarHeight ) ) {
    405                                         fixedTop = false;
     345                        topPos = $top.parent().offset().top;
     346                        editorPos = $editor.offset().top;
     347                        editorHeight = $editor.outerHeight();
     348
     349                        // Should we pin?
     350                        canPin = visual ? autoresizeMinHeight + topHeight : autoresizeMinHeight + 20; // 20px from textarea padding
     351                        canPin = editorHeight > ( canPin + 5 );
    406352
     353                        if ( ! canPin ) {
     354                                if ( resize ) {
    407355                                        $tools.css( {
    408356                                                position: 'absolute',
    409357                                                top: 0,
     
    423371                                                top: heights.menuBarHeight,
    424372                                                width: contentWrapWidth - ( borderWidth * 2 ) - ( visual ? 0 : ( $top.outerWidth() - $top.width() ) )
    425373                                        } );
    426                                 // Handle scrolling down.
    427                                 } else if ( windowPos >= ( topPos - heights.toolsHeight - heights.adminBarHeight + editorHeight - buffer ) ) {
    428                                         fixedTop = false;
     374
     375                                        $statusBar.add( $bottom ).attr( 'style', '' );
     376                                }
     377                        } else {
     378                                // Maybe pin the top.
     379                                if ( ( ! fixedTop || resize ) &&
     380                                        // Handle scrolling down.
     381                                        ( windowPos >= ( topPos - heights.toolsHeight - heights.adminBarHeight ) &&
     382                                        // Handle scrolling up.
     383                                        windowPos <= ( topPos - heights.toolsHeight - heights.adminBarHeight + editorHeight - buffer ) ) ) {
     384                                        fixedTop = true;
    429385
    430386                                        $tools.css( {
    431                                                 position: 'absolute',
    432                                                 top: editorHeight - buffer,
     387                                                position: 'fixed',
     388                                                top: heights.adminBarHeight,
    433389                                                width: contentWrapWidth
    434390                                        } );
    435391
    436392                                        if ( visual && $menuBar.length ) {
    437393                                                $menuBar.css( {
    438                                                         position: 'absolute',
    439                                                         top: editorHeight - buffer,
    440                                                         width: contentWrapWidth - ( borderWidth * 2 )
     394                                                        position: 'fixed',
     395                                                        top: heights.adminBarHeight + heights.toolsHeight,
     396                                                        width: contentWrapWidth - ( borderWidth * 2 ) - ( visual ? 0 : ( $top.outerWidth() - $top.width() ) )
    441397                                                } );
    442398                                        }
    443399
    444400                                        $top.css( {
    445                                                 position: 'absolute',
    446                                                 top: editorHeight - buffer + heights.menuBarHeight,
     401                                                position: 'fixed',
     402                                                top: heights.adminBarHeight + heights.toolsHeight + heights.menuBarHeight,
    447403                                                width: contentWrapWidth - ( borderWidth * 2 ) - ( visual ? 0 : ( $top.outerWidth() - $top.width() ) )
    448404                                        } );
    449                                 }
    450                         }
    451 
    452                         // Maybe adjust the bottom bar.
    453                         if ( ( ! fixedBottom || resize ) &&
    454                                 // +[n] for the border around the .wp-editor-container.
    455                                 ( windowPos + heights.windowHeight ) <= ( editorPos + editorHeight + heights.bottomHeight + heights.statusBarHeight + borderWidth ) ) {
    456                                 fixedBottom = true;
    457 
    458                                 $statusBar.css( {
    459                                         position: 'fixed',
    460                                         bottom: heights.bottomHeight,
    461                                         width: contentWrapWidth - ( borderWidth * 2 )
    462                                 } );
     405                                // Maybe unpin the top.
     406                                } else if ( fixedTop || resize ) {
     407                                        // Handle scrolling up.
     408                                        if ( windowPos <= ( topPos - heights.toolsHeight - heights.adminBarHeight ) ) {
     409                                                fixedTop = false;
    463410
    464                                 $bottom.css( {
    465                                         position: 'fixed',
    466                                         bottom: 0,
    467                                         width: contentWrapWidth
    468                                 } );
    469                         } else if ( ( fixedBottom || resize ) &&
    470                                         ( windowPos + heights.windowHeight ) > ( editorPos + editorHeight + heights.bottomHeight + heights.statusBarHeight - borderWidth ) ) {
    471                                 fixedBottom = false;
     411                                                $tools.css( {
     412                                                        position: 'absolute',
     413                                                        top: 0,
     414                                                        width: contentWrapWidth
     415                                                } );
    472416
    473                                 $statusBar.add( $bottom ).attr( 'style', '' );
    474                         }
    475                 }
     417                                                if ( visual && $menuBar.length ) {
     418                                                        $menuBar.css( {
     419                                                                position: 'absolute',
     420                                                                top: 0,
     421                                                                width: contentWrapWidth - ( borderWidth * 2 )
     422                                                        } );
     423                                                }
    476424
    477                 // Sidebar pinning
    478                 if ( $postboxContainer.width() < 300 && heights.windowWidth > 600 && // sidebar position is changed with @media from CSS, make sure it is on the side
    479                         $document.height() > ( $sideSortables.height() + postBodyTop + 120 ) && // the sidebar is not the tallest element
    480                         heights.windowHeight < editorHeight ) { // the editor is taller than the viewport
     425                                                $top.css( {
     426                                                        position: 'absolute',
     427                                                        top: heights.menuBarHeight,
     428                                                        width: contentWrapWidth - ( borderWidth * 2 ) - ( visual ? 0 : ( $top.outerWidth() - $top.width() ) )
     429                                                } );
     430                                        // Handle scrolling down.
     431                                        } else if ( windowPos >= ( topPos - heights.toolsHeight - heights.adminBarHeight + editorHeight - buffer ) ) {
     432                                                fixedTop = false;
    481433
    482                         if ( ( heights.sideSortablesHeight + pinnedToolsTop + sidebarBottom ) > heights.windowHeight || fixedSideTop || fixedSideBottom ) {
    483                                 // Reset when scrolling to the top
    484                                 if ( windowPos + pinnedToolsTop <= postBodyTop ) {
    485                                         $sideSortables.attr( 'style', '' );
    486                                         fixedSideTop = fixedSideBottom = false;
    487                                 } else {
    488                                         if ( windowPos > lastScrollPosition ) {
    489                                                 // Scrolling down
    490                                                 if ( fixedSideTop ) {
    491                                                         // let it scroll
    492                                                         fixedSideTop = false;
    493                                                         sidebarTop = $sideSortables.offset().top - heights.adminBarHeight;
    494                                                         footerTop = $footer.offset().top;
    495 
    496                                                         // don't get over the footer
    497                                                         if ( footerTop < sidebarTop + heights.sideSortablesHeight + sidebarBottom ) {
    498                                                                 sidebarTop = footerTop - heights.sideSortablesHeight - 12;
    499                                                         }
     434                                                $tools.css( {
     435                                                        position: 'absolute',
     436                                                        top: editorHeight - buffer,
     437                                                        width: contentWrapWidth
     438                                                } );
    500439
    501                                                         $sideSortables.css({
     440                                                if ( visual && $menuBar.length ) {
     441                                                        $menuBar.css( {
    502442                                                                position: 'absolute',
    503                                                                 top: sidebarTop,
    504                                                                 bottom: ''
    505                                                         });
    506                                                 } else if ( ! fixedSideBottom && heights.sideSortablesHeight + $sideSortables.offset().top + sidebarBottom < windowPos + heights.windowHeight ) {
    507                                                         // pin the bottom
    508                                                         fixedSideBottom = true;
    509 
    510                                                         $sideSortables.css({
    511                                                                 position: 'fixed',
    512                                                                 top: 'auto',
    513                                                                 bottom: sidebarBottom
    514                                                         });
     443                                                                top: editorHeight - buffer,
     444                                                                width: contentWrapWidth - ( borderWidth * 2 )
     445                                                        } );
    515446                                                }
    516                                         } else if ( windowPos < lastScrollPosition ) {
    517                                                 // Scrolling up
    518                                                 if ( fixedSideBottom ) {
    519                                                         // let it scroll
    520                                                         fixedSideBottom = false;
    521                                                         sidebarTop = $sideSortables.offset().top - sidebarBottom;
    522                                                         footerTop = $footer.offset().top;
    523 
    524                                                         // don't get over the footer
    525                                                         if ( footerTop < sidebarTop + heights.sideSortablesHeight + sidebarBottom ) {
    526                                                                 sidebarTop = footerTop - heights.sideSortablesHeight - 12;
    527                                                         }
    528447
    529                                                         $sideSortables.css({
    530                                                                 position: 'absolute',
    531                                                                 top: sidebarTop,
    532                                                                 bottom: ''
    533                                                         });
    534                                                 } else if ( ! fixedSideTop && $sideSortables.offset().top >= windowPos + pinnedToolsTop ) {
    535                                                         // pin the top
    536                                                         fixedSideTop = true;
    537 
    538                                                         $sideSortables.css({
    539                                                                 position: 'fixed',
    540                                                                 top: pinnedToolsTop,
    541                                                                 bottom: ''
    542                                                         });
     448                                                $top.css( {
     449                                                        position: 'absolute',
     450                                                        top: editorHeight - buffer + heights.menuBarHeight,
     451                                                        width: contentWrapWidth - ( borderWidth * 2 ) - ( visual ? 0 : ( $top.outerWidth() - $top.width() ) )
     452                                                } );
     453                                        }
     454                                }
     455
     456                                // Maybe adjust the bottom bar.
     457                                if ( ( ! fixedBottom || ( resize && advanced ) ) &&
     458                                                // +[n] for the border around the .wp-editor-container.
     459                                                ( windowPos + heights.windowHeight ) <= ( editorPos + editorHeight + heights.bottomHeight + heights.statusBarHeight + borderWidth ) ) {
     460
     461                                        if ( event && event.deltaHeight > 0 ) {
     462                                                window.scrollBy( 0, event.deltaHeight );
     463                                        } else if ( advanced ) {
     464                                                fixedBottom = true;
     465
     466                                                $statusBar.css( {
     467                                                        position: 'fixed',
     468                                                        bottom: heights.bottomHeight,
     469                                                        visibility: '',
     470                                                        width: contentWrapWidth - ( borderWidth * 2 )
     471                                                } );
     472
     473                                                $bottom.css( {
     474                                                        position: 'fixed',
     475                                                        bottom: 0,
     476                                                        width: contentWrapWidth
     477                                                } );
     478                                        }
     479                                } else if ( ( ! advanced && fixedBottom ) ||
     480                                                ( ( fixedBottom || resize ) &&
     481                                                ( windowPos + heights.windowHeight ) > ( editorPos + editorHeight + heights.bottomHeight + heights.statusBarHeight - borderWidth ) ) ) {
     482                                        fixedBottom = false;
     483
     484                                        $statusBar.add( $bottom ).attr( 'style', '' );
     485
     486                                        ! advanced && $statusBar.css( 'visibility', 'hidden' );
     487                                }
     488                        }
     489
     490                        // Sidebar pinning
     491                        if ( $postboxContainer.width() < 300 && heights.windowWidth > 600 && // sidebar position is changed with @media from CSS, make sure it is on the side
     492                                $document.height() > ( $sideSortables.height() + postBodyTop + 120 ) && // the sidebar is not the tallest element
     493                                heights.windowHeight < editorHeight ) { // the editor is taller than the viewport
     494
     495                                if ( ( heights.sideSortablesHeight + pinnedToolsTop + sidebarBottom ) > heights.windowHeight || fixedSideTop || fixedSideBottom ) {
     496                                        // Reset when scrolling to the top
     497                                        if ( windowPos + pinnedToolsTop <= postBodyTop ) {
     498                                                $sideSortables.attr( 'style', '' );
     499                                                fixedSideTop = fixedSideBottom = false;
     500                                        } else {
     501                                                if ( windowPos > lastScrollPosition ) {
     502                                                        // Scrolling down
     503                                                        if ( fixedSideTop ) {
     504                                                                // let it scroll
     505                                                                fixedSideTop = false;
     506                                                                sidebarTop = $sideSortables.offset().top - heights.adminBarHeight;
     507                                                                footerTop = $footer.offset().top;
     508
     509                                                                // don't get over the footer
     510                                                                if ( footerTop < sidebarTop + heights.sideSortablesHeight + sidebarBottom ) {
     511                                                                        sidebarTop = footerTop - heights.sideSortablesHeight - 12;
     512                                                                }
     513
     514                                                                $sideSortables.css({
     515                                                                        position: 'absolute',
     516                                                                        top: sidebarTop,
     517                                                                        bottom: ''
     518                                                                });
     519                                                        } else if ( ! fixedSideBottom && heights.sideSortablesHeight + $sideSortables.offset().top + sidebarBottom < windowPos + heights.windowHeight ) {
     520                                                                // pin the bottom
     521                                                                fixedSideBottom = true;
     522
     523                                                                $sideSortables.css({
     524                                                                        position: 'fixed',
     525                                                                        top: 'auto',
     526                                                                        bottom: sidebarBottom
     527                                                                });
     528                                                        }
     529                                                } else if ( windowPos < lastScrollPosition ) {
     530                                                        // Scrolling up
     531                                                        if ( fixedSideBottom ) {
     532                                                                // let it scroll
     533                                                                fixedSideBottom = false;
     534                                                                sidebarTop = $sideSortables.offset().top - sidebarBottom;
     535                                                                footerTop = $footer.offset().top;
     536
     537                                                                // don't get over the footer
     538                                                                if ( footerTop < sidebarTop + heights.sideSortablesHeight + sidebarBottom ) {
     539                                                                        sidebarTop = footerTop - heights.sideSortablesHeight - 12;
     540                                                                }
     541
     542                                                                $sideSortables.css({
     543                                                                        position: 'absolute',
     544                                                                        top: sidebarTop,
     545                                                                        bottom: ''
     546                                                                });
     547                                                        } else if ( ! fixedSideTop && $sideSortables.offset().top >= windowPos + pinnedToolsTop ) {
     548                                                                // pin the top
     549                                                                fixedSideTop = true;
     550
     551                                                                $sideSortables.css({
     552                                                                        position: 'fixed',
     553                                                                        top: pinnedToolsTop,
     554                                                                        bottom: ''
     555                                                                });
     556                                                        }
    543557                                                }
    544558                                        }
     559                                } else {
     560                                        // if the sidebar container is smaller than the viewport, then pin/unpin the top when scrolling
     561                                        if ( windowPos >= ( postBodyTop - pinnedToolsTop ) ) {
     562
     563                                                $sideSortables.css( {
     564                                                        position: 'fixed',
     565                                                        top: pinnedToolsTop
     566                                                } );
     567                                        } else {
     568                                                $sideSortables.attr( 'style', '' );
     569                                        }
     570
     571                                        fixedSideTop = fixedSideBottom = false;
    545572                                }
     573
     574                                lastScrollPosition = windowPos;
    546575                        } else {
    547                                 // if the sidebar container is smaller than the viewport, then pin/unpin the top when scrolling
    548                                 if ( windowPos >= ( postBodyTop - pinnedToolsTop ) ) {
     576                                $sideSortables.attr( 'style', '' );
     577                                fixedSideTop = fixedSideBottom = false;
     578                        }
    549579
    550                                         $sideSortables.css( {
    551                                                 position: 'fixed',
    552                                                 top: pinnedToolsTop
     580                        if ( resize ) {
     581                                $contentWrap.css( {
     582                                        paddingTop: heights.toolsHeight
     583                                } );
     584
     585                                if ( visual ) {
     586                                        $visualEditor.css( {
     587                                                paddingTop: heights.visualTopHeight + heights.menuBarHeight
    553588                                        } );
    554589                                } else {
    555                                         $sideSortables.attr( 'style', '' );
     590                                        $textEditor.css( {
     591                                                marginTop: heights.textTopHeight
     592                                        } );
     593
     594                                        $textEditorClone.width( contentWrapWidth - 20 - ( borderWidth * 2 ) );
    556595                                }
     596                        }
     597                }
    557598
    558                                 fixedSideTop = fixedSideBottom = false;
     599                function fullscreenHide() {
     600                        textEditorResize();
     601                        adjust();
     602                }
     603
     604                function initialResize( callback ) {
     605                        for ( var i = 1; i < 6; i++ ) {
     606                                setTimeout( callback, 500 * i );
    559607                        }
     608                }
    560609
    561                         lastScrollPosition = windowPos;
    562                 } else {
    563                         $sideSortables.attr( 'style', '' );
    564                         fixedSideTop = fixedSideBottom = false;
     610                function afterScroll() {
     611                        clearTimeout( scrollTimer );
     612                        scrollTimer = setTimeout( adjust, 100 );
    565613                }
    566614
    567                 if ( resize ) {
    568                         $contentWrap.css( {
    569                                 paddingTop: heights.toolsHeight
     615                function on() {
     616                        // Scroll to the top when triggering this from JS.
     617                        // Ensures toolbars are pinned properly.
     618                        if ( window.pageYOffset && window.pageYOffset > pageYOffsetAtTop ) {
     619                                window.scrollTo( window.pageXOffset, 0 );
     620                        }
     621
     622                        $wrap.addClass( 'wp-editor-expand' );
     623
     624                        // Adjust when the window is scrolled or resized.
     625                        $window.on( 'scroll.editor-expand resize.editor-expand', function( event ) {
     626                                adjust( event.type );
     627                                afterScroll();
    570628                        } );
    571629
    572                         if ( visual ) {
    573                                 $visualEditor.css( {
    574                                         paddingTop: heights.visualTopHeight + heights.menuBarHeight
    575                                 } );
    576                         } else {
    577                                 $textEditor.css( {
    578                                         marginTop: heights.textTopHeight
    579                                 } );
     630                        // Adjust when collapsing the menu, changing the columns, changing the body class.
     631                        $document.on( 'wp-collapse-menu.editor-expand postboxes-columnchange.editor-expand editor-classchange.editor-expand', adjust )
     632                                .on( 'postbox-toggled.editor-expand', function() {
     633                                        if ( ! fixedSideTop && ! fixedSideBottom && window.pageYOffset > pinnedToolsTop ) {
     634                                                fixedSideBottom = true;
     635                                                window.scrollBy( 0, -1 );
     636                                                adjust();
     637                                                window.scrollBy( 0, 1 );
     638                                        }
     639
     640                                        adjust();
     641                                }).on( 'wp-window-resized.editor-expand', function() {
     642                                        if ( mceEditor && ! mceEditor.isHidden() ) {
     643                                                mceEditor.execCommand( 'wpAutoResize' );
     644                                        } else {
     645                                                textEditorResize();
     646                                        }
     647                                });
    580648
    581                                 $textEditorClone.width( contentWrapWidth - 20 - ( borderWidth * 2 ) );
     649                        $textEditor.on( 'focus.editor-expand input.editor-expand propertychange.editor-expand', textEditorResize );
     650                        $textEditor.on( 'keyup.editor-expand', textEditorKeyup );
     651                        mceBind();
     652
     653                        // Adjust when entering/exiting fullscreen mode.
     654                        fullscreen && fullscreen.pubsub.subscribe( 'hidden', fullscreenHide );
     655
     656                        if ( mceEditor ) {
     657                                mceEditor.settings.wp_autoresize_on = true;
     658                                mceEditor.execCommand( 'wpAutoResizeOn' );
     659
     660                                if ( ! mceEditor.isHidden() ) {
     661                                        mceEditor.execCommand( 'wpAutoResize' );
     662                                }
    582663                        }
     664
     665                        if ( ! mceEditor || mceEditor.isHidden() ) {
     666                                textEditorResize();
     667                        }
     668
     669                        adjust();
     670
     671                        $document.trigger( 'editor-expand-on' );
    583672                }
    584         }
    585673
    586         function fullscreenHide() {
    587                 textEditorResize();
    588                 adjust();
    589         }
     674                function off() {
     675                        var height = window.getUserSetting('ed_size');
     676
     677                        // Scroll to the top when triggering this from JS.
     678                        // Ensures toolbars are reset properly.
     679                        if ( window.pageYOffset && window.pageYOffset > pageYOffsetAtTop ) {
     680                                window.scrollTo( window.pageXOffset, 0 );
     681                        }
     682
     683                        $wrap.removeClass( 'wp-editor-expand' );
    590684
    591         function initialResize( callback ) {
    592                 for ( var i = 1; i < 6; i++ ) {
    593                         setTimeout( callback, 500 * i );
     685                        $window.off( '.editor-expand' );
     686                        $document.off( '.editor-expand' );
     687                        $textEditor.off( '.editor-expand' );
     688                        mceUnbind();
     689
     690                        // Adjust when entering/exiting fullscreen mode.
     691                        fullscreen && fullscreen.pubsub.unsubscribe( 'hidden', fullscreenHide );
     692
     693                        // Reset all css
     694                        $.each( [ $visualTop, $textTop, $tools, $menuBar, $bottom, $statusBar, $contentWrap, $visualEditor, $textEditor, $sideSortables ], function( i, element ) {
     695                                element && element.attr( 'style', '' );
     696                        });
     697
     698                        fixedTop = fixedBottom = fixedSideTop = fixedSideBottom = false;
     699
     700                        if ( mceEditor ) {
     701                                mceEditor.settings.wp_autoresize_on = false;
     702                                mceEditor.execCommand( 'wpAutoResizeOff' );
     703
     704                                if ( ! mceEditor.isHidden() ) {
     705                                        $textEditor.hide();
     706
     707                                        if ( height ) {
     708                                                mceEditor.theme.resizeTo( null, height );
     709                                        }
     710                                }
     711                        }
     712
     713                        if ( height ) {
     714                                $textEditor.height( height );
     715                        }
     716
     717                        $document.trigger( 'editor-expand-off' );
    594718                }
    595         }
    596719
    597         function afterScroll() {
    598                 clearTimeout( scrollTimer );
    599                 scrollTimer = setTimeout( adjust, 100 );
    600         }
     720                // Start on load
     721                if ( $wrap.hasClass( 'wp-editor-expand' ) ) {
     722                        on();
    601723
    602         function on() {
    603                 // Scroll to the top when triggering this from JS.
    604                 // Ensures toolbars are pinned properly.
    605                 if ( window.pageYOffset && window.pageYOffset > pageYOffsetAtTop ) {
    606                         window.scrollTo( window.pageXOffset, 0 );
     724                        // Ideally we need to resize just after CSS has fully loaded and QuickTags is ready.
     725                        if ( $contentWrap.hasClass( 'html-active' ) ) {
     726                                initialResize( function() {
     727                                        adjust();
     728                                        textEditorResize();
     729                                } );
     730                        }
    607731                }
    608732
    609                 $wrap.addClass( 'wp-editor-expand' );
     733                // Show the on/off checkbox
     734                $( '#adv-settings .editor-expand' ).show();
     735                $( '#editor-expand-toggle' ).on( 'change.editor-expand', function() {
     736                        if ( $(this).prop( 'checked' ) ) {
     737                                on();
     738                                window.setUserSetting( 'editor_expand', 'on' );
     739                        } else {
     740                                off();
     741                                window.setUserSetting( 'editor_expand', 'off' );
     742                        }
     743                });
     744
     745                // Expose on() and off()
     746                window.editorExpand = {
     747                        on: on,
     748                        off: off
     749                };
     750        } );
    610751
    611                 // Adjust when the window is scrolled or resized.
    612                 $window.on( 'scroll.editor-expand resize.editor-expand', function( event ) {
    613                         adjust( event.type );
    614                         afterScroll();
     752        /* DFW. */
     753        $( function() {
     754                var $body = $( document.body ),
     755                        $wrap = $( '#wpcontent' ),
     756                        $editor = $( '#post-body-content' ),
     757                        $title = $( '#title' ),
     758                        $content = $( '#content' ),
     759                        $overlay = $( document.createElement( 'DIV' ) ),
     760                        $slug = $( '#edit-slug-box' ),
     761                        $slugFocusEl = $slug.find( 'a' )
     762                                .add( $slug.find( 'button' ) )
     763                                .add( $slug.find( 'input' ) ),
     764                        $menuWrap = $( '#adminmenuwrap' ),
     765                        $textButton = $(),
     766                        $editorWindow = $(),
     767                        $editorIframe = $(),
     768                        mceBind = function() {},
     769                        mceUnbind = function() {},
     770                        dfw = window.getUserSetting( 'dfw' ),
     771                        isActive = window.getUserSetting( 'editor_expand' ) === 'on',
     772                        isOn = isActive ? dfw ? !! parseInt( dfw, 10 ) : true : false,
     773                        traveledX = 0,
     774                        traveledY = 0,
     775                        buffer = 20,
     776                        faded, fadedAdminBar, fadedSlug,
     777                        editorRect, x, y, mouseY, scrollY, button,
     778                        focusLostTimer, overlayTimer, editorHasFocus;
     779
     780                $body.append( $overlay );
     781
     782                $overlay.css( {
     783                        display: 'none',
     784                        position: 'fixed',
     785                        top: $adminBar.height(),
     786                        right: 0,
     787                        bottom: 0,
     788                        left: 0,
     789                        'z-index': 9997
    615790                } );
    616791
    617                 // Adjust when collapsing the menu, changing the columns, changing the body class.
    618                 $document.on( 'wp-collapse-menu.editor-expand postboxes-columnchange.editor-expand editor-classchange.editor-expand', adjust )
    619                         .on( 'postbox-toggled.editor-expand', function() {
    620                                 if ( ! fixedSideTop && ! fixedSideBottom && window.pageYOffset > pinnedToolsTop ) {
    621                                         fixedSideBottom = true;
    622                                         window.scrollBy( 0, -1 );
    623                                         adjust();
    624                                         window.scrollBy( 0, 1 );
    625                                 }
     792                $editor.css( {
     793                        position: 'relative'
     794                } );
    626795
    627                                 adjust();
    628                         }).on( 'wp-window-resized.editor-expand', function() {
    629                                 if ( mceEditor && ! mceEditor.isHidden() ) {
    630                                         mceEditor.execCommand( 'wpAutoResize' );
    631                                 } else {
    632                                         textEditorResize();
    633                                 }
    634                         });
     796                // Wait for quicktags to initialize.
     797                setTimeout( function() {
     798                        $textButton = $( '#qt_content_fullscreen' ).toggleClass( 'active', isOn ).on( 'click.focus', toggle );
     799                }, 300 );
    635800
    636                 $textEditor.on( 'focus.editor-expand input.editor-expand propertychange.editor-expand', textEditorResize );
    637                 $textEditor.on( 'keyup.editor-expand', textEditorKeyup );
    638                 mceBind();
     801                $window.on( 'mousemove.focus', function( event ) {
     802                        mouseY = event.pageY;
     803                } );
     804
     805                function activate() {
     806                        if ( ! isActive ) {
     807                                isActive = true;
     808
     809                                button.disabled( false );
     810                        }
     811                }
    639812
    640                 // Adjust when entering/exiting fullscreen mode.
    641                 fullscreen && fullscreen.pubsub.subscribe( 'hidden', fullscreenHide );
     813                function deactivate() {
     814                        if ( isActive ) {
     815                                off();
    642816
    643                 if ( mceEditor ) {
    644                         mceEditor.settings.wp_autoresize_on = true;
    645                         mceEditor.execCommand( 'wpAutoResizeOn' );
     817                                isActive = false;
    646818
    647                         if ( ! mceEditor.isHidden() ) {
    648                                 mceEditor.execCommand( 'wpAutoResize' );
     819                                button.disabled( true );
    649820                        }
    650821                }
    651822
    652                 if ( ! mceEditor || mceEditor.isHidden() ) {
    653                         textEditorResize();
     823                function on() {
     824                        if ( ! isOn && isActive ) {
     825                                isOn = true;
     826
     827                                mceBind();
     828
     829                                $content.on( 'keydown.focus', fadeOut );
     830
     831                                $title.add( $content ).on( 'blur.focus', maybeFadeIn );
     832
     833                                fadeOut();
     834
     835                                window.setUserSetting( 'dfw', '1' );
     836
     837                                $textButton.addClass( 'active' );
     838                        }
    654839                }
    655840
    656                 adjust();
    657         }
     841                function off() {
     842                        if ( isOn ) {
     843                                isOn = false;
     844
     845                                mceUnbind();
     846
     847                                $title.add( $content ).off( '.focus' );
     848
     849                                fadeIn();
    658850
    659         function off() {
    660                 var height = window.getUserSetting('ed_size');
     851                                $editor.off( '.focus' );
    661852
    662                 // Scroll to the top when triggering this from JS.
    663                 // Ensures toolbars are reset properly.
    664                 if ( window.pageYOffset && window.pageYOffset > pageYOffsetAtTop ) {
    665                         window.scrollTo( window.pageXOffset, 0 );
     853                                window.setUserSetting( 'dfw', '0' );
     854
     855                                $textButton.removeClass( 'active' );
     856                        }
    666857                }
    667858
    668                 $wrap.removeClass( 'wp-editor-expand' );
     859                function toggle() {
     860                        ( isOn ? off : on )();
     861                }
    669862
    670                 $window.off( '.editor-expand' );
    671                 $document.off( '.editor-expand' );
    672                 $textEditor.off( '.editor-expand' );
    673                 mceUnbind();
     863                function fadeOut( event ) {
     864                        var key = event && event.keyCode;
    674865
    675                 // Adjust when entering/exiting fullscreen mode.
    676                 fullscreen && fullscreen.pubsub.unsubscribe( 'hidden', fullscreenHide );
     866                        if ( key === 27 ) {
     867                                fadeIn();
     868                                return;
     869                        }
    677870
    678                 // Reset all css
    679                 $.each( [ $visualTop, $textTop, $tools, $menuBar, $bottom, $statusBar, $contentWrap, $visualEditor, $textEditor, $sideSortables ], function( i, element ) {
    680                         element && element.attr( 'style', '' );
    681                 });
     871                        if ( key && (
     872                                // Special keys ( tab, ctrl, alt, esc, arrow keys... )
     873                                ( key <= 47 && key !== 8 && key !== 13 && key !== 32 && key !== 46 ) ||
     874                                // Windows keys
     875                                ( key >= 91 && key <= 93 ) ||
     876                                // F keys
     877                                ( key >= 112 && key <= 135 ) ||
     878                                // Num Lock, Scroll Lock, OEM
     879                                ( key >= 144 && key <= 150 ) ||
     880                                // OEM or non-printable
     881                                key >= 224
     882                        ) ) {
     883                                return;
     884                        }
     885
     886                        if ( ! faded ) {
     887                                faded = true;
     888
     889                                clearTimeout( overlayTimer );
    682890
    683                 fixedTop = fixedBottom = fixedSideTop = fixedSideBottom = false;
     891                                overlayTimer = setTimeout( function() {
     892                                        $overlay.show();
     893                                }, 600 );
     894
     895                                $editor.css( 'z-index', 9998 );
     896
     897                                $overlay
     898                                        // Always recalculate the editor area entering the overlay with the mouse.
     899                                        .on( 'mouseenter.focus', function() {
     900                                                editorRect = $editor.offset();
     901                                                editorRect.right = editorRect.left + $editor.outerWidth();
     902                                                editorRect.bottom = editorRect.top + $editor.outerHeight();
     903
     904                                                $window.on( 'scroll.focus', function() {
     905                                                        var nScrollY = window.pageYOffset;
     906
     907                                                        if ( (
     908                                                                scrollY && mouseY &&
     909                                                                scrollY !== nScrollY
     910                                                        ) && (
     911                                                                mouseY < editorRect.top - buffer ||
     912                                                                mouseY > editorRect.bottom + buffer
     913                                                        ) ) {
     914                                                                fadeIn();
     915                                                        }
     916
     917                                                        scrollY = nScrollY;
     918                                                } );
     919                                        } )
     920                                        .on( 'mouseleave.focus', function() {
     921                                                x = y =  null;
     922                                                traveledX = traveledY = 0;
     923
     924                                                $window.off( 'scroll.focus' );
     925                                        } )
     926                                        // Fade in when the mouse moves away form the editor area.
     927                                        .on( 'mousemove.focus', function( event ) {
     928                                                var nx = event.pageX,
     929                                                        ny = event.pageY;
     930
     931                                                if ( x && y && ( nx !== x || ny !== y ) ) {
     932                                                        if (
     933                                                                ( ny <= y && ny < editorRect.top ) ||
     934                                                                ( ny >= y && ny > editorRect.bottom ) ||
     935                                                                ( nx <= x && nx < editorRect.left ) ||
     936                                                                ( nx >= x && nx > editorRect.right )
     937                                                        ) {
     938                                                                traveledX += Math.abs( x - nx );
     939                                                                traveledY += Math.abs( y - ny );
     940
     941                                                                if ( (
     942                                                                        ny <= editorRect.top - buffer ||
     943                                                                        ny >= editorRect.bottom + buffer ||
     944                                                                        nx <= editorRect.left - buffer ||
     945                                                                        nx >= editorRect.right + buffer
     946                                                                ) && (
     947                                                                        traveledX > 10 ||
     948                                                                        traveledY > 10
     949                                                                ) ) {
     950                                                                        fadeIn();
     951
     952                                                                        x = y =  null;
     953                                                                        traveledX = traveledY = 0;
     954
     955                                                                        return;
     956                                                                }
     957                                                        } else {
     958                                                                traveledX = traveledY = 0;
     959                                                        }
     960                                                }
    684961
    685                 if ( mceEditor ) {
    686                         mceEditor.settings.wp_autoresize_on = false;
    687                         mceEditor.execCommand( 'wpAutoResizeOff' );
     962                                                x = nx;
     963                                                y = ny;
     964                                        } )
     965                                        // When the overlay is touched, always fade in and cancel the event.
     966                                        .on( 'touchstart.focus', function( event ) {
     967                                                event.preventDefault();
     968                                                fadeIn();
     969                                        } );
    688970
    689                         if ( ! mceEditor.isHidden() ) {
    690                                 $textEditor.hide();
     971                                $editor.off( 'mouseenter.focus' );
    691972
    692                                 if ( height ) {
    693                                         mceEditor.theme.resizeTo( null, height );
     973                                if ( focusLostTimer ) {
     974                                        clearTimeout( focusLostTimer );
     975                                        focusLostTimer = null;
    694976                                }
     977
     978                                $menuWrap.off( 'mouseenter.focus' );
     979
     980                                $body.addClass( 'focus-on' ).removeClass( 'focus-off' );
    695981                        }
     982
     983                        fadeOutAdminBar();
     984                        fadeOutSlug();
    696985                }
    697986
    698                 if ( height ) {
    699                         $textEditor.height( height );
     987                function fadeIn() {
     988                        if ( faded ) {
     989                                faded = false;
     990
     991                                clearTimeout( overlayTimer );
     992
     993                                overlayTimer = setTimeout( function() {
     994                                        $overlay.hide();
     995                                }, 200 );
     996
     997                                $editor.css( 'z-index', '' );
     998
     999                                $overlay.off( 'mouseenter.focus mouseleave.focus mousemove.focus touchstart.focus' );
     1000
     1001                                $editor.on( 'mouseenter.focus', function() {
     1002                                        if ( $.contains( $editor.get( 0 ), document.activeElement ) || editorHasFocus ) {
     1003                                                fadeOut();
     1004                                        }
     1005                                } );
     1006
     1007                                focusLostTimer = setTimeout( function() {
     1008                                        focusLostTimer = null;
     1009                                        $editor.off( 'mouseenter.focus' );
     1010                                }, 1000 );
     1011
     1012                                $menuWrap.on( 'mouseenter.focus', function() {
     1013                                        if ( focusLostTimer ) {
     1014                                                clearTimeout( focusLostTimer );
     1015                                                focusLostTimer = null;
     1016                                        }
     1017
     1018                                        $editor.off( 'mouseenter.focus' );
     1019                                } );
     1020
     1021                                $body.addClass( 'focus-off' ).removeClass( 'focus-on' );
     1022                        }
     1023
     1024                        fadeInAdminBar();
     1025                        fadeInSlug();
    7001026                }
    701         }
    7021027
    703         // Start on load
    704         if ( $wrap.hasClass( 'wp-editor-expand' ) ) {
    705                 on();
     1028                function maybeFadeIn() {
     1029                        setTimeout( function() {
     1030                                var position = document.activeElement.compareDocumentPosition( $editor.get( 0 ) );
    7061031
    707                 // Ideally we need to resize just after CSS has fully loaded and QuickTags is ready.
    708                 if ( $contentWrap.hasClass( 'html-active' ) ) {
    709                         initialResize( function() {
    710                                 adjust();
    711                                 textEditorResize();
    712                         } );
     1032                                function hasFocus( $el ) {
     1033                                        return $.contains( $el.get( 0 ), document.activeElement );
     1034                                }
     1035
     1036                                // The focussed node is before or behind the editor area, and not ouside the wrap.
     1037                                if ( ( position === 2 || position === 4 ) && ( hasFocus( $menuWrap ) || hasFocus( $wrap ) || hasFocus( $footer ) ) ) {
     1038                                        fadeIn();
     1039                                }
     1040                        }, 0 );
    7131041                }
    714         }
    7151042
    716         // Show the on/off checkbox
    717         $( '#adv-settings .editor-expand' ).show();
    718         $( '#editor-expand-toggle' ).on( 'change.editor-expand', function() {
    719                 if ( $(this).prop( 'checked' ) ) {
    720                         on();
    721                         window.setUserSetting( 'editor_expand', 'on' );
    722                 } else {
    723                         off();
    724                         window.setUserSetting( 'editor_expand', 'off' );
    725                 }
    726         });
    727 
    728         // Expose on() and off()
    729         window.editorExpand = {
    730                 on: on,
    731                 off: off
    732         };
    733 });
     1043                function fadeOutAdminBar() {
     1044                        if ( ! fadedAdminBar && faded ) {
     1045                                fadedAdminBar = true;
     1046
     1047                                $adminBar
     1048                                        .on( 'mouseenter.focus', function() {
     1049                                                $adminBar.addClass( 'focus-off' );
     1050                                        } )
     1051                                        .on( 'mouseleave.focus', function() {
     1052                                                $adminBar.removeClass( 'focus-off' );
     1053                                        } );
     1054                        }
     1055                }
     1056
     1057                function fadeInAdminBar() {
     1058                        if ( fadedAdminBar ) {
     1059                                fadedAdminBar = false;
     1060
     1061                                $adminBar.off( '.focus' );
     1062                        }
     1063                }
     1064
     1065                function fadeOutSlug() {
     1066                        if ( ! fadedSlug && faded && ! $slug.find( ':focus').length ) {
     1067                                fadedSlug = true;
     1068
     1069                                $slug.stop().fadeTo( 'fast', 0.3 ).on( 'mouseenter.focus', fadeInSlug ).off( 'mouseleave.focus' );
     1070
     1071                                $slugFocusEl.on( 'focus.focus', fadeInSlug ).off( 'blur.focus' );
     1072                        }
     1073                }
     1074
     1075                function fadeInSlug() {
     1076                        if ( fadedSlug ) {
     1077                                fadedSlug = false;
     1078
     1079                                $slug.stop().fadeTo( 'fast', 1 ).on( 'mouseleave.focus', fadeOutSlug ).off( 'mouseenter.focus' );
     1080
     1081                                $slugFocusEl.on( 'blur.focus', fadeOutSlug ).off( 'focus.focus' );
     1082                        }
     1083                }
     1084
     1085                $document.on( 'tinymce-editor-setup.focus', function( event, editor ) {
     1086                        editor.addButton( 'dfw', {
     1087                                classes: 'wp-dfw btn widget',
     1088                                disabled: ! isActive,
     1089                                onclick: toggle,
     1090                                onPostRender: function() {
     1091                                        button = this;
     1092                                },
     1093                                tooltip: 'Distraction Free Writing'
     1094                        } );
     1095                } );
     1096
     1097                $document.on( 'tinymce-editor-init.focus', function( event, editor ) {
     1098                        function focus() {
     1099                                editorHasFocus = true;
     1100                        }
     1101
     1102                        function blur() {
     1103                                editorHasFocus = false;
     1104                        }
     1105
     1106                        if ( editor.id === 'content' ) {
     1107                                $editorWindow = $( editor.getWin() );
     1108                                $editorIframe = $( editor.getContentAreaContainer() ).find( 'iframe' );
     1109
     1110                                mceBind = function() {
     1111                                        button.active( true );
     1112                                        editor.on( 'keydown', fadeOut );
     1113                                        editor.on( 'blur', maybeFadeIn );
     1114                                        editor.on( 'focus', focus );
     1115                                        editor.on( 'blur', blur );
     1116                                };
     1117
     1118                                mceUnbind = function() {
     1119                                        button.active( false );
     1120                                        editor.off( 'keydown', fadeOut );
     1121                                        editor.off( 'blur', maybeFadeIn );
     1122                                        editor.off( 'focus', focus );
     1123                                        editor.off( 'blur', blur );
     1124                                };
     1125
     1126                                if ( isOn ) {
     1127                                        mceBind();
     1128                                }
     1129
     1130                                // Make sure the body focusses when clicking outside it.
     1131                                editor.on( 'click', function( event ) {
     1132                                        if ( event.target === editor.getDoc().documentElement ) {
     1133                                                editor.focus();
     1134                                        }
     1135                                } );
     1136                        }
     1137                } );
     1138
     1139                $document.on( 'editor-expand-on.focus', activate ).on( 'editor-expand-off.focus', deactivate );
     1140
     1141                if ( isOn ) {
     1142                        $content.on( 'keydown.focus', fadeOut );
     1143
     1144                        $title.add( $content ).on( 'blur.focus', maybeFadeIn );
     1145                }
     1146        } );
     1147} )( window, window.jQuery );
  • src/wp-includes/class-wp-editor.php

     
    456456                                        }
    457457                                }
    458458
    459                                 if ( $set['dfw'] )
    460                                         $plugins[] = 'wpfullscreen';
    461 
    462459                                self::$plugins = $plugins;
    463460                                self::$ext_plugins = $ext_plugins;
    464461
     
    555552                                 * @param array  $buttons   First-row list of buttons.
    556553                                 * @param string $editor_id Unique editor identifier, e.g. 'content'.
    557554                                 */
    558                                 $mce_buttons = apply_filters( 'mce_buttons', array('bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'hr', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' ), $editor_id );
     555                                $mce_buttons = apply_filters( 'mce_buttons', array('bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'hr', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker', 'wp_adv', 'dfw' ), $editor_id );
    559556
    560557                                /**
    561558                                 * Filter the second-row list of TinyMCE buttons (Visual tab).
     
    608605                                unset($set['tinymce']['body_class']);
    609606                        }
    610607
    611                         if ( $set['dfw'] ) {
    612                                 // replace the first 'fullscreen' with 'wp_fullscreen'
    613                                 if ( ($key = array_search('fullscreen', $mce_buttons)) !== false )
    614                                         $mce_buttons[$key] = 'wp_fullscreen';
    615                                 elseif ( ($key = array_search('fullscreen', $mce_buttons_2)) !== false )
    616                                         $mce_buttons_2[$key] = 'wp_fullscreen';
    617                                 elseif ( ($key = array_search('fullscreen', $mce_buttons_3)) !== false )
    618                                         $mce_buttons_3[$key] = 'wp_fullscreen';
    619                                 elseif ( ($key = array_search('fullscreen', $mce_buttons_4)) !== false )
    620                                         $mce_buttons_4[$key] = 'wp_fullscreen';
    621                         }
    622 
    623608                        $mceInit = array (
    624609                                'selector' => "#$editor_id",
    625610                                'resize' => 'vertical',
     
    714699                        wp_enqueue_script('wplink');
    715700                }
    716701
    717                 if ( in_array('wpfullscreen', self::$plugins, true) || in_array('fullscreen', self::$qt_buttons, true) )
    718                         wp_enqueue_script('wp-fullscreen');
    719 
    720702                if ( self::$has_medialib ) {
    721703                        add_thickbox();
    722704                        wp_enqueue_script('media-upload');
     
    11681150                if ( in_array( 'wplink', self::$plugins, true ) || in_array( 'link', self::$qt_buttons, true ) )
    11691151                        self::wp_link_dialog();
    11701152
    1171                 if ( in_array( 'wpfullscreen', self::$plugins, true ) || in_array( 'fullscreen', self::$qt_buttons, true ) )
    1172                         self::wp_fullscreen_html();
    1173 
    11741153                /**
    11751154                 * Fires after any core TinyMCE editor instances are created.
    11761155                 *
     
    11811160                do_action( 'after_wp_tiny_mce', self::$mce_settings );
    11821161        }
    11831162
    1184         public static function wp_fullscreen_html() {
    1185                 global $content_width;
    1186                 $post = get_post();
    1187 
    1188                 $width = isset( $content_width ) && 800 > $content_width ? $content_width : 800;
    1189                 $width = $width + 22; // compensate for the padding and border
    1190                 $dfw_width = get_user_setting( 'dfw_width', $width );
    1191                 $save = isset( $post->post_status ) && $post->post_status == 'publish' ? __('Update') : __('Save');
    1192 
    1193                 ?>
    1194                 <div id="wp-fullscreen-body" class="wp-core-ui<?php if ( is_rtl() ) echo ' rtl'; ?>" data-theme-width="<?php echo (int) $width; ?>" data-dfw-width="<?php echo (int) $dfw_width; ?>">
    1195                 <div id="fullscreen-topbar">
    1196                         <div id="wp-fullscreen-toolbar">
    1197                         <div id="wp-fullscreen-close"><a href="#" onclick="wp.editor.fullscreen.off();return false;"><?php _e('Exit fullscreen'); ?></a></div>
    1198                         <div id="wp-fullscreen-central-toolbar" style="width:<?php echo $width; ?>px;">
    1199 
    1200                         <div id="wp-fullscreen-mode-bar">
    1201                                 <div id="wp-fullscreen-modes" class="button-group">
    1202                                         <a class="button wp-fullscreen-mode-tinymce" href="#" onclick="wp.editor.fullscreen.switchmode( 'tinymce' ); return false;"><?php _e( 'Visual' ); ?></a>
    1203                                         <a class="button wp-fullscreen-mode-html" href="#" onclick="wp.editor.fullscreen.switchmode( 'html' ); return false;"><?php _ex( 'Text', 'Name for the Text editor tab (formerly HTML)' ); ?></a>
    1204                                 </div>
    1205                         </div>
    1206 
    1207                         <div id="wp-fullscreen-button-bar"><div id="wp-fullscreen-buttons" class="mce-toolbar">
    1208                 <?php
    1209 
    1210                 $buttons = array(
    1211                         // format: title, onclick, show in both editors
    1212                         'bold' => array( 'title' => __('Bold (Ctrl + B)'), 'both' => false ),
    1213                         'italic' => array( 'title' => __('Italic (Ctrl + I)'), 'both' => false ),
    1214                         'bullist' => array( 'title' => __('Unordered list (Alt + Shift + U)'), 'both' => false ),
    1215                         'numlist' => array( 'title' => __('Ordered list (Alt + Shift + O)'), 'both' => false ),
    1216                         'blockquote' => array( 'title' => __('Blockquote (Alt + Shift + Q)'), 'both' => false ),
    1217                         'wp-media-library' => array( 'title' => __('Media library (Alt + Shift + M)'), 'both' => true ),
    1218                         'link' => array( 'title' => __('Insert/edit link (Alt + Shift + A)'), 'both' => true ),
    1219                         'unlink' => array( 'title' => __('Unlink (Alt + Shift + S)'), 'both' => false ),
    1220                         'help' => array( 'title' => __('Help (Alt + Shift + H)'), 'both' => false ),
    1221                 );
    1222 
    1223                 /**
    1224                  * Filter the list of TinyMCE buttons for the fullscreen
    1225                  * 'Distraction Free Writing' editor.
    1226                  *
    1227                  * @since 3.2.0
    1228                  *
    1229                  * @param array $buttons An array of TinyMCE buttons for the DFW editor.
    1230                  */
    1231                 $buttons = apply_filters( 'wp_fullscreen_buttons', $buttons );
    1232 
    1233                 foreach ( $buttons as $button => $args ) {
    1234                         if ( 'separator' == $args ) {
    1235                                 continue;
    1236                         }
    1237 
    1238                         $onclick = ! empty( $args['onclick'] ) ? ' onclick="' . $args['onclick'] . '"' : '';
    1239                         $title = esc_attr( $args['title'] );
    1240                         ?>
    1241 
    1242                         <div class="mce-widget mce-btn<?php if ( $args['both'] ) { ?> wp-fullscreen-both<?php } ?>">
    1243                         <button type="button" aria-label="<?php echo $title; ?>" title="<?php echo $title; ?>"<?php echo $onclick; ?> id="wp_fs_<?php echo $button; ?>">
    1244                                 <i class="mce-ico mce-i-<?php echo $button; ?>"></i>
    1245                         </button>
    1246                         </div>
    1247                         <?php
    1248                 }
    1249 
    1250                 ?>
    1251 
    1252                 </div></div>
    1253 
    1254                 <div id="wp-fullscreen-save">
    1255                         <input type="button" class="button button-primary right" value="<?php echo $save; ?>" onclick="wp.editor.fullscreen.save();" />
    1256                         <span class="wp-fullscreen-saved-message"><?php if ( $post->post_status == 'publish' ) _e('Updated.'); else _e('Saved.'); ?></span>
    1257                         <span class="wp-fullscreen-error-message"><?php _e('Save failed.'); ?></span>
    1258                         <span class="spinner"></span>
    1259                 </div>
    1260 
    1261                 </div>
    1262                 </div>
    1263         </div>
    1264         <div id="wp-fullscreen-statusbar">
    1265                 <div id="wp-fullscreen-status">
    1266                         <div id="wp-fullscreen-count"><?php printf( __( 'Word count: %s' ), '<span class="word-count">0</span>' ); ?></div>
    1267                         <div id="wp-fullscreen-tagline"><?php _e('Just write.'); ?></div>
    1268                 </div>
    1269         </div>
    1270         </div>
    1271 
    1272         <div class="fullscreen-overlay" id="fullscreen-overlay"></div>
    1273         <div class="fullscreen-overlay fullscreen-fader fade-300" id="fullscreen-fader"></div>
    1274         <?php
    1275         }
    1276 
    12771163        /**
    12781164         * Performs post queries for internal linking.
    12791165         *
  • src/wp-includes/css/editor.css

     
    192192        cursor: pointer;
    193193}
    194194
    195 #wp-fullscreen-buttons .mce-btn,
    196195.mce-toolbar .mce-btn-group .mce-btn,
    197196.qt-fullscreen {
    198197        border: 1px solid transparent;
     
    204203        filter: none;
    205204}
    206205
    207 #wp-fullscreen-buttons .mce-btn:hover,
    208206.mce-toolbar .mce-btn-group .mce-btn:hover,
    209 #wp-fullscreen-buttons .mce-btn:focus,
    210207.mce-toolbar .mce-btn-group .mce-btn:focus,
    211208.qt-fullscreen:hover,
    212209.qt-fullscreen:focus {
     
    215212        color: #222;
    216213        -webkit-box-shadow: inset 0 1px 0 #fff, 0 1px 0 rgba( 0, 0, 0, 0.08 );
    217214        box-shadow: inset 0 1px 0 #fff, 0 1px 0 rgba( 0, 0, 0, 0.08 );
     215        outline: none;
    218216}
    219217
    220218.mce-toolbar .mce-btn-group .mce-btn.mce-active,
    221 #wp-fullscreen-buttons .mce-btn.mce-active,
    222219.mce-toolbar .mce-btn-group .mce-btn:active,
    223 #wp-fullscreen-buttons .mce-btn:active {
     220.qt-fullscreen.active {
    224221        background: #ebebeb;
    225222        border-color: #999;
    226223        -webkit-box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, 0.3 );
     
    236233}
    237234
    238235.mce-toolbar .mce-btn-group .mce-btn.mce-disabled:hover,
    239 #wp-fullscreen-buttons .mce-btn.mce-disabled:hover,
    240 .mce-toolbar .mce-btn-group .mce-btn.mce-disabled:focus,
    241 #wp-fullscreen-buttons .mce-btn.mce-disabled:focus {
     236.mce-toolbar .mce-btn-group .mce-btn.mce-disabled:focus {
    242237        color: #aaa;
    243238        background: none;
    244239        border-color: #ddd;
     
    601596i.mce-i-strikethrough,
    602597i.mce-i-spellchecker,
    603598i.mce-i-fullscreen,
    604 i.mce-i-wp_fullscreen,
     599i.mce-i-dfw,
    605600i.mce-i-wp_adv,
    606601i.mce-i-underline,
    607602i.mce-i-alignjustify,
     
    693688}
    694689
    695690i.mce-i-fullscreen:before,
    696 i.mce-i-wp_fullscreen:before,
     691i.mce-i-dfw:before,
    697692.qt-fullscreen:before {
    698693        content: '\f211';
    699694}
     
    970965        font-weight: bold;
    971966}
    972967
    973 .mce-toolbar .mce-btn-group .mce-btn.mce-wp-fullscreen,
     968.mce-toolbar .mce-btn-group .mce-btn.mce-wp-dfw,
    974969.qt-fullscreen {
    975970        position: absolute;
    976971        top: 0;
     
    984979                padding: 6px 7px;
    985980        }
    986981
    987         #wp-fullscreen-buttons .mce-btn,
    988982        .mce-toolbar .mce-btn-group .mce-btn {
    989983                margin: 1px;
    990984        }
     
    994988                height: 34px;
    995989        }
    996990
    997         .mce-toolbar .mce-btn-group .mce-btn.mce-wp-fullscreen {
     991        .mce-toolbar .mce-btn-group .mce-btn.mce-wp-dfw {
    998992                margin: 4px 4px 0 0;
    999993        }
    1000994
     
    15691563        color: #2ea2cc;
    15701564}
    15711565*/
    1572 /* Distraction Free Writing mode
    1573  * =Overlay Styles
    1574 -------------------------------------------------------------- */
    1575 .fullscreen-overlay {
    1576         z-index: 100005;
    1577         display: none;
    1578         position: fixed;
    1579         top: 0;
    1580         bottom: 0;
    1581         left: 0;
    1582         right: 0;
    1583         -webkit-filter: inherit;
    1584         filter: inherit;
    1585 }
    1586 
    1587 .wp-fullscreen-active .fullscreen-overlay,
    1588 .wp-fullscreen-active #wp-fullscreen-body {
    1589         display: block;
    1590 }
    15911566
    1592 .fullscreen-fader {
    1593         z-index: 200000;
    1594 }
    1595 
    1596 .wp-fullscreen-active .fullscreen-fader,
    1597 .wp-core-ui.wp-fullscreen-active .postbox-container {
    1598         display: none;
    1599 }
    1600 
    1601 /* =Overlay Body
    1602 -------------------------------------------------------------- */
    1603 
    1604 #wp-fullscreen-body,
    16051567.mce-fullscreen {
    16061568        z-index: 100010;
    16071569}
    16081570
    1609 #wp-fullscreen-body {
    1610         display: none;
    1611 }
    1612 
    1613 .wp-fullscreen-wrap {
    1614         margin: 0;
    1615         padding: 0;
    1616         position: absolute;
    1617         left: 0;
    1618         right: 0;
    1619         bottom: 30px;
    1620         top: 60px;
    1621         z-index: 100015;
    1622 }
    1623 
    1624 .wp-fullscreen-wrap .wp-editor-container,
    1625 .wp-fullscreen-title,
    1626 #wp-fullscreen-central-toolbar {
    1627         -webkit-box-sizing: border-box;
    1628         -moz-box-sizing: border-box;
    1629         box-sizing: border-box;
    1630         max-width: 100%;
    1631 }
    1632 
    1633 .wp-fullscreen-active .wp-editor-tools,
    1634 .wp-fullscreen-active .quicktags-toolbar,
    1635 .wp-fullscreen-active .mce-toolbar-grp,
    1636 .wp-fullscreen-active .mce-statusbar {
    1637         display: none;
    1638 }
    1639 
    1640 #wp-fullscreen-statusbar {
    1641         position: fixed;
    1642         left: 0;
    1643         right: 0;
    1644         bottom: 0;
    1645         height: 30px;
    1646         z-index: 100020;
    1647         background: #fff;
    1648         -webkit-transition: height 0.2s;
    1649         transition: height 0.2s;
    1650 }
    1651 
    1652 #wp-fullscreen-status {
    1653         margin: 0 auto;
    1654         padding: 0;
    1655 }
    1656 
    1657 .wp-fullscreen-active .wp-fullscreen-title,
    1658 .wp-fullscreen-active .wp-fullscreen-title:focus,
    1659 .wp-fullscreen-active .wp-editor-container {
    1660         -webkit-border-radius: 0;
    1661         border-radius: 0;
    1662         border: 1px dashed transparent;
    1663         background: transparent;
    1664         -webkit-box-shadow: none;
    1665         box-shadow: none;
    1666         -webkit-transition: border-color 0.4s;
    1667         transition: border-color 0.4s;
    1668 }
    1669 
    1670 .wp-fullscreen-active .wp-editor-container {
    1671         margin: 0 auto 40px;
    1672 }
    1673 
    1674 .wp-fullscreen-active .wp-fullscreen-title {
    1675         font-size: 1.7em;
    1676         line-height: 100%;
    1677         outline: medium none;
    1678         padding: 3px 7px;
    1679         margin: 10px auto 30px;
    1680         display: block;
    1681 }
    1682 
    1683 #wp-fullscreen-tagline {
    1684         color: #888;
    1685         font-size: 18px;
    1686         float: right;
    1687         padding: 4px 0 0;
    1688 }
    1689 
    1690 /* =Top bar
     1571/* =DFW
    16911572-------------------------------------------------------------- */
    1692 #fullscreen-topbar {
    1693         background: #f5f5f5;
    1694         border-bottom: 1px solid #dedede;
    1695         height: 45px;
    1696         position: fixed;
    1697         left: 0;
    1698         right: 0;
    1699         top: 0;
    1700         width: 100%;
    1701         z-index: 100020;
    1702         -webkit-transition: opacity 0.4s;
    1703         transition: opacity 0.4s;
    1704 }
    1705 
    1706 #wp-fullscreen-toolbar {
    1707         padding: 6px 10px 0;
    1708         clear: both;
    1709         max-width: 1100px;
    1710         margin: 0 auto;
    1711 }
    1712 
    1713 #wp-fullscreen-mode-bar,
    1714 #wp-fullscreen-button-bar,
    1715 #wp-fullscreen-close {
    1716         float: left;
    1717 }
    1718 
    1719 #wp-fullscreen-count,
    1720 #wp-fullscreen-tagline {
    1721         display: inline-block;
    1722 }
    17231573
    1724 #wp-fullscreen-button-bar {
    1725         margin-top: 2px;
    1726 }
    1727 
    1728 #wp-fullscreen-save {
    1729         float: right;
    1730         padding: 2px 0 0;
    1731         min-width: 95px;
    1732 }
    1733 
    1734 #wp-fullscreen-count,
    1735 #wp-fullscreen-close {
    1736         padding: 5px 0 0;
    1737 }
    1738 
    1739 #wp-fullscreen-central-toolbar {
    1740         margin: auto;
    1741         padding: 0;
    1742         min-width: 620px;
    1743 }
    1744 
    1745 #wp-fullscreen-buttons > div {
    1746         float: left;
    1747 }
    1748 
    1749 #wp-fullscreen-mode-bar {
    1750         padding: 3px 14px 0 0;
    1751 }
    1752 
    1753 #wp-fullscreen-buttons .hidden {
    1754         display: none;
    1755 }
    1756 
    1757 #wp-fullscreen-buttons .disabled {
    1758         opacity: 0.5;
    1759 }
    1760 
    1761 #wp-fullscreen-buttons .mce-btn button {
    1762     margin: 0;
    1763     outline: 0 none;
    1764     border: 0 none;
    1765     white-space: nowrap;
    1766     width: auto;
    1767     background: none;
    1768         color: #333333;
    1769     cursor: pointer;
    1770     font-size: 18px;
    1771     line-height: 20px;
    1772     overflow: visible;
    1773     text-align: center;
    1774     -webkit-box-sizing: border-box;
    1775     -moz-box-sizing: border-box;
    1776     box-sizing: border-box;
    1777 }
    1778 
    1779 .wp-html-mode #wp-fullscreen-buttons div {
    1780         display: none;
    1781 }
    1782 
    1783 .wp-html-mode #wp-fullscreen-buttons div.wp-fullscreen-both {
    1784         display: block;
    1785 }
    1786 
    1787 #wp-fullscreen-save img {
    1788         vertical-align: middle;
    1789 }
    1790 
    1791 #wp-fullscreen-save span {
    1792         display: none;
    1793         margin: 5px 6px 0;
    1794         float: left;
    1795 }
    1796 
    1797 /* =Thickbox Adjustments
    1798 -------------------------------------------------------------- */
    1799 .wp-fullscreen-active #TB_overlay {
    1800         z-index: 100050;
    1801 }
    1802 
    1803 .wp-fullscreen-active #TB_window {
    1804         z-index: 100051;
    1805 }
    1806 
    1807 /* Colors */
    1808 .fullscreen-overlay {
    1809         background: #fff;
    1810 }
    1811 
    1812 /* =CSS 3 transitions
    1813 -------------------------------------------------------------- */
    1814 
    1815 .wp-fullscreen-active #fullscreen-topbar {
    1816         -webkit-transition-duration: 0.8s;
    1817         transition-duration: 0.8s;
     1574.focus-on .wrap > h2,
     1575.focus-on #wpfooter,
     1576.focus-on .postbox-container,
     1577.focus-on div.updated,
     1578.focus-on div.error,
     1579.focus-on #wp-toolbar {
    18181580        opacity: 0;
    1819         filter: alpha(opacity=0);
    1820 }
    1821 
    1822 .wp-fullscreen-active #wp-fullscreen-statusbar {
    1823         height: 0;
     1581        transition-duration: 0.6s;
     1582        transition-property: opacity;
     1583        transition-timing-function: ease-in-out;
    18241584}
    18251585
    1826 .wp-fullscreen-active.wp-dfw-show-ui #fullscreen-topbar {
    1827         -webkit-transition-duration: 0.4s;
    1828         transition-duration: 0.4s;
     1586.focus-off .wrap > h2,
     1587.focus-off #wpfooter,
     1588.focus-off .postbox-container,
     1589.focus-off div.updated,
     1590.focus-off div.error,
     1591.focus-off #wp-toolbar {
    18291592        opacity: 1;
    1830         filter: alpha(opacity=100);
    1831 }
    1832 
    1833 .wp-fullscreen-active.wp-dfw-show-ui #wp-fullscreen-statusbar {
    1834         height: 29px;
    1835         background: #f8f8f8;
    1836         border-top: 1px solid #eee;
    1837 }
    1838 
    1839 .wp-fullscreen-active .wp-fullscreen-title,
    1840 .wp-fullscreen-active .wp-editor-container {
    1841         -webkit-transition-duration: 0.8s;
    1842         transition-duration: 0.8s;
    1843         border-color: transparent;
    1844 }
    1845 
    1846 .wp-fullscreen-active.wp-dfw-show-ui .wp-fullscreen-title,
    1847 .wp-fullscreen-active.wp-dfw-show-ui .wp-editor-container {
    1848         -webkit-transition-duration: 0.4s;
    1849         transition-duration: 0.4s;
    1850         border-color: #ccc;
    1851 }
    1852 
    1853 .fade-1000,
    1854 .fade-600,
    1855 .fade-400,
    1856 .fade-300 {
    1857         opacity: 0;
    1858         -webkit-transition-property: opacity;
     1593        transition-duration: 0.2s;
    18591594        transition-property: opacity;
     1595        transition-timing-function: ease-in-out;
    18601596}
    18611597
    1862 .fade-1000 {
    1863         -webkit-transition-duration: 1s;
    1864         transition-duration: 1s;
    1865 }
    1866 
    1867 .fade-600 {
    1868         -webkit-transition-duration: 0.6s;
     1598.focus-on #adminmenuback,
     1599.focus-on #adminmenuwrap,
     1600.focus-on .screen-meta-toggle {
    18691601        transition-duration: 0.6s;
     1602        transition-property: transform;
     1603        transition-timing-function: ease-in-out;
    18701604}
    18711605
    1872 .fade-400 {
    1873         -webkit-transition-duration: 0.4s;
    1874         transition-duration: 0.4s;
    1875 }
    1876 
    1877 .fade-300 {
    1878         -webkit-transition-duration: 0.3s;
    1879         transition-duration: 0.3s;
     1606.focus-on #adminmenuback,
     1607.focus-on #adminmenuwrap {
     1608        transform: translateX( -100% );
    18801609}
    18811610
    1882 .fade-trigger {
    1883         opacity: 1;
    1884 }
    1885 
    1886 /* DFW on touch screen devices */
    1887 .wp-dfw-touch #fullscreen-topbar {
    1888         position: absolute;
    1889         opacity: 1;
    1890 }
    1891 
    1892 .wp-dfw-touch .wp-fullscreen-wrap .wp-editor-container,
    1893 .wp-dfw-touch .wp-fullscreen-title {
    1894         max-width: 700px;
    1895 }
    1896 
    1897 .wp-fullscreen-active.wp-dfw-touch  .wp-fullscreen-title,
    1898 .wp-fullscreen-active.wp-dfw-touch .wp-editor-container {
    1899         border-color: #ccc;
    1900 }
    1901 
    1902 .wp-dfw-touch #wp-fullscreen-statusbar {
    1903         height: 30px;
    1904 }
    1905 
    1906 @media screen and ( max-width: 782px ) {
    1907         #wp-fullscreen-close,
    1908         #wp-fullscreen-central-toolbar,
    1909         #wp-fullscreen-mode-bar,
    1910         #wp-fullscreen-button-bar,
    1911         #wp-fullscreen-save {
    1912                 display: inline-block;
    1913         }
    1914 
    1915         #fullscreen-topbar {
    1916                 height: 85px;
    1917         }
    1918 
    1919         #wp-fullscreen-central-toolbar {
    1920                 width: auto !important;
    1921                 min-width: 0;
    1922         }
    1923 
    1924         #wp-fullscreen-close {
    1925                 line-height: 30px;
    1926                 vertical-align: top;
    1927                 padding: 0 12px;
    1928         }
    1929 
    1930         #wp-fullscreen-button-bar {
    1931                 position: absolute;
    1932                 top: 45px;
    1933                 left: 0;
    1934         }
    1935 
    1936         .wp-fullscreen-wrap {
    1937                 top: 95px;
    1938         }
    1939 
    1940         #wp-fullscreen-save {
    1941                 position: absolute;
    1942                 right: 10px;
    1943         }
     1611.focus-on .screen-meta-toggle {
     1612        transform: translateY( -100% );
    19441613}
    19451614
    1946 @media screen and ( max-width: 480px ) {
    1947         #wp_fs_help {
    1948                 display: none;
    1949         }
    1950 
    1951         .wp-fullscreen-wrap .wp-editor-container,
    1952         .wp-fullscreen-title {
    1953                 width: 480px !important;
    1954         }
    1955 
    1956         body.wp-fullscreen-active {
    1957                 width: 480px;
    1958                 overflow: auto;
    1959         }
    1960 
    1961         #fullscreen-topbar,
    1962         .wp-fullscreen-wrap {
    1963                 width: 480px;
    1964         }
    1965 
    1966         #fullscreen-topbar {
    1967                 position: absolute;
    1968         }
    1969 
    1970         #wp-fullscreen-status {
    1971                 width: auto !important;
    1972                 max-width: 100%;
    1973                 padding: 0 10px;
    1974         }
     1615.focus-off #adminmenuback,
     1616.focus-off #adminmenuwrap,
     1617.focus-off .screen-meta-toggle {
     1618        transform: translateX( 0 );
     1619        transition-duration: 0.2s;
     1620        transition-property: transform;
     1621        transition-timing-function: ease-in-out;
    19751622}
    19761623
    19771624/* =Localization
     
    20011648  (-o-min-device-pixel-ratio: 5/4),
    20021649  (-webkit-min-device-pixel-ratio: 1.25),
    20031650  (min-resolution: 120dpi) {
    2004         .wp-media-buttons .add_media span.wp-media-buttons-icon,
    2005         #wp-fullscreen-buttons #wp_fs_image span.mce_image {
     1651        .wp-media-buttons .add_media span.wp-media-buttons-icon {
    20061652                background: none;
    20071653        }
    20081654}