Ticket #38342: 38342.diff
File 38342.diff, 14.9 KB (added by , 8 years ago) |
---|
-
src/wp-admin/includes/dashboard.php
diff --git src/wp-admin/includes/dashboard.php src/wp-admin/includes/dashboard.php index aab5976..83fa978 100644
function wp_dashboard_quick_press( $error_msg = false ) { 491 491 $post_ID = (int) $post->ID; 492 492 ?> 493 493 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"> 499 495 500 496 <div class="input-text-wrap" id="title-wrap"> 501 <label class=" screen-reader-textprompt" for="title" id="title-prompt-text">497 <label class="prompt" for="title" id="title-prompt-text"> 502 498 503 499 <?php 504 500 /** This filter is documented in wp-admin/edit-form-advanced.php */ 505 501 echo apply_filters( 'enter_title_here', __( 'Title' ), $post ); 506 502 ?> 507 503 </label> 508 <input type="text" name=" post_title" id="title" autocomplete="off" />504 <input type="text" name="title" id="title" autocomplete="off" /> 509 505 </div> 510 506 511 507 <div class="textarea-wrap" id="description-wrap"> 512 <label class=" screen-reader-textprompt" for="content" id="content-prompt-text"><?php _e( 'What’s on your mind?' ); ?></label>508 <label class="prompt" for="content" id="content-prompt-text"><?php _e( 'What’s on your mind?' ); ?></label> 513 509 <textarea name="content" id="content" class="mceEditor" rows="3" cols="15" autocomplete="off"></textarea> 514 510 </div> 515 516 511 <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> 521 514 <?php submit_button( __( 'Save Draft' ), 'primary', 'save', false, array( 'id' => 'save-post' ) ); ?> 522 515 <br class="clear" /> 523 516 </p> … … function wp_dashboard_recent_drafts( $drafts = false ) { 554 547 */ 555 548 $query_args = apply_filters( 'dashboard_recent_drafts_query_args', $query_args ); 556 549 557 $drafts = get_posts( $query_args ); 550 $dashboard_data_request = new WP_REST_Request( 'GET', '/wp/v2/posts' ); 551 $dashboard_data_request->set_query_params( array( 552 'filter[post_type]' => 'post', 553 'status' => 'draft', 554 'author' => get_current_user_id(), 555 'per_page' => 4 556 ) ); 557 $drafts = rest_do_request( $dashboard_data_request ); 558 558 559 if ( ! $drafts ) { 559 560 return; 560 561 } 561 }562 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 “%s”' ), $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 563 } 564 565 echo '<div id="quick-press-drafts" class="drafts">'; 566 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"; 567 echo '<h2 class="hide-if-no-js">' . __( 'Drafts' ) . "</h2>\n"; 568 echo '<script type="text/javascript">var quickPress = {}; quickPress.data = ' . json_encode( $drafts ) . ';</script>'; 569 echo '<script id="tmpl-item-quick-press-draft" type="text/template">'; 570 /* translators: %s: post title */ 571 echo '<div class="draft-title"><a href="{{ data.link }}" aria-label="' . esc_attr( __( 'Edit Post' ) ) . '">{{ data.title }}</a>'; 572 echo '<time datetime="{{ data.date }}">{{ data.formattedDate }}</time></div>'; 573 echo '{{{ data.formattedShortContent }}}'; 574 echo '</script>'; 575 echo '<ul class="drafts-list">'; 582 576 echo "</ul>\n</div>"; 583 577 } 584 578 -
src/wp-admin/js/dashboard.js
diff --git src/wp-admin/js/dashboard.js src/wp-admin/js/dashboard.js index fa100dd..43d4a36 100644
1 /* global pagenow, ajaxurl, postboxes, wpActiveEditor:true */1 /* global wp, quickPress, pagenow, ajaxurl, postboxes, wpActiveEditor:true */ 2 2 var ajaxWidgets, ajaxPopulateWidgets, quickPressLoad; 3 3 4 4 jQuery(document).ready( function($) { … … jQuery(document).ready( function($) { 61 61 62 62 postboxes.add_postbox_toggles(pagenow, { pbshow: ajaxPopulateWidgets } ); 63 63 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 126 64 $( '.meta-box-sortables' ).sortable( 'option', 'containment', '#wpwrap' ); 127 65 128 66 function autoResizeTextarea() { … … jQuery(document).ready( function($) { 186 124 }); 187 125 } 188 126 127 autoResizeTextarea(); 128 129 } ); 130 131 wp.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 if ( ! attributes ) { 151 return attributes; 152 } 153 154 if ( 'object' === typeof attributes.content ) { 155 attributes.content = attributes.content.rendered; 156 } 157 158 if ( 'object' === typeof attributes.title ) { 159 attributes.title = attributes.title.rendered; 160 } 161 162 return attributes; 163 }, 164 165 validate: function( attributes ) { 166 if ( ! attributes.title && ! attributes.content ) { 167 return 'no-content'; 168 } 169 } 170 }); 171 172 QuickPress.Collections = {}; 173 174 QuickPress.Collections.Drafts = wp.api.collections.Posts.extend({ 175 model: QuickPress.Models.Draft, 176 177 comparator: function( a, b ) { 178 return a.get( 'date' ) < b.get( 'date' ); 179 } 180 }); 181 182 QuickPress.Views = {}; 183 184 QuickPress.Views.Form = wp.Backbone.View.extend({ 185 events: { 186 'click #title-wrap,#description-wrap': 'hidePromptAndFocus', 187 'focus #title-wrap,#description-wrap': 'hidePrompt', 188 'blur #title-wrap,#description-wrap': 'showPrompt', 189 click: 'setActiveEditor', 190 focusin: 'setActiveEditor', 191 submit: 'submit' 192 }, 193 194 initialize: function() { 195 this.listenTo( this.model, 'invalid', this.render ); 196 }, 197 198 togglePrompt: function( element, visible ) { 199 var $input = $( ':input', element ), 200 hasContent = $input.val().length > 0; 201 202 $( '.prompt', element ).toggleClass( 'screen-reader-text', ! visible || hasContent ); 203 }, 204 205 showPrompt: function( event ) { 206 this.togglePrompt( event.currentTarget, true ); 207 }, 208 209 hidePrompt: function( event ) { 210 this.togglePrompt( event.currentTarget, false ); 211 }, 212 213 hidePromptAndFocus: function( event ) { 214 this.togglePrompt( event.currentTarget, false ); 215 $( ':input', event.target ).focus(); 216 }, 217 218 setActiveEditor: function() { 219 wpActiveEditor = 'content'; 220 }, 221 222 submit: function( event ) { 223 var values; 224 225 event.preventDefault(); 226 227 values = this.$el.serializeArray().reduce( function( memo, field ) { 228 memo[ field.name ] = field.value; 229 return memo; 230 }, {} ); 231 232 this.model.set( values ); 233 if ( ! this.model.isValid() ) { 234 return; 235 } 236 237 // Show a spinner during the callback. 238 $('#quick-press .spinner').css( 'visibility', 'inherit' ); 239 240 this.model.save() 241 // TODO: `always` should be `done` to handle success only 242 .always( function() { 243 console.log( 'always' ); 244 $( '#quick-press .spinner' ).css( 'visibility', 'hidden' ); 245 } ) 246 .success( function(){ 247 console.log( 'success' ); 248 this.collection.add( this.model ); 249 // @todo Refresh the nonce (client should handle this). 250 // @todo Clear the form. 251 }.bind( this ) ) 252 .error( function() { 253 console.log( 'error' ); 254 // // TODO: Handle failure 255 } ); 256 257 // TODO: Clear form model 258 }, 259 260 render: function() { 261 var $error = this.$el.find( '.error' ); 262 263 $error.toggle( !! this.model.validationError ); 264 if ( this.model.validationError ) { 265 $error.html( $( '<p />', { 266 text: quickPress.l10n[ this.model.validationError ] 267 } ) ); 268 } 269 } 270 }); 271 272 QuickPress.Views.DraftList = wp.Backbone.View.extend({ 273 initialize: function() { 274 this.listenTo( this.collection, 'add', this.render ); 275 }, 276 277 render: function() { 278 var slicedCollection = this.collection.slice( 0, 4 ); 279 280 this.$el.toggle( this.collection.length > 0 ); 281 this.$el.find( '.view-all' ).toggle( slicedCollection.length > 3 ); 282 this.$el.find( '.drafts-list' ).html( slicedCollection.map( function( draft ) { 283 return new QuickPress.Views.DraftListItem({ 284 model: draft 285 }).render().el; 286 }) ); 287 288 return this; 289 } 290 }); 291 292 QuickPress.Views.DraftListItem = wp.Backbone.View.extend({ 293 tagName: 'li', 294 295 template: wp.template( 'item-quick-press-draft' ), 296 297 render: function() { 298 // TODO: Render highlight effect to new post 299 300 this.$el.html( this.template( this.model.attributes ) ); 301 302 return this; 303 } 304 }); 305 306 draftsCollection = new QuickPress.Collections.Drafts( quickPress.data.data ); 307 308 new QuickPress.Views.DraftList({ 309 el: '#quick-press-drafts', 310 collection: draftsCollection 311 }).render(); 312 313 new QuickPress.Views.Form({ 314 el: '#quick-press', 315 model: new QuickPress.Models.Draft(), 316 collection: draftsCollection 317 }).render(); 189 318 } ); -
src/wp-admin/post.php
diff --git src/wp-admin/post.php src/wp-admin/post.php index 437d1bd..df78352 100644
if ( ! $sendback || 60 60 } 61 61 62 62 switch($action) { 63 case 'post-quickdraft-save':64 // Check nonce and capabilities65 $nonce = $_REQUEST['_wpnonce'];66 $error_msg = false;67 68 // For output of the quickdraft dashboard widget69 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 91 63 case 'postajaxpost': 92 64 case 'post': 93 65 check_admin_referer( 'add-' . $post_type ); -
src/wp-includes/default-filters.php
diff --git src/wp-includes/default-filters.php src/wp-includes/default-filters.php index d5f2116..699c8af 100644
add_filter( 'the_excerpt_embed', 'wp_embed_excerpt_attachment' ); 492 492 add_filter( 'oembed_dataparse', 'wp_filter_oembed_result', 10, 3 ); 493 493 add_filter( 'oembed_response_data', 'get_oembed_response_data_rich', 10, 4 ); 494 494 add_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10, 3 ); 495 add_action( 'rest_api_init', 'wp_dashboard_filter_api' ); 495 496 496 497 unset( $filter, $action ); -
src/wp-includes/script-loader.php
diff --git src/wp-includes/script-loader.php src/wp-includes/script-loader.php index 874f5e7..15634ad 100644
function wp_default_scripts( &$scripts ) { 705 705 'current' => __( 'Current Color' ), 706 706 ) ); 707 707 708 $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox' ), false, 1 );708 $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-api', 'wp-backbone' ), false, 1 ); 709 709 710 710 $scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" ); 711 711 … … function _wp_footer_scripts() { 1175 1175 } 1176 1176 1177 1177 /** 1178 * Set up a filter for the dashboard API requests. 1179 */ 1180 function wp_dashboard_filter_api() { 1181 1182 /** 1183 * Filter the WP API response for the recent drafts widget in the dashboard, adding a formatted date 1184 * which is difficult to construct correctly in JavaScript. 1185 */ 1186 function wp_dashboard_filter_api_post( $response, $post, $request ) { 1187 1188 if ( 'draft' !== $post->post_status ) { 1189 return; 1190 } 1191 1192 $response->data['formattedDate'] = get_the_time( __( 'F j, Y' ), $post ); 1193 $response->data['formattedShortContent'] = wp_trim_words( $post->post_content, 10 ); 1194 return $response; 1195 } 1196 1197 add_filter( "rest_prepare_post", 'wp_dashboard_filter_api_post', 10, 3 ); 1198 1199 } 1200 1201 /** 1178 1202 * Hooks to print the scripts and styles in the footer. 1179 1203 * 1180 1204 * @since 2.8.0