diff --git src/wp-admin/css/dashboard.css src/wp-admin/css/dashboard.css
index 72b0230..3c7b618 100644
--- src/wp-admin/css/dashboard.css
+++ src/wp-admin/css/dashboard.css
@@ -518,6 +518,10 @@ form.initial-form.quickpress-open input#title {
 	resize: none;
 }
 
+#quick-press.is-saving .spinner {
+	visibility: inherit;
+}
+
 /* Dashboard Quick Draft - Drafts list */
 
 .js #dashboard_quick_press .drafts {
@@ -541,9 +545,68 @@ form.initial-form.quickpress-open input#title {
 	margin: 0 12px;
 }
 
+#dashboard_quick_press .drafts ul.is-placeholder li {
+	padding: 3px 0;
+	color: transparent;
+}
+
+@-webkit-keyframes loading-fade {
+
+	0% {
+		opacity: 0.5;
+	}
+
+	50% {
+		opacity: 1;
+	}
+
+	100% {
+		opacity: 0.5;
+	}
+}
+
+@keyframes loading-fade {
+
+	0% {
+		opacity: 0.5;
+	}
+
+	50% {
+		opacity: 1;
+	}
+
+	100% {
+		opacity: 0.5;
+	}
+}
+
+#dashboard_quick_press .drafts ul.is-placeholder li:before,
+#dashboard_quick_press .drafts ul.is-placeholder li:after {
+	content: "";
+	display: block;
+	height: 13px;
+	background: #eee;
+	-webkit-animation: loading-fade 1.6s ease-in-out infinite;
+	animation: loading-fade 1.6s ease-in-out infinite;
+}
+
+#dashboard_quick_press .drafts ul.is-placeholder li:before {
+	margin-bottom: 5px;
+	width: 40%;
+}
+
+#dashboard_quick_press .drafts ul.is-placeholder li:after {
+	width: 80%;
+}
+
 #dashboard_quick_press .drafts li {
 	margin-bottom: 1em;
 }
+
+#dashboard_quick_press .drafts li.is-new {
+	background-color: #fffbe5;
+}
+
 #dashboard_quick_press .drafts li time {
 	color: #72777c;
 }
