Index: wp-includes/revision.php
===================================================================
--- wp-includes/revision.php	(revision 24363)
+++ wp-includes/revision.php	(working copy)
@@ -681,68 +681,3 @@
 
 	return true;
 }
-
-/**
- * Displays a human readable HTML representation of the difference between two strings.
- * similar to wp_text_diff, but tracks and returns could of lines added and removed
- *
- * @since 3.6.0
- *
- * @see wp_parse_args() Used to change defaults to user defined settings.
- * @uses Text_Diff
- * @uses WP_Text_Diff_Renderer_Table
- *
- * @param string $left_string "old" (left) version of string
- * @param string $right_string "new" (right) version of string
- * @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults.
- * @return array contains html, linesadded & linesdeletd, empty string if strings are equivalent.
- */
-function wp_text_diff_with_count( $left_string, $right_string, $args = null ) {
-	$defaults = array( 'title' => '', 'title_left' => '', 'title_right' => '' );
-	$args = wp_parse_args( $args, $defaults );
-
-	if ( ! class_exists( 'WP_Text_Diff_Renderer_Table' ) )
-			require( ABSPATH . WPINC . '/wp-diff.php' );
-
-	$left_string  = normalize_whitespace( $left_string );
-	$right_string = normalize_whitespace( $right_string );
-
-	$left_lines  = explode( "\n", $left_string );
-	$right_lines = explode( "\n", $right_string) ;
-
-	$text_diff = new Text_Diff($left_lines, $right_lines  );
-	$lines_added = $text_diff->countAddedLines();
-	$lines_deleted = $text_diff->countDeletedLines();
-
-	$renderer  = new WP_Text_Diff_Renderer_Table();
-	$diff = $renderer->render( $text_diff );
-
-	if ( !$diff )
-			return '';
-
-		$r  = "<table class='diff'>\n";
-
-	if ( ! empty( $args[ 'show_split_view' ] ) ) {
-		$r .= "<col class='content diffsplit left' /><col class='content diffsplit middle' /><col class='content diffsplit right' />";
-	} else {
-		$r .= "<col class='content' />";
-	}
-
-	if ( $args['title'] || $args['title_left'] || $args['title_right'] )
-		$r .= "<thead>";
-	if ( $args['title'] )
-		$r .= "<tr class='diff-title'><th colspan='4'>$args[title]</th></tr>\n";
-	if ( $args['title_left'] || $args['title_right'] ) {
-		$r .= "<tr class='diff-sub-title'>\n";
-		$r .= "\t<td></td><th>$args[title_left]</th>\n";
-		$r .= "\t<td></td><th>$args[title_right]</th>\n";
-		$r .= "</tr>\n";
-	}
-	if ( $args['title'] || $args['title_left'] || $args['title_right'] )
-		$r .= "</thead>\n";
-
-	$r .= "<tbody>\n$diff\n</tbody>\n";
-	$r .= "</table>";
-
-	return array( 'html' => $r, 'lines_added' => $lines_added, 'lines_deleted' => $lines_deleted );
-}
Index: wp-admin/admin-ajax.php
===================================================================
--- wp-admin/admin-ajax.php	(revision 24363)
+++ wp-admin/admin-ajax.php	(working copy)
@@ -42,7 +42,7 @@
 
 $core_actions_get = array(
 	'fetch-list', 'ajax-tag-search', 'wp-compression-test', 'imgedit-preview', 'oembed-cache',
-	'autocomplete-user', 'dashboard-widgets', 'logged-in', 'revisions-data'
+	'autocomplete-user', 'dashboard-widgets', 'logged-in',
 );
 
 $core_actions_post = array(
@@ -56,7 +56,8 @@
 	'save-widget', 'set-post-thumbnail', 'date_format', 'time_format', 'wp-fullscreen-save-post',
 	'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'get-attachment',
 	'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor',
-	'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'show-post-format-ui',
+	'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs',
+	'show-post-format-ui',
 );
 
 // Register core Ajax calls.
Index: wp-admin/includes/ajax-actions.php
===================================================================
--- wp-admin/includes/ajax-actions.php	(revision 24363)
+++ wp-admin/includes/ajax-actions.php	(working copy)
@@ -2102,219 +2102,29 @@
 	wp_send_json($response);
 }
 
