Make WordPress Core

Ticket #38342: 38342-2.diff

File 38342-2.diff, 23.5 KB (added by aduth, 8 years ago)
  • src/wp-admin/css/dashboard.css

    diff --git src/wp-admin/css/dashboard.css src/wp-admin/css/dashboard.css
    index 72b0230..8509be5 100644
    form.initial-form.quickpress-open input#title { 
    541541        margin: 0 12px;
    542542}
    543543
     544#dashboard_quick_press .drafts ul.is-placeholder li {
     545        padding: 3px 0;
     546        color: transparent;
     547}
     548
     549@keyframes loading-fade {
     550        0% { opacity: .5; }
     551        50% { opacity: 1; }
     552        100% { opacity: .5; }
     553}
     554
     555#dashboard_quick_press .drafts ul.is-placeholder li:before,
     556#dashboard_quick_press .drafts ul.is-placeholder li:after {
     557        content: '';
     558        display: block;
     559        height: 13px;
     560        background: #eee;
     561        animation: loading-fade 1.6s ease-in-out infinite;
     562}
     563
     564#dashboard_quick_press .drafts ul.is-placeholder li:before {
     565        margin-bottom: 5px;
     566        width: 40%;
     567}
     568
     569#dashboard_quick_press .drafts ul.is-placeholder li:after {
     570        width: 80%;
     571}
     572
    544573#dashboard_quick_press .drafts li {
    545574        margin-bottom: 1em;
    546575}
     576
     577#dashboard_quick_press .drafts li.is-new {
     578        background-color: #fffbe5;
     579}
     580
    547581#dashboard_quick_press .drafts li time {
    548582        color: #72777c;
    549583}
  • src/wp-admin/includes/dashboard.php

    diff --git src/wp-admin/includes/dashboard.php src/wp-admin/includes/dashboard.php
    index aab5976..b472072 100644
    function wp_dashboard_quick_press( $error_msg = false ) { 
    491491        $post_ID = (int) $post->ID;
    492492?>
    493493
    494         <form name="post" action="<?php echo esc_url( admin_url( 'post.php' ) ); ?>" method="post" id="quick-press" class="initial-form hide-if-no-js">
    495 
    496                 <?php if ( $error_msg ) : ?>
    497                 <div class="error"><?php echo $error_msg; ?></div>
    498                 <?php endif; ?>
     494        <form name="post" method="post" id="quick-press" class="initial-form hide-if-no-js">
    499495
    500496                <div class="input-text-wrap" id="title-wrap">
    501                         <label class="screen-reader-text prompt" for="title" id="title-prompt-text">
     497                        <label class="prompt" for="title" id="title-prompt-text">
    502498
    503499                                <?php
    504500                                /** This filter is documented in wp-admin/edit-form-advanced.php */
    505501                                echo apply_filters( 'enter_title_here', __( 'Title' ), $post );
    506502                                ?>
    507503                        </label>
    508                         <input type="text" name="post_title" id="title" autocomplete="off" />
     504                        <input type="text" name="title" id="title" autocomplete="off" />
    509505                </div>
    510506
    511507                <div class="textarea-wrap" id="description-wrap">
    512                         <label class="screen-reader-text prompt" for="content" id="content-prompt-text"><?php _e( 'What&#8217;s on your mind?' ); ?></label>
     508                        <label class="prompt" for="content" id="content-prompt-text"><?php _e( 'What&#8217;s on your mind?' ); ?></label>
    513509                        <textarea name="content" id="content" class="mceEditor" rows="3" cols="15" autocomplete="off"></textarea>
    514510                </div>
    515 
    516511                <p class="submit">
    517                         <input type="hidden" name="action" id="quickpost-action" value="post-quickdraft-save" />
    518                         <input type="hidden" name="post_ID" value="<?php echo $post_ID; ?>" />
    519                         <input type="hidden" name="post_type" value="post" />
    520                         <?php wp_nonce_field( 'add-post' ); ?>
     512                        <div class="error inline" style="display: none;"><p></p></div>
     513                        <div class="spinner no-float"></div>
    521514                        <?php submit_button( __( 'Save Draft' ), 'primary', 'save', false, array( 'id' => 'save-post' ) ); ?>
    522515                        <br class="clear" />
    523516                </p>
    function wp_dashboard_quick_press( $error_msg = false ) { 
    531524 * Show recent drafts of the user on the dashboard.
    532525 *
    533526 * @since 2.7.0
    534  *
    535  * @param array $drafts
    536527 */
    537 function wp_dashboard_recent_drafts( $drafts = false ) {
    538         if ( ! $drafts ) {
    539                 $query_args = array(
    540                         'post_type'      => 'post',
    541                         'post_status'    => 'draft',
    542                         'author'         => get_current_user_id(),
    543                         'posts_per_page' => 4,
    544                         'orderby'        => 'modified',
    545                         'order'          => 'DESC'
    546                 );
    547 
    548                 /**
    549                  * Filters the post query arguments for the 'Recent Drafts' dashboard widget.
    550                  *
    551                  * @since 4.4.0
    552                  *
    553                  * @param array $query_args The query arguments for the 'Recent Drafts' dashboard widget.
    554                  */
    555                 $query_args = apply_filters( 'dashboard_recent_drafts_query_args', $query_args );
    556 
    557                 $drafts = get_posts( $query_args );
    558                 if ( ! $drafts ) {
    559                         return;
    560                 }
    561         }
    562 
    563         echo '<div class="drafts">';
    564         if ( count( $drafts ) > 3 ) {
    565                 echo '<p class="view-all"><a href="' . esc_url( admin_url( 'edit.php?post_status=draft' ) ) . '" aria-label="' . __( 'View all drafts' ) . '">' . _x( 'View all', 'drafts' ) . "</a></p>\n";
    566         }
    567         echo '<h2 class="hide-if-no-js">' . __( 'Drafts' ) . "</h2>\n<ul>";
    568 
    569         $drafts = array_slice( $drafts, 0, 3 );
    570         foreach ( $drafts as $draft ) {
    571                 $url = get_edit_post_link( $draft->ID );
    572                 $title = _draft_or_post_title( $draft->ID );
    573                 echo "<li>\n";
    574                 /* translators: %s: post title */
    575                 echo '<div class="draft-title"><a href="' . esc_url( $url ) . '" aria-label="' . esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ) . '">' . esc_html( $title ) . '</a>';
    576                 echo '<time datetime="' . get_the_time( 'c', $draft ) . '">' . get_the_time( __( 'F j, Y' ), $draft ) . '</time></div>';
    577                 if ( $the_content = wp_trim_words( $draft->post_content, 10 ) ) {
    578                         echo '<p>' . $the_content . '</p>';
    579                 }
    580                 echo "</li>\n";
    581         }
     528function wp_dashboard_recent_drafts() {
     529        echo '<div id="quick-press-drafts" class="drafts">';
     530        echo '<p class="view-all" style="display: none;"><a href="' . esc_url( admin_url( 'edit.php?post_status=draft' ) ) . '" aria-label="' . __( 'View all drafts' ) . '">' . _x( 'View all', 'drafts' ) . "</a></p>\n";
     531        echo '<h2 class="hide-if-no-js">' . __( 'Drafts' ) . "</h2>\n";
     532        echo '<script id="tmpl-item-quick-press-draft" type="text/template">';
     533        /* translators: %s: post title */
     534        echo '<div class="draft-title"><a href="post.php?post={{ data.id }}&action=edit" aria-label="' . esc_attr( __( 'Edit Post' ) ) . '">{{ data.title }}</a>';
     535        echo '<time datetime="{{ data.date }}">{{ data.formattedDate }}</time></div>';
     536        echo '{{{ data.formattedContent }}}';
     537        echo '</script>';
     538        echo '<ul class="drafts-list is-placeholder">';
     539        for ( $i = 0; $i < 4; $i++ ) {
     540                echo '<li><span class="screen-reader-text">' . esc_html( __( 'Loading…' ) ) . '</span></li>';
     541        }
    582542        echo "</ul>\n</div>";
    583543}
    584544
  • src/wp-admin/js/dashboard.js

    diff --git src/wp-admin/js/dashboard.js src/wp-admin/js/dashboard.js
    index fa100dd..253c444 100644
     
    1 /* global pagenow, ajaxurl, postboxes, wpActiveEditor:true */
    2 var ajaxWidgets, ajaxPopulateWidgets, quickPressLoad;
     1/* global _, wp, quickPress, pagenow, ajaxurl, postboxes, wpActiveEditor:true */
     2var ajaxWidgets, ajaxPopulateWidgets;
    33
    4 jQuery(document).ready( function($) {
     4jQuery( document ).ready( function( $ ) {
    55        var welcomePanel = $( '#welcome-panel' ),
    6                 welcomePanelHide = $('#wp_welcome_panel-hide'),
     6                welcomePanelHide = $( '#wp_welcome_panel-hide' ),
    77                updateWelcomePanel;
    88
    99        updateWelcomePanel = function( visible ) {
    jQuery(document).ready( function($) { 
    1111                        action: 'update-welcome-panel',
    1212                        visible: visible,
    1313                        welcomepanelnonce: $( '#welcomepanelnonce' ).val()
    14                 });
     14                } );
    1515        };
    1616
    17         if ( welcomePanel.hasClass('hidden') && welcomePanelHide.prop('checked') ) {
    18                 welcomePanel.removeClass('hidden');
     17        if ( welcomePanel.hasClass( 'hidden' ) && welcomePanelHide.prop( 'checked' ) ) {
     18                welcomePanel.removeClass( 'hidden' );
    1919        }
    2020
    21         $('.welcome-panel-close, .welcome-panel-dismiss a', welcomePanel).click( function(e) {
     21        $( '.welcome-panel-close, .welcome-panel-dismiss a', welcomePanel).click( function(e) {
    2222                e.preventDefault();
    23                 welcomePanel.addClass('hidden');
     23                welcomePanel.addClass( 'hidden' );
    2424                updateWelcomePanel( 0 );
    25                 $('#wp_welcome_panel-hide').prop('checked', false);
    26         });
     25                $( '#wp_welcome_panel-hide' ).prop( 'checked', false);
     26        } );
    2727
    2828        welcomePanelHide.click( function() {
    29                 welcomePanel.toggleClass('hidden', ! this.checked );
     29                welcomePanel.toggleClass( 'hidden', ! this.checked );
    3030                updateWelcomePanel( this.checked ? 1 : 0 );
    31         });
     31        } );
    3232
    3333        // These widgets are sometimes populated via ajax
    3434        ajaxWidgets = ['dashboard_primary'];
    3535
    3636        ajaxPopulateWidgets = function(el) {
    3737                function show(i, id) {
    38                         var p, e = $('#' + id + ' div.inside:visible').find('.widget-loading');
     38                        var p, e = $( '#' + id + ' div.inside:visible' ).find( '.widget-loading' );
    3939                        if ( e.length ) {
    4040                                p = e.parent();
    4141                                setTimeout( function(){
    4242                                        p.load( ajaxurl + '?action=dashboard-widgets&widget=' + id + '&pagenow=' + pagenow, '', function() {
    43                                                 p.hide().slideDown('normal', function(){
    44                                                         $(this).css('display', '');
    45                                                 });
    46                                         });
     43                                                p.hide().slideDown( 'normal', function(){
     44                                                        $(this).css( 'display', '' );
     45                                                } );
     46                                        } );
    4747                                }, i * 500 );
    4848                        }
    4949                }
    jQuery(document).ready( function($) { 
    6161
    6262        postboxes.add_postbox_toggles(pagenow, { pbshow: ajaxPopulateWidgets } );
    6363
    64         /* QuickPress */
    65         quickPressLoad = function() {
    66                 var act = $('#quickpost-action'), t;
    67 
    68                 $( '#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]' ).prop( 'disabled' , false );
    69 
    70                 t = $('#quick-press').submit( function( e ) {
    71                         e.preventDefault();
    72                         $('#dashboard_quick_press #publishing-action .spinner').show();
    73                         $('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').prop('disabled', true);
    74 
    75                         $.post( t.attr( 'action' ), t.serializeArray(), function( data ) {
    76                                 // Replace the form, and prepend the published post.
    77                                 $('#dashboard_quick_press .inside').html( data );
    78                                 $('#quick-press').removeClass('initial-form');
    79                                 quickPressLoad();
    80                                 highlightLatestPost();
    81                                 $('#title').focus();
    82                         });
    83 
    84                         function highlightLatestPost () {
    85                                 var latestPost = $('.drafts ul li').first();
    86                                 latestPost.css('background', '#fffbe5');
    87                                 setTimeout(function () {
    88                                         latestPost.css('background', 'none');
    89                                 }, 1000);
    90                         }
    91                 } );
    92 
    93                 $('#publish').click( function() { act.val( 'post-quickpress-publish' ); } );
    94 
    95                 $('#title, #tags-input, #content').each( function() {
    96                         var input = $(this), prompt = $('#' + this.id + '-prompt-text');
    97 
    98                         if ( '' === this.value ) {
    99                                 prompt.removeClass('screen-reader-text');
    100                         }
    101 
    102                         prompt.click( function() {
    103                                 $(this).addClass('screen-reader-text');
    104                                 input.focus();
    105                         });
    106 
    107                         input.blur( function() {
    108                                 if ( '' === this.value ) {
    109                                         prompt.removeClass('screen-reader-text');
    110                                 }
    111                         });
    112 
    113                         input.focus( function() {
    114                                 prompt.addClass('screen-reader-text');
    115                         });
    116                 });
    117 
    118                 $('#quick-press').on( 'click focusin', function() {
    119                         wpActiveEditor = 'content';
    120                 });
    121 
    122                 autoResizeTextarea();
    123         };
    124         quickPressLoad();
    125 
    12664        $( '.meta-box-sortables' ).sortable( 'option', 'containment', '#wpwrap' );
    12765
    12866        function autoResizeTextarea() {
    jQuery(document).ready( function($) { 
    13169                }
    13270
    13371                // Add a hidden div. We'll copy over the text from the textarea to measure its height.
    134                 $('body').append( '<div class="quick-draft-textarea-clone" style="display: none;"></div>' );
     72                $( 'body' ).append( '<div class="quick-draft-textarea-clone" style="display: none;"></div>' );
    13573
    136                 var clone = $('.quick-draft-textarea-clone'),
    137                         editor = $('#content'),
     74                var clone = $( '.quick-draft-textarea-clone' ),
     75                        editor = $( '#content' ),
    13876                        editorHeight = editor.height(),
    13977                        // 100px roughly accounts for browser chrome and allows the
    14078                        // save draft button to show on-screen at the same time.
    jQuery(document).ready( function($) { 
    14280
    14381                // Match up textarea and clone div as much as possible.
    14482                // Padding cannot be reliably retrieved using shorthand in all browsers.
    145                 clone.css({
    146                         'font-family': editor.css('font-family'),
    147                         'font-size':   editor.css('font-size'),
    148                         'line-height': editor.css('line-height'),
    149                         'padding-bottom': editor.css('paddingBottom'),
    150                         'padding-left': editor.css('paddingLeft'),
    151                         'padding-right': editor.css('paddingRight'),
    152                         'padding-top': editor.css('paddingTop'),
     83                clone.css( {
     84                        'font-family': editor.css( 'font-family' ),
     85                        'font-size':   editor.css( 'font-size' ),
     86                        'line-height': editor.css( 'line-height' ),
     87                        'padding-bottom': editor.css( 'paddingBottom' ),
     88                        'padding-left': editor.css( 'paddingLeft' ),
     89                        'padding-right': editor.css( 'paddingRight' ),
     90                        'padding-top': editor.css( 'paddingTop' ),
    15391                        'white-space': 'pre-wrap',
    15492                        'word-wrap': 'break-word',
    15593                        'display': 'none'
    156                 });
     94                } );
    15795
    15896                // propertychange is for IE < 9
    159                 editor.on('focus input propertychange', function() {
     97                editor.on( 'focus input propertychange', function() {
    16098                        var $this = $(this),
    16199                                // &nbsp; is to ensure that the height of a final trailing newline is included.
    162100                                textareaContent = $this.val() + '&nbsp;',
    163101                                // 2px is for border-top & border-bottom
    164                                 cloneHeight = clone.css('width', $this.css('width')).text(textareaContent).outerHeight() + 2;
     102                                cloneHeight = clone.css( 'width', $this.css( 'width' )).text(textareaContent).outerHeight() + 2;
    165103
    166104                        // Default to having scrollbars
    167                         editor.css('overflow-y', 'auto');
     105                        editor.css( 'overflow-y', 'auto' );
    168106
    169107                        // Only change the height if it has indeed changed and both heights are below the max.
    170108                        if ( cloneHeight === editorHeight || ( cloneHeight >= editorMaxHeight && editorHeight >= editorMaxHeight ) ) {
    jQuery(document).ready( function($) { 
    180118                        }
    181119
    182120                        // No scrollbars as we change height, not for IE < 9
    183                         editor.css('overflow', 'hidden');
     121                        editor.css( 'overflow', 'hidden' );
    184122
    185                         $this.css('height', editorHeight + 'px');
    186                 });
     123                        $this.css( 'height', editorHeight + 'px' );
     124                } );
    187125        }
    188126
     127        autoResizeTextarea();
     128
     129} );
     130
     131wp.api.loadPromise.done( function() {
     132        var $ = jQuery,
     133                QuickPress = {},
     134                draftsCollection;
     135
     136        QuickPress.Models = {};
     137
     138        QuickPress.Models.Draft = wp.api.models.Post.extend( {
     139                initialize: function( attributes ) {
     140                        if ( attributes ) {
     141                                this.set( this.normalizeAttributes( attributes ) );
     142                        }
     143                },
     144
     145                parse: function( response ) {
     146                        return this.normalizeAttributes( response );
     147                },
     148
     149                normalizeAttributes: function( attributes ) {
     150                        var date;
     151
     152                        if ( ! attributes ) {
     153                                return attributes;
     154                        }
     155
     156                        if ( 'object' === typeof attributes.content ) {
     157                                attributes.content = attributes.content.rendered;
     158                        }
     159
     160                        if ( 'object' === typeof attributes.title ) {
     161                                attributes.title = attributes.title.rendered;
     162                        }
     163
     164                        attributes.formattedContent = wp.formatting.trimWords( attributes.content, 10 );
     165
     166                        date = new Date( attributes.modified_gmt );
     167
     168                        if ( 'undefined' !== typeof Intl && Intl.DateTimeFormat ) {
     169                                attributes.formattedDate = new Intl.DateTimeFormat( undefined, {
     170                                        timeZone: 'UTC',
     171                                        month: 'long',
     172                                        day: 'numeric',
     173                                        year: 'numeric'
     174                                } ).format( date );
     175                        } else {
     176                                attributes.formattedDate = date.toLocaleDateString();
     177                        }
     178
     179                        return attributes;
     180                },
     181
     182                sync: function() {
     183                        this.set( 'date_gmt', ( new Date() ).toISOString() );
     184
     185                        return wp.api.models.Post.prototype.sync.apply( this, arguments );
     186                },
     187
     188                validate: function( attributes ) {
     189                        if ( ! attributes.title && ! attributes.content ) {
     190                                return 'no-content';
     191                        }
     192                }
     193        } );
     194
     195        QuickPress.Collections = {};
     196
     197        QuickPress.Collections.Drafts = wp.api.collections.Posts.extend( {
     198                model: QuickPress.Models.Draft,
     199
     200                comparator: function( a, b ) {
     201                        return a.get( 'date' ) < b.get( 'date' );
     202                }
     203        } );
     204
     205        QuickPress.Views = {};
     206
     207        QuickPress.Views.Form = wp.Backbone.View.extend( {
     208                events: {
     209                        'click :input': 'hidePromptAndFocus',
     210                        'focus :input': 'hidePrompt',
     211                        'blur :input': 'showPrompt',
     212                        reset: 'showAllPrompts',
     213                        click: 'setActiveEditor',
     214                        focusin: 'setActiveEditor',
     215                        submit: 'submit'
     216                },
     217
     218                initialize: function() {
     219                        this.showAllPrompts();
     220
     221                        this.listenTo( this.model, 'invalid', this.render );
     222                        this.listenTo( this.model, 'error', this.showSyncError );
     223                },
     224
     225                togglePrompt: function( element, visible ) {
     226                        var $input = $( element ),
     227                                hasContent = $input.val().length > 0;
     228
     229                        $( element ).siblings( '.prompt' ).toggleClass( 'screen-reader-text', ! visible || hasContent );
     230                },
     231
     232                showAllPrompts: function() {
     233                        this.$el.find( ':input' ).each( function( i, input ) {
     234                                _.defer( this.togglePrompt.bind( this, input, true ) );
     235                        }.bind( this ) );
     236                },
     237
     238                showPrompt: function( event ) {
     239                        this.togglePrompt( event.target, true );
     240                },
     241
     242                hidePrompt: function( event ) {
     243                        this.togglePrompt( event.target, false );
     244                },
     245
     246                hidePromptAndFocus: function( event ) {
     247                        this.togglePrompt( event.target, false );
     248                        $( ':input', event.target ).focus();
     249                },
     250
     251                setActiveEditor: function() {
     252                        wpActiveEditor = 'content';
     253                },
     254
     255                showSyncError: function() {
     256                        this.syncError = true;
     257                        this.render();
     258                },
     259
     260                submit: function( event ) {
     261                        var values;
     262
     263                        delete this.syncError;
     264                        event.preventDefault();
     265
     266                        values = this.$el.serializeArray().reduce( function( memo, field ) {
     267                                memo[ field.name ] = field.value;
     268                                return memo;
     269                        }, {} );
     270
     271                        this.model.set( values );
     272                        if ( ! this.model.isValid() ) {
     273                                return;
     274                        }
     275
     276                        // Show a spinner during the callback.
     277                        $( '#quick-press .spinner' ).css( 'visibility', 'inherit' );
     278
     279                        this.model.save()
     280                                .always( function() {
     281                                        $( '#quick-press .spinner' ).css( 'visibility', 'hidden' );
     282                                } )
     283                                .success( function() {
     284                                        this.collection.add( this.model );
     285                                        this.model = new QuickPress.Models.Draft();
     286                                        this.el.reset();
     287                                }.bind( this ) );
     288                },
     289
     290                render: function() {
     291                        var $error = this.$el.find( '.error' ),
     292                                errorText;
     293
     294                        if ( this.model.validationError ) {
     295                                errorText = quickPress.l10n[ this.model.validationError ];
     296                        } else if ( this.syncError ) {
     297                                errorText = quickPress.l10n.error;
     298                        }
     299
     300                        $error.toggle( !! errorText );
     301                        if ( errorText ) {
     302                                $error.html( $( '<p />', { text: errorText } ) );
     303                        }
     304                }
     305        } );
     306
     307        QuickPress.Views.DraftList = wp.Backbone.View.extend( {
     308                initialize: function() {
     309                        this.listenTo( this.collection, 'add', this.renderNew );
     310                },
     311
     312                renderNew: function() {
     313                        var $newEl = this.render().$el.find( 'li:first' ).addClass( 'is-new' );
     314                        setTimeout( function() {
     315                                $newEl.removeClass( 'is-new' );
     316                        }, 1000 );
     317                },
     318
     319                render: function() {
     320                        var slicedCollection = this.collection.slice( 0, 4 );
     321
     322                        this.$el.toggle( this.collection.length > 0 );
     323                        this.$el.find( '.view-all' ).toggle( slicedCollection.length > 3 );
     324                        this.$el.find( '.drafts-list' )
     325                                .removeClass( 'is-placeholder' )
     326                                .html( slicedCollection.map( function( draft ) {
     327                                        return new QuickPress.Views.DraftListItem( {
     328                                                model: draft
     329                                        } ).render().el;
     330                                } ) );
     331
     332                        return this;
     333                }
     334        } );
     335
     336        QuickPress.Views.DraftListItem = wp.Backbone.View.extend( {
     337                tagName: 'li',
     338
     339                template: wp.template( 'item-quick-press-draft' ),
     340
     341                render: function() {
     342                        // TODO: Render highlight effect to new post
     343
     344                        this.$el.html( this.template( this.model.attributes ) );
     345
     346                        return this;
     347                }
     348        } );
     349
     350        draftsCollection = new QuickPress.Collections.Drafts( quickPress.data.data );
     351
     352        new QuickPress.Views.DraftList( {
     353                el: '#quick-press-drafts',
     354                collection: draftsCollection
     355        } ).render();
     356
     357        new QuickPress.Views.Form( {
     358                el: '#quick-press',
     359                model: new QuickPress.Models.Draft(),
     360                collection: draftsCollection
     361        } ).render();
    189362} );
  • src/wp-admin/post.php

    diff --git src/wp-admin/post.php src/wp-admin/post.php
    index 437d1bd..df78352 100644
    if ( ! $sendback || 
    6060}
    6161
    6262switch($action) {
    63 case 'post-quickdraft-save':
    64         // Check nonce and capabilities
    65         $nonce = $_REQUEST['_wpnonce'];
    66         $error_msg = false;
    67 
    68         // For output of the quickdraft dashboard widget
    69         require_once ABSPATH . 'wp-admin/includes/dashboard.php';
    70 
    71         if ( ! wp_verify_nonce( $nonce, 'add-post' ) )
    72                 $error_msg = __( 'Unable to submit this form, please refresh and try again.' );
    73 
    74         if ( ! current_user_can( get_post_type_object( 'post' )->cap->create_posts ) ) {
    75                 exit;
    76         }
    77 
    78         if ( $error_msg )
    79                 return wp_dashboard_quick_press( $error_msg );
    80 
    81         $post = get_post( $_REQUEST['post_ID'] );
    82         check_admin_referer( 'add-' . $post->post_type );
    83 
    84         $_POST['comment_status'] = get_default_comment_status( $post->post_type );
    85         $_POST['ping_status']    = get_default_comment_status( $post->post_type, 'pingback' );
    86 
    87         edit_post();
    88         wp_dashboard_quick_press();
    89         exit;
    90 
    9163case 'postajaxpost':
    9264case 'post':
    9365        check_admin_referer( 'add-' . $post_type );
  • src/wp-includes/js/wp-util.js

    diff --git src/wp-includes/js/wp-util.js src/wp-includes/js/wp-util.js
    index 527441d..79ab07e 100644
    window.wp = window.wp || {}; 
    121121                }
    122122        };
    123123
     124        // wp.formatting
     125        // ------
     126        //
     127        // Tools for formatting strings
     128        wp.formatting = {
     129                settings: settings.formatting || {},
     130
     131                /**
     132                 * Trims text to a certain number of words.
     133                 *
     134                 * @see wp_trim_words
     135                 *
     136                 * @param  {string}  text     Text to trim.
     137                 * @param  {?number} numWords Number of words (default: 55).
     138                 * @param  {?string} more     What to append if text needs to be trimmed (default: '…').
     139                 * @return {string}           Trimmed text.
     140                 */
     141                trimWords: function( text, numWords, more ) {
     142                        var words, separator;
     143
     144                        if ( 'undefined' === typeof numWords ) {
     145                                numWords = 55;
     146                        }
     147
     148                        if ( 'undefined' === typeof more ) {
     149                                more = wp.formatting.settings.trimWordsMore;
     150                        }
     151
     152                        text = text.replace( /[\n\r\t ]+/g, ' ' ).replace( /^ | $/g, '' );
     153
     154                        if ( wp.formatting.settings.trimWordsByCharacter ) {
     155                                separator = '';
     156                        } else {
     157                                separator = ' ';
     158                        }
     159
     160                        words = text.split( separator );
     161
     162                        if ( words.length <= numWords ) {
     163                                return words.join( separator );
     164                        }
     165
     166                        return words.slice( 0, numWords ).join( separator ) + more;
     167                }
     168        };
     169
    124170}(jQuery));
  • src/wp-includes/script-loader.php

    diff --git src/wp-includes/script-loader.php src/wp-includes/script-loader.php
    index 143bfa1..9007a9c 100644
    function wp_default_scripts( &$scripts ) { 
    333333                'ajax' => array(
    334334                        'url' => admin_url( 'admin-ajax.php', 'relative' ),
    335335                ),
     336                'formatting' => array(
     337                        'trimWordsMore'  => __( '&hellip;' ),
     338                        /*
     339                         * translators: If your word count is based on single characters (e.g. East Asian characters),
     340                         * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
     341                         * Do not translate into your own language.
     342                         */
     343                        'trimWordsByCharacter' => strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ),
     344                ),
    336345        ) );
    337346
    338347        $scripts->add( 'wp-backbone', "/wp-includes/js/wp-backbone$suffix.js", array('backbone', 'wp-util'), false, 1 );
    function wp_default_scripts( &$scripts ) { 
    716725                        'current' => __( 'Current Color' ),
    717726                ) );
    718727
    719                 $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox' ), false, 1 );
     728                $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-api', 'wp-backbone' ), false, 1 );
     729                if ( did_action( 'init' ) ) {
     730                        $dashboard_data_request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     731                        $dashboard_data_request->set_query_params( array(
     732                                'filter[post_type]' => 'post',
     733                                'status'            => 'draft',
     734                                'author'            => get_current_user_id(),
     735                                'per_page'          => 4
     736                        ) );
     737
     738                        $scripts->localize( 'dashboard', 'quickPress', array(
     739                                'data' => rest_do_request( $dashboard_data_request ),
     740                                'l10n' => array(
     741                                        'no-content' => __( 'Post content cannot be empty.' ),
     742                                        'error'      => __( 'An error has occurred. Please reload the page and try again.' )
     743                                )
     744                        ) );
     745                }
    720746
    721747                $scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" );
    722748