diff --git src/wp-admin/includes/dashboard.php src/wp-admin/includes/dashboard.php
index 0ecf0a2..299546b 100644
--- src/wp-admin/includes/dashboard.php
+++ src/wp-admin/includes/dashboard.php
@@ -50,6 +50,7 @@ function wp_dashboard_setup() {
 	if ( is_blog_admin() && current_user_can( get_post_type_object( 'post' )->cap->create_posts ) ) {
 		$quick_draft_title = sprintf( '<span class="hide-if-no-js">%1$s</span> <span class="hide-if-js">%2$s</span>', __( 'Quick Draft' ), __( 'Drafts' ) );
 		wp_add_dashboard_widget( 'dashboard_quick_press', $quick_draft_title, 'wp_dashboard_quick_press' );
+		add_action( 'admin_footer', 'wp_dashboard_print_recent_drafts_template' );
 	}
 
 	// WordPress News
@@ -494,46 +495,47 @@ function wp_dashboard_quick_press( $error_msg = false ) {
 	$post_ID = (int) $post->ID;
 ?>
 
-	<form name="post" action="<?php echo esc_url( admin_url( 'post.php' ) ); ?>" method="post" id="quick-press" class="initial-form hide-if-no-js">
-
-		<?php if ( $error_msg ) : ?>
-		<div class="error"><?php echo $error_msg; ?></div>
-		<?php endif; ?>
-
+	<form name="post" method="post" id="quick-press" class="initial-form hide-if-no-js">
+		<div class="notice notice-error notice-alt inline hidden"><p></p></div>
 		<div class="input-text-wrap" id="title-wrap">
-			<label class="screen-reader-text prompt" for="title" id="title-prompt-text">
+			<label class="prompt" for="title" id="title-prompt-text">
 
 				<?php
 				/** This filter is documented in wp-admin/edit-form-advanced.php */
 				echo apply_filters( 'enter_title_here', __( 'Title' ), $post );
 				?>
 			</label>
-			<input type="text" name="post_title" id="title" autocomplete="off" />
+			<input type="text" name="title" id="title" autocomplete="off" />
 		</div>
 
 		<div class="textarea-wrap" id="description-wrap">
-			<label class="screen-reader-text prompt" for="content" id="content-prompt-text"><?php _e( 'What&#8217;s on your mind?' ); ?></label>
+			<label class="prompt" for="content" id="content-prompt-text"><?php _e( 'What&#8217;s on your mind?' ); ?></label>
 			<textarea name="content" id="content" class="mceEditor" rows="3" cols="15" autocomplete="off"></textarea>
 		</div>
-
 		<p class="submit">
-			<input type="hidden" name="action" id="quickpost-action" value="post-quickdraft-save" />
-			<input type="hidden" name="post_ID" value="<?php echo $post_ID; ?>" />
-			<input type="hidden" name="post_type" value="post" />
-			<?php wp_nonce_field( 'add-post' ); ?>
+			<div class="spinner no-float"></div>
 			<?php submit_button( __( 'Save Draft' ), 'primary', 'save', false, array( 'id' => 'save-post' ) ); ?>
 			<br class="clear" />
 		</p>
 
 	</form>
+	<div id="quick-press-drafts" class="drafts">
+		<p class="view-all" style="display: none;">
+			<a href="<?php echo esc_url( admin_url( 'edit.php?post_status=draft' ) ) ?>" aria-label="<?php esc_attr_e( 'View all drafts' ) ?>"><?php _ex( 'View all', 'drafts' ) ?></a>
+		</p>
+		<h2 class="hide-if-no-js"><?php _e( 'Drafts' ) ?></h2>
+		<ul class="drafts-list is-placeholder">
+			<li><span class="screen-reader-text"><?php _e( 'Loading&hellip;' ) ?></span></li>
+		</ul>
+	</div>
 	<?php
-	wp_dashboard_recent_drafts();
 }
 
 /**
  * Show recent drafts of the user on the dashboard.
  *
  * @since 2.7.0
+ * @deprecated 4.7
  *
  * @param array $drafts
  */
@@ -548,13 +550,7 @@ function wp_dashboard_recent_drafts( $drafts = false ) {
 			'order'          => 'DESC'
 		);
 
-		/**
-		 * Filters the post query arguments for the 'Recent Drafts' dashboard widget.
-		 *
-		 * @since 4.4.0
-		 *
-		 * @param array $query_args The query arguments for the 'Recent Drafts' dashboard widget.
-		 */
+		/** This filter is documented in wp-includes/rest-api.php */
 		$query_args = apply_filters( 'dashboard_recent_drafts_query_args', $query_args );
 
 		$drafts = get_posts( $query_args );
@@ -586,6 +582,25 @@ function wp_dashboard_recent_drafts( $drafts = false ) {
 }
 
 /**
+ * Get the HTML template for the Quick Draft recent posts.
+ *
+ * @since 4.7.0
+ *
+ * @return string The template HTML.
+ */
+function wp_dashboard_print_recent_drafts_template() {
+	?>
+	<script id="tmpl-item-quick-press-draft" type="text/template">
+		<div class="draft-title">
+			<a href="post.php?post={{ data.id }}&action=edit" aria-label="<?php esc_attr_e( 'Edit Post' ) ?>">{{ data.formattedTitle }}</a>
+			<time datetime="{{ data.date }}">{{ data.formattedDate }}</time>
+		</div>
+		{{{ data.formattedContent }}}
+	</script>
+	<?php
+}
+
+/**
  * Outputs a row for the Recent Comments widget.
  *
  * @access private
diff --git src/wp-admin/js/dashboard.js src/wp-admin/js/dashboard.js
index fa100dd..67246fa 100644
--- src/wp-admin/js/dashboard.js
+++ src/wp-admin/js/dashboard.js
@@ -1,5 +1,5 @@
-/* global pagenow, ajaxurl, postboxes, wpActiveEditor:true */
-var ajaxWidgets, ajaxPopulateWidgets, quickPressLoad;
+/* global _, wp, quickDraft, pagenow, ajaxurl, postboxes, wpActiveEditor:true */
+var ajaxWidgets, ajaxPopulateWidgets, QuickDraft = {};
 
 jQuery(document).ready( function($) {
 	var welcomePanel = $( '#welcome-panel' ),
@@ -59,69 +59,13 @@ jQuery(document).ready( function($) {
 	};
 	ajaxPopulateWidgets();
 
-	postboxes.add_postbox_toggles(pagenow, { pbshow: ajaxPopulateWidgets } );
-
-	/* QuickPress */
-	quickPressLoad = function() {
-		var act = $('#quickpost-action'), t;
-
-		$( '#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]' ).prop( 'disabled' , false );
-
-		t = $('#quick-press').submit( function( e ) {
-			e.preventDefault();
-			$('#dashboard_quick_press #publishing-action .spinner').show();
-			$('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').prop('disabled', true);
-
-			$.post( t.attr( 'action' ), t.serializeArray(), function( data ) {
-				// Replace the form, and prepend the published post.
-				$('#dashboard_quick_press .inside').html( data );
-				$('#quick-press').removeClass('initial-form');
-				quickPressLoad();
-				highlightLatestPost();
-				$('#title').focus();
-			});
-
-			function highlightLatestPost () {
-				var latestPost = $('.drafts ul li').first();
-				latestPost.css('background', '#fffbe5');
-				setTimeout(function () {
-					latestPost.css('background', 'none');
-				}, 1000);
-			}
-		} );
-
-		$('#publish').click( function() { act.val( 'post-quickpress-publish' ); } );
-
-		$('#title, #tags-input, #content').each( function() {
-			var input = $(this), prompt = $('#' + this.id + '-prompt-text');
-
-			if ( '' === this.value ) {
-				prompt.removeClass('screen-reader-text');
-			}
-
-			prompt.click( function() {
-				$(this).addClass('screen-reader-text');
-				input.focus();
-			});
-
-			input.blur( function() {
-				if ( '' === this.value ) {
-					prompt.removeClass('screen-reader-text');
-				}
-			});
-
-			input.focus( function() {
-				prompt.addClass('screen-reader-text');
-			});
-		});
+	postboxes.add_postbox_toggles(pagenow, { pbshow: function( id ) {
+		ajaxPopulateWidgets();
 
-		$('#quick-press').on( 'click focusin', function() {
-			wpActiveEditor = 'content';
-		});
-
-		autoResizeTextarea();
-	};
-	quickPressLoad();
+		if ( 'dashboard_quick_press' === id ) {
+			QuickDraft.init();
+		}
+	} } );
 
 	$( '.meta-box-sortables' ).sortable( 'option', 'containment', '#wpwrap' );
 
@@ -186,4 +130,380 @@ jQuery(document).ready( function($) {
 		});
 	}
 
+	autoResizeTextarea();
+
+	if ( jQuery( '#dashboard_quick_press' ).is( ':visible' ) ) {
+		QuickDraft.init();
+	}
+});
+
+// Set up the QuickDraft views.
+QuickDraft.Views = {};
+
+/**
+ * Set up a view object for the quick draft form.
+ *
+ * @since 4.7.0
+ *
+ * @augments wp.Backbone.View
+ */
+QuickDraft.Views.Form = wp.Backbone.View.extend( {
+
+	// Set up our default action handlers.
+	events: {
+
+		// Hide the prompt whena field receives focus.
+		'focus :input': 'hidePrompt',
+
+		// Possibly re-display the prompt when a field looses focus.
+		'blur :input':  'showPrompt',
+
+		// Listen for a reset event, showing all prompts.
+		'reset':        'showAllPrompts',
+
+		// Listed for and handle form submissions.
+		'submit':       'handleFormSubmission'
+	},
+
+	// Initialize the QuickDraft Form view.
+	initialize: function() {
+
+		// Show all prompts in the form to begin.
+		this.showAllPrompts();
+
+		// Rerender if the error state changes.
+		quickDraft.state.on( 'change:errorState', _.bind( this.render, this ) );
+	},
+
+	/**
+	 * Handle toggling of the helper prompts shown inside each field.
+	 *
+	 * Will only show the prompt if the field is empty.
+	 *
+	 * @param  {object}  element Field element containing the helper prompt.
+	 * @param  {boolean} visible Should the prompt be visible?
+	 */
+	togglePrompt: function( element, visible ) {
+		var $input = jQuery( element ),
+			hasContent = $input.val().length > 0;
+
+		jQuery( element ).siblings( '.prompt' ).toggleClass( 'screen-reader-text', ! visible || hasContent );
+	},
+
+	// Show all of the field promts.
+	showAllPrompts: function() {
+		this.$el.find( ':input' ).each( _.bind( function( i, input ) {
+
+			// Prompt toggling must be deferred because the reset event is
+			// fired before the input values have been cleared
+			_.defer( _.bind( this.togglePrompt, this, input, true ) );
+		}, this ) );
+	},
+
+	/**
+	 * Show the prompt inside a field.
+	 *
+	 * @param {object} event The event triggering this show request.
+	 */
+	showPrompt: function( event ) {
+		this.togglePrompt( event.target, true );
+	},
+
+	/**
+	 * Hide the prompt inside a field.
+	 *
+	 * @param {object} event The event triggering this hide request.
+	 */
+	hidePrompt: function( event ) {
+		this.togglePrompt( event.target, false );
+	},
+
+	/**
+	 * Handle error conditions.
+	 *
+	 * {string} error The error condition, or false to reset.
+	 */
+	setErrorState: function( error ) {
+
+		// Set or reset the app state error condition.
+		quickDraft.state.set( 'errorState', error );
+
+		if ( false !== error ) {
+
+			// Alert screen readers that an error occurred.
+			wp.a11y.speak( error, 'assertive' );
+		}
+
+	},
+
+	/**
+	 * Handle the form submission event.
+	 *
+	 * @param {object} event The form submission event.
+	 */
+	handleFormSubmission: function( event ) {
+		var values,
+			hasValuesToSave = false;
+
+		// Prevent the browser's default form submission handling.
+		event.preventDefault();
+
+		if ( quickDraft.state.get( 'submitting' ) ) {
+			return false;
+		}
+
+		quickDraft.state.set( 'submitting', true );
+
+		// Reset the error state.
+		this.setErrorState( false );
+
+		// Extract the form field values.
+		values = _.reduce( this.$el.serializeArray(), function( memo, field ) {
+			memo[ field.name ] = field.value;
+			return memo;
+		}, {} );
+
+		// Check to see if there are any values to save.
+		_.each( values, function( value ) {
+			if ( '' !== value ) {
+				hasValuesToSave = true;
+			}
+		});
+
+		// If the values are all blank, show an error.
+		if ( ! hasValuesToSave ) {
+
+			// Set the error.
+			this.setErrorState( quickDraft.l10n.errorEmptyFields );
+			return;
+		}
+
+		// Save the new values to the model and confirm they are valid.
+		this.model.set( values );
+		if ( ! this.model.isValid() ) {
+			return;
+		}
+
+		// Show a spinner during the callback.
+		this.$el.addClass( 'is-saving' );
+
+		// Trigger the model save.
+		this.model.save()
+
+			// Always remove the spinner.
+			.always(
+				_.bind( function() {
+					this.$el.removeClass( 'is-saving' );
+
+					// Refocus in the title field, hiding its prompt.
+					_.delay( function() { jQuery( '#quick-press input#title' ).focus(); }, 250 );
+
+					// Submission complete
+					quickDraft.state.set( 'submitting', false );
+
+				}, this )
+			)
+
+			// Handle save success.
+			.success(
+				_.bind( function() {
+					// Success! Clear any previous error state.
+					 this.render();
+
+					// Add the post model to the head of our collection.
+					this.collection.add( this.model, { at: 0 } );
+
+					// Create a new post model to contain the form data and reset the form.
+					this.model = new wp.api.models.Post();
+					this.model.on( 'change:errorState', _.bind( this.render, this ) );
+
+					this.el.reset();
+				}, this )
+			)
+
+			// Handle save failure.
+			.error(
+				_.bind( function( model, error ) {
+					var message = '';
+
+					// Try to parse and use the response message.
+					try {
+						message = JSON.parse( error.responseText ).message;
+					} catch( e ) {
+
+						// Fall back to a default error string if we parse fails.
+						message = quickDraft.l10n.error;
+					}
+
+					// Set the app error condition.
+					this.setErrorState( message );
+				}, this )
+			)
+			;
+	},
+
+	// Render the form view.
+	render: function() {
+		var $error    = this.$el.find( '.notice-alt' ),
+			errorText = quickDraft.state.get( 'errorState' );
+
+		// Error notice is only visible if error text is set.
+		$error.toggleClass( 'hidden', ! errorText );
+		if ( errorText ) {
+
+			// Note: The inner text transform prevents XSS via html().
+			$error.html( jQuery( '<p />', { text: errorText } ) );
+		}
+	}
+} );
+
+/**
+ * Set up a view object for the Quick Draft list of drafts.
+ *
+ * @since 4.7.0
+ *
+ * @augments wp.Backbone.View
+ */
+QuickDraft.Views.DraftList = wp.Backbone.View.extend( {
+
+	// Initialize the draft list view.
+	initialize: function() {
+
+		// Render the view once the drafts have loaded.
+		this.listenTo( this.collection, 'sync', this.onDraftsLoaded );
+	},
+
+	// Once the drafts have loaded, complete the setup.
+	onDraftsLoaded: function() {
+
+		// Add a listener for new items added to the underlying (draft) post collection.
+		this.listenTo( this.collection, 'add', this.renderNew );
+
+		// Render the view!
+		this.render();
+	},
+
+	// Handle a new item being added to the collection.
+	renderNew: function() {
+
+		// Display highlight effect to first (added) item for one second.
+		var $newEl = this.render().$el.find( 'li:first' ).addClass( 'is-new' );
+		setTimeout( function() {
+			$newEl.removeClass( 'is-new' );
+		}, 1000 );
+
+		// Alert screen readers that a new draft has been added.
+		wp.a11y.speak( quickDraft.l10n.newDraftCreated, 'assertive' );
+	},
+
+	// Render the draft post list view.
+	render: function() {
+
+		// Hide drafts list entirely if no drafts exist.
+		this.$el.toggle( this.collection.length > 0 );
+
+		// Display a 'View All' link if there are more drafts available.
+		this.$el.find( '.view-all' ).toggle( this.collection.hasMore() );
+
+		// Remove the placeholder class and render the models.
+		this.$el.find( '.drafts-list' )
+			.removeClass( 'is-placeholder' )
+			.html(
+				_.map( this.collection.models, function( draft ) {
+					return new QuickDraft.Views.DraftListItem( {
+						model: draft
+					} ).render().el;
+				} )
+			);
+
+		return this;
+	}
 } );
+
+/**
+ * Set up a view object an individual draft in the draft list.
+ *
+ * @since 4.7.0
+ *
+ * @augments wp.Backbone.View
+ */
+QuickDraft.Views.DraftListItem = wp.Backbone.View.extend( {
+	tagName: 'li',
+
+	// Render beased on the passed template.
+	template: wp.template( 'item-quick-press-draft' ),
+
+	// Render a single draft list item.
+	render: function() {
+
+		// Clone the original model attributes, so we can leave the model untouched.
+		var attributes = _.clone( this.model.attributes );
+
+		// Trim the content to 10 words.
+		attributes.formattedContent = wp.formatting.trimWords( attributes.content.rendered, 10 );
+
+		// If the title is missing entirely, add a no title placeholder.
+		attributes.formattedTitle = attributes.title.rendered.length > 0 ? attributes.title.rendered : quickDraft.l10n.noTitle;
+
+		// Format the data using Intl.DateTimeFormat with a fallback to date.toLocaleDateString.
+		var date = new Date( wp.api.utils.parseISO8601( attributes.date + quickDraft.timezoneOffset ) );
+		if ( 'undefined' !== typeof Intl && Intl.DateTimeFormat ) {
+			attributes.formattedDate = new Intl.DateTimeFormat( undefined, {
+				month: 'long',
+				day: 'numeric',
+				year: 'numeric'
+			} ).format( date );
+		} else {
+			attributes.formattedDate = date.toLocaleDateString();
+		}
+
+		// Output the rendered template.
+		this.$el.html( this.template( attributes ) );
+
+		// Continue the rendering chain.
+		return this;
+	}
+} );
+
+
+/**
+ * Initialize the Quick Draft feature.
+ *
+ * @since 4.7.0
+ *
+ */
+QuickDraft.init = function() {
+
+	// Set up a state model to track the application state.
+	quickDraft.state = new Backbone.Model({
+		'errorState': false
+	});
+
+	// Wait for the wp-api client to initialize.
+	wp.api.loadPromise.done( function() {
+
+		// Fetch up to 4 of the current user's recent drafts by extending wp.api.collections.Posts.
+		var draftsCollection = new wp.api.collections.Posts();
+		draftsCollection.fetch( {
+			data: {
+				status: 'draft',
+				author: quickDraft.currentUserId,
+				per_page: 4,
+				order_by: 'date',
+				'quick-draft-post-list': true /* flag passed for back end filters */
+			}
+		} );
+
+		// Drafts list is initialized but not rendered until drafts load.
+		new QuickDraft.Views.DraftList( {
+			el: '#quick-press-drafts',
+			collection: draftsCollection
+		} );
+
+		new QuickDraft.Views.Form( {
+			el: '#quick-press',
+			model: new wp.api.models.Post(),
+			collection: draftsCollection
+		} ).render();
+	});
+};
diff --git src/wp-includes/js/wp-util.js src/wp-includes/js/wp-util.js
index 527441d..bdc7531 100644
--- src/wp-includes/js/wp-util.js
+++ src/wp-includes/js/wp-util.js
@@ -121,4 +121,50 @@ window.wp = window.wp || {};
 		}
 	};
 