-function wp_ajax_revisions_data() {
-	check_ajax_referer( 'revisions-ajax-nonce', 'nonce' );
+function wp_ajax_get_revision_diffs() {
+	require ABSPATH . 'wp-admin/includes/revision.php';
 
-	$compare_to = ! empty( $_GET['compare_to'] ) ? absint( $_GET['compare_to'] ) : 0;
-	$show_autosaves = ! empty( $_GET['show_autosaves'] );
-	$show_split_view = ! empty( $_GET['show_split_view'] );
-	$post_id = ! empty( $_GET['post_id'] ) ? absint( $_GET['post_id'] ) : 0;
-	$right_handle_at = ! empty( $_GET['right_handle_at'] ) ? (int) $_GET['right_handle_at'] : 0;
-	$left_handle_at = ! empty( $_GET['left_handle_at'] ) ? (int) $_GET['left_handle_at'] : 0;
-	$single_revision_id = ! empty( $_GET['single_revision_id'] ) ? absint( $_GET['single_revision_id'] ) : 0;
-	$compare_two_mode = (bool) $post_id;
+	// check_ajax_referer( 'revisions-ajax-nonce', 'nonce' );
 
-	$all_the_revisions = array();
-	if ( ! $post_id )
-		$post_id = $compare_to;
+	if ( ! $post = get_post( (int) $_REQUEST['post_id'] ) )
+		wp_send_json_error();
 
-	if ( ! current_user_can( 'read_post', $post_id ) )
-		continue;
+	if ( ! current_user_can( 'read_post', $post->ID ) )
+		wp_send_json_error();
 
-	if ( ! $revisions = wp_get_post_revisions( $post_id ) )
-		return;
+	// Really just pre-loading the cache here.
+	if ( ! $revisions = wp_get_post_revisions( $post->ID ) )
+		wp_send_json_error();
 
-	$left_revision = get_post( $compare_to );
+	$return = array();
+	@set_time_limit( count( $_REQUEST['compare'] ) );
 
-	// single model fetch mode
-	// return the diff of a single revision comparison
-	if ( $single_revision_id ) {
-		$right_revision = get_post( $single_revision_id );
+	foreach ( $_REQUEST['compare'] as $compare_key ) {
+		list( $compare_from, $compare_to ) = explode( ':', $compare_key ); // from:to
 
-		if ( ! $compare_to )
-			$left_revision = get_post( $post_id );
+		$return[ $compare_key ] = wp_get_revision_ui_diff( $post, $compare_from, $compare_to );
+	}
 
-		// make sure the right revision is the most recent, except on oldest revision
-		if ( $compare_to && $right_revision->post_date < $left_revision->post_date ) {
-			$temp = $left_revision;
-			$left_revision = $right_revision;
-			$right_revision = $temp;
-		}
-
-		$lines_added = $lines_deleted = 0;
-		$content = '';
-		// compare from left to right, passed from application
-		foreach ( _wp_post_revision_fields() as $field => $field_value ) {
-			$left_content = apply_filters( "_wp_post_revision_field_$field", $left_revision->$field, $field, $left_revision, 'left' );
-			$right_content = apply_filters( "_wp_post_revision_field_$field", $right_revision->$field, $field, $right_revision, 'right' );
-
-			add_filter( "_wp_post_revision_field_$field", 'htmlspecialchars' );
-
-			$args = array();
-
-			if ( $show_split_view )
-				 $args = array( 'show_split_view' => true );
-
-			// compare_to == 0 means first revision, so compare to a blank field to show whats changed
-			$diff = wp_text_diff_with_count( ( 0 == $compare_to ) ? '' : $left_content, $right_content, $args );
-
-			if ( isset( $diff[ 'html' ] ) ) {
-				$content .= sprintf( '<div class="diff-label">%s</div>', $field_value );
-				$content .= $diff[ 'html' ];
-			}
-
-			if ( isset( $diff[ 'lines_added' ] ) )
-				$lines_added = $lines_added + $diff[ 'lines_added' ];
-
-			if ( isset( $diff[ 'lines_deleted' ] ) )
-				$lines_deleted = $lines_deleted + $diff[ 'lines_deleted' ];
-		}
-		$content = '' == $content ? __( 'No difference' ) : $content;
-
-		$all_the_revisions = array (
-			'diff'         => $content,
-			'linesDeleted' => $lines_deleted,
-			'linesAdded'   => $lines_added
-		);
-
-		echo json_encode( $all_the_revisions );
-		exit();
-	} // end single model fetch
-
-	$count = -1;
-
-	// reverse the list to start with oldest revision
-	$revisions = array_reverse( $revisions );
-
-	$previous_revision_id = 0;
-
-	/* translators: revision date format, see http://php.net/date */
-	$datef = _x( 'j F, Y @ G:i:s', 'revision date format');
-
-	foreach ( $revisions as $revision ) :
-		if ( ! $show_autosaves && wp_is_post_autosave( $revision ) )
-			continue;
-
-		$revision_from_date_author = '';
-		$is_current_revision = false;
-		$count++;
-
-		/**
-		* return blank data for diffs to the left of the left handle (for right handel model)
-		* or to the right of the right handle (for left handel model)
-		* and visa versa in RTL mode
-		*/
-		if( ! is_rtl() ) {
-			if ( ( ( 0 != $left_handle_at && $count < $left_handle_at ) ||
-				 ( 0 != $right_handle_at && $count > ( $right_handle_at - 2 ) ) ) ) {
-				$all_the_revisions[] = array (
-					'ID' => $revision->ID,
-				);
-				continue;
-			}
-		} else { // is_rtl
-			if ( ( 0 != $left_handle_at && $count > ( $left_handle_at - 1 ) ||
-				 ( 0 != $left_handle_at && $count < $right_handle_at ) ) ) {
-				$all_the_revisions[] = array (
-					'ID' => $revision->ID,
-				);
-				continue;
-			}
-		}
-
-		if ( $compare_two_mode ) {
-			$compare_to_gravatar = get_avatar( $left_revision->post_author, 24 );
-			$compare_to_author = get_the_author_meta( 'display_name', $left_revision->post_author );
-			$compare_to_date = date_i18n( $datef, strtotime( $left_revision->post_modified ) );
-
-			$revision_from_date_author = sprintf(
-				/* translators: post revision title: 1: author avatar, 2: author name, 3: time ago, 4: date */
-				_x( '%1$s %2$s, %3$s ago (%4$s)', 'post revision title' ),
-				$compare_to_gravatar,
-				$compare_to_author,
-				human_time_diff( strtotime( $left_revision->post_modified ), current_time( 'timestamp' ) ),
-				$compare_to_date
-			);
-		}
-
-		$gravatar = get_avatar( $revision->post_author, 24 );
-		$author = get_the_author_meta( 'display_name', $revision->post_author );
-		$date = date_i18n( $datef, strtotime( $revision->post_modified ) );
-		$revision_date_author = sprintf(
-			/* translators: post revision title: 1: author avatar, 2: author name, 3: time ago, 4: date */
-			_x( '%1$s %2$s, %3$s ago (%4$s)', 'post revision title' ),
-			$gravatar,
-			$author,
-			human_time_diff( strtotime( $revision->post_modified ), current_time( 'timestamp' ) ),
-			$date
-		);
-
-		/* translators: 1: date */
-		$autosavef = _x( '%1$s [Autosave]', 'post revision title extra' );
-		/* translators: 1: date */
-		$currentf  = _x( '%1$s [Current Revision]', 'post revision title extra' );
-
-		if ( ! $post = get_post( $post_id ) )
-			continue;
-
-		if ( $left_revision->post_modified === $post->post_modified )
-			$revision_from_date_author = sprintf( $currentf, $revision_from_date_author );
-		elseif ( wp_is_post_autosave( $left_revision ) )
-			$revision_from_date_author = sprintf( $autosavef, $revision_from_date_author );
-
-		if ( $revision->post_modified === $post->post_modified ) {
-			$revision_date_author = sprintf( $currentf, $revision_date_author );
-			$is_current_revision = true;
-		} elseif ( wp_is_post_autosave( $revision ) ) {
-			$revision_date_author = sprintf( $autosavef, $revision_date_author );
-		}
-
-		/* translators: revision date short format, see http://php.net/date */
-		$date_short_format = _x( 'j M @ G:i', 'revision date short format');
-		$date_short = date_i18n( $date_short_format, strtotime( $revision->post_modified ) );
-
-		$revision_date_author_short = sprintf(
-			'%s <strong>%s</strong><br />%s',
-			$gravatar,
-			$author,
-			$date_short
-		);
-
-		$restore_link = wp_nonce_url(
-			add_query_arg(
-				array( 'revision' => $revision->ID,
-					'action' => 'restore' ),
-					admin_url( 'revision.php' )
-			),
-			"restore-post_{$revision->ID}"
-		);
-
-		// if this is a left handled calculation swap data
-		if ( 0 != $right_handle_at ) {
-			$tmp = $revision_from_date_author;
-			$revision_from_date_author = $revision_date_author;
-			$revision_date_author = $tmp;
-		}
-
-		if ( ( $compare_two_mode || -1 !== $previous_revision_id ) ) {
-			$all_the_revisions[] = array (
-				'ID'           => $revision->ID,
-				'titleTo'      => $revision_date_author,
-				'titleFrom'    => $revision_from_date_author,
-				'titleTooltip' => $revision_date_author_short,
-				'restoreLink'  => urldecode( $restore_link ),
-				'previousID'   => $previous_revision_id,
-				'isCurrent'    => $is_current_revision,
-			);
-		}
-		$previous_revision_id = $revision->ID;
-
-	endforeach;
-
-	// in RTL + single handle mode, reverse the revision direction
-	if ( is_rtl() && $compare_two_mode )
-		$all_the_revisions = array_reverse( $all_the_revisions );
-
-	echo json_encode( $all_the_revisions );
-	exit();
+	wp_send_json_success( $return );
 }
Index: wp-admin/includes/revision.php
===================================================================
--- wp-admin/includes/revision.php	(revision 0)
+++ wp-admin/includes/revision.php	(revision 0)
@@ -0,0 +1,54 @@
+<?php
+
+function wp_get_revision_ui_diff( $post, $compare_from, $compare_to ) {
+	if ( ! $post = get_post( $post ) )
+		return false;
+
+	if ( $compare_from ) {
+		if ( ! $compare_from = get_post( $compare_from ) )
+			return false;
+	} else {
+		// If we're dealing with the first revision...
+		$compare_from = false;
+	}
+
+	if ( ! $compare_to = get_post( $compare_to ) )
+		return false;
+
+	// If comparing revisions, make sure we're dealing with the right post parent.
+	if ( $compare_from && $compare_from->post_parent !== $post->ID )
+		return false;
+	if ( $compare_to->post_parent !== $post->ID )
+		return false;
+
+	if ( $compare_from && $compare_from->post_date > $compare_to->post_date ) {
+		$temp = $compare_from;
+		$compare_from = $compare_to;
+		$compare_to = $temp;
+	}
+
+	$return = array();
+
+	foreach ( _wp_post_revision_fields() as $field => $name ) {
+		$content_from = $compare_from ? apply_filters( "_wp_post_revision_field_$field", $compare_from->$field, $field, $compare_from, 'left' ) : '';
+		$content_to = apply_filters( "_wp_post_revision_field_$field", $compare_to->$field, $field, $compare_to, 'right' );
+
+		add_filter( "_wp_post_revision_field_$field", 'esc_html' );
+
+		// compare_to == 0 means first revision, so compare to a blank field to show whats changed
+		$diff = wp_text_diff( $content_from, $content_to, array( 'show_split_view' => true ) );
+
+		if ( ! $diff && 'post_title' === $field ) {
+			// It's a better user experience to still show the Title, even if it didn't change.
+			// No, you didn't see this.
+			$diff = "<table class='diff'><col class='ltype' /><col class='content' /><col class='ltype' /><col class='content' /><tbody><tr>";
+			$diff .= '<td>' . esc_html( $compare_from->post_title ) . '</td><td></td><td>' . esc_html( $compare_to->post_title ) . '</td>';
+			$diff .= '</tr></tbody>';
+			$diff .= '</table>';
+		}
+
+		if ( $diff )
+			$return[ $field ] = compact( 'name', 'diff' );
+	}
+	return $return;
+}
Index: wp-admin/revision.php
===================================================================
--- wp-admin/revision.php	(revision 24363)
+++ wp-admin/revision.php	(working copy)
@@ -8,6 +8,11 @@
 
 /** WordPress Administration Bootstrap */
 require_once('./admin.php');
+
+require ABSPATH . 'wp-admin/includes/revision.php';
+
+// wp_get_revision_ui_diff( $post, $compare_from, $compare_to )
+
 wp_reset_vars( array( 'revision', 'action' ) );
 
 $revision_id = absint( $revision );