+	// wp.formatting
+	// ------
+	//
+	// Tools for formatting strings
+	wp.formatting = {
+		settings: settings.formatting || {},
+
+		/**
+		 * Trims text to a certain number of words.
+		 *
+		 * @see wp_trim_words
+		 *
+		 * @param  {string} text     Text to trim.
+		 * @param  {number} numWords Number of words. Optional, default is 55.
+		 * @param  {string} more     What to append if text needs to be trimmed. Optional, default is '…'.
+		 * @return {string}          Trimmed text.
+		 */
+		trimWords: function( text, numWords, more ) {
+			var words, separator;
+
+			if ( 'undefined' === typeof numWords ) {
+				numWords = 55;
+			}
+
+			if ( 'undefined' === typeof more ) {
+				more = wp.formatting.settings.trimWordsMore;
+			}
+
+			text = text.replace( /[\n\r\t ]+/g, ' ' ).replace( /^ | $/g, '' );
+
+			if ( wp.formatting.settings.trimWordsByCharacter ) {
+				separator = '';
+			} else {
+				separator = ' ';
+			}
+
+			words = text.split( separator );
+
+			if ( words.length <= numWords ) {
+				return words.join( separator );
+			}
+
+			return words.slice( 0, numWords ).join( separator ) + more;
+		}
+	};
+
 }(jQuery));
diff --git src/wp-includes/rest-api.php src/wp-includes/rest-api.php
index 3d0b7ee..3711e32 100644
--- src/wp-includes/rest-api.php
+++ src/wp-includes/rest-api.php
@@ -164,6 +164,37 @@ function rest_api_default_filters() {
 	add_filter( 'rest_post_dispatch', 'rest_send_allow_header', 10, 3 );
 
 	add_filter( 'rest_pre_dispatch', 'rest_handle_options_request', 10, 3 );
+
+	// Legacy filter for Quick Draft recent posts.
+	add_filter( 'rest_post_query', 'rest_filter_quick_draft_query', 10, 2 );
+}
+
+/**
+ * Filter query args used by he Quick Draft recent posts list.
+ *
+ * @param array           $args    Key value array of query var to query value.
+ * @param WP_REST_Request $request The request used.
+ */
+function rest_filter_quick_draft_query( $query_args, $request ) {
+
+	// Only modify Quick Draft queries.
+	$params = $request->get_query_params();
+
+	if ( ! isset( $params['quick-draft-post-list'] ) ) {
+		return $query_args;
+	}
+
+	/**
+	 * Filters the post query arguments for the 'Recent Drafts' dashboard widget.
+	 *
+	 * @since 4.4.0
+	 *
+	 * @param array $query_args The query arguments for the 'Recent Drafts' dashboard widget.
+	 */
+	$query_args = apply_filters( 'dashboard_recent_drafts_query_args', $query_args );
+
+	return $query_args;
+
 }
 
 /**
diff --git src/wp-includes/script-loader.php src/wp-includes/script-loader.php
index be32073..c10fa11 100644
--- src/wp-includes/script-loader.php
+++ src/wp-includes/script-loader.php
@@ -336,6 +336,15 @@ function wp_default_scripts( &$scripts ) {
 		'ajax' => array(
 			'url' => admin_url( 'admin-ajax.php', 'relative' ),
 		),
+		'formatting' => array(
+			'trimWordsMore'  => __( '&hellip;' ),
+			/*
+			 * translators: If your word count is based on single characters (e.g. East Asian characters),
+			 * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
+			 * Do not translate into your own language.
+			 */
+			'trimWordsByCharacter' => strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ),
+		),
 	) );
 
 	$scripts->add( 'wp-backbone', "/wp-includes/js/wp-backbone$suffix.js", array('backbone', 'wp-util'), false, 1 );
@@ -721,7 +730,17 @@ function wp_default_scripts( &$scripts ) {
 			'current' => __( 'Current Color' ),
 		) );
 
-		$scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox' ), false, 1 );
+		$scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-api', 'wp-backbone', 'wp-a11y', 'wp-util' ), false, 1 );
+		did_action( 'init' ) && $scripts->localize( 'dashboard', 'quickDraft', array(
+			'currentUserId'  => get_current_user_id(),
+			'l10n' => array(
+				'error'            => __( 'An error has occurred. Please reload the page and try again.' ),
+				'newDraftCreated'  => __( 'Success. A new draft was created.' ),
+				'errorEmptyFields' => __( 'Error. All fields were empty.' ),
+				'noTitle'          => __( '(no title)' ),
+			),
+			'timezoneOffset' => ( get_option( 'gmt_offset' ) >= 0 ? '+' : '-' ) . date( 'H:i', abs( get_option( 'gmt_offset' ) * 3600 ) ),
+		) );
 
 		$scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" );
 
diff --git tests/qunit/index.html tests/qunit/index.html
index 9a17ec2..baf0f46 100644
--- tests/qunit/index.html
+++ tests/qunit/index.html
@@ -61,6 +61,7 @@
 		<script src="wp-admin/js/customize-base.js"></script>
 		<script src="wp-admin/js/customize-header.js"></script>
 		<script src="wp-includes/js/shortcode.js"></script>
+		<script src="wp-includes/js/wp-util.js"></script>
 		<script src="wp-admin/js/customize-controls.js"></script>
 		<script src="wp-admin/js/customize-controls-utils.js"></script>
 		<script src="wp-admin/js/customize-nav-menus.js"></script>
